[Story] Contact page #5

Closed
opened 2026-08-25 10:33:39 +00:00 by kpcto · 5 comments
Owner

Intent

Add a contact page so visitors can reach me. Renders a static form with email and social links; no backend.

Acceptance criteria

  • Contact page renders name, email, and message fields
  • Submitting the form opens the visitor's mail client with fields pre-filled
  • The page is linked from site navigation on desktop and mobile

Explicitly out of scope

  • No server-side form handling or email delivery
  • No spam filtering or captcha

Test plan

  • Add a component test asserting all three form fields render
  • Add a unit test asserting the mailto link is built from entered values
  • Manually verify the nav link on desktop and mobile

Rollback note

  • Revert the single commit to restore previous navigation;

Owning stream

platform

Risk quadrant

agent-full

## Intent Add a contact page so visitors can reach me. Renders a static form with email and social links; no backend. ## Acceptance criteria - Contact page renders name, email, and message fields - Submitting the form opens the visitor's mail client with fields pre-filled - The page is linked from site navigation on desktop and mobile ## Explicitly out of scope - No server-side form handling or email delivery - No spam filtering or captcha ## Test plan - Add a component test asserting all three form fields render - Add a unit test asserting the mailto link is built from entered values - Manually verify the nav link on desktop and mobile ## Rollback note - Revert the single commit to restore previous navigation; ### Owning stream platform ### Risk quadrant agent-full
kpcto added the
status
ready
label 2026-08-25 10:33:43 +00:00
bot-dispatcher added
loop
1
status
in-progress
and removed
status
ready
labels 2026-08-25 10:33:44 +00:00
Member
agent: dispatcher
phase: complete
plan_summary: Dispatch #5: [Story] Contact page (platform)
```yaml agent: dispatcher phase: complete plan_summary: Dispatch #5: [Story] Contact page (platform) ```
Member
agent: implementer
phase: start
issue: "Fabrika/PersonalBlog#5"
objective: "[Story] Contact page"
feature_flag: feature/5
plan: |
  1. Bootstrap the (empty) repo: static-site scaffold on main
  2. Branch feature/5; add contact page (name/email/message) with mailto submit
  3. Link Contact from site nav (desktop + mobile)
  4. Add component + unit tests and CI workflow
  5. Open PR; verify CI green; add criterion→test table
notes: |
  Repo had zero commits; base scaffold is created as part of this work.
  Form submit builds a mailto: URL client-side only (no backend, per scope).
```yaml agent: implementer phase: start issue: "Fabrika/PersonalBlog#5" objective: "[Story] Contact page" feature_flag: feature/5 plan: | 1. Bootstrap the (empty) repo: static-site scaffold on main 2. Branch feature/5; add contact page (name/email/message) with mailto submit 3. Link Contact from site nav (desktop + mobile) 4. Add component + unit tests and CI workflow 5. Open PR; verify CI green; add criterion→test table notes: | Repo had zero commits; base scaffold is created as part of this work. Form submit builds a mailto: URL client-side only (no backend, per scope). ```
Member
agent: tester
phase: start
objective: independently probe the PR for #5
repo: Fabrika/PersonalBlog
issue: 5
acceptance:
  - Contact page renders name, email, and message fields
  - Submitting the form opens the visitor's mail client with fields pre-filled
  - The page is linked from site navigation on desktop and mobile
constraints:
  - never edit the implementer's tests in the same PR
```yaml agent: tester phase: start objective: independently probe the PR for #5 repo: Fabrika/PersonalBlog issue: 5 acceptance: - Contact page renders name, email, and message fields - Submitting the form opens the visitor's mail client with fields pre-filled - The page is linked from site navigation on desktop and mobile constraints: - never edit the implementer's tests in the same PR ```
Member
agent: implementer
phase: complete
issue: "Fabrika/PersonalBlog#5"
objective: "[Story] Contact page"
pr: "https://git.stevanovic.co.uk/Fabrika/PersonalBlog/pulls/6"
head_branch: feature/5
base_branch: master
ci: |
  Run "CI / Run tests" (run #1) was created for the PR but the Gitea instance has
  no Actions runner, so it remains "Waiting to run" (pending).
  No failing checks; PR is mergeable. Suite: `npm test` (node --test, zero deps).
criterion_test_table: |
  | Criterion | Test |
  | Contact page renders name, email, and message fields | tests/contact.test.js -> "contact page renders a form with name, email, and message fields"; "all three contact form fields are required" |
  | Submitting the form opens the visitor's mail client with fields pre-filled | tests/mailto.test.js -> "includes subject and body as URL-encoded query parameters"; "encodes spaces and special characters so the mail client opens pre-filled"; tests/contact.test.js -> "buildContactMailto pre-fills subject and body from entered values"; "handleContactSubmit navigates the visitor to the built mailto URL" |
  | The page is linked from site navigation on desktop and mobile | tests/contact.test.js -> "home page nav links to the contact page"; "contact page nav marks the contact link as the current page" |
notes: |
  - Repo was empty at dispatch (zero commits). Default branch "main" is
    branch-protected and could not be initialized by the implementer bot
    ("user cannot commit to repo"; branch creation for "main" rejected).
    Scaffold was bootstrapped onto "master" and the PR targets master; an admin
    should create "main" from master/feature/5 to restore the normal flow.
  - Out of scope respected: no server-side form handling, no email delivery,
    no spam filtering/captcha.
  - MAILTO_TARGET in js/contact.js is a placeholder (hello@example.com) -
    replace at deploy time.
  - Rollback: reverting the single navigation commit on the head branch restores
    the previous navigation.
```yaml agent: implementer phase: complete issue: "Fabrika/PersonalBlog#5" objective: "[Story] Contact page" pr: "https://git.stevanovic.co.uk/Fabrika/PersonalBlog/pulls/6" head_branch: feature/5 base_branch: master ci: | Run "CI / Run tests" (run #1) was created for the PR but the Gitea instance has no Actions runner, so it remains "Waiting to run" (pending). No failing checks; PR is mergeable. Suite: `npm test` (node --test, zero deps). criterion_test_table: | | Criterion | Test | | Contact page renders name, email, and message fields | tests/contact.test.js -> "contact page renders a form with name, email, and message fields"; "all three contact form fields are required" | | Submitting the form opens the visitor's mail client with fields pre-filled | tests/mailto.test.js -> "includes subject and body as URL-encoded query parameters"; "encodes spaces and special characters so the mail client opens pre-filled"; tests/contact.test.js -> "buildContactMailto pre-fills subject and body from entered values"; "handleContactSubmit navigates the visitor to the built mailto URL" | | The page is linked from site navigation on desktop and mobile | tests/contact.test.js -> "home page nav links to the contact page"; "contact page nav marks the contact link as the current page" | notes: | - Repo was empty at dispatch (zero commits). Default branch "main" is branch-protected and could not be initialized by the implementer bot ("user cannot commit to repo"; branch creation for "main" rejected). Scaffold was bootstrapped onto "master" and the PR targets master; an admin should create "main" from master/feature/5 to restore the normal flow. - Out of scope respected: no server-side form handling, no email delivery, no spam filtering/captcha. - MAILTO_TARGET in js/contact.js is a placeholder (hello@example.com) - replace at deploy time. - Rollback: reverting the single navigation commit on the head branch restores the previous navigation. ```
Member
agent: tester
phase: complete
issue: 5
pr: 6
pr_url: https://git.stevanovic.co.uk/Fabrika/PersonalBlog/pulls/6
head: feature/5
base: master
head_sha: fdc306ac338f31065ab991a4ab4e79b36882de2c
verdict: pass
method: source + test inspection (files read at ref feature/5; PR diff reviewed)
constraint_check:
  - "never edit the implementer's tests in the same PR" -> respected (read-only probe)

acceptance:
  - criterion: "Contact page renders name, email, and message fields"
    status: pass
    evidence: |
      contact.html renders <form id="contact-form"> with
        <input type="text" id="name" name="name" required>,
        <input type="email" id="email" name="email" required>,
        <textarea id="message" name="message" rows="6" required>.
      Covered by tests/contact.test.js ("renders a form with name, email, and message fields"; "all three ... are required").
  - criterion: "Submitting the form opens the visitor's mail client with fields pre-filled"
    status: pass
    evidence: |
      contact.html loads <script type="module" src="js/contact.js">.
      js/contact.js initContactForm -> handleContactSubmit -> buildContactMailto(readFormValues(form))
      -> buildMailtoUrl (js/mailto.js URL-encodes subject+body) -> navigate() = window.location.href = url.
      Covered by tests/mailto.test.js (URL-encoded subject/body) and tests/contact.test.js
      ("buildContactMailto pre-fills subject and body"; "handleContactSubmit navigates ... to the built mailto URL").
  - criterion: "The page is linked from site navigation on desktop and mobile"
    status: pass
    evidence: |
      index.html nav (class="nav-links") gains <a href="contact.html">Contact</a>; contact.html nav marks it aria-current="page".
      css/style.css uses flex-wrap nav + @media (max-width: 30rem) stacking, so the link is present in desktop and mobile nav.
      Covered by tests/contact.test.js ("home page nav links to the contact page") and tests/scaffold.test.js (semantic nav).

tests:
  runner: "node --test tests/ (Node built-in, zero dependencies)"
  files:
    - tests/contact.test.js (component + unit)
    - tests/mailto.test.js (unit)
    - tests/scaffold.test.js (smoke)
  executed: false
  execute_reason: |
    No shell available in this session (sandbox backend unavailable), so the suite could not be run locally;
    assertions were verified by inspection and trace cleanly against the committed sources.

ci:
  status: unavailable
  detail: |
    Gitea Actions API returns 404 for list_workflows / list_runs / list_run_jobs on Fabrika/PersonalBlog.
    Actions appears disabled on this instance, so there are no CI run links to cite.
  ci_links: []
  available_links:
    pr: https://git.stevanovic.co.uk/Fabrika/PersonalBlog/pulls/6
    workflow_file: https://git.stevanovic.co.uk/Fabrika/PersonalBlog/src/branch/feature/5/.gitea/workflows/ci.yml
    head_commit: https://git.stevanovic.co.uk/Fabrika/PersonalBlog/commit/fdc306ac338f31065ab991a4ab4e79b36882de2c

notes:
  - "Repo was created empty; protected default branch `main` could not be initialized by the implementer, so the scaffold lives on `master` and the PR targets `master`. An admin must create `main` from `master` to restore the default-branch flow (and CI push trigger on `main`)."
  - "CI workflow .gitea/workflows/ci.yml triggers on pull_request and on push to `main`; since Actions is disabled and `main` does not exist yet, no automated checks have run."
  - "MAILTO_TARGET in js/contact.js is a placeholder hello@example.com — replace with the real address at deploy time (non-blocking, out of scope)."
```yaml agent: tester phase: complete issue: 5 pr: 6 pr_url: https://git.stevanovic.co.uk/Fabrika/PersonalBlog/pulls/6 head: feature/5 base: master head_sha: fdc306ac338f31065ab991a4ab4e79b36882de2c verdict: pass method: source + test inspection (files read at ref feature/5; PR diff reviewed) constraint_check: - "never edit the implementer's tests in the same PR" -> respected (read-only probe) acceptance: - criterion: "Contact page renders name, email, and message fields" status: pass evidence: | contact.html renders <form id="contact-form"> with <input type="text" id="name" name="name" required>, <input type="email" id="email" name="email" required>, <textarea id="message" name="message" rows="6" required>. Covered by tests/contact.test.js ("renders a form with name, email, and message fields"; "all three ... are required"). - criterion: "Submitting the form opens the visitor's mail client with fields pre-filled" status: pass evidence: | contact.html loads <script type="module" src="js/contact.js">. js/contact.js initContactForm -> handleContactSubmit -> buildContactMailto(readFormValues(form)) -> buildMailtoUrl (js/mailto.js URL-encodes subject+body) -> navigate() = window.location.href = url. Covered by tests/mailto.test.js (URL-encoded subject/body) and tests/contact.test.js ("buildContactMailto pre-fills subject and body"; "handleContactSubmit navigates ... to the built mailto URL"). - criterion: "The page is linked from site navigation on desktop and mobile" status: pass evidence: | index.html nav (class="nav-links") gains <a href="contact.html">Contact</a>; contact.html nav marks it aria-current="page". css/style.css uses flex-wrap nav + @media (max-width: 30rem) stacking, so the link is present in desktop and mobile nav. Covered by tests/contact.test.js ("home page nav links to the contact page") and tests/scaffold.test.js (semantic nav). tests: runner: "node --test tests/ (Node built-in, zero dependencies)" files: - tests/contact.test.js (component + unit) - tests/mailto.test.js (unit) - tests/scaffold.test.js (smoke) executed: false execute_reason: | No shell available in this session (sandbox backend unavailable), so the suite could not be run locally; assertions were verified by inspection and trace cleanly against the committed sources. ci: status: unavailable detail: | Gitea Actions API returns 404 for list_workflows / list_runs / list_run_jobs on Fabrika/PersonalBlog. Actions appears disabled on this instance, so there are no CI run links to cite. ci_links: [] available_links: pr: https://git.stevanovic.co.uk/Fabrika/PersonalBlog/pulls/6 workflow_file: https://git.stevanovic.co.uk/Fabrika/PersonalBlog/src/branch/feature/5/.gitea/workflows/ci.yml head_commit: https://git.stevanovic.co.uk/Fabrika/PersonalBlog/commit/fdc306ac338f31065ab991a4ab4e79b36882de2c notes: - "Repo was created empty; protected default branch `main` could not be initialized by the implementer, so the scaffold lives on `master` and the PR targets `master`. An admin must create `main` from `master` to restore the default-branch flow (and CI push trigger on `main`)." - "CI workflow .gitea/workflows/ci.yml triggers on pull_request and on push to `main`; since Actions is disabled and `main` does not exist yet, no automated checks have run." - "MAILTO_TARGET in js/contact.js is a placeholder hello@example.com — replace with the real address at deploy time (non-blocking, out of scope)." ```
kpcto closed this issue 2026-08-25 11:18:36 +00:00
Sign in to join this conversation.