Skip to content

Instantly share code, notes, and snippets.

@jstacoder
Last active June 12, 2023 11:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jstacoder/73e6439c3eb2045731f3d859c8feba3f to your computer and use it in GitHub Desktop.
Save jstacoder/73e6439c3eb2045731f3d859c8feba3f to your computer and use it in GitHub Desktop.
useEventStore hook for calendar app
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