diff --git a/app/(app)/tasks/TaskForm.tsx b/app/(app)/tasks/TaskForm.tsx
index ea76753..55f2861 100644
--- a/app/(app)/tasks/TaskForm.tsx
+++ b/app/(app)/tasks/TaskForm.tsx
@@ -5,7 +5,7 @@
"use client";
-import { AlertCircle, X } from "lucide-react";
+import { AlertCircle, Check, X } from "lucide-react";
import { DbTask, TaskStatus } from "@/lib/types/task";
import { useTaskForm } from "./useTaskForm";
import TaskHeader from "./task/TaskHeader";
@@ -98,12 +98,9 @@ export default function TaskForm({
Cancel
-
+
);
diff --git a/app/components/ui/buttons/ActionButton.tsx b/app/components/ui/buttons/ActionButton.tsx
index ba18fc3..ca35e74 100644
--- a/app/components/ui/buttons/ActionButton.tsx
+++ b/app/components/ui/buttons/ActionButton.tsx
@@ -4,39 +4,28 @@
*/
import Link from "next/link";
-import { ReactNode } from "react";
+import { ReactNode, ButtonHTMLAttributes } from "react";
import { LucideIcon } from "lucide-react";
-/**
- * Properties for the ActionButton component.
- *
- * @interface ActionButtonProps
- * @property {string} href - The target URL path or external link.
- * @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 text.
- */
-interface ActionButtonProps {
- href: string;
+interface ActionButtonProps extends ButtonHTMLAttributes {
+ href?: string;
variant?: "primary" | "secondary" | "danger";
children: ReactNode;
icon?: LucideIcon;
}
-/**
- * Renders an accessible link styled as an action button with hover states and optional icons.
- *
- * @param {ActionButtonProps} props - The component props.
- * @returns {JSX.Element} The rendered action button link component.
- */
export function ActionButton({
href,
variant = "primary",
children,
icon: Icon,
+ type = "button",
+ disabled,
+ className = "",
+ ...props
}: ActionButtonProps) {
const baseStyles =
- "group w-full sm:w-auto inline-flex items-center justify-center gap-2.5 font-medium transition-all duration-200 ease-out active:scale-[0.97] px-4 py-2.5 rounded-xl text-sm tracking-wide shadow-xs focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 cursor-pointer";
+ "group w-full sm:w-auto inline-flex items-center justify-center gap-2.5 font-medium transition-all duration-200 ease-out active:scale-[0.97] px-4 py-2.5 rounded-xl text-sm tracking-wide shadow-xs focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 cursor-pointer disabled:opacity-50 disabled:pointer-events-none";
const variants = {
primary:
@@ -44,15 +33,38 @@ export function ActionButton({
secondary:
"bg-card text-foreground border border-foreground-muted/50 hover:bg-background-muted hover:border-foreground hover:-translate-y-0.5",
danger:
- "bg-destructive/15 text-destructive border border-destructive/30 hover:bg-destructive hover:text-foreground hover:border-destructive hover:-translate-y-0.5",
+ "bg-destructive/15 text-destructive border border-destructive/30 hover:bg-destructive hover:text-foreground hover.border-destructive hover:-translate-y-0.5",
};
- return (
-
+ const combinedStyles = `${baseStyles} ${variants[variant]} ${className}`;
+
+ const content = (
+ <>
{Icon && (
)}
{children}
-
+ >
+ );
+
+ // If an href is passed -> Link button
+ if (href) {
+ return (
+
+ {content}
+
+ );
+ }
+
+ // Otherwise, it's a real HTML button
+ return (
+
);
}