diff --git a/DATABASE.md b/DATABASE.md index 2bc9da3..9349986 100644 --- a/DATABASE.md +++ b/DATABASE.md @@ -12,16 +12,23 @@ User accounts and profile information. |--------|------|-------------|-------------| | id | INTEGER | PRIMARY KEY | User identifier | | email | VARCHAR | UNIQUE, INDEXED | User email | +| username | VARCHAR | UNIQUE, INDEXED | Username (optional, for login) | | hashed_password | VARCHAR | NOT NULL | Bcrypt hashed password | | full_name | VARCHAR | NOT NULL | User's full name | -| phone | VARCHAR | NULLABLE | Phone number | +| phone | VARCHAR | UNIQUE, INDEXED | Phone number (optional, for login) | | address | VARCHAR | NULLABLE | Street address | | city | VARCHAR | NULLABLE | City | | postal_code | VARCHAR | NULLABLE | Postal/ZIP code | | country | VARCHAR | NULLABLE | Country | | is_active | BOOLEAN | DEFAULT TRUE | Account status | +| is_admin | BOOLEAN | DEFAULT FALSE | Admin privileges | +| must_change_password | BOOLEAN | DEFAULT FALSE | Force password change | +| password_reset_pin | VARCHAR | NULLABLE | Password reset PIN | +| pin_expires_at | DATETIME | NULLABLE | PIN expiration time | | created_at | DATETIME | DEFAULT NOW() | Account creation date | +**Login Options:** Users can login with email, username, or phone number + ### categories Product categories. @@ -146,11 +153,18 @@ Contact form submissions. | Column | Type | Constraints | Description | |--------|------|-------------|-------------| | id | INTEGER | PRIMARY KEY | Message identifier | -| name | VARCHAR | NOT NULL | Sender name | +| full_name | VARCHAR | NOT NULL | Sender full name | | email | VARCHAR | NOT NULL | Sender email | +| phone | VARCHAR | NULLABLE | Sender phone (optional) | | subject | VARCHAR | NOT NULL | Message subject | | message | TEXT | NOT NULL | Message content | | created_at | DATETIME | DEFAULT NOW() | Submission date | +| is_read | BOOLEAN | DEFAULT FALSE | Admin read status | +| status | VARCHAR | DEFAULT 'new' | Status: new/read/replied | +| admin_notes | TEXT | NULLABLE | Internal admin notes | + +**Constraints:** CHECK (status IN ('new', 'read', 'replied')) +**Indexes:** status, is_read, created_at ## Relationships Diagram @@ -192,12 +206,17 @@ The seed script includes: Indexed columns for performance: - users.email (UNIQUE) +- users.username (UNIQUE, partial index on non-null) +- users.phone (UNIQUE, partial index on non-null) - categories.name (UNIQUE) - categories.slug (UNIQUE) - products.name - products.category_id - orders.order_number (UNIQUE) - orders.user_id +- contact_messages.status +- contact_messages.is_read +- contact_messages.created_at ## Backup and Restore diff --git a/SYSTEM_UPDATE_GUIDE.md b/SYSTEM_UPDATE_GUIDE.md new file mode 100644 index 0000000..267f070 --- /dev/null +++ b/SYSTEM_UPDATE_GUIDE.md @@ -0,0 +1,298 @@ +# System Update - Quick Reference Guide + +## Date +May 8, 2026 + +## Changes Implemented + +### 1. Contact Messages System - FIXED +**Problem:** Database error when submitting contact form - column "full_name" did not exist + +**Solution:** +- Applied migration `007_enhance_contact_messages.sql` +- Renamed `name` → `full_name` in database +- Added: `phone`, `is_read`, `status`, `admin_notes` columns +- Added status constraint and indexes for performance + +**Features:** +- ✅ Public contact form with validation +- ✅ Admin dashboard tab with message management +- ✅ Unread counter badge +- ✅ Status tracking (New/Read/Replied) +- ✅ Admin notes for internal use + +--- + +### 2. Flexible Login System - NEW +**Feature:** Users can now login with email, username, OR phone number + +**Changes Made:** + +#### Backend +- Added `username` column to users table (unique, indexed) +- Made `phone` column unique and indexed for login +- Updated `authenticate_user()` to search by email OR username OR phone +- Changed login endpoint to accept `identifier` instead of `email` +- Updated User model and schemas + +#### Frontend +- Login form: "Email" → "Email, Username, or Phone" +- Register form: Added optional username and phone fields +- Updated API calls to use new login format + +**Example Logins:** +``` +Email: admin@brandmaster.com +Username: admin123 (if set) +Phone: 0504370045 (if set) +``` + +--- + +## Files Modified + +### Backend (8 files) +1. ✅ `backend/migrations/007_enhance_contact_messages.sql` - NEW +2. ✅ `backend/migrations/008_add_username_to_users.sql` - NEW +3. ✅ `backend/app/models/user.py` - Added username, updated phone +4. ✅ `backend/app/models/contact_message.py` - Enhanced model +5. ✅ `backend/app/schemas/user.py` - Added username field +6. ✅ `backend/app/schemas/contact.py` - Enhanced schemas +7. ✅ `backend/app/services/auth.py` - Flexible authenticate_user() +8. ✅ `backend/app/routers/auth.py` - Updated login endpoint +9. ✅ `backend/app/routers/contact.py` - Admin endpoints +10. ✅ `backend/app/main.py` - Registered admin router + +### Frontend (3 files) +1. ✅ `frontend/src/pages/Login.jsx` - Flexible login form +2. ✅ `frontend/src/pages/Register.jsx` - Added username/phone fields +3. ✅ `frontend/src/pages/Admin.jsx` - Contact Messages tab +4. ✅ `frontend/src/pages/Contact.jsx` - Enhanced form + +### Documentation (2 files) +1. ✅ `DATABASE.md` - Updated schema documentation +2. ✅ `deploy-complete-update.bat` - Automated deployment script + +--- + +## Deployment Steps + +### Quick Deploy (Automated) +```bash +cd c:\Users\dvirl\OneDrive\Desktop\gitea\brand-master +deploy-complete-update.bat +``` + +### Manual Deploy +```bash +# 1. Apply migrations +apply-migration.bat 007_enhance_contact_messages.sql +apply-migration.bat 008_add_username_to_users.sql + +# 2. Build images +cd backend && docker build -t harbor.dvirlabs.com/my-apps/brand-master-backend:latest . +cd ../frontend && docker build -t harbor.dvirlabs.com/my-apps/brand-master-frontend:latest . + +# 3. Push to Harbor +docker push harbor.dvirlabs.com/my-apps/brand-master-backend:latest +docker push harbor.dvirlabs.com/my-apps/brand-master-frontend:latest + +# 4. Deploy with Helm +cd brand-master-chart +helm upgrade brand-master . --namespace my-apps --wait +``` + +--- + +## Testing Checklist + +### ✅ Contact Form Fix +- [ ] Navigate to https://brand-master.dvirlabs.com/contact +- [ ] Fill in all fields (name, email, phone, subject, message) +- [ ] Submit form +- [ ] Verify success message (should NOT get database error) + +### ✅ Admin Contact Messages +- [ ] Login as admin +- [ ] Click "Contact Messages" tab +- [ ] Verify unread counter appears +- [ ] Click on message to open details +- [ ] Update status to "Read" +- [ ] Add admin notes +- [ ] Save changes +- [ ] Verify unread counter updates + +### ✅ Flexible Login +- [ ] Test login with email: `admin@brandmaster.com` +- [ ] Register new user with username: `testuser123` +- [ ] Test login with username: `testuser123` +- [ ] Register user with phone: `0501234567` +- [ ] Test login with phone: `0501234567` + +--- + +## Database Schema Changes + +### contact_message Table +```sql +-- BEFORE +name VARCHAR -- Changed to full_name +email VARCHAR +subject VARCHAR +message TEXT +created_at TIMESTAMP + +-- AFTER +full_name VARCHAR -- Renamed from 'name' +email VARCHAR +phone VARCHAR -- NEW (optional) +subject VARCHAR +message TEXT +created_at TIMESTAMP +is_read BOOLEAN -- NEW (default: false) +status VARCHAR -- NEW (new/read/replied) +admin_notes TEXT -- NEW (nullable) +``` + +### user Table +```sql +-- BEFORE +email VARCHAR (UNIQUE, INDEXED) +phone VARCHAR (NULLABLE) + +-- AFTER +email VARCHAR (UNIQUE, INDEXED) +username VARCHAR (UNIQUE, INDEXED, NULLABLE) -- NEW +phone VARCHAR (UNIQUE, INDEXED, NULLABLE) -- Now unique & indexed +``` + +--- + +## API Changes + +### Login Endpoint +```javascript +// BEFORE +POST /api/auth/login +{ + email: "admin@brandmaster.com", + password: "Admin123!" +} + +// AFTER +POST /api/auth/login +{ + identifier: "admin@brandmaster.com", // Can be email, username, or phone + password: "Admin123!" +} +``` + +### Register Endpoint +```javascript +// BEFORE +POST /api/auth/register +{ + email: "user@example.com", + password: "password123", + full_name: "John Doe" +} + +// AFTER +POST /api/auth/register +{ + email: "user@example.com", + username: "johndoe", // NEW (optional) + phone: "0501234567", // NEW (optional) + password: "password123", + full_name: "John Doe" +} +``` + +### New Admin Endpoints +``` +GET /api/admin/contact-messages - List all messages +GET /api/admin/contact-messages/unread-count - Get unread count +GET /api/admin/contact-messages/{id} - Get single message +PUT /api/admin/contact-messages/{id} - Update message +DELETE /api/admin/contact-messages/{id} - Delete message +``` + +--- + +## Default Admin Credentials + +**Email:** `admin@brandmaster.com` +**Password:** `Admin123!` + +**Can also login with:** +- Email: `admin@brandmaster.com` +- Username: (not set by default) +- Phone: (not set by default) + +To add username/phone to admin account: +```sql +UPDATE "user" +SET username = 'admin', phone = '0504370045' +WHERE email = 'admin@brandmaster.com'; +``` + +--- + +## Troubleshooting + +### Contact Form Still Shows Error +```bash +# Check if migration was applied +kubectl exec -it -n my-apps deployment/brand-master-postgres -- psql -U brand_master -d brand_master_db + +# Run this query +\d contact_message + +# Should show: full_name, phone, is_read, status, admin_notes columns +``` + +### Login with Username Doesn't Work +```bash +# Check if migration was applied +\d "user" + +# Should show: username column with UNIQUE constraint + +# Check indexes +\di idx_user_username +``` + +### Backend Logs Show Errors +```bash +kubectl logs -n my-apps deployment/brand-master-backend --tail=50 +``` + +--- + +## Success Criteria + +✅ No database errors when submitting contact form +✅ Contact messages appear in admin dashboard +✅ Unread counter shows correct number +✅ Can login with email +✅ Can login with username (when set) +✅ Can login with phone (when set) +✅ New users can register with username and phone +✅ All form validations work correctly + +--- + +## Next Steps (Optional Enhancements) + +1. Email notifications for new contact messages +2. Reply to messages from admin panel +3. Set username/phone for existing users via profile page +4. Bulk actions for messages (delete multiple, mark all as read) +5. Export contact messages to CSV +6. Advanced search and filtering + +--- + +**Status:** ✅ Ready for Deployment +**Deployment Script:** `deploy-complete-update.bat` +**Estimated Deployment Time:** 5-10 minutes diff --git a/backend/app/__pycache__/main.cpython-314.pyc b/backend/app/__pycache__/main.cpython-314.pyc index eb0a86b..0ea81bf 100644 Binary files a/backend/app/__pycache__/main.cpython-314.pyc and b/backend/app/__pycache__/main.cpython-314.pyc differ diff --git a/backend/app/models/__pycache__/contact_message.cpython-314.pyc b/backend/app/models/__pycache__/contact_message.cpython-314.pyc index 6140d4b..c865365 100644 Binary files a/backend/app/models/__pycache__/contact_message.cpython-314.pyc and b/backend/app/models/__pycache__/contact_message.cpython-314.pyc differ diff --git a/backend/app/models/__pycache__/product.cpython-314.pyc b/backend/app/models/__pycache__/product.cpython-314.pyc index 028e468..8700f61 100644 Binary files a/backend/app/models/__pycache__/product.cpython-314.pyc and b/backend/app/models/__pycache__/product.cpython-314.pyc differ diff --git a/backend/app/models/__pycache__/user.cpython-314.pyc b/backend/app/models/__pycache__/user.cpython-314.pyc index f6b2c60..dc80046 100644 Binary files a/backend/app/models/__pycache__/user.cpython-314.pyc and b/backend/app/models/__pycache__/user.cpython-314.pyc differ diff --git a/backend/app/models/user.py b/backend/app/models/user.py index 77ae775..6ed290d 100644 --- a/backend/app/models/user.py +++ b/backend/app/models/user.py @@ -16,9 +16,10 @@ class User(Base): id = Column(Integer, primary_key=True, index=True) email = Column(String, unique=True, index=True) + username = Column(String, unique=True, index=True, nullable=True) hashed_password = Column(String) full_name = Column(String) - phone = Column(String, nullable=True) + phone = Column(String, unique=True, nullable=True, index=True) address = Column(String, nullable=True) city = Column(String, nullable=True) postal_code = Column(String, nullable=True) diff --git a/backend/app/routers/__pycache__/auth.cpython-314.pyc b/backend/app/routers/__pycache__/auth.cpython-314.pyc index 454bda1..ddf9b57 100644 Binary files a/backend/app/routers/__pycache__/auth.cpython-314.pyc and b/backend/app/routers/__pycache__/auth.cpython-314.pyc differ diff --git a/backend/app/routers/__pycache__/contact.cpython-314.pyc b/backend/app/routers/__pycache__/contact.cpython-314.pyc index 9d98ca8..f4b587b 100644 Binary files a/backend/app/routers/__pycache__/contact.cpython-314.pyc and b/backend/app/routers/__pycache__/contact.cpython-314.pyc differ diff --git a/backend/app/routers/__pycache__/products.cpython-314.pyc b/backend/app/routers/__pycache__/products.cpython-314.pyc index b2fa4c3..1018c7b 100644 Binary files a/backend/app/routers/__pycache__/products.cpython-314.pyc and b/backend/app/routers/__pycache__/products.cpython-314.pyc differ diff --git a/backend/app/routers/auth.py b/backend/app/routers/auth.py index c1556ff..b942315 100644 --- a/backend/app/routers/auth.py +++ b/backend/app/routers/auth.py @@ -20,6 +20,11 @@ from app.config import settings router = APIRouter(prefix="/api/auth", tags=["auth"]) +class LoginRequest(BaseModel): + identifier: str # Can be email, username, or phone + password: str + + class ForgotPasswordRequest(BaseModel): email: EmailStr @@ -51,8 +56,8 @@ def register(user: UserCreate, db: Session = Depends(get_db)): @router.post("/login") -def login(email: str, password: str, db: Session = Depends(get_db)): - user = authenticate_user(db, email, password) +def login(request: LoginRequest, db: Session = Depends(get_db)): + user = authenticate_user(db, request.identifier, request.password) if not user: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, diff --git a/backend/app/schemas/__pycache__/contact.cpython-314.pyc b/backend/app/schemas/__pycache__/contact.cpython-314.pyc index 820c952..0bc68cb 100644 Binary files a/backend/app/schemas/__pycache__/contact.cpython-314.pyc and b/backend/app/schemas/__pycache__/contact.cpython-314.pyc differ diff --git a/backend/app/schemas/__pycache__/product.cpython-314.pyc b/backend/app/schemas/__pycache__/product.cpython-314.pyc index 3b37ae2..9342840 100644 Binary files a/backend/app/schemas/__pycache__/product.cpython-314.pyc and b/backend/app/schemas/__pycache__/product.cpython-314.pyc differ diff --git a/backend/app/schemas/__pycache__/user.cpython-314.pyc b/backend/app/schemas/__pycache__/user.cpython-314.pyc index 450ef46..800d4cc 100644 Binary files a/backend/app/schemas/__pycache__/user.cpython-314.pyc and b/backend/app/schemas/__pycache__/user.cpython-314.pyc differ diff --git a/backend/app/schemas/user.py b/backend/app/schemas/user.py index fc38c43..ae1f30a 100644 --- a/backend/app/schemas/user.py +++ b/backend/app/schemas/user.py @@ -10,10 +10,13 @@ class UserBase(BaseModel): class UserCreate(UserBase): password: str + username: Optional[str] = None + phone: Optional[str] = None class UserUpdate(BaseModel): full_name: Optional[str] = None + username: Optional[str] = None phone: Optional[str] = None address: Optional[str] = None city: Optional[str] = None @@ -39,6 +42,7 @@ class ResetPasswordWithPinRequest(BaseModel): class UserResponse(UserBase): id: int + username: Optional[str] phone: Optional[str] address: Optional[str] city: Optional[str] diff --git a/backend/app/services/__pycache__/auth.cpython-314.pyc b/backend/app/services/__pycache__/auth.cpython-314.pyc index 1a25e92..4351b98 100644 Binary files a/backend/app/services/__pycache__/auth.cpython-314.pyc and b/backend/app/services/__pycache__/auth.cpython-314.pyc differ diff --git a/backend/app/services/auth.py b/backend/app/services/auth.py index a01873c..cc54803 100644 --- a/backend/app/services/auth.py +++ b/backend/app/services/auth.py @@ -73,8 +73,22 @@ def verify_token(token: str) -> Optional[int]: return None -def authenticate_user(db: Session, email: str, password: str) -> Optional[User]: - user = db.query(User).filter(User.email == email).first() +def authenticate_user(db: Session, identifier: str, password: str) -> Optional[User]: + """ + Authenticate user by email, username, or phone number + identifier: can be email, username, or phone number + """ + from sqlalchemy import or_ + + # Try to find user by email, username, or phone + user = db.query(User).filter( + or_( + User.email == identifier, + User.username == identifier, + User.phone == identifier + ) + ).first() + if not user or not verify_password(password, user.hashed_password): return None return user diff --git a/backend/migrations/008_add_username_to_users.sql b/backend/migrations/008_add_username_to_users.sql new file mode 100644 index 0000000..ca8b5fe --- /dev/null +++ b/backend/migrations/008_add_username_to_users.sql @@ -0,0 +1,24 @@ +-- Migration: Add username field to users table +-- Date: 2026-05-08 +-- Description: Add username column and update phone to be unique for flexible login + +-- Add username column +ALTER TABLE "user" ADD COLUMN IF NOT EXISTS username VARCHAR(255); + +-- Make phone unique for login purposes (drop constraint first if exists) +DO $$ +BEGIN + IF EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'user_phone_key') THEN + ALTER TABLE "user" DROP CONSTRAINT user_phone_key; + END IF; +END $$; + +-- Add unique constraint on phone (only for non-null values) +CREATE UNIQUE INDEX IF NOT EXISTS idx_user_phone_unique ON "user"(phone) WHERE phone IS NOT NULL; + +-- Create unique index on username (only for non-null values) +CREATE UNIQUE INDEX IF NOT EXISTS idx_user_username ON "user"(username) WHERE username IS NOT NULL; + +-- Add comments +COMMENT ON COLUMN "user".username IS 'Unique username for login (alternative to email)'; +COMMENT ON COLUMN "user".phone IS 'Phone number (can be used for login when provided)'; diff --git a/deploy-complete-update.bat b/deploy-complete-update.bat new file mode 100644 index 0000000..0ffd1df --- /dev/null +++ b/deploy-complete-update.bat @@ -0,0 +1,188 @@ +@echo off +REM Complete System Update Deployment Script (Windows) +REM This script deploys Contact Messages + Flexible Login features + +echo ================================================================ +echo Brand Master - Complete System Update Deployment +echo ================================================================ +echo. +echo This will deploy: +echo 1. Contact Messages Management System +echo 2. Flexible Login (Email/Username/Phone) +echo. + +REM Configuration +set NAMESPACE=my-apps +set BACKEND_IMAGE=harbor.dvirlabs.com/my-apps/brand-master-backend:latest +set FRONTEND_IMAGE=harbor.dvirlabs.com/my-apps/brand-master-frontend:latest + +REM Step 1: Apply Database Migrations +echo ================================================================ +echo Step 1: Applying database migrations... +echo ================================================================ +echo. + +echo [1/2] Applying contact messages migration... +if exist "apply-migration.bat" ( + call apply-migration.bat 007_enhance_contact_messages.sql + if errorlevel 1 ( + echo [ERROR] Contact messages migration failed! + echo Please fix the error and try again. + pause + exit /b 1 + ) + echo [SUCCESS] Contact messages migration applied +) else ( + echo [ERROR] Migration script not found! + pause + exit /b 1 +) +echo. + +echo [2/2] Applying flexible login migration... +call apply-migration.bat 008_add_username_to_users.sql +if errorlevel 1 ( + echo [ERROR] Flexible login migration failed! + echo Please fix the error and try again. + pause + exit /b 1 +) +echo [SUCCESS] Flexible login migration applied +echo. + +REM Step 2: Build Backend Image +echo ================================================================ +echo Step 2: Building backend Docker image... +echo ================================================================ +cd backend +docker build -t %BACKEND_IMAGE% . +if errorlevel 1 ( + echo [ERROR] Backend build failed! + pause + exit /b 1 +) +echo [SUCCESS] Backend image built successfully +cd .. +echo. + +REM Step 3: Build Frontend Image +echo ================================================================ +echo Step 3: Building frontend Docker image... +echo ================================================================ +cd frontend +docker build -t %FRONTEND_IMAGE% . +if errorlevel 1 ( + echo [ERROR] Frontend build failed! + pause + exit /b 1 +) +echo [SUCCESS] Frontend image built successfully +cd .. +echo. + +REM Step 4: Push Images to Harbor +echo ================================================================ +echo Step 4: Pushing images to Harbor registry... +echo ================================================================ +echo Pushing backend... +docker push %BACKEND_IMAGE% +if errorlevel 1 ( + echo [ERROR] Backend push failed! + pause + exit /b 1 +) +echo [SUCCESS] Backend image pushed + +echo Pushing frontend... +docker push %FRONTEND_IMAGE% +if errorlevel 1 ( + echo [ERROR] Frontend push failed! + pause + exit /b 1 +) +echo [SUCCESS] Frontend image pushed +echo. + +REM Step 5: Deploy to Kubernetes +echo ================================================================ +echo Step 5: Deploying to Kubernetes... +echo ================================================================ +cd brand-master-chart +helm upgrade brand-master . --namespace %NAMESPACE% --set backend.image.tag=latest --set frontend.image.tag=latest --wait --timeout 5m +if errorlevel 1 ( + echo [ERROR] Helm deployment failed! + pause + exit /b 1 +) +echo [SUCCESS] Helm deployment successful +cd .. +echo. + +REM Step 6: Verify Deployment +echo ================================================================ +echo Step 6: Verifying deployment... +echo ================================================================ +echo Checking pods status... +kubectl get pods -n %NAMESPACE% | findstr brand-master + +echo. +echo Checking backend logs... +kubectl logs -n %NAMESPACE% deployment/brand-master-backend --tail=30 + +echo. +echo ================================================================ +echo Deployment Completed Successfully! +echo ================================================================ +echo. +echo NEW FEATURES DEPLOYED: +echo. +echo 1. CONTACT MESSAGES MANAGEMENT +echo - Admin can view/manage contact form submissions +echo - Unread counter badge in admin dashboard +echo - Status tracking (New/Read/Replied) +echo - Admin notes functionality +echo. +echo 2. FLEXIBLE LOGIN +echo - Users can now login with: +echo * Email: admin@brandmaster.com +echo * Username: (if set during registration) +echo * Phone: (if set during registration) +echo. +echo TESTING INSTRUCTIONS: +echo ================================================================ +echo. +echo A. Test Contact Form: +echo 1. Visit: https://brand-master.dvirlabs.com/contact +echo 2. Fill form with name, email, phone, subject, message +echo 3. Submit and verify success +echo. +echo B. Test Admin Dashboard: +echo 1. Login: https://brand-master.dvirlabs.com/login +echo 2. Credentials: admin@brandmaster.com / Admin123! +echo 3. Click "Contact Messages" tab +echo 4. View unread counter, open message, update status +echo. +echo C. Test Flexible Login: +echo 1. Try logging in with email: admin@brandmaster.com +echo 2. Create new user with username and phone +echo 3. Try logging in with username +echo 4. Try logging in with phone number +echo. +echo USEFUL COMMANDS: +echo ================================================================ +echo - View backend logs: +echo kubectl logs -n %NAMESPACE% deployment/brand-master-backend -f +echo. +echo - View frontend logs: +echo kubectl logs -n %NAMESPACE% deployment/brand-master-frontend -f +echo. +echo - Check database: +echo kubectl exec -it -n %NAMESPACE% deployment/brand-master-postgres -- psql -U brand_master -d brand_master_db +echo. +echo - Check contact messages: +echo SELECT * FROM contact_message ORDER BY created_at DESC LIMIT 10; +echo. +echo - Check users table: +echo SELECT id, email, username, phone, full_name FROM "user"; +echo. +pause diff --git a/frontend/src/pages/Login.jsx b/frontend/src/pages/Login.jsx index e2b20ad..75e72cd 100644 --- a/frontend/src/pages/Login.jsx +++ b/frontend/src/pages/Login.jsx @@ -10,7 +10,7 @@ export default function Login() { const navigate = useNavigate() const { setUser, setToken } = useContext(AuthContext) const [formData, setFormData] = useState({ - email: '', + identifier: '', password: '', }) const [loading, setLoading] = useState(false) @@ -36,11 +36,9 @@ export default function Login() { setLoading(true) try { - const response = await api.post('/auth/login', null, { - params: { - email: formData.email, - password: formData.password, - }, + const response = await api.post('/auth/login', { + identifier: formData.identifier, + password: formData.password, }) // Check if user must change password @@ -55,7 +53,7 @@ export default function Login() { setTimeout(() => navigate('/'), 1000) } } catch (error) { - setToast({ type: 'error', message: 'Invalid email or password' }) + setToast({ type: 'error', message: 'Invalid credentials' }) console.error('Login error:', error) } finally { setLoading(false) @@ -144,12 +142,13 @@ export default function Login() {