better laodign states

This commit is contained in:
zmeyer44 2023-10-27 14:49:16 -04:00
parent 092a262653
commit 4980e4335d
3 changed files with 95 additions and 8 deletions

View File

@ -1,13 +1,19 @@
"use client";
import { useRef, useEffect, useState } from "react";
import { CardLoading } from "@/components/Cards/CalendarEvent";
import { formatDate, fromUnix, relativeTime } from "@/lib/utils/dates";
import {
formatDate,
fromUnix,
relativeTime,
addMinutesToDate,
} from "@/lib/utils/dates";
import useCurrentUser from "@/lib/hooks/useCurrentUser";
import { DUMMY_1 } from "@/constants";
import { NDKEvent } from "@nostr-dev-kit/ndk";
import { getTagValues } from "@/lib/nostr/utils";
import LargeFeedCard from "@/components/Cards/CalendarEvent/LargeFeedCard";
import LargeFeedCard, {
LoadingCard,
} from "@/components/Cards/CalendarEvent/LargeFeedCard";
import { cn } from "@/lib/utils";
type CalendarSectionProps = {
events: NDKEvent[];
@ -43,6 +49,32 @@ export default function CalendarSection({ events }: CalendarSectionProps) {
</div>
);
}
export function CalendarSectionLoading() {
const startDate = addMinutesToDate(new Date(), 60);
return (
<div className="relative flex w-full items-start gap-x-3 @container">
{/* Date Indicator */}
<div className="sticky top-[calc(var(--header-height)_+_28px)] hidden w-[230px] shrink-0 md:block">
<CalendarIcon date={startDate} />
</div>
{/* Date Indicator Mobile */}
<div className="absolute inset-y-0 right-0 z-50 md:hidden">
<div className="sticky top-[calc(var(--header-height)_+_14px)] shrink-0">
<CalendarIconOpacity date={startDate} />
</div>
</div>
{/* Events */}
<div className="flex-1 space-y-4 max-md:pt-[60px]">
<LoadingCard />
<LoadingCard />
<LoadingCard />
<LoadingCard />
</div>
</div>
);
}
function CalendarIcon({ date }: { date: Date }) {
return (
<div

View File

@ -1,11 +1,13 @@
"use client";
import { NDKEvent, type NDKKind } from "@nostr-dev-kit/ndk";
import CalendarSection from "./_components/CalendarSection";
import CalendarSection, {
CalendarSectionLoading,
} from "./_components/CalendarSection";
import useEvents from "@/lib/hooks/useEvents";
import { getTagValues } from "@/lib/nostr/utils";
import { fromUnix, daysOffset } from "@/lib/utils/dates";
export default function Page() {
const { events } = useEvents({
const { events, isLoading } = useEvents({
filter: {
kinds: [31923 as NDKKind],
limit: 100,
@ -13,6 +15,16 @@ export default function Page() {
});
const eventsByDay = groupEventsByDay(events);
if (isLoading && !eventsByDay.length) {
return (
<div className="relative flex-col px-5 pt-5 sm:pt-7">
<div className="mx-auto max-w-[900px] space-y-4">
<CalendarSectionLoading />
</div>
</div>
);
}
return (
<div className="relative flex-col px-5 pt-5 sm:pt-7">
<div className="mx-auto max-w-[900px] space-y-4">

View File

@ -15,6 +15,8 @@ import AvatarStack from "@/components/ProfileContainers/AvatarStack";
import { NDKEvent } from "@nostr-dev-kit/ndk";
import { getTagValues, getTagAllValues } from "@/lib/nostr/utils";
import { HiOutlineMapPin, HiOutlineUserCircle } from "react-icons/hi2";
import { Skeleton } from "@/components/ui/skeleton";
import { AspectRatio } from "@/components/ui/aspect-ratio";
type LargeFeedCardProps = {
event: NDKEvent;
@ -69,7 +71,7 @@ export default function LargeFeedCard({ event }: LargeFeedCardProps) {
</div>
</div>
</CardHeader>
<div className="absolute inset-y-[0.5rem] right-[0.5rem] w-2/5">
<div className="absolute inset-y-[0.5rem] right-[0.5rem] w-2/5 overflow-hidden rounded-[0.5rem]">
{image ? (
<Image
src={image}
@ -81,9 +83,50 @@ export default function LargeFeedCard({ event }: LargeFeedCardProps) {
)}
/>
) : (
<div className=""></div>
<div className="h-[100px] w-full rounded-[0.5rem] bg-gradient-to-b from-primary/50"></div>
)}
</div>
</Card>
);
}
export function LoadingCard() {
return (
<Card className="relative flex justify-between gap-x-4 rounded-[1rem] bg-muted p-[0.5rem]">
<CardHeader className="w-3/5 justify-between p-0 pr-5">
<div className="">
<div className="flex gap-x-1">
<Skeleton className="h-3 w-3" />
<Skeleton className="h-3 w-[50px]" />
</div>
<div className="pl-3">
<Skeleton className="mt-3 h-5 w-[220px]" />
<div className="mt-2 space-y-1.5">
<Skeleton className="h-3.5 w-3/4" />
<Skeleton className="h-3.5 w-3/5" />
<Skeleton className="h-3.5 w-1/4" />
</div>
</div>
</div>
<div className="mt-2 flex items-center gap-x-4 pl-2">
<div className="flex items-center gap-x-2">
<Skeleton className="h-3 w-3" />
<Skeleton className="h-3 w-[50px]" />
</div>
</div>
<div className="flex w-full flex-col justify-end self-start pl-2 pt-2">
<div className="flex w-3/4 items-center justify-stretch gap-3">
<Skeleton className="h-8 w-1/3 rounded-md" />
<Skeleton className="h-8 w-1/3 rounded-md" />
</div>
</div>
</CardHeader>
<div className="absolute inset-y-[0.5rem] right-[0.5rem] w-2/5 overflow-hidden rounded-[0.5rem]">
<AspectRatio
ratio={16 / 9}
className="w-full rounded-[0.5rem] bg-primary/20"
></AspectRatio>
</div>
</Card>
);
}