g1t/apps/web/app/components/security-activation.tsx
Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar | 1 | /** |
| 2 | * The Security and quality activation on the Billing page: what it turns | |
| 3 | * on, its price (the price book's, through billing), and starting or | |
| 4 | * ending it. Owners only; comped and enterprise workspaces have it | |
| 5 | * included. | |
| 6 | */ | |
| 7 | import { CreditCard, ShieldCheck } from "lucide-react"; | |
| 8 | import { Form } from "react-router"; | |
| 9 | ||
| 10 | import type { FeatureState } from "@g1t/contracts"; | |
| 11 | ||
| 12 | import { SubmitButton } from "./ui"; | |
| 13 | ||
| 14 | export function SecurityActivationCard({ | |
| 15 | state, | |
| 16 | owner, | |
| 17 | enabled, | |
| 18 | error, | |
| 19 | }: { | |
| 20 | state: FeatureState | null; | |
| 21 | owner: boolean; | |
| 22 | enabled: boolean; | |
| 23 | error?: string; | |
| 24 | }) { | |
| 25 | if (!state) return null; | |
| 26 | const { plan, subscription, included } = state; | |
| 27 | const status = subscription?.status; | |
| 28 | const on = state.on; | |
| 29 | const label = included ? "Included" : status === "canceling" ? "Ends at the period's end" : status === "past_due" ? "Payment due" : on ? "On" : "Off"; | |
| 30 | return ( | |
| 31 | <section id="security" className="mb-6 rounded-xl border border-line bg-surface p-5"> | |
| 32 | <div className="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between"> | |
| 33 | <div className="min-w-0"> | |
| 34 | <h2 className="flex flex-wrap items-center gap-2 text-base font-semibold"> | |
| 35 | <ShieldCheck size={16} className="text-accent" /> | |
| 36 | {plan.title} | |
| Merge branch 'worktree-agent-ad7c6d88d93adc817' | 37 | <span className={`rounded-full px-2 py-0.5 text-xs ${on ? "bg-success/15 text-success" : "border border-line text-muted"}`}>{label}</span> |
| Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar | 38 | </h2> |
| 39 | <p className="mt-1.5 max-w-2xl text-sm text-muted"> | |
| 40 | The security suite's paid features for the workspace's private repositories. Public repositories have them free, and | |
| 41 | secret scanning, push protection, vulnerability alerts and security updates stay free everywhere. | |
| 42 | </p> | |
| 43 | </div> | |
| 44 | <p className="shrink-0 sm:text-right"> | |
| 45 | <span className="text-2xl font-semibold tabular-nums tracking-tight">${(plan.monthlyCents / 100).toFixed(plan.monthlyCents % 100 ? 2 : 0)}</span> | |
| 46 | <span className="text-sm text-muted"> / month</span> | |
| 47 | <span className="block text-xs text-faint">per workspace, never per seat</span> | |
| 48 | </p> | |
| 49 | </div> | |
| 50 | <ul className="mt-4 grid gap-1.5 text-sm text-muted sm:grid-cols-2"> | |
| 51 | {plan.includes.map((line) => ( | |
| 52 | <li key={line} className="flex gap-2"> | |
| Merge branch 'worktree-agent-ad7c6d88d93adc817' | 53 | <span className="text-success">✓</span> |
| Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar | 54 | {line} |
| 55 | </li> | |
| 56 | ))} | |
| 57 | </ul> | |
| 58 | <p className="mt-3 text-xs text-faint">{plan.overage}</p> | |
| 59 | {included ? ( | |
| 60 | <p className="mt-4 text-sm text-muted">Included for this workspace at no charge.</p> | |
| 61 | ) : !enabled ? ( | |
| 62 | <p className="mt-4 text-sm text-muted">Payments are not set up on this g1t, so it is on for every workspace.</p> | |
| 63 | ) : !owner ? ( | |
| 64 | <p className="mt-4 text-sm text-muted">An owner turns it on or off.</p> | |
| 65 | ) : ( | |
| 66 | <Form method="post" className="mt-5 flex flex-wrap items-center gap-3"> | |
| 67 | <input type="hidden" name="feature" value="security" /> | |
| 68 | {!on ? ( | |
| 69 | <SubmitButton variant="accent" name="intent" value="subscribe" pending="Opening Stripe…"> | |
| 70 | <CreditCard size={14} /> | |
| 71 | Turn on Security and quality | |
| 72 | </SubmitButton> | |
| 73 | ) : status === "canceling" ? ( | |
| 74 | <SubmitButton variant="accent" name="intent" value="resume" pending="Saving…"> | |
| 75 | Keep it on | |
| 76 | </SubmitButton> | |
| 77 | ) : ( | |
| 78 | <SubmitButton variant="quiet" name="intent" value="cancel" pending="Saving…"> | |
| 79 | Turn off at the period's end | |
| 80 | </SubmitButton> | |
| 81 | )} | |
| 82 | </Form> | |
| 83 | )} | |
| 84 | {error && <p className="mt-3 text-sm text-danger">{error}</p>} | |
| 85 | </section> | |
| 86 | ); | |
| 87 | } |
This file's history is long; its oldest lines are credited to the oldest commit read.