// c51 (edit) — UI: edit-form, login-required prompt, applied-live // success page, commit-failure page, non-admin "read-only" wall. // Composes the docs layout's chrome via renderPage with bodyHtml so // the form can use real
elements (markdown would escape them). import { renderPage, escape, } from "./b51_render_layout.ts"; import type { ResolvedEdit } from "./b32_edit_resolve.ts"; import type { GitCommitOk, GitCommitFailure } from "./a31_git_parse.ts"; const layoutWrap = (innerHtml: string): string => `
${innerHtml}
`; // Override the standard
: the edit experience needs // full-width form controls, not the doc-layout's three columns. const editBodyClass = "edit-body"; const shortSha = (sha: string): string => sha.slice(0, 7); // SAMA-native commit URL on tdd.md itself. The /GIT/ prefix routes to // c21_handlers_commit_view which reads the data from Forgejo's API and // renders it through tdd.md's chrome — visitor never leaves the main // domain. const tddCommitUrl = (sha: string): string => `/GIT/tdd.md/commit/${sha}`; // -------- /edit/:section/:slug — form for the admin -------- export const renderEditFormPage = async ( resolved: ResolvedEdit, currentBody: string, viewer: string, ): Promise => { const inner = `

edit · ${escape(resolved.title)}

Editing ${escape(resolved.filePath)} as ${escape(viewer)}. Saving will commit directly to syntaxai/tdd.md@main on git.tdd.md and refresh the live page. view the live page · log out

cancel

This editor commits to git via Forgejo's contents API — the container has no .git directory, no SSH keys, only an HTTP token. Every save becomes a real commit you can review at git.tdd.md.

`; return renderPage({ title: `edit · ${resolved.title} — tdd.md`, bodyHtml: layoutWrap(inner), description: `Edit ${resolved.title} on tdd.md. Admin-only; saves commit directly to git.tdd.md.`, ogPath: `https://tdd.md/edit/${resolved.section}/${resolved.slug}`, noindex: true, bodyClass: editBodyClass, }); }; // -------- login wall before the form -------- export const renderEditLoginWall = async ( resolved: ResolvedEdit, ): Promise => { const returnTo = `/edit/${resolved.section}/${resolved.slug}`; const inner = `

edit · ${escape(resolved.title)}

To edit a page you need to sign in via GitHub. Editing is admin-only — only the site owner's GitHub account can save changes. We use GitHub for identity only; saves commit to git.tdd.md, never to GitHub.

If you have an edit suggestion and you're not the admin, open an issue at git.tdd.md/syntaxai/tdd.md/issues.

← back to the page

`; return renderPage({ title: `sign in to edit · ${resolved.title} — tdd.md`, bodyHtml: layoutWrap(inner), description: `Sign in via GitHub to edit ${resolved.title} on tdd.md.`, noindex: true, bodyClass: editBodyClass, }); }; // -------- non-admin signed-in wall -------- export const renderEditNonAdminWall = async ( resolved: ResolvedEdit, viewer: string, ): Promise => { const inner = `

edit · ${escape(resolved.title)}

Signed in as ${escape(viewer)}, but editing is admin-only. Only the site owner can save changes from here.

If you'd like to suggest an edit, open an issue at git.tdd.md/syntaxai/tdd.md/issues describing the change.

← back to the page · log out

`; return renderPage({ title: `edit · ${resolved.title} — tdd.md`, bodyHtml: layoutWrap(inner), noindex: true, bodyClass: editBodyClass, }); }; // -------- admin direct-edit applied live -------- export const renderEditAppliedLive = async ( resolved: ResolvedEdit, commit: GitCommitOk, ): Promise => { const sha = commit.commitSha; const inner = `

applied live · ${escape(resolved.title)}

Your edit to ${escape(resolved.pageUrl)} is now live and committed.

Commit ${escape(shortSha(sha))} landed in the local bare repo (/app/repo in the container, ~/repos/tdd.md.git on p620) via git plumbing. No HTTP, no Forgejo, no SSH involved — just a real git commit on disk.

The container's content/ dir is copied from the working tree at image build, and the next deploy fetches new commits from the local bare repo before rebuilding — so this commit will outlive any container restart.

→ view the live page · edit again

`; return renderPage({ title: `applied · ${resolved.title} — tdd.md`, bodyHtml: layoutWrap(inner), noindex: true, bodyClass: editBodyClass, }); }; // -------- admin commit failed (Forgejo conflict / network / other) -------- export const renderEditCommitFailed = async ( resolved: ResolvedEdit, failure: GitCommitFailure, ): Promise => { const explanation = failure.kind === "conflict" ? "The branch tip moved while you were editing — someone else committed in between. Refresh the editor to load the latest version, then re-apply your change." : failure.kind === "permission" ? "The container can't write to the bare repo. Check that /home/scri/repos/tdd.md.git on p620 is mounted read-write into /app/repo." : failure.kind === "not_found" ? "The 'main' branch doesn't exist in the bare repo. Verify that ~/repos/tdd.md.git on p620 has a refs/heads/main." : "git rejected the commit for an unexpected reason. See the message below."; const inner = `

commit failed · ${escape(resolved.title)}

Your edit to ${escape(resolved.pageUrl)} was not applied. The live page is unchanged.

git returned ${escape(failure.kind)}.

${escape(explanation)}

git stderr
${escape(failure.message.slice(0, 2000))}

← back to the editor (refreshes the form)

`; return renderPage({ title: `commit failed · ${resolved.title} — tdd.md`, bodyHtml: layoutWrap(inner), noindex: true, bodyClass: editBodyClass, }); };