import { useMemo } from 'react'; import { Button, Paper, Text, Menu, ActionIcon, Pagination, NativeSelect, Group, useMantineTheme, Alert, ColorSwatch } from '@mantine/core'; import { json, LoaderArgs, MetaFunction, redirect } from '@remix-run/node'; import { Form, Link, Outlet, useCatch, useLoaderData, useSearchParams } from '@remix-run/react'; import { AlertTriangle, Edit3, Plus, Settings, Trash } from 'react-feather'; import { requireUserId } from '~/session.server'; import { getProjects } from '~/models/project.server'; export const meta: MetaFunction = () => { return { title: 'Projects | WorkTimer', description: 'Manage your projects. You must be logged in to do this.' }; }; export async function loader({ request }: LoaderArgs) { const userId = await requireUserId(request); if (!userId) return redirect('/login'); const url = new URL(request.url); const page = url.searchParams.get('page') ? parseInt(url.searchParams.get('page')!, 10) : 1; const size = url.searchParams.get('size') ? parseInt(url.searchParams.get('size')!, 10) : 25; const orderBy = url.searchParams.get('orderBy') || 'createdAt'; const order = url.searchParams.get('order') || 'desc'; return json({ ...(await getProjects({ page, size, userId, orderBy, order: order === 'asc' ? 'asc' : 'desc' })) }); } export default function Projects() { const data = useLoaderData(); const [searchParams, setSearchParams] = useSearchParams(); const theme = useMantineTheme(); const pageSize = useMemo(() => { return parseInt(searchParams.get('size') || '25', 10); }, [searchParams]); const page = useMemo(() => { return parseInt(searchParams.get('page') || '1', 10); }, [searchParams]); return (

Projects

{ setSearchParams({ page: page.toString(), size: event.currentTarget.value }); }} /> {data.total / pageSize > 1 && ( { setSearchParams({ page: page.toString(), size: pageSize.toString() }); }} /> )}
{data.total} entries
{data.projects.map((project) => (
{project.name} {project.description}
Edit project } > Edit
} > Delete
))}
); } export function ErrorBoundary({ error }: { error: Error }) { console.error(error); return ( } title="Error" color="red"> An unexpected error occurred: {error.message} ); } export function CatchBoundary() { const caught = useCatch(); if (caught.status === 404) { return ( } title="Error" color="red"> Not found ); } throw new Error(`Unexpected caught response with status: ${caught.status}`); }