Skip to content

feat(landing): reintroduce /contact page styled like /demo#5315

Merged
waleedlatif1 merged 5 commits into
stagingfrom
fix/contact
Jul 1, 2026
Merged

feat(landing): reintroduce /contact page styled like /demo#5315
waleedlatif1 merged 5 commits into
stagingfrom
fix/contact

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Reintroduce the /contact page (removed in improvement(landing): refine hero and mothership visuals #5181) with a two-column layout mirroring /demo: value proposition + trusted-by logos on the left, a message-form card on the right
  • Styled wholly on the platform light tokens and chip components — card chrome, field rhythm, and responsive tiers are identical to the demo booking card
  • Restore the contact contract and /api/contact route (rate-limit, honeypot, Turnstile, help-inbox notification + visitor confirmation email), now fully contract-bound via parseRequest
  • Add a useSubmitContact React Query mutation hook (contract-bound requestJson)
  • Link Contact from the footer Resources column and add /contact to the sitemap

Type of Change

  • New feature (reintroduction)

Testing

Tested manually. tsc, biome, check:api-validation:strict, check:react-query, and check:client-boundary all pass.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

- Restore the /contact page (removed in #5181) with a two-column layout
  mirroring /demo: value prop + trusted-by logos on the left, a message
  form card on the right, on the platform light tokens and chip components
- Restore the contact contract, /api/contact route (rate-limit, honeypot,
  Turnstile, help-inbox notification + visitor confirmation), now fully
  contract-bound via parseRequest
- Add a useSubmitContact React Query mutation hook
- Link Contact from the footer Resources column and add it to the sitemap
@vercel

vercel Bot commented Jul 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 1, 2026 8:14am

Request Review

@cursor

cursor Bot commented Jul 1, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
New unauthenticated public endpoint handles PII and outbound email; abuse controls (rate limit, honeypot, Turnstile, fail-closed backstop) are substantive but email and captcha misconfiguration could still affect availability or deliverability.

Overview
Reintroduces a public /contact landing page (demo-style two-column layout with chip form, Turnstile, honeypot, and success state) wired through a new submitContactContract, useSubmitContact, and POST /api/contact.

The API path applies per-IP rate limits, honeypot discard, Turnstile verification with a stricter no-captcha bucket when the widget or transport fails, emails help@, and sends a best-effort visitor confirmation. checkRateLimitDirect now accepts failClosed for that captcha backstop (with tests).

Discovery updates: footer Contact link, sitemap /contact, and API route-count baseline 882.

Reviewed by Cursor Bugbot for commit 45d333e. Configure here.

Comment thread apps/sim/app/(landing)/contact/components/contact-form/contact-form.tsx Outdated
Comment thread apps/sim/lib/api/contracts/contact.ts Outdated
@greptile-apps

greptile-apps Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR reintroduces the public contact page and its submission flow. The main changes are:

  • New /contact landing page styled like the demo page.
  • Contact form with shared contract validation, honeypot, and Turnstile support.
  • New /api/contact route for help-inbox notifications and visitor confirmation email.
  • Contact mutation hook, footer link, sitemap entry, and rate-limiter fail-closed support.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
apps/sim/app/api/contact/route.ts Adds the contact API route with contract parsing, Turnstile verification, honeypot handling, no-captcha fallback throttling, and email delivery.
apps/sim/app/(landing)/contact/components/contact-form/contact-form.tsx Adds the client contact form with shared validation, invisible Turnstile execution, and React Query submission.
apps/sim/lib/core/rate-limiter/rate-limiter.ts Adds an opt-in fail-closed mode for direct rate-limit checks.
apps/sim/lib/api/contracts/contact.ts Adds the shared contact request and response contract used by the route and client hook.

Reviews (5): Last reviewed commit: "refactor(contact): TSDoc over inline com..." | Re-trigger Greptile

Comment thread apps/sim/app/api/contact/route.ts Outdated
Comment thread apps/sim/app/api/contact/route.ts
Comment thread apps/sim/app/(landing)/contact/components/contact-form/contact-form.tsx Outdated
- Make captcha server-authoritative: drop the client-trusted captchaUnavailable
  flag; a valid Turnstile token is the only way past the stricter fallback
  bucket, so callers can't opt out of the challenge
- Re-execute the Turnstile widget on every submit (incl. after expiry) instead
  of falling into the no-captcha path once the token expires
- Reset the pre-submit gate on mutation settle so rapid double-clicks can't fire
  a duplicate /api/contact request
- Map only feature_request to its email type; every other topic resolves to a
  General Inquiry confirmation so support requests aren't labeled bug reports
- Drop the confirmation-email promise from the success copy (it's best-effort)
- Collapse the duplicated no-captcha rate-limit branch; hoist shared response
  constants; read the Turnstile site key as a module constant
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/app/api/contact/route.ts Outdated
The Turnstile site key is already domain-bound in Cloudflare, so pinning
expectedHostname to the marketing SITE_URL (www.sim.ai) only rejected valid
tokens issued on self-hosted, preview, and apex-vs-www hosts. Remove the pin
and rely on Cloudflare's own domain binding.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor 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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 2b54626. Configure here.

Comment thread apps/sim/app/api/contact/route.ts
checkRateLimitDirect fails open on limiter-storage errors so a limiter outage
never takes down normal traffic. But the contact route's no-captcha bucket is
the only throttle on token-less submits, so a fail-open there let uncaptcha'd
requests reach the email path unthrottled during an outage.

- Add an opt-in { failClosed } option to checkRateLimitDirect; default behavior
  (fail open) is unchanged
- Use failClosed on the contact no-captcha backstop so an unenforceable limit
  rejects instead of admitting
- Cover both fail-open and fail-closed paths with tests
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor 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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 2d44d47. Configure here.

Move the captcha-design rationale into the route handler's TSDoc and drop the
inline body/JSX comments, per the project's TSDoc-only comment convention.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor 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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 45d333e. Configure here.

@waleedlatif1 waleedlatif1 merged commit af53eda into staging Jul 1, 2026
12 checks passed
@waleedlatif1 waleedlatif1 deleted the fix/contact branch July 1, 2026 08:17
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