No attendance records yet.
+ ) : ( +| Date | +Status | +Check-in | +Office | +Reason | +
|---|---|---|---|---|
| {rec.workDate.toISOString().slice(0, 10)} | ++ + {badge.label} + + | +{rec.checkInTime.toISOString().slice(11, 16)} | +{rec.office?.name ?? "—"} | +{rec.reason ?? "—"} | +
Placeholder for migrated Gantt view.
++ Welcome back, {profile.fullName ?? profile.email} +
+ + {/* Stats */} +No tasks assigned yet.
+ ) : ( +{task.title}
++ {task.project.name} · {task.project.code} +
++ {label} +
+{value}
+Project list route migrated from React Router to Next.js page routing.
+ + Open sample project route + ++ {tasks.length} task{tasks.length !== 1 ? "s" : ""} awaiting review +
+Role-protected route with Clerk role metadata validation.
+You do not have permission to access this route.
+{createError}
+ )} + + {/* Board */} ++ No tasks +
+ )} ++ {task.title} +
+ {task.description && ( ++ {task.description} +
+ )} ++ {task.revisionCount} revision{task.revisionCount !== 1 ? "s" : ""} +
+ )} ++ {error} +
+ )} ++ {label} +
++ No tasks in queue. +
+ ); + } + + const handleReview = async (taskId: string, outcome: string) => { + if (outcome === "rejected" && !comment.trim()) { + setError("Comment required for rejection"); + return; + } + setReviewing(taskId); + setError(null); + try { + const res = await fetch(`/api/jcc/tasks/${taskId}/review`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ outcome, comment: comment.trim() || undefined }) + }); + const json = await res.json() as { error?: string }; + if (!res.ok) { + setError(json.error ?? "Review failed"); + return; + } + setTasks((prev) => prev.filter((t) => t.id !== taskId)); + setSelected(null); + setComment(""); + } catch { + setError("Network error"); + } finally { + setReviewing(null); + } + }; + + return ( ++ {error} +
+ )} + + {tasks.map((task) => ( +{task.title}
++ {task.project.name} ({task.project.code}) ·{" "} + {task.assignee + ? (task.assignee.fullName ?? task.assignee.email) + : "Unassigned"}{" "} + ·{" "} + {task.submittedAt + ? `Submitted ${new Date(task.submittedAt).toLocaleDateString()}` + : "Unknown date"} +
+ {task.revisionCount > 0 && ( ++ {task.revisionCount} revision{task.revisionCount !== 1 ? "s" : ""} +
+ )} +