diff --git a/next.config.js b/next.config.js index fb8cca10e..71a2af037 100644 --- a/next.config.js +++ b/next.config.js @@ -106,8 +106,9 @@ const nextConfig = { 'store': path.join(__dirname, 'store'), 'api': path.join(__dirname, 'api'), 'config': path.join(__dirname, 'config.js'), - '@sentry/node': config.isServer ? '@sentry/node' : '@sentry/browser', + 'pages': path.join(__dirname, 'pages'), + '@sentry/node': config.isServer ? '@sentry/node' : '@sentry/browser', 'react': path.join(__dirname, 'node_modules', 'react'), 'react-dom': path.join(__dirname, 'node_modules', 'react-dom'), }) diff --git a/pages/_app/index.jsx b/pages/_app/index.jsx index e20f77a82..27115d226 100644 --- a/pages/_app/index.jsx +++ b/pages/_app/index.jsx @@ -1,9 +1,10 @@ import React from 'react' import NextApp from 'next/app' import { withRouter } from 'next/router' + import '@oacore/design/lib/index.css' import './global.css' - +import TermsModal from 'templates/terms-modal' import { UnauthorizedError } from 'api/errors' import { AuthorizationError, AccessError, NotFoundError } from 'store/errors' import { logPageView } from 'utils/analytics' @@ -149,30 +150,32 @@ class App extends NextApp { const { Component, pageProps, router } = this.props const { isAuthorized } = this.state const pathname = router.asPath - const variant = - isAuthorized && !isRouteWithoutStore(pathname) ? 'internal' : 'public' + const isPublicRoute = isRouteWithoutStore(pathname) + const variant = isAuthorized && !isPublicRoute ? 'internal' : 'public' - if (!isAuthorized) { + if (!isAuthorized || isPublicRoute) { return ( - {isRouteWithoutStore(pathname) ? : null} + {isPublicRoute ? : null} ) } return ( - - - + + + + + ) } diff --git a/store/data-provider/index.js b/store/data-provider/index.js index bcefc7524..d2649cdf0 100644 --- a/store/data-provider/index.js +++ b/store/data-provider/index.js @@ -1,19 +1,22 @@ -import { action, observable } from 'mobx' +import { action, observable, computed } from 'mobx' import Resource from '../resource' import Works from './works' import DepositDates from './deposit-dates' import DOI from './doi' import Issues from '../issues' -import apiRequest from '../../api' -import { NotFoundError as NetworkNotFoundError } from '../../api/errors' import { NotFoundError } from '../errors' +import { NotFoundError as NetworkNotFoundError } from 'api/errors' +import apiRequest from 'api' + class DataProvider extends Resource { @observable id = '' @observable name = '' + @observable acceptedTerms = false + @observable irus = null @observable rioxx = null @@ -38,10 +41,20 @@ class DataProvider extends Resource { @observable location = {} + @observable revalidatingPolicies = false + + @observable policies = null + + @computed + get areTermsAccepted() { + return this.policies?.some((p) => p?.type === 'terms' && p?.acceptedDate) + } + @action retrieve() { super.retrieve().then( () => { this.reset() + this.retrievePolicies() this.retrieveStatistics() this.retrievePluginConfig() this.retrieveIrusStats() @@ -115,6 +128,25 @@ class DataProvider extends Resource { } } + @action async retrievePolicies() { + const { data } = await this.options.request( + `/data-providers/${this.id}/policies` + ) + this.policies = data + } + + @action async acceptTerms() { + this.revalidatingPolicies = true + try { + await this.options.request(`/data-providers/${this.id}/policies/terms`, { + method: 'POST', + }) + await this.retrievePolicies() + } catch (error) { + this.revalidatingPolicies = true + } + } + @action reset() { this.irus = null diff --git a/templates/terms-modal/index.jsx b/templates/terms-modal/index.jsx new file mode 100644 index 000000000..416f6f7fd --- /dev/null +++ b/templates/terms-modal/index.jsx @@ -0,0 +1,41 @@ +import React from 'react' +import { Button, Modal } from '@oacore/design' + +import styles from './styles.module.css' + +import TermsPage from 'pages/terms' +import { withGlobalStore } from 'store' + +const TermsModal = ({ store, children }) => ( + <> + {children} + {!store.user.superAdmin && + store.dataProvider.policies !== null && + !store.dataProvider.areTermsAccepted && ( + + + + + + + Agreeing as {store.user.email} + + + + + )} + +) +export default withGlobalStore(TermsModal) diff --git a/templates/terms-modal/styles.module.css b/templates/terms-modal/styles.module.css new file mode 100644 index 000000000..ad38c7624 --- /dev/null +++ b/templates/terms-modal/styles.module.css @@ -0,0 +1,19 @@ +.modal { + max-width: 50rem; +} + +.content { + display: grid; + grid-template-columns: auto fit-content(80ch) auto; +} + +.footer { + display: flex; + align-items: center; + justify-content: flex-end; +} + +.name-text { + margin-right: 1rem; + font-weight: 600; +}