diff --git a/src/features/profile/components/PageWrapper.tsx b/src/features/profile/components/PageWrapper.tsx new file mode 100644 index 0000000..629aff8 --- /dev/null +++ b/src/features/profile/components/PageWrapper.tsx @@ -0,0 +1,22 @@ +import { Box } from '@mui/material'; +import React from 'react'; + +interface PageWrapperProps { + children: React.ReactNode; +} + +export function PageWrapper({ children }: PageWrapperProps) { + return ( + + {children} + + ); +} diff --git a/src/features/profile/components/activeDevices/ActiveDevices.tsx b/src/features/profile/components/activeDevices/ActiveDevices.tsx index 0a19f38..941d3d7 100644 --- a/src/features/profile/components/activeDevices/ActiveDevices.tsx +++ b/src/features/profile/components/activeDevices/ActiveDevices.tsx @@ -3,6 +3,7 @@ import { useTranslation } from 'react-i18next'; import { DeviceMessage, Logout } from 'iconsax-react'; import Logo from '@/components/Logo'; import { CardContainer } from '@/components/CardContainer'; +import { PageWrapper } from '../PageWrapper'; export function ActiveDevices() { const { t } = useTranslation('activeDevices'); @@ -39,25 +40,13 @@ export function ActiveDevices() { ]; return ( - - + + + + {t('active.deletDevicesButton')} @@ -82,111 +71,125 @@ export function ActiveDevices() { py: 2, display: 'flex', flexDirection: 'column', - gap: 2, - flex: 1, + // gap: 2, }} > - - {devices.map((device) => ( + {devices.map((device) => ( + + + {device.timeAndDate} + + - - {device.timeAndDate} + + + {device.deviceModel} - - - - {device.deviceModel} - - - - {device.ip} - - - {device.current && ( - - )} - - + + + + {device.ip} + + + + {device.current && ( - + )} - ))} - + + + + + + ))} - + ); } diff --git a/src/features/profile/components/security/PasswordSecurity.tsx b/src/features/profile/components/security/PasswordSecurity.tsx index d8daf3d..4c65dd5 100644 --- a/src/features/profile/components/security/PasswordSecurity.tsx +++ b/src/features/profile/components/security/PasswordSecurity.tsx @@ -19,6 +19,7 @@ import { PasswordValidationItem } from './PasswordValidation'; import { Toast } from '@/components/Toast'; import Logo from '@/components/Logo'; import { CardContainer } from '@/components/CardContainer'; +import { PageWrapper } from '../PageWrapper'; export function PasswordSecurity() { const theme = useTheme(); @@ -70,14 +71,7 @@ export function PasswordSecurity() { }, [password, validPassword]); return ( - + @@ -148,7 +142,6 @@ export function PasswordSecurity() { )} - setPassword(e.target.value)} sx={{ '& .MuiOutlinedInput-root': { borderRadius: 2 } }} /> - {password && showValidation && ( @@ -221,7 +213,6 @@ export function PasswordSecurity() { )} - - {password && showValidation && ( @@ -280,7 +270,6 @@ export function PasswordSecurity() { )} - - - + ); } diff --git a/src/features/profile/components/security/RecentLogins.tsx b/src/features/profile/components/security/RecentLogins.tsx index 4341624..69911a1 100644 --- a/src/features/profile/components/security/RecentLogins.tsx +++ b/src/features/profile/components/security/RecentLogins.tsx @@ -1,6 +1,7 @@ import { Box, Typography, Button } from '@mui/material'; import { useTranslation } from 'react-i18next'; import { CardContainer } from '@/components/CardContainer'; +import { PageWrapper } from '../PageWrapper'; export function RecentLogins() { const { t } = useTranslation('security'); @@ -22,27 +23,25 @@ export function RecentLogins() { ]; return ( - + @@ -50,31 +49,54 @@ export function RecentLogins() { {d.time} {d.device} {d.ip} - + {d.current && ( + )} - )} - - - } - > - + } > - - {isEditing ? ( - - {t('settings.theme')} - - - ) : ( - - - {t('settings.theme')} - - - {mode === 'light' - ? t('settings.light') - : t('settings.dark')} - - - )} + + + {isEditing ? ( + + + {t('settings.theme')} + + + + ) : ( + + + {t('settings.theme')} + + + {mode === 'light' + ? t('settings.light') + : t('settings.dark')} + + + )} + + + {isEditing ? ( + o.label} + value={ + languageOptions.find((o) => o.code === draftLanguage) || + null + } + onChange={handleDraftLanguageChange} + renderInput={(p) => ( + + )} + size="medium" + fullWidth + /> + ) : ( + + + {t('settings.language')} + + + { + languageOptions.find((o) => o.code === savedLanguage) + ?.label + } + + + )} + - + {isEditing ? ( o.label} - value={ - languageOptions.find((o) => o.code === draftLanguage) || - null - } - onChange={handleDraftLanguageChange} + options={calendarOptions} + value={selectedCalendar} + onChange={(_, v) => v && setSelectedCalendar(v)} renderInput={(p) => ( - + )} size="medium" fullWidth @@ -171,41 +202,15 @@ export function Setting() { ) : ( - {t('settings.language')} - - - { - languageOptions.find((o) => o.code === savedLanguage) - ?.label - } + {t('settings.calendar')} + {selectedCalendar} )} - - {isEditing ? ( - v && setSelectedCalendar(v)} - renderInput={(p) => ( - - )} - size="medium" - fullWidth - /> - ) : ( - - - {t('settings.calendar')} - - {selectedCalendar} - - )} - - - - + + + ); } diff --git a/src/features/profile/components/userInformation/PersonalInformation.tsx b/src/features/profile/components/userInformation/PersonalInformation.tsx index 4e35d18..80a531d 100644 --- a/src/features/profile/components/userInformation/PersonalInformation.tsx +++ b/src/features/profile/components/userInformation/PersonalInformation.tsx @@ -6,6 +6,7 @@ import { ProfileImage } from './personlInformation/ProfileImage'; import { InfoRowDisplay } from './personlInformation/InfoRowDisplay'; import { InfoRowEdit } from './personlInformation/InfoRowEdit'; import Logo from '@/components/Logo'; +import { PageWrapper } from '../PageWrapper'; export function PersonalInformation() { const { t } = useTranslation('profileSetting'); @@ -39,7 +40,7 @@ export function PersonalInformation() { }; return ( - + - + ); } diff --git a/src/features/profile/components/userInformation/PhoneNumber.tsx b/src/features/profile/components/userInformation/PhoneNumber.tsx index b2971e7..2c986f0 100644 --- a/src/features/profile/components/userInformation/PhoneNumber.tsx +++ b/src/features/profile/components/userInformation/PhoneNumber.tsx @@ -1,10 +1,11 @@ -import React, { useState, type ChangeEvent } from 'react'; +import { useState, type ChangeEvent } from 'react'; import { Box, Typography, Button, TextField, IconButton } from '@mui/material'; import { Edit, Refresh, TickCircle } from 'iconsax-react'; import { useTranslation } from 'react-i18next'; import { CardContainer } from '@/components/CardContainer'; import { CountDownTimer } from '@/components/CountDownTimer'; import { Toast } from '@/components/Toast'; +import { PageWrapper } from '../PageWrapper'; export function PhoneNumber() { const { t } = useTranslation('profileSetting'); @@ -72,7 +73,7 @@ export function PhoneNumber() { }; return ( - + )} - + ); } diff --git a/src/features/profile/components/userInformation/SocialMedia.tsx b/src/features/profile/components/userInformation/SocialMedia.tsx index 4bc6b1a..7882a6f 100644 --- a/src/features/profile/components/userInformation/SocialMedia.tsx +++ b/src/features/profile/components/userInformation/SocialMedia.tsx @@ -14,6 +14,8 @@ import { ListItemText, useMediaQuery, } from '@mui/material'; +import Slide from '@mui/material/Slide'; +import type { TransitionProps } from '@mui/material/transitions'; import type { Theme } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { CardContainer } from '@/components/CardContainer'; @@ -27,17 +29,34 @@ import { Message, ArrowDown3, } from 'iconsax-react'; +import { PageWrapper } from '../PageWrapper'; + +const MobileSlide = React.forwardRef(function MobileSlide( + props: TransitionProps & { children: React.ReactElement }, + ref: React.Ref, +) { + return ; +}); export function SocialMedia() { const { t } = useTranslation('profileSetting'); + const [openDialog, setOpenDialog] = useState(false); const [emailInput, setEmailInput] = useState(''); const [emailError, setEmailError] = useState(false); const [anchor, setAnchor] = useState(null); + const openMenu = Boolean(anchor); const fullScreen = useMediaQuery((theme: Theme) => theme.breakpoints.down('sm'), ); + const downMd = useMediaQuery((theme: Theme) => theme.breakpoints.down('md')); + const computedMaxWidth = (fullScreen ? 'xs' : downMd ? 'sm' : 'md') as + | 'xs' + | 'sm' + | 'md' + | 'lg' + | 'xl'; const handleOpenDialog = () => setOpenDialog(true); const handleCloseDialog = () => setOpenDialog(false); @@ -59,7 +78,7 @@ export function SocialMedia() { ] as const; return ( - + - + @@ -207,10 +226,18 @@ export function SocialMedia() { open={openDialog} onClose={handleCloseDialog} fullWidth - maxWidth="xs" fullScreen={fullScreen} - sx={{ - '& .MuiDialog-paper': { m: { xs: 1, sm: 'auto' }, borderRadius: 2 }, + maxWidth={computedMaxWidth} + scroll="paper" + keepMounted + TransitionComponent={fullScreen ? MobileSlide : undefined} + PaperProps={{ + sx: { + m: { xs: 0, sm: 2 }, + borderRadius: { xs: 0, sm: 2 }, + width: { xs: '100%', sm: 'auto' }, + height: { xs: '100%', sm: 'auto' }, + }, }} > - + {t('settingForm.addEmailButton')} - + + + + {t('settingForm.newEmail')} + + + {t('settingForm.dialogHeader')} + + + + + + + + + + + {t('settingForm.or')} + + + + - - - {t('settingForm.newEmail')} - - - {t('settingForm.dialogHeader')} - - - - - - - - - - {t('settingForm.or')} - - - - - - - - + + {t('settingForm.google')} + + - + ); } diff --git a/src/features/profile/routes/SettingPage.tsx b/src/features/profile/routes/SettingPage.tsx index 3a1ccbb..895b0e7 100644 --- a/src/features/profile/routes/SettingPage.tsx +++ b/src/features/profile/routes/SettingPage.tsx @@ -1,3 +1,4 @@ +import React, { useState } from 'react'; import { createBrowserRouter, RouterProvider, @@ -18,7 +19,16 @@ import { Sms, Menu, } from 'iconsax-react'; -import { Box, Typography, useTheme, useMediaQuery } from '@mui/material'; +import { + Box, + Typography, + useTheme, + useMediaQuery, + Drawer, + AppBar, + Toolbar, + IconButton, +} from '@mui/material'; import { useTranslation } from 'react-i18next'; import { ActiveDevices } from '../components/activeDevices/ActiveDevices'; @@ -58,19 +68,17 @@ export function Layout() { const isMdUp = useMediaQuery(theme.breakpoints.up('md')); const location = useLocation(); const { t } = useTranslation('sideMap'); + const [drawerOpen, setDrawerOpen] = useState(false); - const drawerWidth = 274; - const minimizedWidth = 64; - const navWidth = isMdUp ? drawerWidth : minimizedWidth; - const contentWidth = 810; - const contentHeight = '78vh'; - const totalWidth = navWidth + contentWidth; + const contentMaxWidth = '100%'; + const contentWidthMd = '810px'; + const navWidthMd = '274px'; const navConfig: NavItemConfig[] = [ { text: t('side.account'), - getIcon: (isSelected) => - isSelected ? ( + getIcon: (sel) => + sel ? ( ) : ( @@ -79,8 +87,8 @@ export function Layout() { children: [ { text: t('side.personalInfo'), - getIcon: (isSelected) => - isSelected ? ( + getIcon: (sel) => + sel ? ( ) : ( @@ -89,8 +97,8 @@ export function Layout() { }, { text: t('side.phoneNumber'), - getIcon: (isSelected) => - isSelected ? ( + getIcon: (sel) => + sel ? ( ) : ( @@ -99,8 +107,8 @@ export function Layout() { }, { text: t('side.email'), - getIcon: (isSelected) => - isSelected ? ( + getIcon: (sel) => + sel ? ( ) : ( @@ -111,8 +119,8 @@ export function Layout() { }, { text: t('side.security'), - getIcon: (isSelected) => - isSelected ? ( + getIcon: (sel) => + sel ? ( ) : ( @@ -121,8 +129,8 @@ export function Layout() { children: [ { text: t('side.password'), - getIcon: (isSelected) => - isSelected ? ( + getIcon: (sel) => + sel ? ( ) : ( @@ -131,8 +139,8 @@ export function Layout() { }, { text: t('side.verifiedAddress'), - getIcon: (isSelected) => - isSelected ? ( + getIcon: (sel) => + sel ? ( ) : ( @@ -141,8 +149,8 @@ export function Layout() { }, { text: t('side.recentLogins'), - getIcon: (isSelected) => - isSelected ? ( + getIcon: (sel) => + sel ? ( ) : ( @@ -153,8 +161,8 @@ export function Layout() { }, { text: t('side.activeDevices'), - getIcon: (isSelected) => - isSelected ? ( + getIcon: (sel) => + sel ? ( ) : ( @@ -163,8 +171,8 @@ export function Layout() { }, { text: t('side.settings'), - getIcon: (isSelected) => - isSelected ? ( + getIcon: (sel) => + sel ? ( ) : ( @@ -177,43 +185,66 @@ export function Layout() { - - - + {!isMdUp && ( + + + setDrawerOpen(true)} + > + + + + + )} + + {isMdUp && ( + : } + header={
} activePath={location.pathname + location.hash} - sideNavVariant={isMdUp ? 'full' : 'minimized'} + sideNavVariant="full" positioning="absolute" - // drawerWidth={drawerWidth} - // minimizedWidth={minimizedWidth} /> - - - + )} + + + {!isMdUp && ( + setDrawerOpen(false)} + > + + } + activePath={location.pathname + location.hash} + sideNavVariant="full" + /> + + + )} ); } @@ -227,16 +258,7 @@ const router = createBrowserRouter([ { path: '/profile', element: ( - +
@@ -252,15 +274,7 @@ const router = createBrowserRouter([ { path: '/security', element: ( - +
@@ -271,22 +285,8 @@ const router = createBrowserRouter([
), }, - { - path: '/devices', - element: ( - - - - ), - }, - { - path: '/setting', - element: ( - - - - ), - }, + { path: '/devices', element: }, + { path: '/setting', element: }, ], }, ]);