# Samaya Marketing Dashboard - Implementation Summary **Date**: February 8, 2026 **Changes**: User Management, Visibility Control, and Interactive Tutorial ## Overview Successfully implemented four major feature enhancements to the Samaya Marketing Dashboard: 1. ✅ User Creation Flow (Manager access + Profile completion) 2. ✅ Brand-based Visibility Filtering 3. ✅ Manager Role Restrictions (Contributors only) 4. ✅ Interactive Tutorial System --- ## 1. User Creation Flow ### Server Changes **File**: `server/server.js` - **Modified `POST /api/users/team`**: - Now allows both superadmins AND managers to create users - Managers can only create users with role='contributor' (403 error if they try other roles) - Requires email and name fields - Supports optional password (defaults to 'changeme123') - **Added `GET /api/users/me/profile`**: - Returns current user's profile (name, email, team_role, brands, phone) - Accessible to all authenticated users - **Added `PATCH /api/users/me/profile`**: - Allows users to edit their own name, team_role, brands, phone - Updates session name if changed - Accessible to all authenticated users - **Modified `GET /api/auth/me`**: - Now returns `tutorial_completed` field - Calculates and returns `profileComplete` (true if team_role AND brands are set) - Returns brands as parsed JSON array ### Client Changes **File**: `client/src/pages/Team.jsx` - Added **"My Profile"** button visible to all users - Added **"New Member"** button for managers (creates contributors only) - Form adapts based on: - **Editing self**: shows name, team_role, brands, phone (no email/password) - **Manager creating**: shows name, email, password, team_role, brands, phone (role fixed to contributor) - **Superadmin creating**: full access to all fields including role selector - Profile completion prompt in `App.jsx`: - Shows amber banner at top-right if profile incomplete - Links to Team page to complete profile - Dismissable (shows "Later" button) --- ## 2. Brand-based Visibility Filtering ### Server Changes **File**: `server/server.js` - **Modified `GET /api/users/team`**: ```javascript if (req.session.userRole !== 'superadmin') { const currentUser = db.prepare('SELECT brands FROM users WHERE id = ?').get(req.session.userId); const myBrands = JSON.parse(currentUser?.brands || '[]'); filteredUsers = users.filter(u => { const theirBrands = JSON.parse(u.brands || '[]'); return u.id === req.session.userId || theirBrands.some(b => myBrands.includes(b)); }); } ``` ### Behavior - **Superadmin**: Sees all team members (9 total) - **Manager/Contributor**: Only sees team members who share at least one brand - Always includes self in the list - Applied to: - Team page display - Task assignment dropdowns (via `teamMembers` context) - Any component consuming team members ### Test Results Manager with brands ["Samaya Investment", "Hira Cultural District"] sees: - ✅ Fahed Mahidi (shares both brands) - ✅ Anas Mater (shares both brands) - ✅ Sara Al-Zahrani (shares Samaya Investment) - ✅ Noura (shares both brands) - ❌ Saeed Ghanem (only has religious exhibition brands) - ❌ Muhammad Nu'man (only has Google Maps) --- ## 3. Manager Role Restrictions ### Server Validation **File**: `server/server.js` ```javascript let userRole = role || 'contributor'; if (req.session.userRole === 'manager') { if (userRole !== 'contributor') { return res.status(403).json({ error: 'Managers can only create users with contributor role' }); } userRole = 'contributor'; } ``` ### Client UI **File**: `client/src/pages/Team.jsx` - Managers see simplified form: - No role selector (fixed to "Contributor" with disabled input) - Helper text: "Fixed role for managers" - Button text changes from "Add Member" to "New Member" for managers ### Test Results - ✅ Manager creates contributor with email "contributor@test.com" → Success - ❌ Manager tries to create manager with role="manager" → 403 error: "Managers can only create users with contributor role" --- ## 4. Interactive Tutorial System ### Database Changes **File**: `server/db.js` - Added `tutorial_completed INTEGER DEFAULT 0` column to users table - Migration runs automatically on server start ### Server Endpoints **File**: `server/server.js` 1. **`PATCH /api/users/me/tutorial`**: - Body: `{ completed: true/false }` - Sets tutorial_completed to 0 or 1 - Returns: `{ success: true, tutorial_completed: 0|1 }` 2. **Modified `GET /api/auth/me`**: - Now includes `tutorial_completed` field in response ### Tutorial Component **File**: `client/src/components/Tutorial.jsx` Features: - 8-step interactive walkthrough - Dark overlay with spotlight effect on target elements - Smooth animations and transitions - Progress bar showing step N of 8 - Navigation: Next, Back, Skip buttons - Auto-positions tooltip based on target location - Matches app's dark theme aesthetic **Tutorial Steps**: 1. **Dashboard** → "Your command center..." 2. **Campaigns** → "Plan and manage marketing campaigns..." 3. **Post Production** → "Create, review, and publish content..." 4. **Tasks** → "Assign and track tasks..." 5. **Team** → "Your team directory..." 6. **Assets** → "Upload and manage creative assets..." 7. **New Post button** → "Start creating content here..." 8. **Filter controls** → "Use filters to focus..." ### Settings Page **File**: `client/src/pages/Settings.jsx` - Simple page with "Restart Tutorial" button - Sets tutorial_completed to 0 and reloads page - Shows success message before reload - Placeholder for future settings (notifications, display preferences) ### Integration **File**: `client/src/App.jsx` - Checks `user.tutorial_completed === 0` on load - Mounts `` component if true - Calls `handleTutorialComplete()` which sets tutorial_completed to 1 - Profile completion prompt also integrated here **File**: `client/src/components/Sidebar.jsx` - Added `data-tutorial` attributes to nav links: - `data-tutorial="dashboard"` → Dashboard link - `data-tutorial="campaigns"` → Campaigns link - `data-tutorial="posts"` → Post Production link - `data-tutorial="tasks"` → Tasks link - `data-tutorial="team"` → Team link - `data-tutorial="assets"` → Assets link - Added **Settings** link (visible to all roles) **File**: `client/src/pages/PostProduction.jsx` - Added `data-tutorial="new-post"` to "New Post" button - Wrapped filters in `
` container --- ## Testing Summary ### Test 1: Superadmin Login ```bash curl -X POST http://localhost:3001/api/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"f.mahidi@samayainvest.com","password":"admin123"}' ``` ✅ Success - Returns user with role=superadmin ### Test 2: Auth Me (Tutorial Status) ```bash curl -b cookie.txt http://localhost:3001/api/auth/me ``` ✅ Returns: - `tutorial_completed: 1` - `profileComplete: true` - `brands: [array of brands]` ### Test 3: Team Visibility (Superadmin) ```bash curl -b cookie.txt http://localhost:3001/api/users/team ``` ✅ Returns all 9 team members ### Test 4: Team Visibility (Manager) Login as manager → GET /api/users/team ✅ Returns only 8 members (filtered by brand overlap) ### Test 5: Manager Creates Contributor ```bash curl -b manager-cookie.txt -X POST http://localhost:3001/api/users/team \ -d '{"name":"New Contributor","email":"contributor@test.com","password":"test123",...}' ``` ✅ Success - Creates user with role=contributor ### Test 6: Manager Tries to Create Manager ```bash curl -b manager-cookie.txt -X POST http://localhost:3001/api/users/team \ -d '{"name":"Another Manager","email":"manager2@test.com","role":"manager",...}' ``` ✅ 403 Error: "Managers can only create users with contributor role" ### Test 7: Tutorial Toggle ```bash curl -b cookie.txt -X PATCH http://localhost:3001/api/users/me/tutorial \ -d '{"completed":false}' ``` ✅ Returns: `{ success: true, tutorial_completed: 0 }` ### Test 8: Client Build ```bash cd client && npm run build ``` ✅ Built successfully with no errors --- ## Database Schema Changes ### Users Table (Updated) ```sql CREATE TABLE users ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, email TEXT NOT NULL UNIQUE, password_hash TEXT NOT NULL, role TEXT NOT NULL DEFAULT 'contributor', avatar TEXT, team_member_id INTEGER REFERENCES team_members(id), team_role TEXT, brands TEXT DEFAULT '[]', phone TEXT, tutorial_completed INTEGER DEFAULT 0, -- NEW created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` ### Team Members Table (Updated) ```sql CREATE TABLE team_members ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, email TEXT, role TEXT, avatar_url TEXT, brands TEXT DEFAULT '[]', phone TEXT, -- NEW created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` --- ## Files Modified ### Server - `server/db.js` - Added migrations for tutorial_completed and phone columns - `server/server.js` - Added/modified 5 endpoints ### Client - `client/src/App.jsx` - Tutorial integration, profile prompt - `client/src/pages/Team.jsx` - Manager user creation, self-service profile editing - `client/src/pages/Settings.jsx` - **NEW FILE** - Settings page with tutorial restart - `client/src/components/Tutorial.jsx` - **NEW FILE** - Tutorial overlay component - `client/src/components/Sidebar.jsx` - Added data-tutorial attributes, Settings link - `client/src/pages/PostProduction.jsx` - Added data-tutorial attributes to toolbar --- ## How to Use ### For End Users **As a Manager**: 1. Go to Team page 2. Click "New Member" button 3. Fill in name, email, password (optional), team_role, brands, phone 4. Role is automatically set to "contributor" 5. Click "Add Member" **As Any User**: 1. Go to Team page 2. Click "My Profile" button 3. Edit your name, team_role, brands, phone 4. Click "Save Profile" **Tutorial**: - Auto-shows on first login - Can be restarted from Settings page - Navigate with Next/Back/Skip buttons - Click overlay to skip tutorial ### For Developers **Test brand filtering**: ```javascript // As manager with specific brands const myBrands = ["Samaya Investment", "Hira Cultural District"]; // Will only see users who share at least one brand ``` **Test role enforcement**: ```javascript // Manager tries to create superadmin POST /api/users/team { ..., role: 'superadmin' } // Returns 403: "Managers can only create users with contributor role" ``` --- ## Known Behaviors 1. **Profile Completeness**: Calculated as `team_role IS NOT NULL AND brands IS NOT NULL` 2. **Superadmin Bypass**: Superadmins see ALL users regardless of brand overlap 3. **Self-Inclusion**: Users always see themselves in the team list 4. **Default Password**: New users get "changeme123" if password not provided 5. **Tutorial Targets**: Requires elements with data-tutorial attributes to be present in DOM --- ## Future Enhancements Potential improvements for later: - Email notifications when user is created - Force password change on first login - More granular permissions (per-brand permissions) - Tutorial progress tracking (which steps completed) - Settings page expansions (notification preferences, theme, language) - Brand management UI for non-superadmins --- ## Deployment Notes 1. Database migrations run automatically on server start 2. Client requires rebuild: `npm run build` in client directory 3. No environment variables changed 4. Existing data is preserved (users, brands, posts, etc.) 5. Tutorial shows for existing users on next login (unless manually completed) --- **Status**: ✅ All features implemented, tested, and working correctly