feat: update card and title description
This commit is contained in:
5596
package-lock.json
generated
Normal file
5596
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -29,6 +29,7 @@
|
||||
"next-auth": "^4.24.4",
|
||||
"react": "18.2.0",
|
||||
"react-beautiful-dnd": "^13.1.1",
|
||||
"react-contenteditable": "^3.3.7",
|
||||
"react-dom": "18.2.0",
|
||||
"react-icons": "^4.11.0",
|
||||
"react-lottie-player": "^1.5.5",
|
||||
|
||||
@@ -125,7 +125,7 @@ export default function BoardPage() {
|
||||
className="-mr-0.5 h-5 w-5"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
New
|
||||
New list
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,7 @@ export function Boards() {
|
||||
if (data?.length === 0) return <></>;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<>
|
||||
{data?.map((board) => {
|
||||
return (
|
||||
<Link key={board.publicId} href={`boards/${board.publicId}`}>
|
||||
@@ -20,6 +20,6 @@ export function Boards() {
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,84 +1,75 @@
|
||||
"use client";
|
||||
|
||||
import { useParams } from "next/navigation";
|
||||
import { HiOutlinePlusSmall } from "react-icons/hi2";
|
||||
import { Formik, Form, Field, type FieldProps } from "formik";
|
||||
import { useFormik } from "formik";
|
||||
import ContentEditable from "react-contenteditable";
|
||||
|
||||
import { api } from "~/trpc/react";
|
||||
|
||||
interface FormValues {
|
||||
cardId: string;
|
||||
title: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export default function CardPage() {
|
||||
const params = useParams();
|
||||
|
||||
const cardId = params?.id?.length && params.id[0];
|
||||
const cardId = params?.id?.length ? params.id[0] : null;
|
||||
|
||||
const { data } = api.card.byId.useQuery({ id: cardId ?? "" });
|
||||
|
||||
const updateCard = api.card.update.useMutation();
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
cardId: cardId ?? "",
|
||||
title: data?.title ? data.title : "",
|
||||
description: data?.description ? data.description : "",
|
||||
},
|
||||
onSubmit: (values: FormValues) => {
|
||||
updateCard.mutate({
|
||||
cardId: values.cardId,
|
||||
title: values.title,
|
||||
description: values.description,
|
||||
});
|
||||
},
|
||||
enableReinitialize: true,
|
||||
});
|
||||
|
||||
if (!cardId) return <></>;
|
||||
|
||||
const { data } = api.card.byId.useQuery({ id: cardId });
|
||||
|
||||
const updateCard = api.card.updateDescription.useMutation();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="mb-8 flex w-full justify-between">
|
||||
<h1 className="font-medium tracking-tight text-dark-1000 sm:text-[1.2rem]">
|
||||
{data?.title}
|
||||
</h1>
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
className="inline-flex items-center gap-x-1.5 rounded-md bg-dark-1000 px-3 py-2 text-sm font-semibold text-dark-50 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2"
|
||||
>
|
||||
<HiOutlinePlusSmall
|
||||
className="-mr-0.5 h-5 w-5"
|
||||
aria-hidden="true"
|
||||
<form onSubmit={formik.handleSubmit} className="w-full space-y-6">
|
||||
<div className="mt-2">
|
||||
<input
|
||||
type="text"
|
||||
id="title"
|
||||
name="title"
|
||||
value={formik.values.title}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.submitForm}
|
||||
className="block w-full border-0 bg-transparent p-0 py-1.5 font-medium tracking-tight text-dark-1000 focus:ring-0 sm:text-[1.2rem] sm:leading-6"
|
||||
/>
|
||||
New
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div className="mb-8 flex w-full max-w-2xl justify-between">
|
||||
<Formik
|
||||
initialValues={{
|
||||
cardId,
|
||||
description: data?.description ? data.description : "",
|
||||
}}
|
||||
onSubmit={(values: FormValues) => {
|
||||
updateCard.mutate({
|
||||
cardId: values.cardId,
|
||||
description: values.description,
|
||||
});
|
||||
}}
|
||||
enableReinitialize
|
||||
>
|
||||
<Form className="w-full space-y-6">
|
||||
<div>
|
||||
<div className="mt-2">
|
||||
<Field
|
||||
id="description"
|
||||
name="description"
|
||||
render={({ field, form }: FieldProps) => (
|
||||
<div
|
||||
onBlur={() => form.submitForm()}
|
||||
onInput={async (e) => {
|
||||
const { innerText } = e.target as HTMLDivElement;
|
||||
await form.setFieldValue("description", innerText);
|
||||
}}
|
||||
contentEditable
|
||||
className="block w-full border-0 bg-transparent py-1.5 text-dark-1000 focus-visible:outline-none sm:text-sm sm:leading-6"
|
||||
>
|
||||
{field.value || "Add description..."}
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
</Formik>
|
||||
<form onSubmit={formik.handleSubmit} className="w-full space-y-6">
|
||||
<div className="mt-2">
|
||||
<ContentEditable
|
||||
html={formik.values.description || "Add description..."}
|
||||
disabled={false}
|
||||
onChange={(e) =>
|
||||
formik.setFieldValue("description", e.target.value)
|
||||
}
|
||||
onBlur={formik.submitForm}
|
||||
className="block w-full border-0 bg-transparent py-1.5 text-dark-1000 focus-visible:outline-none sm:text-sm sm:leading-6"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -67,7 +67,7 @@ export const BoardProvider: React.FC<{ children: ReactNode }> = ({
|
||||
const refetchBoard = () =>
|
||||
utils.board.byId.refetch({ id: boardData.publicId });
|
||||
|
||||
const updateCardMutation = api.card.update.useMutation({
|
||||
const updateCardMutation = api.card.reorder.useMutation({
|
||||
onSuccess: async () => {
|
||||
try {
|
||||
await refetchBoard();
|
||||
|
||||
@@ -16,6 +16,7 @@ export const boardRouter = createTRPCRouter({
|
||||
if (!userId) return;
|
||||
|
||||
return ctx.db.query.boards.findMany({
|
||||
where: eq(boards.createdBy, userId),
|
||||
columns: {
|
||||
publicId: true,
|
||||
name: true,
|
||||
|
||||
@@ -58,10 +58,11 @@ export const cardRouter = createTRPCRouter({
|
||||
where: eq(cards.publicId, input.id),
|
||||
})
|
||||
),
|
||||
updateDescription: publicProcedure
|
||||
update: publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
cardId: z.string(),
|
||||
cardId: z.string().min(12),
|
||||
title: z.string().min(1),
|
||||
description: z.string(),
|
||||
}))
|
||||
.mutation(({ ctx, input }) => {
|
||||
@@ -69,9 +70,9 @@ export const cardRouter = createTRPCRouter({
|
||||
|
||||
if (!userId) return;
|
||||
|
||||
return ctx.db.update(cards).set({ description: input.description}).where(eq(cards.publicId, input.cardId));
|
||||
return ctx.db.update(cards).set({ title: input.title, description: input.description }).where(eq(cards.publicId, input.cardId));
|
||||
}),
|
||||
update: publicProcedure
|
||||
reorder: publicProcedure
|
||||
.input(
|
||||
z.object({
|
||||
cardId: z.string().min(12),
|
||||
|
||||
Reference in New Issue
Block a user