better laodign states
This commit is contained in:
parent
092a262653
commit
4980e4335d
@ -1,13 +1,19 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { useRef, useEffect, useState } from "react";
|
import { useRef, useEffect, useState } from "react";
|
||||||
import { CardLoading } from "@/components/Cards/CalendarEvent";
|
import {
|
||||||
import { formatDate, fromUnix, relativeTime } from "@/lib/utils/dates";
|
formatDate,
|
||||||
|
fromUnix,
|
||||||
|
relativeTime,
|
||||||
|
addMinutesToDate,
|
||||||
|
} from "@/lib/utils/dates";
|
||||||
|
|
||||||
import useCurrentUser from "@/lib/hooks/useCurrentUser";
|
import useCurrentUser from "@/lib/hooks/useCurrentUser";
|
||||||
import { DUMMY_1 } from "@/constants";
|
|
||||||
import { NDKEvent } from "@nostr-dev-kit/ndk";
|
import { NDKEvent } from "@nostr-dev-kit/ndk";
|
||||||
import { getTagValues } from "@/lib/nostr/utils";
|
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";
|
import { cn } from "@/lib/utils";
|
||||||
type CalendarSectionProps = {
|
type CalendarSectionProps = {
|
||||||
events: NDKEvent[];
|
events: NDKEvent[];
|
||||||
@ -43,6 +49,32 @@ export default function CalendarSection({ events }: CalendarSectionProps) {
|
|||||||
</div>
|
</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 }) {
|
function CalendarIcon({ date }: { date: Date }) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { NDKEvent, type NDKKind } from "@nostr-dev-kit/ndk";
|
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 useEvents from "@/lib/hooks/useEvents";
|
||||||
import { getTagValues } from "@/lib/nostr/utils";
|
import { getTagValues } from "@/lib/nostr/utils";
|
||||||
import { fromUnix, daysOffset } from "@/lib/utils/dates";
|
import { fromUnix, daysOffset } from "@/lib/utils/dates";
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const { events } = useEvents({
|
const { events, isLoading } = useEvents({
|
||||||
filter: {
|
filter: {
|
||||||
kinds: [31923 as NDKKind],
|
kinds: [31923 as NDKKind],
|
||||||
limit: 100,
|
limit: 100,
|
||||||
@ -13,6 +15,16 @@ export default function Page() {
|
|||||||
});
|
});
|
||||||
const eventsByDay = groupEventsByDay(events);
|
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 (
|
return (
|
||||||
<div className="relative flex-col px-5 pt-5 sm:pt-7">
|
<div className="relative flex-col px-5 pt-5 sm:pt-7">
|
||||||
<div className="mx-auto max-w-[900px] space-y-4">
|
<div className="mx-auto max-w-[900px] space-y-4">
|
||||||
|
@ -15,6 +15,8 @@ import AvatarStack from "@/components/ProfileContainers/AvatarStack";
|
|||||||
import { NDKEvent } from "@nostr-dev-kit/ndk";
|
import { NDKEvent } from "@nostr-dev-kit/ndk";
|
||||||
import { getTagValues, getTagAllValues } from "@/lib/nostr/utils";
|
import { getTagValues, getTagAllValues } from "@/lib/nostr/utils";
|
||||||
import { HiOutlineMapPin, HiOutlineUserCircle } from "react-icons/hi2";
|
import { HiOutlineMapPin, HiOutlineUserCircle } from "react-icons/hi2";
|
||||||
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
|
import { AspectRatio } from "@/components/ui/aspect-ratio";
|
||||||
|
|
||||||
type LargeFeedCardProps = {
|
type LargeFeedCardProps = {
|
||||||
event: NDKEvent;
|
event: NDKEvent;
|
||||||
@ -69,7 +71,7 @@ export default function LargeFeedCard({ event }: LargeFeedCardProps) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</CardHeader>
|
</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 ? (
|
||||||
<Image
|
<Image
|
||||||
src={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>
|
</div>
|
||||||
</Card>
|
</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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user