@@ -0,0 +1,158 @@
1+import Head from "next/head";
2+import Link from "next/link";
3+import { getPage } from "../../lib/lib";
4+import { join } from "path";
5+import Meta from "../../components/Meta";
6+import Container from "../../components/Container";
7+import SingleColumn from "../../components/SingleColumn";
8+import ErrorPage from "../404";
9+import Section from "../../components/Section";
10+import ob from "urbit-ob";
11+import { decode } from "html-entities";
12+import Markdown from "../../components/Markdown";
13+import Sigil from "../../components/Sigil";
14+import axios from "axios";
16+const IdPage = ({ data, markdown, network, params }) => {
17+ const { id } = params;
18+ if (!ob.isValidPatp(id)) {
19+ return <ErrorPage />;
22+ const parent = network ? network.sponsor["urbit-id"] : ob.sein(id);
24+ ob.clan(id) === "planet"
25+ ? network?.sponsor?.sponsor?.["urbit-id"] || ob.sein(parent)
31+ <title>{id} • Urbit ID • urbit.org</title>
35+ <Section className="space-y-12" narrow>
36+ <div className="flex items-center space-x-4">
37+ {/* Avatar or sigil */}
40+ className="rounded-xl"
46+ <div className="rounded-xl overflow-hidden">
47+ <Sigil patp={id} size={100} />
50+ <div className="flex flex-col">
55+ <div className="flex flex-col md:flex-row space-y-4 md:space-y-0 justify-between">
56+ <div className="flex flex-col">
57+ <p className="font-bold text-wall-400">ID Type</p>
58+ <p className="font-mono">
59+ {ob.clan(id).slice(0, 1).toUpperCase() + ob.clan(id).slice(1)}
62+ <div className="flex flex-col">
63+ <p className="font-bold text-wall-400">Status</p>
64+ <p className="font-mono">
65+ {network ? "Spawned/Owned" : "Unspawned"}
68+ <div className="flex flex-col">
69+ <p className="font-bold text-wall-400">Parent</p>
70+ <Link href={`/id/${parent}`}>
71+ <a className="type-ui font-mono text-green-400">{parent}</a>
75+ <div className="flex flex-col">
76+ <p className="font-bold text-wall-400">Galaxy</p>
77+ <Link href={`/id/${galaxy}`}>
78+ <a className="type-ui font-mono text-green-400">{galaxy}</a>
83+ {(data.description !== "An Urbit ID." || markdown) && (
84+ <div className="flex flex-col space-y-4">
85+ <p className="font-bold text-wall-400">Description</p>
88+ className="flex flex-col space-y-4"
89+ dangerouslySetInnerHTML={{ __html: decode(markdown) }}
92+ <p>{data.description}</p>
96+ <hr className="text-wall-200" />
97+ <div className="flex flex-col space-y-6">
99+ Urbit is a clean-slate, peer-to-peer operating system and network.
101+ <div className="flex flex-col space-y-4">
102+ <p className="text-sm font-semibold text-wall-400">
103+ Learn how get your own Urbit ID.
105+ {/* TODO: Joining groups guide. */}
106+ <button className="button-lg max-w-xs bg-green-400 text-white">
111+ <hr className="text-wall-200" />
112+ <div className="flex flex-col space-y-1">
113+ <p>Have an Urbit ID?</p>
114+ {/* TODO Submission guide. */}
115+ <p className="font-semibold text-green-400">
116+ Claim and customize your Urbit.org page
120+ <a className="text-xl pt-8 block font-semibold">Urbit.org</a>
128+export const getServerSideProps = async ({ params }) => {
129+ let { data, content } = getPage(
130+ join(process.cwd(), "content/id/", params.id.slice(1))
131+ ) || { data: {}, content: {} };
134+ if (!data.ship && ob.isValidPatp(params.id)) {
135+ data = { ship: params.id, description: "An Urbit ID." };
138+ const network = await axios
140+ `https://mt2aga2c5l.execute-api.us-east-2.amazonaws.com/get-node?urbit-id=${params.id}`
142+ .then((res) => res.data);
144+ const markdown = content
145+ ? await Markdown({ post: { content: content } })
158+export default IdPage;