Rebuilds content management around a single admin route (/admin — "BlackDice Studio"), replacing blackdice-studio.html. Publishing writes one JSON content document instead of regenerating HTML files, so it can no longer overwrite hand-made site changes the way the old tool did. - /admin: click-to-edit copy/images, article CRUD with a Word-safe rich text editor, demo clip management, per-page SEO, enquiry log, publish history with rollback - Real per-page URLs for all pages and articles, each with its own meta/canonical/OG/JSON-LD - Newsroom + article pages driven by the CMS post library, seeded from the old studio's export (17 articles) plus a drafted GSMA Open Gateway press release awaiting approval - Demo sections on Mobile SDK and Halo CPE, interactive by default and upgradable to an uploaded clip per slot - Dependency-free Node API server (auth, publish, uploads, snapshots, leads, live sitemap) - Deployment configs for Node/nginx/IIS, Vercel and Netlify See docs/ARCHITECTURE.md, docs/PROJECT-STRUCTURE.md, docs/CMS-GUIDE.md and docs/DEPLOYMENT.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
7.8 KiB
7.8 KiB
Project structure
A directory-by-directory map of the repo. See ARCHITECTURE.md for how these pieces fit together at runtime.
website-react/
├── src/
│ ├── main.tsx Router entry point — one route per page + /blog/:slug + /admin
│ ├── vite-env.d.ts
│ │
│ ├── site/ ── The marketing website ──
│ │ ├── SiteApp.tsx Renders siteMarkup.txt, applies CMS content, mounts React islands
│ │ ├── siteMarkup.txt Page HTML (12 pages) with data-cms hooks — imported as a raw string
│ │ ├── siteController.js Ported vanilla JS: page show/hide, nav, enquiry forms, live feed
│ │ ├── styles.css The site's stylesheet (+ newsroom/article/demo additions)
│ │ ├── blog/
│ │ │ ├── NewsGrid.tsx Newsroom grid (/news) + home page "latest" strip, same data source
│ │ │ └── ArticlePage.tsx Single article view at /blog/<slug>
│ │ └── demos/
│ │ ├── DemoSection.tsx Tabbed demo panel (Mobile SDK) — clip or interactive fallback
│ │ └── DemoPlayer.tsx <video> player for a CMS-configured demo slot
│ │
│ ├── demo/ ── The BlackDice Angel product demo (pre-existing) ──
│ │ ├── DemoScreen.tsx Full interactive demo player (Flows A–D)
│ │ ├── DemoVideoPage.tsx Cinematic video-only page (/demo-video)
│ │ ├── demo.css Scoped reset so the phone UI is pixel-faithful
│ │ ├── components/ Icons, ScoreRing
│ │ ├── context/ DemoContext (interactive flow state)
│ │ ├── data/ mock.ts — sample data for the interactive flows
│ │ └── threats/ Threat-detection scenario library
│ │ ├── scenarios.ts 5 scenario definitions (scam call, SMS, SIM swap, DNS, permissions)
│ │ ├── ThreatDemo.tsx The phone-mockup cinematic player (ThreatCinematic)
│ │ ├── ThreatDemosSlider.tsx Slider through all scenarios (/threat-demos, or embedded)
│ │ └── ThreatDemoPlayerPage.tsx Single scenario at /threat-demo/:id
│ │
│ └── cms/ ── Content model, API client, and the admin app ──
│ ├── types.ts SiteContent, Post, DemoSlot, SiteSettings — the published document's shape
│ ├── pages.ts Route table, default SEO copy, demo-slot ↔ page ↔ scenario mapping
│ ├── store.tsx Merges factory + published content; ContentProvider/useContent; applyContent()
│ ├── api.ts Fetch wrappers for every /api/* route; client-side image downscaling
│ ├── seo.ts Per-route <title>/meta/canonical/OG/JSON-LD writer
│ ├── sanitise.ts DOM-based HTML sanitiser for pasted/edited article bodies
│ ├── generated/ Build artefacts — do not hand-edit
│ │ ├── cmsFields.json Field manifest (652 fields), written by scripts/inject-cms-ids.mjs
│ │ └── seedContent.json Factory content, written by scripts/seed-content.mjs
│ └── admin/ ── BlackDice Studio (/admin) ──
│ ├── AdminApp.tsx Shell: login gate, tabs, publish button, renders SiteApp as the live preview
│ ├── admin.css Studio's chrome — fully namespaced .bdcms-*
│ ├── useDraft.ts Editor's working copy: localStorage mirror, publish, discard, snapshots
│ ├── useInlineEditor.ts Click-to-edit wiring over the previewed site
│ ├── originals.ts Parses the shipped markup for "revert to original" / edited-field markers
│ ├── RichText.tsx Article body editor (contentEditable + toolbar + paste sanitising)
│ ├── PagesPanel.tsx Pages tab — field list, image/stat editing
│ ├── PostsPanel.tsx Articles tab — full post CRUD
│ ├── DemosPanel.tsx Demos tab — clip/poster upload per slot
│ ├── SeoPanel.tsx SEO tab — per-page meta + site-wide settings
│ ├── LeadsPanel.tsx Enquiries tab — submitted leads, CSV export
│ └── HistoryPanel.tsx History tab — snapshots, import/export, discard
│
├── server/
│ └── index.mjs The whole backend: auth, content, uploads, leads, sitemap. No dependencies.
│
├── scripts/
│ ├── inject-cms-ids.mjs Adds data-cms/-img/-num hooks to siteMarkup.txt (idempotent)
│ ├── seed-content.mjs Imports a blackdice-studio.json export into seedContent.json
│ ├── resize-images.mjs Downscales oversized images (used by seed-content.mjs)
│ ├── generate-sitemap.mjs Writes public/sitemap.xml + robots.txt from current content
│ └── dev.mjs Runs the API server + Vite dev server together (npm run dev)
│
├── content-seed/
│ └── additional-posts.json Posts authored in-repo (e.g. the GSMA release) — survive re-imports
│
├── content/ Runtime data — NOT in git (see .gitignore)
│ ├── site-content.json The published document
│ ├── versions/ One snapshot per publish
│ ├── uploads/ Images/clips uploaded via Studio
│ └── leads.jsonl Enquiry form submissions
│
├── public/ Static assets served as-is
│ ├── logo.svg, *.png Brand assets and product screenshots
│ ├── content/posts/ Article hero images imported from the studio export (in git)
│ ├── sitemap.xml, robots.txt Static fallback (server generates a live version too)
│ ├── _redirects Netlify SPA fallback
│ └── web.config IIS SPA fallback
│
├── docs/
│ ├── ARCHITECTURE.md How the system works (this is the deep-dive)
│ ├── PROJECT-STRUCTURE.md This file
│ ├── CMS-GUIDE.md For editors: how to use Studio
│ └── DEPLOYMENT.md For ops: environment, hosting, backups, release checklist
│
├── index.html Vite entry HTML (default meta tags; overwritten per-route at runtime)
├── vite.config.ts Dev server + API proxy config
├── tsconfig.json
├── vercel.json Vercel SPA fallback
├── package.json
└── README.md Start here
Where to make a given kind of change
| I want to… | Change this |
|---|---|
| Edit copy, images or an article | Don't touch code — use /admin |
| Change page layout/structure | src/site/siteMarkup.txt, then npm run cms:ids |
| Add a new page/route | src/cms/pages.ts (PAGES array) + a matching id="pg-pN" block in siteMarkup.txt + Route in main.tsx |
| Change site-wide styling | src/site/styles.css |
| Change Studio's own UI | src/cms/admin/* and admin.css |
| Add an API endpoint | server/index.mjs (handleApi) |
| Change what's in the published document | src/cms/types.ts (SiteContent) — update mergeContent in store.tsx too |
| Add a demo slot | src/cms/pages.ts (DEMO_SLOTS) + a mount <div> in siteMarkup.txt + portal it in SiteApp.tsx |
| Change article sanitisation rules | Both src/cms/sanitise.ts and scripts/seed-content.mjs — keep them in step |