feat: add user centric features

This commit is contained in:
gosangam
2026-05-30 23:44:08 +05:30
parent 7bd2952caa
commit dcdd2383c6
63 changed files with 16783 additions and 1735 deletions
+65 -260
View File
@@ -1,279 +1,84 @@
"use client";
import Link from "next/link";
import {
BookOpen,
Mail,
Mic,
PenLine,
Newspaper,
NotebookPen,
BookA,
Users,
FileStack,
ArrowUpRight,
} from "lucide-react";
import { Compass, LogIn, Sparkles } from "lucide-react";
import { useAuth } from "@/components/auth/auth-provider";
/**
* Editorial homepage.
* / — the Home (Feed) gate.
*
* Three layers, top to bottom:
* 1. Hero — a large serif quote attributed to Śrīla Prabhupāda + a stat
* strip ("36 books · 6,866 letters · 3,787 lectures · …").
* 2. Start here — three primary entry points (Books, Letters, Lectures)
* rendered as full-width feature tiles with longer copy.
* 3. Explore — a six-card asymmetric grid for the remaining sections.
* The Instagram-inspired infinite-scroll feed of posts from people you
* follow will live here. Until that ships we show two paths:
*
* SiteHeader handles brand + nav + search + user menu, so this page paints
* directly onto the background — no PageHeader needed.
* • Sign in — for visitors who don't have an account yet; the eventual
* feed is personalised, so an account is the prerequisite.
* • Explore the Knowledgebase — Śrīla Prabhupāda's full library is
* ready today, regardless of feed status.
*
* The "Sign in" CTA hides once the user is authenticated — at that point
* there's nothing to gate, just a "feed coming soon" note above the
* always-on Knowledgebase entry.
*/
type Feature = {
href: string;
label: string;
blurb: string;
count?: string;
icon: React.ComponentType<{ className?: string }>;
};
export default function HomePage() {
const { user, loading } = useAuth();
const authed = !loading && !!user;
const FEATURED: Feature[] = [
{
href: "/books",
label: "Books",
blurb:
"Bhagavad-gītā, Śrīmad-Bhāgavatam, Caitanya-caritāmṛta and 34 more — each verse with Devanāgarī, transliteration, synonyms, translation and purport.",
count: "37 books",
icon: BookOpen,
},
{
href: "/letters",
label: "Letters",
blurb:
"Three decades of personal correspondence to disciples, family, and officials. Browse by year, recipient, or location.",
count: "6,866 letters",
icon: Mail,
},
{
href: "/transcriptions",
label: "Lectures & Conversations",
blurb:
"Lectures, morning walks, room conversations, and dialogues — the living voice of the Founder-Ācārya preserved in text and audio.",
count: "3,787 transcripts",
icon: Mic,
},
];
const EXPLORE: Feature[] = [
{
href: "/essays",
label: "Essays",
blurb: "Foundational standalone essays.",
count: "23 essays",
icon: PenLine,
},
{
href: "/magazines",
label: "Back to Godhead",
blurb: "The original 1944 – 1973 magazine archive.",
count: "1,124 articles",
icon: Newspaper,
},
{
href: "/journals",
label: "Journals",
blurb: "The Jaladuta Diary and The Beginning.",
count: "300 entries",
icon: NotebookPen,
},
{
href: "/glossary",
label: "Glossary",
blurb: "Sanskrit and Vedic terms with definitions.",
count: "2,749 terms",
icon: BookA,
},
{
href: "/disciples",
label: "Disciples",
blurb: "Initiated disciples 1966 – 1977.",
count: "4,747 names",
icon: Users,
},
{
href: "/other-documents",
label: "Other Documents",
blurb: "Miscellaneous analyses and writings.",
count: "12 documents",
icon: FileStack,
},
];
const STATS = [
{ label: "Books", value: "37" },
{ label: "Letters", value: "6,866" },
{ label: "Lectures", value: "3,787" },
{ label: "Glossary", value: "2,749" },
];
export default function Home() {
return (
<div className="flex-1">
<Hero />
<Featured />
<Explore />
</div>
);
}
<main className="flex-1 max-w-2xl w-full mx-auto px-4 sm:px-6 py-16 sm:py-24">
<div className="flex flex-col items-center text-center gap-5">
<span
aria-hidden
className="inline-flex size-14 items-center justify-center rounded-full bg-primary/10 text-primary"
>
<Sparkles className="size-6" />
</span>
// ─── Hero ────────────────────────────────────────────────────────────────
<h1 className="font-[family-name:var(--font-title)] font-semibold text-2xl sm:text-3xl text-foreground leading-tight text-balance">
{authed
? "Your feed is coming soon"
: "Welcome to Prabhupāda Says"}
</h1>
function Hero() {
return (
<section className="max-w-5xl mx-auto px-4 sm:px-6 pt-12 sm:pt-20 pb-10 sm:pb-14">
{/* Eyebrow */}
<p className="uppercase tracking-[0.22em] text-xs font-medium text-muted-foreground">
The Words of Śrīla Prabhupāda
</p>
{/* Hero quote — each sentence on its own line so the visual rhythm is
predictable regardless of viewport. text-balance keeps wraps tidy. */}
<blockquote className="mt-5 font-[family-name:var(--font-title)] font-semibold text-3xl sm:text-4xl md:text-5xl leading-[1.2] text-foreground max-w-3xl text-balance">
<span className="block">“Books are the basis.</span>
<span className="block">Purity is the force.</span>
<span className="block">Preaching is the essence.</span>
<span className="block">Utility is the principle.”</span>
</blockquote>
<p className="mt-6 text-base text-muted-foreground max-w-xl leading-relaxed">
A complete, searchable library of His Divine Grace A.C. Bhaktivedanta
Swami Prabhupāda&apos;s books, letters, lectures, and teachings — set
in modern Unicode Sanskrit, free to read.
</p>
{/* Stat strip */}
<dl className="mt-10 grid grid-cols-2 sm:grid-cols-4 gap-x-6 gap-y-4 max-w-2xl border-y border-border py-5">
{STATS.map((s) => (
<div key={s.label}>
<dd className="font-[family-name:var(--font-title)] font-semibold text-2xl text-foreground tabular-nums">
{s.value}
</dd>
<dt className="text-xs uppercase tracking-[0.14em] text-muted-foreground mt-0.5">
{s.label}
</dt>
</div>
))}
</dl>
</section>
);
}
// ─── Featured (3-up large tiles) ─────────────────────────────────────────
function Featured() {
return (
<section className="max-w-5xl mx-auto px-4 sm:px-6 py-10">
<SectionHeading eyebrow="Start here" title="Three doors in" />
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 sm:gap-5">
{FEATURED.map((f) => (
<FeaturedTile key={f.href} feature={f} />
))}
</div>
</section>
);
}
function FeaturedTile({ feature }: { feature: Feature }) {
const Icon = feature.icon;
return (
<Link
href={feature.href}
className="group relative flex flex-col h-full rounded-2xl bg-card ring-1 ring-foreground/10 hover:ring-foreground/25 hover:shadow-md transition-all p-6"
>
<div className="flex items-start justify-between">
<div className="flex items-center justify-center size-11 rounded-xl bg-primary/12 text-primary">
<Icon className="size-5" />
</div>
<ArrowUpRight className="size-4 text-muted-foreground/60 group-hover:text-foreground transition-colors" />
</div>
<h3 className="mt-5 font-[family-name:var(--font-title)] font-semibold text-2xl sm:text-[1.6rem] leading-tight text-foreground">
{feature.label}
</h3>
<p className="mt-2 text-sm text-muted-foreground leading-relaxed flex-1">
{feature.blurb}
</p>
{feature.count ? (
<p className="mt-5 text-xs uppercase tracking-[0.14em] font-medium text-muted-foreground">
{feature.count}
<p className="text-sm text-muted-foreground leading-relaxed max-w-md">
{authed
? "We're building a feed of quotes shared by the community. Until it lands, dive into the Knowledgebase — Śrīla Prabhupāda's books, letters, lectures, and teachings."
: "Sign in to follow seekers and see their quotes here once the feed launches, or jump straight into the Knowledgebase — the original, unedited writings of His Divine Grace A.C. Bhaktivedanta Swami Prabhupāda."}
</p>
) : null}
</Link>
);
}
// ─── Explore (smaller grid) ──────────────────────────────────────────────
function Explore() {
return (
<section className="max-w-5xl mx-auto px-4 sm:px-6 py-10 pb-16">
<SectionHeading eyebrow="Explore" title="The wider library" />
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4">
{EXPLORE.map((f) => (
<ExploreTile key={f.href} feature={f} />
))}
</div>
</section>
);
}
function ExploreTile({ feature }: { feature: Feature }) {
const Icon = feature.icon;
return (
<Link
href={feature.href}
className="group flex items-start gap-4 rounded-xl bg-card/70 ring-1 ring-foreground/8 hover:ring-foreground/20 hover:bg-card transition-all p-4 sm:p-5"
>
<div className="flex items-center justify-center size-9 rounded-lg bg-secondary text-secondary-foreground/80 shrink-0">
<Icon className="size-4" />
</div>
<div className="flex-1 min-w-0">
<div className="flex items-center justify-between gap-2">
<h4 className="font-[family-name:var(--font-title)] font-semibold text-lg text-foreground leading-tight">
{feature.label}
</h4>
<ArrowUpRight className="size-3.5 text-muted-foreground/50 group-hover:text-foreground transition-colors shrink-0" />
<div className="flex flex-col sm:flex-row items-center gap-3 mt-2">
{!authed ? (
<Link
href="/login"
className="inline-flex items-center justify-center gap-2 rounded-lg bg-primary text-primary-foreground px-5 h-11 text-sm font-medium hover:bg-primary/90 transition-colors min-w-[12rem]"
>
<LogIn className="size-4" />
Sign in to view feed
</Link>
) : null}
<Link
href="/search"
className={
authed
? "inline-flex items-center justify-center gap-2 rounded-lg bg-primary text-primary-foreground px-5 h-11 text-sm font-medium hover:bg-primary/90 transition-colors min-w-[12rem]"
: "inline-flex items-center justify-center gap-2 rounded-lg border border-border text-foreground px-5 h-11 text-sm font-medium hover:bg-muted transition-colors min-w-[12rem]"
}
>
<Compass className="size-4" />
Explore Knowledgebase
</Link>
</div>
<p className="text-sm text-muted-foreground mt-1 leading-relaxed">
{feature.blurb}
</p>
{feature.count ? (
<p className="text-xs uppercase tracking-[0.14em] font-medium text-muted-foreground/80 mt-2">
{feature.count}
{!authed ? (
<p className="text-xs text-muted-foreground mt-1">
No account?{" "}
<Link href="/signup" className="text-foreground hover:underline">
Create one
</Link>{" "}
— it&apos;s free.
</p>
) : null}
</div>
</Link>
);
}
// ─── Section heading (eyebrow + title) ───────────────────────────────────
function SectionHeading({
eyebrow,
title,
}: {
eyebrow: string;
title: string;
}) {
return (
<div className="mb-6 flex items-baseline gap-4">
<span className="text-xs uppercase tracking-[0.2em] font-semibold text-muted-foreground">
{eyebrow}
</span>
<span className="flex-1 h-px bg-border" />
<h2 className="font-[family-name:var(--font-title)] font-semibold text-xl sm:text-2xl text-foreground">
{title}
</h2>
</div>
</main>
);
}