--- phase: 43-documents-branding plan: 03 type: execute wave: 3 depends_on: ["43-01", "43-02"] files_modified: - ui/src/components/DocumentGeneratePanel.tsx - ui/src/components/BrandKitPanel.tsx - ui/src/components/BrandKitResult.tsx - ui/src/pages/ContentStudio.tsx autonomous: false requirements: [DOC-01, DOC-02, DOC-03, BRAND-01, BRAND-02, BRAND-03, BRAND-04, BRAND-05, BRAND-06] must_haves: truths: - "User can select document type (report, invoice, one-pager, api-docs) and generate a PDF" - "Generated PDF can be downloaded from the UI" - "User can describe a brand and generate a full brand kit" - "Brand kit result shows logo, avatars, social images, signature, letterhead previews" - "User can download the entire brand kit as a ZIP file" - "ContentStudio has Documents and Brand tabs alongside existing tabs" artifacts: - path: "ui/src/components/DocumentGeneratePanel.tsx" provides: "Document type selection, prompt input, PDF generation trigger, download" min_lines: 60 - path: "ui/src/components/BrandKitPanel.tsx" provides: "Brand prompt input, generation trigger, result display" min_lines: 50 - path: "ui/src/components/BrandKitResult.tsx" provides: "Brand kit display: logo, avatars, social images, templates, guidelines, ZIP download" min_lines: 80 - path: "ui/src/pages/ContentStudio.tsx" provides: "Documents and Brand tabs added" contains: "documents" key_links: - from: "ui/src/components/DocumentGeneratePanel.tsx" to: "useContentJob" via: "submit('pdf-document', { docType, prompt, title })" pattern: "pdf-document" - from: "ui/src/components/BrandKitPanel.tsx" to: "useContentJob" via: "submit('brand-kit', { prompt })" pattern: "brand-kit" - from: "ui/src/pages/ContentStudio.tsx" to: "ui/src/components/DocumentGeneratePanel.tsx" via: "import + TabsContent" pattern: "DocumentGeneratePanel" --- UI panels for document generation and brand kit, wired into ContentStudio tabs. Purpose: Give users a UI to generate PDFs (reports, invoices, one-pagers, API docs) and complete brand identity kits from a prompt. Adds "Documents" and "Brand" tabs to ContentStudio. Output: DocumentGeneratePanel, BrandKitPanel, BrandKitResult components, updated ContentStudio. @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/43-documents-branding/43-RESEARCH.md @.planning/phases/43-documents-branding/43-01-SUMMARY.md @.planning/phases/43-documents-branding/43-02-SUMMARY.md @ui/src/pages/ContentStudio.tsx @ui/src/components/SocialPostPanel.tsx @ui/src/hooks/useContentJob.ts @ui/src/api/contentJobs.ts From server/src/services/renderers/types.ts (Plan 01): ```typescript export interface PdfDocumentBundle { type: "pdf-document-bundle"; docType: string; title: string; pdfBase64: string; } export interface BrandKitBundle { type: "brand-kit-bundle"; spec: { name: string; tagline: string; primaryColor: string; secondaryColor: string; fontStyle: string; industry: string; }; logoSvgBase64: string; avatarPngs: Record; // "512"|"256"|"128"|"64"|"32" -> base64 socialImages: Record; // "twitter-profile" etc -> base64 signatureHtml: string; letterheadHtml: string; guidelinesPdfBase64: string; zipBase64: string; } ``` From ui/src/hooks/useContentJob.ts: ```typescript export function useContentJob(companyId: string): { submit: (jobType: string, input: Record) => void; status: string | null; bundle: unknown; resultAssetId: string | null; error: string | null; }; ``` From ui/src/api/contentJobs.ts: ```typescript export function getContentJobAsset(companyId: string, assetId: string): Promise<{ url: string }>; ``` UI pattern from SocialPostPanel.tsx: - useContentJob for submit + SSE progress - When status="done" && resultAssetId && !bundle -> fetch asset -> JSON.parse -> setBundle - Display result component - Download via URL.createObjectURL + .click() Task 1: Create DocumentGeneratePanel and BrandKitPanel + BrandKitResult components ui/src/components/DocumentGeneratePanel.tsx, ui/src/components/BrandKitPanel.tsx, ui/src/components/BrandKitResult.tsx - ui/src/components/SocialPostPanel.tsx (full file — reference pattern for useContentJob, asset fetch, bundle state, download trigger) - ui/src/components/SocialPostResult.tsx (result display pattern) - ui/src/hooks/useContentJob.ts (hook API) - ui/src/api/contentJobs.ts (getContentJobAsset) - ui/src/components/WallpaperGeneratePanel.tsx (another panel example for download pattern) **DocumentGeneratePanel.tsx:** - Props: `{ companyId: string }` - State: prompt (string), title (string), docType ("report" | "invoice" | "one-pager" | "api-docs"), bundle (PdfDocumentBundle | null) - Define PdfDocumentBundle type locally (same pattern as SocialPostBundle in SocialPostPanel — bundle types are defined locally in panel files per project convention for wallpaper/social, BUT research says to use types.ts for these. Follow research: import is server-side only. Define locally in UI file matching the server shape.) - useContentJob(companyId) for submit + status tracking - UI layout using shadcn Card, CardHeader, CardContent: - Select dropdown for docType with 4 options: Report, Invoice, One-Pager, API Documentation - Input for title - Textarea for prompt/content description - Generate button (disabled when loading, shows Loader2 spinner) - Progress bar when status is "running" or "queued" - When status="done" && resultAssetId && !bundle: fetch asset via getContentJobAsset, parse JSON, setBundle - When bundle exists: show title, docType badge, and a "Download PDF" button - Download PDF: decode pdfBase64 -> Uint8Array -> Blob("application/pdf") -> URL.createObjectURL -> .click() -> revokeObjectURL **BrandKitPanel.tsx:** - Props: `{ companyId: string }` - State: prompt (string), bundle (BrandKitBundle | null) - Define BrandKitBundle type locally (matching server shape) - useContentJob(companyId) for submit + status - UI layout: - Textarea for brand description prompt (placeholder: "Describe the brand you want to create -- name, industry, style preferences, colors...") - Generate button with loading state - Progress bar during generation - When done: fetch asset, parse JSON, setBundle, render BrandKitResult **BrandKitResult.tsx:** - Props: `{ bundle: BrandKitBundle }` - Display in a grid layout: - **Logo section**: SVG preview via `` - **Avatars section**: Grid of 5 avatar sizes as `` with size labels - **Social images section**: Grid of social platform images with platform name labels - **Templates section**: "Email Signature" and "Letterhead" cards with HTML preview in sandboxed iframes (`srcdoc={signatureHtml}`) - **Guidelines**: "Brand Guidelines" card with a "Download PDF" button (decode guidelinesPdfBase64 -> blob download) - **Full Kit Download**: Prominent "Download Brand Kit (ZIP)" button at the bottom - ZIP download function: same base64-to-blob pattern but with type "application/zip" and `.zip` extension (use the downloadZip pattern from RESEARCH.md) - PDF download for guidelines: same base64-to-blob pattern with type "application/pdf" Use shadcn components: Card, CardHeader, CardTitle, CardContent, Button, Textarea, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Progress. Import Loader2 from lucide-react. - grep -q "DocumentGeneratePanel" ui/src/components/DocumentGeneratePanel.tsx - grep -q "pdf-document" ui/src/components/DocumentGeneratePanel.tsx - grep -q "BrandKitPanel" ui/src/components/BrandKitPanel.tsx - grep -q "brand-kit" ui/src/components/BrandKitPanel.tsx - grep -q "BrandKitResult" ui/src/components/BrandKitResult.tsx - grep -q "zipBase64" ui/src/components/BrandKitResult.tsx - grep -q "Download Brand Kit" ui/src/components/BrandKitResult.tsx pnpm --filter @paperclipai/ui exec tsc --noEmit Document and brand kit panels render with correct form inputs, submit correct job types, display results, and provide download functionality for PDF and ZIP. Task 2: Add Documents and Brand tabs to ContentStudio ui/src/pages/ContentStudio.tsx - ui/src/pages/ContentStudio.tsx (current tab structure — 5 tabs: diagrams, icons, themes, wallpapers, social) 1. Add imports at the top of ContentStudio.tsx: ```typescript import { DocumentGeneratePanel } from "../components/DocumentGeneratePanel"; import { BrandKitPanel } from "../components/BrandKitPanel"; ``` 2. Add two new TabsTrigger entries in the TabsList, AFTER the "Social" trigger: ```tsx Documents Brand ``` 3. Add two new TabsContent blocks after the social TabsContent: ```tsx {companyId ? ( ) : ( Select a company to get started. )} {companyId ? ( ) : ( Select a company to get started. )} ``` Keep `defaultValue="diagrams"` unchanged. Use stable string values "documents" and "brand" for tab IDs. - grep -q "DocumentGeneratePanel" ui/src/pages/ContentStudio.tsx - grep -q "BrandKitPanel" ui/src/pages/ContentStudio.tsx - grep -q '"documents"' ui/src/pages/ContentStudio.tsx - grep -q '"brand"' ui/src/pages/ContentStudio.tsx pnpm --filter @paperclipai/ui exec tsc --noEmit ContentStudio has 7 tabs: Diagrams, Icons, Themes, Wallpapers, Social, Documents, Brand. TypeScript compiles cleanly. Task 3: Visual verification of Documents and Brand tabs ui/src/pages/ContentStudio.tsx Human verifies the complete document generation and brand kit UI end-to-end. How to verify: 1. Navigate to Content Studio in the Nexus UI 2. Verify 7 tabs visible: Diagrams, Icons, Themes, Wallpapers, Social, Documents, Brand 3. Click "Documents" tab: - Select "Report" from dropdown - Enter a title and prompt - Click Generate — verify spinner/progress appears - When done, verify "Download PDF" button appears 4. Click "Brand" tab: - Enter a brand description - Click Generate — verify progress appears - When done, verify logo SVG preview, avatar grid, social images, template previews, and "Download Brand Kit (ZIP)" button 5. Download the ZIP — verify it contains logo/, social/, templates/, guidelines.pdf Resume signal: Type "approved" or describe issues. pnpm --filter @paperclipai/ui exec tsc --noEmit User confirms Documents and Brand tabs work end-to-end: PDF generation + download, brand kit generation + preview + ZIP download. - `pnpm --filter @paperclipai/ui exec tsc --noEmit` compiles without errors - ContentStudio renders 7 tabs - Document generation flow works end-to-end - Brand kit generation shows all asset previews and ZIP download - Documents tab: user can select type, enter prompt, generate PDF, download it - Brand tab: user can enter description, generate full brand kit, see all previews, download ZIP - All 7 ContentStudio tabs render correctly - TypeScript clean After completion, create `.planning/phases/43-documents-branding/43-03-SUMMARY.md`
Select a company to get started.