From 064b3f66dc999c2b608febeaf41325efab563b28 Mon Sep 17 00:00:00 2001 From: Koosha Lahouti Date: Wed, 30 Jul 2025 19:44:08 +0330 Subject: [PATCH] feat: language can be changed between persian and english and everything got responsive --- package-lock.json | 30 +- package.json | 2 + public/locales/en/setting.json | 6 +- public/locales/fa/setting.json | 6 +- .../activeDevices/ActiveDevices.tsx | 152 +++++----- .../components/security/UserSecurity.tsx | 167 ++++------- .../profile/components/setting/Setting.tsx | 264 +++++++++--------- .../components/setting/data/Languages.tsx | 44 --- 8 files changed, 306 insertions(+), 365 deletions(-) delete mode 100644 src/features/profile/components/setting/data/Languages.tsx diff --git a/package-lock.json b/package-lock.json index fe1023c..24da072 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,8 +17,10 @@ "i18next-http-backend": "^3.0.2", "iconsax-react": "^0.0.8", "react": "^19.1.0", + "react-country-flag": "^3.1.0", "react-dom": "^19.1.0", "react-i18next": "^15.6.0", + "react-virtuoso": "^4.13.0", "stylis": "^4.3.6", "stylis-plugin-rtl": "^2.1.1" }, @@ -1067,9 +1069,9 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.3.tgz", - "integrity": "sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.4.tgz", + "integrity": "sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3722,6 +3724,18 @@ "node": ">=0.10.0" } }, + "node_modules/react-country-flag": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/react-country-flag/-/react-country-flag-3.1.0.tgz", + "integrity": "sha512-JWQFw1efdv9sTC+TGQvTKXQg1NKbDU2mBiAiRWcKM9F1sK+/zjhP2yGmm8YDddWyZdXVkR8Md47rPMJmo4YO5g==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": ">=16" + } + }, "node_modules/react-dom": { "version": "19.1.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", @@ -3792,6 +3806,16 @@ "react-dom": ">=16.6.0" } }, + "node_modules/react-virtuoso": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/react-virtuoso/-/react-virtuoso-4.13.0.tgz", + "integrity": "sha512-XHv2Fglpx80yFPdjZkV9d1baACKghg/ucpDFEXwaix7z0AfVQj+mF6lM+YQR6UC/TwzXG2rJKydRMb3+7iV3PA==", + "license": "MIT", + "peerDependencies": { + "react": ">=16 || >=17 || >= 18 || >= 19", + "react-dom": ">=16 || >=17 || >= 18 || >=19" + } + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", diff --git a/package.json b/package.json index 91571b6..b2ffcf4 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,10 @@ "i18next-http-backend": "^3.0.2", "iconsax-react": "^0.0.8", "react": "^19.1.0", + "react-country-flag": "^3.1.0", "react-dom": "^19.1.0", "react-i18next": "^15.6.0", + "react-virtuoso": "^4.13.0", "stylis": "^4.3.6", "stylis-plugin-rtl": "^2.1.1" }, diff --git a/public/locales/en/setting.json b/public/locales/en/setting.json index 7024be4..c5c78f4 100644 --- a/public/locales/en/setting.json +++ b/public/locales/en/setting.json @@ -9,6 +9,10 @@ "light": "Light", "dark": "Dark", "language": "زبان/language", - "calendar": "Calendar and date format" + "calendar": "Calendar and date format", + "solar": "Solar", + "lunar": "Lunar", + "christian": "Christian", + "iran": "Iran" } } diff --git a/public/locales/fa/setting.json b/public/locales/fa/setting.json index 948eb7a..1b07a7a 100644 --- a/public/locales/fa/setting.json +++ b/public/locales/fa/setting.json @@ -9,6 +9,10 @@ "light": "روشن", "dark": "تاریک", "language": "زبان/language", - "calendar": "فرمت تقویم و تاریخ" + "calendar": "فرمت تقویم و تاریخ", + "solar": "شمسی", + "lunar": "قمری", + "christian": "میلادی", + "iran": "ایران" } } diff --git a/src/features/profile/components/activeDevices/ActiveDevices.tsx b/src/features/profile/components/activeDevices/ActiveDevices.tsx index 350bb2e..f4b4bb6 100644 --- a/src/features/profile/components/activeDevices/ActiveDevices.tsx +++ b/src/features/profile/components/activeDevices/ActiveDevices.tsx @@ -45,6 +45,7 @@ export function ActiveDevices() { maxWidth: '834px', mx: 'auto', px: { xs: 2, sm: 3 }, + py: 4, }} > - - + + - + {t('active.activeDevices')} {t('active.activeDevicesCaption')} @@ -88,87 +82,111 @@ export function ActiveDevices() { borderColor: 'error.main', color: 'error.main', border: '1px solid', + textTransform: 'none', }} > {t('active.deletDevicesButton')} - - {devices.map((device) => ( + {devices.map((device) => ( + + + {device.timeAndDate} + + - - {device.timeAndDate} + + + {device.deviceModel} + - - - - {device.deviceModel} - - + + {device.ip} + - - {device.ip} - - - - {device.current ? ( - - ) : null} - - - + + {device.current && ( - + )} - ))} - + + + + + + ))} ); diff --git a/src/features/profile/components/security/UserSecurity.tsx b/src/features/profile/components/security/UserSecurity.tsx index ae794a4..578e0bf 100644 --- a/src/features/profile/components/security/UserSecurity.tsx +++ b/src/features/profile/components/security/UserSecurity.tsx @@ -8,7 +8,9 @@ import { TextField, DialogActions, IconButton, + useMediaQuery, } from '@mui/material'; +import { useTheme } from '@mui/material/styles'; import { useTranslation } from 'react-i18next'; import { useState, useEffect } from 'react'; import { CloseCircle, Refresh } from 'iconsax-react'; @@ -18,6 +20,8 @@ import Logo from '@/components/Logo'; import { CardContainer } from '@/components/CardContainer'; export function UserSecurity() { + const theme = useTheme(); + const fullScreen = useMediaQuery(theme.breakpoints.down('sm')); const { t } = useTranslation('security'); const [open, setOpen] = useState(false); const [password, setPassword] = useState(''); @@ -63,14 +67,14 @@ export function UserSecurity() { }, [password, validPassword]); return ( - + - + @@ -119,30 +110,22 @@ export function UserSecurity() { } > - + {changePassword ? ( - + رمز عبور فعال است آخرین تغییر چند ثانیه پیش ) : ( - - - {t('securityForm.notDeterminedPassword')} - - + {t('securityForm.notDeterminedPassword')} + )} @@ -150,21 +133,13 @@ export function UserSecurity() { open={open} onClose={handleClose} fullWidth + fullScreen={fullScreen} maxWidth="xs" scroll="body" - PaperProps={{ - sx: { mx: 1 }, - }} + PaperProps={{ sx: { mx: 1 } }} > - + @@ -182,48 +157,18 @@ export function UserSecurity() { px: { xs: 2, sm: 3 }, }} > - - setPassword(e.target.value)} - sx={{ - '& .MuiOutlinedInput-root': { - borderRadius: 2, - }, - }} - /> - + setPassword(e.target.value)} + sx={{ '& .MuiOutlinedInput-root': { borderRadius: 2 } }} + /> {password && showValidation && ( - - + + )} - - setConfirmPassword(e.target.value)} - error={confirmPassword.length > 0 && !matchPassword} - helperText={ - confirmPassword.length > 0 && !matchPassword - ? t('securityForm.notCompatibility') - : ' ' - } - sx={{ - '& .MuiOutlinedInput-root': { - borderRadius: 2, - }, - }} - /> - + setConfirmPassword(e.target.value)} + error={confirmPassword.length > 0 && !matchPassword} + helperText={ + confirmPassword.length > 0 && !matchPassword + ? t('securityForm.notCompatibility') + : ' ' + } + sx={{ '& .MuiOutlinedInput-root': { borderRadius: 2 } }} + /> - + )}