import type { User, Team } from "@prisma/client"; import type { LinksFunction, LoaderFunction, ActionFunction } from "remix"; import { Link, useLoaderData, useActionData, Form, redirect, useCatch, json, } from "remix"; import { getUser, requireUserId } from "~/utils/session.server"; import { db } from "~/utils/db.server"; import Check from "~/icons/Check"; export const links: LinksFunction = () => { return []; }; type LoaderData = { user: (User & { team: Team & { members: User[] } }) | null; }; type ActionData = { formError?: string; formSuccess?: string; fieldErrors?: { theme: string | undefined; }; fields?: { theme: string; }; }; export const loader: LoaderFunction = async ({ request }) => { const user = await getUser(request); if (!user?.id) { return redirect("/login"); } const data: LoaderData = { user, }; return data; }; const themes = [ "light", "dark", "cupcake", "bumblebee", "emerald", "corporate", "synthwave", "retro", "cyberpunk", "valentine", ]; const badRequest = (data: ActionData) => json(data, { status: 400 }); const success = (data: ActionData) => json(data, { status: 200 }); const validateTheme = (theme: unknown) => { if (typeof theme !== "string" || !themes.includes(theme)) { return `That theme is not valid`; } }; export const action: ActionFunction = async ({ request }) => { const userId = await requireUserId(request); const user = await getUser(request); const form = await request.formData(); const theme = form.get("theme"); if (typeof theme !== "string" || user === null) { return badRequest({ formError: `Form not submitted correctly.`, }); } const fieldErrors = { theme: validateTheme(theme), }; const fields = { theme }; if (Object.values(fieldErrors).some(Boolean)) { return badRequest({ fieldErrors, fields }); } const updatedUser = await db.user.update({ where: { id: userId, }, data: { theme, }, }); if (!updatedUser) { return badRequest({ formError: `Something went wrong trying to update user.`, }); } return success({ formSuccess: "Preferences updated successfully." }); }; export default function AccountPreferencesRoute() { const data = useLoaderData(); const actionData = useActionData(); const activeTheme = data.user?.theme || "dark"; return ( <>
Preferences Manage

Theme

{themes.map((theme) => (
))} {actionData?.fieldErrors?.theme && (
)} {actionData?.formSuccess && (
)}
); } export function CatchBoundary() { const caught = useCatch(); if (caught.status === 401) { return (

You must be logged in to set your preferences.

Login
); } } export function ErrorBoundary() { return (
Something unexpected went wrong. Sorry about that.
); }