Merge branch 'feat/user-profile' into feat/user-security
This commit is contained in:
39
src/components/CountDownTimer.tsx
Normal file
39
src/components/CountDownTimer.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
interface CountdownTimerProps {
|
||||
initialSeconds: number;
|
||||
onComplete?: () => void;
|
||||
}
|
||||
|
||||
export function CountDownTimer({
|
||||
initialSeconds,
|
||||
onComplete,
|
||||
}: CountdownTimerProps) {
|
||||
const [secondsLeft, setSecondsLeft] = useState(initialSeconds);
|
||||
|
||||
useEffect(() => {
|
||||
setSecondsLeft(initialSeconds);
|
||||
}, [initialSeconds]);
|
||||
|
||||
useEffect(() => {
|
||||
if (secondsLeft <= 0) {
|
||||
onComplete?.();
|
||||
return;
|
||||
}
|
||||
const timer = setInterval(() => {
|
||||
setSecondsLeft((prev) => prev - 1);
|
||||
}, 1000);
|
||||
return () => clearInterval(timer);
|
||||
}, [secondsLeft, onComplete]);
|
||||
|
||||
const toPersianDigits = (str: string) =>
|
||||
str.replace(/\d/g, (d: string) => '۰۱۲۳۴۵۶۷۸۹'[parseInt(d)]);
|
||||
|
||||
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 <span>{formatTime(secondsLeft)}</span>;
|
||||
}
|
||||
40
src/components/Countries.tsx
Normal file
40
src/components/Countries.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
// components/Countries.ts
|
||||
|
||||
export interface Country {
|
||||
name: string;
|
||||
fa: string;
|
||||
flag: string;
|
||||
}
|
||||
|
||||
export const countries: Country[] = [
|
||||
{ name: 'Afghanistan', fa: 'افغانستان', flag: 'af' },
|
||||
{ name: 'Albania', fa: 'آلبانی', flag: 'al' },
|
||||
{ name: 'Algeria', fa: 'الجزایر', flag: 'dz' },
|
||||
{ name: 'Argentina', fa: 'آرژانتین', flag: 'ar' },
|
||||
{ name: 'Armenia', fa: 'ارمنستان', flag: 'am' },
|
||||
{ name: 'Australia', fa: 'استرالیا', flag: 'au' },
|
||||
{ name: 'Austria', fa: 'اتریش', flag: 'at' },
|
||||
{ name: 'Bahrain', fa: 'بحرین', flag: 'bh' },
|
||||
{ name: 'Canada', fa: 'کانادا', flag: 'ca' },
|
||||
{ name: 'China', fa: 'چین', flag: 'cn' },
|
||||
{ name: 'France', fa: 'فرانسه', flag: 'fr' },
|
||||
{ name: 'Germany', fa: 'آلمان', flag: 'de' },
|
||||
{ name: 'India', fa: 'هند', flag: 'in' },
|
||||
{ name: 'Iran', fa: 'ایران', flag: 'ir' },
|
||||
{ name: 'Iraq', fa: 'عراق', flag: 'iq' },
|
||||
{ name: 'Italy', fa: 'ایتالیا', flag: 'it' },
|
||||
{ name: 'Japan', fa: 'ژاپن', flag: 'jp' },
|
||||
{ name: 'Netherlands', fa: 'هلند', flag: 'nl' },
|
||||
{ name: 'Pakistan', fa: 'پاکستان', flag: 'pk' },
|
||||
{ name: 'Qatar', fa: 'قطر', flag: 'qa' },
|
||||
{ name: 'Russia', fa: 'روسیه', flag: 'ru' },
|
||||
{ name: 'Saudi Arabia', fa: 'عربستان سعودی', flag: 'sa' },
|
||||
{ name: 'Spain', fa: 'اسپانیا', flag: 'es' },
|
||||
{ name: 'Sweden', fa: 'سوئد', flag: 'se' },
|
||||
{ name: 'Switzerland', fa: 'سوئیس', flag: 'ch' },
|
||||
{ name: 'Turkey', fa: 'ترکیه', flag: 'tr' },
|
||||
{ name: 'United Arab Emirates', fa: 'امارات متحده عربی', flag: 'ae' },
|
||||
{ name: 'United Kingdom', fa: 'بریتانیا', flag: 'gb' },
|
||||
{ name: 'United States', fa: 'ایالات متحده آمریکا', flag: 'us' },
|
||||
{ name: 'Yemen', fa: 'یمن', flag: 'ye' },
|
||||
];
|
||||
46
src/components/CountryFlag.tsx
Normal file
46
src/components/CountryFlag.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import { Box, Typography } from '@mui/material';
|
||||
|
||||
export const countryCodeMap: { [key: string]: string } = {
|
||||
ایران: 'ir',
|
||||
قطر: 'qa',
|
||||
آلمان: 'de',
|
||||
آمریکا: 'us',
|
||||
فرانسه: 'fr',
|
||||
ایتالیا: 'it',
|
||||
اسپانیا: 'es',
|
||||
انگلیس: 'gb',
|
||||
کانادا: 'ca',
|
||||
استرالیا: 'au',
|
||||
چین: 'cn',
|
||||
ژاپن: 'jp',
|
||||
هند: 'in',
|
||||
روسیه: 'ru',
|
||||
برزیل: 'br',
|
||||
آرژانتین: 'ar',
|
||||
ترکیه: 'tr',
|
||||
سوئیس: 'ch',
|
||||
سوئد: 'se',
|
||||
نروژ: 'no',
|
||||
عربستان: 'sa',
|
||||
امارات: 'ae',
|
||||
عراق: 'iq',
|
||||
پاکستان: 'pk',
|
||||
};
|
||||
|
||||
export function CountryFlag({ country }: { country: string }) {
|
||||
const countryCode = countryCodeMap[country] || 'un';
|
||||
const flagUrl = `https://flagcdn.com/w40/${countryCode}.png`;
|
||||
|
||||
return (
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
<img
|
||||
src={flagUrl}
|
||||
alt={country}
|
||||
width="24"
|
||||
height="16"
|
||||
style={{ borderRadius: '2px', border: '1px solid #ccc' }}
|
||||
/>
|
||||
<Typography variant="body2">{country}</Typography>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
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