grain.social is a photo sharing platform built on atproto.
1import { CSS, RootProps } from "@bigmoves/bff";
2import { Meta } from "@bigmoves/bff/components";
3import { Layout } from "./components/Layout.tsx";
4import { GOATCOUNTER_URL } from "./env.ts";
5import type { State } from "./state.ts";
6
7export function Root(props: Readonly<RootProps<State>>) {
8 const profile = props.ctx.state.profile;
9 const hasNotifications =
10 props.ctx.state.notifications?.find((n) => n.isRead === false) !==
11 undefined;
12 return (
13 <html lang="en" class="h-full">
14 <head>
15 <meta charset="UTF-8" />
16 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
17 <Meta meta={props.ctx.state.meta} />
18 {GOATCOUNTER_URL
19 ? (
20 <script
21 data-goatcounter={GOATCOUNTER_URL}
22 async
23 src="//gc.zgo.at/count.js"
24 />
25 )
26 : null}
27 <style dangerouslySetInnerHTML={{ __html: CSS }} />
28 <link
29 rel="preload"
30 href="/build/fonts/Jersey20-Regular.ttf"
31 as="font"
32 type="font/ttf"
33 crossorigin="anonymous"
34 />
35 <link
36 rel="stylesheet"
37 href={`/build/styles.css?${
38 props.ctx.fileFingerprints.get("styles.css")
39 }`}
40 />
41 <link
42 rel="stylesheet"
43 href="https://unpkg.com/@fortawesome/fontawesome-free@6.7.2/css/all.min.css"
44 preload
45 />
46 <script
47 type="module"
48 key="app.esm.js"
49 src={`/build/app.esm.js?${
50 props.ctx.fileFingerprints.get("app.esm.js")
51 }`}
52 />
53 </head>
54 <body class="h-full dark:bg-zinc-950 dark:text-white">
55 <Layout id="layout">
56 <Layout.Nav
57 heading={
58 <h1
59 class="text-4xl text-zinc-900 dark:text-white"
60 style={{
61 fontFamily: "'Jersey 20', sans-serif",
62 }}
63 >
64 grain
65 <sub class="bottom-[0.75rem] text-[1rem]">beta</sub>
66 </h1>
67 }
68 profile={profile}
69 hasNotifications={hasNotifications}
70 />
71 <Layout.Content>{props.children}</Layout.Content>
72 </Layout>
73 </body>
74 </html>
75 );
76}