diff --git a/app/(app)/dashboard/card/Card.tsx b/app/(app)/dashboard/card/Card.tsx
index d16893c..fef9079 100644
--- a/app/(app)/dashboard/card/Card.tsx
+++ b/app/(app)/dashboard/card/Card.tsx
@@ -11,6 +11,8 @@ import CardActions from "./CardActions";
import CardAvatars from "./CardAvatars";
import CardDueDate from "./CardDueDate";
import CardPriority from "./CardPriority";
+import HighlightText from "@/app/components/ui/HighlightText";
+import { useSearchParams } from "next/navigation";
/**
* Properties for the Card component.
@@ -29,8 +31,8 @@ export interface CardProps {
}
/**
- * Renders an interactive card container handling drag-and-drop actions, loading states,
- * and assembling modular sub-components for priorities, due dates, avatars, and actions.
+ * Renders an interactive card container supporting search match highlighting, drag-and-drop actions,
+ * loading states, and modular sub-components for priorities, due dates, avatars, and actions.
*
* @param {CardProps} props - The component props containing the task object, updating status flag, and status change handler.
* @returns {JSX.Element} The rendered card component.
@@ -41,6 +43,9 @@ export default function Card({
onStatusChange,
onDelete,
}: CardProps) {
+ const searchParams = useSearchParams();
+ const searchQuery = searchParams.get("search") || "";
+
/**
* Initiates the drag action on a task card if not currently updating, storing its ID and status payload.
*
@@ -87,14 +92,14 @@ export default function Card({
{/* --- Card Header --- */}
- {task.title}
+
{/* Card Description */}
- {task.description}
+
{/* --- Card Footer --- */}
diff --git a/app/(app)/trash/TrashList.tsx b/app/(app)/trash/TrashList.tsx
index 630f928..9bf00b1 100644
--- a/app/(app)/trash/TrashList.tsx
+++ b/app/(app)/trash/TrashList.tsx
@@ -8,16 +8,21 @@
import { Task, PRIORITY_CONFIG } from "@/types/task";
import { Calendar } from "lucide-react";
import TaskActionButton from "./components/TaskActionButton";
+import HighlightText from "@/app/components/ui/HighlightText";
+import { useSearchParams } from "next/navigation";
/**
- * Renders a list of deleted tasks stored in the trash, featuring priority badges,
- * deletion dates, and action controls for permanent deletion or restoration.
+ * Renders a list of deleted tasks stored in the trash with search term highlighting,
+ * featuring priority badges, deletion dates, and action controls for permanent deletion or restoration.
*
* @param {Object} props - The component props.
* @param {Task[]} props.tasks - The array of deleted tasks to render.
* @returns {JSX.Element} The rendered trash list component or an empty state placeholder.
*/
export default function TrashList({ tasks }: { tasks: Task[] }) {
+ const searchParams = useSearchParams();
+ const searchQuery = searchParams.get("search") || "";
+
return (
{tasks.length === 0 ? (
@@ -54,7 +59,7 @@ export default function TrashList({ tasks }: { tasks: Task[] }) {
- {task.title}
+
- {task.description}
+
)}
diff --git a/app/components/ui/HighlightText.tsx b/app/components/ui/HighlightText.tsx
new file mode 100644
index 0000000..bb96972
--- /dev/null
+++ b/app/components/ui/HighlightText.tsx
@@ -0,0 +1,56 @@
+/**
+ * @file components/ui/HighlightText.tsx
+ * @description Component to highlight matching search query terms within a text string.
+ */
+
+/**
+ * Properties for the HighlightText component.
+ *
+ * @interface HighlightTextProps
+ * @property {string | null} [text] - The full text string to render and search within.
+ * @property {string} [query] - The search query term to highlight within the text.
+ * @property {string} [className] - Optional CSS classes applied to the wrapping container element.
+ */
+interface HighlightTextProps {
+ text?: string | null;
+ query?: string;
+ className?: string;
+}
+
+/**
+ * Renders a text string with case-insensitive highlighted search query matches wrapped in a marked element.
+ *
+ * @param {HighlightTextProps} props - The component props.
+ * @returns {JSX.Element | null} The rendered text component with highlighted query terms, or null if no text is provided.
+ */
+export default function HighlightText({
+ text,
+ query,
+ className = "",
+}: HighlightTextProps) {
+ if (!text) return null;
+ if (!query || !query.trim()) {
+ return {text};
+ }
+
+ // Regular expression with escaping for special characters, case-insensitive ('gi')
+ const escapedQuery = query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
+ const parts = text.split(new RegExp(`(${escapedQuery})`, "gi"));
+
+ return (
+
+ {parts.map((part, index) =>
+ part.toLowerCase() === query.toLowerCase() ? (
+
+ {part}
+
+ ) : (
+ part
+ ),
+ )}
+
+ );
+}