80 lines
2.2 KiB
TypeScript
80 lines
2.2 KiB
TypeScript
import {
|
|
CalendarItem,
|
|
Classmate,
|
|
EtjanstChild,
|
|
MenuItem,
|
|
NewsItem,
|
|
Notification,
|
|
ScheduleItem,
|
|
Skola24Child,
|
|
TimetableEntry,
|
|
User,
|
|
} from '@skolplattformen/api-skolplattformen'
|
|
import { EntityName, EntityReducer, EntityState } from './types'
|
|
|
|
const createReducer = <T>(entity: EntityName): EntityReducer<T> => {
|
|
const reducer: EntityReducer<T> = (state = {}, action) => {
|
|
if (action.entity !== entity || !action.extra) return state
|
|
const key = action.extra?.key
|
|
|
|
const node = state[key] || {
|
|
status: 'pending',
|
|
data: action.extra.defaultValue,
|
|
}
|
|
let newNode: EntityState<T>
|
|
switch (action.type) {
|
|
case 'GET_FROM_API': {
|
|
newNode = {
|
|
...node,
|
|
error: undefined,
|
|
status: 'loading',
|
|
}
|
|
break
|
|
}
|
|
case 'RESULT_FROM_API': {
|
|
newNode = {
|
|
...node,
|
|
data: action.data || node.data,
|
|
status: 'loaded',
|
|
}
|
|
break
|
|
}
|
|
case 'API_ERROR': {
|
|
newNode = {
|
|
...node,
|
|
status: action.extra.retries < 3 ? node.status : 'error',
|
|
error: action.error,
|
|
}
|
|
break
|
|
}
|
|
case 'RESULT_FROM_CACHE': {
|
|
newNode = {
|
|
...node,
|
|
data: action.data || node.data,
|
|
}
|
|
break
|
|
}
|
|
default: {
|
|
newNode = { ...node }
|
|
}
|
|
}
|
|
return {
|
|
...state,
|
|
[key]: newNode,
|
|
}
|
|
}
|
|
return reducer
|
|
}
|
|
|
|
export const user = createReducer<User>('USER')
|
|
export const etjanstChildren = createReducer<EtjanstChild[]>('ETJANST_CHILDREN')
|
|
export const skola24Children = createReducer<Skola24Child[]>('SKOLA24_CHILDREN')
|
|
export const calendar = createReducer<CalendarItem[]>('CALENDAR')
|
|
export const classmates = createReducer<Classmate[]>('CLASSMATES')
|
|
export const menu = createReducer<MenuItem[]>('MENU')
|
|
export const news = createReducer<NewsItem[]>('NEWS')
|
|
export const newsDetails = createReducer<NewsItem[]>('NEWS_DETAILS')
|
|
export const notifications = createReducer<Notification[]>('NOTIFICATIONS')
|
|
export const schedule = createReducer<ScheduleItem[]>('SCHEDULE')
|
|
export const timetable = createReducer<TimetableEntry[]>('TIMETABLE')
|