Skip to content

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

167 lines6,732 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";
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb972import { Link, data, redirect } from "react-router";
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales3
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
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9717/** Soon pages that have since been built, and where each is now. */
18const BUILT: Record<string, string> = { releases: "releases" };
19
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales20export function loader({ params }: Route.LoaderArgs) {
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9721 const built = BUILT[params.feature];
22 if (built) throw redirect(`/${params.owner}/${params.repo}/${built}`);
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales23 const item = roadmapItem(params.feature);
24 if (!item) throw data(null, { status: 404 });
25 return { item };
26}
27
28/**
29 * A page a project will have: what it is for, what it will do, and what
30 * to use until then. Reached from the project menu's Soon items.
31 */
32export default function Soon({ loaderData, params }: Route.ComponentProps) {
A flat project menu with Code first, views as tabs, and Stripe for every owner33 return <SoonView item={loaderData.item} base={`/${params.owner}/${params.repo}`} />;
34}
35
36/**
37 * A Soon page, for a project's (under `base`, `/<owner>/<project>`) or the
38 * workspace's (`/<owner>/-`).
39 */
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look40/**
41 * What is coming, and what to use until then. In a project, "until then"
42 * is a page of that project. Across a workspace it lives in each project,
43 * so `inProjects` lists them, or offers to make the first one.
44 */
45export function SoonView({
46 item,
47 base,
48 inProjects,
49 newProject,
50}: {
51 item: RoadmapItem;
52 base: string;
53 inProjects?: { name: string; to: string }[];
54 newProject?: string;
55}) {
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales56 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 owner57 const inWorkspace = item.section === "Workspace";
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales58 return (
59 <div className="mx-auto max-w-3xl">
Observability gets its own page; tabs never overflow60 {/* A project's tabs already say where this is; the workspace's need saying. */}
61 {inWorkspace && (
62 <p className="mb-4 flex items-center gap-2 text-sm text-muted">
63 <span>Across projects</span>
64 <span className="text-line-strong">/</span>
65 <span className="text-fg">{item.title}</span>
66 </p>
67 )}
68 <div className="flex flex-wrap items-center gap-3">
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales69 <h1 className="text-3xl font-semibold tracking-tight">{item.title}</h1>
70 <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">
71 <Sparkles size={12} />
72 Soon
73 </span>
74 </div>
75 <p className="mt-3 text-lg text-muted">{item.summary}</p>
76
77 <section className="mt-8 rounded-xl border border-line bg-surface p-6">
78 <p className="leading-relaxed">{item.why}</p>
79 <h2 className="mt-6 text-sm font-medium text-muted">What it will do</h2>
80 <ul className="mt-3 space-y-2.5">
81 {item.plans.map((plan) => (
82 <li key={plan} className="flex gap-3 text-sm">
83 <Check size={16} className="mt-0.5 shrink-0 text-accent" />
84 <span>{plan}</span>
85 </li>
86 ))}
87 </ul>
88 </section>
89
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look90 {item.today && inProjects && (
91 <section className="mt-4 rounded-xl border border-line px-5 py-4">
92 <span className="block text-xs text-faint">Until then: {item.today.label.toLowerCase()} in each project</span>
93 {inProjects.length > 0 ? (
94 <ul className="mt-2 divide-y divide-line">
95 {inProjects.map((project) => (
96 <li key={project.to}>
97 <Link
98 to={`${project.to}/${item.today!.path}`}
99 className="group flex items-center justify-between gap-4 py-2.5 text-sm"
100 >
101 <span className="font-medium">
102 {item.today!.label} in {project.name}
103 </span>
104 <ArrowRight size={16} className="text-faint transition-transform group-hover:translate-x-0.5 group-hover:text-fg" />
105 </Link>
106 </li>
107 ))}
108 </ul>
109 ) : (
110 <Link
111 to={newProject ?? "/new"}
112 className="group mt-2 flex items-center justify-between gap-4 text-sm"
113 >
114 <span>
115 <span className="font-medium">Create a project</span>
116 <span className="text-muted"> to plan {item.today.label.toLowerCase()} in it.</span>
117 </span>
118 <ArrowRight size={16} className="text-faint transition-transform group-hover:translate-x-0.5 group-hover:text-fg" />
119 </Link>
120 )}
121 </section>
122 )}
123
124 {item.today && !inProjects && (
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales125 <Link
126 to={`${base}/${item.today.path}`}
127 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"
128 >
129 <span>
130 <span className="block text-xs text-faint">Until then</span>
131 <span className="mt-0.5 block text-sm font-medium">{item.today.label}</span>
132 </span>
133 <ArrowRight size={16} className="text-faint transition-transform group-hover:translate-x-0.5 group-hover:text-fg" />
134 </Link>
135 )}
136
137 {siblings.length > 0 && (
138 <section className="mt-10">
A flat project menu with Code first, views as tabs, and Stripe for every owner139 <h2 className="text-sm font-medium text-muted">
140 Also coming {inWorkspace ? "across projects" : `to ${item.section}`}
141 </h2>
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales142 <ul className="mt-3 grid gap-3 sm:grid-cols-2">
143 {siblings.map((other) => (
144 <li key={other.key}>
145 <Link
146 to={`${base}/soon/${other.key}`}
147 className="block h-full rounded-xl border border-line p-4 transition-colors hover:border-line-strong hover:bg-surface"
148 >
149 <span className="text-sm font-medium">{other.title}</span>
150 <span className="mt-1 block text-sm text-muted">{other.summary}</span>
151 </Link>
152 </li>
153 ))}
154 </ul>
155 </section>
156 )}
157
158 <p className="mt-10 text-xs text-faint">
159 {ROADMAP.length} things are on the way to every project. Want this one sooner, or something else?{" "}
Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look160 <a href="https://g1t.sh/flagon-io/g1t/issues/new" className="text-muted hover:text-fg">
A menu shaped by how g1t works, Soon pages for every promise, and sudo for sales161 Tell us
162 </a>
163 .
164 </p>
165 </div>
166 );
167}

This file's history is long; its oldest lines are credited to the oldest commit read.