From 854a42980d9c26164260ef7ab4612568485a6c2a Mon Sep 17 00:00:00 2001 From: Talal Sharabi Date: Thu, 12 Mar 2026 15:35:36 +0400 Subject: [PATCH] fix: CORS for localhost:3000, login with username or email, favicon Made-with: Cursor --- backend/src/config/index.ts | 13 ++++++++++++- backend/src/modules/auth/auth.routes.ts | 2 +- frontend/public/favicon.ico | Bin 0 -> 1086 bytes frontend/src/app/icon.png | 0 frontend/src/app/layout.tsx | 3 +++ frontend/src/app/login/page.tsx | 21 +++++++++++---------- 6 files changed, 27 insertions(+), 12 deletions(-) create mode 100644 frontend/public/favicon.ico delete mode 100644 frontend/src/app/icon.png diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 9a135df..db920a2 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -18,7 +18,18 @@ export const config = { }, cors: { - origin: process.env.CORS_ORIGIN?.split(',') || ['http://localhost:3000'], + origin: (() => { + const envOrigins = process.env.CORS_ORIGIN?.split(',').map((o) => o.trim()).filter(Boolean); + const defaults = ['http://localhost:3000', 'http://localhost:5173']; + const origins = envOrigins?.length ? envOrigins : defaults; + // In development, always allow both common dev server origins + if (process.env.NODE_ENV !== 'production') { + ['http://localhost:3000', 'http://localhost:5173'].forEach((o) => { + if (!origins.includes(o)) origins.push(o); + }); + } + return origins; + })(), }, upload: { diff --git a/backend/src/modules/auth/auth.routes.ts b/backend/src/modules/auth/auth.routes.ts index 1279142..4737f48 100644 --- a/backend/src/modules/auth/auth.routes.ts +++ b/backend/src/modules/auth/auth.routes.ts @@ -30,7 +30,7 @@ router.post( router.post( '/login', [ - body('email').isEmail().withMessage('البريد الإلكتروني غير صالح'), + body('email').trim().notEmpty().withMessage('البريد الإلكتروني أو اسم المستخدم مطلوب'), body('password').notEmpty().withMessage('كلمة المرور مطلوبة'), ], validate, diff --git a/frontend/public/favicon.ico b/frontend/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..3239bf69ebdf7e7a7a64f83f12a68df0778d6f56 GIT binary patch literal 1086 zcmZQzU<5(|0R|wcz@Wjxz#zuJz@P!dKp~(AL>x$A1=da9{*U6(Fc?h(BQp&E0B{hq A9RL6T literal 0 HcmV?d00001 diff --git a/frontend/src/app/icon.png b/frontend/src/app/icon.png deleted file mode 100644 index e69de29..0000000 diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index 83258dc..63454f3 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -21,6 +21,9 @@ const readexPro = Readex_Pro({ export const metadata: Metadata = { title: 'ATMATA - نظام إدارة علاقات العملاء', description: 'Enterprise CRM System for Contact Management, Sales, HR, Inventory, Projects, and Marketing', + icons: { + icon: '/favicon.ico', + }, } export default function RootLayout({ diff --git a/frontend/src/app/login/page.tsx b/frontend/src/app/login/page.tsx index 588a316..ff138fe 100644 --- a/frontend/src/app/login/page.tsx +++ b/frontend/src/app/login/page.tsx @@ -7,7 +7,7 @@ import { LogIn, Mail, Lock, Building2, AlertCircle } from 'lucide-react' export default function LoginPage() { const { login } = useAuth() - const [email, setEmail] = useState('') + const [emailOrUsername, setEmailOrUsername] = useState('') const [password, setPassword] = useState('') const [error, setError] = useState('') const [isLoading, setIsLoading] = useState(false) @@ -18,7 +18,7 @@ export default function LoginPage() { setIsLoading(true) try { - await login(email, password) + await login(emailOrUsername, password) } catch (err: any) { setError(err.message || 'فشل تسجيل الدخول. الرجاء المحاولة مرة أخرى.') } finally { @@ -50,20 +50,21 @@ export default function LoginPage() { )}
- {/* Email Field */} + {/* Email or Username Field */}
-