import type { ActionArgs, LoaderArgs, MetaFunction } from '@remix-run/node'; import { json, redirect } from '@remix-run/node'; import { Form, useActionData, useCatch, useLoaderData, useNavigate } from '@remix-run/react'; import * as React from 'react'; import { Alert, Drawer, TextInput, Text, useMantineTheme, Group, Button, Textarea, Stack, Select, ColorSwatch, ColorInput, ActionIcon, Input, ColorPicker } from '@mantine/core'; import { AlertTriangle, Delete, Play, RefreshCcw, Save, Square, Trash } from 'react-feather'; import invariant from 'tiny-invariant'; import { deleteTimeEntry, getTimeEntry, updateTimeEntry } from '~/models/timeEntry.server'; import { requireUserId } from '~/session.server'; import { deleteProject, getProject, getProjects, Project, updateProject } from '~/models/project.server'; import { DatePicker, TimeInput } from '@mantine/dates'; export const meta: MetaFunction = () => { return { title: 'Edit Project | WorkTimer', description: 'Edit a project. You must be logged in to do this.' }; }; export async function loader({ request, params }: LoaderArgs) { const userId = await requireUserId(request); invariant(params.projectId, 'projectId not found'); const project = await getProject({ userId, id: params.projectId }); if (!project) { throw new Response('Not Found', { status: 404 }); } return json({ project }); } export async function action({ request, params }: ActionArgs) { const userId = await requireUserId(request); invariant(params.projectId, 'projectId not found'); const project = await getProject({ userId, id: params.projectId }); if (!project) { throw new Response('Not Found', { status: 404 }); } if (request.method === 'DELETE') { await deleteProject({ userId, id: params.projectId }); } else if (request.method === 'PATCH') { const formData = await request.formData(); const name = (formData.get('name') || undefined) as string | undefined; const description = (formData.get('description') || undefined) as | string | undefined; let color = (formData.get('color') || undefined) as string | undefined; await updateProject({ projectId: params.projectId, name, description, color }); } return redirect('/projects'); } const LayoutWrapper = ({ children }: React.PropsWithChildren<{}>) => { const theme = useMantineTheme(); const navigate = useNavigate(); return ( { navigate('/projects'); }} > {children} ); }; const randomColor = () => `#${Math.floor(Math.random() * 16777215).toString(16)}`; export default function ProjectDetailsPage() { const actionData = useActionData(); const data = useLoaderData(); const theme = useMantineTheme(); const nameRef = React.useRef(null); const descriptionRef = React.useRef(null); const colorRef = React.useRef(null); const [color, setColor] = React.useState( data.project.color || randomColor() ); return (