sendou.ink/app/routes/u.$identifier/builds/index.tsx
Kalle 34ca290bdd
Redesign (#1179)
* Remove light mode

* Trim header

* New front page initial

* Get rid of build layout

* Breadcrumbs

* Desktop side nav

* Overhaul colors

* Add breadcrumbs

* New sub nav style

* Front page action buttons

* Add back add new build button

* Add articles page with icon

* Minor Object damage page layout tweaks

* Remove one unnecessary render from object damage

* Fix wrong link in article page

* Profile -> My Page in header

* Log in/out buttons in front

* Add drawings to front page

* Remove unnecessary comment
2022-12-05 16:05:51 +02:00

94 lines
2.8 KiB
TypeScript

import type { ActionFunction } from "@remix-run/node";
import { json, type LoaderArgs } from "@remix-run/node";
import { useLoaderData, useMatches } from "@remix-run/react";
import { z } from "zod";
import { BuildCard } from "~/components/BuildCard";
import { LinkButton } from "~/components/Button";
import { BUILD } from "~/constants";
import { db } from "~/db";
import { useTranslation } from "~/hooks/useTranslation";
import { getUser, requireUser, useUser } from "~/modules/auth";
import { atOrError } from "~/utils/arrays";
import {
notFoundIfFalsy,
parseRequestFormData,
type SendouRouteHandle,
} from "~/utils/remix";
import { userNewBuildPage } from "~/utils/urls";
import { actualNumber, id } from "~/utils/zod";
import { userParamsSchema, type UserPageLoaderData } from "../../u.$identifier";
const buildsActionSchema = z.object({
buildToDeleteId: z.preprocess(actualNumber, id),
});
export const action: ActionFunction = async ({ request }) => {
const user = await requireUser(request);
const data = await parseRequestFormData({
request,
schema: buildsActionSchema,
});
if (
!db.builds
.buildsByUserId(user.id)
.some((build) => build.id === data.buildToDeleteId)
) {
throw new Response(null, { status: 400 });
}
db.builds.deleteById(data.buildToDeleteId);
return null;
};
export const handle: SendouRouteHandle = {
i18n: ["weapons", "builds", "gear"],
};
export const loader = async ({ params, request }: LoaderArgs) => {
const loggedInUser = await getUser(request);
const { identifier } = userParamsSchema.parse(params);
const user = notFoundIfFalsy(db.users.findByIdentifier(identifier));
const builds = db.builds.buildsByUserId(user.id);
if (builds.length === 0 && loggedInUser?.id !== user.id) {
throw new Response(null, { status: 404 });
}
return json({ builds });
};
export default function UserBuildsPage() {
const { t } = useTranslation("builds");
const user = useUser();
const parentPageData = atOrError(useMatches(), -2).data as UserPageLoaderData;
const data = useLoaderData<typeof loader>();
const isOwnPage = user?.id === parentPageData.id;
return (
<div className="stack lg">
{data.builds.length < BUILD.MAX_COUNT && isOwnPage && (
<div className="stack items-end">
<LinkButton to={userNewBuildPage(parentPageData)} tiny>
{t("addBuild")}
</LinkButton>
</div>
)}
{data.builds.length > 0 ? (
<div className="builds-container">
{data.builds.map((build) => (
<BuildCard key={build.id} build={build} canEdit={isOwnPage} />
))}
</div>
) : (
<div className="text-center text-lg text-lighter font-semi-bold">
{t("noBuilds")}
</div>
)}
</div>
);
}