Skip to content

Offboard Wix: 4 marketing pages + contact form#334

Closed
kylefritz wants to merge 24 commits into
masterfrom
offboard-wix
Closed

Offboard Wix: 4 marketing pages + contact form#334
kylefritz wants to merge 24 commits into
masterfrom
offboard-wix

Conversation

@kylefritz

Copy link
Copy Markdown
Owner

Summary

Folds the four marketing pages (/, /about, /subscribe, /contact) from the Wix-hosted motzibread.com into the Rails app. Self-hosts all marketing assets in S3 and adds a contact form that emails the bakery while persisting submissions for triage in /admin.

  • Per-page singular controllers (HomeController rewritten to render instead of redirect; new AboutController / SubscribeController / ContactController) with a separate marketing.html.erb layout and marketing.scss scoped under body.marketing
  • ContactMessage model + ActiveAdmin resource + ContactMailer.notify_bakery (with submitter as Reply-To); honeypot field for spam; rack-attack throttle 5/hr/IP on POST /contact
  • MarketingHelper#holiday_menu_link surfaces a nav link to Menu.current_holiday when active — replaces the old Wix → motzibread.square.site flow with an in-app link to /menus/:id
  • 10 Wix-hosted images mirrored to s3://motzi/public/marketing/ via one-shot rake marketing:fetch_assets; map at docs/superpowers/specs/marketing-assets-map.md
  • Playwright + Claude Haiku visual QA spec at test/visual/marketing-screenshots.spec.ts (manual, not CI)

Spec: docs/superpowers/specs/2026-05-12-wix-cms-migration.md
Plan: docs/superpowers/plans/2026-05-12-wix-cms-migration.md

Before merging

  • Set CONTACT_INBOX on Heroku (defaults to info@motzibread.com if unset; confirm with Maya/Russell)
  • Flesh out marketing.scss for page-body classes (.hero, .cta-primary, .field, .find-us, etc.) — current SCSS only styles the layout chrome, so CTA buttons and form fields render browser-default

Test plan

  • CI passes (Rails 415 tests, JS tests)
  • Manually visit /, /about, /subscribe, /contact on the deployed Heroku app and confirm each renders
  • Submit a test message via the contact form; confirm it appears in /admin/contact_messages and that the bakery inbox receives the email with the submitter as Reply-To
  • Confirm /menu (existing menu) and /admin (existing admin) still work — marketing layout shouldn't leak
  • Sign in as admin and visit / — confirm "Admin" link appears in the marketing nav
  • Sign out via /signout — confirm redirect back to / (now the marketing home)
  • Email order links continue to deep-link to /menu (verified: all order/reminder mailers use current_menu_url(uid: ...))
  • (Optional, local) Run bunx playwright test test/visual/marketing-screenshots.spec.ts against this branch with Rails on localhost:3000

Follow-ups (separate work, not in this PR)

  • Phase 2 DNS cutover: point motzibread.com at Heroku, retire Wix subscription
  • Retire motzibread.square.site once holiday menus run through the in-app flow
  • Content audit with Maya/Russell — phone, hours, retail partners, owner blurb may all be stale on Wix

kylefritz and others added 18 commits May 12, 2026 20:16
Brainstormed and planned with Claude. Spec covers porting four marketing
pages (home, about, subscribe, contact) from Wix into the Rails app with
per-page singular controllers, a separate marketing layout, S3-hosted
assets, and a contact form. Plan breaks the work into 15 TDD-disciplined
tasks for subagent-driven execution.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 168f687cea

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

t.string :phone
t.text :message, null: false
t.string :ip
t.string :user_agent

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Store captured user agents without the 255-byte cap

Because ContactController#create copies request.user_agent into this column, any legitimate browser, extension, or bot that sends a User-Agent longer than PostgreSQL's string limit will make @message.save raise instead of saving the contact request and emailing the bakery. Use a text column here, or truncate/validate before saving, so long headers do not turn valid /contact submissions into 500s.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 37ccecd — the offending file (the ContactMessage migration) was deleted in c6ed094 when we switched to the existing Feedback model, but the same length concern applied there. Added a before_validation to Feedback that truncates user_agent (512) and url (2048) so long request headers can't fail save and lose the submission. The length validations stay as belt-and-suspenders.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens if we don't have claude api key on gh workflows etc

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 2ea1a48. Per CLAUDE.md visual specs aren't in CI, but anyone running them locally without the key was getting a hard module-load failure (new Anthropic() throws at construction). Now: client construction is deferred (process.env.ANTHROPIC_API_KEY ? new Anthropic() : null) and each test calls test.skip(!client, ...) — running without the key reports tests as skipped instead of broken. Same fix applied to the existing email-screenshots.spec.ts for consistency.

kylefritz and others added 6 commits May 13, 2026 00:41
Drop the ContactMessage model, ContactMailer, and associated admin/tests.
Route contact form submissions into Feedback with source: "contact".
Add name/phone columns to feedbacks, surface them in the mailer and admin,
and set reply_to from the submitter's email when present.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
HomeController, AboutController, SubscribeController, and ContactController
all declared layout "marketing" and skip_before_action :authenticate_user!
independently. Pull both declarations into a shared MarketingController base.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add named route helpers (about_path, subscribe_path, contact_path) and
replace raw <a href> tags with link_to in the marketing header, footer,
home page CTAs, and subscribe CTA. The contact form's url also switches
to contact_path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Long browser User-Agent or referer URLs would fail validation and lose
the submission. Both fields are captured from request headers, never
user-typed, so silent truncation is the right behavior. Length
validations stay as belt-and-suspenders for any caller that bypasses
the callback.
The Anthropic SDK throws at construction without the key, which made
the spec fail at module load. Defer client construction and call
test.skip in each test body so 'bunx playwright test' without the key
reports tests as skipped instead of broken.
… visual helper

- contact_controller: redirect_to contact_path (×2) instead of literal '/contact'
- feedback_mailer: reply_to: @feedback.email.presence — drop the splat-or-empty hash
- feedback_test: drop 'contact is a valid source' (already covered by valid-sources loop)
- visual specs: extract test/visual/helpers.ts for the Anthropic client guard,
  PNG height-crop fallback, and messages.create call. Both email and marketing
  specs now share the subtle 7900px height threshold rather than maintaining it twice.
@kylefritz

Copy link
Copy Markdown
Owner Author

Superseded by #351, which carries the same Wix offboarding work forward (pixel-matched to the live Wix design).

@kylefritz kylefritz closed this Jul 14, 2026
@kylefritz
kylefritz deleted the offboard-wix branch July 14, 2026 02:44
kylefritz added a commit that referenced this pull request Jul 14, 2026
…m CreditBundle

Setting.holiday_menu_id lingers after a holiday ends, so the marketing
nav kept advertising a menu that no longer accepts orders (the member
app handles this gracefully with a closed state; marketing shouldn't
advertise it at all).

The subscribe page hardcoded Wix's stale $182/$98 pricing — 7-13%
below what checkout actually charges. Render from the same
CreditBundle rows the purchase flow uses so copy can't drift again.

Refs #334

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kylefritz added a commit that referenced this pull request Jul 14, 2026
Visual fixes from side-by-side screenshot audit against motzibread.com:
- Body font: EB Garamond serif -> Mulish light (Wix uses Avenir LT
  Light / DIN Next Light; Mulish is the closest Google Fonts stand-in)
- Home hero: full-bleed illustration with the three-line brick-red
  tagline overlaid in cream highlight boxes, as on Wix
- Purple announcement bar under the header (pre-order link + hours;
  Wix renders it as a dismissible overlay, ours is a solid band)
- Contact form: underline-only fields, placeholder labels with required
  asterisks, name/email side by side, plain-text Send (labels stay in
  the markup, visually hidden)
- Section headings: Mulish instead of Oswald; terracotta on About,
  purple uppercase on Subscribe (with Wix's trailing dash quirk)
- Footer: Wix three-column layout (logo + vertical nav / one-line
  terracotta address / IG), stacked right-aligned credits
- About: restore the 'local grain movement' sentence Wix had; its
  'here' link is dead on Wix, pointed at Common Grain Alliance pending
  owner confirmation
- Sold-out badge angled like Wix's sticker

Integration:
- Marketing pages now load GA (shared layouts/_analytics partial), the
  browser error reporter, and ahoy tracking via a new marketing pack
- Per-page meta descriptions + OpenGraph tags
- Sign out link in the marketing nav for signed-in users
- CanonicalHostRedirect middleware: set CANONICAL_HOST at DNS cutover
  and motzibread.herokuapp.com 301s to the custom domain (no-op until
  then; health checks exempt)

Refs #334

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
kylefritz added a commit that referenced this pull request Jul 14, 2026
The subscription concept is legacy: creating an account just joins the
weekly menu email list (sign-up sets receive_weekly_menu), and credits
are an optional pre-purchase for a per-loaf discount. The Wix copy this
branch ported still sold 'subscriptions', including a hardcoded
'Currently Sold Out' badge that contradicts prod, where
Setting.accepting_subscribers is true.

- /subscribe: 'How It Works' page — weekly menu email, then credits
- Nav label Subscriptions -> How It Works (header + footer)
- Home purple band: 'Get the Weekly Menu'
- CTA: SUBSCRIBE NOW -> SIGN UP NOW
- Sold-out badge now renders only when accepting_subscribers is off

Refs #334

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant