crimata-website/app/views/layouts/application.html.erb
Andrew Gundersen a1175ab00d Add passwordless email auth with pre-checkout signup
Flow: enter email → magic link → verified → Stripe checkout → dashboard

- SessionsController: new/create (send magic link), sent, verify, destroy
- Customer model: generate_magic_token!, magic_token_valid?, verify_email!
- Migration: magic_token, magic_token_expires_at, email_verified_at + unique indexes
- CustomerMailer + mailer layout with magic link email (html + text)
- CheckoutController: GET /checkout/start requires auth, passes customer_id
  as Stripe metadata; webhook finds customer by metadata and updates record
- DashboardController: requires auth, uses current_customer from session
- ApplicationController: current_customer, require_auth, redirect_after_auth
  (stores return_to so verify sends user back to where they were headed)
- Resend gem + initializer; production uses :resend delivery method
- Dev logs magic link URL to Rails logger instead of sending email
- Pricing page: simple link to /checkout/start (no more JS fetch)
- Layout: Sign in / Dashboard / Sign out nav links

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 17:12:23 -05:00

38 lines
1.6 KiB
Text

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%= content_for?(:title) ? yield(:title) : "Crimata" %></title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #fff; color: #111; }
header { padding: 1.5rem 2rem; border-bottom: 1px solid #eee; display: flex; justify-content: space-between; align-items: center; }
.logo { font-size: 1.25rem; font-weight: 700; letter-spacing: -0.5px; text-decoration: none; color: #111; }
nav a { margin-left: 1.5rem; text-decoration: none; color: #555; font-size: 0.95rem; }
nav a:hover { color: #111; }
main { max-width: 960px; margin: 0 auto; padding: 4rem 2rem; }
.btn { display: inline-block; background: #111; color: #fff; border: none; padding: 0.875rem 2.5rem; font-size: 1rem; font-weight: 600; border-radius: 8px; cursor: pointer; text-decoration: none; transition: background 0.15s; }
.btn:hover { background: #333; }
</style>
</head>
<body>
<header>
<%= link_to "Crimata", root_path, class: "logo" %>
<nav>
<%= link_to "Pricing", pricing_path %>
<% if current_customer %>
<%= link_to "Dashboard", dashboard_path %>
<%= link_to "Sign out", logout_path %>
<% else %>
<%= link_to "Sign in", login_path %>
<% end %>
</nav>
</header>
<main>
<%= yield %>
</main>
</body>
</html>