feat: add PendingRewardDialog, RewardConfirmDialog, and TaskConfirmDialog components
All checks were successful
Gitea Actions Demo / build-and-push (push) Successful in 25s

- Implemented PendingRewardDialog for handling pending reward requests.
- Created RewardConfirmDialog for confirming reward redemption.
- Developed TaskConfirmDialog for task confirmation with child name display.

test: add unit tests for ChildView and ParentView components

- Added comprehensive tests for ChildView including task triggering and SSE event handling.
- Implemented tests for ParentView focusing on override modal and SSE event management.

test: add ScrollingList component tests

- Created tests for ScrollingList to verify item fetching, loading states, and custom item classes.
- Included tests for two-step click interactions and edit button display logic.
- Moved toward hashed passwords.
This commit is contained in:
2026-02-10 20:21:05 -05:00
parent 3dee8b80a2
commit 401c21ad82
45 changed files with 4353 additions and 441 deletions

View File

@@ -35,3 +35,39 @@ export async function getTrackingEventsForChild(params: {
return fetch(`/api/admin/tracking?${query.toString()}`)
}
/**
* Set or update a custom value for a task/reward for a specific child.
*/
export async function setChildOverride(
childId: string,
entityId: string,
entityType: 'task' | 'reward',
customValue: number,
): Promise<Response> {
return fetch(`/api/child/${childId}/override`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
entity_id: entityId,
entity_type: entityType,
custom_value: customValue,
}),
})
}
/**
* Get all overrides for a specific child.
*/
export async function getChildOverrides(childId: string): Promise<Response> {
return fetch(`/api/child/${childId}/overrides`)
}
/**
* Delete an override (reset to default).
*/
export async function deleteChildOverride(childId: string, entityId: string): Promise<Response> {
return fetch(`/api/child/${childId}/override/${entityId}`, {
method: 'DELETE',
})
}

View File

@@ -94,6 +94,8 @@ export interface Event {
| TaskModifiedEventPayload
| RewardModifiedEventPayload
| TrackingEventCreatedPayload
| ChildOverrideSetPayload
| ChildOverrideDeletedPayload
}
export interface ChildModifiedEventPayload {
@@ -144,6 +146,16 @@ export interface TrackingEventCreatedPayload {
action: ActionType
}
export interface ChildOverrideSetPayload {
override: ChildOverride
}
export interface ChildOverrideDeletedPayload {
child_id: string
entity_id: string
entity_type: string
}
export type EntityType = 'task' | 'reward' | 'penalty'
export type ActionType = 'activated' | 'requested' | 'redeemed' | 'cancelled'
@@ -178,3 +190,25 @@ export const TRACKING_EVENT_FIELDS = [
'updated_at',
'metadata',
] as const
export type OverrideEntityType = 'task' | 'reward'
export interface ChildOverride {
id: string
child_id: string
entity_id: string
entity_type: OverrideEntityType
custom_value: number
created_at: number
updated_at: number
}
export const CHILD_OVERRIDE_FIELDS = [
'id',
'child_id',
'entity_id',
'entity_type',
'custom_value',
'created_at',
'updated_at',
] as const