chore: change styles and add Api for user profile

This commit is contained in:
Koosha Lahouti
2025-08-12 20:20:28 +03:30
parent ed57858c2e
commit 782ef2a2de
35 changed files with 2785 additions and 1843 deletions

View File

@@ -22,8 +22,6 @@ export function CardContainer({
sx={{
marginInline: 'auto',
width: '100%',
maxWidth: 'min(100%, 818px)',
// paddingInline: { xs: 2, sm: 3, md: 4 },
display: 'flex',
flexDirection: 'column',
gap: 2,

View File

@@ -1,4 +1,6 @@
import { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { toLocaleDigits } from '@/utils/persianDigit';
interface CountdownTimerProps {
initialSeconds: number;
@@ -9,30 +11,30 @@ export function CountDownTimer({
initialSeconds,
onComplete,
}: CountdownTimerProps) {
const { i18n } = useTranslation();
const [secondsLeft, setSecondsLeft] = useState(initialSeconds);
useEffect(() => {
setSecondsLeft(initialSeconds);
}, [initialSeconds]);
useEffect(() => {
if (secondsLeft <= 0) {
onComplete?.();
return;
}
const timer = setInterval(() => {
setSecondsLeft((prev) => prev - 1);
setSecondsLeft((prev) => {
if (prev <= 1) {
clearInterval(timer);
onComplete?.();
return 0;
}
return prev - 1;
});
}, 1000);
return () => clearInterval(timer);
}, [secondsLeft, onComplete]);
const toPersianDigits = (str: string) =>
str.replace(/\d/g, (d: string) => '۰۱۲۳۴۵۶۷۸۹'[parseInt(d)]);
return () => clearInterval(timer);
}, [initialSeconds, onComplete]);
const formatTime = (totalSeconds: number) => {
const minutes = String(Math.floor(totalSeconds / 60)).padStart(2, '0');
const seconds = String(totalSeconds % 60).padStart(2, '0');
return toPersianDigits(`${minutes}:${seconds}`);
return toLocaleDigits(`${minutes}:${seconds}`, i18n.language);
};
return <span>{formatTime(secondsLeft)}</span>;

View File

@@ -20,13 +20,18 @@ export function CountryFlag({ code }: CountryFlagProps) {
return (
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<img
<Box
component="img"
loading="lazy"
src={flagUrl}
alt={displayName}
width="24"
height="16"
style={{ borderRadius: '2px', border: '1px solid #ccc' }}
sx={{
width: 24,
height: 16,
borderRadius: 0.5,
border: '1px solid',
borderColor: 'divider',
}}
/>
<Typography variant="body2">{displayName}</Typography>
</Box>

View File

@@ -1,12 +1,23 @@
import { ToggleButtonGroup, ToggleButton, Box } from '@mui/material';
import { useColorScheme } from '@mui/material/styles';
import { Sun1, Moon } from 'iconsax-react';
import { useTranslation } from 'react-i18next';
import { Icon } from '@rkheftan/harmony-ui';
import { type MouseEvent } from 'react';
export const ThemeToggleButton = () => {
const { mode, setMode } = useColorScheme();
enum ThemeMode {
Light = 'light',
Dark = 'dark',
}
interface ThemeToggleButtonProps {
value: 'light' | 'dark';
onChange: (newMode: 'light' | 'dark') => void;
}
export const ThemeToggleButton = ({
value,
onChange,
}: ThemeToggleButtonProps) => {
const { t } = useTranslation('setting');
const handleChange = (
@@ -14,26 +25,26 @@ export const ThemeToggleButton = () => {
newMode: 'light' | 'dark' | null,
) => {
if (newMode !== null) {
setMode(newMode);
localStorage.setItem('theme', newMode);
onChange(newMode);
}
};
return (
<Box dir="rtl">
<Box>
<ToggleButtonGroup
value={mode}
value={value}
exclusive
onChange={handleChange}
sx={{
borderRadius: '12px',
borderRadius: 1.5,
border: '1px solid',
borderColor: 'divider',
overflow: 'hidden',
}}
>
<ToggleButton
value="light"
value={ThemeMode.Light}
aria-label="light theme"
sx={{
textTransform: 'none',
display: 'flex',
@@ -51,7 +62,8 @@ export const ThemeToggleButton = () => {
</ToggleButton>
<ToggleButton
value="dark"
value={ThemeMode.Dark}
aria-label="dark theme"
sx={{
textTransform: 'none',
display: 'flex',

View File

@@ -2,7 +2,6 @@ import { Alert, Snackbar, type AlertColor } from '@mui/material';
import { type PropsWithChildren } from 'react';
export interface ToastProps extends PropsWithChildren {
color: AlertColor | undefined;
open: boolean;