Last active
June 12, 2023 11:53
-
-
Save jstacoder/73e6439c3eb2045731f3d859c8feba3f to your computer and use it in GitHub Desktop.
useEventStore hook for calendar app
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { | |
createContext, | |
useReducer, | |
useContext, | |
} from 'react' | |
type Event = { | |
title: string; | |
start: string | Date; | |
end?: string | Date; | |
color?: string; | |
id: string; | |
allDay?: boolean; | |
borderColor?: string; | |
} | |
interface IEventContext { | |
events: Event[], | |
addEvent: (event: Event)=> void, | |
editEvent: (event: Event, newEvent: Event) => void, | |
removeEvent: (event: Event) => void, | |
} | |
const initialEventContext : IEventContext = { | |
events: [], | |
addEvent:()=> null, | |
removeEvent: ()=> null, | |
editEvent: ()=> null, | |
} | |
const EventContext = createContext<IEventContext>(initialEventContext) | |
interface IAction { | |
type: ActionType; | |
payload: any; | |
} | |
type ActionCreator = (actionArgs: any) => IAction | |
type ActionType = string | |
const add_event: ActionType = 'ADD_EVENT' | |
const remove_event: ActionType = 'REMOVE_EVENT' | |
const edit_event: ActionType = 'EDIT_EVENT' | |
const addEventAction: ActionCreator = (actionArgs: ({event: Event})): IAction => ({ | |
type: add_event, | |
payload: { | |
event: actionArgs.event | |
} | |
}) | |
const removeEventAction: ActionCreator = (actionArgs: ({event: Event})): IAction => ({ | |
type: remove_event, | |
payload: { | |
eventId: actionArgs.event.id, | |
} | |
}) | |
const editEventAction: ActionCreator = (actionArgs: ({event: Event, newEvent: Event})): IAction => ({ | |
type: edit_event, | |
payload: { | |
eventId: actionArgs.event.id, | |
data: actionArgs.newEvent, | |
} | |
}) | |
const reducer = (state: IEventContext["events"], action: IAction): IEventContext["events"] => { | |
switch(action.type){ | |
case add_event: | |
return [ | |
...state, | |
action.payload.event, | |
] | |
case remove_event: | |
return [ | |
...state, | |
...(state.filter(e=> e.id !== action.payload.eventId)) | |
] | |
case edit_event: | |
return [ | |
...state.filter(e=> e.id !== action.payload.eventId), | |
...action.payload.data | |
] | |
default: | |
return state | |
} | |
} | |
export const EventContextProvider : React.FC<React.PropsWithChildren> = ({children}) => { | |
const [events, dispatch] = useReducer<typeof reducer>(reducer, []) | |
const addEvent = (event: Event) => dispatch(addEventAction( {event } )) | |
const removeEvent = (event: Event) => dispatch(removeEventAction({ event })) | |
const editEvent = (event: Event, newEvent: Event) => dispatch(editEventAction({ event, newEvent})) | |
const value: IEventContext = { | |
events, | |
addEvent, | |
removeEvent, | |
editEvent, | |
} | |
return ( | |
<EventContext.Provider value={value}> | |
{children} | |
</EventContext.Provider> | |
) | |
} | |
const useEventStore = () => useContext(EventContext) | |
export default useEventStore |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment