71 lines
1.4 KiB
TypeScript
71 lines
1.4 KiB
TypeScript
import {
|
|
createContext,
|
|
ReactNode,
|
|
useContext,
|
|
useMemo,
|
|
useState,
|
|
} from "react";
|
|
|
|
export interface BirthdayEntry {
|
|
id: string;
|
|
name: string;
|
|
date: string;
|
|
}
|
|
|
|
interface AddBirthdayInput {
|
|
name: string;
|
|
date: string;
|
|
}
|
|
|
|
interface BirthdaysContextValue {
|
|
birthdays: BirthdayEntry[];
|
|
addBirthday: (input: AddBirthdayInput) => void;
|
|
}
|
|
|
|
const BirthdaysContext = createContext<BirthdaysContextValue | undefined>(
|
|
undefined
|
|
);
|
|
|
|
export function BirthdaysProvider({ children }: { children: ReactNode }) {
|
|
const [birthdays, setBirthdays] = useState<BirthdayEntry[]>([]);
|
|
|
|
const value = useMemo(
|
|
() => ({
|
|
birthdays,
|
|
addBirthday: ({ name, date }: AddBirthdayInput) => {
|
|
const trimmedName = name.trim();
|
|
|
|
if (!trimmedName) {
|
|
return;
|
|
}
|
|
|
|
setBirthdays((currentBirthdays) => [
|
|
...currentBirthdays,
|
|
{
|
|
id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
name: trimmedName,
|
|
date,
|
|
},
|
|
]);
|
|
},
|
|
}),
|
|
[birthdays]
|
|
);
|
|
|
|
return (
|
|
<BirthdaysContext.Provider value={value}>
|
|
{children}
|
|
</BirthdaysContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useBirthdays() {
|
|
const context = useContext(BirthdaysContext);
|
|
|
|
if (!context) {
|
|
throw new Error("useBirthdays must be used within a BirthdaysProvider");
|
|
}
|
|
|
|
return context;
|
|
}
|