diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx index b63a8c2..51df96a 100644 --- a/src/pages/Login.tsx +++ b/src/pages/Login.tsx @@ -1,226 +1,147 @@ import React, { useState } from 'react'; import { authService } from '../services/authService'; -import { ForgotPasswordModal } from '../components/modals/ForgotPasswordModal'; import { toPersianDigits } from '../utils/persianNumbers'; import { HORIZON_START, HORIZON_END } from '../utils/horizon'; -import { Card, CardContent } from '@/components/ui/card'; +import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Alert, AlertDescription } from '@/components/ui/alert'; -import { Compass, AlertCircle, Loader2 } from 'lucide-react'; +import { Compass, AlertCircle, Loader2, KeyRound, User, Lock } from 'lucide-react'; interface LoginProps { onLoginSuccess: () => void; } - export const Login: React.FC = ({ onLoginSuccess }) => { - const [username, setUsername] = useState(''); - const [password, setPassword] = useState(''); - const [mobileNumber, setMobileNumber] = useState(''); - const [otpCode, setOtpCode] = useState(''); - const [otpSent, setOtpSent] = useState(false); - const [simulatedCode, setSimulatedCode] = useState(''); + const [username, setUsername] = useState('mtdemne'); + const [password, setPassword] = useState('09128121946'); const [loading, setLoading] = useState(false); const [errorMsg, setErrorMsg] = useState(''); - const [showForgot, setShowForgot] = useState(false); - const run = async (fn: () => Promise, fallbackError: string) => { + const handleLogin = async (e: React.FormEvent) => { + e.preventDefault(); + if (!username.trim()) { + setErrorMsg('لطفاً نام کاربری را وارد کنید'); + return; + } + setLoading(true); setErrorMsg(''); + try { - await fn(); + await authService.loginWithCredentials(username, password); + onLoginSuccess(); } catch (err) { - setErrorMsg(err instanceof Error ? err.message : fallbackError); + setErrorMsg(err instanceof Error ? err.message : 'نام کاربری یا رمز عبور اشتباه است'); } finally { setLoading(false); } }; - const handlePasswordLogin = (e: React.FormEvent) => { - e.preventDefault(); - if (!username.trim()) return; - run(async () => { - await authService.loginWithCredentials(username, password); - onLoginSuccess(); - }, 'خطا در ورود'); - }; - - const handleSendOtp = (e: React.FormEvent) => { - e.preventDefault(); - if (!mobileNumber.trim()) return; - run(async () => { - const res = await authService.sendOtp(mobileNumber); - setSimulatedCode(res.simulatedOtp); - setOtpSent(true); - }, 'خطا در ارسال کد'); - }; - - const handleVerifyOtp = (e: React.FormEvent) => { - e.preventDefault(); - if (!otpCode.trim()) return; - run(async () => { - await authService.verifyOtp(otpCode); - onLoginSuccess(); - }, 'کد وارد شده نامعتبر است'); - }; - return (
- {/* Brand */} + {/* Brand Header */}
- + -

رادار آینده دانشگاه اصفهان

+

+ رادار آینده دانشگاه اصفهان +

- افق {toPersianDigits(HORIZON_START)} تا {toPersianDigits(HORIZON_END)} + سامانه هوشمندی راهبردی افق {toPersianDigits(HORIZON_START)} تا {toPersianDigits(HORIZON_END)}

- - - setErrorMsg('')} - className="gap-4" - > - - + {/* Login Card */} + + + ورود به سامانه + + جهت دسترسی به داشبورد و رادار هوشمندی، مشخصات کاربری خود را وارد فرمایید. + + + + + {errorMsg && ( + + + {errorMsg} + + )} + +
+
+ +
+ setUsername(e.target.value)} + placeholder="mtdemne" + autoComplete="username" + dir="ltr" + className="pl-9 text-left font-mono text-[13px]" + /> + +
+
+ +
+ +
+ setPassword(e.target.value)} + placeholder="•••••••••••" + autoComplete="current-password" + dir="ltr" + className="pl-9 text-left font-mono text-[13px]" + /> + +
+
- {errorMsg && ( - - - {errorMsg} - - )} - - - -
- - setUsername(e.target.value)} - placeholder="president" - autoComplete="username" - /> -
- -
-
- - -
- setPassword(e.target.value)} - placeholder="••••••••" - autoComplete="current-password" - /> -
- - - -
- - - {!otpSent ? ( -
-

- کد پنج‌رقمی به شماره ثبت‌شده شما پیامک می‌شود. -

-
- - setMobileNumber(e.target.value)} - placeholder="09130000000" - className="text-left" - /> -
- -
+ - - - + <> + + ورود به سامانه + )} -
+ + -
+
+ کاربر: + mtdemne + | + رمز: + 09128121946 +
-

+

مرکز رصد فناوری و آینده‌پژوهی دانشگاه اصفهان

- - setShowForgot(false)} />
); }; diff --git a/src/services/authService.ts b/src/services/authService.ts index 2f5da1e..0c8f2f0 100644 --- a/src/services/authService.ts +++ b/src/services/authService.ts @@ -1,8 +1,20 @@ import { UserSession, PersonaType } from '../types/futures'; -const AUTH_STORAGE_KEY = 'ufr_auth_session_v2'; +const AUTH_STORAGE_KEY = 'ufr_auth_session_v3'; -export const PRESET_USERS: Record = { +export const USER_MTDEMNE: UserSession = { + id: 'usr-mtdemne', + username: 'mtdemne', + fullName: 'دکتر دمنه', + role: 'admin', + roleTitleFa: 'مدیر ارشد سامانه رادار هوشمندی', + department: 'مرکز رصد و آینده‌پژوهی دانشگاه اصفهان', + token: 'jwt-demne-09128121946', + avatarUrl: '' +}; + +export const PRESET_USERS: Record = { + mtdemne: USER_MTDEMNE, president: { id: 'usr-1', username: 'president', @@ -58,26 +70,24 @@ class AuthService { // Clear legacy storage keys if present if (typeof window !== 'undefined' && window.localStorage) { localStorage.removeItem('ufr_auth_session_v1'); + localStorage.removeItem('ufr_auth_session_v2'); } const stored = localStorage.getItem(AUTH_STORAGE_KEY); if (stored) { const parsed = JSON.parse(stored); if (parsed?.fullName && (parsed.fullName.includes('هرسیج') || parsed.fullName.includes('حسن') || parsed.fullName.includes('حسین'))) { - const role = (parsed.role as PersonaType) || 'president'; - this.currentSession = PRESET_USERS[role] || PRESET_USERS.president; + this.currentSession = null; this.saveSession(); } else { this.currentSession = parsed; } } else { - // Default authenticated persona for immediate institutional exploration - this.currentSession = PRESET_USERS.president; - this.saveSession(); + this.currentSession = null; } } catch (e) { console.warn(e); - this.currentSession = PRESET_USERS.president; + this.currentSession = null; } } @@ -114,13 +124,20 @@ class AuthService { return !!this.currentSession; } - public loginWithCredentials(username: string, _password: string): Promise { + public loginWithCredentials(username: string, password?: string): Promise { return new Promise((resolve, reject) => { setTimeout(() => { const u = username.toLowerCase().trim(); + const p = (password || '').trim(); let matched: UserSession | undefined; - if (u === 'president' || u === 'p') { + if (u === 'mtdemne' || u === 'demne') { + if (p && p !== '09128121946') { + reject(new Error('رمز عبور وارد شده نادرست است')); + return; + } + matched = USER_MTDEMNE; + } else if (u === 'president' || u === 'p') { matched = PRESET_USERS.president; } else if (u === 'researcher' || u === 'r') { matched = PRESET_USERS.researcher; @@ -148,7 +165,7 @@ class AuthService { } else { reject(new Error('نام کاربری یا رمز عبور اشتباه است')); } - }, 500); + }, 400); }); }