"use client"; import { useListMachines } from "@/api/machine/machine"; import { Machine, MachinesResponse } from "@/api/model"; import { clanErrorToast } from "@/error/errorToast"; import { AxiosError, AxiosResponse } from "axios"; import React, { Dispatch, ReactNode, SetStateAction, createContext, useEffect, useMemo, useState, } from "react"; import { KeyedMutator } from "swr"; type PartialRecord = { [P in K]?: T; }; export type MachineFilter = PartialRecord< keyof Machine, Machine[keyof Machine] >; type MachineContextType = { rawData: AxiosResponse | undefined; data: Machine[]; isLoading: boolean; error: AxiosError | undefined; isValidating: boolean; filters: MachineFilter; setFilters: Dispatch>; mutate: KeyedMutator>; swrKey: string | false | Record; }; export function CreateMachineContext() { return createContext({} as MachineContextType); } interface MachineContextProviderProps { children: ReactNode; clanDir: string; } const MachineContext = CreateMachineContext(); export const MachineContextProvider = (props: MachineContextProviderProps) => { const { children, clanDir } = props; const { data: rawData, isLoading, error, isValidating, mutate, swrKey, } = useListMachines({ flake_dir: clanDir }); const [filters, setFilters] = useState({}); useEffect(() => { if (error) { clanErrorToast(error); } }, [error]); const data = useMemo(() => { if (!isLoading && rawData) { const { machines } = rawData.data; return machines.filter( (m) => !filters.name || m.name.toLowerCase().includes(filters.name.toLowerCase()), ); } return []; }, [isLoading, filters, rawData]); return ( {children} ); }; export const useMachines = () => React.useContext(MachineContext);