Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 99 additions & 11 deletions apps/web/app/signin/page.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,114 @@
import { redirect } from "next/dist/client/components/navigation";
import Image from "next/image";
import MarkaLogo from "@/components/MarkaLogo";
import SignInForm from "@/components/signin/SignInForm";
import { MARKA } from "@/lib/brand";
import { useTranslation } from "@/lib/i18n/server";
import { getServerAuthSession } from "@/server/auth";

export default async function SignInPage() {
const session = await getServerAuthSession();
// oxlint-disable-next-line rules-of-hooks
const { t } = await useTranslation();
if (session) {
redirect("/");
}

return (
<div className="bg-linear-to-b from-sidebar/70 relative flex min-h-svh items-center justify-center overflow-hidden via-background to-background px-4 py-10 sm:px-6">
<div
aria-hidden
className="bg-radial from-primary/12 pointer-events-none absolute inset-x-0 top-0 h-80 to-transparent blur-3xl"
/>
<div className="relative w-full max-w-md space-y-6">
<div className="flex items-center justify-center">
<MarkaLogo height={72} />
<main className="grid min-h-svh bg-background lg:grid-cols-[minmax(0,1.05fr)_minmax(28rem,0.95fr)]">
<section className="relative hidden overflow-hidden bg-primary text-primary-foreground lg:flex lg:flex-col lg:justify-between lg:p-12 xl:p-16">
<svg
aria-hidden="true"
className="pointer-events-none absolute inset-0 h-full w-full opacity-[0.12]"
fill="none"
preserveAspectRatio="xMidYMid slice"
viewBox="0 0 800 900"
>
<path
d="M-40 130H840M-40 290H840M-40 450H840M-40 610H840M-40 770H840"
stroke="currentColor"
/>
<path
d="M120 -40V940M280 -40V940M440 -40V940M600 -40V940M760 -40V940"
stroke="currentColor"
/>
<circle
cx="600"
cy="210"
r="142"
stroke="currentColor"
strokeWidth="2"
/>
<circle
cx="600"
cy="210"
r="88"
stroke="currentColor"
strokeWidth="2"
/>
<circle
cx="600"
cy="210"
r="34"
stroke="currentColor"
strokeWidth="2"
/>
<path
d="M458 210H742M600 68V352"
stroke="currentColor"
strokeWidth="2"
/>
</svg>

<div className="relative flex items-center">
<Image
src={MARKA.wordmark.white}
alt={MARKA.name}
width={510}
height={135}
priority
style={{ height: 42, width: "auto" }}
className="dark:hidden"
/>
<Image
src={MARKA.wordmark.navy}
alt=""
width={510}
height={135}
priority
style={{ height: 42, width: "auto" }}
className="hidden dark:block"
/>
</div>

<div className="relative max-w-lg pb-4 xl:pb-8">
<p className="mb-5 text-sm font-medium text-primary-foreground/65">
{t("signin.eyebrow")}
</p>
<h1 className="max-w-md text-balance text-4xl font-semibold leading-[1.08] tracking-[-0.035em] xl:text-5xl">
{t("signin.title")}
</h1>
<p className="mt-6 max-w-md text-base leading-7 text-primary-foreground/70">
{t("signin.description")}
</p>
</div>

<p className="relative text-xs text-primary-foreground/45">
{t("signin.footer")}
</p>
</section>

<section className="flex min-h-svh flex-col items-center justify-center px-5 py-8 sm:px-8 lg:px-12">
<div className="w-full max-w-md space-y-8">
<div className="flex justify-center lg:hidden">
<MarkaLogo height={44} />
</div>
<SignInForm />
<p className="text-center text-xs text-muted-foreground">
{t("signin.privacy_note")}
</p>
</div>
<SignInForm />
</div>
</div>
</section>
</main>
);
}
6 changes: 4 additions & 2 deletions apps/web/components/MarkaLogo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import Image from "next/image";
import { MARKA } from "@/lib/brand";

export default function MarkaLogo({ height }: { height: number }) {
const width = Math.round((height * 510) / 135);

return (
<span className="flex items-center">
<Image
src={MARKA.wordmark.navy}
alt={MARKA.name}
width={510}
width={width}
height={height}
style={{ height, width: "auto" }}
className="dark:hidden"
Expand All @@ -17,7 +19,7 @@ export default function MarkaLogo({ height }: { height: number }) {
src={MARKA.wordmark.white}
alt=""
aria-hidden="true"
width={510}
width={width}
height={height}
style={{ height, width: "auto" }}
className="hidden dark:block"
Expand Down
12 changes: 6 additions & 6 deletions apps/web/components/signin/SignInForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,16 @@ export default async function SignInForm() {
{providerValues && providerValues.length > 0 && (
<OAuthAutoRedirect oauthProviderId={providerValues[0].id} />
)}
<Card className="w-full rounded-2xl border-border/70 bg-card/95 shadow-xl backdrop-blur">
<CardHeader className="space-y-2 px-5 pb-3 pt-6 text-center sm:px-7 sm:pt-7">
<CardTitle className="text-2xl font-semibold tracking-tight">
<Card className="w-full rounded-xl border-border/80 bg-card shadow-sm">
<CardHeader className="space-y-2 px-5 pb-4 pt-6 sm:px-8 sm:pt-8">
<CardTitle className="text-2xl font-semibold tracking-[-0.025em]">
Welcome back
</CardTitle>
<CardDescription>
<CardDescription className="text-left leading-6">
Sign in to continue to {MARKA.name}.
</CardDescription>
</CardHeader>
<CardContent className="space-y-5 px-5 pb-6 sm:px-7 sm:pb-7">
<CardContent className="space-y-5 px-5 pb-6 sm:px-8 sm:pb-8">
{serverConfig.demoMode && (
<Alert>
<Info className="h-4 w-4" />
Expand All @@ -61,7 +61,7 @@ export default async function SignInForm() {
<>
<div className="flex w-full items-center gap-3">
<div className="flex-1 border-t border-border" />
<span className="bg-card px-1 text-xs font-medium text-muted-foreground">
<span className="bg-card px-2 text-xs font-medium text-muted-foreground">
Or continue with
</span>
<div className="flex-1 border-t border-border" />
Expand Down
7 changes: 7 additions & 0 deletions apps/web/lib/i18n/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@
"bookmarks": "Bookmarks",
"storage": "Storage"
},
"signin": {
"eyebrow": "Your personal library",
"title": "Keep the things worth finding.",
"description": "Save links, notes, images, and pages in one private place, then get back to them when you need them.",
"footer": "Self-hosted. Built for your collection.",
"privacy_note": "Private by design, ready when you are."
},
"layouts": {
"masonry": "Masonry",
"grid": "Grid",
Expand Down
Loading