Add database setup script and fix dark mode visibility

- Add scripts/setup-db.ts to programmatically create missing PocketBase
  collections (period_logs, dailyLogs) with proper relation fields
- Fix dark mode visibility across settings, login, calendar, and dashboard
  components by using semantic CSS tokens and dark: variants
- Add db:setup npm script and document usage in AGENTS.md
- Update vitest config to include scripts directory tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-12 21:23:20 +00:00
parent ca35b36efa
commit ce80fb1ede
11 changed files with 547 additions and 67 deletions

View File

@@ -12,21 +12,27 @@ function getStatusColors(status: Decision["status"]): {
} {
switch (status) {
case "REST":
return { background: "bg-red-100 border-red-300", text: "text-red-700" };
return {
background:
"bg-red-100 dark:bg-red-900/50 border-red-300 dark:border-red-700",
text: "text-red-700 dark:text-red-300",
};
case "GENTLE":
case "LIGHT":
case "REDUCED":
return {
background: "bg-yellow-100 border-yellow-300",
text: "text-yellow-700",
background:
"bg-yellow-100 dark:bg-yellow-900/50 border-yellow-300 dark:border-yellow-700",
text: "text-yellow-700 dark:text-yellow-300",
};
case "TRAIN":
return {
background: "bg-green-100 border-green-300",
text: "text-green-700",
background:
"bg-green-100 dark:bg-green-900/50 border-green-300 dark:border-green-700",
text: "text-green-700 dark:text-green-300",
};
default:
return { background: "border", text: "text-gray-600" };
return { background: "border", text: "text-muted-foreground" };
}
}

View File

@@ -14,21 +14,24 @@ interface MiniCalendarProps {
}
const PHASE_COLORS: Record<CyclePhase, string> = {
MENSTRUAL: "bg-blue-100",
FOLLICULAR: "bg-green-100",
OVULATION: "bg-purple-100",
EARLY_LUTEAL: "bg-yellow-100",
LATE_LUTEAL: "bg-red-100",
MENSTRUAL: "bg-blue-100 dark:bg-blue-900/50 text-blue-900 dark:text-blue-100",
FOLLICULAR:
"bg-green-100 dark:bg-green-900/50 text-green-900 dark:text-green-100",
OVULATION:
"bg-purple-100 dark:bg-purple-900/50 text-purple-900 dark:text-purple-100",
EARLY_LUTEAL:
"bg-yellow-100 dark:bg-yellow-900/50 text-yellow-900 dark:text-yellow-100",
LATE_LUTEAL: "bg-red-100 dark:bg-red-900/50 text-red-900 dark:text-red-100",
};
const COMPACT_DAY_NAMES = ["S", "M", "T", "W", "T", "F", "S"];
const PHASE_LEGEND = [
{ name: "Menstrual", color: "bg-blue-100" },
{ name: "Follicular", color: "bg-green-100" },
{ name: "Ovulation", color: "bg-purple-100" },
{ name: "Early Luteal", color: "bg-yellow-100" },
{ name: "Late Luteal", color: "bg-red-100" },
{ name: "Menstrual", color: "bg-blue-100 dark:bg-blue-900/50" },
{ name: "Follicular", color: "bg-green-100 dark:bg-green-900/50" },
{ name: "Ovulation", color: "bg-purple-100 dark:bg-purple-900/50" },
{ name: "Early Luteal", color: "bg-yellow-100 dark:bg-yellow-900/50" },
{ name: "Late Luteal", color: "bg-red-100 dark:bg-red-900/50" },
];
function getDaysInMonth(year: number, month: number): number {
@@ -102,7 +105,7 @@ export function MiniCalendar({
<button
type="button"
onClick={handlePreviousMonth}
className="p-1 hover:bg-gray-100 rounded text-sm"
className="p-1 hover:bg-muted rounded text-sm"
aria-label="Previous month"
>
@@ -117,7 +120,7 @@ export function MiniCalendar({
<button
type="button"
onClick={handleTodayClick}
className="px-2 py-0.5 text-xs border rounded hover:bg-gray-100"
className="px-2 py-0.5 text-xs border rounded hover:bg-muted"
>
Today
</button>
@@ -125,7 +128,7 @@ export function MiniCalendar({
<button
type="button"
onClick={handleNextMonth}
className="p-1 hover:bg-gray-100 rounded text-sm"
className="p-1 hover:bg-muted rounded text-sm"
aria-label="Next month"
>
@@ -138,7 +141,7 @@ export function MiniCalendar({
<div
// biome-ignore lint/suspicious/noArrayIndexKey: Day names are fixed and index is stable
key={`day-header-${index}`}
className="text-center text-xs font-medium text-gray-500"
className="text-center text-xs font-medium text-muted-foreground"
>
{dayName}
</div>
@@ -165,7 +168,7 @@ export function MiniCalendar({
type="button"
key={date.toISOString()}
className={`p-1 text-xs rounded ${PHASE_COLORS[phase]} ${
isToday ? "ring-2 ring-black font-bold" : ""
isToday ? "ring-2 ring-foreground font-bold" : ""
}`}
>
{date.getDate()}
@@ -182,7 +185,7 @@ export function MiniCalendar({
{PHASE_LEGEND.map((phase) => (
<div key={phase.name} className="flex items-center gap-0.5">
<div className={`w-2 h-2 rounded ${phase.color}`} />
<span className="text-xs text-gray-600">{phase.name}</span>
<span className="text-xs text-muted-foreground">{phase.name}</span>
</div>
))}
</div>