grain.social is a photo sharing platform built on atproto.
1import { profileLink } from "../utils.ts";
2import { Login } from "./Login.tsx";
3
4export function LoginPage({ error }: Readonly<{ error?: string }>) {
5 return (
6 <div
7 id="login"
8 class="flex justify-center items-center w-full h-[calc(100vh-56px)] relative"
9 style="background-image: url('https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:bcgltzqazw5tb6k2g3ttenbj/bafkreiewhwu3ro5dv7omedphb62db4koa7qtvyzfhiiypg3ru4tvuxkrjy@jpeg'); background-size: cover; background-position: center;"
10 >
11 <Login
12 hx-target="#login"
13 error={error}
14 errorClass="text-white"
15 inputPlaceholder="Enter your handle or pds host"
16 submitText="Login"
17 infoText="e.g., user.bsky.social, user.grain.social, example.com, https://pds.example.com"
18 infoClass="text-white text-sm! bg-zinc-950/70 p-4 font-mono"
19 />
20 <div class="absolute bottom-2 left-2 right-2 flex flex-col sm:flex-row justify-between items-start sm:items-end text-white text-sm gap-1 sm:gap-0">
21 <div class="flex flex-col sm:flex-row">
22 <span>
23 © 2025 Grain Social. All rights reserved.
24 </span>
25 <span class="flex flex-row items-center flex-wrap">
26 <a
27 href="/support/terms"
28 class="underline hover:no-underline ml-0 sm:ml-2 mt-1 sm:mt-0"
29 >
30 Terms
31 </a>
32 <span class="mx-1">|</span>
33 <a
34 href="/support/privacy"
35 class="underline hover:no-underline ml-0 sm:ml-1 mt-1 sm:mt-0"
36 >
37 Privacy
38 </a>
39 <span class="mx-1">|</span>
40 <a
41 href="/support/copyright"
42 class="underline hover:no-underline ml-0 sm:ml-1 mt-1 sm:mt-0"
43 >
44 Copyright
45 </a>
46 </span>
47 </div>
48 <div>
49 Photo by{" "}
50 <a
51 href={profileLink("chadtmiller.com")}
52 class="underline hover:no-underline"
53 >
54 @chadtmiller.com
55 </a>
56 </div>
57 </div>
58 </div>
59 );
60}