)
}
```
- [ ] **Step 4: Update Header page title map**
In `client/src/components/Header.jsx`, find the `PAGE_TITLE_KEYS` map and add:
```js
'/content': 'header.content',
```
Add to both i18n files: `"header.content": "Content"` (en), `"header.content": "المحتوى"` (ar).
Remove entries for `/posts`, `/calendar`, `/artefacts`, `/translations`, `/assets`, `/brands`, `/tasks`, `/budgets` (these now redirect).
- [ ] **Step 5: Test redirects**
Navigate to `/posts` → should redirect to `/content/posts`
Navigate to `/artefacts` → should redirect to `/content/design`
Navigate to `/content` → should show placeholder with tabs
- [ ] **Step 6: Commit**
```bash
git add client/src/App.jsx client/src/pages/Content.jsx client/src/components/Header.jsx
git commit -m "feat: add route redirects for nav reorg, placeholder Content page"
```
### Task 1.3: Absorb Budgets into Finance Page
**Files:**
- Modify: `client/src/pages/Finance.jsx`
- Modify: `client/src/i18n/en.json`
- Modify: `client/src/i18n/ar.json`
- [ ] **Step 1: Read Finance.jsx and Budgets.jsx**
Read both files to understand current structure and plan the merge.
- [ ] **Step 2: Add tab toggle to Finance page**
At the top of the Finance page, add a tab bar switching between "Dashboard" and "Budgets":
```jsx
const [searchParams, setSearchParams] = useSearchParams()
const activeTab = searchParams.get('tab') || 'dashboard'
```
Render tabs:
```jsx
```
- [ ] **Step 3: Conditionally render content**
Wrap the existing Finance dashboard content in `{activeTab === 'dashboard' && (...)}`.
Import the Budgets page component and render: `{activeTab === 'budgets' && }`.
Alternatively, if Budgets is too large to import directly, lazy-load it.
- [ ] **Step 4: Test both tabs work**
- [ ] **Step 5: Commit**
```bash
git add client/src/pages/Finance.jsx client/src/i18n/en.json client/src/i18n/ar.json
git commit -m "feat: absorb Budgets as tab inside Finance page"
```
### Task 1.4: Absorb Brands & Assets into Settings Page
**Files:**
- Modify: `client/src/pages/Settings.jsx`
- Modify: `client/src/i18n/en.json`
- Modify: `client/src/i18n/ar.json`
- [ ] **Step 1: Read Settings.jsx, Brands.jsx, Assets.jsx**
Understand current Settings structure and what needs to be added.
- [ ] **Step 2: Add tab navigation to Settings**
Same pattern as Finance: tabs for "General", "Brands", "Assets" using `useSearchParams`.
```jsx
const tabs = [
{ key: 'general', labelKey: 'settings.general' },
{ key: 'brands', labelKey: 'nav.brands' },
{ key: 'assets', labelKey: 'nav.assets' },
]
```
- [ ] **Step 3: Render tab content**
- General tab: existing Settings content
- Brands tab: import and render Brands component
- Assets tab: import and render Assets component
- [ ] **Step 4: Add i18n key for "General"**
```json
"settings.general": "General" // en
"settings.general": "عام" // ar
```
- [ ] **Step 5: Test all three tabs**
- [ ] **Step 6: Commit**
```bash
git add client/src/pages/Settings.jsx client/src/i18n/en.json client/src/i18n/ar.json
git commit -m "feat: absorb Brands & Assets as tabs inside Settings page"
```
### Task 1.5: Absorb Tasks into Projects Page
**Files:**
- Modify: `client/src/pages/Projects.jsx`
- Modify: `client/src/i18n/en.json`
- Modify: `client/src/i18n/ar.json`
- [ ] **Step 1: Read Projects.jsx and Tasks.jsx**
- [ ] **Step 2: Add "Projects" / "All Tasks" tab toggle to Projects page**
Same `useSearchParams` pattern. Default tab is "projects".
- [ ] **Step 3: Render Tasks component in "All Tasks" tab**
Import Tasks and render when `tab === 'tasks'`.
- [ ] **Step 4: Add i18n keys**
```json
"projects.allTasks": "All Tasks" // en
"projects.allTasks": "جميع المهام" // ar
```
- [ ] **Step 5: Test both tabs**
- [ ] **Step 6: Commit**
```bash
git add client/src/pages/Projects.jsx client/src/i18n/en.json client/src/i18n/ar.json
git commit -m "feat: absorb Tasks as tab inside Projects page"
```
### Task 1.6: Standardize Page Headers
**Files:**
- Modify: All page files (PostProduction/Content, Issues, Projects, Finance, Campaigns, Team, Settings, Dashboard)
- Create: `client/src/components/PageHeader.jsx`
- [ ] **Step 1: Create shared PageHeader component**
```jsx
import { Search, X } from 'lucide-react'
import { useState } from 'react'
import { useLanguage } from '../i18n/LanguageContext'
export default function PageHeader({
title,
searchTerm,
onSearchChange,
filters, // ReactNode — inline filter dropdowns
viewToggle, // ReactNode — view mode buttons
actions, // ReactNode — create button, bulk actions
}) {
const [searchOpen, setSearchOpen] = useState(!!searchTerm)
const { t } = useLanguage()
return (
)
}
```
- [ ] **Step 5: Build My Tasks widget**
Aggregates: content items assigned to user, pending approvals, tasks, issues. Show as a simple list with type icon + title + urgency indicator.
- [ ] **Step 6: Build Recent Activity widget**
There is no `/api/activity` endpoint. Compose the feed client-side from recent items across entities:
- Fetch recent posts (sorted by UpdatedAt, limit 5)
- Fetch recent content items (sorted by UpdatedAt, limit 5)
- Fetch recent issues (sorted by updated_at, limit 5)
- Merge, sort by date descending, take top 10
- Display: avatar + "User updated Post Title" + relative timestamp
Alternative (simpler): Skip this widget for now and add a `GET /api/activity` server endpoint later. Show a placeholder "Activity feed — coming soon" instead. **Ask the user which approach they prefer during implementation.**
- [ ] **Step 7: Build Upcoming Deadlines widget**
Items with due dates approaching. Color-coded: red (overdue), amber (this week), gray (later).
- [ ] **Step 8: Add i18n keys**
```json
"dashboard.activeCampaigns": "Active Campaigns",
"dashboard.contentInPipeline": "Content in Pipeline",
"dashboard.awaitingApproval": "Awaiting Your Approval",
"dashboard.publishedThisPeriod": "Published This Period",
"dashboard.pipelineOverview": "Pipeline Overview",
"dashboard.myTasks": "My Tasks",
"dashboard.recentActivity": "Recent Activity",
"dashboard.upcomingDeadlines": "Upcoming Deadlines"
```
(+ Arabic equivalents)
- [ ] **Step 9: Test dashboard loads with all widgets**
- [ ] **Step 10: Commit**
```bash
git add client/src/pages/Dashboard.jsx client/src/i18n/en.json client/src/i18n/ar.json
git commit -m "feat: redesign dashboard — pipeline funnel, my tasks, activity feed, deadlines"
```
---
## Chunk 6: Phase 6 — Premium Polish
### Task 6.1: Enhanced Animations & Transitions
**Files:**
- Modify: `client/src/index.css`
- [ ] **Step 1: Add spring-like bezier curves**
```css
:root {
--spring-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
--spring-smooth: cubic-bezier(0.22, 1, 0.36, 1);
}
```
- [ ] **Step 2: Add new keyframes**
```css
@keyframes slideInRight {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes countUp {
from { opacity: 0; transform: translateY(8px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes barGrow {
from { width: 0; }
}
@keyframes fadeSlideUp {
from { opacity: 0; transform: translateY(8px); }
to { opacity: 1; transform: translateY(0); }
}
```
- [ ] **Step 3: Add prefers-reduced-motion override**
```css
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
```
- [ ] **Step 4: Enhance existing card-hover**
```css
.card-hover {
transition: transform 0.2s var(--spring-smooth), box-shadow 0.2s ease;
}
.card-hover:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px -5px rgba(0,0,0,0.1), 0 0 0 1px rgba(79,70,229,0.08);
}
```
- [ ] **Step 5: Add button press effect**
```css
.btn-press {
transition: transform 0.1s ease;
}
.btn-press:hover { transform: scale(1.02); }
.btn-press:active { transform: scale(0.98); }
```
- [ ] **Step 6: Add tab indicator slide**
```css
.tab-indicator {
transition: left 0.3s var(--spring-bounce), width 0.3s var(--spring-bounce);
}
```
- [ ] **Step 7: Commit**
```bash
git add client/src/index.css
git commit -m "feat: premium animations — spring curves, card hover, button press, tab slide"
```
### Task 6.2: Glass Effects & Visual Depth
**Files:**
- Modify: `client/src/index.css`
- Modify: `client/src/components/SlidePanel.jsx`
- Modify: `client/src/components/Modal.jsx`
- Modify: `client/src/components/StatusBadge.jsx`
- [ ] **Step 1: SlidePanel — frosted glass header**
Update SlidePanel so the header section has:
```css
backdrop-filter: blur(20px);
background: rgba(255, 255, 255, 0.85);
```
(Dark mode: `rgba(21, 21, 30, 0.85)`)
Make header sticky (`sticky top-0 z-10`) so it stays visible while content scrolls.
- [ ] **Step 2: Modal — deeper backdrop blur**
Update Modal backdrop from `backdrop-blur-sm` to `backdrop-blur-md` (8px → 12px).
- [ ] **Step 3: StatusBadge — glass morphism**
Add a `.badge-glass` variant class:
```css
.badge-glass {
backdrop-filter: blur(8px);
border: 1px solid rgba(255, 255, 255, 0.15);
}
```
Apply to StatusBadge in dark mode.
- [ ] **Step 4: Add layered shadows for depth**
```css
.shadow-layered {
box-shadow:
0 1px 2px rgba(0,0,0,0.04),
0 4px 8px rgba(0,0,0,0.04),
0 16px 32px rgba(0,0,0,0.04);
}
```
- [ ] **Step 5: Commit**
```bash
git add client/src/index.css client/src/components/SlidePanel.jsx client/src/components/Modal.jsx client/src/components/StatusBadge.jsx
git commit -m "feat: glass effects — frosted panel header, deeper blur, layered shadows"
```
### Task 6.3: Typography & Spacing Refinement
**Files:**
- Modify: `client/src/index.css`
- Modify: `client/src/components/PageHeader.jsx`
- [ ] **Step 1: Update page title typography**
In PageHeader, update the h1:
```jsx
{title}
```
- [ ] **Step 2: Add tabular-nums utility**
In index.css:
```css
.tabular-nums { font-variant-numeric: tabular-nums; }
```
Apply to all metric/count displays in Dashboard, KanbanBoard column counts, etc.
- [ ] **Step 3: Enforce text-text-secondary for all secondary text**
Search for any raw `text-gray-*` classes used for secondary text and replace with `text-text-secondary`. This ensures dark mode consistency.
- [ ] **Step 4: Commit**
```bash
git add client/src/index.css client/src/components/PageHeader.jsx
git commit -m "feat: typography refinement — lighter titles, tabular nums, consistent text colors"
```
### Task 6.4: Premium Empty States
**Files:**
- Modify: `client/src/components/EmptyState.jsx`
- [ ] **Step 1: Enhance EmptyState with gradient icon background**
Update the icon container in the full (non-compact) variant:
```jsx
```
- [ ] **Step 2: Update copy tone**
Add a `friendlyCopy` prop or update existing description strings across all pages to use warmer language. Example: "No artefacts found" → "No designs yet — create your first one to get started."
- [ ] **Step 3: Add subtle entrance animation**
```jsx
))}
```
- [ ] **Step 3: Add bar grow animation to pipeline funnel**
```jsx
```
- [ ] **Step 4: Commit**
```bash
git add client/src/pages/Dashboard.jsx
git commit -m "feat: dashboard widget animations — count-up, staggered feed, bar grow"
```
---
## Execution Notes
- **Phase order matters loosely:** Phase 1 should go first (nav reorg creates the Content route). Phases 2-5 can be done in any order after Phase 1. Phase 6 (polish) should go last.
- **Each commit is independently deployable** — the app works after every commit.
- **Test after every task** — run `npm run dev` and verify the changes visually.
- **NocoDB columns auto-create on restart** — after any server.js schema change, restart the server and check logs.
- **i18n:** Always add keys to both `en.json` and `ar.json` in the same commit.