From 04ad2ec97f2b6c3aa2678e4207c230e248eef5e3 Mon Sep 17 00:00:00 2001 From: Piotr Gawron <p.gawron@atcomp.pl> Date: Thu, 10 Oct 2024 11:40:40 +0200 Subject: [PATCH] accept ToS --- .../ModalLayout/ModalLayout.component.tsx | 3 +- .../Modal/ToSModal/ToSModal.component.tsx | 29 ++++++++++++++--- src/redux/apiPath.ts | 1 + src/redux/user/user.thunks.ts | 32 +++++++++++++++++-- 4 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/components/FunctionalArea/Modal/ModalLayout/ModalLayout.component.tsx b/src/components/FunctionalArea/Modal/ModalLayout/ModalLayout.component.tsx index 56e1991a..b202afcd 100644 --- a/src/components/FunctionalArea/Modal/ModalLayout/ModalLayout.component.tsx +++ b/src/components/FunctionalArea/Modal/ModalLayout/ModalLayout.component.tsx @@ -30,6 +30,7 @@ export const ModalLayout = ({ children }: ModalLayoutProps): JSX.Element => { modalName === 'login' && 'h-auto w-[400px]', modalName === 'access-denied' && 'h-auto w-[400px]', modalName === 'select-project' && 'h-auto w-[400px]', + modalName === 'terms-of-service' && 'h-auto w-[400px]', modalName === 'add-comment' && 'h-auto w-[400px]', modalName === 'error-report' && 'h-auto w-[800px]', ['edit-overlay', 'logged-in-menu'].includes(modalName) && 'h-auto w-[432px]', @@ -46,7 +47,7 @@ export const ModalLayout = ({ children }: ModalLayoutProps): JSX.Element => { <div> {modalTitle} </div> )} - {modalName !== 'logged-in-menu' && ( + {modalName !== 'logged-in-menu' && modalName !== 'terms-of-service' && ( <button type="button" onClick={handleCloseModal} aria-label="close button"> <Icon name="close" className="fill-font-500" /> </button> diff --git a/src/components/FunctionalArea/Modal/ToSModal/ToSModal.component.tsx b/src/components/FunctionalArea/Modal/ToSModal/ToSModal.component.tsx index 222c4fdc..7d3d4e76 100644 --- a/src/components/FunctionalArea/Modal/ToSModal/ToSModal.component.tsx +++ b/src/components/FunctionalArea/Modal/ToSModal/ToSModal.component.tsx @@ -2,22 +2,43 @@ import React from 'react'; import { useAppDispatch } from '@/redux/hooks/useAppDispatch'; import { Button } from '@/shared/Button'; -import { logout } from '@/redux/user/user.thunks'; +import { getSessionValid, logout, updateUser } from '@/redux/user/user.thunks'; +import { closeModal } from '@/redux/modal/modal.slice'; +import { userSelector } from '@/redux/user/user.selectors'; +import { useAppSelector } from '@/redux/hooks/useAppSelector'; +import { termsOfServiceValSelector } from '@/redux/configuration/configuration.selectors'; export const ToSModal: React.FC = () => { const dispatch = useAppDispatch(); + const { userData } = useAppSelector(userSelector); + + const termsOfService = useAppSelector(termsOfServiceValSelector); + const updateUserTosHandler = async (): Promise<void> => { // eslint-disable-next-line no-console console.log('update'); + if (userData) { + const user = { ...userData, termsOfUseConsent: true }; + await dispatch(updateUser(user)); + await dispatch(getSessionValid()); + dispatch(closeModal()); + } }; - const logoutHandler = (): void => { - dispatch(logout()); + const logoutHandler = async (): Promise<void> => { + await dispatch(logout()); + dispatch(closeModal()); }; return ( <div className="w-[400px] border border-t-[#E1E0E6] bg-white p-[24px]"> - <div className="grid grid-cols-2 gap-2"> + <div> + I agree to the minerva{' '} + <a href={termsOfService} target="_blank" className="underline"> + Terms of Service. + </a> + </div> + <div className="mt-4 grid grid-cols-2 gap-2"> <div> <Button className="ring-transparent hover:ring-transparent" diff --git a/src/redux/apiPath.ts b/src/redux/apiPath.ts index 944cfa00..0b30a948 100644 --- a/src/redux/apiPath.ts +++ b/src/redux/apiPath.ts @@ -102,6 +102,7 @@ export const apiPath = { getSubmapConnections: (): string => `projects/${PROJECT_ID}/submapConnections/`, logout: (): string => `doLogout`, user: (login: string): string => `users/${login}`, + updateUser: (login: string): string => `users/${login}`, getStacktrace: (code: string): string => `stacktrace/${code}`, submitError: (): string => `minervanet/submitError`, getOauthProviders: (): string => `oauth/providers/`, diff --git a/src/redux/user/user.thunks.ts b/src/redux/user/user.thunks.ts index 3e1f7bc1..9b016dd8 100644 --- a/src/redux/user/user.thunks.ts +++ b/src/redux/user/user.thunks.ts @@ -9,9 +9,11 @@ import { getError } from '@/utils/error-report/getError'; import axios, { HttpStatusCode } from 'axios'; import { showToast } from '@/utils/showToast'; import { setLoginForOldMinerva } from '@/utils/setLoginForOldMinerva'; -import { apiPath } from '../apiPath'; -import { closeModal, openLoggedInMenuModal } from '../modal/modal.slice'; +import { ThunkConfig } from '@/types/store'; +import { userSchema } from '@/models/userSchema'; import { hasPrivilege } from './user.utils'; +import { closeModal, openLoggedInMenuModal } from '../modal/modal.slice'; +import { apiPath } from '../apiPath'; const getUserRole = (privileges: UserPrivilege[]): string => { if (hasPrivilege(privileges, 'IS_ADMIN')) { @@ -118,3 +120,29 @@ export const logout = createAsyncThunk('user/logout', async () => { return Promise.reject(getError({ error, prefix: 'Log out' })); } }); + +export const updateUser = createAsyncThunk<undefined, User, ThunkConfig>( + 'users/updateUser', + // eslint-disable-next-line consistent-return + async user => { + try { + const newUser = await axiosInstance.patch<User>( + apiPath.updateUser(user.login), + { + user: { + termsOfUseConsent: user.termsOfUseConsent, + }, + }, + { + withCredentials: true, + }, + ); + + validateDataUsingZodSchema(newUser, userSchema); + + showToast({ type: 'success', message: 'ToS agreement registered' }); + } catch (error) { + return Promise.reject(getError({ error })); + } + }, +); -- GitLab