diff --git a/apps/web/src/components/bench/BenchResourceCard.tsx b/apps/web/src/components/bench/BenchResourceCard.tsx
index d308a1e..f0b2ae1 100644
--- a/apps/web/src/components/bench/BenchResourceCard.tsx
+++ b/apps/web/src/components/bench/BenchResourceCard.tsx
@@ -1,5 +1,3 @@
-"use client";
-
import Link from "next/link";
interface BenchResourceCardProps {
@@ -29,11 +27,7 @@ export function BenchResourceCard({
.join("");
const availabilityLevel =
- availableHoursPerDay >= 6
- ? "high"
- : availableHoursPerDay >= 3
- ? "medium"
- : "low";
+ availableHoursPerDay >= 6 ? "high" : availableHoursPerDay >= 3 ? "medium" : "low";
const levelClass =
availabilityLevel === "high"
@@ -55,10 +49,14 @@ export function BenchResourceCard({
- {initials}
+
+ {initials}
+
-
{name}
+
+ {name}
+
{eid}
diff --git a/apps/web/src/components/dynamic-fields/DynamicFieldRenderer.tsx b/apps/web/src/components/dynamic-fields/DynamicFieldRenderer.tsx
index 305da95..3e5399b 100644
--- a/apps/web/src/components/dynamic-fields/DynamicFieldRenderer.tsx
+++ b/apps/web/src/components/dynamic-fields/DynamicFieldRenderer.tsx
@@ -1,5 +1,3 @@
-"use client";
-
import { clsx } from "clsx";
import { formatDateLong } from "~/lib/format.js";
import { FieldType } from "@capakraken/shared";
@@ -36,9 +34,7 @@ function renderValue(fieldDef: BlueprintFieldDefinition, value: unknown): React.
{bool ? "Yes" : "No"}
@@ -100,9 +96,7 @@ function FieldRow({ fieldDef, value }: { fieldDef: BlueprintFieldDefinition; val
{fieldDef.label}
{renderValue(fieldDef, value)}
- {fieldDef.description && (
- {fieldDef.description}
- )}
+ {fieldDef.description && {fieldDef.description}
}
);
}
diff --git a/apps/web/src/components/mobile/MobileCapacityCard.tsx b/apps/web/src/components/mobile/MobileCapacityCard.tsx
index 0d594ac..dd274dd 100644
--- a/apps/web/src/components/mobile/MobileCapacityCard.tsx
+++ b/apps/web/src/components/mobile/MobileCapacityCard.tsx
@@ -1,5 +1,3 @@
-"use client";
-
interface MobileCapacityCardProps {
totalResources: number;
activeResources: number;
@@ -16,8 +14,7 @@ export function MobileCapacityCard({
const pct = Math.min(100, Math.max(0, avgUtilizationPct));
const circumference = 2 * Math.PI * 34; // radius = 34
const dashOffset = circumference * (1 - pct / 100);
- const color =
- pct >= 90 ? "#d97706" : pct >= 70 ? "#059669" : "#6b7280";
+ const color = pct >= 90 ? "#d97706" : pct >= 70 ? "#059669" : "#6b7280";
return (
@@ -27,7 +24,15 @@ export function MobileCapacityCard({
{/* CSS-only donut */}
@@ -54,7 +67,9 @@ export function MobileCapacityCard({
{overbookedCount > 0 && (
Overbooked
- {overbookedCount}
+
+ {overbookedCount}
+
)}
diff --git a/apps/web/src/components/mobile/MobileProjectCard.tsx b/apps/web/src/components/mobile/MobileProjectCard.tsx
index f6b57ed..e2b34cd 100644
--- a/apps/web/src/components/mobile/MobileProjectCard.tsx
+++ b/apps/web/src/components/mobile/MobileProjectCard.tsx
@@ -1,11 +1,9 @@
-"use client";
-
import Link from "next/link";
const STATUS_BADGE: Record
= {
- ACTIVE: "bg-emerald-100 text-emerald-800 dark:bg-emerald-900/40 dark:text-emerald-300",
- DRAFT: "bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400",
- ON_HOLD: "bg-amber-100 text-amber-800 dark:bg-amber-900/40 dark:text-amber-300",
+ ACTIVE: "bg-emerald-100 text-emerald-800 dark:bg-emerald-900/40 dark:text-emerald-300",
+ DRAFT: "bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400",
+ ON_HOLD: "bg-amber-100 text-amber-800 dark:bg-amber-900/40 dark:text-amber-300",
COMPLETED: "bg-blue-100 text-blue-800 dark:bg-blue-900/40 dark:text-blue-300",
CANCELLED: "bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-300",
};
@@ -18,20 +16,32 @@ interface MobileProjectCardProps {
allocationsCount?: number;
}
-export function MobileProjectCard({ id, shortCode, name, status, allocationsCount }: MobileProjectCardProps) {
+export function MobileProjectCard({
+ id,
+ shortCode,
+ name,
+ status,
+ allocationsCount,
+}: MobileProjectCardProps) {
return (
- {shortCode}
+
+ {shortCode}
+
{name}
{allocationsCount !== undefined && (
-
{allocationsCount} allocation{allocationsCount !== 1 ? "s" : ""}
+
+ {allocationsCount} allocation{allocationsCount !== 1 ? "s" : ""}
+
)}
-
+
{status.charAt(0) + status.slice(1).toLowerCase().replace("_", " ")}
diff --git a/apps/web/src/components/projects/BudgetStatusBar.tsx b/apps/web/src/components/projects/BudgetStatusBar.tsx
index b614eef..8b3945d 100644
--- a/apps/web/src/components/projects/BudgetStatusBar.tsx
+++ b/apps/web/src/components/projects/BudgetStatusBar.tsx
@@ -1,5 +1,3 @@
-"use client";
-
import { clsx } from "clsx";
import { formatMoney } from "~/lib/format.js";
import { InfoTooltip } from "~/components/ui/InfoTooltip.js";
@@ -55,14 +53,18 @@ export function BudgetStatusBar({
// Cap visual bar segments at 100% total
const cappedConfirmedPercent = Math.min(confirmedPercent, 100);
- const cappedProposedPercent = Math.min(proposedPercent, Math.max(0, 100 - cappedConfirmedPercent));
+ const cappedProposedPercent = Math.min(
+ proposedPercent,
+ Math.max(0, 100 - cappedConfirmedPercent),
+ );
- const highestWarning = warnings.length > 0
- ? warnings.reduce((prev, curr) => {
- const levels: Record = { info: 0, warning: 1, critical: 2 };
- return (levels[curr.level] ?? 0) > (levels[prev.level] ?? 0) ? curr : prev;
- })
- : null;
+ const highestWarning =
+ warnings.length > 0
+ ? warnings.reduce((prev, curr) => {
+ const levels: Record = { info: 0, warning: 1, critical: 2 };
+ return (levels[curr.level] ?? 0) > (levels[prev.level] ?? 0) ? curr : prev;
+ })
+ : null;
return (
@@ -74,12 +76,18 @@ export function BudgetStatusBar({
{/* Confirmed segment */}
{/* Proposed segment */}
@@ -89,8 +97,7 @@ export function BudgetStatusBar({
{formatEur(allocatedCents)}
{" / "}
- {formatEur(budgetCents)}
- {" "}
+ {formatEur(budgetCents)}{" "}
({utilizationPercent.toFixed(1)}%)
@@ -102,12 +109,20 @@ export function BudgetStatusBar({
getWarningBadgeStyle(highestWarning.level),
)}
>
- {highestWarning.level === "critical" ? "⚠" : highestWarning.level === "warning" ? "!" : "i"}
+ {highestWarning.level === "critical"
+ ? "⚠"
+ : highestWarning.level === "warning"
+ ? "!"
+ : "i"}
{warnings.length > 1 ? `${warnings.length} warnings` : "Warning"}
)}
-
- {remainingCents >= 0 ? `${formatEur(remainingCents)} left` : `${formatEur(Math.abs(remainingCents))} over`}
+
+ {remainingCents >= 0
+ ? `${formatEur(remainingCents)} left`
+ : `${formatEur(Math.abs(remainingCents))} over`}
@@ -115,11 +130,21 @@ export function BudgetStatusBar({
{/* Legend */}
-
+
Confirmed {formatEur(confirmedCents)}
-
+
Proposed {formatEur(proposedCents)}
diff --git a/apps/web/src/components/timeline/TimelineHeader.tsx b/apps/web/src/components/timeline/TimelineHeader.tsx
index 02d2097..9f98294 100644
--- a/apps/web/src/components/timeline/TimelineHeader.tsx
+++ b/apps/web/src/components/timeline/TimelineHeader.tsx
@@ -1,5 +1,3 @@
-"use client";
-
import { clsx } from "clsx";
import { MONTHS_SHORT } from "./timelineConstants.js";
@@ -33,7 +31,10 @@ export function TimelineHeader({
className="sticky top-0 z-40 flex bg-white dark:bg-gray-900 border-b border-gray-100 dark:border-gray-800"
style={{ height: HEADER_MONTH_HEIGHT }}
>
-
+
{monthGroups.map((m, i) => (
{showLabel && (
<>
-
+
{zoom === "week"
? `${date.getDate()} ${MONTHS_SHORT[date.getMonth()]}`
: date.getDate()}
{zoom === "day" && (
-
+
{["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"][dow]}
)}