diff --git a/src/AppRoutes.jsx b/src/AppRoutes.jsx index 662dceb26..87a33a3b0 100644 --- a/src/AppRoutes.jsx +++ b/src/AppRoutes.jsx @@ -5,10 +5,10 @@ import { Routes, Route, Navigate, Outlet } from 'react-router-dom'; import { useSession } from '@hooks'; import { SessionProvider } from '@contexts'; // Component Imports -import { CIVIC_FORM_LIST, FormLayout } from '@components/CivicProfileForms'; +import { PROFILE_FORM_LIST, FormLayout } from '@components/ProfileForms'; import { MESSAGE_PAGES_LIST, MessagesLayout } from '@components/Messages'; // Page Imports -import { CivicProfile, Home, Contacts, Profile, Signup } from './pages'; +import { Account, Profile, Contacts, Home, Signup } from './pages'; const ProtectedRoute = ({ isLoggedIn, children }) => isLoggedIn ? children ?? : ; @@ -43,7 +43,7 @@ const AppRoutes = () => { }> } /> - } /> + } /> {MESSAGE_PAGES_LIST.map(({ path: routePath, element }) => ( @@ -60,9 +60,9 @@ const AppRoutes = () => { /> ))} - } /> - }> - {CIVIC_FORM_LIST.map((formProps) => ( + } /> + }> + {PROFILE_FORM_LIST.map((formProps) => ( { +const AccountComponent = ({ contactProfile }) => { const { session } = useSession(); const { updateProfileInfo, setProfileData, profileData, fetchProfileInfo } = useContext(SignedInUserContext); - // Public Profile Data - const [profileName, setProfileName] = useState(profileData?.profileInfo?.profileName); + // Public Profile Data (Account Data) + const [accountName, setAccountName] = useState(profileData?.profileInfo?.profileName); const [nickname, setNickname] = useState(profileData?.profileInfo?.nickname); const [edit, setEdit] = useState(false); - const loadProfileData = async () => { + const loadAccountData = async () => { const profileDataSolid = await fetchProfileInfo(session.info.webId); setProfileData(profileDataSolid); - setProfileName(profileDataSolid.profileInfo?.profileName); + setAccountName(profileDataSolid.profileInfo?.profileName); setNickname(profileDataSolid.profileInfo?.nickname); }; const handleCancelEdit = () => { - loadProfileData(); + loadAccountData(); setEdit(!edit); }; @@ -56,33 +56,26 @@ const ProfileComponent = ({ contactProfile }) => { event.preventDefault(); const inputValues = { - profileName, + accountName, nickname }; await updateProfileInfo(session, profileData, inputValues); - loadProfileData(); + loadAccountData(); setEdit(false); }; useEffect(() => { - loadProfileData(); + loadAccountData(); }, []); const theme = useTheme(); const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm')); return ( - - + +
{ padding: '20px' }} > - - + - - + {!contactProfile && ( - )} -
+ ); }; -export default ProfileComponent; +export default AccountComponent; diff --git a/src/components/Profile/ProfileEditButtonGroup.jsx b/src/components/Account/AccountEditButtonGroup.jsx similarity index 72% rename from src/components/Profile/ProfileEditButtonGroup.jsx rename to src/components/Account/AccountEditButtonGroup.jsx index dfd309bf9..6db50ff6a 100644 --- a/src/components/Profile/ProfileEditButtonGroup.jsx +++ b/src/components/Account/AccountEditButtonGroup.jsx @@ -8,21 +8,21 @@ import ClearIcon from '@mui/icons-material/Clear'; import EditIcon from '@mui/icons-material/Edit'; /** - * The ProfileEditButtonGroup Component is a component that consist of the profile - * page edit buttons for the ProfileInputField component + * The AccountEditButtonGroup Component is a component that consist of the account + * page edit buttons for the AccountInputField component * * @memberof Profile - * @name ProfileEditButtonGroup - * @param {object} Props - Props for Profile Edit buttons + * @name AccountEditButtonGroup + * @param {object} Props - Props for Account Edit buttons * @param {boolean} Props.edit - Boolean state for editing values in the - * ProfileInputField component + * AccountInputField component * @param {() => void} Props.handleCancelEdit - Handler function for canceling - * edit for ProfileInputField component + * edit for AccountInputField component * @param {() => void} Props.handleEditInput - Handler function for editing the - * ProfileInputField component - * @returns {React.JSX.Element} The ProfileEditButtonGroup + * AccountInputField component + * @returns {React.JSX.Element} The AccountEditButtonGroup */ -const ProfileEditButtonGroup = ({ edit, handleCancelEdit, handleEditInput }) => ( +const AccountEditButtonGroup = ({ edit, handleCancelEdit, handleEditInput }) => ( ); -export default ProfileEditButtonGroup; +export default AccountEditButtonGroup; diff --git a/src/components/Profile/ProfileImageField.jsx b/src/components/Account/AccountImageField.jsx similarity index 54% rename from src/components/Profile/ProfileImageField.jsx rename to src/components/Account/AccountImageField.jsx index c6cbbbbe7..18e562c93 100644 --- a/src/components/Profile/ProfileImageField.jsx +++ b/src/components/Account/AccountImageField.jsx @@ -4,84 +4,80 @@ import React, { useContext, useState } from 'react'; import { useSession } from '@hooks'; // Material UI Imports import Avatar from '@mui/material/Avatar'; -import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import HideImageIcon from '@mui/icons-material/HideImage'; import ImageIcon from '@mui/icons-material/Image'; +import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; // Contexts Imports import { SignedInUserContext } from '@contexts'; import useNotification from '../../hooks/useNotification'; /** - * ProfileImageField Component - Component that creates the editable inputs fields - * for the Profile page + * AccountImageField Component - Component that creates the editable + * account avatar image selector for the Account page * * @memberof Profile - * @name ProfileImageField - * @param {object} Props - Props used for NewMessage - * @param {() => void} Props.loadProfileData - Handler function for setting local - * state for profile card in PASS + * @name AccountImageField + * @param {object} Props - Props used for AccountImageField + * @param {() => void} Props.loadAccountData - Handler function for setting local + * state for account card in PASS * @param {object} [Props.contactProfile] - Contact object with data from profile - * or null if user profile is selected - * @returns {React.JSX.Element} React component for NewMessage + * or null if user account is selected + * @returns {React.JSX.Element} React component for AccountImageField */ -const ProfileImageField = ({ loadProfileData, contactProfile }) => { +const AccountImageField = ({ loadAccountData, contactProfile }) => { const { addNotification } = useNotification(); const { session } = useSession(); const { profileData, fetchProfileInfo, removeProfileImage, uploadProfileImage } = useContext(SignedInUserContext); - const [profileImg, setProfileImg] = useState(localStorage.getItem('profileImage')); + const [accountImg, setAccountImg] = useState(localStorage.getItem('profileImage')); - const handleProfileImage = async (event) => { + const handleAccountImage = async (event) => { if (event.target.files[0].size > 1 * 1000 * 1024) { - addNotification('error', 'Profile images have a maximum size of 1MB.'); + addNotification('error', 'Account images have a maximum size of 1MB.'); } else { await uploadProfileImage(session, profileData, event.target.files[0]); - const updatedProfileData = await fetchProfileInfo(session.info.webId); - localStorage.setItem('profileImage', updatedProfileData.profileInfo.profileImage); - setProfileImg(updatedProfileData.profileInfo.profileImage); + const updatedAccountData = await fetchProfileInfo(session.info.webId); + localStorage.setItem('profileImage', updatedAccountData.profileInfo.profileImage); + setAccountImg(updatedAccountData.profileInfo.profileImage); - loadProfileData(); + loadAccountData(); } }; - const handleRemoveProfileImg = async () => { - if (window.confirm("You're about to delete your profile image. Do you wish to continue?")) { + const handleRemoveAccountImg = async () => { + if (window.confirm("You're about to delete your account image. Do you wish to continue?")) { await removeProfileImage(session, profileData); - loadProfileData(); + loadAccountData(); localStorage.removeItem('profileImage'); - setProfileImg(null); + setAccountImg(null); } }; return ( - - Profile Image: + Account Image: {!contactProfile && - (profileImg ? ( + (accountImg ? ( ))} - + ); }; -export default ProfileImageField; +export default AccountImageField; diff --git a/src/components/Profile/ProfileInputField.jsx b/src/components/Account/AccountInputField.jsx similarity index 71% rename from src/components/Profile/ProfileInputField.jsx rename to src/components/Account/AccountInputField.jsx index f9ca48b09..314f54a53 100644 --- a/src/components/Profile/ProfileInputField.jsx +++ b/src/components/Account/AccountInputField.jsx @@ -6,20 +6,20 @@ import Input from '@mui/material/Input'; import InputLabel from '@mui/material/InputLabel'; /** - * ProfileInputField Component - Component that creates the editable inputs fields - * for the Profile page + * AccountInputField Component - Component that creates the editable input fields + * for the Account page * * @memberof Profile - * @name ProfileInputField - * @param {object} Props - Props used for NewMessage + * @name AccountInputField + * @param {object} Props - Props used for AccountInputField * @param {string} Props.inputName - Name of input field - * @param {string} Props.inputValue - Value of input field used for updating profile + * @param {string} Props.inputValue - Value of input field used for updating account * @param {(value: React.SetStateAction) => void} Props.setInputValue * - Set function for inputValue * @param {boolean} Props.edit - Boolean used to toggle edit inputs - * @returns {React.JSX.Element} React component for NewMessage + * @returns {React.JSX.Element} React component for AccountInputField */ -const ProfileInputField = ({ inputName, inputValue, setInputValue, edit }) => ( +const AccountInputField = ({ inputName, inputValue, setInputValue, edit }) => ( {inputName}: @@ -34,4 +34,4 @@ const ProfileInputField = ({ inputName, inputValue, setInputValue, edit }) => ( ); -export default ProfileInputField; +export default AccountInputField; diff --git a/src/components/Account/index.js b/src/components/Account/index.js new file mode 100644 index 000000000..093ff1799 --- /dev/null +++ b/src/components/Account/index.js @@ -0,0 +1,12 @@ +import AccountComponent from './AccountComponent'; +import AccountImageField from './AccountImageField'; +import AccountInputField from './AccountInputField'; + +/** + * Components and functions related to the Account card on Solid and displaying + * them on PASS + * + * @namespace Profile + */ + +export { AccountComponent, AccountImageField, AccountInputField }; diff --git a/src/components/Modals/AddContactModal.jsx b/src/components/Modals/AddContactModal.jsx index fda815043..0cc16d6f0 100644 --- a/src/components/Modals/AddContactModal.jsx +++ b/src/components/Modals/AddContactModal.jsx @@ -27,7 +27,7 @@ import { FormSection } from '../Form'; */ const renderWebId = (username) => { const baseUrl = new URL(localStorage.getItem('oidcIssuer')); - return new URL(`${username}/profile/card#me`, baseUrl); + return new URL(`${username}/account/card#me`, baseUrl); }; /** diff --git a/src/components/NavBar/NavMenu.jsx b/src/components/NavBar/NavMenu.jsx index 6fbba40c5..d00bf7007 100644 --- a/src/components/NavBar/NavMenu.jsx +++ b/src/components/NavBar/NavMenu.jsx @@ -37,7 +37,7 @@ import { useMessageList } from '@hooks'; * - The set function for showConfirmationModal * @param {(event) => void} Props.handleNotificationsMenu - Handler function for * Notification Menu - * @param {string} Props.profileImg - String for profile image + * @param {string} Props.accountImg - String for account image * @returns {React.JSX.Element} - The NavMenu Component */ const NavMenu = ({ @@ -48,7 +48,7 @@ const NavMenu = ({ setAnchorEl, setShowConfirmation, handleNotificationsMenu, - profileImg + accountImg }) => { const theme = useTheme(); const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm')); @@ -109,7 +109,7 @@ const NavMenu = ({ - Civic Profile + Profile @@ -161,9 +161,9 @@ const NavMenu = ({ > Notifications - {/* profile */} + {/* account */} setContact(null)} @@ -173,8 +173,8 @@ const NavMenu = ({ sx={{ width: '100%', minHeight: '36px' }} startIcon={ } > - Profile + Account diff --git a/src/components/NavBar/NavbarDesktop.jsx b/src/components/NavBar/NavbarDesktop.jsx index 7a16322ed..1e37ee881 100644 --- a/src/components/NavBar/NavbarDesktop.jsx +++ b/src/components/NavBar/NavbarDesktop.jsx @@ -58,10 +58,10 @@ const NavbarDesktop = ({ setShowConfirmation }) => { }; const { profileData } = useContext(SignedInUserContext); - const [profileImg, setProfileImg] = useState(localStorage.getItem('profileImage')); + const [accountImg, setAccountImg] = useState(localStorage.getItem('profileImage')); useEffect(() => { - setProfileImg(localStorage.getItem('profileImage')); + setAccountImg(localStorage.getItem('profileImage')); }, [profileData]); return ( @@ -131,7 +131,7 @@ const NavbarDesktop = ({ setShowConfirmation }) => {

Notification 2

- {/* profile icon */} + {/* account icon */} { color="inherit" > @@ -158,7 +158,7 @@ const NavbarDesktop = ({ setShowConfirmation }) => { setAnchorEl={setAnchorEl} setShowConfirmation={setShowConfirmation} handleNotificationsMenu={handleNotificationsMenu} - profileImg={profileImg} + accountImg={accountImg} /> )} diff --git a/src/components/NavBar/NavbarLinks.jsx b/src/components/NavBar/NavbarLinks.jsx index 5c1b7847b..6b718de1e 100644 --- a/src/components/NavBar/NavbarLinks.jsx +++ b/src/components/NavBar/NavbarLinks.jsx @@ -24,7 +24,7 @@ const NavbarLinks = () => { // array of current nav links for menus const routesArray = [ { label: 'Contacts', path: '/contacts' }, - { label: 'Civic Profile', path: '/civic-profile/basic-info' } + { label: 'Profile', path: '/profile/basic-info' } ]; return ( diff --git a/src/components/Profile/index.js b/src/components/Profile/index.js deleted file mode 100644 index 6a4a78f99..000000000 --- a/src/components/Profile/index.js +++ /dev/null @@ -1,12 +0,0 @@ -import ProfileComponent from './ProfileComponent'; -import ProfileImageField from './ProfileImageField'; -import ProfileInputField from './ProfileInputField'; - -/** - * Components and functions related to the Profile card on Solid and displaying - * the on PASS - * - * @namespace Profile - */ - -export { ProfileComponent, ProfileImageField, ProfileInputField }; diff --git a/src/components/CivicProfileForms/BasicInfo.jsx b/src/components/ProfileForms/BasicInfo.jsx similarity index 100% rename from src/components/CivicProfileForms/BasicInfo.jsx rename to src/components/ProfileForms/BasicInfo.jsx diff --git a/src/components/CivicProfileForms/FinancialInfo.jsx b/src/components/ProfileForms/FinancialInfo.jsx similarity index 100% rename from src/components/CivicProfileForms/FinancialInfo.jsx rename to src/components/ProfileForms/FinancialInfo.jsx diff --git a/src/components/CivicProfileForms/FormLayout.jsx b/src/components/ProfileForms/FormLayout.jsx similarity index 100% rename from src/components/CivicProfileForms/FormLayout.jsx rename to src/components/ProfileForms/FormLayout.jsx diff --git a/src/components/CivicProfileForms/FormList.js b/src/components/ProfileForms/FormList.js similarity index 87% rename from src/components/CivicProfileForms/FormList.js rename to src/components/ProfileForms/FormList.js index f2fed39a5..62822f39d 100644 --- a/src/components/CivicProfileForms/FormList.js +++ b/src/components/ProfileForms/FormList.js @@ -2,7 +2,7 @@ import BasicInfo from './BasicInfo'; import FinancialInfo from './FinancialInfo'; import HousingInfo from './HousingInfo'; -const CIVIC_FORM_LIST = [ +const PROFILE_FORM_LIST = [ { path: 'basic-info', label: 'Basic Information', element: BasicInfo, key: 'basic_info' }, { path: 'housing-info', label: 'Housing Information', element: HousingInfo, key: 'housing_info' }, { @@ -13,4 +13,4 @@ const CIVIC_FORM_LIST = [ } ]; -export default CIVIC_FORM_LIST; +export default PROFILE_FORM_LIST; diff --git a/src/components/CivicProfileForms/HousingInfo.jsx b/src/components/ProfileForms/HousingInfo.jsx similarity index 98% rename from src/components/CivicProfileForms/HousingInfo.jsx rename to src/components/ProfileForms/HousingInfo.jsx index 2ad49d964..aa30d95ba 100644 --- a/src/components/CivicProfileForms/HousingInfo.jsx +++ b/src/components/ProfileForms/HousingInfo.jsx @@ -9,7 +9,7 @@ import { useCivicProfile } from '@hooks'; /** * HousingInfo - A form to fill out with housing security info * - * @memberof CivicProfileForms + * @memberof ProfileForms * @name HousingInfo * @returns {React.JSX.Element} The HousingInfo Component */ diff --git a/src/components/CivicProfileForms/index.js b/src/components/ProfileForms/index.js similarity index 56% rename from src/components/CivicProfileForms/index.js rename to src/components/ProfileForms/index.js index 9ca6bb73c..6e35d681b 100644 --- a/src/components/CivicProfileForms/index.js +++ b/src/components/ProfileForms/index.js @@ -1,7 +1,7 @@ import BasicInfo from './BasicInfo'; import FinancialInfo from './FinancialInfo'; -import HousingInfo from './HousingInfo'; import FormLayout from './FormLayout'; -import CIVIC_FORM_LIST from './FormList'; +import HousingInfo from './HousingInfo'; +import PROFILE_FORM_LIST from './FormList'; -export { BasicInfo, FinancialInfo, HousingInfo, FormLayout, CIVIC_FORM_LIST }; +export { BasicInfo, FinancialInfo, FormLayout, HousingInfo, PROFILE_FORM_LIST }; diff --git a/src/pages/Account.jsx b/src/pages/Account.jsx new file mode 100644 index 000000000..5ba42861c --- /dev/null +++ b/src/pages/Account.jsx @@ -0,0 +1,233 @@ +// React Imports +import React, { useContext, useEffect, useState } from 'react'; +import { Link, useLocation } from 'react-router-dom'; +// Custom Hook Imports +import { useNotification, useSession } from '@hooks'; +// Material UI Imports +import AddIcon from '@mui/icons-material/Add'; +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import CircularProgress from '@mui/material/CircularProgress'; +import Container from '@mui/material/Container'; +import ShareIcon from '@mui/icons-material/Share'; +import Typography from '@mui/material/Typography'; +import useMediaQuery from '@mui/material/useMediaQuery'; +import { useTheme } from '@mui/material/styles'; +// Context Imports +import { DocumentListContext } from '@contexts'; +// Component Imports +import { ConfirmationModal, UploadDocumentModal, SetAclPermissionsModal } from '@components/Modals'; +import DocumentTable from '@components/Documents'; +import { AccountComponent } from '@components/Account'; +import { LoadingAnimation } from '@components/Notification'; +// Model Helpers +import { fetchProfileInfo } from '../model-helpers'; + +/** + * Account Page - Page that displays the user's account card information and + * allow users to edit/update them on PASS + * + * @memberof Pages + * @name Account + * @returns {React.JSX.Element} The Account Page + */ +const Account = () => { + // Route related states + const location = useLocation(); + if (location.pathname.split('/')[1] === 'contacts') { + localStorage.setItem('restorePath', '/contacts'); + } else { + localStorage.setItem('restorePath', '/account'); + } + const theme = useTheme(); + const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm')); + + // Documents related states + const { session } = useSession(); + const [showConfirmationModal, setShowConfirmationModal] = useState(false); + const [processing, setProcessing] = useState(false); + const { addNotification } = useNotification(); + const { removeDocument } = useContext(DocumentListContext); + const [selectedDocToDelete, setSelectedDocToDelete] = useState(null); + const [showAddDocModal, setShowAddDocModal] = useState(false); + const [showAclPermissionModal, setShowAclPermissionModal] = useState(false); + const [dataset, setDataset] = useState({ + modalType: '', + docName: '', + docType: '' + }); + + const handleSelectDeleteDoc = (document) => { + setSelectedDocToDelete(document); + setShowConfirmationModal(true); + }; + + // Function for deleting documents + const handleDeleteDoc = async () => { + setProcessing(true); + try { + await removeDocument(selectedDocToDelete.name); + addNotification('success', `${selectedDocToDelete?.name} deleted from the pod.`); + } catch (e) { + addNotification('error', `Document deletion failed. Reason: ${e.message}`); + } finally { + setShowConfirmationModal(false); + setProcessing(false); + } + }; + + // Account related states + const contact = location.state?.contact; + const [contactProfile, setContactProfile] = useState(null); + const webIdUrl = contact?.webId ?? session.info.webId; + const [loadingAccount, setLoadingAccount] = useState(true); + + // Handler for the SetAclPermissions Modal that + // sets the appropriate version of the modal to load, + // and the file name for the relevant document, (if any) + // before opening the modal. + const handleAclPermissionsModal = (modalType, docName = '', docType = '') => { + setDataset({ + modalType, + docName, + docType + }); + setShowAclPermissionModal(true); + }; + + useEffect(() => { + const fetchContactProfile = async () => { + const profileData = await fetchProfileInfo(webIdUrl); + setContactProfile({ + ...contact, + ...profileData.profileInfo + }); + }; + + if (contact) { + fetchContactProfile(); + } else { + setContactProfile(null); + } + }, [contact]); + + useEffect(() => { + setTimeout(() => { + setLoadingAccount(false); + }, 1000); + }, []); + + if (loadingAccount) { + return ( + + + + ); + } + + const signupLink = `${window.location.origin}/signup?webId=${encodeURIComponent( + session.info.webId + )}`; + + return ( + + + Account Information + {!contact && ( + + + Your Signup Link + + + )} + + User WebId: + + {webIdUrl} + + + + + + + {!contact && ( + + )} + + + + + + + handleSelectDeleteDoc(document)} + /> + + ); +}; + +export default Account; diff --git a/src/pages/CivicProfile.jsx b/src/pages/CivicProfile.jsx deleted file mode 100644 index 4119d8161..000000000 --- a/src/pages/CivicProfile.jsx +++ /dev/null @@ -1,43 +0,0 @@ -// React Imports -import React from 'react'; -import { Link, Outlet, useLocation } from 'react-router-dom'; -// MUI Imports -import Container from '@mui/material/Container'; -import MenuItem from '@mui/material/MenuItem'; -import MenuList from '@mui/material/MenuList'; -import useMediaQuery from '@mui/material/useMediaQuery'; -import { useTheme } from '@mui/system'; -// Component Imports -import { CIVIC_FORM_LIST } from '@components/CivicProfileForms'; - -const CivicProfile = () => { - const location = useLocation(); - - localStorage.setItem('restorePath', location.pathname); - const currentForm = location.pathname.split('/').pop(); - const theme = useTheme(); - const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm')); - - return ( - - - - - - - - - ); -}; - -export default CivicProfile; diff --git a/src/pages/Profile.jsx b/src/pages/Profile.jsx index b0080ca4f..1bbdd709d 100644 --- a/src/pages/Profile.jsx +++ b/src/pages/Profile.jsx @@ -1,27 +1,14 @@ // React Imports -import React, { useContext, useEffect, useState } from 'react'; -import { Link, useLocation } from 'react-router-dom'; -// Custom Hook Imports -import { useNotification, useSession } from '@hooks'; -// Material UI Imports -import AddIcon from '@mui/icons-material/Add'; -import Box from '@mui/material/Box'; -import Button from '@mui/material/Button'; -import CircularProgress from '@mui/material/CircularProgress'; +import React from 'react'; +import { Link, Outlet, useLocation } from 'react-router-dom'; +// MUI Imports import Container from '@mui/material/Container'; -import ShareIcon from '@mui/icons-material/Share'; -import Typography from '@mui/material/Typography'; +import MenuItem from '@mui/material/MenuItem'; +import MenuList from '@mui/material/MenuList'; import useMediaQuery from '@mui/material/useMediaQuery'; -import { useTheme } from '@mui/material/styles'; -// Context Imports -import { DocumentListContext } from '@contexts'; +import { useTheme } from '@mui/system'; // Component Imports -import { ConfirmationModal, UploadDocumentModal, SetAclPermissionsModal } from '@components/Modals'; -import DocumentTable from '@components/Documents'; -import { ProfileComponent } from '@components/Profile'; -import { LoadingAnimation } from '@components/Notification'; -// Model Helpers -import { fetchProfileInfo } from '../model-helpers'; +import { PROFILE_FORM_LIST } from '@components/ProfileForms'; /** * Profile Page - Page that displays the user's profile card information and @@ -32,200 +19,31 @@ import { fetchProfileInfo } from '../model-helpers'; * @returns {React.JSX.Element} The Profile Page */ const Profile = () => { - // Route related states const location = useLocation(); - if (location.pathname.split('/')[1] === 'contacts') { - localStorage.setItem('restorePath', '/contacts'); - } else { - localStorage.setItem('restorePath', '/profile'); - } + + localStorage.setItem('restorePath', location.pathname); + const currentForm = location.pathname.split('/').pop(); const theme = useTheme(); const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm')); - // Documents related states - const { session } = useSession(); - const [showConfirmationModal, setShowConfirmationModal] = useState(false); - const [processing, setProcessing] = useState(false); - const { addNotification } = useNotification(); - const { removeDocument } = useContext(DocumentListContext); - const [selectedDocToDelete, setSelectedDocToDelete] = useState(null); - const [showAddDocModal, setShowAddDocModal] = useState(false); - const [showAclPermissionModal, setShowAclPermissionModal] = useState(false); - const [dataset, setDataset] = useState({ - modalType: '', - docName: '', - docType: '' - }); - - const handleSelectDeleteDoc = (document) => { - setSelectedDocToDelete(document); - setShowConfirmationModal(true); - }; - - // Function for deleting documents - const handleDeleteDoc = async () => { - setProcessing(true); - try { - await removeDocument(selectedDocToDelete.name); - addNotification('success', `${selectedDocToDelete?.name} deleted from the pod.`); - } catch (e) { - addNotification('error', `Document deletion failed. Reason: ${e.message}`); - } finally { - setShowConfirmationModal(false); - setProcessing(false); - } - }; - - // Profile related states - const contact = location.state?.contact; - const [contactProfile, setContactProfile] = useState(null); - const webIdUrl = contact?.webId ?? session.info.webId; - const [loadingProfile, setLoadingProfile] = useState(true); - - // Handler for the SetAclPermissions Modal that - // sets the appropriate version of the modal to load, - // and the file name for the relevant document, (if any) - // before opening the modal. - const handleAclPermissionsModal = (modalType, docName = '', docType = '') => { - setDataset({ - modalType, - docName, - docType - }); - setShowAclPermissionModal(true); - }; - - useEffect(() => { - const fetchContactProfile = async () => { - const profileData = await fetchProfileInfo(webIdUrl); - setContactProfile({ - ...contact, - ...profileData.profileInfo - }); - }; - - if (contact) { - fetchContactProfile(); - } else { - setContactProfile(null); - } - }, [contact]); - - useEffect(() => { - setTimeout(() => { - setLoadingProfile(false); - }, 1000); - }, []); - - if (loadingProfile) { - return ( - - - - ); - } - - const signupLink = `${window.location.origin}/signup?webId=${encodeURIComponent( - session.info.webId - )}`; - return ( - - - Profile Information - {!contact ? ( - - - Your Signup Link - - - ) : null} - - User WebId: - - {webIdUrl} - - - - - - - {!contact && ( - - )} - - - - - - - handleSelectDeleteDoc(document)} - /> + + + + + + + ); }; diff --git a/src/pages/index.js b/src/pages/index.js index 8b48ba6f4..13de26e55 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -1,13 +1,14 @@ -import Home from './Home'; +import Account from './Account'; import Contacts from './Contacts'; +import Home from './Home'; import Messages from './Messages'; import Profile from './Profile'; import Signup from './Signup'; -import CivicProfile from './CivicProfile'; + /** * The main pages in PASS * * @namespace Pages */ -export { Contacts, CivicProfile, Home, Messages, Profile, Signup }; +export { Account, Contacts, Home, Messages, Profile, Signup }; diff --git a/test/components/Profile/ProfileComponent.test.jsx b/test/components/Account/AccountComponent.test.jsx similarity index 86% rename from test/components/Profile/ProfileComponent.test.jsx rename to test/components/Account/AccountComponent.test.jsx index 964f63a53..ece88a2a5 100644 --- a/test/components/Profile/ProfileComponent.test.jsx +++ b/test/components/Account/AccountComponent.test.jsx @@ -2,7 +2,7 @@ import React from 'react'; import { cleanup, render } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { afterEach, describe, expect, it, vi } from 'vitest'; -import { ProfileComponent } from '@components/Profile'; +import { AccountComponent } from '@components/Account'; import { SignedInUserContext } from '@contexts'; import * as profileHelper from '../../../src/model-helpers/Profile'; import '@testing-library/jest-dom/extend-expect'; @@ -29,13 +29,13 @@ const mockSignedInUserContextMemo = { }) }; -describe('ProfileComponent', () => { +describe('AccountComponent', () => { afterEach(() => cleanup()); it('renders cancel and update buttons after clicking on edit button from initial render', async () => { const { queryByRole } = render( - + ); let editButton = queryByRole('button', { name: 'Edit' }); @@ -57,7 +57,7 @@ describe('ProfileComponent', () => { it('renders edit buttons after clicking on cancel button', async () => { const { queryByRole } = render( - + ); let editButton = queryByRole('button', { name: 'Edit' }); @@ -81,10 +81,10 @@ describe('ProfileComponent', () => { expect(cancelButton).toBeNull(); }); - it('renders no edit button for ProfileInputFields if contactProfile is not null', () => { + it('renders no edit button for AccountInputFields if contactProfile is not null', () => { const { queryByRole } = render( - + ); const editButton = queryByRole('button', { name: 'Edit' }); @@ -93,10 +93,10 @@ describe('ProfileComponent', () => { }); }); -it('renders profile component as row default', () => { +it('renders account component as row by default', () => { const component = render( - + ); @@ -106,11 +106,11 @@ it('renders profile component as row default', () => { expect(cssProperty.flexDirection).toBe('row'); }); -it('renders profile component as column mobile', () => { +it('renders account component as column for mobile', () => { window.matchMedia = createMatchMedia(599); const component = render( - + ); diff --git a/test/components/Profile/ProfileImageField.test.jsx b/test/components/Account/AccountImageField.test.jsx similarity index 74% rename from test/components/Profile/ProfileImageField.test.jsx rename to test/components/Account/AccountImageField.test.jsx index 8a7d9e64e..84738af96 100644 --- a/test/components/Profile/ProfileImageField.test.jsx +++ b/test/components/Account/AccountImageField.test.jsx @@ -1,20 +1,20 @@ import React from 'react'; import { render } from '@testing-library/react'; import { describe, expect, it } from 'vitest'; -import { ProfileImageField } from '../../../src/components/Profile'; +import { AccountImageField } from '@components/Account'; import '@testing-library/jest-dom/extend-expect'; -const MockProfileComponent = ({ noUserImage, mockContactProfile }) => { +const MockAccountComponent = ({ noUserImage, mockContactProfile }) => { if (!noUserImage) { localStorage.setItem('profileImage', 'https://example.com/user.png'); } - return ; + return ; }; -describe('ProfileImageField', () => { - it('renders Choose Img button and PersonIcon if contactProfile is null and user has no profile img', () => { +describe('AccountImageField', () => { + it('renders Choose Img button and PersonIcon if contactProfile is null and user has no account image', () => { const { queryByRole, queryByTestId } = render( - + ); const buttonElement = queryByRole('button'); expect(buttonElement.textContent).toBe('Choose Img'); @@ -23,9 +23,9 @@ describe('ProfileImageField', () => { expect(svgElement).not.toBeNull(); }); - it('renders Remove Img button and image if contactProfile is null, but user has profile image', () => { + it('renders Remove Img button and image if contactProfile is null, but user has account image', () => { const { queryByRole, queryByTestId } = render( - + ); const buttonElement = queryByRole('button'); expect(buttonElement.textContent).toBe('Remove Img'); @@ -37,8 +37,8 @@ describe('ProfileImageField', () => { expect(svgElement).toBeNull(); }); - it('renders no button with PersonIcon if contactProfile is not null and has no profile image', () => { - const { queryByRole, queryByTestId } = render(); + it('renders no button with PersonIcon if contactProfile is not null and has no account image', () => { + const { queryByRole, queryByTestId } = render(); const buttonElement = queryByRole('button'); expect(buttonElement).toBeNull(); @@ -46,10 +46,10 @@ describe('ProfileImageField', () => { expect(svgElement).not.toBeNull(); }); - it('renders no button with image if contactProfile is not null and has profile image', () => { + it('renders no button with image if contactProfile is not null and has account image', () => { const mockContactProfile = { profileImage: 'https://example.com/client.png' }; const { queryByRole, queryByTestId } = render( - + ); const buttonElement = queryByRole('button'); expect(buttonElement).toBeNull(); diff --git a/test/components/Profile/ProfileInputField.test.jsx b/test/components/Account/AccountInputField.test.jsx similarity index 74% rename from test/components/Profile/ProfileInputField.test.jsx rename to test/components/Account/AccountInputField.test.jsx index 99eb8d65e..4992cc08c 100644 --- a/test/components/Profile/ProfileInputField.test.jsx +++ b/test/components/Account/AccountInputField.test.jsx @@ -1,16 +1,16 @@ import React, { useState } from 'react'; import { render } from '@testing-library/react'; import { describe, expect, it } from 'vitest'; -import { ProfileInputField } from '../../../src/components/Profile'; +import { AccountInputField } from '@components/Account'; import '@testing-library/jest-dom/extend-expect'; -const MockProfileComponent = ({ name }) => { +const MockAccountComponent = ({ name }) => { const mockInputName = 'Name'; const mockInputValue = name; const [, mockSetInputValue] = useState(''); const [mockEdit] = useState(false); return ( - { ); }; -describe('ProfileInputField', () => { - it('renders ProfileInputField with name Alice', () => { +describe('AccountInputField', () => { + it('renders AccountInputField with name Alice', () => { const mockInputValue = 'Alice'; - const { queryByRole } = render(); + const { queryByRole } = render(); const inputElement = queryByRole('textbox'); expect(inputElement).toBeInTheDocument(); @@ -31,9 +31,9 @@ describe('ProfileInputField', () => { expect(inputElement).toHaveAttribute('disabled'); }); - it('renders ProfileInputField with empty string and placeholder for "No value set" if inputValue is null', () => { + it('renders AccountInputField with empty string and placeholder for "No value set" if inputValue is null', () => { const mockInputValue = null; - const { queryByRole } = render(); + const { queryByRole } = render(); const inputElement = queryByRole('textbox'); expect(inputElement).toBeInTheDocument(); diff --git a/test/components/Messages/Inbox.test.jsx b/test/components/Messages/Inbox.test.jsx index c57842317..d5e1abb11 100644 --- a/test/components/Messages/Inbox.test.jsx +++ b/test/components/Messages/Inbox.test.jsx @@ -22,7 +22,7 @@ const MockInboxList = [ uploadDate: new Date('2023-10-23T19:59:31.424Z'), readStatus: false, sender: 'PODMAN', - senderWebId: 'http://localhost:3000/pod-test-name-here/profile/card#me', + senderWebId: 'http://localhost:3000/pod-test-name-here/account/card#me', recipient: 'PODMAN' }, { @@ -34,7 +34,7 @@ const MockInboxList = [ uploadDate: new Date('2023-10-23T19:59:31.424Z'), readStatus: true, sender: 'PODMAN', - senderWebId: 'http://localhost:3000/pod-test-name-here/profile/card#me', + senderWebId: 'http://localhost:3000/pod-test-name-here/account/card#me', recipient: 'PODMAN' } ]; @@ -49,7 +49,7 @@ const MockOutboxList = [ uploadDate: new Date('2023-10-23T19:59:31.424Z'), readStatus: true, sender: 'PODMAN', - senderWebId: 'http://localhost:3000/pod-test-name-here/profile/card#me', + senderWebId: 'http://localhost:3000/pod-test-name-here/account/card#me', recipient: 'PODMAN' } ]; @@ -104,7 +104,7 @@ describe('Messages Page', () => { session: { fetch: vi.fn(), info: { - webId: 'https://example.com/profile/', + webId: 'https://example.com/account/', isLoggedIn: true } } diff --git a/test/components/Messages/Outbox.test.jsx b/test/components/Messages/Outbox.test.jsx index f715d7a13..58dac3a9e 100644 --- a/test/components/Messages/Outbox.test.jsx +++ b/test/components/Messages/Outbox.test.jsx @@ -22,7 +22,7 @@ const MockInboxList = [ uploadDate: new Date('2023-10-23T19:59:31.424Z'), readStatus: false, sender: 'PODMAN', - senderWebId: 'http://localhost:3000/pod-test-name-here/profile/card#me', + senderWebId: 'http://localhost:3000/pod-test-name-here/account/card#me', recipient: 'PODMAN' }, { @@ -34,7 +34,7 @@ const MockInboxList = [ uploadDate: new Date('2023-10-23T19:59:31.424Z'), readStatus: true, sender: 'PODMAN', - senderWebId: 'http://localhost:3000/pod-test-name-here/profile/card#me', + senderWebId: 'http://localhost:3000/pod-test-name-here/account/card#me', recipient: 'PODMAN' } ]; @@ -49,7 +49,7 @@ const MockOutboxList = [ uploadDate: new Date('2023-10-23T19:59:31.424Z'), readStatus: true, sender: 'PODMAN', - senderWebId: 'http://localhost:3000/pod-test-name-here/profile/card#me', + senderWebId: 'http://localhost:3000/pod-test-name-here/account/card#me', recipient: 'PODMAN' } ]; @@ -104,7 +104,7 @@ describe('Messages Page', () => { session: { fetch: vi.fn(), info: { - webId: 'https://example.com/profile/', + webId: 'https://example.com/account/', isLoggedIn: true } } diff --git a/test/components/NavBar/NavMenu.test.jsx b/test/components/NavBar/NavMenu.test.jsx index 44d0e7ab6..5cecf7f9e 100644 --- a/test/components/NavBar/NavMenu.test.jsx +++ b/test/components/NavBar/NavMenu.test.jsx @@ -16,23 +16,23 @@ const MockNavMenu = () => ( ); -it('does not render contacts and civic profile links above 600px', () => { +it('does not render contacts and profile links above 600px', () => { const { queryByText } = render(); const contactsLink = queryByText('Contacts'); - const civicProfileLink = queryByText('Civic Profile'); + const profileLink = queryByText('Profile'); expect(contactsLink).toBeNull(); - expect(civicProfileLink).toBeNull(); + expect(profileLink).toBeNull(); }); -it('renders contacts and civic profile links below 600px', () => { +it('renders contacts and profile links below 600px', () => { window.matchMedia = createMatchMedia(599); const { queryByText } = render(); const contactsLink = queryByText('Contacts'); - const civicProfileLink = queryByText('Civic Profile'); + const profileLink = queryByText('Profile'); expect(contactsLink).not.toBeNull(); - expect(civicProfileLink).not.toBeNull(); + expect(profileLink).not.toBeNull(); }); diff --git a/test/components/CivicProfileForms/BasicInfo.test.jsx b/test/components/ProfileForms/BasicInfo.test.jsx similarity index 83% rename from test/components/CivicProfileForms/BasicInfo.test.jsx rename to test/components/ProfileForms/BasicInfo.test.jsx index bc70244c7..a9ec22fc0 100644 --- a/test/components/CivicProfileForms/BasicInfo.test.jsx +++ b/test/components/ProfileForms/BasicInfo.test.jsx @@ -1,7 +1,7 @@ import React from 'react'; import { render } from '@testing-library/react'; import { expect, it, describe } from 'vitest'; -import { BasicInfo } from '@components/CivicProfileForms'; +import { BasicInfo } from '@components/ProfileForms'; describe('Basic Info Form', () => { it('renders', () => { diff --git a/test/components/CivicProfileForms/FinancialInfo.test.jsx b/test/components/ProfileForms/FinancialInfo.test.jsx similarity index 82% rename from test/components/CivicProfileForms/FinancialInfo.test.jsx rename to test/components/ProfileForms/FinancialInfo.test.jsx index a4adf2e4d..b93f0a904 100644 --- a/test/components/CivicProfileForms/FinancialInfo.test.jsx +++ b/test/components/ProfileForms/FinancialInfo.test.jsx @@ -1,7 +1,7 @@ import React from 'react'; import { render } from '@testing-library/react'; import { expect, it, describe } from 'vitest'; -import { FinancialInfo } from '@components/CivicProfileForms'; +import { FinancialInfo } from '@components/ProfileForms'; describe('Financial Info Form', () => { it('renders', () => { diff --git a/test/components/CivicProfileForms/FormLayout.test.jsx b/test/components/ProfileForms/FormLayout.test.jsx similarity index 68% rename from test/components/CivicProfileForms/FormLayout.test.jsx rename to test/components/ProfileForms/FormLayout.test.jsx index 269072529..55b7519f9 100644 --- a/test/components/CivicProfileForms/FormLayout.test.jsx +++ b/test/components/ProfileForms/FormLayout.test.jsx @@ -2,7 +2,7 @@ import React from 'react'; import { render } from '@testing-library/react'; import { MemoryRouter as Router } from 'react-router-dom'; import { expect, it, describe } from 'vitest'; -import { FormLayout, CIVIC_FORM_LIST } from '@components/CivicProfileForms'; +import { FormLayout, PROFILE_FORM_LIST } from '@components/ProfileForms'; const renderLayout = (route) => render( @@ -11,27 +11,27 @@ const renderLayout = (route) => ); -describe('Civic Form Layout', () => { - it('creates a next button that navigates to the next element in the Civic list', () => { - const [firstRoute, secondRoute] = CIVIC_FORM_LIST; +describe('Profile Form Layout', () => { + it('creates a next button that navigates to the next element in the Profile list', () => { + const [firstRoute, secondRoute] = PROFILE_FORM_LIST; const { getByRole } = renderLayout(firstRoute.path); expect(getByRole('link').getAttribute('href')).toBe(`/${secondRoute.path}`); }); - it('creates a prev button that navigates to the previous element in the Civic list', () => { - const lastRoute = CIVIC_FORM_LIST[CIVIC_FORM_LIST.length - 1]; - const prevRoute = CIVIC_FORM_LIST[CIVIC_FORM_LIST.length - 2]; + it('creates a prev button that navigates to the previous element in the Profile list', () => { + const lastRoute = PROFILE_FORM_LIST[PROFILE_FORM_LIST.length - 1]; + const prevRoute = PROFILE_FORM_LIST[PROFILE_FORM_LIST.length - 2]; const { getByRole } = renderLayout(lastRoute.path); expect(getByRole('link').getAttribute('href')).toBe(`/${prevRoute.path}`); }); it('does not create a next button on the last page', () => { - const [firstRoute, secondRoute] = CIVIC_FORM_LIST; + const [firstRoute, secondRoute] = PROFILE_FORM_LIST; const { queryAllByRole } = renderLayout(firstRoute.path); expect(queryAllByRole('link').length).toEqual(1); expect(queryAllByRole('link')[0].getAttribute('href')).toBe(`/${secondRoute.path}`); }); it('does not create a prev button on the first page', () => { - const lastRoute = CIVIC_FORM_LIST[CIVIC_FORM_LIST.length - 1]; - const prevRoute = CIVIC_FORM_LIST[CIVIC_FORM_LIST.length - 2]; + const lastRoute = PROFILE_FORM_LIST[PROFILE_FORM_LIST.length - 1]; + const prevRoute = PROFILE_FORM_LIST[PROFILE_FORM_LIST.length - 2]; const { queryAllByRole } = renderLayout(lastRoute.path); expect(queryAllByRole('link').length).toEqual(1); expect(queryAllByRole('link')[0].getAttribute('href')).toBe(`/${prevRoute.path}`); diff --git a/test/components/CivicProfileForms/HousingInfo.test.jsx b/test/components/ProfileForms/HousingInfo.test.jsx similarity index 96% rename from test/components/CivicProfileForms/HousingInfo.test.jsx rename to test/components/ProfileForms/HousingInfo.test.jsx index 6bbf85adb..4c6fc2943 100644 --- a/test/components/CivicProfileForms/HousingInfo.test.jsx +++ b/test/components/ProfileForms/HousingInfo.test.jsx @@ -1,7 +1,7 @@ import React from 'react'; import { render } from '@testing-library/react'; import { vi, expect, it, describe } from 'vitest'; -import { HousingInfo } from '@components/CivicProfileForms'; +import { HousingInfo } from '@components/ProfileForms'; import { useCivicProfile } from '@hooks'; import userEvent from '@testing-library/user-event'; diff --git a/test/components/Signup/ShowNewPod.test.jsx b/test/components/Signup/ShowNewPod.test.jsx index a5609f248..8a7491773 100644 --- a/test/components/Signup/ShowNewPod.test.jsx +++ b/test/components/Signup/ShowNewPod.test.jsx @@ -12,7 +12,7 @@ vi.mock('react-router-dom', async () => { return { ...originalModule, - useSearchParams: () => [new URLSearchParams({ webId: 'https://example.com/profile' })] + useSearchParams: () => [new URLSearchParams({ webId: 'https://example.com/account' })] }; }); diff --git a/test/contexts/SignedInUserContext.test.jsx b/test/contexts/SignedInUserContext.test.jsx index 98b98a8b9..213f2f24c 100644 --- a/test/contexts/SignedInUserContext.test.jsx +++ b/test/contexts/SignedInUserContext.test.jsx @@ -53,7 +53,7 @@ describe('SignedInUserContext', () => { session: { info: { isLoggedIn: true, - webId: 'https://example.com/pod/profile/card#me' + webId: 'https://example.com/pod/account/card#me' } } }} diff --git a/test/hooks/useCivicProfile.test.jsx b/test/hooks/useCivicProfile.test.jsx index 58dbcbbd0..68453dfda 100644 --- a/test/hooks/useCivicProfile.test.jsx +++ b/test/hooks/useCivicProfile.test.jsx @@ -28,7 +28,7 @@ const queryClient = new QueryClient({ const sessionInfo = { session: { info: { - webId: 'https://example.com/profile' + webId: 'https://example.com/account' } } }; diff --git a/test/hooks/useContactsList.test.jsx b/test/hooks/useContactsList.test.jsx index 9087dcd31..119729065 100644 --- a/test/hooks/useContactsList.test.jsx +++ b/test/hooks/useContactsList.test.jsx @@ -28,7 +28,7 @@ const queryClient = new QueryClient({ const sessionInfo = { session: { info: { - webId: 'https://example.com/profile' + webId: 'https://example.com/account' } } }; diff --git a/test/hooks/useMessageList.test.jsx b/test/hooks/useMessageList.test.jsx index 53bcbdcef..9f0fca6b3 100644 --- a/test/hooks/useMessageList.test.jsx +++ b/test/hooks/useMessageList.test.jsx @@ -20,7 +20,7 @@ const sessionInfo = { session: { info: { isLoggedIn: true, - webId: 'https://example.com/test/profile/card#me' + webId: 'https://example.com/test/account/card#me' } } }; diff --git a/test/hooks/useRdfCollection.test.jsx b/test/hooks/useRdfCollection.test.jsx index 809572890..8ad349606 100644 --- a/test/hooks/useRdfCollection.test.jsx +++ b/test/hooks/useRdfCollection.test.jsx @@ -29,7 +29,7 @@ const queryClient = new QueryClient({ const sessionInfo = { session: { info: { - webId: 'http://example.com/profile' + webId: 'http://example.com/account' } } }; diff --git a/test/layouts/Layout.test.jsx b/test/layouts/Layout.test.jsx index caaea7198..a99a77ceb 100644 --- a/test/layouts/Layout.test.jsx +++ b/test/layouts/Layout.test.jsx @@ -31,7 +31,7 @@ describe('Desktop view', () => { session: { info: { isLoggedIn: true, - webId: 'https://example.com/pod/profile/card#me' + webId: 'https://example.com/pod/account/card#me' } } }} @@ -79,7 +79,7 @@ describe('Mobile view below 600px', () => { session: { info: { isLoggedIn: true, - webId: 'https://example.com/pod/profile/card#me' + webId: 'https://example.com/pod/account/card#me' } } }} diff --git a/test/model-helpers/Profile.test.js b/test/model-helpers/Profile.test.js index 8eb34db50..80a3944dc 100644 --- a/test/model-helpers/Profile.test.js +++ b/test/model-helpers/Profile.test.js @@ -9,7 +9,7 @@ import { import * as utils from '../../src/utils'; let session = {}; -const mockWebId = 'https://example.com/pod/profile/card#me'; +const mockWebId = 'https://example.com/pod/account/card#me'; vi.mock('@inrupt/solid-client'); @@ -40,7 +40,7 @@ describe('fetchProfileInfo', () => { } }, type: 'Subject', - url: 'https://example.com/pod/profile/card#me' + url: 'https://example.com/pod/account/card#me' }); vi.spyOn(solidClient, 'getSolidDataset').mockResolvedValue(); @@ -155,7 +155,7 @@ describe('uploadProfileImage', () => { }; const mockImageData = new Blob(new Array(9).fill(0), { type: 'image/png' }); const mockInputImage = new File([mockImageData], 'image.png', { type: 'image/png' }); - const mockFileResource = solidClient.mockFileFrom('https://example.com/pod/profile/image.png'); + const mockFileResource = solidClient.mockFileFrom('https://example.com/pod/account/image.png'); const mockFileResourceWithAcl = solidClient.addMockResourceAclTo(mockFileResource); vi.spyOn(solidClient, 'saveFileInContainer').mockResolvedValue(mockFileResource); @@ -224,7 +224,7 @@ describe('removeProfileImage', () => { const mockDatasetThing = solidClient.getThing(mockDataset, mockWebId); const mockData = { mockDataset, mockDatasetThing }; - vi.spyOn(solidClient, 'getUrl').mockReturnValue('https://example.com/pod/profile/image.png'); + vi.spyOn(solidClient, 'getUrl').mockReturnValue('https://example.com/pod/account/image.png'); vi.spyOn(solidClient, 'removeUrl').mockReturnThis(); vi.spyOn(solidClient, 'setThing').mockReturnThis(); vi.spyOn(solidClient, 'saveSolidDatasetAt'); diff --git a/test/pages/PersonalProfile.test.jsx b/test/pages/PersonalProfile.test.jsx deleted file mode 100644 index 876a10f16..000000000 --- a/test/pages/PersonalProfile.test.jsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react'; -import { render } from '@testing-library/react'; -import { BrowserRouter } from 'react-router-dom'; -import { expect, it, describe } from 'vitest'; -import { CivicProfile } from '@pages'; -import { CIVIC_FORM_LIST } from '@components/CivicProfileForms'; - -describe('Civic Profile', () => { - const numLinks = CIVIC_FORM_LIST.length; - - it('renders buttons for all forms in CIVIC_FORM_LIST', () => { - const { getByRole, getAllByRole } = render( - - - - ); - expect(getByRole('navigation')).not.toBeNull(); - expect(getAllByRole('link').length).toEqual(numLinks); - }); -}); diff --git a/test/pages/CivicProfile.test.jsx b/test/pages/Profile.test.jsx similarity index 94% rename from test/pages/CivicProfile.test.jsx rename to test/pages/Profile.test.jsx index cc729e24b..145e931d6 100644 --- a/test/pages/CivicProfile.test.jsx +++ b/test/pages/Profile.test.jsx @@ -2,13 +2,13 @@ import React from 'react'; import { BrowserRouter } from 'react-router-dom'; import { render } from '@testing-library/react'; import { expect, it } from 'vitest'; -import { CivicProfile } from '@pages'; +import { Profile } from '@pages'; import createMatchMedia from '../helpers/createMatchMedia'; it('renders page container flex direction as row and nav container width as 25% by default', () => { const component = render( - + ); @@ -26,7 +26,7 @@ it('renders page container flex direction as column and nav container width as 1 window.matchMedia = createMatchMedia(599); const component = render( - + ); diff --git a/test/pages/Signup.test.jsx b/test/pages/Signup.test.jsx index 230ef3cf8..970aa0774 100644 --- a/test/pages/Signup.test.jsx +++ b/test/pages/Signup.test.jsx @@ -14,7 +14,7 @@ vi.mock('react-router-dom', async () => { return { ...originalModule, - useSearchParams: () => [new URLSearchParams({ webId: 'https://example.com/profile' })] + useSearchParams: () => [new URLSearchParams({ webId: 'https://example.com/account' })] }; }); @@ -44,7 +44,7 @@ describe('Signup Page', () => { podUrl: 'https://example.com', session: { info: { - webId: 'https://example.com/profile/', + webId: 'https://example.com/account/', isLoggedIn: false } } @@ -59,7 +59,7 @@ describe('Signup Page', () => { podUrl: 'https://example.com', session: { info: { - webId: 'https://example.com/profile/', + webId: 'https://example.com/account/', isLoggedIn: false } } @@ -106,7 +106,7 @@ describe('Signup Page', () => { podUrl: 'https://example.com', session: { info: { - webId: 'https://example.com/profile/', + webId: 'https://example.com/account/', isLoggedIn: true } } diff --git a/test/utils/session-core.test.js b/test/utils/session-core.test.js index 88540ba0c..7960a71d5 100644 --- a/test/utils/session-core.test.js +++ b/test/utils/session-core.test.js @@ -28,7 +28,7 @@ describe('setDocContainerAclPermission', () => { it('runs setDocAclForUser with the correct inputs', async () => { const permissions = { read: true, append: true }; - const expectedWebId = 'https://pod2.example.com/profile/card#me'; + const expectedWebId = 'https://pod2.example.com/account/card#me'; const expectedContainerUrl = 'https://pod.example.com/PASS/Documents/';