flagon-io/g1t

public

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

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

113 lines4,584 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";
Social cards for every page: og.g1t.sh5import { page } from "../../lib/meta";
A flat project menu with Code first, views as tabs, and Stripe for every owner6import { ROADMAP, type RoadmapItem, roadmapIn, roadmapItem } from "../../lib/roadmap";
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales7
Social cards for every page: og.g1t.sh8export function meta({ params, ...args }: Route.MetaArgs) {
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales9 const item = roadmapItem(params.feature);
Social cards for every page: og.g1t.sh10 return page(args, {
11 title: `${item?.title ?? "Soon"} · ${params.owner}/${params.repo} · g1t`,
12 description: item ? `Soon on g1t: ${item.summary}` : null,
13 version: item ? [item.title, item.summary] : undefined,
14 });
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales15}
16
17export function loader({ params }: Route.LoaderArgs) {
18 const item = roadmapItem(params.feature);
19 if (!item) throw data(null, { status: 404 });
20 return { item };
21}
22
23/**
24 * A page a project will have: what it is for, what it will do, and what
25 * to use until then. Reached from the project menu's Soon items.
26 */
27export default function Soon({ loaderData, params }: Route.ComponentProps) {
A flat project menu with Code first, views as tabs, and Stripe for every owner28 return <SoonView item={loaderData.item} base={`/${params.owner}/${params.repo}`} />;
29}
30
31/**
32 * A Soon page, for a project's (under `base`, `/<owner>/<project>`) or the
33 * workspace's (`/<owner>/-`).
34 */
35export function SoonView({ item, base }: { item: RoadmapItem; base: string }) {
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales36 const siblings = roadmapIn(item.section).filter((other) => other.key !== item.key);
A flat project menu with Code first, views as tabs, and Stripe for every owner37 const inWorkspace = item.section === "Workspace";
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales38 return (
39 <div className="mx-auto max-w-3xl">
Observability gets its own page; tabs never overflow40 {/* A project's tabs already say where this is; the workspace's need saying. */}
41 {inWorkspace && (
42 <p className="mb-4 flex items-center gap-2 text-sm text-muted">
43 <span>Across projects</span>
44 <span className="text-line-strong">/</span>
45 <span className="text-fg">{item.title}</span>
46 </p>
47 )}
48 <div className="flex flex-wrap items-center gap-3">
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales49 <h1 className="text-3xl font-semibold tracking-tight">{item.title}</h1>
50 <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">
51 <Sparkles size={12} />
52 Soon
53 </span>
54 </div>
55 <p className="mt-3 text-lg text-muted">{item.summary}</p>
56
57 <section className="mt-8 rounded-xl border border-line bg-surface p-6">
58 <p className="leading-relaxed">{item.why}</p>
59 <h2 className="mt-6 text-sm font-medium text-muted">What it will do</h2>
60 <ul className="mt-3 space-y-2.5">
61 {item.plans.map((plan) => (
62 <li key={plan} className="flex gap-3 text-sm">
63 <Check size={16} className="mt-0.5 shrink-0 text-accent" />
64 <span>{plan}</span>
65 </li>
66 ))}
67 </ul>
68 </section>
69
70 {item.today && (
71 <Link
72 to={`${base}/${item.today.path}`}
73 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"
74 >
75 <span>
76 <span className="block text-xs text-faint">Until then</span>
77 <span className="mt-0.5 block text-sm font-medium">{item.today.label}</span>
78 </span>
79 <ArrowRight size={16} className="text-faint transition-transform group-hover:translate-x-0.5 group-hover:text-fg" />
80 </Link>
81 )}
82
83 {siblings.length > 0 && (
84 <section className="mt-10">
A flat project menu with Code first, views as tabs, and Stripe for every owner85 <h2 className="text-sm font-medium text-muted">
86 Also coming {inWorkspace ? "across projects" : `to ${item.section}`}
87 </h2>
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales88 <ul className="mt-3 grid gap-3 sm:grid-cols-2">
89 {siblings.map((other) => (
90 <li key={other.key}>
91 <Link
92 to={`${base}/soon/${other.key}`}
93 className="block h-full rounded-xl border border-line p-4 transition-colors hover:border-line-strong hover:bg-surface"
94 >
95 <span className="text-sm font-medium">{other.title}</span>
96 <span className="mt-1 block text-sm text-muted">{other.summary}</span>
97 </Link>
98 </li>
99 ))}
100 </ul>
101 </section>
102 )}
103
104 <p className="mt-10 text-xs text-faint">
105 {ROADMAP.length} things are on the way to every project. Want this one sooner, or something else?{" "}
106 <a href="https://g1t.sh/syntaqx/g1t/issues/new" className="text-muted hover:text-fg">
107 Tell us
108 </a>
109 .
110 </p>
111 </div>
112 );
113}