Skip to content

Commit

Permalink
feat: add update employee
Browse files Browse the repository at this point in the history
  • Loading branch information
CarlosPavajeau committed May 14, 2024
1 parent 08a2a0e commit 9ee6feb
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 1 deletion.
7 changes: 7 additions & 0 deletions src/app/(dashboard)/dashboard/employees/columns.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";

import { type ColumnDef } from "@tanstack/react-table";
import UpdateEmployeeModal from "~/app/(dashboard)/dashboard/stores/update.modal";
import { type RouterOutputs } from "~/trpc/shared";

export type Employee = RouterOutputs["employee"]["byStore"][number];
Expand All @@ -18,4 +19,10 @@ export const columns: ColumnDef<Employee>[] = [
accessorKey: "employee.phone",
header: "Teléfono",
},
{
id: "actions",
cell: ({ row }) => {
return <UpdateEmployeeModal employee={row.original} />;
},
},
];
136 changes: 136 additions & 0 deletions src/app/(dashboard)/dashboard/stores/update.modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import { zodResolver } from "@hookform/resolvers/zod";
import { RotateCw, SquarePen } from "lucide-react";
import { useEffect, useState } from "react";
import { useForm, type SubmitHandler } from "react-hook-form";
import type { TypeOf } from "zod";
import { Button } from "~/components/ui/button";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "~/components/ui/dialog";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "~/components/ui/form";
import { Input } from "~/components/ui/input";
import { useToast } from "~/components/ui/use-toast";
import { updateEmployeeInput } from "~/server/api/schemas/employees";
import { api } from "~/trpc/react";
import type { RouterOutputs } from "~/trpc/shared";

type Props = {
employee: NonNullable<RouterOutputs["employee"]["byStore"][number]>;
};

type FormValues = TypeOf<typeof updateEmployeeInput>;

const UpdateEmployeeModal = ({ employee }: Props) => {
const [isOpen, setIsOpen] = useState(false);
const form = useForm<FormValues>({
defaultValues: {
id: employee.employee.id,
name: employee.employee.name,
email: employee.employee.email,
phone: employee.employee.phone ?? undefined,
},
resolver: zodResolver(updateEmployeeInput),
});

const updateEmployee = api.employee.update.useMutation();
const onSubmit: SubmitHandler<FormValues> = (values) => {
updateEmployee.mutate(values);
};

const utils = api.useUtils();
const { toast } = useToast();
useEffect(() => {
if (updateEmployee.isSuccess) {
toast({
title: "Éxito",
description: "Empleado actualizado correctamente",
});

void utils.employee.byStore.invalidate();
setIsOpen(false);
}
}, [updateEmployee.isSuccess]);

Check warning on line 63 in src/app/(dashboard)/dashboard/stores/update.modal.tsx

View workflow job for this annotation

GitHub Actions / Run ESLint

React Hook useEffect has missing dependencies: 'toast' and 'utils.employee.byStore'. Either include them or remove the dependency array

return (
<Dialog open={isOpen} onOpenChange={setIsOpen}>
<DialogTrigger>
<Button variant="secondary" size="icon">
<SquarePen className="h-4 w-4" />
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Editar empleado</DialogTitle>
</DialogHeader>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>Nombre</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>

<FormMessage />
</FormItem>
)}
/>

<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Correo</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>

<FormMessage />
</FormItem>
)}
/>

<FormField
control={form.control}
name="phone"
render={({ field }) => (
<FormItem>
<FormLabel>Teléfono</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>

<FormMessage />
</FormItem>
)}
/>

<Button type="submit" disabled={updateEmployee.isPending}>
{updateEmployee.isPending && (
<RotateCw className="mr-2 h-4 w-4 animate-spin" />
)}
Actualizar empleado
</Button>
</form>
</Form>
</DialogContent>
</Dialog>
);
};

export default UpdateEmployeeModal;
13 changes: 12 additions & 1 deletion src/server/api/routers/employees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { eq } from "drizzle-orm";
import { z } from "zod";
import { byStoreInput } from "~/server/api/schemas/common";

import { createEmployeeInput } from "~/server/api/schemas/employees";
import {
createEmployeeInput,
updateEmployeeInput,
} from "~/server/api/schemas/employees";
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";
import { employees, employeeStore } from "~/server/db/schema";

Expand Down Expand Up @@ -62,4 +65,12 @@ export const employeesRouter = createTRPCRouter({
where: eq(employeeStore.storeId, input.storeId),
});
}),
update: protectedProcedure
.input(updateEmployeeInput)
.mutation(async ({ ctx, input }) => {
await ctx.db
.update(employees)
.set(input)
.where(eq(employees.id, input.id));
}),
});
7 changes: 7 additions & 0 deletions src/server/api/schemas/employees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,10 @@ export const createEmployeeInput = z.object({
phone: z.string().max(32).optional(),
storeId: z.string().min(1).max(36),
});

export const updateEmployeeInput = z.object({
id: z.string().min(1).max(32),
name: z.string().min(1).max(128),
email: z.string().max(255),
phone: z.string().max(32).optional(),
});

0 comments on commit 9ee6feb

Please sign in to comment.