Services: Admin-Lehrer, Backend-Lehrer, Studio v2, Website, Klausur-Service, School-Service, Voice-Service, Geo-Service, BreakPilot Drive, Agent-Core Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
122 lines
3.6 KiB
TypeScript
122 lines
3.6 KiB
TypeScript
'use client'
|
|
|
|
import React, { createContext, useContext, useReducer, useMemo } from 'react'
|
|
import type { CustomCatalogEntry, CustomCatalogs, CatalogId } from './catalog-manager/types'
|
|
|
|
// =============================================================================
|
|
// SIMPLIFIED STATE (Admin-Lehrer only needs catalog-manager state)
|
|
// =============================================================================
|
|
|
|
export interface SDKState {
|
|
customCatalogs: CustomCatalogs
|
|
}
|
|
|
|
export type SDKAction =
|
|
| { type: 'ADD_CUSTOM_CATALOG_ENTRY'; payload: CustomCatalogEntry }
|
|
| { type: 'UPDATE_CUSTOM_CATALOG_ENTRY'; payload: { catalogId: CatalogId; entryId: string; data: Record<string, unknown> } }
|
|
| { type: 'DELETE_CUSTOM_CATALOG_ENTRY'; payload: { catalogId: CatalogId; entryId: string } }
|
|
| { type: 'SET_STATE'; payload: Partial<SDKState> }
|
|
|
|
export const initialState: SDKState = {
|
|
customCatalogs: {},
|
|
}
|
|
|
|
// =============================================================================
|
|
// REDUCER
|
|
// =============================================================================
|
|
|
|
function sdkReducer(state: SDKState, action: SDKAction): SDKState {
|
|
switch (action.type) {
|
|
case 'ADD_CUSTOM_CATALOG_ENTRY': {
|
|
const entry = action.payload
|
|
const existing = state.customCatalogs[entry.catalogId] || []
|
|
return {
|
|
...state,
|
|
customCatalogs: {
|
|
...state.customCatalogs,
|
|
[entry.catalogId]: [...existing, entry],
|
|
},
|
|
}
|
|
}
|
|
|
|
case 'UPDATE_CUSTOM_CATALOG_ENTRY': {
|
|
const { catalogId, entryId, data } = action.payload
|
|
const existing = state.customCatalogs[catalogId] || []
|
|
return {
|
|
...state,
|
|
customCatalogs: {
|
|
...state.customCatalogs,
|
|
[catalogId]: existing.map(e =>
|
|
e.id === entryId
|
|
? { ...e, data, updatedAt: new Date().toISOString() }
|
|
: e
|
|
),
|
|
},
|
|
}
|
|
}
|
|
|
|
case 'DELETE_CUSTOM_CATALOG_ENTRY': {
|
|
const { catalogId, entryId } = action.payload
|
|
const existing = state.customCatalogs[catalogId] || []
|
|
return {
|
|
...state,
|
|
customCatalogs: {
|
|
...state.customCatalogs,
|
|
[catalogId]: existing.filter(e => e.id !== entryId),
|
|
},
|
|
}
|
|
}
|
|
|
|
case 'SET_STATE': {
|
|
return { ...state, ...action.payload }
|
|
}
|
|
|
|
default:
|
|
return state
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// CONTEXT
|
|
// =============================================================================
|
|
|
|
interface SDKContextValue {
|
|
state: SDKState
|
|
dispatch: React.Dispatch<SDKAction>
|
|
}
|
|
|
|
const SDKContext = createContext<SDKContextValue | null>(null)
|
|
|
|
// =============================================================================
|
|
// PROVIDER
|
|
// =============================================================================
|
|
|
|
interface SDKProviderProps {
|
|
children: React.ReactNode
|
|
}
|
|
|
|
export function SDKProvider({ children }: SDKProviderProps) {
|
|
const [state, dispatch] = useReducer(sdkReducer, initialState)
|
|
|
|
const value: SDKContextValue = useMemo(() => ({
|
|
state,
|
|
dispatch,
|
|
}), [state, dispatch])
|
|
|
|
return <SDKContext.Provider value={value}>{children}</SDKContext.Provider>
|
|
}
|
|
|
|
// =============================================================================
|
|
// HOOK
|
|
// =============================================================================
|
|
|
|
export function useSDK(): SDKContextValue {
|
|
const context = useContext(SDKContext)
|
|
if (!context) {
|
|
throw new Error('useSDK must be used within SDKProvider')
|
|
}
|
|
return context
|
|
}
|
|
|
|
export { SDKContext }
|