From f2d547fa013464d0edada96ab52f727d12f151b8 Mon Sep 17 00:00:00 2001 From: Kalle <38327916+Sendouc@users.noreply.github.com> Date: Mon, 16 May 2022 22:56:47 +0300 Subject: [PATCH] Move user page data loading to layout route --- app/routes/u.$identifier.tsx | 63 +++++++++++++++++++++++++++++- app/routes/u.$identifier/edit.tsx | 41 +++++-------------- app/routes/u.$identifier/index.tsx | 55 ++++---------------------- 3 files changed, 78 insertions(+), 81 deletions(-) diff --git a/app/routes/u.$identifier.tsx b/app/routes/u.$identifier.tsx index b6766e503..1cd335d63 100644 --- a/app/routes/u.$identifier.tsx +++ b/app/routes/u.$identifier.tsx @@ -1,13 +1,72 @@ -import { Outlet } from "@remix-run/react"; +import type { LoaderFunction } from "@remix-run/node"; +import { json } from "@remix-run/node"; +import { Outlet, useLoaderData } from "@remix-run/react"; +import { countries } from "countries-list"; +import { z } from "zod"; import { Main } from "~/components/Main"; import { SubNav, SubNavLink } from "~/components/SubNav"; +import { db } from "~/db"; +import type { User } from "~/db/types"; +import { useUser } from "~/hooks/useUser"; +import { notFoundIfFalsy } from "~/utils/remix"; + +export const userParamsSchema = z.object({ identifier: z.string() }); + +export type UserPageLoaderData = Pick< + User, + | "id" + | "discordName" + | "discordAvatar" + | "discordDiscriminator" + | "discordId" + | "youtubeId" + | "twitch" + | "twitter" +> & { country?: { name: string; emoji: string; code: string } }; + +export const loader: LoaderFunction = ({ params }) => { + const { identifier } = userParamsSchema.parse(params); + const user = notFoundIfFalsy(db.users.findByIdentifier(identifier)); + + const countryObj = user.country + ? countries[user.country as keyof typeof countries] + : undefined; + + return json({ + id: user.id, + discordAvatar: user.discordAvatar, + discordDiscriminator: user.discordDiscriminator, + discordId: user.discordId, + discordName: user.discordName, + twitch: user.twitch, + twitter: user.twitter, + youtubeId: user.youtubeId, + country: + countryObj && user.country + ? { + name: countryObj.name, + emoji: countryObj.emoji, + code: user.country, + } + : undefined, + }); +}; export default function UserPageLayout() { + const data = useLoaderData(); + const user = useUser(); + + const isOwnPage = data.id === user?.id; + return ( <> Profile - Edit + {isOwnPage ? ( + + Edit + + ) : null}
diff --git a/app/routes/u.$identifier/edit.tsx b/app/routes/u.$identifier/edit.tsx index 4d654725e..15337b23f 100644 --- a/app/routes/u.$identifier/edit.tsx +++ b/app/routes/u.$identifier/edit.tsx @@ -1,23 +1,13 @@ -import type { - ActionFunction, - LinksFunction, - LoaderFunction, -} from "@remix-run/node"; -import { json } from "@remix-run/node"; -import { Form, useLoaderData, useTransition } from "@remix-run/react"; +import type { ActionFunction, LinksFunction } from "@remix-run/node"; +import { Form, useMatches, useTransition } from "@remix-run/react"; import { countries } from "countries-list"; -import { Button } from "~/components/Button"; -import styles from "~/styles/u-edit.css"; import { z } from "zod"; -import { falsyToNull } from "~/utils/zod"; -import { - notFoundIfFalsy, - parseRequestFormData, - requireUser, -} from "~/utils/remix"; +import { Button } from "~/components/Button"; import { db } from "~/db"; -import type { User } from "~/db/types"; -import { userParamsSchema } from "./index"; +import styles from "~/styles/u-edit.css"; +import { parseRequestFormData, requireUser } from "~/utils/remix"; +import { falsyToNull } from "~/utils/zod"; +import type { UserPageLoaderData } from "../u.$identifier"; export const links: LinksFunction = () => { return [{ rel: "stylesheet", href: styles }]; @@ -47,20 +37,9 @@ export const action: ActionFunction = async ({ request }) => { return null; }; -type UserEditLoaderData = Pick; - -export const loader: LoaderFunction = async ({ request, params }) => { - const user = await requireUser(request); - const { identifier } = userParamsSchema.parse(params); - - const userFromDb = notFoundIfFalsy(db.users.findByIdentifier(identifier)); - if (userFromDb.id !== user.id) throw new Response(null, { status: 401 }); - - return json({ country: userFromDb?.country }); -}; - export default function UserEditPage() { - const data = useLoaderData(); + const [, parentRoute] = useMatches(); + const data = parentRoute.data as UserPageLoaderData; const transition = useTransition(); return ( @@ -71,7 +50,7 @@ export default function UserEditPage() { className="u-edit__country-select" name="country" id="country" - defaultValue={data.country ?? ""} + defaultValue={data.country?.code ?? ""} >