104 lines
2.7 KiB
TypeScript
104 lines
2.7 KiB
TypeScript
import { LoaderFunctionArgs, useLoaderData } from "react-router-dom";
|
|
import { createDMsPageURL } from "#lib/urls";
|
|
import { parseOffset } from "#lib/pagination";
|
|
import { fetchDMs } from "#api/dms";
|
|
import { PageSkeleton } from "#components/pages";
|
|
import { HeaderAd, SliderAd } from "#components/ads";
|
|
import { Paginator } from "#components/pagination";
|
|
import { CardList, DMCard } from "#components/cards";
|
|
import { FormRouter } from "#components/forms";
|
|
import { IApprovedDM } from "#entities/dms";
|
|
|
|
interface IProps {
|
|
query?: string;
|
|
count: number;
|
|
offset?: number;
|
|
dms: IApprovedDM[];
|
|
}
|
|
|
|
export function DMsPage() {
|
|
const { query, count, dms, offset } = useLoaderData() as IProps;
|
|
const title = "DMs";
|
|
const heading = "DMs";
|
|
|
|
return (
|
|
<PageSkeleton name="all-dms" title={title} heading={heading}>
|
|
<SliderAd />
|
|
<HeaderAd />
|
|
|
|
<div className="paginator" id="paginator-top">
|
|
<Paginator
|
|
count={count}
|
|
offset={offset}
|
|
constructURL={(offset) => String(createDMsPageURL(offset, query))}
|
|
/>
|
|
|
|
<FormRouter
|
|
action="/dms"
|
|
method="GET"
|
|
encType="application/x-www-form-urlencoded"
|
|
>
|
|
<input
|
|
id="q"
|
|
className="search-input"
|
|
type="text"
|
|
name="q"
|
|
autoComplete="off"
|
|
defaultValue={query}
|
|
minLength={3}
|
|
placeholder="search for dms..."
|
|
/>
|
|
<input type="submit" style={{ display: "none" }} />
|
|
</FormRouter>
|
|
</div>
|
|
|
|
<CardList layout="phone">
|
|
{count === 0 ? (
|
|
<div className="no-results">
|
|
<h2 className="site-section__subheading">
|
|
Nobody here but us chickens!
|
|
</h2>
|
|
<p className="subtitle">There are no DMs.</p>
|
|
</div>
|
|
) : (
|
|
dms.map((dm) => (
|
|
<DMCard key={dm.hash} dm={dm} artist={dm.artist} isGlobal />
|
|
))
|
|
)}
|
|
</CardList>
|
|
|
|
<div className="paginator" id="paginator-bottom">
|
|
<Paginator
|
|
count={count}
|
|
offset={offset}
|
|
constructURL={(offset) => String(createDMsPageURL(offset, query))}
|
|
/>
|
|
</div>
|
|
</PageSkeleton>
|
|
);
|
|
}
|
|
|
|
export async function loader({ request }: LoaderFunctionArgs): Promise<IProps> {
|
|
const searchParams = new URL(request.url).searchParams;
|
|
|
|
let offset: number | undefined = undefined;
|
|
{
|
|
const inputOffset = searchParams.get("o")?.trim();
|
|
if (inputOffset) {
|
|
offset = parseOffset(inputOffset);
|
|
}
|
|
}
|
|
|
|
const query = searchParams.get("q")?.trim();
|
|
|
|
const { props } = await fetchDMs(offset, query);
|
|
const { count, dms } = props;
|
|
|
|
return {
|
|
count,
|
|
offset,
|
|
query,
|
|
dms,
|
|
};
|
|
}
|