MVP frontend+backend
This commit is contained in:
+130
-17
@@ -17,6 +17,7 @@ import type {
|
||||
VacationDays,
|
||||
VacationDaysCreateRequest,
|
||||
WorkspaceCreateRequest,
|
||||
WorkspaceUpdateRequest,
|
||||
WorkspaceOverview,
|
||||
} from '@/types'
|
||||
import type { Workspace, BreakPeriod, Tip, PlannedLeaveDay } from '@/types'
|
||||
@@ -47,10 +48,17 @@ async function apiFetch<T>(
|
||||
message: response.statusText,
|
||||
}
|
||||
try {
|
||||
const body = (await response.json()) as { detail?: string; code?: string; message?: string }
|
||||
const body = (await response.json()) as {
|
||||
detail?: string | Array<{ msg?: string }>
|
||||
code?: string
|
||||
message?: string
|
||||
}
|
||||
const detail = Array.isArray(body.detail)
|
||||
? body.detail.map((e) => e.msg ?? JSON.stringify(e)).join('; ')
|
||||
: body.detail
|
||||
error = {
|
||||
code: body.code ?? String(response.status),
|
||||
message: body.detail ?? body.message ?? response.statusText,
|
||||
message: detail ?? body.message ?? response.statusText,
|
||||
}
|
||||
} catch {
|
||||
// response body wasn't JSON — use status text
|
||||
@@ -91,6 +99,30 @@ export async function refreshToken(): Promise<TokenResponse> {
|
||||
return apiFetch('/auth/refresh', { method: 'POST' })
|
||||
}
|
||||
|
||||
export interface UserContext {
|
||||
personal_data_uuid: string
|
||||
workspace_id: string
|
||||
parent_name: string
|
||||
children: Array<{ id: string; name: string; birth_date: string }>
|
||||
}
|
||||
|
||||
export async function getUserContext(): Promise<UserContext> {
|
||||
return apiFetch('/auth/context')
|
||||
}
|
||||
|
||||
export interface CreateChildRequest {
|
||||
workspace_id: string
|
||||
name: string
|
||||
birth_date: string
|
||||
}
|
||||
|
||||
export async function createChild(req: CreateChildRequest): Promise<{ id: string; name: string }> {
|
||||
return apiFetch('/children', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(req),
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Workspace
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -103,6 +135,19 @@ export async function getWorkspace(workspaceId: string): Promise<Workspace> {
|
||||
return apiFetch(`/workspace/${workspaceId}`)
|
||||
}
|
||||
|
||||
export async function updateWorkspace(
|
||||
workspaceId: string,
|
||||
req: WorkspaceUpdateRequest,
|
||||
): Promise<Workspace> {
|
||||
return apiFetch(`/workspace/${workspaceId}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({
|
||||
name: req.name,
|
||||
planning_goal: req.planningGoal,
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Vacation days (reference endpoint group — mirror this pattern for others)
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -160,21 +205,55 @@ export async function getWorkspaceOverview(
|
||||
return apiFetch(`/analytics/${workspaceId}/overview?child_id=${childId}`)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Settings
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
interface ParentSettingsUpdate {
|
||||
salary_type?: string | undefined
|
||||
employment_status?: string | undefined
|
||||
}
|
||||
|
||||
export async function updateParentSettings(
|
||||
personalDataUuid: string,
|
||||
payload: ParentSettingsUpdate,
|
||||
): Promise<{ uuid: string; name: string; salary_type: string; employment_status: string }> {
|
||||
return apiFetch(`/settings/parent/${personalDataUuid}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
}
|
||||
|
||||
interface ChildSettingsUpdate {
|
||||
birth_date?: string
|
||||
preschool_start_date?: string
|
||||
}
|
||||
|
||||
export async function updateChildSettings(
|
||||
childId: string,
|
||||
payload: ChildSettingsUpdate,
|
||||
): Promise<{ id: string; name: string; birth_date: string }> {
|
||||
return apiFetch(`/settings/child/${childId}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Break Periods
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export async function getBreakPeriods(workspaceId: string): Promise<BreakPeriod[]> {
|
||||
return apiFetch(`/workspaces/${workspaceId}/break-periods`)
|
||||
return apiFetch(`/break-periods/${workspaceId}`)
|
||||
}
|
||||
|
||||
export async function createBreakPeriod(
|
||||
workspaceId: string,
|
||||
payload: { startDate: string; endDate: string; name: string; targetWeeks: number },
|
||||
): Promise<BreakPeriod> {
|
||||
return apiFetch(`/workspaces/${workspaceId}/break-periods`, {
|
||||
return apiFetch(`/break-periods`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(payload),
|
||||
body: JSON.stringify({ ...payload, workspace_id: workspaceId }),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -187,40 +266,74 @@ export async function deleteBreakPeriod(id: string): Promise<void> {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export async function getTips(workspaceId: string): Promise<Tip[]> {
|
||||
return apiFetch(`/workspaces/${workspaceId}/tips`)
|
||||
return apiFetch(`/tips/${workspaceId}`)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Parental Leave Fetch
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export async function getParentalLeave(workspaceId: string): Promise<ParentalLeaveFetch> {
|
||||
return apiFetch(`/workspaces/${workspaceId}/parental-leave`)
|
||||
export async function getParentalLeave(
|
||||
personalDataUuid: string,
|
||||
childId: string,
|
||||
): Promise<ParentalLeaveFetch> {
|
||||
return apiFetch(`/parental-leave/${personalDataUuid}/${childId}`)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 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 getPlannedDays(childId?: string): Promise<PlannedLeaveDay[]> {
|
||||
const query = childId ? `?child_id=${childId}` : ''
|
||||
return apiFetch(`/planned-days${query}`)
|
||||
}
|
||||
|
||||
export async function createPlannedDay(
|
||||
workspaceId: string,
|
||||
childId: string,
|
||||
payload: { date: string; leaveType: string },
|
||||
): Promise<PlannedLeaveDay> {
|
||||
return apiFetch(`/workspaces/${workspaceId}/planned-days`, {
|
||||
return apiFetch(`/planned-days`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ ...payload, childId }),
|
||||
body: JSON.stringify({ ...payload, child_id: childId }),
|
||||
})
|
||||
}
|
||||
|
||||
export async function deletePlannedDay(id: string): Promise<void> {
|
||||
return apiFetch(`/planned-days/${id}`, { method: 'DELETE' })
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FK Scraper (dev / authenticated users only — requires scraper_enabled=true)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
interface ScraperStartRequest {
|
||||
workspace_id?: string
|
||||
personal_data_uuid?: string
|
||||
child_id?: string
|
||||
}
|
||||
|
||||
interface ScraperStartResponse {
|
||||
session_id: string
|
||||
status: string
|
||||
workspace_id: string
|
||||
personal_data_uuid: string
|
||||
child_id: string
|
||||
}
|
||||
|
||||
export async function startScraperSession(
|
||||
payload: ScraperStartRequest,
|
||||
): Promise<ScraperStartResponse> {
|
||||
return apiFetch('/fetch-data/start', { method: 'POST', body: JSON.stringify(payload) })
|
||||
}
|
||||
|
||||
export async function pollScraperSession(sessionId: string): Promise<unknown> {
|
||||
return apiFetch(`/fetch-data/poll?session_id=${encodeURIComponent(sessionId)}`)
|
||||
}
|
||||
|
||||
export async function cancelScraperSession(sessionId: string): Promise<void> {
|
||||
return apiFetch('/fetch-data/cancel', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ session_id: sessionId }),
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user