Add the option to login with username or phone or email and fix the leave messages
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
parent
437fe72e48
commit
29aa5c2f36
23
DATABASE.md
23
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
|
||||
|
||||
|
||||
298
SYSTEM_UPDATE_GUIDE.md
Normal file
298
SYSTEM_UPDATE_GUIDE.md
Normal file
@ -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
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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,
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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]
|
||||
|
||||
Binary file not shown.
@ -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
|
||||
|
||||
24
backend/migrations/008_add_username_to_users.sql
Normal file
24
backend/migrations/008_add_username_to_users.sql
Normal file
@ -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)';
|
||||
188
deploy-complete-update.bat
Normal file
188
deploy-complete-update.bat
Normal file
@ -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
|
||||
@ -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() {
|
||||
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="form-group">
|
||||
<label>Email</label>
|
||||
<label>Email, Username, or Phone</label>
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
value={formData.email}
|
||||
type="text"
|
||||
name="identifier"
|
||||
value={formData.identifier}
|
||||
onChange={handleChange}
|
||||
placeholder="Enter email, username, or phone"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -10,6 +10,8 @@ export default function Register() {
|
||||
const { setUser, setToken } = useContext(AuthContext)
|
||||
const [formData, setFormData] = useState({
|
||||
email: '',
|
||||
username: '',
|
||||
phone: '',
|
||||
password: '',
|
||||
full_name: '',
|
||||
})
|
||||
@ -30,17 +32,17 @@ export default function Register() {
|
||||
try {
|
||||
const response = await api.post('/auth/register', {
|
||||
email: formData.email,
|
||||
username: formData.username || null,
|
||||
phone: formData.phone || null,
|
||||
password: formData.password,
|
||||
full_name: formData.full_name,
|
||||
})
|
||||
|
||||
setToast({ type: 'success', message: 'Account created successfully! Logging you in...' })
|
||||
|
||||
const loginResponse = await api.post('/auth/login', null, {
|
||||
params: {
|
||||
email: formData.email,
|
||||
password: formData.password,
|
||||
},
|
||||
const loginResponse = await api.post('/auth/login', {
|
||||
identifier: formData.email,
|
||||
password: formData.password,
|
||||
})
|
||||
|
||||
setToken(loginResponse.data.access_token)
|
||||
@ -83,6 +85,28 @@ export default function Register() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label>Username (Optional)</label>
|
||||
<input
|
||||
type="text"
|
||||
name="username"
|
||||
value={formData.username}
|
||||
onChange={handleChange}
|
||||
placeholder="Choose a unique username"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label>Phone (Optional)</label>
|
||||
<input
|
||||
type="tel"
|
||||
name="phone"
|
||||
value={formData.phone}
|
||||
onChange={handleChange}
|
||||
placeholder="+972 XX-XXX-XXXX"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label>Password</label>
|
||||
<input
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user