chore: change styles and add Api for user profile
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user