Skip to content

Commit d3d202d

Browse files
authored
Feature/update luxe edit (#14)
* Update luxe-edit dependency to version 0.2.0 and refactor related imports and usage in blog components * Update deployment workflows to specify branch references and trigger deploy on sync * Add project overview and branch architecture documentation to CLAUDE.md
1 parent 25769cf commit d3d202d

7 files changed

Lines changed: 89 additions & 13 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ jobs:
2525
steps:
2626
- name: Checkout repository
2727
uses: actions/checkout@v4
28+
with:
29+
ref: web
2830

2931
- name: Setup Node.js
3032
uses: actions/setup-node@v4

.github/workflows/sync-to-web.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,21 @@ jobs:
3333
git checkout HEAD -- data/ gitforge.config.json
3434
git diff --cached --quiet || git commit -m "Sync code from main"
3535
git push origin web
36+
echo "pushed=true" >> "$GITHUB_OUTPUT"
3637
else
3738
echo "web branch not yet created — skipping sync"
39+
echo "pushed=false" >> "$GITHUB_OUTPUT"
3840
fi
41+
id: sync
42+
43+
- name: Trigger deploy
44+
if: steps.sync.outputs.pushed == 'true'
45+
uses: actions/github-script@v7
46+
with:
47+
script: |
48+
await github.rest.actions.createWorkflowDispatch({
49+
owner: context.repo.owner,
50+
repo: context.repo.repo,
51+
workflow_id: 'deploy.yml',
52+
ref: 'web'
53+
})

CLAUDE.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Project: Gitfolio
2+
3+
## Overview
4+
5+
This repo is both:
6+
- A **Vite + React + TS** template for a GitHub profile site.
7+
- An **npm CLI package** named `gitforge` that generates static data from the GitHub API.
8+
9+
## Branch Architecture
10+
11+
Two-branch setup:
12+
13+
| Branch | Purpose |
14+
|--------|---------|
15+
| `main` | Development — code only. `data/*.json` files are always empty `[]`. |
16+
| `web` | Deployment — code + personal data. `data/` files hold real content. |
17+
18+
- `validate-main.yml` enforces that `data/*.json` stay empty on `main`.
19+
- When a user forks the repo they get `main` with empty data, then create their own `web` branch for personal data.
20+
- `sync-to-web.yml` merges code from `main``web` on every push, but always restores `web`'s `data/` and `gitforge.config.json` so personal data is never overwritten.
21+
- `deploy.yml` always checks out the `web` branch (explicit `ref: web`) for all trigger types (push, schedule, workflow_dispatch).
22+
- Because `GITHUB_TOKEN` pushes don't trigger other workflows, `sync-to-web.yml` explicitly dispatches `deploy.yml` via the GitHub API after pushing to `web`.
23+
24+
## CLI & Config
25+
26+
- Config source of truth: `gitforge.config.json` (git-ignored). Only `gitforge.config.example.json` is tracked.
27+
- Generator script: `scripts/generate-github-data.js`, exposed as the `gitforge` binary via `package.json`.
28+
- Usage: `gitforge [owner] [--type user|org]` — or reads `gitforge.config.json` when no CLI args given.
29+
30+
## Generated Files
31+
32+
Do not hand-edit or rely on these for long-term docs — they are regenerated:
33+
- `src/generated/githubData.ts`
34+
- `src/siteContent.json`
35+
36+
When editing site content, work against `src/siteContent.json` (keeping in mind it gets regenerated).
37+
38+
## App Constraints
39+
40+
- Functional React components, TypeScript, Tailwind CSS.
41+
- Single-page app (React Router for internal nav), clean/dark/minimal/developer-focused.
42+
- Deterministic and static — no runtime GitHub API calls from the browser.
43+
44+
## Tech Stack
45+
46+
- React + Vite + TypeScript
47+
- Tailwind CSS
48+
- pnpm
49+
- Rich text editor: `luxe-edit` (v0.2.0)
50+
- Save content as JSON via `getEditorJSON(editorState)` in `onChange`
51+
- Render saved JSON as HTML via `getDOMFromJSON(savedJson)`
52+
53+
## Key Files
54+
55+
- `scripts/generate-github-data.js` — CLI / data generator
56+
- `gitforge.config.example.json` — tracked config template
57+
- `src/generated/githubData.ts` — generated GitHub data (do not hand-edit)
58+
- `src/siteContent.json` — generated site content (do not hand-edit)
59+
- `src/admin/pages/AdminBlogsPage.tsx` — blog editor (uses LuxeEditor)
60+
- `src/pages/BlogPage.tsx` — blog display (renders JSON via `getDOMFromJSON`)
61+
- `src/types/contentTypes.ts` — shared content types (`Blog`, `Project`, `Post`, `Video`)
62+
- `.github/workflows/` — CI/CD workflows

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"preview": "vite preview"
1414
},
1515
"dependencies": {
16-
"luxe-edit": "^0.1.6",
16+
"luxe-edit": "^0.2.0",
1717
"react": "^19.2.0",
1818
"react-dom": "^19.2.0",
1919
"react-markdown": "^9.0.1",

pnpm-lock.yaml

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/admin/pages/AdminBlogsPage.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { LuxeEditor, getEditorJSON, getEditorFormattedText } from 'luxe-edit'
1+
import { LuxeEditor, getEditorJSON } from 'luxe-edit'
22
import 'luxe-edit/index.css'
33
import { useAdminAuthContext } from '../context/AdminAuthContext'
44
import { useBlogsStore } from '../hooks/useBlogsStore'
@@ -170,10 +170,7 @@ function BlogCard({
170170
}}
171171
initialJSON={blog.contentJSON}
172172
onChange={(editorState) => {
173-
onUpdate({
174-
content: getEditorFormattedText(editorState),
175-
contentJSON: getEditorJSON(editorState),
176-
})
173+
onUpdate({ contentJSON: getEditorJSON(editorState) })
177174
}}
178175
ignoreInitialChange
179176
/>

src/pages/BlogPage.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useParams, Link } from 'react-router-dom'
22
import { useSiteData } from '../hooks/useSiteData'
3-
import { getHTMLFromJSON } from 'luxe-edit'
3+
import { getDOMFromJSON } from 'luxe-edit'
44
import ReactMarkdown from 'react-markdown'
55

66
export default function BlogPage() {
@@ -48,7 +48,7 @@ export default function BlogPage() {
4848
{blog.contentJSON ? (
4949
<div
5050
className="prose prose-slate dark:prose-invert max-w-none text-sm text-slate-700 dark:text-slate-300"
51-
dangerouslySetInnerHTML={{ __html: getHTMLFromJSON(blog.contentJSON) }}
51+
dangerouslySetInnerHTML={{ __html: getDOMFromJSON(blog.contentJSON) }}
5252
/>
5353
) : (
5454
<div className="prose prose-slate dark:prose-invert max-w-none text-sm text-slate-700 dark:text-slate-300">

0 commit comments

Comments
 (0)