"use client"; import { useEffect, useState } from "react"; import Image from "next/image"; import Link from "next/link"; import { RiArrowRightLine } from "react-icons/ri"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { cn, getLettersPlain, getTwoLetters } from "@/lib/utils"; import { NDKEvent } from "@nostr-dev-kit/ndk"; import { BANNER } from "@/constants/app"; import { nip19 } from "nostr-tools"; import useProfile from "@/lib/hooks/useProfile"; import useEvents from "@/lib/hooks/useEvents"; import { getTagsValues, getTagValues, sortEventsByTagNumber, } from "@/lib/nostr/utils"; import { Skeleton } from "@/components/ui/skeleton"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { unixTimeNowInSeconds } from "@/lib/nostr/dates"; import { uniqBy } from "ramda"; type CalendarCardProps = { calendar: NDKEvent; }; export default function CalendarCard({ calendar }: CalendarCardProps) { const { pubkey, tags, content } = calendar; const { profile } = useProfile(pubkey); const encodedEvent = calendar.encode(); const [upcomingEvents, setUpcomingEvents] = useState([]); const name = getTagValues("name", tags); const image = getTagValues("image", tags); const banner = getTagValues("banner", tags) ?? profile?.image ?? profile?.banner ?? BANNER; const description = content ?? getTagValues("about", tags); const calendarEvents = getTagsValues("a", tags); const calendarEventIdentifiers = calendarEvents .filter(Boolean) .map((e) => { if (e.includes(":") && e.split(":").length === 3) { const [kind, pubkey, identifier] = e.split(":") as [ string, string, string, ]; return { type: "naddr", data: { kind, pubkey, identifier, }, }; } else if (nip19.BECH32_REGEX.test(e)) { return nip19.decode(e); } else return; }) .filter(Boolean) .filter(({ type }) => type === "naddr") .map((e) => e.data as nip19.AddressPointer); const { events } = useEvents({ filter: { kinds: calendarEventIdentifiers.map((k) => k.kind), authors: calendarEventIdentifiers.map((k) => k.pubkey), ["#d"]: calendarEventIdentifiers.map((k) => k.identifier), }, }); useEffect(() => { if (events) { const filteredEvents = events.filter( (e) => parseInt(getTagValues("start", e.tags) ?? "0") > unixTimeNowInSeconds(), ); const sortedEvents = sortEventsByTagNumber(filteredEvents, "start"); setUpcomingEvents( uniqBy((e) => getTagValues("name", e.tags), sortedEvents), ); } }, [events]); return ( background
{name} {description} {getLettersPlain(name ?? profile?.displayName ?? profile?.name)} {/* user */} Upcoming Events: {upcomingEvents.length ? (
    {upcomingEvents.map((item) => { const { tags, content } = item; const encodedEvent = item.encode(); const name = getTagValues("name", tags); const description = content; return (
  • {name}

    {description ?? ""}

  • ); })}
) : (

No upcoming events

)}
); } export function LoadingCalendarCard() { const textColor = "bg-zinc-200"; return (
Upcoming Events:
); }