xmas/src/PartyContext.tsx
2022-10-11 17:59:57 +02:00

68 lines
2.0 KiB
TypeScript

import React, { createContext, useCallback, useEffect, useMemo, useState } from 'react';
import { getPartyStatusRequest, getSelfStatusRequest, parseURI } from './partyApi';
import './PartyPage.css';
export const PartyContext = createContext<PartyContextType>({
party: { definitely_coming: 0, maybe_coming: 0 },
self: { token: "", name: "", coming: "yes", grammatical_gender: "m" }
});
export type PartyContextType = {
party: PartyStatus,
self: SelfStatus,
}
export type PartyStatus = {
"definitely_coming": number,
"maybe_coming": number,
}
export type SelfStatus = {
token: string,
name: string,
coming: "yes" | "no" | "maybe" | null,
"grammatical_gender": "m" | "f" | "d",
extra?: SelfStatusExtraData,
}
export type UpdatableSelfStatus = {
coming?: "yes" | "no" | "maybe" | null,
extra?: SelfStatusExtraData,
}
export type APIEndPoint = { partyName: string, token: string };
// Adapt this type to your desires
export type SelfStatusExtraData = {
};
export const PartyContextProvider: React.FC<{ children: React.ReactNode }> = (props) => {
const [partyContext, setPartyContext] = useState<PartyContextType>();
const apiEndpoint = useMemo<APIEndPoint>(() => {
// eslint-disable-next-line no-restricted-globals
const href = location.href;
const p = parseURI(href);
if (!p) return { partyName: "error", token: "" }
return p;
}, []);
const loadData = useCallback(async () => {
if (partyContext !== undefined) return;
const selfStatus = await getSelfStatusRequest(apiEndpoint);
const partyStatus = await getPartyStatusRequest(apiEndpoint);
const ctx = { party: partyStatus, self: selfStatus };
setPartyContext(ctx);
}, [apiEndpoint, partyContext]);
useEffect(() => {
loadData();
}, [apiEndpoint, loadData]);
return partyContext ?
<PartyContext.Provider value={partyContext}>
{props.children}
</PartyContext.Provider>
: <div className="loading" />;
};