g1t/apps/web/app/routes/repo/soon.tsx

96 lines3,928 bytesCodeBlame

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.

A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales1import { ArrowRight, Check, Sparkles } from "lucide-react";
2import { Link, data } from "react-router";
3
4import type { Route } from "./+types/soon";
5import { ROADMAP, roadmapIn, roadmapItem } from "../../lib/roadmap";
6
7export function meta({ params }: Route.MetaArgs) {
8 const item = roadmapItem(params.feature);
9 return [{ title: `${item?.title ?? "Soon"} · ${params.owner}/${params.repo} · g1t` }];
10}
11
12export function loader({ params }: Route.LoaderArgs) {
13 const item = roadmapItem(params.feature);
14 if (!item) throw data(null, { status: 404 });
15 return { item };
16}
17
18/**
19 * A page a project will have: what it is for, what it will do, and what
20 * to use until then. Reached from the project menu's Soon items.
21 */
22export default function Soon({ loaderData, params }: Route.ComponentProps) {
23 const { item } = loaderData;
24 const base = `/${params.owner}/${params.repo}`;
25 const siblings = roadmapIn(item.section).filter((other) => other.key !== item.key);
26 return (
27 <div className="mx-auto max-w-3xl">
28 <p className="flex items-center gap-2 text-sm text-muted">
29 <span>{item.section}</span>
30 <span className="text-line-strong">/</span>
31 <span className="text-fg">{item.title}</span>
32 </p>
33 <div className="mt-4 flex flex-wrap items-center gap-3">
34 <h1 className="text-3xl font-semibold tracking-tight">{item.title}</h1>
35 <span className="inline-flex items-center gap-1.5 rounded-full border border-accent/40 bg-accent/10 px-2.5 py-0.5 text-xs font-medium text-accent">
36 <Sparkles size={12} />
37 Soon
38 </span>
39 </div>
40 <p className="mt-3 text-lg text-muted">{item.summary}</p>
41
42 <section className="mt-8 rounded-xl border border-line bg-surface p-6">
43 <p className="leading-relaxed">{item.why}</p>
44 <h2 className="mt-6 text-sm font-medium text-muted">What it will do</h2>
45 <ul className="mt-3 space-y-2.5">
46 {item.plans.map((plan) => (
47 <li key={plan} className="flex gap-3 text-sm">
48 <Check size={16} className="mt-0.5 shrink-0 text-accent" />
49 <span>{plan}</span>
50 </li>
51 ))}
52 </ul>
53 </section>
54
55 {item.today && (
56 <Link
57 to={`${base}/${item.today.path}`}
58 className="group mt-4 flex items-center justify-between gap-4 rounded-xl border border-line px-5 py-4 transition-colors hover:border-line-strong hover:bg-surface"
59 >
60 <span>
61 <span className="block text-xs text-faint">Until then</span>
62 <span className="mt-0.5 block text-sm font-medium">{item.today.label}</span>
63 </span>
64 <ArrowRight size={16} className="text-faint transition-transform group-hover:translate-x-0.5 group-hover:text-fg" />
65 </Link>
66 )}
67
68 {siblings.length > 0 && (
69 <section className="mt-10">
70 <h2 className="text-sm font-medium text-muted">Also coming to {item.section}</h2>
71 <ul className="mt-3 grid gap-3 sm:grid-cols-2">
72 {siblings.map((other) => (
73 <li key={other.key}>
74 <Link
75 to={`${base}/soon/${other.key}`}
76 className="block h-full rounded-xl border border-line p-4 transition-colors hover:border-line-strong hover:bg-surface"
77 >
78 <span className="text-sm font-medium">{other.title}</span>
79 <span className="mt-1 block text-sm text-muted">{other.summary}</span>
80 </Link>
81 </li>
82 ))}
83 </ul>
84 </section>
85 )}
86
87 <p className="mt-10 text-xs text-faint">
88 {ROADMAP.length} things are on the way to every project. Want this one sooner, or something else?{" "}
89 <a href="https://g1t.sh/syntaqx/g1t/issues/new" className="text-muted hover:text-fg">
90 Tell us
91 </a>
92 .
93 </p>
94 </div>
95 );
96}