feat: add description on create new card

This commit is contained in:
Henry
2024-08-13 22:57:04 +01:00
parent 18de6f03d8
commit ccdbd9fa14
15 changed files with 267 additions and 200 deletions

View File

@@ -24,7 +24,7 @@ export function DeleteBoardConfirmation() {
};
return (
<>
<div className="p-5">
<div className="flex w-full flex-col justify-between pb-4">
<h2 className="text-md pb-4 font-medium text-neutral-900 dark:text-dark-1000">
Are you sure you want to delete this board?
@@ -47,6 +47,6 @@ export function DeleteBoardConfirmation() {
Delete
</button>
</div>
</>
</div>
);
}

View File

@@ -31,7 +31,7 @@ export function DeleteListConfirmation({
});
return (
<>
<div className="p-5">
<div className="flex w-full flex-col justify-between pb-4">
<h2 className="text-md pb-4 font-medium text-neutral-900 dark:text-dark-1000">
Are you sure you want to delete this list?
@@ -58,6 +58,6 @@ export function DeleteListConfirmation({
Delete
</button>
</div>
</>
</div>
);
}

View File

@@ -1,5 +1,6 @@
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import ContentEditable from "react-contenteditable";
import { api } from "~/utils/api";
import {
@@ -39,6 +40,7 @@ export function NewCardForm({ listPublicId }: NewCardFormProps) {
useForm<NewCardFormInput>({
defaultValues: {
title: "",
description: "",
listPublicId,
labelPublicIds: [],
memberPublicIds: [],
@@ -53,10 +55,10 @@ export function NewCardForm({ listPublicId }: NewCardFormProps) {
const position = watch("position");
const createCard = api.card.create.useMutation({
onSuccess: async () => {
onSuccess: () => {
refetchBoard();
},
onError: async () => {
onError: () => {
closeModal();
refetchBoard();
showPopup({
@@ -107,6 +109,7 @@ export function NewCardForm({ listPublicId }: NewCardFormProps) {
createCard.mutate({
title: data.title,
description: data.description,
listPublicId: data.listPublicId,
labelPublicIds: data.labelPublicIds,
memberPublicIds: data.memberPublicIds,
@@ -147,32 +150,38 @@ export function NewCardForm({ listPublicId }: NewCardFormProps) {
const selectedList = formattedLists.find((item) => item.selected);
return (
<>
<div className="flex w-full items-center justify-between pb-4">
<h2 className="text-sm font-bold text-neutral-900 dark:text-dark-1000">
New card
</h2>
<button
className="rounded p-1 hover:bg-light-200 focus:outline-none dark:hover:bg-dark-300"
onClick={() => closeModal()}
>
<HiXMark size={18} className="text-light-900 dark:text-dark-900" />
</button>
</div>
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label
htmlFor="title"
className="block pb-2 text-sm font-normal leading-6 text-neutral-900 dark:text-dark-1000"
<form onSubmit={handleSubmit(onSubmit)}>
<div className="px-5 pt-5">
<div className="flex w-full items-center justify-between pb-5">
<h2 className="text-sm font-bold text-neutral-900 dark:text-dark-1000">
New card
</h2>
<button
className="rounded p-1 hover:bg-light-200 focus:outline-none dark:hover:bg-dark-300"
onClick={(e) => {
closeModal();
e.preventDefault();
}}
>
Title
</label>
<HiXMark size={18} className="text-light-900 dark:text-dark-900" />
</button>
</div>
<div>
<input
id="title"
type="text"
{...register("title")}
className="block w-full rounded-md border-0 bg-dark-300 bg-white/5 py-1.5 text-neutral-900 shadow-sm ring-1 ring-inset ring-light-600 focus:ring-2 focus:ring-inset focus:ring-light-600 dark:text-dark-1000 dark:ring-dark-700 dark:focus:ring-dark-700 sm:text-sm sm:leading-6"
placeholder="Card title"
className="block w-full rounded-md border-0 bg-dark-300 bg-white/5 py-1.5 text-neutral-900 placeholder-dark-800 shadow-sm ring-1 ring-inset ring-light-600 focus:ring-2 focus:ring-inset focus:ring-light-600 dark:text-dark-1000 dark:ring-dark-700 dark:focus:ring-dark-700 sm:text-sm sm:leading-6"
/>
</div>
<div className="mt-2 ">
<ContentEditable
placeholder="Add description..."
html={watch("description") || ""}
onChange={(e) => setValue("description", e.target.value)}
className="block min-h-[70px] w-full rounded-md border-0 bg-dark-300 bg-white/5 px-3 py-1.5 text-light-900 text-neutral-900 shadow-sm ring-1 ring-inset ring-light-600 focus:ring-2 focus:ring-inset focus:ring-light-600 focus-visible:outline-none dark:text-dark-1000 dark:ring-dark-700 dark:focus:ring-dark-700 sm:text-sm sm:leading-6"
/>
</div>
<div className="mt-2 flex space-x-1">
@@ -280,7 +289,7 @@ export function NewCardForm({ listPublicId }: NewCardFormProps) {
e.preventDefault();
setValue("position", position === "start" ? "end" : "start");
}}
className="flex h-auto items-center rounded-[5px] border-[1px] border-light-600 bg-light-200 px-1.5 py-1 text-left text-xs text-light-800 hover:bg-light-300 dark:border-dark-600 dark:bg-dark-400 dark:text-dark-1000 dark:hover:bg-dark-500"
className="flex h-auto items-center rounded-[5px] border-[1px] border-light-600 bg-light-200 px-1.5 py-1 text-left text-xs text-light-800 hover:bg-light-300 focus-visible:outline-none dark:border-dark-600 dark:bg-dark-400 dark:text-dark-1000 dark:hover:bg-dark-500"
>
{position === "start" ? (
<HiOutlineBarsArrowUp size={14} />
@@ -289,8 +298,10 @@ export function NewCardForm({ listPublicId }: NewCardFormProps) {
)}
</button>
</div>
</div>
<div className="mt-3 flex items-center justify-end">
<div className="mt-5 flex items-center justify-end border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600">
<div className="mr-4 flex items-center justify-end">
<span className="mr-2 text-xs text-light-900 dark:text-dark-900">
Create more
</span>
@@ -315,7 +326,7 @@ export function NewCardForm({ listPublicId }: NewCardFormProps) {
</Switch>
</div>
<div className="mt-5 sm:mt-6">
<div>
<button
type="submit"
className="inline-flex w-full justify-center rounded-md bg-light-1000 px-3 py-2 text-sm font-semibold text-light-50 shadow-sm focus-visible:outline-none dark:bg-dark-1000 dark:text-dark-50"
@@ -323,7 +334,7 @@ export function NewCardForm({ listPublicId }: NewCardFormProps) {
Create card
</button>
</div>
</form>
</>
</div>
</form>
);
}

View File

@@ -1,4 +1,4 @@
import { useState, useEffect } from "react";
import { useEffect } from "react";
import { api } from "~/utils/api";
import { useForm } from "react-hook-form";
@@ -69,7 +69,7 @@ export function NewListForm({ boardPublicId }: { boardPublicId: string }) {
};
return (
<>
<div className="p-5">
<div className="flex w-full items-center justify-between pb-4">
<h2 className="text-sm font-bold text-neutral-900 dark:text-dark-1000">
New list
@@ -129,6 +129,6 @@ export function NewListForm({ boardPublicId }: { boardPublicId: string }) {
</button>
</div>
</form>
</>
</div>
);
}

View File

@@ -212,9 +212,19 @@ export default function BoardPage() {
>
{(provided) => (
<Link
onClick={(e) => {
if (
card.publicId.startsWith("PLACEHOLDER")
)
e.preventDefault();
}}
key={card.publicId}
href={`/cards/${card.publicId}`}
className="mb-2 flex !cursor-pointer flex-col rounded-md border border-light-200 bg-light-50 px-3 py-2 text-sm text-neutral-900 dark:border-dark-200 dark:bg-dark-300 dark:text-dark-1000 dark:hover:bg-dark-400"
className={`mb-2 flex !cursor-pointer flex-col rounded-md border border-light-200 bg-light-50 px-3 py-2 text-sm text-neutral-900 dark:border-dark-200 dark:bg-dark-300 dark:text-dark-1000 dark:hover:bg-dark-400 ${
card.publicId.startsWith("PLACEHOLDER")
? "pointer-events-none"
: ""
}`}
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
@@ -280,7 +290,7 @@ export default function BoardPage() {
</DragDropContext>
)}
</div>
<Modal>
<Modal modalSize={modalContentType === "NEW_CARD" ? "md" : "sm"}>
{modalContentType === "DELETE_BOARD" && <DeleteBoardConfirmation />}
{modalContentType === "DELETE_LIST" && (
<DeleteListConfirmation listPublicId={selectedPublicListId} />

View File

@@ -251,7 +251,7 @@ export function ImportBoardsForm() {
const [step, setStep] = useState(1);
return (
<>
<div className="p-5">
<div className="flex w-full justify-between pb-4">
<h2 className="text-sm font-medium text-neutral-900 dark:text-dark-1000">
New import
@@ -266,6 +266,6 @@ export function ImportBoardsForm() {
{step === 1 && <SelectSource handleNextStep={() => setStep(step + 1)} />}
{step === 2 && <ImportTrello />}
</>
</div>
);
}

View File

@@ -1,6 +1,8 @@
import { useRouter } from "next/navigation";
import { api } from "~/utils/api";
import { useModal } from "~/providers/modal";
import { useBoard } from "~/providers/board";
import { usePopup } from "~/providers/popup";
interface DeleteCardConfirmationProps {
cardPublicId: string;
@@ -13,16 +15,31 @@ export function DeleteCardConfirmation({
}: DeleteCardConfirmationProps) {
const { closeModal } = useModal();
const router = useRouter();
const { removeCard, refetchBoard } = useBoard();
const { showPopup } = usePopup();
const deleteCard = api.card.delete.useMutation({
onSuccess: () => {
closeModal();
router.push(`/boards/${boardPublicId}`);
},
const deleteCardMutation = api.card.delete.useMutation({
onSuccess: () => refetchBoard(),
onError: () =>
showPopup({
header: "Error deleting card",
message: "Please try again later, or contact customer support.",
}),
});
const handleDeleteCard = () => {
removeCard({
cardPublicId,
});
closeModal();
router.push(`/boards/${boardPublicId}`);
deleteCardMutation.mutate({
cardPublicId,
});
};
return (
<>
<div className="p-5">
<div className="flex w-full flex-col justify-between pb-4">
<h2 className="text-md pb-4 font-medium text-neutral-900 dark:text-dark-1000">
Are you sure you want to delete this card?
@@ -39,16 +56,12 @@ export function DeleteCardConfirmation({
Cancel
</button>
<button
onClick={() =>
deleteCard.mutate({
cardPublicId,
})
}
onClick={handleDeleteCard}
className="inline-flex justify-center rounded-md bg-light-1000 px-3 py-2 text-sm font-semibold text-light-50 shadow-sm focus-visible:outline-none dark:bg-dark-1000 dark:text-dark-50"
>
Delete
</button>
</div>
</>
</div>
);
}

View File

@@ -52,7 +52,7 @@ export function NewLabelForm({ cardPublicId }: cardPublicId) {
});
return (
<>
<div className="p-5">
<div className="flex w-full items-center justify-between pb-4 text-neutral-900 dark:text-dark-1000">
<h2 className="text-sm font-medium">New label</h2>
<button
@@ -158,6 +158,6 @@ export function NewLabelForm({ cardPublicId }: cardPublicId) {
</div>
</Form>
</Formik>
</>
</div>
);
}