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