81 lines
2.6 KiB
TypeScript
81 lines
2.6 KiB
TypeScript
"use client";
|
|
|
|
/**
|
|
* VaniOfTheDayCTA — a home-page card suggesting the day's "Vāṇī of the Day":
|
|
* one prose chapter, verse, or lecture chosen by the backend (the same for
|
|
* everyone that day, never repeating within 90 days). Tapping it opens the
|
|
* item. Renders nothing until/unless the pick loads, so it never leaves an
|
|
* empty frame. Styled to match SadhnaStreakCTA.
|
|
*/
|
|
|
|
import { useEffect, useState } from "react";
|
|
import Link from "next/link";
|
|
import { ChevronRight } from "lucide-react";
|
|
import { getVaniOfTheDay, type Vani } from "@/lib/vani";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
/** Quote-marks glyph (svgrepo). Inherits color via `currentColor`. */
|
|
function QuotesIcon({ className }: { className?: string }) {
|
|
return (
|
|
<svg
|
|
viewBox="0 0 32 32"
|
|
fill="currentColor"
|
|
className={className}
|
|
aria-hidden
|
|
>
|
|
<path d="M13,11c0.6,0,1-0.4,1-1s-0.4-1-1-1c-5,0-9,4-9,9c0,2.8,2.2,5,5,5s5-2.2,5-5s-2.2-5-5-5c-0.3,0-0.7,0-1,0.1C9.3,11.8,11,11,13,11z" />
|
|
<path d="M23,13c-0.3,0-0.7,0-1,0.1c1.3-1.3,3-2.1,5-2.1c0.6,0,1-0.4,1-1s-0.4-1-1-1c-5,0-9,4-9,9c0,2.8,2.2,5,5,5s5-2.2,5-5S25.8,13,23,13z" />
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
export function VaniOfTheDayCTA({ className }: { className?: string } = {}) {
|
|
const [vani, setVani] = useState<Vani | null>(null);
|
|
|
|
useEffect(() => {
|
|
let cancelled = false;
|
|
getVaniOfTheDay()
|
|
.then((v) => {
|
|
if (!cancelled) setVani(v);
|
|
})
|
|
.catch(() => {
|
|
/* card simply doesn't render */
|
|
});
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, []);
|
|
|
|
if (!vani) return null;
|
|
|
|
// Third line: the book name for a verse/chapter, or "Lecture • DATE"
|
|
// (label + date) for a transcript.
|
|
const source =
|
|
vani.kind === "transcript"
|
|
? [vani.label, vani.date].filter(Boolean).join(" • ")
|
|
: vani.book_title || vani.label;
|
|
|
|
return (
|
|
<Link
|
|
href={vani.href}
|
|
className={cn(
|
|
"group flex w-full max-w-md items-center gap-3.5 rounded-2xl border border-border bg-card p-4 text-left transition-colors hover:border-primary/40 hover:bg-muted/40",
|
|
className,
|
|
)}
|
|
>
|
|
<div className="min-w-0 flex-1">
|
|
<p className="text-xs font-medium text-primary">Vani of the day</p>
|
|
<p className="mt-0.5 truncate text-base font-semibold text-foreground leading-snug">
|
|
{vani.title}
|
|
</p>
|
|
{source ? (
|
|
<p className="truncate text-sm text-muted-foreground leading-snug">
|
|
{source}
|
|
</p>
|
|
) : null}
|
|
</div>
|
|
<ChevronRight className="size-5 shrink-0 text-muted-foreground transition-transform group-hover:translate-x-0.5 group-hover:text-foreground" />
|
|
</Link>
|
|
);
|
|
}
|