auto select calendar and some other simple stuff
This commit is contained in:
parent
80be2c0197
commit
e3156d7e21
@ -3,16 +3,20 @@ import { useModal } from "@/app/_providers/modal/provider";
|
|||||||
import CreateCalendarEventModal from "@/components/Modals/CreateCalendarEvent";
|
import CreateCalendarEventModal from "@/components/Modals/CreateCalendarEvent";
|
||||||
|
|
||||||
type CreateEventButtonProps = {
|
type CreateEventButtonProps = {
|
||||||
eventReference: string;
|
eventIdentifier: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function CreateEventButton({
|
export default function CreateEventButton({
|
||||||
eventReference,
|
eventIdentifier,
|
||||||
}: CreateEventButtonProps) {
|
}: CreateEventButtonProps) {
|
||||||
const modal = useModal();
|
const modal = useModal();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button onClick={() => modal?.show(<CreateCalendarEventModal />)}>
|
<Button
|
||||||
|
onClick={() =>
|
||||||
|
modal?.show(<CreateCalendarEventModal calendar={eventIdentifier} />)
|
||||||
|
}
|
||||||
|
>
|
||||||
Create Event
|
Create Event
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
@ -19,9 +19,9 @@ import {
|
|||||||
checkPayment,
|
checkPayment,
|
||||||
updateListUsersFromZaps,
|
updateListUsersFromZaps,
|
||||||
} from "@/lib/actions/zap";
|
} from "@/lib/actions/zap";
|
||||||
import { useModal } from "@/app/_providers/modal/provider";
|
|
||||||
import { type NDKEvent } from "@nostr-dev-kit/ndk";
|
import { type NDKEvent } from "@nostr-dev-kit/ndk";
|
||||||
import { btcToSats, formatNumber } from "@/lib/utils";
|
import { btcToSats, formatNumber } from "@/lib/utils";
|
||||||
|
import { nip19 } from "nostr-tools";
|
||||||
|
|
||||||
const CreateEventButton = dynamic(() => import("./CreateEventButton"), {
|
const CreateEventButton = dynamic(() => import("./CreateEventButton"), {
|
||||||
ssr: false,
|
ssr: false,
|
||||||
@ -32,13 +32,12 @@ const EditCalendarButton = dynamic(() => import("./EditCalendarButton"), {
|
|||||||
|
|
||||||
export default function Header({ event }: { event: NDKEvent }) {
|
export default function Header({ event }: { event: NDKEvent }) {
|
||||||
const { currentUser } = useCurrentUser();
|
const { currentUser } = useCurrentUser();
|
||||||
const modal = useModal();
|
|
||||||
const { ndk } = useNDK();
|
const { ndk } = useNDK();
|
||||||
const [checkingPayment, setCheckingPayment] = useState(false);
|
const [checkingPayment, setCheckingPayment] = useState(false);
|
||||||
const [hasValidPayment, setHasValidPayment] = useState(false);
|
const [hasValidPayment, setHasValidPayment] = useState(false);
|
||||||
const { pubkey, tags } = event;
|
const { pubkey, tags } = event;
|
||||||
const { profile } = useProfile(pubkey);
|
const { profile } = useProfile(pubkey);
|
||||||
const eventReference = event.encode();
|
const identifier = event.tagId();
|
||||||
const name = getTagValues("name", tags) ?? "Untitled";
|
const name = getTagValues("name", tags) ?? "Untitled";
|
||||||
const image =
|
const image =
|
||||||
getTagValues("banner", tags) ??
|
getTagValues("banner", tags) ??
|
||||||
@ -134,7 +133,7 @@ export default function Header({ event }: { event: NDKEvent }) {
|
|||||||
<div className="flex flex-wrap items-center justify-end gap-3">
|
<div className="flex flex-wrap items-center justify-end gap-3">
|
||||||
{!!currentUser && currentUser.pubkey === pubkey && (
|
{!!currentUser && currentUser.pubkey === pubkey && (
|
||||||
<>
|
<>
|
||||||
<CreateEventButton eventReference={eventReference} />
|
<CreateEventButton eventIdentifier={identifier} />
|
||||||
<EditCalendarButton event={event.rawEvent()} />
|
<EditCalendarButton event={event.rawEvent()} />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
@ -13,15 +13,17 @@ import {
|
|||||||
import { cn, getLettersPlain, getTwoLetters } from "@/lib/utils";
|
import { cn, getLettersPlain, getTwoLetters } from "@/lib/utils";
|
||||||
import { NDKEvent } from "@nostr-dev-kit/ndk";
|
import { NDKEvent } from "@nostr-dev-kit/ndk";
|
||||||
import { BANNER } from "@/constants/app";
|
import { BANNER } from "@/constants/app";
|
||||||
import { getNameToShow } from "@/lib/utils";
|
|
||||||
import { nip19 } from "nostr-tools";
|
import { nip19 } from "nostr-tools";
|
||||||
import useProfile from "@/lib/hooks/useProfile";
|
import useProfile from "@/lib/hooks/useProfile";
|
||||||
import useEvents from "@/lib/hooks/useEvents";
|
import useEvents from "@/lib/hooks/useEvents";
|
||||||
import { getTagsValues, getTagValues } from "@/lib/nostr/utils";
|
import {
|
||||||
import { useNDK } from "@/app/_providers/ndk";
|
getTagsValues,
|
||||||
|
getTagValues,
|
||||||
|
sortEventsByTagNumber,
|
||||||
|
} from "@/lib/nostr/utils";
|
||||||
import { Skeleton } from "@/components/ui/skeleton";
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
import { AspectRatio } from "@/components/ui/aspect-ratio";
|
|
||||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||||
|
import { unixTimeNowInSeconds } from "@/lib/nostr/dates";
|
||||||
|
|
||||||
type CalendarCardProps = {
|
type CalendarCardProps = {
|
||||||
calendar: NDKEvent;
|
calendar: NDKEvent;
|
||||||
@ -29,12 +31,9 @@ type CalendarCardProps = {
|
|||||||
|
|
||||||
export default function CalendarCard({ calendar }: CalendarCardProps) {
|
export default function CalendarCard({ calendar }: CalendarCardProps) {
|
||||||
const { pubkey, tags, content } = calendar;
|
const { pubkey, tags, content } = calendar;
|
||||||
const { ndk } = useNDK();
|
|
||||||
const npub = nip19.npubEncode(pubkey);
|
|
||||||
const { profile } = useProfile(pubkey);
|
const { profile } = useProfile(pubkey);
|
||||||
const encodedEvent = calendar.encode();
|
const encodedEvent = calendar.encode();
|
||||||
const [upcomingEvents, setUpcomingEvents] = useState<NDKEvent[]>([]);
|
const [upcomingEvents, setUpcomingEvents] = useState<NDKEvent[]>([]);
|
||||||
const [isFetching, setIsFetching] = useState(false);
|
|
||||||
const name = getTagValues("name", tags);
|
const name = getTagValues("name", tags);
|
||||||
const image = getTagValues("image", tags);
|
const image = getTagValues("image", tags);
|
||||||
const banner =
|
const banner =
|
||||||
@ -46,38 +45,25 @@ export default function CalendarCard({ calendar }: CalendarCardProps) {
|
|||||||
.map((e) => nip19.decode(e))
|
.map((e) => nip19.decode(e))
|
||||||
.filter(({ type }) => type === "naddr")
|
.filter(({ type }) => type === "naddr")
|
||||||
.map((e) => e.data as nip19.AddressPointer);
|
.map((e) => e.data as nip19.AddressPointer);
|
||||||
|
const { events } = useEvents({
|
||||||
async function handleFetchEvents(data: nip19.AddressPointer[]) {
|
filter: {
|
||||||
if (!ndk) return;
|
kinds: calendarEventIdentifiers.map((k) => k.kind),
|
||||||
setIsFetching(true);
|
authors: calendarEventIdentifiers.map((k) => k.pubkey),
|
||||||
const events: NDKEvent[] = [];
|
["#d"]: calendarEventIdentifiers.map((k) => k.identifier),
|
||||||
const promiseArray = [];
|
},
|
||||||
for (const info of data) {
|
});
|
||||||
const calendarEventPromise = ndk
|
|
||||||
.fetchEvent({
|
|
||||||
authors: [info.pubkey],
|
|
||||||
["#d"]: [info.identifier],
|
|
||||||
kinds: [info.kind],
|
|
||||||
})
|
|
||||||
.then((e) => e && events.push(e))
|
|
||||||
.catch((err) => console.log("err"));
|
|
||||||
promiseArray.push(calendarEventPromise);
|
|
||||||
}
|
|
||||||
await Promise.all(promiseArray);
|
|
||||||
setUpcomingEvents(events);
|
|
||||||
setIsFetching(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (events) {
|
||||||
!ndk ||
|
const filteredEvents = events.filter(
|
||||||
calendarEventIdentifiers.length === 0 ||
|
(e) =>
|
||||||
isFetching ||
|
parseInt(getTagValues("start", e.tags) ?? "0") >
|
||||||
upcomingEvents.length
|
unixTimeNowInSeconds(),
|
||||||
)
|
);
|
||||||
return;
|
const sortedEvents = sortEventsByTagNumber(filteredEvents, "start");
|
||||||
handleFetchEvents(calendarEventIdentifiers);
|
setUpcomingEvents(sortedEvents);
|
||||||
}, [ndk, calendarEventIdentifiers]);
|
}
|
||||||
|
}, [events]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="relative h-[350px] w-[250px] min-w-[250] overflow-hidden">
|
<Card className="relative h-[350px] w-[250px] min-w-[250] overflow-hidden">
|
||||||
@ -119,34 +105,40 @@ export default function CalendarCard({ calendar }: CalendarCardProps) {
|
|||||||
<CardTitle>Upcoming Events:</CardTitle>
|
<CardTitle>Upcoming Events:</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="overflow-hidden px-0">
|
<CardContent className="overflow-hidden px-0">
|
||||||
<ul className="w-full">
|
{upcomingEvents.length ? (
|
||||||
{upcomingEvents.map((item) => {
|
<ul className="w-full">
|
||||||
const { tags, content } = item;
|
{upcomingEvents.map((item) => {
|
||||||
const encodedEvent = item.encode();
|
const { tags, content } = item;
|
||||||
const name = getTagValues("name", tags);
|
const encodedEvent = item.encode();
|
||||||
const description = content;
|
const name = getTagValues("name", tags);
|
||||||
return (
|
const description = content;
|
||||||
<li key={item.id} className="w-full overflow-hidden">
|
return (
|
||||||
<Link
|
<li key={item.id} className="w-full overflow-hidden">
|
||||||
href={`/event/${encodedEvent}`}
|
<Link
|
||||||
className="flex max-w-full items-center justify-between overflow-hidden py-1.5 pl-4 pr-2 transition-colors hover:bg-muted hover:text-primary"
|
href={`/event/${encodedEvent}`}
|
||||||
>
|
className="flex max-w-full items-center justify-between overflow-hidden py-1.5 pl-4 pr-2 transition-colors hover:bg-muted hover:text-primary"
|
||||||
<div className="shrink overflow-x-hidden">
|
>
|
||||||
<h4 className="line-clamp-1 text-sm font-semibold text-card-foreground">
|
<div className="shrink overflow-x-hidden">
|
||||||
{name}
|
<h4 className="line-clamp-1 text-sm font-semibold text-card-foreground">
|
||||||
</h4>
|
{name}
|
||||||
<p className="line-clamp-2 text-[10px] leading-4 text-muted-foreground">
|
</h4>
|
||||||
{description ?? ""}
|
<p className="line-clamp-2 text-[10px] leading-4 text-muted-foreground">
|
||||||
</p>
|
{description ?? ""}
|
||||||
</div>
|
</p>
|
||||||
<div className="center ml-auto shrink-0 pl-2">
|
</div>
|
||||||
<RiArrowRightLine className="h-5 w-5" />
|
<div className="center ml-auto shrink-0 pl-2">
|
||||||
</div>
|
<RiArrowRightLine className="h-5 w-5" />
|
||||||
</Link>
|
</div>
|
||||||
</li>
|
</Link>
|
||||||
);
|
</li>
|
||||||
})}
|
);
|
||||||
</ul>
|
})}
|
||||||
|
</ul>
|
||||||
|
) : (
|
||||||
|
<div className="py-3 text-center text-sm text-muted-foreground">
|
||||||
|
<p>No upcoming events</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
@ -34,7 +34,14 @@ import useCurrentUser from "@/lib/hooks/useCurrentUser";
|
|||||||
import useImageUpload from "@/lib/hooks/useImageUpload";
|
import useImageUpload from "@/lib/hooks/useImageUpload";
|
||||||
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";
|
||||||
export default function CreateCalendarEventModal() {
|
|
||||||
|
type CreateCalendarEventModalProps = {
|
||||||
|
calendar?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function CreateCalendarEventModal({
|
||||||
|
calendar: _calendar,
|
||||||
|
}: CreateCalendarEventModalProps) {
|
||||||
const modal = useModal();
|
const modal = useModal();
|
||||||
const now = new Date(new Date().setHours(12, 0, 0, 0));
|
const now = new Date(new Date().setHours(12, 0, 0, 0));
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
@ -73,7 +80,7 @@ export default function CreateCalendarEventModal() {
|
|||||||
const [timezone, setTimezone] = useState(
|
const [timezone, setTimezone] = useState(
|
||||||
Intl.DateTimeFormat().resolvedOptions().timeZone,
|
Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||||
);
|
);
|
||||||
const [calendar, setCalendar] = useState<string>();
|
const [calendar, setCalendar] = useState<string>(_calendar ?? "");
|
||||||
const [location, setLocation] = useState<{
|
const [location, setLocation] = useState<{
|
||||||
address: string;
|
address: string;
|
||||||
name: string;
|
name: string;
|
||||||
@ -154,6 +161,7 @@ export default function CreateCalendarEventModal() {
|
|||||||
kind: 31923,
|
kind: 31923,
|
||||||
};
|
};
|
||||||
const event = await createEvent(ndk, preEvent);
|
const event = await createEvent(ndk, preEvent);
|
||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
const encodedEvent = event.encode();
|
const encodedEvent = event.encode();
|
||||||
if (calendar) {
|
if (calendar) {
|
||||||
@ -326,7 +334,7 @@ export default function CreateCalendarEventModal() {
|
|||||||
({
|
({
|
||||||
...o,
|
...o,
|
||||||
label: getTagValues("name", o.tags) as string,
|
label: getTagValues("name", o.tags) as string,
|
||||||
value: o.encode(),
|
value: o.tagId(),
|
||||||
}) as NDKEvent & {
|
}) as NDKEvent & {
|
||||||
label: string;
|
label: string;
|
||||||
value: string;
|
value: string;
|
||||||
@ -339,7 +347,7 @@ export default function CreateCalendarEventModal() {
|
|||||||
}
|
}
|
||||||
className="px-0 pr-1 font-normal"
|
className="px-0 pr-1 font-normal"
|
||||||
value={calendar}
|
value={calendar}
|
||||||
onChange={(calendar) => setCalendar(calendar.encode())}
|
onChange={(calendar) => setCalendar(calendar.tagId())}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -35,47 +35,12 @@ export default function EventsFromCalendar({
|
|||||||
["#d"]: calendarEventIdentifiers.map((k) => k.identifier),
|
["#d"]: calendarEventIdentifiers.map((k) => k.identifier),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
// async function handleFetchEvents(data: nip19.AddressPointer[]) {
|
|
||||||
// if (!ndk) return;
|
|
||||||
// setIsFetching(true);
|
|
||||||
// const events: NDKEvent[] = [];
|
|
||||||
// const promiseArray = [];
|
|
||||||
// for (const info of data) {
|
|
||||||
// console.log("INFO", info);
|
|
||||||
// const calendarEventPromise = ndk
|
|
||||||
// .fetchEvent({
|
|
||||||
// authors: [info.pubkey],
|
|
||||||
// ["#d"]: [info.identifier],
|
|
||||||
// kinds: [info.kind],
|
|
||||||
// })
|
|
||||||
// .then((e) => e && events.push(e))
|
|
||||||
// .catch((err) => console.log("err"));
|
|
||||||
// promiseArray.push(calendarEventPromise);
|
|
||||||
// }
|
|
||||||
// await Promise.all(promiseArray);
|
|
||||||
// setEvents(events);
|
|
||||||
// setIsFetching(false);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// if (
|
|
||||||
// !ndk ||
|
|
||||||
// calendarEventIdentifiers.length === 0 ||
|
|
||||||
// isFetching ||
|
|
||||||
// events.length
|
|
||||||
// )
|
|
||||||
// return;
|
|
||||||
// handleFetchEvents(calendarEventIdentifiers);
|
|
||||||
// }, [ndk, calendarEventIdentifiers]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (events) {
|
if (events) {
|
||||||
const grouped = groupEventsByDay(events);
|
const grouped = groupEventsByDay(events);
|
||||||
console.log("Runnign group", events, " to", grouped);
|
|
||||||
setEventsByDay(grouped);
|
setEventsByDay(grouped);
|
||||||
}
|
}
|
||||||
}, [events]);
|
}, [events]);
|
||||||
console.log(eventsByDay);
|
|
||||||
if (isFetching) {
|
if (isFetching) {
|
||||||
if (Loader) {
|
if (Loader) {
|
||||||
return <Loader />;
|
return <Loader />;
|
||||||
|
@ -43,11 +43,29 @@ export function aTagToNip19(aTag: string[]): string {
|
|||||||
identifier: tagIdSplit[2] as string,
|
identifier: tagIdSplit[2] as string,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
export function sortEventsByTagNumber<T extends { tags: string[][] }>(
|
||||||
|
events: T[],
|
||||||
|
key: string,
|
||||||
|
swap?: boolean,
|
||||||
|
) {
|
||||||
|
const direction = swap ? -1 : 1;
|
||||||
|
return events.sort((a, b) => {
|
||||||
|
const aVal = parseInt(getTagValues(key, a.tags) ?? "0");
|
||||||
|
const bVal = parseInt(getTagValues(key, b.tags) ?? "0");
|
||||||
|
if (aVal > bVal) {
|
||||||
|
return direction;
|
||||||
|
} else if (aVal < bVal) {
|
||||||
|
return direction * -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
export const getTagValues = (name: string, tags: string[][]) => {
|
export const getTagValues = (name: string, tags: string[][]) => {
|
||||||
const [itemTag] = tags.filter((tag: string[]) => tag[0] === name);
|
const [itemTag] = tags.filter((tag: string[]) => tag[0] === name);
|
||||||
const [, item] = itemTag || [, undefined];
|
const [, item] = itemTag || [, undefined];
|
||||||
return item;
|
return item;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getTagAllValues = (name: string, tags: string[][]) => {
|
export const getTagAllValues = (name: string, tags: string[][]) => {
|
||||||
const [itemTag] = tags.filter((tag: string[]) => tag[0] === name);
|
const [itemTag] = tags.filter((tag: string[]) => tag[0] === name);
|
||||||
const itemValues = itemTag || [, undefined];
|
const itemValues = itemTag || [, undefined];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user