From 1a8bed2d4f3d8728e15b5ffeba0f450d6dc9345c Mon Sep 17 00:00:00 2001 From: Chneemann Date: Thu, 27 Aug 2026 09:40:11 +0200 Subject: [PATCH] refactor(ui,tasks): enhance ActionButton to support submit/disabled states and expose isSubmitting --- app/(app)/tasks/TaskForm.tsx | 15 ++++++++++-- app/(app)/tasks/useTaskForm.ts | 3 ++- app/components/ui/buttons/ActionButton.tsx | 27 +++++++++++++++++++++- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/app/(app)/tasks/TaskForm.tsx b/app/(app)/tasks/TaskForm.tsx index 55f2861..64bf98a 100644 --- a/app/(app)/tasks/TaskForm.tsx +++ b/app/(app)/tasks/TaskForm.tsx @@ -50,6 +50,7 @@ export default function TaskForm({ form, error, isEditMode, + isSubmitting, todayString, updateField, handleAssigneeToggle, @@ -95,10 +96,20 @@ export default function TaskForm({
- + Cancel - + {isEditMode ? "Save Changes" : "Create Task"}
diff --git a/app/(app)/tasks/useTaskForm.ts b/app/(app)/tasks/useTaskForm.ts index 8c2ccfd..7cc8452 100644 --- a/app/(app)/tasks/useTaskForm.ts +++ b/app/(app)/tasks/useTaskForm.ts @@ -23,7 +23,7 @@ export function useTaskForm( defaultStatus?: TaskStatus, ) { const router = useRouter(); - const [, startTransition] = useTransition(); + const [isPending, startTransition] = useTransition(); const isEditMode = mode === "edit" && initialData; const todayString = new Date().toISOString().split("T")[0]; @@ -121,6 +121,7 @@ export function useTaskForm( form, error, isEditMode, + isSubmitting: isPending, todayString, updateField, handleAssigneeToggle, diff --git a/app/components/ui/buttons/ActionButton.tsx b/app/components/ui/buttons/ActionButton.tsx index ca35e74..110a471 100644 --- a/app/components/ui/buttons/ActionButton.tsx +++ b/app/components/ui/buttons/ActionButton.tsx @@ -7,6 +7,16 @@ import Link from "next/link"; import { ReactNode, ButtonHTMLAttributes } from "react"; import { LucideIcon } from "lucide-react"; +/** + * Properties for the ActionButton component. + * + * @interface ActionButtonProps + * @extends {ButtonHTMLAttributes} + * @property {string} [href] - Optional navigation target URL. Renders a Next.js Link component if defined. + * @property {"primary" | "secondary" | "danger"} [variant="primary"] - Visual style variant of the button. + * @property {ReactNode} children - Button label content or child nodes. + * @property {LucideIcon} [icon] - Optional Lucide icon component to display alongside the text label. + */ interface ActionButtonProps extends ButtonHTMLAttributes { href?: string; variant?: "primary" | "secondary" | "danger"; @@ -14,6 +24,12 @@ interface ActionButtonProps extends ButtonHTMLAttributes { icon?: LucideIcon; } +/** + * Renders a customizable button or link element styled with Tailwind CSS, supporting variants, icons, and disabled states. + * + * @param {ActionButtonProps} props - The component props. + * @returns {JSX.Element} The rendered button or link component. + */ export function ActionButton({ href, variant = "primary", @@ -50,7 +66,16 @@ export function ActionButton({ // If an href is passed -> Link button if (href) { return ( - + { + if (disabled) e.preventDefault(); + }} + className={`${combinedStyles} ${ + disabled ? "pointer-events-none opacity-50" : "" + }`} + > {content} );