From 6b13cfee0a4aeb7f0bbe1008547804ec41e839ef Mon Sep 17 00:00:00 2001 From: zmeyer44 Date: Mon, 23 Oct 2023 23:49:20 -0400 Subject: [PATCH] adding events --- app/(app)/app/_sections/UpcomingEvents.tsx | 84 +++++++++ app/(app)/app/page.tsx | 2 + .../event/[naddr]/_components/Header.tsx | 47 ++---- components/Cards/CalendarEvent/index.tsx | 159 ++++++++++++++++++ .../ProfileContainers/SmallProfileLine.tsx | 43 +++++ 5 files changed, 301 insertions(+), 34 deletions(-) create mode 100644 app/(app)/app/_sections/UpcomingEvents.tsx create mode 100644 components/Cards/CalendarEvent/index.tsx create mode 100644 components/ProfileContainers/SmallProfileLine.tsx diff --git a/app/(app)/app/_sections/UpcomingEvents.tsx b/app/(app)/app/_sections/UpcomingEvents.tsx new file mode 100644 index 0000000..c9d3e0f --- /dev/null +++ b/app/(app)/app/_sections/UpcomingEvents.tsx @@ -0,0 +1,84 @@ +"use client"; +import { + Section, + SectionHeader, + SectionTitle, + SectionContent, +} from "@/containers/PageSection"; +import { Button } from "@/components/ui/button"; +import { RiArrowRightLine } from "react-icons/ri"; +import CalendarEventCard, { + CardLoading, +} from "@/components/Cards/CalendarEvent"; +import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"; +import Link from "next/link"; +import useEvents from "@/lib/hooks/useEvents"; +import { Event } from "nostr-tools"; +import KindLoading from "@/components/KindCard/loading"; +import { nip19 } from "nostr-tools"; +import { getTagValues, getTagsValues } from "@/lib/nostr/utils"; +import { type NDKKind } from "@nostr-dev-kit/ndk"; +import { uniqBy } from "ramda"; + +export default function UpcomingEventsSection() { + const { events } = useEvents({ + filter: { + kinds: [31923 as NDKKind], + limit: 10, + }, + }); + + console.log("UpcomingEventsSection", events); + + const processedEvents = uniqBy( + (e) => getTagValues("name", e.tags), + events, + ).sort((a, b) => { + const aImage = getTagValues("image", a.tags); + const bImage = getTagValues("image", b.tags); + if (aImage && bImage) { + return 0; + } + if (bImage) return 1; + return -1; + }); + + return ( +
+ +
+ Upcoming Events +
+ +
+ + +
+ {processedEvents?.length > 3 ? ( + processedEvents.slice(0, 6).map((e, idx) => { + return ( + + + + ); + }) + ) : ( + <> + + + + + + )} +
+ +
+
+
+ ); +} diff --git a/app/(app)/app/page.tsx b/app/(app)/app/page.tsx index c19d0d8..970cbfe 100644 --- a/app/(app)/app/page.tsx +++ b/app/(app)/app/page.tsx @@ -1,5 +1,6 @@ import dynamic from "next/dynamic"; import ExploreCreators from "./_sections/ExploreCreators"; +import UpcomingEvents from "./_sections/UpcomingEvents"; import LongFormContentSection from "./_sections/LongFormContent"; import BecomeACreator from "./_sections/BecomeACreator"; @@ -23,6 +24,7 @@ export default function Page() { return (
+ diff --git a/app/(app)/event/[naddr]/_components/Header.tsx b/app/(app)/event/[naddr]/_components/Header.tsx index 55d1be5..c6afdb2 100644 --- a/app/(app)/event/[naddr]/_components/Header.tsx +++ b/app/(app)/event/[naddr]/_components/Header.tsx @@ -46,14 +46,10 @@ export default function Header({ event }: { event: NDKEvent }) { const { ndk } = useNDK(); const [checkingPayment, setCheckingPayment] = useState(false); const [hasValidPayment, setHasValidPayment] = useState(false); - const [syncingUsers, setSyncingUsers] = useState(false); const { pubkey, tags } = event; const { profile } = useProfile(pubkey); - console.log("EVENT", tags); - const noteIds = getTagsValues("e", tags).filter(Boolean); const title = getTagValues("name", tags) ?? "Untitled"; - console.log("tite", tags); const image = getTagValues("image", tags) ?? getTagValues("picture", tags) ?? @@ -110,19 +106,7 @@ export default function Header({ event }: { event: NDKEvent }) { setCheckingPayment(false); } } - async function handleSyncUsers() { - if (!event || !ndk) return; - setSyncingUsers(true); - try { - console.log("handleSyncUsers"); - await updateListUsersFromZaps(ndk, event.tagId(), rawEvent); - toast.success("Users Synced!"); - } catch (err) { - console.log("error syncing users", err); - } finally { - setSyncingUsers(false); - } - } + async function handleSendZap() { try { const result = await sendZap( @@ -163,7 +147,7 @@ export default function Header({ event }: { event: NDKEvent }) {
-
+

{title}

@@ -175,14 +159,7 @@ export default function Header({ event }: { event: NDKEvent }) { {!!currentUser && currentUser.pubkey === pubkey && ( <> -
-
+
{!!description && ( -

+

{description}

)}
-
+
{!!startDate && (
-

+

{formatDate(startDate, "dddd, MMMM Do")}

{!!endDate ? ( -

{`${formatDate( +

{`${formatDate( startDate, "h:mm a", )} to ${formatDate(endDate, "h:mm a")}`}

) : ( -

{`${formatDate( +

{`${formatDate( startDate, "h:mm a", )}`}

@@ -270,8 +247,10 @@ export default function Header({ event }: { event: NDKEvent }) {
{location.length > 2 ? ( <> -

{location[1]}

-

+

+ {location[1]} +

+

{location[2]}

diff --git a/components/Cards/CalendarEvent/index.tsx b/components/Cards/CalendarEvent/index.tsx new file mode 100644 index 0000000..40d478d --- /dev/null +++ b/components/Cards/CalendarEvent/index.tsx @@ -0,0 +1,159 @@ +"use client"; +import Image from "next/image"; +import { cn, formatNumber } from "@/lib/utils"; +import { Badge } from "@/components/ui/badge"; +import { RxClock, RxCalendar } from "react-icons/rx"; +import { HiOutlineUsers } from "react-icons/hi"; +import { AspectRatio } from "@/components/ui/aspect-ratio"; +import { Skeleton } from "@/components/ui/skeleton"; +import { formatDate } from "@/lib/utils/dates"; +import { NostrEvent } from "@nostr-dev-kit/ndk"; +import { + getTagAllValues, + getTagValues, + getTagsValues, +} from "@/lib/nostr/utils"; +import useProfile from "@/lib/hooks/useProfile"; +import SmallProfileLine from "@/components/ProfileContainers/SmallProfileLine"; + +type CalendarEventCardProps = { + event: NostrEvent; + className?: string; +}; + +export default function CalendarEventCard({ + className, + event, +}: CalendarEventCardProps) { + const { pubkey, tags } = event; + const { profile } = useProfile(pubkey); + + const title = getTagValues("name", tags) || "Untitled"; + console.log("tite", tags); + const image = + getTagValues("image", tags) ?? + getTagValues("picture", tags) ?? + getTagValues("banner", tags) ?? + profile?.banner; + + const description = event.content; + const startDate = getTagValues("start", tags) + ? new Date(parseInt(getTagValues("start", tags) as string) * 1000) + : null; + const endDate = getTagValues("end", tags) + ? new Date(parseInt(getTagValues("end", tags) as string) * 1000) + : null; + const getLocation = () => { + let temp = getTagAllValues("location", tags); + if (temp[0]) { + return temp; + } + return getTagAllValues("address", tags); + }; + const location = getLocation(); + + const users = getTagsValues("p", tags); + const hashtags = getTagsValues("t", tags); + return ( +
+
+ + {title} + +
+
+

{title}

+
+
+ {!!startDate && ( + <> + {startDate.getDay() === endDate?.getDay() ? ( +
+ + {formatDate(startDate, "ddd, MMM D")} +
+ ) : ( +
+ + {formatDate(startDate, "ddd, MMM D")} + {!!endDate && ( + <> + {" "} + -{" "} + {formatDate(endDate, "MMM D")} + + )} +
+ )} + +
+ + {formatDate(startDate, "h:mm a")} + {!!endDate && ( + <> + {" "} + -{" "} + {formatDate(endDate, "h:mm a")} + + )} +
+ + )} + {!!users.length && ( +
+ + {formatNumber(users.length)} +
+ )} +
+
+
+
+ +
+
+ ); +} +export function CardLoading({ className }: { className: string }) { + return ( +
+
+ +
+
+ +
+
+ + +
+
+
+
+ + + +
+
+ ); +} diff --git a/components/ProfileContainers/SmallProfileLine.tsx b/components/ProfileContainers/SmallProfileLine.tsx new file mode 100644 index 0000000..0701247 --- /dev/null +++ b/components/ProfileContainers/SmallProfileLine.tsx @@ -0,0 +1,43 @@ +import Link from "next/link"; +import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar"; +import useProfile from "@/lib/hooks/useProfile"; +import { nip19 } from "nostr-tools"; +import { getTwoLetters, getNameToShow } from "@/lib/utils"; +import { Skeleton } from "@/components/ui/skeleton"; +import { HiMiniChevronRight, HiCheckBadge } from "react-icons/hi2"; + +type ProfileInfoProps = { + pubkey: string; +}; +export default function ProfileInfo({ pubkey }: ProfileInfoProps) { + const { profile } = useProfile(pubkey); + const npub = nip19.npubEncode(pubkey); + return ( + + + + + {getTwoLetters({ npub, profile })} + + +
+ {getNameToShow({ npub, profile })} + {!!profile?.nip05 && } +
+ + ); +} + +export function LoadingProfileInfo() { + return ( +
+ +
+ +
+
+ ); +}