Commit Graph

224 Commits

Author SHA1 Message Date
kayjaydee eca3e1d0b6 feat(06-02): add Blog nav link in AppHeader between Hytale and Projects
- Insert { key: 'blog', path: '/blog' } in navLinks computed array
- Position: between hytale and projects (D-15 ordering)
- Template v-for iterations unchanged — new link auto-propagates to
  desktop nav + mobile slideover
- Label resolved via t(`nav.${link.key}`) → uses nav.blog key
  added in Task 2.1
2026-04-22 09:11:27 +02:00
kayjaydee 68f55d4157 feat(06-02): add blog i18n keys (nav.blog, a11y.blog*, blog.*)
- Add nav.blog in FR (Blog) + EN (Blog)
- Add a11y.blogTocToggle, blogPrev, blogNext with {title} interpolation
- Add blog.* block: title, subtitle, stats (articles/tags/languages),
  readingTime ({minutes} interpolation), prevArticle, nextArticle,
  backToBlog, toc.title, emptyState (title/description/cta),
  breadcrumb (home/blog)
- FR uses accents (Bientôt, précédent, Sommaire) per projects convention
2026-04-22 09:11:07 +02:00
kayjaydee f05cdebbcf docs(06-01): complete content schema + reading-time foundation plan
- Add 06-01-SUMMARY.md (5 tasks shipped, 0 deviations).
- Update STATE.md: Phase 6 Plan 06-01 shipped (1/4), gotchas recorded
  (hook schema strip, Nitro ~/ alias), next plan = 06-02.
- Update ROADMAP.md M1.1 progress: Phase 5 Complete, Phase 6 at 1/4.
2026-04-22 09:08:42 +02:00
kayjaydee 0752468f07 chore(06-01): mark test-kotlin-syntax articles as draft (FR + EN)
- Add `draft: true` to frontmatter of both test-kotlin-syntax.md files
  so they are excluded from all `queryCollection(...).where('draft', '=', false)`
  listings (D-14).
- Articles remain accessible via direct URL (no draft filter on `.path(x).first()`),
  keeping them available for internal rendering tests.
- Listings will be empty until real Hytale seed articles land in Phase 8 —
  the empty state will render per D-16 ("Hytale articles coming soon" CTA).
- Body content untouched (only frontmatter +1 line each).
2026-04-22 09:05:47 +02:00
kayjaydee 64dfe376bf feat(06-01): add useReadingTime composable fallback (200 wpm)
- Pure synchronous helper returning minutes (>= 1) from either a pre-computed
  word count (number) or raw text (string, tokenized on whitespace).
- Client-side safety net when `article.minutes` isn't yet populated
  (e.g., dev hot-reload before the Nitro hook re-parsed). Source of truth
  remains the Nitro `content:file:afterParse` hook (D-19).
- Same 200 wpm formula as server-side hook — ensures listing ↔ article parity.
- Auto-imported by Nuxt thanks to `use*` naming convention.
2026-04-22 09:04:53 +02:00
kayjaydee b5fe5deed5 feat(06-01): add Nitro hook content:file:afterParse for reading-time injection
- Register `content:file:afterParse` hook to inject `wordCount` + `minutes`
  on every parsed markdown content object (D-19: 200 wpm, floor 1 min).
- Import pure util `countWordsInMinimalBody` from app/utils/countWords.
- Guard against non-`.md` files (defensive — hook fires on all sources).
- Values persist in @nuxt/content SQLite DB and are queryable via
  queryCollection thanks to matching Zod fields (content.config.ts).
2026-04-22 09:02:23 +02:00
kayjaydee 28a84e0b64 feat(06-01): add countWordsInMinimalBody util for reading-time computation
- Pure AST traversal of @nuxt/content v3 minimal body shape
- Skips code and pre tags (code snippets are not readable prose)
- Zero dependency, zero import, reused by Nitro hook
2026-04-22 08:57:05 +02:00
kayjaydee b56c607a00 feat(06-01): extend blogSchema with draft/wordCount/minutes fields
- Add draft: z.boolean().optional().default(false) to allow .where('draft','=',false)
- Add wordCount + minutes as optional (injected by Nitro hook at parse time)
- Collections blog_fr/blog_en unchanged (schema is referenced by variable)
2026-04-22 08:56:46 +02:00
kayjaydee 61daa96663 docs(state): phase 6 planned (4 plans, 3 waves) .planning/STATE.md 2026-04-22 01:12:01 +02:00
kayjaydee d1ac5f9ee6 docs(06): create phase plan (4 plans, 3 waves)
Phase 6 Blog Pages decomposed into:
- 06-01 (Wave 1): content schema + reading-time Nitro hook + draft flags
- 06-02 (Wave 2): i18n keys + AppHeader link + BlogCard unified
- 06-03 (Wave 3): listing page /blog SSR bilingue
- 06-04 (Wave 3): [slug] enrichment + BlogToc + BlogPrevNext

Plans 06-03 and 06-04 have zero file overlap and run in parallel.

Covers BLOG-02, BLOG-03, BLOG-06. Honors all 21 D-XX user decisions
from 06-CONTEXT.md. Phase 5 gotchas (literal queryCollection, single
[slug].vue, no routeRules /blog/**) respected in every query branch.
2026-04-22 01:09:25 +02:00
kayjaydee 2d3974ea2c docs(06): research phase blog pages - API @nuxt/content v3, TOC IO, surround, hook reading time 2026-04-22 00:51:49 +02:00
kayjaydee 8915340ca8 docs(state): record phase 6 UI-SPEC approved session .planning/STATE.md 2026-04-22 00:42:01 +02:00
kayjaydee df9d70f15c docs(06): UI-SPEC approved (6/6 dimensions pass) .planning/phases/06-blog-pages/06-UI-SPEC.md 2026-04-22 00:41:46 +02:00
kayjaydee 1864c13cbb docs(06): UI design contract
Phase 6 Blog Pages — contrat visuel/interaction pour listing /blog et article /blog/[slug]. Tokens hérités Phase 5 (prose, brand-*, colorMode), inventaire composants (BlogCard, BlogToc, BlogPrevNext), i18n keys blog.* + nav.blog, pattern hero + cards inspiré /projects.
2026-04-22 00:40:21 +02:00
kayjaydee c1ab4e1cfb docs(state): record phase 6 context session .planning/STATE.md 2026-04-22 00:34:58 +02:00
kayjaydee eb3db1b4df docs(06): capture phase 6 blog pages context .planning/phases/06-blog-pages/06-CONTEXT.md .planning/phases/06-blog-pages/06-DISCUSSION-LOG.md 2026-04-22 00:34:43 +02:00
kayjaydee 7ee0a29056 feat(ROADMAP): mark Phase 5 as completed and update project state; prepare for Phase 6 planning 2026-04-22 00:23:25 +02:00
kayjaydee 7db3aae52c feat(blog): add dynamic blog post rendering with i18n support and error handling in [slug].vue 2026-04-22 00:20:52 +02:00
kayjaydee f89d3f769c test(05): complete UAT - 5 passed, 2 issues .planning/phases/05-nuxt-content-setup-renderer/05-UAT.md 2026-04-21 23:25:18 +02:00
kayjaydee f0bf0a989c refactor(config): update nuxt.config.ts to enhance module configuration, remove deprecated files, and improve contact form validation with zod schema 2026-04-21 23:15:04 +02:00
kayjaydee 3c8470b738 feat(config): add route rules for blog redirection to French version with 301 status code 2026-04-21 19:36:43 +02:00
kayjaydee 388c05a3a2 fix(05): update test.vue path to /fr/blog prefix, add compatibilityDate 2026-04-21 16:55:57 +02:00
kayjaydee 36e7e14d7f content(en): update test article to match FR showcase — identical content, translated 2026-04-21 16:51:58 +02:00
kayjaydee c6320760fb feat(05): i18n strategy prefix — /fr/blog and /en/blog explicit routes, update collection prefixes 2026-04-21 16:49:32 +02:00
kayjaydee 2b8aa6d377 fix(05): blog EN path uses /en/blog prefix to match blog_en collection 2026-04-21 16:47:12 +02:00
kayjaydee fb9491dc62 feat(05): add blog/[...slug].vue — render @nuxt/content articles via queryCollection 2026-04-21 16:45:34 +02:00
kayjaydee 0fe5b545ad fix(05): install @iconify-json/lucide, pre-bundle zod in vite optimizeDeps 2026-04-21 16:41:23 +02:00
kayjaydee ed384ec970 docs(05-02): SUMMARY.md — MDC components, test articles, checkpoint approved 2026-04-21 16:36:38 +02:00
kayjaydee 9f5e2e169e fix(05-02): single dark theme for code blocks — github-dark always, remove dual-theme CSS 2026-04-21 16:35:06 +02:00
kayjaydee 81eda7e37e fix(05-02): ProseImg use span.block instead of figure — fix SSR hydration mismatch (block-in-p invalid HTML) 2026-04-21 15:58:41 +02:00
kayjaydee 4269bcb4ea fix(05-02): Clear.vue MDC component, replace raw div clear:both (hydration mismatch) 2026-04-21 15:51:06 +02:00
kayjaydee 5db7a99213 fix(05-02): ProseImg inheritAttrs false — classes MDC custom overrident le layout auto 2026-04-21 15:37:51 +02:00
kayjaydee 1810a6e121 fix(05-02): restore Shiki token colors — add .shiki to ProsePre pre, broaden CSS selector to pre span 2026-04-21 15:34:02 +02:00
kayjaydee 5c35d13d3e feat(05-02): ProsePre override — dark bg fixe #0d1117, badge langage, Shiki tokens transparents 2026-04-21 15:31:40 +02:00
kayjaydee 9848338619 feat(05-02): add Columns/Details/Video/Badge MDC components + full showcase article 2026-04-21 15:31:00 +02:00
kayjaydee 36cd7f11aa feat(05-02): ProseImg flexible — align left/right/center/full + caption + width 2026-04-21 15:28:39 +02:00
kayjaydee 52d49dce71 fix(05-02): widen test page to max-w-6xl 2026-04-21 15:26:05 +02:00
kayjaydee ca3f257bb7 fix(05-02): widen test page to max-w-3xl 2026-04-21 15:25:41 +02:00
kayjaydee 49f7e70c9d fix(05-02): rebuild Alert sans UAlert, ProseImg img natif, test.vue layout propre 2026-04-21 15:24:22 +02:00
kayjaydee e46912d197 fix(05-02): alert alignment via #title slot, dark-only code theme, simplify ProseImg 2026-04-21 15:20:14 +02:00
kayjaydee d9a035c6b4 fix(05-02): ContentSlot→slot, image path, Shiki dual-theme CSS 2026-04-21 15:16:04 +02:00
kayjaydee 8f4c6d01fd feat(05-02): add test articles FR/EN and temporary test page
- content/fr/blog/test-kotlin-syntax.md: FR test article covering all 4 validation criteria
- content/en/blog/test-kotlin-syntax.md: EN version with same slug
- app/pages/test.vue: temporary page at /test for visual checkpoint verification
- Both articles contain: kotlin code block, NuxtImg image, markdown table, 4 callout types
2026-04-21 14:36:49 +02:00
kayjaydee 871ee8ed62 feat(05-02): create MDC components ProseImg.vue and Alert.vue
- ProseImg.vue: transparent NuxtImg override for markdown images (BLOG-05)
- Alert.vue: MDC callout component with 4 types (info/warning/tip/danger) via UAlert
- ContentSlot required for MDC slot content rendering (Pitfall 4)
2026-04-21 14:36:22 +02:00
kayjaydee 65bd95b441 docs(05-01): complete @nuxt/content setup plan — SUMMARY created 2026-04-21 14:35:24 +02:00
kayjaydee d2d754f85b chore(05-01): add .data to .gitignore (nuxt/content SQLite runtime artifact) 2026-04-21 14:34:58 +02:00
kayjaydee a10a438d03 feat(05-01): create content.config.ts with bilingual blog collections
- Define blog_fr collection: fr/blog/**/*.md → prefix /blog (FR default locale)
- Define blog_en collection: en/blog/**/*.md → prefix /en/blog (EN prefixed)
- Add Zod schema: title, description, date (required) + tags, image (optional)
2026-04-21 14:34:42 +02:00
kayjaydee 7da168843c feat(05-01): configure @nuxt/content with Shiki dual-theme and typography plugin
- Add '@nuxt/content' to modules array in nuxt.config.ts
- Add content block: Shiki dual-theme github-light/github-dark
- Add Shiki langs: kotlin, java, typescript, shell, bash, json, vue, html, css
- Add experimental.sqliteConnector: 'native' (Node 22 native SQLite)
- Add @plugin "@tailwindcss/typography" in main.css
2026-04-21 14:33:54 +02:00
kayjaydee dba0d6c3ac chore(05-01): install @nuxt/content@3.13.0 and @tailwindcss/typography@0.5.19
- Add @nuxt/content to dependencies
- Add @tailwindcss/typography to devDependencies
2026-04-21 14:33:29 +02:00
kayjaydee 6762990e61 docs(05): add detailed pattern map for @nuxt/content setup and renderer
- Introduced a new document outlining the configuration and component patterns for integrating @nuxt/content.
- Included mappings for `nuxt.config.ts`, `content.config.ts`, and new components `ProseImg.vue` and `Alert.vue`.
- Added example markdown content for testing syntax highlighting and layout.
- Documented critical patterns and anti-patterns to follow during implementation.
2026-04-21 12:52:59 +02:00
kayjaydee 29c1dff759 fix(05): resolve checker issues — open questions resolved, depends_on corrected, test.vue added
- 05-RESEARCH.md: rename section to 'Open Questions (RESOLVED)' with explicit answers
  (frontmatter schema: tags array, image relative path, author implicit from site.ts;
   i18n prefix: /blog for blog_fr, /en/blog for blog_en)
- 05-02-PLAN.md: fix depends_on from '05-01-PLAN.md' to '01'
- 05-02-PLAN.md: add app/pages/test.vue in Task 2 files (with note to delete after checkpoint)
2026-04-21 12:52:51 +02:00