< Summary

Information
Class: locations.edit.tsx
Assembly: app.routes
File(s): /home/runner/work/ClutterStock/ClutterStock/frontend/app/routes/locations.edit.tsx
Tag: 58_25416222083
Line coverage
0%
Covered lines: 0
Uncovered lines: 29
Coverable lines: 29
Total lines: 75
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 24
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/ClutterStock/ClutterStock/frontend/app/routes/locations.edit.tsx

#LineLine coverage
 1import { redirect } from "react-router";
 2import type { Route } from "./+types/locations.edit";
 3import { routes } from "~/constants/routes";
 4import { deleteLocation, getLocation, updateLocation } from "~/api/client";
 5import { LocationForm } from "~/features/locations";
 6import { tryApi } from "~/lib/action-helpers.server";
 7import { useToastFromActionData } from "~/lib/toasts";
 8import { pushFlash } from "~/lib/toasts.server";
 9
 010export function loader({ params, request }: Route.LoaderArgs) {
 011  const id = Number(params.id);
 012  if (Number.isNaN(id)) throw new Response("Not found", { status: 404 });
 013  return getLocation(id, request);
 14}
 15
 016export async function action({ request, params }: Route.ActionArgs) {
 017  const id = Number(params.id);
 018  if (Number.isNaN(id)) throw new Response("Not found", { status: 404 });
 019  const formData = await request.formData();
 020  if (formData.get("_action") === "delete") {
 021    const del = await tryApi(() => deleteLocation(id, request));
 022    if (!del.ok) return del;
 023    await pushFlash(request, { kind: "success", message: "Location deleted" });
 024    return redirect(routes.locations.list());
 25  }
 026  const name = formData.get("name");
 027  const description = formData.get("description");
 028  if (typeof name !== "string" || !name.trim()) {
 029    return { ok: false as const, error: "Name is required" };
 30  }
 031  const result = await tryApi(() =>
 32    updateLocation(
 33      id,
 34      {
 35        name: name.trim(),
 36        description:
 37          typeof description === "string" && description.trim()
 38            ? description.trim()
 39            : undefined,
 40      },
 41      request,
 42    ),
 43  );
 044  if (!result.ok) return result;
 045  await pushFlash(request, {
 46    kind: "success",
 47    message: `Location "${result.data.name}" updated`,
 48  });
 049  return redirect(routes.locations.list());
 50}
 51
 052export function meta({ loaderData }: Route.MetaArgs) {
 053  const name = loaderData?.name ?? "Location";
 054  return [{ title: `Edit ${name} | ClutterStock` }];
 55}
 56
 057export default function LocationEdit({
 58  loaderData,
 59  actionData,
 60}: Route.ComponentProps) {
 061  useToastFromActionData(actionData);
 62  const error =
 063    actionData && "error" in actionData ? actionData.error : undefined;
 64  const fieldErrors =
 065    actionData && "fieldErrors" in actionData ? actionData.fieldErrors : undefined;
 066  return (
 67    <LocationForm
 68      title="Edit location"
 69      submitLabel="Save"
 70      error={error}
 71      fieldErrors={fieldErrors}
 72      location={loaderData}
 73    />
 74  );
 75}