diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 66411c2..5b5009d 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -15,6 +15,7 @@ import AdminUsersPage from './pages/admin/AdminUsersPage' import AdminDropdownsPage from './pages/admin/AdminDropdownsPage' import AdminClientsPage from './pages/admin/AdminClientsPage' import LoginPage from './pages/LoginPage' +import HelpPage from './pages/HelpPage' function AuthGate({ children }: { children: React.ReactNode }) { const { instance, inProgress, accounts } = useMsal() @@ -109,6 +110,7 @@ export default function App() { } /> } /> } /> + } /> } /> diff --git a/frontend/src/components/layout/Sidebar.tsx b/frontend/src/components/layout/Sidebar.tsx index 37afbe7..3898443 100644 --- a/frontend/src/components/layout/Sidebar.tsx +++ b/frontend/src/components/layout/Sidebar.tsx @@ -34,6 +34,13 @@ const IconPlus = () => ( ) +const IconHelp = () => ( + + + + + +) export default function Sidebar() { const navigate = useNavigate() @@ -125,6 +132,18 @@ export default function Sidebar() { Upload Brief + + {/* ── Divider ── */} diff --git a/frontend/src/pages/HelpPage.tsx b/frontend/src/pages/HelpPage.tsx new file mode 100644 index 0000000..4992092 --- /dev/null +++ b/frontend/src/pages/HelpPage.tsx @@ -0,0 +1,419 @@ +import { useState } from 'react' +import { useNavigate } from 'react-router-dom' +import { useAuthStore } from '../stores/useAuthStore' + +// ── Section types ────────────────────────────────────────────────────────────── + +interface Section { + id: string + icon: string + title: string + adminOnly?: boolean + content: React.ReactNode +} + +// ── Reusable helpers ─────────────────────────────────────────────────────────── + +const H2 = ({ children }: { children: React.ReactNode }) => ( +

{children}

+) +const H3 = ({ children }: { children: React.ReactNode }) => ( +

{children}

+) +const P = ({ children }: { children: React.ReactNode }) => ( +

{children}

+) +const Li = ({ children }: { children: React.ReactNode }) => ( +
  • {children}
  • +) +const Code = ({ children }: { children: React.ReactNode }) => ( + {children} +) +const Tip = ({ children }: { children: React.ReactNode }) => ( +
    + Tip: + {children} +
    +) +const Steps = ({ items }: { items: string[] }) => ( +
      + {items.map((item, i) => ( +
    1. + ))} +
    +) + +// ── Sections ─────────────────────────────────────────────────────────────────── + +const SECTIONS: Section[] = [ + { + id: 'overview', + icon: '📋', + title: 'Overview', + content: ( + <> +

    What is AC Helper?

    +

    + AC Helper is an Activation Calendar management tool for Oliver Agency. + It lets you create and manage deliverable sheets, extract deliverables from briefs using AI, + and export them in a format tailored to each client. +

    +

    Core concepts

    +
      +
    • Sheet — a spreadsheet of deliverables (rows). Each row is one ad/asset.
    • +
    • Brief extraction — upload a client brief (PDF, PPTX, DOCX, XLSX) and AI reads it and populates a sheet automatically.
    • +
    • AI command — type a plain-English instruction to add or modify rows in the sheet.
    • +
    • Client — each client can have its own Category/Media hierarchy and CSV export format.
    • +
    • Export template — define which columns appear in the exported CSV and what they're called.
    • +
    +

    Navigation

    +
      +
    • The sidebar (left) lists all your sheets. Click any sheet to open it.
    • +
    • Dashboard — quick access to recent sheets and extractions.
    • +
    • Upload Brief — start a new AI extraction.
    • +
    • Admins see Users / Clients / Dropdowns links at the bottom of the sidebar.
    • +
    + + ), + }, + { + id: 'sheets', + icon: '📄', + title: 'Sheets', + content: ( + <> +

    Working with Sheets

    +

    Create a new sheet

    + + button next to "Sheets" in the sidebar, or click New Sheet on the Dashboard.', + 'A blank sheet opens immediately. The name defaults to today\'s date — you can rename it.', + ]} /> + +

    Rename, duplicate, delete

    +

    Right-click any sheet in the sidebar to open the context menu with Rename, Duplicate and Delete options.

    + +

    Sheet columns

    +
      +
    • Title — deliverable name / description
    • +
    • Status — Booked / To-do / In Progress / Done
    • +
    • Category — task type (e.g. Social (Static), OOH Print). Dropdown — values depend on the selected client.
    • +
    • Media — media channel. Dependent on Category.
    • +
    • Sub-media — sub-channel
    • +
    • Format — size/spec (e.g. 1080x1080)
    • +
    • Supply date / Live date — key dates
    • +
    • Language / Country — market
    • +
    • Quantity — number of units
    • +
    + +

    Editing cells

    +

    Click any cell to edit. Category and Media are dropdowns — the available values come from the selected client's hierarchy (or the global list if no client is set).

    + Changes are auto-saved a few seconds after you stop typing. The "Saving…" indicator appears in the header. + +

    Assign a client to a sheet

    +

    In the sheet header, select a client from the Client dropdown. This loads that client's Category/Media hierarchy and their export template.

    + +

    Clear sheet

    +

    Click Clear in the sheet header to remove all rows and reset the AI activity log.

    + + ), + }, + { + id: 'ai', + icon: '🤖', + title: 'AI Commands', + content: ( + <> +

    AI Commands

    +

    + The command bar at the bottom of every sheet lets you add or modify deliverables using plain English. + The AI understands the client's Category/Media hierarchy and will only use valid values. +

    + +

    Example commands

    +
      +
    • Add 5 social media banners for UK
    • +
    • Add 3 email newsletters for DE, FR, ES
    • +
    • Create 10 OOH Print A4 deliverables for Germany
    • +
    • Add 2 TVC 30s adaptations for France, supply 15 May, live 1 June
    • +
    • Change all UK rows to "In Progress"
    • +
    + +

    YOLO mode

    +

    + Toggle the YOLO switch to stop the AI from asking clarifying questions. + It will make its best guess and apply changes immediately. Useful when you're in a hurry. +

    + +

    Voice input

    +

    + Click the microphone button to start dictating. Click again to stop. + The transcript appears in the command field in real-time — edit it if needed, then press Enter or click Send. +

    + Voice works best in Chrome / Edge. Make sure microphone permission is granted for this site. + +

    Quick starters

    +

    Below the command bar there are pre-filled example commands. Click one to load it into the input, then customise and send.

    + +

    Activity log

    +

    Every AI action is recorded in the activity log (visible below the sheet). It shows what the AI did, which rows were affected, and any messages from the AI.

    + + ), + }, + { + id: 'brief', + icon: '📁', + title: 'Brief Extraction', + content: ( + <> +

    Extracting Deliverables from a Brief

    +

    + The AI can read a client brief document and automatically populate a sheet with the deliverables it finds. + Supported formats: .pdf, .pptx, .docx, .xlsx, .ppt, .doc, .xls +

    + +

    Step-by-step

    + Upload Brief in the sidebar or on the Dashboard.', + '(Optional) Select a Client from the dropdown — this helps the AI use the right categories.', + 'Drag & drop your file(s) or click to browse. You can upload multiple files at once.', + 'The extraction runs in the background. You\'ll see a progress card appear.', + 'When complete, click Review to inspect the extracted deliverables.', + 'On the review page, adjust rows if needed, then click Import to Sheet to add them to an existing sheet or create a new one.', + ]} /> + + You can upload multiple briefs at once. Each one becomes a separate extraction job. + +

    Review page

    +

    + The review page shows all extracted rows in a table. You can edit any cell before importing. + Use Append to add rows to an existing sheet, or Replace to overwrite it. +

    + + ), + }, + { + id: 'export', + icon: '⬇️', + title: 'Export CSV', + content: ( + <> +

    Exporting to CSV

    +

    + Click Export CSV in the sheet header to download the current sheet as a CSV file. + The column names and order depend on the active export template. +

    + +

    Export template priority

    +

    The system uses the first template it finds, in this order:

    +
      +
    1. Client template — set by admin for the selected client
    2. +
    3. Your personal template — set by you using the ⚙ button
    4. +
    5. Global template — set by admin in the Dropdowns admin page
    6. +
    7. Built-in default — standard AC columns
    8. +
    + +

    Set your personal export template

    + ⚙ button next to "Export CSV" in the sheet header.', + 'A panel opens. Drag & drop a sample .csv file — it only needs the header row.', + 'The system detects your column names and suggests which internal field each one maps to.', + 'Adjust the mapping if needed using the dropdowns.', + 'Click Save template. From now on every export will use your column names.', + ]} /> + + To reset to the default format, open the ⚙ panel and click Remove. + + ), + }, + { + id: 'admin-clients', + icon: '🏢', + title: 'Admin: Clients', + adminOnly: true, + content: ( + <> +

    Managing Clients

    +

    Go to Clients in the sidebar (admin only). Each client can have its own Category/Media hierarchy and CSV export template.

    + +

    Create a client

    + Add Client field and press Enter or click Create.', + 'The client now appears in the list and in the Client dropdown on every sheet.', + ]} /> + +

    Upload a custom Category/Media hierarchy

    +

    + By default, sheets use the global dropdown hierarchy. You can override this per client with an .xlsx file. +

    + .xlsx file onto the dropdown zone (or click to browse).', + 'The system reads the file headers and shows you the detected column mapping.', + 'Confirm mapping: verify which column is "Category name", which is "Status", which is "Media types".', + 'A full preview of parsed categories appears. Click Apply to save.', + 'The client card shows a Custom hierarchy badge.', + ]} /> + Expected Excel format: Column A = Category name, Column E = Status (Active/Archived), Column G = Media types (comma-separated). The mapping step lets you correct this if your file differs. + +

    Upload a custom export CSV template

    + Export CSV template section.', + 'Drop a sample .csv file. Only the header row matters.', + 'Map each of your column names to the internal field it should contain.', + 'Click Save template.', + ]} /> + +

    Reset to global

    +

    Click Reset to global on a client card to remove the custom hierarchy and revert to the global dropdown list.

    + +

    Delete a client

    +

    Click Delete on a client card. This also removes their custom dropdown and export template files.

    + + ), + }, + { + id: 'admin-dropdowns', + icon: '🗂️', + title: 'Admin: Dropdowns', + adminOnly: true, + content: ( + <> +

    Global Dropdown Data

    +

    + Go to Dropdowns in the sidebar. This page manages the global Category/Media hierarchy + used by sheets that have no client assigned (or whose client has no custom file). +

    + +

    Upload a new hierarchy

    + .xlsx file onto the upload zone.', + 'Confirm the detected column mapping (Category name / Status / Media types).', + 'Review the full list of parsed categories.', + 'Click Apply Changes to replace the global data.', + ]} /> + +

    The current global data is always shown at the bottom of the page.

    + Uploading a new file replaces the entire global list. Clients with custom hierarchies are not affected. + + ), + }, + { + id: 'admin-users', + icon: '👥', + title: 'Admin: Users', + adminOnly: true, + content: ( + <> +

    User Management

    +

    Go to Users in the sidebar. Every user who has signed in appears here.

    + +

    Roles

    +
      +
    • user — can create and manage their own sheets, upload briefs, export CSV.
    • +
    • admin — everything above, plus access to the admin panel (Users, Clients, Dropdowns).
    • +
    + +

    Change a user's role

    +

    Click the role badge next to a user and select admin or user from the dropdown.

    + +

    Deactivate a user

    +

    Toggle the Active switch off to prevent a user from logging in. Their data is preserved.

    + +

    Admin bootstrap

    +

    + The emails daveporter@oliver.agency and vadymsamoilenko@oliver.agency automatically + receive admin role on first login and cannot be downgraded through the UI. +

    + + ), + }, + { + id: 'login', + icon: '🔐', + title: 'Login & Access', + content: ( + <> +

    Signing In

    + +

    Standard login (Microsoft SSO)

    +

    Click Sign in with Microsoft on the login page. You'll be redirected to Microsoft for authentication. Use your Oliver Agency account.

    + +

    Emergency access

    +

    + If Microsoft SSO / 2FA is unavailable, use the emergency bypass: +

    + Emergency access link at the bottom.', + 'Enter the emergency token (ask an admin).', + 'Click Sign in.', + ]} /> +

    The emergency token is configured in the server .env file as EMERGENCY_TOKEN=…. If not set, emergency access is disabled.

    + +

    Signing out

    +

    There is no explicit sign-out button — closing the browser tab ends the session. The Microsoft SSO token expires and you'll be asked to sign in again on your next visit.

    + + ), + }, +] + +// ── Page ─────────────────────────────────────────────────────────────────────── + +export default function HelpPage() { + const navigate = useNavigate() + const user = useAuthStore(s => s.user) + const isAdmin = user?.role === 'admin' + const [activeId, setActiveId] = useState('overview') + + const visible = SECTIONS.filter(s => !s.adminOnly || isAdmin) + const active = visible.find(s => s.id === activeId) ?? visible[0] + + return ( +
    + {/* Left nav */} +
    +
    + User Guide +
    + +
    + + {/* Content */} +
    +
    + {active.content} +
    +
    +
    + ) +}