diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..fcbd9ff4 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,128 @@ +# AGENTS.md — @story-cms/kit + +Instructions for AI coding agents (Codex, Cursor, Claude Code, Copilot, etc.) working in this repository. + +## Project overview + +**Journeys Studio Kit** (`@story-cms/kit`) is a publishable npm package that provides: + +- **Frontend**: Vue 3 + Inertia.js UI components, field widgets, and Pinia stores +- **Backend**: AdonisJS 6 services, models, middleware, and scaffolding stubs +- **Documentation**: [Histoire](https://histoire.dev/) component stories (not Storybook) + +This repo is the **kit library**, not a full CMS app. Client apps (e.g. `@bnap/cms`) consume the built package. Local development uses Histoire (`npm run dev`) to preview and document components. + +## Repository map + +| Path | Purpose | +|------|---------| +| `src/frontend/` | Vue components, stores, styles | +| `src/backend/` | Adonis services, models, middleware, stubs | +| `src/types.ts` | Shared TypeScript types | +| `tests/unit/` | Playwright unit tests | +| `tests/e2e/` | Playwright end-to-end tests | +| `scripts/` | Build helpers (e.g. color usage generator) | +| `.cursor/rules/` | Detailed, file-scoped Cursor rules (see index below) | + +Full directory tree: `.cursor/rules/project-structure.mdc` + +## Commands + +```bash +npm run dev # Histoire dev server (component docs) +npm run build # types + frontend (Vite) + backend (tsc) +npm run ui:build # Frontend only +npm run backend:build # Backend only +npm run lint # ESLint +npm run lint:fix # ESLint with auto-fix +npm run test # Playwright unit tests +npm run test:e2e # Playwright e2e tests +npm run colors:usage # Regenerate colors.palette.ts + colors.usage.ts +npm run story:build # Build Histoire static site +npm run story:preview # Preview built Histoire site +``` + +Run `npm run colors:usage` after changing theme tokens in `tailwind.config.js` or color-class usage in the frontend. + +## Frontend conventions + +- Vue 3 **Composition API** with ` diff --git a/src/frontend/dashboard/action-card.vue b/src/frontend/dashboard/action-card.vue new file mode 100644 index 00000000..52f6055a --- /dev/null +++ b/src/frontend/dashboard/action-card.vue @@ -0,0 +1,34 @@ + + + diff --git a/src/frontend/dashboard/action-grid.story.vue b/src/frontend/dashboard/action-grid.story.vue new file mode 100644 index 00000000..fc3bd371 --- /dev/null +++ b/src/frontend/dashboard/action-grid.story.vue @@ -0,0 +1,41 @@ + + + diff --git a/src/frontend/dashboard/action-grid.vue b/src/frontend/dashboard/action-grid.vue new file mode 100644 index 00000000..fab690b8 --- /dev/null +++ b/src/frontend/dashboard/action-grid.vue @@ -0,0 +1,40 @@ + + + diff --git a/src/frontend/dashboard/dashboard-index.story.vue b/src/frontend/dashboard/dashboard-index.story.vue index bf00c72b..864ffa20 100644 --- a/src/frontend/dashboard/dashboard-index.story.vue +++ b/src/frontend/dashboard/dashboard-index.story.vue @@ -55,7 +55,6 @@ isManager: true, isAdmin: false, role: 'editor', - language: '*', }" :translation-progress="translationProgress" :is-read-only="false" @@ -75,23 +74,19 @@ const loadData: StoryHandler = ({ app, story, variant }): void => { miniSidebar({ app, story, variant }); }; +const daysAgo = (days: number): string => + new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString(); + +const yesterday = daysAgo(1); +const aboutAWeekAgo = daysAgo(8); +const earlyLastYear = daysAgo(400); +const overAYearAgo = daysAgo(750); + const translationProgress = [ { progress: [ - { - name: 'Interface', - done: 100, - draft: 0, - total: 100, - lastUpdated: '2025-04-10 15:22:16.448+03', - }, - { - name: 'Content', - done: 200, - draft: 0, - total: 200, - lastUpdated: '2025-04-10 15:22:16.448+03', - }, + { name: 'Interface', done: 100, draft: 0, total: 100, lastUpdated: yesterday }, + { name: 'Content', done: 35, draft: 15, total: 100, lastUpdated: yesterday }, ], language: 'German', locale: 'de', @@ -99,23 +94,95 @@ const translationProgress = [ }, { progress: [ - { - name: 'Interface', - done: 75, - draft: 0, - total: 100, - lastUpdated: '2025-04-10 15:22:16.448+03', - }, - { - name: 'Content', - done: 150, - draft: 50, - total: 200, - lastUpdated: '2025-04-10 15:22:16.448+03', - }, + { name: 'Interface', done: 100, draft: 0, total: 100, lastUpdated: earlyLastYear }, + { name: 'Content', done: 200, draft: 0, total: 200, lastUpdated: earlyLastYear }, + ], + language: 'Francais', + locale: 'fr', + isReadOnly: false, + }, + { + progress: [ + { name: 'Interface', done: 100, draft: 0, total: 100, lastUpdated: earlyLastYear }, + { name: 'Content', done: 150, draft: 0, total: 150, lastUpdated: earlyLastYear }, + ], + language: 'Latviešu', + locale: 'lv', + isReadOnly: false, + }, + { + progress: [ + { name: 'Interface', done: 100, draft: 0, total: 100, lastUpdated: aboutAWeekAgo }, + { name: 'Content', done: 70, draft: 30, total: 100, lastUpdated: aboutAWeekAgo }, + ], + language: 'Español', + locale: 'es', + isReadOnly: false, + }, + { + progress: [ + { name: 'Interface', done: 100, draft: 0, total: 100, lastUpdated: yesterday }, + { name: 'Content', done: 35, draft: 15, total: 100, lastUpdated: yesterday }, + ], + language: 'Hindi', + locale: 'hi', + isReadOnly: false, + }, + { + progress: [ + { name: 'Interface', done: 75, draft: 0, total: 100, lastUpdated: yesterday }, + { name: 'Content', done: 50, draft: 0, total: 100, lastUpdated: yesterday }, + ], + language: 'Swiss German Alemanni', + locale: 'gsw', + isReadOnly: false, + }, + { + progress: [ + { name: 'Interface', done: 100, draft: 0, total: 100, lastUpdated: yesterday }, + { name: 'Content', done: 80, draft: 20, total: 100, lastUpdated: yesterday }, + ], + language: 'Japanese', + locale: 'ja', + isReadOnly: false, + }, + { + // done: 1 (not 0) keeps `done !== total` so language-block.vue doesn't + // treat this trivially-equal 0-total pair as "all done"; total: 0 gives + // each ring's blank/no-data look. + progress: [ + { name: 'Interface', done: 1, draft: 0, total: 0, lastUpdated: overAYearAgo }, + { name: 'Content', done: 1, draft: 0, total: 0, lastUpdated: overAYearAgo }, + ], + language: 'Korean', + locale: 'ko', + isReadOnly: false, + }, + { + progress: [ + { name: 'Interface', done: 75, draft: 0, total: 100, lastUpdated: yesterday }, + { name: 'Content', done: 100, draft: 0, total: 200, lastUpdated: yesterday }, + ], + language: 'Marathi', + locale: 'mr', + isReadOnly: false, + }, + { + progress: [ + { name: 'Interface', done: 100, draft: 0, total: 100, lastUpdated: yesterday }, + { name: 'Content', done: 35, draft: 15, total: 100, lastUpdated: yesterday }, + ], + language: 'Portuguese', + locale: 'pt', + isReadOnly: false, + }, + { + progress: [ + { name: 'Interface', done: 0, draft: 0, total: 0, lastUpdated: '' }, + { name: 'Content', done: 0, draft: 0, total: 0, lastUpdated: '' }, ], - language: 'Bengali', - locale: 'bn', + language: 'Cantonese', + locale: 'yue', isReadOnly: false, }, ]; diff --git a/src/frontend/dashboard/dashboard-index.vue b/src/frontend/dashboard/dashboard-index.vue index 487ce706..ef873a19 100644 --- a/src/frontend/dashboard/dashboard-index.vue +++ b/src/frontend/dashboard/dashboard-index.vue @@ -1,46 +1,16 @@ @@ -48,9 +45,10 @@ diff --git a/src/frontend/dashboard/ring-block.story.vue b/src/frontend/dashboard/ring-block.story.vue deleted file mode 100644 index e35ef4b4..00000000 --- a/src/frontend/dashboard/ring-block.story.vue +++ /dev/null @@ -1,51 +0,0 @@ - - - diff --git a/src/frontend/dashboard/ring-block.vue b/src/frontend/dashboard/ring-block.vue deleted file mode 100644 index fe0ab80c..00000000 --- a/src/frontend/dashboard/ring-block.vue +++ /dev/null @@ -1,121 +0,0 @@ - - - diff --git a/src/frontend/dashboard/ring.story.vue b/src/frontend/dashboard/ring.story.vue index 580109c7..e80ddbc7 100644 --- a/src/frontend/dashboard/ring.story.vue +++ b/src/frontend/dashboard/ring.story.vue @@ -1,61 +1,153 @@ diff --git a/src/frontend/dashboard/ring.vue b/src/frontend/dashboard/ring.vue index 302cac66..70554070 100644 --- a/src/frontend/dashboard/ring.vue +++ b/src/frontend/dashboard/ring.vue @@ -1,115 +1,226 @@ +
+
+

+ {{ item.name }} +

+
+
- {{ - label - }} +
+ + + + +
+ {{ item.data.label }} +
+
+

+ {{ item.name }} +

-

- {{ name }} -

+ diff --git a/src/frontend/dashboard/stat-tile.vue b/src/frontend/dashboard/stat-tile.vue index f24c85ee..82ecd477 100644 --- a/src/frontend/dashboard/stat-tile.vue +++ b/src/frontend/dashboard/stat-tile.vue @@ -1,7 +1,7 @@