import { LoaderFunctionArgs, redirect, useLoaderData } from "react-router"; import { createDiscordServerPageURL, createProfilePageURL } from "#lib/urls"; import { parseOffset } from "#lib/pagination"; import { ElementType } from "#lib/types"; import { fetchProfilePosts } from "#api/profiles"; import { FooterAd, SliderAd } from "#components/advs"; import { Paginator } from "#components/pagination"; import { CardList, PostCard } from "#components/cards"; import { ProfilePageSkeleton } from "#components/pages"; import { ButtonSubmit, FormRouter } from "#components/forms"; import { ProfileHeader, Tabs, IArtistDetails, getArtist, } from "#entities/profiles"; import { paysites } from "#entities/paysites"; import { IPost } from "#entities/posts"; import { findFavouritePosts } from "#entities/account"; import { useRef, useState } from "react"; interface IProps { profile: IArtistDetails; postsData?: { count: number; offset?: number; posts: (IPost & { isFavourite: boolean })[]; }; query?: string; tags?: string[]; dmCount?: number; hasLinks?: boolean; } export function ProfilePage() { const { profile, postsData, query, tags, dmCount, hasLinks } = useLoaderData() as IProps; const [isLoading, setIsLoading] = useState(false); const { service, id, name } = profile; const paysite = paysites[service]; const title = `Posts of "${name}" from "${paysite.title}"`; return ( {!(postsData && (postsData?.count !== 0 || query)) ? undefined : ( <> setIsLoading(loading)} /> String( createProfilePageURL({ service, profileID: id, offset, query, tags, }) ) } /> > )} {!postsData ? ( Nobody here but us chickens! There are no posts for your query. ) : ( <> {postsData.posts.map((post) => ( ))} String( createProfilePageURL({ service, profileID: id, offset, query, tags, }) ) } /> > )} ); } interface ISearchFormProps extends Pick { onLoadingChange: (loading: boolean) => void; } function SearchForm({ query, onLoadingChange }: ISearchFormProps) { const timeoutRef = useRef(null); const onInputChange = (e: React.ChangeEvent) => { if (timeoutRef.current) clearTimeout(timeoutRef.current); const target = e.currentTarget as HTMLInputElement; onLoadingChange(true); timeoutRef.current = setTimeout(() => { if (target.form) target.form.requestSubmit(); onLoadingChange(false); }, 1000); }; return ( {(state) => ( <> { if (timeoutRef.current) clearTimeout(timeoutRef.current); onLoadingChange(false); }} > > )} ); } export async function loader({ params, request, }: LoaderFunctionArgs): Promise { const searchParams = new URL(request.url).searchParams; const service = params.service?.trim() || ""; const profileID = params.creator_id?.trim() || ""; if (service === "discord") { return redirect(String(createDiscordServerPageURL(profileID))); } const offsetParam = searchParams.get("o")?.trim(); const offset = offsetParam ? parseOffset(offsetParam) : undefined; const query = searchParams.get("q")?.trim(); const tags = searchParams.getAll("tag"); const profile = await getArtist(service, profileID); if (profileID == profile.public_id && profile.public_id != profile.id) { return redirect(String(createProfilePageURL({ service, profileID: profile.id }))); } const { props, results: posts } = await fetchProfilePosts( service, profileID, offset, query, tags ); const { count, dm_count, has_links } = props; const hasLinks = !has_links || has_links === "0" ? false : true; const favPostData = await findFavouritePosts( posts.map(({ service, user, id }) => { return { service, user, id, }; }) ); const finalPosts = posts.map< ElementType["postsData"]["posts"]> >((post) => { const match = favPostData.find( ({ service, user, id }) => service === post.service && user === post.user && id === post.id ); return { ...post, isFavourite: !match ? false : true }; }); return { profile, query, tags, postsData: { count, offset, posts: finalPosts, }, dmCount: dm_count, hasLinks, }; }
There are no posts for your query.