Index: frontend/src/App.jsx
===================================================================
--- frontend/src/App.jsx	(revision 8449b9cc520ba82bb2945db031d4b9973a038e59)
+++ frontend/src/App.jsx	(revision 4f85b41e4eaa6d668912791fb3cff6efbe7dc1a4)
@@ -19,4 +19,5 @@
 import NewInvestment from "./pages/Dashboard/pages/Investing/NewInvestment.jsx";
 import Discipline from "./pages/Dashboard/pages/Discipline/Discipline.jsx";
+import DisciplineTracking from "./pages/Dashboard/pages/Discipline/DisciplineTracking.jsx";
 
 function RequireAuth({ children }) {
@@ -59,4 +60,5 @@
           <Route path="investing/assets/new" element={<NewInvestment />} />
           <Route path="discipline" element={<Discipline />} />
+           <Route path="discipline/tracking" element={<DisciplineTracking />} />
         </Route>
         <Route path="*" element={<Navigate to="/" replace />} />
Index: frontend/src/api/dailyCompletion.js
===================================================================
--- frontend/src/api/dailyCompletion.js	(revision 4f85b41e4eaa6d668912791fb3cff6efbe7dc1a4)
+++ frontend/src/api/dailyCompletion.js	(revision 4f85b41e4eaa6d668912791fb3cff6efbe7dc1a4)
@@ -0,0 +1,16 @@
+import api from "./axios";
+
+export async function computeDailyCompletion(date /* yyyy-mm-dd or undefined */) {
+  const res = await api.post("/discipline/daily-completions/compute", null, {
+    params: date ? { date } : {},
+  });
+  return res?.data;
+}
+
+export async function getDailyCompletions({ page = 0, size = 14 } = {}) {
+  const res = await api.get("/discipline/daily-completions", {
+    params: { page, size },
+  });
+  return res?.data;
+}
+
Index: frontend/src/api/discipline.js
===================================================================
--- frontend/src/api/discipline.js	(revision 4f85b41e4eaa6d668912791fb3cff6efbe7dc1a4)
+++ frontend/src/api/discipline.js	(revision 4f85b41e4eaa6d668912791fb3cff6efbe7dc1a4)
@@ -0,0 +1,37 @@
+import api from "./axios";
+
+export async function getDisciplineStatus() {
+  const res = await api.get("/discipline/status");
+  return Boolean(res?.data?.tracking);
+}
+
+export async function startDisciplineTracking() {
+  return api.post("/discipline/start", {});
+}
+
+export async function getTasks({ page = 0, size = 50 } = {}) {
+  const res = await api.get("/discipline/tasks", { params: { page, size } });
+  return res?.data;
+}
+
+export async function createTask(payload) {
+  const res = await api.post("/discipline/tasks", payload);
+  return res?.data;
+}
+
+export async function updateTask(taskId, payload) {
+  const res = await api.put(`/discipline/tasks/${taskId}`, payload);
+  return res?.data;
+}
+
+export async function updateTaskFinished(taskId, isFinished) {
+  const res = await api.patch(`/discipline/tasks/${taskId}/finished`, {
+    isFinished,
+  });
+  return res?.data;
+}
+
+export async function deleteTask(taskId) {
+  return api.delete(`/discipline/tasks/${taskId}`);
+}
+
Index: frontend/src/pages/Dashboard/pages/Discipline/Discipline.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Discipline/Discipline.jsx	(revision 8449b9cc520ba82bb2945db031d4b9973a038e59)
+++ frontend/src/pages/Dashboard/pages/Discipline/Discipline.jsx	(revision 4f85b41e4eaa6d668912791fb3cff6efbe7dc1a4)
@@ -1,16 +1,85 @@
-import React from "react";
+import React, { useEffect, useState } from "react";
+import { useNavigate } from "react-router-dom";
 
-const Discipline = () => {
+import {
+  getDisciplineStatus,
+  startDisciplineTracking,
+} from "../../../../api/discipline";
+
+import DisciplineCenteredCard from "./components/DisciplineCenteredCard.jsx";
+import DisciplineStartCtaCard from "./components/DisciplineStartCtaCard.jsx";
+
+export default function Discipline() {
+  const navigate = useNavigate();
+
+  const [isLoading, setIsLoading] = useState(true);
+  const [isTracking, setIsTracking] = useState(false);
+  const [error, setError] = useState("");
+  const [isSubmitting, setIsSubmitting] = useState(false);
+
+  useEffect(() => {
+    let isMounted = true;
+    const run = async () => {
+      setIsLoading(true);
+      setError("");
+      try {
+        const tracking = await getDisciplineStatus();
+        if (!isMounted) return;
+        setIsTracking(tracking);
+        if (tracking) {
+          navigate("/dashboard/discipline/tracking", { replace: true });
+        }
+      } catch (err) {
+        if (!isMounted) return;
+        const message =
+          err?.response?.data?.message || "Failed to load discipline status";
+        setError(message);
+      } finally {
+        if (isMounted) setIsLoading(false);
+      }
+    };
+
+    run();
+    return () => {
+      isMounted = false;
+    };
+  }, [navigate]);
+
+  const onStart = async () => {
+    setError("");
+    setIsSubmitting(true);
+    try {
+      await startDisciplineTracking();
+      setIsTracking(true);
+      navigate("/dashboard/discipline/tracking", { replace: true });
+    } catch (err) {
+      const message =
+        err?.response?.data?.message ||
+        Object.values(err?.response?.data?.errors ?? {})[0] ||
+        "Failed to start tracking";
+      setError(message);
+    } finally {
+      setIsSubmitting(false);
+    }
+  };
+
+  if (isLoading) {
+    return <DisciplineCenteredCard title="Discipline" message="Loading…" />;
+  }
+
+  if (isTracking) {
+    return <DisciplineCenteredCard title="Discipline" message="Redirecting…" />;
+  }
+
   return (
-    <div className="space-y-4">
-      <h1 className="text-2xl font-bold">Discipline</h1>
-      <div className="card bg-base-200 border border-base-300">
-        <div className="card-body">
-          <p className="opacity-80">Discipline dashboard content goes here.</p>
-        </div>
+    <div className="min-h-[70vh] w-full flex items-center justify-center">
+      <div className="w-full max-w-3xl">
+        <DisciplineStartCtaCard
+          error={error}
+          onStart={onStart}
+          isSubmitting={isSubmitting}
+        />
       </div>
     </div>
   );
-};
-
-export default Discipline;
+}
Index: frontend/src/pages/Dashboard/pages/Discipline/DisciplineTracking.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Discipline/DisciplineTracking.jsx	(revision 4f85b41e4eaa6d668912791fb3cff6efbe7dc1a4)
+++ frontend/src/pages/Dashboard/pages/Discipline/DisciplineTracking.jsx	(revision 4f85b41e4eaa6d668912791fb3cff6efbe7dc1a4)
@@ -0,0 +1,397 @@
+import React, { useCallback, useEffect, useMemo, useState } from "react";
+import graphPlaceholder from "../../../../assets/graph-placeholder.svg";
+
+import {
+  createTask,
+  deleteTask,
+  getTasks,
+  updateTask,
+  updateTaskFinished,
+} from "../../../../api/discipline";
+
+import {
+  computeDailyCompletion,
+  getDailyCompletions,
+} from "../../../../api/dailyCompletion";
+
+import TaskList from "./components/TaskList.jsx";
+
+export default function DisciplineTracking() {
+  const pageSize = 50;
+  const completionPageSize = 14;
+
+  const todayIso = useMemo(() => {
+    const d = new Date();
+    return d.toISOString().slice(0, 10);
+  }, []);
+
+  const [tasks, setTasks] = useState([]);
+  const [page, setPage] = useState(0);
+  const [hasMore, setHasMore] = useState(false);
+  const [isLoading, setIsLoading] = useState(true);
+  const [isLoadingMore, setIsLoadingMore] = useState(false);
+  const [error, setError] = useState("");
+  const [completionInfo, setCompletionInfo] = useState(null);
+  const [isComputing, setIsComputing] = useState(false);
+  const [workingTaskIds, setWorkingTaskIds] = useState([]);
+
+  const [dailyCompletions, setDailyCompletions] = useState([]);
+  const [completionPage, setCompletionPage] = useState(0);
+  const [completionHasMore, setCompletionHasMore] = useState(false);
+  const [isLoadingCompletions, setIsLoadingCompletions] = useState(true);
+  const [isLoadingMoreCompletions, setIsLoadingMoreCompletions] = useState(false);
+  const [completionError, setCompletionError] = useState("");
+
+  const workingSet = useMemo(
+    () => new Set(workingTaskIds),
+    [workingTaskIds],
+  );
+
+  const fetchPage = useCallback(async (nextPage) => {
+    const data = await getTasks({ page: nextPage, size: pageSize });
+    return {
+      nextTasks: Array.isArray(data?.tasks) ? data.tasks : [],
+      nextHasMore: Boolean(data?.hasMore),
+    };
+  }, []);
+
+  const fetchCompletionsPage = useCallback(async (nextPage) => {
+    const data = await getDailyCompletions({
+      page: nextPage,
+      size: completionPageSize,
+    });
+    return {
+      nextCompletions: Array.isArray(data?.completions) ? data.completions : [],
+      nextHasMore: Boolean(data?.hasMore),
+    };
+  }, []);
+
+  useEffect(() => {
+    let cancelled = false;
+    (async () => {
+      try {
+        setIsLoading(true);
+        setError("");
+        const { nextTasks, nextHasMore } = await fetchPage(0);
+        if (cancelled) return;
+        setTasks(nextTasks);
+        setHasMore(nextHasMore);
+        setPage(0);
+      } catch (e) {
+        if (cancelled) return;
+        setError(e?.response?.data?.message || "Failed to load tasks.");
+      } finally {
+        if (!cancelled) setIsLoading(false);
+      }
+    })();
+    return () => {
+      cancelled = true;
+    };
+  }, [fetchPage]);
+
+  useEffect(() => {
+    let cancelled = false;
+    (async () => {
+      try {
+        setIsLoadingCompletions(true);
+        setCompletionError("");
+        const { nextCompletions, nextHasMore } = await fetchCompletionsPage(0);
+        if (cancelled) return;
+        setDailyCompletions(nextCompletions);
+        setCompletionHasMore(nextHasMore);
+        setCompletionPage(0);
+      } catch (e) {
+        if (cancelled) return;
+        setCompletionError(
+          e?.response?.data?.message ||
+            "Failed to load daily completion history.",
+        );
+      } finally {
+        if (!cancelled) setIsLoadingCompletions(false);
+      }
+    })();
+
+    return () => {
+      cancelled = true;
+    };
+  }, [fetchCompletionsPage]);
+
+  const onLoadMoreCompletions = async () => {
+    if (isLoadingMoreCompletions || !completionHasMore) return;
+    const nextPage = completionPage + 1;
+    try {
+      setIsLoadingMoreCompletions(true);
+      setCompletionError("");
+      const { nextCompletions, nextHasMore } =
+        await fetchCompletionsPage(nextPage);
+      setDailyCompletions((prev) => [...prev, ...nextCompletions]);
+      setCompletionHasMore(nextHasMore);
+      setCompletionPage(nextPage);
+    } catch (e) {
+      setCompletionError(
+        e?.response?.data?.message || "Failed to load more completions.",
+      );
+    } finally {
+      setIsLoadingMoreCompletions(false);
+    }
+  };
+
+  const onLoadMore = async () => {
+    if (isLoadingMore || !hasMore) return;
+    const nextPage = page + 1;
+    try {
+      setIsLoadingMore(true);
+      setError("");
+      const { nextTasks, nextHasMore } = await fetchPage(nextPage);
+      setTasks((prev) => [...prev, ...nextTasks]);
+      setHasMore(nextHasMore);
+      setPage(nextPage);
+    } catch (e) {
+      setError(e?.response?.data?.message || "Failed to load more tasks.");
+    } finally {
+      setIsLoadingMore(false);
+    }
+  };
+
+  const withWorking = async (taskId, fn) => {
+    setWorkingTaskIds((prev) => [...prev, taskId]);
+    try {
+      await fn();
+    } finally {
+      setWorkingTaskIds((prev) => prev.filter((id) => id !== taskId));
+    }
+  };
+
+  const onAdd = async (name) => {
+    setError("");
+    try {
+      const created = await createTask({ name });
+      setTasks((prev) => [created, ...prev]);
+    } catch (e) {
+      setError(e?.response?.data?.message || "Failed to create task.");
+    }
+  };
+
+  const onDelete = async (taskId) => {
+    setError("");
+    await withWorking(taskId, async () => {
+      try {
+        await deleteTask(taskId);
+        setTasks((prev) => prev.filter((t) => t.taskId !== taskId));
+      } catch (e) {
+        setError(e?.response?.data?.message || "Failed to delete task.");
+      }
+    });
+  };
+
+  const onToggleFinished = async (taskId, isFinished) => {
+    if (workingSet.has(taskId)) return;
+    setError("");
+
+    // optimistic update
+    setTasks((prev) =>
+      prev.map((t) => (t.taskId === taskId ? { ...t, isFinished } : t)),
+    );
+
+    await withWorking(taskId, async () => {
+      try {
+        const updated = await updateTaskFinished(taskId, isFinished);
+        setTasks((prev) =>
+          prev.map((t) => (t.taskId === taskId ? updated : t)),
+        );
+      } catch (e) {
+        // revert
+        setTasks((prev) =>
+          prev.map((t) =>
+            t.taskId === taskId ? { ...t, isFinished: !isFinished } : t,
+          ),
+        );
+        setError(e?.response?.data?.message || "Failed to update task.");
+      }
+    });
+  };
+
+  const onRename = async (taskId, name) => {
+    setError("");
+    await withWorking(taskId, async () => {
+      try {
+        const updated = await updateTask(taskId, { name });
+        setTasks((prev) =>
+          prev.map((t) => (t.taskId === taskId ? updated : t)),
+        );
+      } catch (e) {
+        setError(e?.response?.data?.message || "Failed to update task.");
+      }
+    });
+  };
+
+  const onComputeToday = async () => {
+    setError("");
+    setCompletionInfo(null);
+    setIsComputing(true);
+    try {
+      const result = await computeDailyCompletion();
+      setCompletionInfo(result?.completion ?? null);
+
+      // refresh daily completion history
+      try {
+        const { nextCompletions, nextHasMore } = await fetchCompletionsPage(0);
+        setDailyCompletions(nextCompletions);
+        setCompletionHasMore(nextHasMore);
+        setCompletionPage(0);
+      } catch {
+        // ignore
+      }
+
+      // refresh tasks as backend will reset finished -> false
+      const { nextTasks, nextHasMore } = await fetchPage(0);
+      setTasks(nextTasks);
+      setHasMore(nextHasMore);
+      setPage(0);
+    } catch (e) {
+      setError(
+        e?.response?.data?.message || "Failed to compute daily completion.",
+      );
+    } finally {
+      setIsComputing(false);
+    }
+  };
+
+  const isTodayClosed = useMemo(() => {
+    return (dailyCompletions ?? []).some((dc) => dc?.date === todayIso);
+  }, [dailyCompletions, todayIso]);
+
+  return (
+    <div className="space-y-6">
+      <div className="flex items-center justify-between gap-3">
+        <h1 className="text-2xl font-bold">Discipline</h1>
+        <button
+          className="btn btn-primary btn-sm"
+          onClick={onComputeToday}
+          disabled={isComputing || isTodayClosed}
+          title="Compute today's completion and reset tasks for the next day"
+        >
+          {isTodayClosed ? "Day closed" : isComputing ? "Computing…" : "Close day"}
+        </button>
+      </div>
+
+      {completionInfo ? (
+        <div className="card bg-base-200 border border-base-300">
+          <div className="card-body">
+            <h2 className="card-title">Daily completion saved</h2>
+            <p className="text-sm opacity-80">
+              Date: {completionInfo.date} — Completion: {completionInfo.procent}%
+            </p>
+          </div>
+        </div>
+      ) : null}
+
+      {isLoading ? (
+        <div className="card bg-base-200 border border-base-300">
+          <div className="card-body">
+            <p className="opacity-80">Loading tasks…</p>
+          </div>
+        </div>
+      ) : (
+        <>
+          <TaskList
+            tasks={tasks}
+            onAdd={onAdd}
+            onDelete={onDelete}
+            onToggleFinished={onToggleFinished}
+            onRename={onRename}
+            isWorkingTaskIds={workingTaskIds}
+          />
+
+          {error ? <p className="text-error text-sm">{error}</p> : null}
+
+          {hasMore ? (
+            <button
+              className="btn btn-outline btn-sm"
+              disabled={isLoadingMore}
+              onClick={onLoadMore}
+            >
+              {isLoadingMore ? "Loading…" : "Load more"}
+            </button>
+          ) : null}
+
+          <div className="card bg-base-200 border border-base-300">
+            <div className="card-body">
+              <h2 className="card-title">Progress</h2>
+              <p className="text-sm opacity-80">(Placeholder graph for now)</p>
+              <div className="mt-4">
+                <img
+                  src={graphPlaceholder}
+                  alt="Discipline graph placeholder"
+                  className="w-full"
+                />
+              </div>
+            </div>
+          </div>
+
+          <div className="card bg-base-200 border border-base-300">
+            <div className="card-body">
+              <h2 className="card-title">Daily completion</h2>
+              <p className="text-sm opacity-80">
+                Previous days completion percentages.
+              </p>
+
+              {completionError ? (
+                <p className="text-error text-sm mt-2">{completionError}</p>
+              ) : null}
+
+              <div className="mt-4 overflow-x-auto">
+                <table className="table table-zebra">
+                  <thead>
+                    <tr>
+                      <th>Date</th>
+                      <th className="text-right">Completion</th>
+                    </tr>
+                  </thead>
+                  <tbody>
+                    {isLoadingCompletions ? (
+                      <tr>
+                        <td colSpan={2} className="opacity-70">
+                          Loading…
+                        </td>
+                      </tr>
+                    ) : (dailyCompletions ?? []).length === 0 ? (
+                      <tr>
+                        <td colSpan={2} className="opacity-70">
+                          No daily completion records yet. Click “Close day” to
+                          save today.
+                        </td>
+                      </tr>
+                    ) : (
+                      (dailyCompletions ?? []).map((dc) => (
+                        <tr key={dc.dailyCompletionId}>
+                          <td>{dc.date ?? "—"}</td>
+                          <td className="text-right tabular-nums">
+                            {dc.procent ?? 0}%
+                          </td>
+                        </tr>
+                      ))
+                    )}
+                  </tbody>
+                </table>
+              </div>
+
+              <div className="mt-4">
+                {completionHasMore ? (
+                  <button
+                    className="btn btn-outline btn-sm"
+                    disabled={isLoadingMoreCompletions}
+                    onClick={onLoadMoreCompletions}
+                  >
+                    {isLoadingMoreCompletions ? "Loading…" : "Load more"}
+                  </button>
+                ) : null}
+              </div>
+            </div>
+          </div>
+        </>
+      )}
+    </div>
+  );
+}
+
Index: frontend/src/pages/Dashboard/pages/Discipline/components/DisciplineCenteredCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Discipline/components/DisciplineCenteredCard.jsx	(revision 4f85b41e4eaa6d668912791fb3cff6efbe7dc1a4)
+++ frontend/src/pages/Dashboard/pages/Discipline/components/DisciplineCenteredCard.jsx	(revision 4f85b41e4eaa6d668912791fb3cff6efbe7dc1a4)
@@ -0,0 +1,17 @@
+import React from "react";
+
+export default function DisciplineCenteredCard({ title, message }) {
+  return (
+    <div className="min-h-[70vh] w-full flex items-center justify-center">
+      <div className="w-full max-w-3xl">
+        <div className="card bg-base-200 border border-base-300">
+          <div className="card-body">
+            <h1 className="card-title text-2xl">{title}</h1>
+            <p className="opacity-80">{message}</p>
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+}
+
Index: frontend/src/pages/Dashboard/pages/Discipline/components/DisciplineStartCtaCard.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Discipline/components/DisciplineStartCtaCard.jsx	(revision 4f85b41e4eaa6d668912791fb3cff6efbe7dc1a4)
+++ frontend/src/pages/Dashboard/pages/Discipline/components/DisciplineStartCtaCard.jsx	(revision 4f85b41e4eaa6d668912791fb3cff6efbe7dc1a4)
@@ -0,0 +1,26 @@
+import React from "react";
+
+export default function DisciplineStartCtaCard({ error, onStart, isSubmitting }) {
+  return (
+    <div className="card bg-base-200 border border-base-300">
+      <div className="card-body">
+        <h1 className="card-title text-2xl">Discipline</h1>
+        <p className="opacity-80">
+          Start tracking your daily discipline tasks. You can add, edit, and mark
+          tasks as completed.
+        </p>
+        {error ? <p className="text-error text-sm mt-2">{error}</p> : null}
+        <div className="mt-4">
+          <button
+            className="btn btn-primary"
+            disabled={isSubmitting}
+            onClick={onStart}
+          >
+            {isSubmitting ? "Starting…" : "Start tracking"}
+          </button>
+        </div>
+      </div>
+    </div>
+  );
+}
+
Index: frontend/src/pages/Dashboard/pages/Discipline/components/TaskList.jsx
===================================================================
--- frontend/src/pages/Dashboard/pages/Discipline/components/TaskList.jsx	(revision 4f85b41e4eaa6d668912791fb3cff6efbe7dc1a4)
+++ frontend/src/pages/Dashboard/pages/Discipline/components/TaskList.jsx	(revision 4f85b41e4eaa6d668912791fb3cff6efbe7dc1a4)
@@ -0,0 +1,171 @@
+import React, { useMemo, useState } from "react";
+
+function normalizeName(value) {
+  return String(value ?? "").trim();
+}
+
+export default function TaskList({
+  tasks,
+  onAdd,
+  onDelete,
+  onToggleFinished,
+  onRename,
+  isWorkingTaskIds,
+}) {
+  const [newTaskName, setNewTaskName] = useState("");
+  const [editTaskId, setEditTaskId] = useState(null);
+  const [editName, setEditName] = useState("");
+
+  const workingSet = useMemo(
+    () => new Set(isWorkingTaskIds ?? []),
+    [isWorkingTaskIds],
+  );
+
+  const beginEdit = (t) => {
+    setEditTaskId(t.taskId);
+    setEditName(t.name ?? "");
+  };
+
+  const cancelEdit = () => {
+    setEditTaskId(null);
+    setEditName("");
+  };
+
+  const submitRename = async () => {
+    const name = normalizeName(editName);
+    if (!name) return;
+    await onRename(editTaskId, name);
+    cancelEdit();
+  };
+
+  return (
+    <div className="card bg-base-200 border border-base-300">
+      <div className="card-body">
+        <div className="flex items-center justify-between gap-3 flex-wrap">
+          <div>
+            <h2 className="card-title">Daily tasks</h2>
+            <p className="text-sm opacity-80">
+              Check a task to mark it finished. Changes are saved immediately.
+            </p>
+          </div>
+        </div>
+
+        <form
+          className="mt-4 flex gap-2"
+          onSubmit={(e) => {
+            e.preventDefault();
+            const name = normalizeName(newTaskName);
+            if (!name) return;
+            onAdd(name);
+            setNewTaskName("");
+          }}
+        >
+          <input
+            className="input input-bordered w-full"
+            placeholder="New task name…"
+            value={newTaskName}
+            onChange={(e) => setNewTaskName(e.target.value)}
+            maxLength={200}
+          />
+          <button className="btn btn-primary" type="submit">
+            Add
+          </button>
+        </form>
+
+        <div className="mt-4 space-y-2">
+          {(tasks ?? []).length === 0 ? (
+            <p className="opacity-70">No tasks yet.</p>
+          ) : (
+            (tasks ?? []).map((t) => {
+              const isWorking = workingSet.has(t.taskId);
+              const isEditing = editTaskId === t.taskId;
+
+              return (
+                <div
+                  key={t.taskId}
+                  className="flex items-center justify-between gap-3 rounded-lg border border-base-300 bg-base-100 px-3 py-2"
+                >
+                  <div className="flex items-center gap-3 w-full">
+                    <input
+                      type="checkbox"
+                      className="checkbox checkbox-success"
+                      checked={Boolean(t.isFinished)}
+                      disabled={isWorking}
+                      onChange={(e) =>
+                        onToggleFinished(t.taskId, e.target.checked)
+                      }
+                    />
+
+                    {isEditing ? (
+                      <input
+                        className="input input-bordered input-sm w-full"
+                        value={editName}
+                        onChange={(e) => setEditName(e.target.value)}
+                        maxLength={200}
+                      />
+                    ) : (
+                      <div className="w-full">
+                        <div
+                          className={
+                            t.isFinished
+                              ? "line-through opacity-70"
+                              : "font-medium"
+                          }
+                        >
+                          {t.name}
+                        </div>
+                      </div>
+                    )}
+                  </div>
+
+                  <div className="flex items-center gap-2">
+                    {isEditing ? (
+                      <>
+                        <button
+                          className="btn btn-primary btn-xs"
+                          type="button"
+                          disabled={isWorking}
+                          onClick={submitRename}
+                        >
+                          Save
+                        </button>
+                        <button
+                          className="btn btn-ghost btn-xs"
+                          type="button"
+                          disabled={isWorking}
+                          onClick={cancelEdit}
+                        >
+                          Cancel
+                        </button>
+                      </>
+                    ) : (
+                      <>
+                        <button
+                          className="btn btn-outline btn-xs"
+                          type="button"
+                          disabled={isWorking}
+                          onClick={() => beginEdit(t)}
+                        >
+                          Edit
+                        </button>
+                        <button
+                          className="btn btn-error btn-xs"
+                          type="button"
+                          disabled={isWorking}
+                          onClick={() => onDelete(t.taskId)}
+                        >
+                          Delete
+                        </button>
+                      </>
+                    )}
+                  </div>
+                </div>
+              );
+            })
+          )}
+        </div>
+      </div>
+    </div>
+  );
+}
+
