on master help sign in
getting-started: rewrite sidebar logic, change copy
bbec4b1Matilde Park
pages/getting-started/[[...slug]].js+127−112
@@ -5,77 +5,39 @@ import { useRouter } from "next/router";
5import classnames from "classnames";
5import classnames from "classnames";
6import { join } from "path";
6import { join } from "path";
7import { getPage } from "../../lib/lib";
7import { getPage } from "../../lib/lib";
8+import { decode } from "html-entities";
8import Markdown from "../../components/Markdown";
9import Markdown from "../../components/Markdown";
9import ContentArea from "../../components/ContentArea";
10import ContentArea from "../../components/ContentArea";
10import Sidebar from "../../components/Sidebar";
11import Sidebar from "../../components/Sidebar";
11import GettingStartedTree from "../../cache/getting-started.json";
12import GettingStartedTree from "../../cache/getting-started.json";
12
13
13−import { decode } from "html-entities";
14−
15−const breadcrumbs = (posts, paths) => {
16− const results = [
17− <Link href="/">Urbit</Link>,
18− <span className="px-1">/</span>,
19− <Link href="/getting-started">Getting Started</Link>,
20− ];
21− let thisLink = "/getting-started";
22− for (const path of paths) {
23− posts = posts.children[path];
24− thisLink = join(thisLink, path);
25− results.push(
26− <span className="px-1">/</span>,
27− <Link href={thisLink}>{posts.title}</Link>
28− );
29− }
30− return results;
31−};
32−
33−const childPages = (thisLink, children, level = 0) => (
34− <ul className="pl-0">
35− {children?.map((child) => (
36− <li>{pageTree(join(thisLink, child.slug), child, level)}</li>
37− ))}
38− </ul>
39−);
40−
41−const pageTree = (thisLink, tree, level = 0) => {
42− const router = useRouter();
43−
44− const isThisPage = router.asPath === thisLink;
45−
46− const pageItemClasses = classnames({
47− "pl-0 font-semibold text-wall-500 text-base hover:text-green-400":
48− level === 0,
49− "pl-8 text-wall-600 text-base hover:text-green-400": level === 1,
50− "pl-12 text-wall-600 text-base hover:text-green-400": level === 2,
51− "dot relative": isThisPage,
52− "text-green-400": isThisPage,
53− });
54−
55− if (thisLink === "/getting-started/cli") {
56− return false;
57− }
58−
59− return (
60− <>
61− <Link href={thisLink} passHref>
62− <a className={`${pageItemClasses} cursor-pointer`}>{tree.title}</a>
63− </Link>
64− </>
65− );
66−};
67−
68export default function UsingLayout({ posts, data, params, search, markdown }) {
14export default function UsingLayout({ posts, data, params, search, markdown }) {
69 const router = useRouter();
15 const router = useRouter();
70
16
71 const select = (href) => {
17 const select = (href) => {
72− const isSelected = href === router.asPath;
18+ const isSelected =
19+ `/getting-started${href === "" ? "" : `/${href}`}` === router.asPath;
73 return classnames({
20 return classnames({
74 dot: isSelected,
21 dot: isSelected,
75 "text-green-400": isSelected,
22 "text-green-400": isSelected,
76 "text-wall-500": !isSelected,
23 "text-wall-500": !isSelected,
77 });
24 });
78 };
25 };
26+
27+ let menu = [{ title: "Overview", slug: "", weight: 0 }],
28+ additional = [];
29+
30+ posts.pages.map((post) => {
31+ if (post?.tag === "additional") {
32+ additional.push(post);
33+ } else {
34+ menu.push(post);
35+ }
36+ });
37+
38+ menu.sort((a, b) => a.weight > b.weight);
39+ additional.sort((a, b) => a.weight > b.weight);
40+
79 const rootClasses = "pl-0 font-semibold text-base hover:text-green-400";
41 const rootClasses = "pl-0 font-semibold text-base hover:text-green-400";
80
42
81 return (
43 return (
@@ -86,35 +48,33 @@ export default function UsingLayout({ posts, data, params, search, markdown }) {
86 </Head>
48 </Head>
87 <div className="flex h-screen min-h-screen w-screen sidebar">
49 <div className="flex h-screen min-h-screen w-screen sidebar">
88 <Sidebar search={search}>
50 <Sidebar search={search}>
51+ <p className="uppercase font-bold text-xs text-wall-400">
52+ Getting Started
53+ </p>
89 <ul>
54 <ul>
55+ {menu.map((post) => (
90− <li>
56+ <li>
91− <Link href="/getting-started" passHref>
57+ <Link href={post.slug} passHref>
92− <a
93− className={`relative ${select(
58+ <a className={`relative ${select(post.slug)} ${rootClasses}`}>
94− "/getting-started"
59+ {post.title}
95− )} ${rootClasses}`}
96− >
97− Getting Started
98− </a>
60+ </a>
99− </Link>
61+ </Link>
100− </li>
62+ </li>
63+ ))}
101 </ul>
64 </ul>
102− {childPages("/getting-started", posts.pages)}
103 <ul className="mt-8">
65 <ul className="mt-8">
104 <p className="uppercase font-bold text-xs text-wall-400">
66 <p className="uppercase font-bold text-xs text-wall-400">
105− Advanced
67+ Additional Guides
106 </p>
68 </p>
69+ {additional.map((post) => (
107− <li>
70+ <li>
108− <Link href="/getting-started/cli" passHref>
71+ <Link href={post.slug} passHref>
109− <a
110− className={`relative ${select(
72+ <a className={`relative ${select(post.slug)} ${rootClasses}`}>
111− "/getting-started/cli"
73+ {post.title}
112− )} ${rootClasses}`}
113− >
114− CLI Install
115− </a>
74+ </a>
116− </Link>
75+ </Link>
117− </li>
76+ </li>
77+ ))}
118 </ul>
78 </ul>
119 </Sidebar>
79 </Sidebar>
120 <ContentArea
80 <ContentArea
@@ -124,28 +84,52 @@ export default function UsingLayout({ posts, data, params, search, markdown }) {
124 search={search}
84 search={search}
125 section={"Getting Started"}
85 section={"Getting Started"}
126 params={params}
86 params={params}
87+ disableToC
127 >
88 >
128 <div className="markdown">
89 <div className="markdown">
129 <article
90 <article
130 dangerouslySetInnerHTML={{ __html: decode(markdown) }}
91 dangerouslySetInnerHTML={{ __html: decode(markdown) }}
131 ></article>
92 ></article>
132 </div>
93 </div>
133− {!params.slug && <LaunchCards />}
94+ {!params?.slug && <LaunchCards />}
134 </ContentArea>
95 </ContentArea>
135 </div>
96 </div>
136 </>
97 </>
137 );
98 );
138}
99}
139
100
101+const breadcrumbs = (posts, paths) => {
102+ const results = [
103+ <Link href="/">Urbit</Link>,
104+ <span className="px-1">/</span>,
105+ <Link href="/getting-started">Getting Started</Link>,
106+ ];
107+ let thisLink = "/getting-started";
108+ for (const path of paths) {
109+ posts = posts.children[path];
110+ thisLink = join(thisLink, path);
111+ results.push(
112+ <span className="px-1">/</span>,
113+ <Link href={thisLink}>{posts.title}</Link>
114+ );
115+ }
116+ return results;
117+};
118+
140function LaunchCards() {
119function LaunchCards() {
141 const info = [
120 const info = [
142 {
121 {
143− title: "Easy",
122+ title: "Desktop app",
144 subtitle: "Deploy Urbit on your local system",
123 subtitle: "Deploy Urbit on your local system",
145 points: [
124 points: [
146− "Zero cost to you",
125+ {
126+ title: "Benefits",
147− "Set up in minutes using a desktop GUI",
127+ content: ["Free", "Set up in minutes"],
128+ },
129+ {
130+ title: "Considerations",
148− "Not a permanent way to use Urbit",
131+ content: ["Not a permanent way to use Urbit"],
132+ },
149 ],
133 ],
150 svg: (
134 svg: (
151 <svg
135 <svg
@@ -165,16 +149,23 @@ function LaunchCards() {
165 />
149 />
166 </svg>
150 </svg>
167 ),
151 ),
168− href: "/getting-started/easy",
152+ href: "/getting-started/desktop",
169 },
153 },
170 {
154 {
171− title: "Fun",
155+ title: "Server setup",
172 subtitle: "Deploy Urbit on a cloud/VPS provider",
156 subtitle: "Deploy Urbit on a cloud/VPS provider",
173 points: [
157 points: [
174− "Self-host and own your data",
158+ {
175− "Portable identity and accessibility from anywhere",
159+ title: "Benefits",
176− "Requires investment in a planet (one-time) and cloud service (monthly)",
160+ content: ["Complete data ownership", "Accessibility from anywhere"],
161+ },
162+ {
163+ title: "Considerations",
164+ content: [
165+ "Requires monthly cloud service subscription & (one-time) Urbit ID purchase",
177− "Requires Linux proficiency",
166+ "Requires Linux proficiency",
167+ ],
168+ },
178 ],
169 ],
179 svg: (
170 svg: (
180 <svg
171 <svg
@@ -192,16 +183,27 @@ function LaunchCards() {
192 />
183 />
193 </svg>
184 </svg>
194 ),
185 ),
195− href: "/getting-started/fun",
186+ href: "/getting-started/server",
196 },
187 },
197 {
188 {
198− title: "Hosted",
189+ title: "Hosted urbit",
199 subtitle: "Deploy Urbit on a managed service",
190 subtitle: "Deploy Urbit on a managed service",
200 points: [
191 points: [
192+ {
193+ title: "Benefits",
194+ content: [
195+ "Accessibility from anywhere",
201− "Streamlined setup for ownership and identity",
196+ "Streamlined setup for ownership and identity",
202− "No technical proficiency required",
197+ "No technical proficiency required",
198+ ],
199+ },
200+ {
201+ title: "Considerations",
202+ content: [
203+ "Requires monthly subscription",
203− "Need to trust your provider",
204+ "Requires trust in your service provider",
204− "Requires monthly investment",
205+ ],
206+ },
205 ],
207 ],
206 svg: (
208 svg: (
207 <svg
209 <svg
@@ -235,31 +237,44 @@ function LaunchCards() {
235 />
237 />
236 </svg>
238 </svg>
237 ),
239 ),
238− href: "/getting-started/hosting",
240+ href: "/getting-started/hosted",
239 },
241 },
240 ];
242 ];
241 return (
243 return (
242 <div className="flex flex-col space-y-8 mt-8">
244 <div className="flex flex-col space-y-8 mt-8">
243 {info.map((e) => {
245 {info.map((e) => {
244 return (
246 return (
245− <div className="py-8 bg-wall-100 rounded-xl">
247+ <div className="p-8 bg-wall-100 rounded-xl max-w-screen-md flex flex-col">
246 <div className="flex">
248 <div className="flex">
247− <div className="px-8 justify-center flex">{e.svg}</div>
249+ <div className="pl-4 pr-8 justify-center items-center flex">
250+ {e.svg}
251+ </div>
248 <div className="flex flex-col">
252 <div className="flex flex-col">
249− <h4>{e.title}</h4>
253+ <h4 className="text-2xl">{e.title}</h4>
250 <p className="font-light text-lg">{e.subtitle}</p>
254 <p className="font-light text-lg">{e.subtitle}</p>
251− <ul className="mx-8 mt-2 list-disc text-sm flex flex-col space-y-2">
252− {e.points.map((point) => {
253− return <li>{point}</li>;
254− })}
255− </ul>
256− <Link href={e.href} passHref>
257− <a className="button-lg max-w-fit text-white mt-4 bg-green-400">
258− Get Started
259− </a>
260− </Link>
261 </div>
255 </div>
262 </div>
256 </div>
257+ <div className="flex mt-8">
258+ {e.points.map((section) => {
259+ return (
260+ <div className="basis-1/2">
261+ <p className="uppercase font-bold text-sm text-black">
262+ {section.title}
263+ </p>
264+ <ul className="mx-8 my-4 list-disc text-sm flex flex-col space-y-2">
265+ {section.content.map((point) => (
266+ <li>{point}</li>
267+ ))}
268+ </ul>
269+ </div>
270+ );
271+ })}
272+ </div>
273+ <Link href={e.href} passHref>
274+ <a className="button-lg max-w-fit text-white mt-4 bg-green-400">
275+ Get Started
276+ </a>
277+ </Link>
263 </div>
278 </div>
264 );
279 );
265 })}
280 })}
@@ -268,7 +283,7 @@ function LaunchCards() {
268}
283}
269
284
270export async function getStaticProps({ params }) {
285export async function getStaticProps({ params }) {
271− const posts = GettingStartedTree;
286+ let posts = GettingStartedTree;
272
287
273 const { data, content } = getPage(
288 const { data, content } = getPage(
274 join(
289 join(