From fcf56dffc75ef385c025b2a744be59a5bd7fb5ea Mon Sep 17 00:00:00 2001 From: Sajad Mirjalili Date: Mon, 29 Sep 2025 11:47:11 +0330 Subject: [PATCH 01/15] fix: loading only outlet instead of whole page for child subroutes --- src/components/layout/Layout.tsx | 7 +++++-- src/components/layout/type.ts | 0 src/routes/index.tsx | 15 ++++----------- 3 files changed, 9 insertions(+), 13 deletions(-) delete mode 100644 src/components/layout/type.ts diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx index befcc88..3e02947 100644 --- a/src/components/layout/Layout.tsx +++ b/src/components/layout/Layout.tsx @@ -4,9 +4,10 @@ import { appRoutes } from '@/routes/config'; import { Outlet, useLocation } from 'react-router-dom'; import { Box, useMediaQuery, useTheme } from '@mui/material'; import { Header } from './Header'; -import { useState } from 'react'; +import { Suspense, useState } from 'react'; import { Toolbar } from './Toolbar'; import { useAuth } from '@/hooks/useAuth'; +import { Loading } from '../routes/Loading'; export const Layout = () => { const navItemConfigs = buildNavItems(appRoutes); @@ -53,7 +54,9 @@ export const Layout = () => { overflowInline: 'auto', }} > - + }> + + diff --git a/src/components/layout/type.ts b/src/components/layout/type.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 43888d8..ef190b8 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -1,8 +1,7 @@ -import { Suspense, type ReactNode } from 'react'; +import { type ReactNode } from 'react'; import { createBrowserRouter, type RouteObject } from 'react-router-dom'; import { appRoutes, type RouteConfig } from './config'; import { ProtectedRoute } from '@/components/routes/ProtectedRoute'; -import { Loading } from '@/components/routes/Loading'; /** * A recursive function to map our custom route config to the format @@ -10,15 +9,9 @@ import { Loading } from '@/components/routes/Loading'; */ function mapRoutes(routes: RouteConfig[]): RouteObject[] { return routes.map((route) => { - // Start with the base element, wrapped in Suspense for lazy loading - let element: ReactNode = ( - }>{route.element} - ); - - // Conditionally wrap the element in the specified layout - // if (route.layout) { - // element = {element}; - // } + // Remove the suspense from here and move to layout outlet + // Avoid loading layout for rendering different children + let element: ReactNode = route.element; if (route.authorize) { element = {element}; From d8f58ad13d6a43190245fa02ee1ae1eaeea8e6fb Mon Sep 17 00:00:00 2001 From: Sajad Mirjalili Date: Mon, 29 Sep 2025 12:03:02 +0330 Subject: [PATCH 02/15] fix: forget password typos, submit with enter --- .../ForgetPassword/ChangePassword.tsx | 12 +++--- .../ForgetPasswordContainer.tsx | 15 ++++--- ...asswordInfo.tsx => ForgetPasswordInfo.tsx} | 39 +++++++++---------- .../ForgetPassword/ForgetPasswordOtp.tsx | 18 ++++----- 4 files changed, 38 insertions(+), 46 deletions(-) rename src/features/authentication/components/ForgetPassword/{ForgettedPasswordInfo.tsx => ForgetPasswordInfo.tsx} (82%) diff --git a/src/features/authentication/components/ForgetPassword/ChangePassword.tsx b/src/features/authentication/components/ForgetPassword/ChangePassword.tsx index 1a10ecc..65df75a 100644 --- a/src/features/authentication/components/ForgetPassword/ChangePassword.tsx +++ b/src/features/authentication/components/ForgetPassword/ChangePassword.tsx @@ -24,7 +24,7 @@ import { useApi } from '@/hooks/useApi'; export interface ChangePasswordProps { onEditInfo: () => void; onPasswordChanged: () => void; - forgettedPasswordInfo: string; + forgetPasswordInfo: string; infoType: AuthType; countryCode: CountryCode; } @@ -32,7 +32,7 @@ export interface ChangePasswordProps { export const ChangePassword = ({ onEditInfo, onPasswordChanged, - forgettedPasswordInfo, + forgetPasswordInfo, infoType, countryCode, }: ChangePasswordProps) => { @@ -78,11 +78,9 @@ export const ChangePassword = ({ confirmInputRef.current?.focus(); } else { const apiRequest: ResetPasswordRequest = { - email: infoType === 'email' ? forgettedPasswordInfo : undefined, + email: infoType === 'email' ? forgetPasswordInfo : undefined, phoneNumber: - infoType === 'phone' - ? countryCode + forgettedPasswordInfo - : undefined, + infoType === 'phone' ? countryCode + forgetPasswordInfo : undefined, newPassword: passValue, confirmNewPassword: confirmPassValue, }; @@ -138,7 +136,7 @@ export const ChangePassword = ({ endIcon={} onClick={onEditInfo} > - {forgettedPasswordInfo} + {forgetPasswordInfo} diff --git a/src/features/authentication/components/ForgetPassword/ForgetPasswordContainer.tsx b/src/features/authentication/components/ForgetPassword/ForgetPasswordContainer.tsx index f605884..ebb8c95 100644 --- a/src/features/authentication/components/ForgetPassword/ForgetPasswordContainer.tsx +++ b/src/features/authentication/components/ForgetPassword/ForgetPasswordContainer.tsx @@ -1,6 +1,6 @@ import { useState } from 'react'; import type { AuthType } from '../../types/authTypes'; -import { ForgettedPasswordInfo } from './ForgettedPasswordInfo'; +import { ForgetPasswordInfo } from './ForgetPasswordInfo'; import { ForgetPasswordOtp } from './ForgetPasswordOtp'; import { ChangePassword } from './ChangePassword'; import type { CountryCode } from '@/types/commonTypes'; @@ -11,8 +11,7 @@ export const ForgetPasswordContainer = () => { const [forgetPassCurrentStep, setForgetPassCurrentStep] = useState< 'enterInfo' | 'verifyOtp' | 'setPassword' >('enterInfo'); - const [forgettedPasswordInfo, setForgettedPasswordInfo] = - useState(''); + const [forgetPasswordInfo, setForgetPasswordInfo] = useState(''); const [infoCountryCode, setInfoCountryCode] = useState('+98'); const [infoType, setInfoType] = useState('email'); @@ -35,11 +34,11 @@ export const ForgetPasswordContainer = () => { return ( <> {forgetPassCurrentStep === 'enterInfo' && ( - { countryCode={infoCountryCode} infoType={infoType} onEditInfo={handleEditInfo} - forgettedPasswordInfo={forgettedPasswordInfo} + forgetPasswordInfo={forgetPasswordInfo} onOTPVerified={handleOtpVerified} /> )} @@ -59,7 +58,7 @@ export const ForgetPasswordContainer = () => { {forgetPassCurrentStep === 'setPassword' && ( ; +export interface ForgetPasswordInfoProps { + forgetPasswordInfo: string; + setForgetPasswordInfo: Dispatch; infoType: AuthType; setInfoType: Dispatch; onVerifyOtp: (value: string) => void; @@ -24,15 +24,15 @@ export interface ForgettedPasswordInfoProps { setCountryCode: Dispatch; } -export function ForgettedPasswordInfo({ - forgettedPasswordInfo, - setForgettedPasswordInfo, +export function ForgetPasswordInfo({ + forgetPasswordInfo, + setForgetPasswordInfo, infoType, setInfoType, onVerifyOtp, countryCode, setCountryCode, -}: ForgettedPasswordInfoProps) { +}: ForgetPasswordInfoProps) { const { t } = useTranslation('authentication'); const textFieldRef = useRef(null); const inputRef = useRef(null); @@ -51,7 +51,7 @@ export function ForgettedPasswordInfo({ if (newValue.startsWith('09')) { newValue = newValue.substring(1); } - setForgettedPasswordInfo(newValue); + setForgetPasswordInfo(newValue); // If the new value contains only digits (or is empty), it's a phone number if (isNumeric(newValue)) { @@ -63,7 +63,7 @@ export function ForgettedPasswordInfo({ const handleBlur = () => { setTouched(true); - validateInput(forgettedPasswordInfo, infoType); + validateInput(forgetPasswordInfo, infoType); }; const validateInput = ( @@ -87,13 +87,11 @@ export function ForgettedPasswordInfo({ }; const handleSubmit = async () => { - if (validateInput(forgettedPasswordInfo, infoType, false)) { + if (validateInput(forgetPasswordInfo, infoType, false)) { const sendCodeRequest: SendForgetPassCodeRequest = { - email: infoType === 'email' ? forgettedPasswordInfo : undefined, + email: infoType === 'email' ? forgetPasswordInfo : undefined, phoneNumber: - infoType === 'phone' - ? countryCode + forgettedPasswordInfo - : undefined, + infoType === 'phone' ? countryCode + forgetPasswordInfo : undefined, }; const res = await sendForgetPassCodeCall(sendCodeRequest); @@ -106,19 +104,18 @@ export function ForgettedPasswordInfo({ }); } - onVerifyOtp(forgettedPasswordInfo); + onVerifyOtp(forgetPasswordInfo); } else { inputRef.current?.focus(); - validateInput(forgettedPasswordInfo, infoType); + validateInput(forgetPasswordInfo, infoType); } }; - const showAdornment = - infoType === 'phone' && forgettedPasswordInfo.length > 0; + const showAdornment = infoType === 'phone' && forgetPasswordInfo.length > 0; return ( - + {t('forgetPassword.forgetPassword')} @@ -133,7 +130,7 @@ export function ForgettedPasswordInfo({ ref={textFieldRef} inputRef={inputRef} label={t('loginForm.emailOrPhoneLabel')} - value={forgettedPasswordInfo} + value={forgetPasswordInfo} onChange={handleInputChange} onBlur={handleBlur} error={inputError} @@ -157,7 +154,7 @@ export function ForgettedPasswordInfo({ /> - diff --git a/src/features/authentication/components/ForgetPassword/ForgetPasswordOtp.tsx b/src/features/authentication/components/ForgetPassword/ForgetPasswordOtp.tsx index d914114..705e718 100644 --- a/src/features/authentication/components/ForgetPassword/ForgetPasswordOtp.tsx +++ b/src/features/authentication/components/ForgetPassword/ForgetPasswordOtp.tsx @@ -18,7 +18,7 @@ import { Icon, useToast } from '@rkheftan/harmony-ui'; import { useApi } from '@/hooks/useApi'; interface ForgetPasswordOtpProps { - forgettedPasswordInfo: string; + forgetPasswordInfo: string; infoType: AuthType; countryCode: CountryCode; onEditInfo: () => void; @@ -26,7 +26,7 @@ interface ForgetPasswordOtpProps { } export function ForgetPasswordOtp({ - forgettedPasswordInfo, + forgetPasswordInfo, infoType, countryCode, onEditInfo, @@ -69,9 +69,9 @@ export function ForgetPasswordOtp({ const handleResendOTPCode = async () => { const sendCodeRequest: SendForgetPassCodeRequest = { - email: infoType === 'email' ? forgettedPasswordInfo : undefined, + email: infoType === 'email' ? forgetPasswordInfo : undefined, phoneNumber: - infoType === 'phone' ? countryCode + forgettedPasswordInfo : undefined, + infoType === 'phone' ? countryCode + forgetPasswordInfo : undefined, }; await sendForgetPassCodeCall(sendCodeRequest); @@ -93,11 +93,9 @@ export function ForgetPasswordOtp({ // Change setTimeout to api call const apiRequest: ConfirmForgetPassCodeRequest = { - email: infoType === 'email' ? forgettedPasswordInfo : undefined, + email: infoType === 'email' ? forgetPasswordInfo : undefined, phoneNumber: - infoType === 'phone' - ? countryCode + forgettedPasswordInfo - : undefined, + infoType === 'phone' ? countryCode + forgetPasswordInfo : undefined, code: otpCode, }; @@ -153,8 +151,8 @@ export function ForgetPasswordOtp({ onClick={onEditInfo} > {infoType === 'phone' - ? countryCode + forgettedPasswordInfo - : forgettedPasswordInfo} + ? countryCode + forgetPasswordInfo + : forgetPasswordInfo} From e3fe01b9c3f1bbed4085e22a3db06f11e3a6058e Mon Sep 17 00:00:00 2001 From: Sajad Mirjalili Date: Mon, 29 Sep 2025 12:09:51 +0330 Subject: [PATCH 03/15] fix: settings defualt values --- public/locales/en/setting.json | 3 +-- public/locales/fa/setting.json | 3 +-- src/features/profile/routes/SettingPage.tsx | 13 ++++++------- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/public/locales/en/setting.json b/public/locales/en/setting.json index cf75b15..87ab0d2 100644 --- a/public/locales/en/setting.json +++ b/public/locales/en/setting.json @@ -100,8 +100,7 @@ "dark": "Dark", "language": "زبان/language", "calendar": "Calendar and date format", - "solar": "Solar", - "lunar": "Lunar", + "jalali": "jalali", "christian": "Christian", "iran": "Iran", "saving": "Saving...", diff --git a/public/locales/fa/setting.json b/public/locales/fa/setting.json index 20c8cdd..3cd7f03 100644 --- a/public/locales/fa/setting.json +++ b/public/locales/fa/setting.json @@ -100,8 +100,7 @@ "dark": "تاریک", "language": "زبان/language", "calendar": "فرمت تقویم و تاریخ", - "solar": "شمسی", - "lunar": "قمری", + "jalali": "شمسی", "christian": "میلادی", "iran": "ایران", "saving": "در حال ذخیره‌سازی...", diff --git a/src/features/profile/routes/SettingPage.tsx b/src/features/profile/routes/SettingPage.tsx index 034e1c4..6318944 100644 --- a/src/features/profile/routes/SettingPage.tsx +++ b/src/features/profile/routes/SettingPage.tsx @@ -19,7 +19,7 @@ import { saveSettings } from '../api/settingsApi'; import { useProfile } from '../hooks/useProfile'; type ThemeMode = 'light' | 'dark'; -type CalendarType = 'christian' | 'solar' | 'lunar'; +type CalendarType = 'christian' | 'jalali'; interface SettingsState { language: string; @@ -33,9 +33,8 @@ const languageOptions = [ ]; const calendarOptions: { key: CalendarType; apiValue: number }[] = [ - { key: 'christian', apiValue: 1 }, - { key: 'solar', apiValue: 2 }, - { key: 'lunar', apiValue: 3 }, + { key: 'jalali', apiValue: 1 }, + { key: 'christian', apiValue: 2 }, ]; const themeApiMap: Record = { light: 1, dark: 2 }; @@ -46,7 +45,7 @@ export function SettingPage() { const [savedSettings, setSavedSettings] = useState({ language: i18n.language, - calendar: 'solar', + calendar: 'jalali', theme: mode === 'light' || mode === 'dark' ? mode : 'light', }); const [draftSettings, setDraftSettings] = @@ -78,9 +77,9 @@ export function SettingPage() { theme: themeReverseMap[theme] || 'light', calendar: calendarOptions.find((c) => c.apiValue === calendarType)?.key || - 'solar', + 'jalali', language: - languageOptions.find((l) => l.apiValue === language)?.code || 'en', + languageOptions.find((l) => l.apiValue === language)?.code || 'fa', }; setSavedSettings(newSettings); setDraftSettings(newSettings); From 4a420da4520727ed47bc34387d9cc455d34fcdb5 Mon Sep 17 00:00:00 2001 From: Sajad Mirjalili Date: Mon, 29 Sep 2025 13:47:45 +0330 Subject: [PATCH 04/15] fix: account active sessions styles --- .../profile/routes/ActiveDevicesPage.tsx | 145 +++++++----------- 1 file changed, 58 insertions(+), 87 deletions(-) diff --git a/src/features/profile/routes/ActiveDevicesPage.tsx b/src/features/profile/routes/ActiveDevicesPage.tsx index b5fc335..037f2d8 100644 --- a/src/features/profile/routes/ActiveDevicesPage.tsx +++ b/src/features/profile/routes/ActiveDevicesPage.tsx @@ -1,11 +1,10 @@ -import React, { useState, useEffect } from 'react'; +import { useState, useEffect } from 'react'; import { Box, Typography, Button, - useTheme, - useMediaQuery, CircularProgress, + Stack, } from '@mui/material'; import { useTranslation } from 'react-i18next'; import { DeviceMessage, Logout } from 'iconsax-react'; @@ -24,8 +23,6 @@ export function ActiveDevicesPage() { const { t, i18n } = useTranslation('setting'); const [devices, setDevices] = useState([]); const [loadingDeleteIds, setLoadingDeleteIds] = useState([]); - const theme = useTheme(); - const isXsup = useMediaQuery(theme.breakpoints.up('xs')); const showToast = useToast(); const { isLoadingProfile, refetchProfile } = useProfile(); @@ -132,7 +129,9 @@ export function ActiveDevicesPage() { flexGrow: 0, width: 'auto', }} - disabled={isLoadingProfile || isTerminating} + disabled={ + isLoadingProfile || isTerminating || devices.length === 1 + } > {isTerminating ? t('active.deleting') @@ -158,20 +157,23 @@ export function ActiveDevicesPage() { sx={{ mx: { xs: 2, sm: 3, md: 4 }, py: 2, - display: 'flex', - flexDirection: 'column', - gap: 2, bgcolor: 'background.paper', }} > {devices.map((device) => ( - + @@ -217,85 +219,54 @@ export function ActiveDevicesPage() { > {device.ip} - - - {device.current && ( - - )} - - - - - - {isXsup && ( - + {device.current && ( + )} - + + {!device.current && ( + + )} + ))} )} From 9a75e599e217fefa36818fc711eb1076f6a60223 Mon Sep 17 00:00:00 2001 From: Sajad Mirjalili Date: Mon, 29 Sep 2025 15:51:28 +0330 Subject: [PATCH 05/15] fix: farsi digits and autofoucs in digits input --- src/components/DigitsInput.tsx | 4 ++++ .../AuthenticationSteps/LoginRegiserForm.tsx | 21 ++++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/components/DigitsInput.tsx b/src/components/DigitsInput.tsx index c133ace..bb90c61 100644 --- a/src/components/DigitsInput.tsx +++ b/src/components/DigitsInput.tsx @@ -8,6 +8,7 @@ import React, { } from 'react'; import { TextField, Stack } from '@mui/material'; import { useTranslation } from 'react-i18next'; +import { replacePersianWithRealNumbers } from '@/utils/replacePersianWithRealNumbers'; interface DigitInputProps { error: boolean; @@ -34,6 +35,8 @@ const DigitInput: React.FC = ({ }; const handleChange = (value: string, index: number) => { + value = replacePersianWithRealNumbers(value); + if (!/^\d$/.test(value) && value !== '') return; const newCode = [...code]; @@ -91,6 +94,7 @@ const DigitInput: React.FC = ({ color={success ? 'success' : 'primary'} key={index} inputRef={(el) => (inputRefs.current[index] = el)} + autoFocus={index === 0} value={digit} onChange={(e) => handleChange(e.target.value, index)} onKeyDown={(e) => e.key === 'Backspace' && handleBackspace(e, index)} diff --git a/src/features/authentication/components/AuthenticationSteps/LoginRegiserForm.tsx b/src/features/authentication/components/AuthenticationSteps/LoginRegiserForm.tsx index eba878f..5a7e42b 100644 --- a/src/features/authentication/components/AuthenticationSteps/LoginRegiserForm.tsx +++ b/src/features/authentication/components/AuthenticationSteps/LoginRegiserForm.tsx @@ -67,9 +67,6 @@ export function LoginRegisterForm({ const handleInputChange = (event: React.ChangeEvent) => { let newValue = event.target.value; newValue = replacePersianWithRealNumbers(newValue); - if (newValue.startsWith('09')) { - newValue = newValue.substring(1); - } setLoginRegisterValue(newValue); @@ -112,10 +109,20 @@ export function LoginRegisterForm({ const handleSubmit = async () => { if (validateInput(loginRegisterValue, authType, false)) { + let newValue = loginRegisterValue; + + if ( + authType === 'phone' && + countryCode === '+98' && + newValue.startsWith('09') + ) { + newValue = newValue.substring(1); + setLoginRegisterValue(newValue); + } + const res = await execUserStatus({ - phoneNumber: - authType === 'phone' ? countryCode + loginRegisterValue : undefined, - email: authType === 'email' ? loginRegisterValue : undefined, + phoneNumber: authType === 'phone' ? countryCode + newValue : undefined, + email: authType === 'email' ? newValue : undefined, }); if (!res) { @@ -123,7 +130,7 @@ export function LoginRegisterForm({ } if (res.success) { - onLoginRegisterSubmit(loginRegisterValue, res.userStatus); + onLoginRegisterSubmit(newValue, res.userStatus); } else { toast({ message: res.message, severity: 'error' }); } From b83e8f4af8cc0f920fe7397d5bb533154f69793b Mon Sep 17 00:00:00 2001 From: Sajad Mirjalili Date: Mon, 29 Sep 2025 16:27:56 +0330 Subject: [PATCH 06/15] fix: otp login styles for mobile, get farsi numbers as input --- src/components/DigitsInput.tsx | 2 +- .../components/AuthenticationSteps/OtpVerifyForm.tsx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/DigitsInput.tsx b/src/components/DigitsInput.tsx index bb90c61..f009b82 100644 --- a/src/components/DigitsInput.tsx +++ b/src/components/DigitsInput.tsx @@ -119,7 +119,7 @@ const DigitInput: React.FC = ({ variant="standard" size="medium" sx={{ - width: '83px', + width: { md: '83px', xs: '20%' }, }} /> ))} diff --git a/src/features/authentication/components/AuthenticationSteps/OtpVerifyForm.tsx b/src/features/authentication/components/AuthenticationSteps/OtpVerifyForm.tsx index edb287b..8027ed1 100644 --- a/src/features/authentication/components/AuthenticationSteps/OtpVerifyForm.tsx +++ b/src/features/authentication/components/AuthenticationSteps/OtpVerifyForm.tsx @@ -191,7 +191,6 @@ export function OtpVerifyForm({ flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', - gap: 4, mb: 0.5, }} > From 190415c821478431112b4d5c77f9e4ba78b7125f Mon Sep 17 00:00:00 2001 From: Sajad Mirjalili Date: Mon, 29 Sep 2025 17:25:20 +0330 Subject: [PATCH 07/15] fix: remove avatar from toolbar and add to sidenav header --- src/components/layout/Header.tsx | 28 +++++++++++++++++++--------- src/components/layout/Toolbar.tsx | 12 ------------ 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx index 94b60a1..c0f5b7b 100644 --- a/src/components/layout/Header.tsx +++ b/src/components/layout/Header.tsx @@ -1,4 +1,5 @@ import { + Avatar, Box, IconButton, ListItemIcon, @@ -14,6 +15,7 @@ import { LTRTypography } from '../common/LTRTypography'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useAuth } from '@/hooks/useAuth'; +import { FlexBox } from '../common/FlexBox'; interface HeaderProps { user: UserInfo; @@ -52,15 +54,23 @@ export const Header: React.FC = ({ user }) => { height: (t) => t.spacing(10.5), }} > - - - {user.fullName} - - {/* TODO: add ternary text color to palette */} - - {user.phoneNumber ?? user.email} - - + + + {user.firstName.charAt(0) + ' ' + user.lastName.charAt(0)} + + + + {user.fullName} + + {/* TODO: add ternary text color to palette */} + + {user.phoneNumber ?? user.email} + + + diff --git a/src/components/layout/Toolbar.tsx b/src/components/layout/Toolbar.tsx index ba84948..1ca8270 100644 --- a/src/components/layout/Toolbar.tsx +++ b/src/components/layout/Toolbar.tsx @@ -63,21 +63,9 @@ export const Toolbar: React.FC = ({ )} - - {isMobile && ( - - {user.firstName.charAt(0) + ' ' + user.lastName.charAt(0)} - - )} - ); From 8808d9bdb12c017426a817144759ba728fdd9dba Mon Sep 17 00:00:00 2001 From: Sajad Mirjalili Date: Mon, 29 Sep 2025 17:26:04 +0330 Subject: [PATCH 08/15] fix: adding access token to storage regardless of scope --- .../components/AuthenticationSteps/AuthenticationSteps.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/features/authentication/components/AuthenticationSteps/AuthenticationSteps.tsx b/src/features/authentication/components/AuthenticationSteps/AuthenticationSteps.tsx index 0435e78..f394e52 100644 --- a/src/features/authentication/components/AuthenticationSteps/AuthenticationSteps.tsx +++ b/src/features/authentication/components/AuthenticationSteps/AuthenticationSteps.tsx @@ -95,9 +95,10 @@ export const AuthenticationSteps = (): JSX.Element => { tokenResponse: GenerateTokenResponse, ) => { setMemoryTokenRes(tokenResponse); - if (authFactory.isCurrentApplication()) { - login(tokenResponse); - } + // TODO: For now both application scopes can have their tokens + // later we need to discuss this base on business plan and change it + // if (authFactory.isCurrentApplication()) {} + login(tokenResponse); if (loginResult.registeredWithOutPhoneNumber) { setCurrentStep('addPhoneNumber'); From 6f96198c53e87f4d2897150f841840c93d69b76a Mon Sep 17 00:00:00 2001 From: Sajad Mirjalili Date: Mon, 29 Sep 2025 17:57:54 +0330 Subject: [PATCH 09/15] fix: active sessions icons and delete button --- src/features/profile/routes/ActiveDevicesPage.tsx | 14 ++++++++++---- src/features/profile/types/settingsType.ts | 3 ++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/features/profile/routes/ActiveDevicesPage.tsx b/src/features/profile/routes/ActiveDevicesPage.tsx index 037f2d8..03452f1 100644 --- a/src/features/profile/routes/ActiveDevicesPage.tsx +++ b/src/features/profile/routes/ActiveDevicesPage.tsx @@ -7,7 +7,7 @@ import { Stack, } from '@mui/material'; import { useTranslation } from 'react-i18next'; -import { DeviceMessage, Logout } from 'iconsax-react'; +import { DeviceMessage, Logout, Mobile } from 'iconsax-react'; import { CardContainer } from '@/components/CardContainer'; import { PageWrapper } from '../components/PageWrapper'; import { Icon } from '@rkheftan/harmony-ui'; @@ -43,7 +43,8 @@ export function ActiveDevicesPage() { const formattedDevices = sessions.map((session: ApiSession) => ({ id: session.key, timeAndDate: formatDate(session.created, i18n.language, t), - deviceModel: `${session.deviceOs} ${session.deviceName}`, + deviceOs: session.deviceOs, + deviceName: session.deviceName, ip: session.ipAddress, current: session.key === currentKey, })); @@ -199,12 +200,16 @@ export function ActiveDevicesPage() { }} > - {device.deviceModel} + {`${device.deviceOs} ${device.deviceName}`} @@ -253,6 +258,7 @@ export function ActiveDevicesPage() { } loading={loadingDeleteIds.includes(device.id)} onClick={() => handleDeleteDevice(device.id)} + fullWidth={false} sx={{ color: 'error.main', borderRadius: 1, diff --git a/src/features/profile/types/settingsType.ts b/src/features/profile/types/settingsType.ts index 26dea18..3b411d2 100644 --- a/src/features/profile/types/settingsType.ts +++ b/src/features/profile/types/settingsType.ts @@ -19,7 +19,8 @@ export interface InfoRowData { export interface Device { id: string; timeAndDate: string; - deviceModel: string; + deviceName: 'smartphone' | 'desktop' | string; + deviceOs: string; ip: string; current: boolean; } From 6f6cdf6e6cb29e87ec709ecf2c9a6ee349c2426e Mon Sep 17 00:00:00 2001 From: Sajad Mirjalili Date: Mon, 29 Sep 2025 18:44:54 +0330 Subject: [PATCH 10/15] fix: bugs in profile phone form --- .../phoneNumber/PhoneEditForm.tsx | 110 ++++++++++++------ 1 file changed, 75 insertions(+), 35 deletions(-) diff --git a/src/features/profile/components/userInformation/phoneNumber/PhoneEditForm.tsx b/src/features/profile/components/userInformation/phoneNumber/PhoneEditForm.tsx index 882122c..f8acdca 100644 --- a/src/features/profile/components/userInformation/phoneNumber/PhoneEditForm.tsx +++ b/src/features/profile/components/userInformation/phoneNumber/PhoneEditForm.tsx @@ -11,10 +11,11 @@ import { Edit2, TickCircle } from 'iconsax-react'; import { CountDownTimer } from '@/components/CountDownTimer'; import { Icon } from '@rkheftan/harmony-ui'; import { type PhoneEditFormProps } from '@/features/profile/types/settingsType'; -import { useRef } from 'react'; +import { useRef, type ChangeEvent } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { CountryCodeSelector } from '@/components/CountryCodeSelector'; import { LTRTypography } from '@/components/common/LTRTypography'; +import { replacePersianWithRealNumbers } from '@/utils/replacePersianWithRealNumbers'; export default function PhoneEditForm({ phoneNumber, @@ -42,6 +43,21 @@ export default function PhoneEditForm({ const textFieldRef = useRef(null); const inputRef = useRef(null); + const handleChange = (event: ChangeEvent) => { + const value = replacePersianWithRealNumbers(event.target.value); + console.log(value); + + setPhoneNumber(value); + }; + + const onSendCode = () => { + if (countryCode === '+98' && phoneNumber.startsWith('09')) { + const newValue = phoneNumber.substring(1); + setPhoneNumber(newValue); + } + handleSendCode(); + }; + return ( @@ -70,6 +86,7 @@ export default function PhoneEditForm({ > handleBlur('phoneNumber')} error={!!phoneNumberError} helperText={phoneNumberError} - onChange={(e) => setPhoneNumber(e.target.value)} + onChange={handleChange} placeholder="09123456789" slotProps={{ input: { - endAdornment: isCodeSent ? ( - - { - setButtonState('default'); - setVerificationCode(''); - setIsCodeSent(false); - }} - edge="end" - > - - - - ) : ( - i18n.dir() === 'rtl' && ( + endAdornment: + i18n.dir() === 'rtl' ? ( - ) - ), - startAdornment: i18n.dir() === 'ltr' && ( - - ), + ) : ( + isCodeSent && ( + + { + setButtonState('default'); + setVerificationCode(''); + setIsCodeSent(false); + }} + edge="end" + > + + + + ) + ), + startAdornment: + i18n.dir() === 'ltr' ? ( + + ) : ( + isCodeSent && ( + + { + setButtonState('default'); + setVerificationCode(''); + setIsCodeSent(false); + }} + edge="end" + > + + + + ) + ), }, }} /> @@ -144,7 +183,8 @@ export default function PhoneEditForm({