# UX/UI Overhaul — Design Spec ## Overview Comprehensive UX/UI improvement focused on three pillars: **consistency**, **navigation reorganization**, and **premium polish**. The biggest structural change is unifying Posts, Translations, and Artefacts into a single "Content" page with a pipeline model reflecting the real production workflow. ## 1. Navigation Reorganization ### Current State - 4 collapsible module groups (Marketing, Projects, Finance, Issues) - 17 clickable items, some requiring 2 clicks (expand group → click item) - Issues is its own module group with a single item ### New Structure: Flat Nav with Dividers (9 items) ``` Dashboard ────────────────── Campaigns Content ← NEW (replaces Posts, Translations, Artefacts, Calendar) ────────────────── Projects ← absorbs Tasks as a tab/view Issues ────────────────── Finance ← absorbs Budgets as a tab ────────────────── Team Settings ← absorbs Brands, Assets as tabs ``` ### Rules - No collapsible groups — every page is 1 click - Subtle divider lines (1px, white at 6% opacity) separate conceptual groups - Active state: existing `sidebar-active-glow` style - Collapsed sidebar: icons only, same as current behavior ### What Moves Where | Current Location | New Location | |-----------------|-------------| | Posts (page) | Content → Posts tab | | Calendar (page) | Content → Posts tab → Calendar view toggle | | Translations (page) | Content → Copy tab (originals, `is_original=true`) + Translations tab (translated versions, `is_original=false`) | | Artefacts (page) | Content → Design tab | | Assets (page) | Settings → Assets tab | | Brands (page) | Settings → Brands tab | | Tasks (page) | Projects → Tasks tab inside project detail. Unlinked tasks accessible via a global "My Tasks" widget on Dashboard + a "All Tasks" view inside the Projects page (not just per-project). The standalone `/tasks` route redirects to `/projects?tab=tasks`. | | Budgets (page) | Finance → Budgets tab | ## 2. Content Page — Unified Pipeline ### Concept The content production pipeline is: **Copy → Translate → Design → Post → Publish**. Currently these are 4 separate pages with no visible connection. The Content page unifies them under one roof with tabs. ### Tabs | Tab | Purpose | Views Available | |-----|---------|----------------| | **Pipeline** | Bird's-eye view of all content items by stage | Kanban (stages as columns) | | **Copy** | Write original copy (usually AR) | List | | **Translations** | Translate/review/correct copy in other languages | List, grouped by language | | **Design** | Create artefacts (images/videos) from approved copy | Grid, List | | **Posts** | Assemble final posts for publishing | Kanban, List, Calendar | ### Pipeline Tab - Kanban columns: `Copy` → `Translate` → `Design` → `Post` → `Published` - Each card shows: title, stage badge, brand, assignee avatar, approval status icon (✅/⏳/❌) - Drag between columns advances stage (triggers approval flow if applicable) - Campaign grouping: cards from the same campaign share a visual group (shared top border or header) - "New Content" button creates a content item starting at Copy stage ### Content Item — Data Model A **Content Item** is a new NocoDB table (`ContentItems`) that threads all pipeline stages together. **ContentItems table schema:** | Column | NocoDB Type | Description | |--------|-----------|-------------| | `Id` | AutoNumber (PK) | NocoDB default | | `title` | SingleLineText | Post concept / idea name | | `stage` | SingleLineText | Current pipeline stage: `copy`, `translate`, `design`, `post`, `published` | | `campaign_id` | Number (FK) | Optional link to Campaigns table | | `brand_id` | Number (FK) | Brand association | | `assignee_id` | Number (FK) | Current stage assignee | | `created_by` | SingleLineText | Creator user ID | **Stage is stored explicitly**, not derived. Advancing stage is a manual action (drag on kanban or "Advance" button) that also triggers the approval flow for the new stage. This keeps queries simple and avoids complex derivation logic. **FK linkage — existing tables get a `content_item_id` column:** - `Translations` table → `content_item_id` (Number, FK) — for both original copy and translations - `Artefacts` table → `content_item_id` (Number, FK) — for designs/videos - `Posts` table → `content_item_id` (Number, FK) — for the assembled post These use the existing `FK_COLUMNS` pattern (Number columns, added via `ensureFKColumns()`). **Copy vs Translation distinction:** Both live in the `Translations` table. A copy entry has `is_original: true` (new Boolean column). The Copy tab filters to `is_original = true`, the Translations tab filters to `is_original = false`. No new table needed. **Server FK_COLUMNS additions:** ```js FK_COLUMNS = { ...existing, Translations: [...existing, 'content_item_id'], Artefacts: [...existing, 'content_item_id'], Posts: [...existing, 'content_item_id'], } ``` **Server TEXT_COLUMNS additions:** ```js TEXT_COLUMNS = { ...existing, Translations: [...existing, { name: 'is_original', uidt: 'Checkbox' }], } ``` ### Detail Panel - Pipeline breadcrumb at top: `Copy ✅ → Translate ✅ → Design ⏳ → Post ○` - Clicking a stage in the breadcrumb scrolls to that section in the panel - "Advance to next stage" action button when current stage is approved - All linked items visible in one panel (copy text, translation list, design thumbnails, post config) ### Approval Flow Per Stage | Stage | Approval Type | |-------|--------------| | Copy | Formal approve/reject | | Translate | Review & correct (lighter — suggestions, not gates) | | Design | Formal approve/reject | | Post | Formal approve/reject (final gate before publish) | ### Standalone Posts Not every content item needs a campaign or full pipeline. Users can: - Create a post directly from the Posts tab (skips Copy/Translate/Design) - Create copy without linking to a campaign - The pipeline is the recommended flow, not enforced ### Routing Scheme | Route | Content | |-------|---------| | `/content` | Default → Pipeline tab | | `/content/pipeline` | Pipeline kanban | | `/content/copy` | Copy tab (original texts) | | `/content/translations` | Translations tab | | `/content/design` | Design tab (artefacts) | | `/content/posts` | Posts tab (kanban/list/calendar) | **Old route redirects:** `/posts` → `/content/posts`, `/translations` → `/content/translations`, `/artefacts` → `/content/design`, `/calendar` → `/content/posts?view=calendar`. Redirects ensure existing bookmarks and shared links continue to work. **Public review routes remain unchanged:** `/review/:token`, `/review-post/:token`, `/review-translation/:token` are not affected by this reorganization. ## 3. Campaign Brief Enhancement ### Current State Campaigns exist but are mostly containers for posts. The campaign detail has a calendar timeline view. ### Enhanced Campaign Brief Campaign detail page becomes a proper strategic document. **New columns on Campaigns table:** | Column | NocoDB Type | Description | |--------|-----------|-------------| | `goals` | SingleLineText | Comma-separated from: `awareness`, `engagement`, `conversions`, `brand_building`, `lead_generation` | | `target_audience` | LongText | Free text description of target audience | | `key_messages` | LongText | Free text key messages / talking points | | `reach_target` | Number | Target reach count | | `engagement_target` | Number | Target engagement rate (stored as percentage × 100) | | `conversion_target` | Number | Target conversion count | | `approval_status` | SingleLineText | `draft`, `pending_approval`, `approved`, `rejected` | | `approved_by` | SingleLineText | User ID who approved | | `approved_at` | SingleLineText | ISO timestamp of approval | **Campaign detail sections:** - **Brief section**: goals (multi-select chips), target audience, key messages - **Metrics targets**: reach, engagement rate, conversions (numeric inputs) - **Timeline**: keep existing calendar timeline (no changes) - **Budget**: link to finance/budget allocation - **Approval gate**: campaign must be approved (`approval_status = approved`) before "Create Content" button appears - **Content items**: cards showing linked content items with pipeline progress indicators ### Campaign → Content Flow - Approved campaign shows "Create Content" button - Creates a content item pre-linked to the campaign - Campaign detail shows all its content items with stage progress ## 4. Dashboard Redesign ### Current Problem Dashboard feels messy and doesn't answer "what needs my attention?" ### New Layout **Top row — 4 metric cards:** | Card | Content | |------|---------| | Active Campaigns | Count + pending approval count | | Content in Pipeline | Total + breakdown by stage | | Awaiting Your Approval | Items needing your review | | Published This Period | Week/month toggle | **Middle — Two columns:** - **Left: Pipeline funnel** — horizontal bar/funnel showing item count per stage. Click any stage → navigates to Content page filtered to that stage. - **Right: My Tasks** — items assigned to current user needing action, sorted by urgency (overdue first, then by due date) **Bottom row — Two sections:** - **Left: Recent Activity** — feed of actions (approvals, new content, status changes, comments). Shows avatar + action + item + timestamp. - **Right: Upcoming Deadlines** — content items and campaigns with approaching due dates. Color-coded by urgency (red = overdue, amber = this week, gray = later). ### Principle Dashboard answers: **"What needs my attention right now?"** — not just display stats. ### "My Tasks" Widget — Data Sources The "My Tasks" widget aggregates items assigned to the current user from: - **Content items** where `assignee_id = currentUser` and stage needs action - **Approval requests** pending the user's review (from any stage) - **Tasks** assigned to the user (from Projects) - **Issues** assigned to the user Sorted by: overdue first, then by due date ascending, then by creation date. ## 5. Consistency Standards ### Page Header Pattern Every page uses the same header layout: ``` [Page Title] [Search] [Filters] [View Toggle] [+ Create] ``` - Same order, same position on every page - Search: expandable icon → input field (consistent interaction) - Filters: always visible inline (no toggle button to show/hide) - View toggle: far right, before Create button - Create button: always primary style, always rightmost ### Filter Bar - Always inline, always visible, consistent height - Same dropdown component across all pages - "Clear all" link appears when any filter is active - Active filters show as pills/badges ### Detail Panels (SlidePanel) - Width: 480px on all pages - Header: `[← Back] Title [⋯ Actions]` - Pipeline breadcrumb at top (for content items) - Tab order: Details → Activity → Approval (consistent) - Save: always top-right in header - Delete: moved from standalone header button to ⋯ overflow menu (intentional change from current Artefacts pattern — reduces accidental deletes, consistent placement) ### Cards (Kanban/Grid) - Single `KanbanCard` component used everywhere (already exists — enforce it) - Required elements: title, status badge, brand badge, assignee avatar, date - Hover: lift + shadow via existing `card-hover` class ### Empty States - Always use shared `EmptyState` component - Always include primary action button ("Create your first X") - Consistent icon size, spacing, copy tone ### Loading States - Skeleton loaders that match actual content dimensions - No bare full-page spinners — always skeletons - Skeleton shapes match the view (card skeletons for grid, row skeletons for list) ## 6. Premium Polish ### Transitions & Animations | Element | Animation | |---------|-----------| | Route changes | Fade + slide-up (150ms ease-out) | | Detail panel open | CSS `cubic-bezier(0.34, 1.56, 0.64, 1)` slide-in from right (simulates spring overshoot without a library) | | Kanban drag | Card lifts with shadow + slight rotation (2deg), drop zone pulses | | Status badge change | Color crossfade (not instant swap) | | View toggle (list↔grid) | Crossfade between views | | Toasts | CSS `cubic-bezier(0.34, 1.56, 0.64, 1)` slide-in from top-right, stack with spacing | | Tab active indicator | Slides to follow selection | ### Hover & Interaction States | Element | Hover Effect | |---------|-------------| | Cards | Lift 2px + deeper shadow + subtle brand-color border glow (10% opacity) | | Buttons | Scale 1.02 on hover, 0.98 on press | | Nav items | Background fills from left (not instant) | | Avatars | Ring glow in role color | ### Visual Depth & Glass Effects - Detail panel header: frosted glass (`backdrop-blur-xl`), stays visible while body scrolls - Modal backdrop: deeper blur (12px, up from current 4px) - Pipeline cards: layered multi-shadow for realistic depth - Sidebar: subtle inner glow at top edge - Status badges: glass morphism (translucent bg + subtle border) ### Typography - Page titles: `text-3xl font-light tracking-tight` (up from text-2xl) - Consistent use of `text-text-secondary` variable (no raw gray-* classes) - Numbers/metrics: `tabular-nums`, slightly heavier weight - Tighter heading letter-spacing across the board ### Empty States — Premium - Illustrated line-art SVG icons from [Iconoir](https://iconoir.com/) library (matching app's line-art aesthetic) instead of plain Lucide icons. Fallback: compose simple illustrations from multiple Lucide icons if Iconoir doesn't have a match. - Subtle gradient background behind icon circle - Friendly, helpful copy ("No content yet — start by writing some copy") ### Dashboard Widgets — Premium - Pipeline funnel: animated fill on first load (bars grow from left) - Metric cards: gradient left-border accent (stage color), number count-up animation - Activity feed: staggered fade-in (50ms between items) - Metric card hover: gentle pulse on accent border ## 7. Animation Approach All animations use **CSS only** — no motion library dependency (no framer-motion, no react-spring). Spring-like effects approximated with `cubic-bezier(0.34, 1.56, 0.64, 1)`. All animations respect `prefers-reduced-motion: reduce` — when enabled, transitions are instant (duration: 0ms) and all decorative animations are disabled. ## 8. Migration & Compatibility ### Route Redirects Old routes redirect to new locations via React Router ``: - `/posts` → `/content/posts` - `/calendar` → `/content/posts?view=calendar` - `/translations` → `/content/translations` - `/artefacts` → `/content/design` - `/assets` → `/settings?tab=assets` - `/brands` → `/settings?tab=brands` - `/tasks` → `/projects?tab=tasks` - `/budgets` → `/finance?tab=budgets` ### Data Migration - New `ContentItems` table created via `ensureRequiredTables()` on server restart - New columns (`content_item_id`, `is_original`) added via `FK_COLUMNS` / `TEXT_COLUMNS` — auto-created on restart - Campaign brief columns added via `TEXT_COLUMNS` — auto-created on restart - **No data migration needed for existing records** — existing posts/translations/artefacts continue to work without a content_item_id (they're standalone) ### Rollout Strategy Phased implementation — each phase is independently deployable: 1. **Phase 1**: Nav reorganization + consistency standards (no data model changes) 2. **Phase 2**: Content page with tabs (restructure existing pages as tab sub-views) 3. **Phase 3**: Content Item model + pipeline (new table, FK linkages, pipeline kanban) 4. **Phase 4**: Campaign brief enhancement 5. **Phase 5**: Dashboard redesign 6. **Phase 6**: Premium polish (animations, glass effects, typography) ### Public Routes Unchanged: `/review/:token`, `/review-post/:token`, `/review-translation/:token` continue to work as-is. ## 9. Files Impacted ### Navigation - `client/src/components/Sidebar.jsx` — rewrite nav structure - `client/src/App.jsx` — update routes (remove standalone pages, add Content route) ### Content Page (new) - `client/src/pages/Content.jsx` — new unified page with tabs - `client/src/components/ContentPipelineBoard.jsx` — new pipeline kanban - `client/src/components/ContentDetailPanel.jsx` — new detail panel with pipeline breadcrumb - Existing pages (`PostProduction.jsx`, `Translations.jsx`, `Artefacts.jsx`) become tab sub-components or are refactored into Content ### Campaigns - `client/src/pages/Campaigns.jsx` — add brief fields (goals, metrics, audience) - `client/src/pages/CampaignDetail.jsx` — add brief section, content items list, approval gate - `server/server.js` — add campaign brief fields to schema, approval endpoint ### Dashboard - `client/src/pages/Dashboard.jsx` — full redesign with new widget layout ### Consistency - `client/src/components/SlidePanel.jsx` — standardize width, header layout - `client/src/components/EmptyState.jsx` — add illustrated SVG variants - `client/src/components/SkeletonLoader.jsx` — match actual content dimensions - All page files — standardize header pattern, filter bar, loading states ### Polish - `client/src/index.css` — new animations, glass effects, spring transitions, typography updates - `client/src/components/KanbanBoard.jsx` — enhanced drag animations - `client/src/components/KanbanCard.jsx` — premium hover states - `client/src/components/StatusBadge.jsx` — glass morphism variant - `client/src/components/Modal.jsx` — deeper backdrop blur - `client/src/components/Toast.jsx` — spring animations ### Server - `server/server.js` — content item model, campaign brief fields, pipeline stage tracking - New `ContentItems` table in `REQUIRED_TABLES` - New columns via `FK_COLUMNS`: `content_item_id` on Translations, Artefacts, Posts - New columns via `TEXT_COLUMNS`: `is_original` on Translations, campaign brief fields on Campaigns (goals, target_audience, key_messages, reach_target, engagement_target, conversion_target, approval_status, approved_by, approved_at) ### i18n - `client/src/i18n/en.json` — new keys for Content page, pipeline stages, dashboard widgets, campaign brief - `client/src/i18n/ar.json` — same keys in Arabic