Phase 1: Fix TypeScript compilation — add missing API functions and fix hook signatures

- Add 8 missing API client functions (getBreakPeriods, createBreakPeriod, deleteBreakPeriod, getTips, getParentalLeave, getPlannedDays, createPlannedDay, deletePlannedDay)
- Fix useAnalytics to accept optional childId parameter
- Fix ApiError strict optional properties handling
- Export HeaderProps from Header component
- Update hook tests to use correct data structures and optional parameters

npx tsc --noEmit now passes with zero errors.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-06-01 17:47:17 +02:00
parent 53d157535a
commit fbb7a04580
15 changed files with 1092 additions and 62 deletions
+70 -3
View File
@@ -19,7 +19,7 @@ import type {
WorkspaceCreateRequest,
WorkspaceOverview,
} from '@/types'
import type { Workspace } from '@/types'
import type { Workspace, BreakPeriod, Tip, PlannedLeaveDay } from '@/types'
const BASE = '/api'
@@ -42,13 +42,15 @@ async function apiFetch<T>(
}
const response = await fetch(`${BASE}${path}`, { ...options, headers })
if (!response.ok) {
let error = { code: String(response.status), message: response.statusText, details: undefined }
let error: { code: string; message: string; details?: Record<string, unknown> } = {
code: String(response.status),
message: response.statusText,
}
try {
const body = (await response.json()) as { detail?: string; code?: string; message?: string }
error = {
code: body.code ?? String(response.status),
message: body.detail ?? body.message ?? response.statusText,
details: undefined,
}
} catch {
// response body wasn't JSON — use status text
@@ -157,3 +159,68 @@ export async function getWorkspaceOverview(
): Promise<WorkspaceOverview> {
return apiFetch(`/analytics/${workspaceId}/overview?child_id=${childId}`)
}
// ---------------------------------------------------------------------------
// Break Periods
// ---------------------------------------------------------------------------
export async function getBreakPeriods(workspaceId: string): Promise<BreakPeriod[]> {
return apiFetch(`/workspaces/${workspaceId}/break-periods`)
}
export async function createBreakPeriod(
workspaceId: string,
payload: { startDate: string; endDate: string; name: string; targetWeeks: number },
): Promise<BreakPeriod> {
return apiFetch(`/workspaces/${workspaceId}/break-periods`, {
method: 'POST',
body: JSON.stringify(payload),
})
}
export async function deleteBreakPeriod(id: string): Promise<void> {
return apiFetch(`/break-periods/${id}`, { method: 'DELETE' })
}
// ---------------------------------------------------------------------------
// Tips
// ---------------------------------------------------------------------------
export async function getTips(workspaceId: string): Promise<Tip[]> {
return apiFetch(`/workspaces/${workspaceId}/tips`)
}
// ---------------------------------------------------------------------------
// Parental Leave Fetch
// ---------------------------------------------------------------------------
export async function getParentalLeave(workspaceId: string): Promise<ParentalLeaveFetch> {
return apiFetch(`/workspaces/${workspaceId}/parental-leave`)
}
// ---------------------------------------------------------------------------
// Planned Days
// ---------------------------------------------------------------------------
export async function getPlannedDays(
workspaceId: string,
childId?: string,
): Promise<PlannedLeaveDay[]> {
const query = childId ? `?childId=${childId}` : ''
return apiFetch(`/workspaces/${workspaceId}/planned-days${query}`)
}
export async function createPlannedDay(
workspaceId: string,
childId: string,
payload: { date: string; leaveType: string },
): Promise<PlannedLeaveDay> {
return apiFetch(`/workspaces/${workspaceId}/planned-days`, {
method: 'POST',
body: JSON.stringify({ ...payload, childId }),
})
}
export async function deletePlannedDay(id: string): Promise<void> {
return apiFetch(`/planned-days/${id}`, { method: 'DELETE' })
}