Files
cn-ui/src/context/CampaignRuleContext.tsx

113 lines
2.7 KiB
TypeScript

import { createContext, useContext, useState, useEffect } from "react";
import type { ReactNode } from "react";
import type { Event } from "../types/event";
export type RuleCondition = {
id: string;
attribute: string;
label: string;
operator: string;
value: string;
};
export type RuleGroup = {
id: string;
operator: "AND" | "OR";
conditions: RuleCondition[];
};
export type CampaignRuleState = {
general: {
id: string;
name: string;
type: string;
effectiveDateStart: string;
effectiveDateEnd: string;
};
criteria: {
globalOperator: "AND" | "OR";
groups: RuleGroup[];
};
formula: any;
notification: any;
availableEvents: Event[];
isLoadingEvents: boolean;
eventsError: string | null;
};
type CampaignRuleContextType = {
state: CampaignRuleState;
updateState: (section: keyof CampaignRuleState, payload: any) => void;
currentStep: number;
setStep: (step: number) => void;
};
const initialState: CampaignRuleState = {
general: {
id: "",
name: "",
type: "",
effectiveDateStart: "",
effectiveDateEnd: "",
},
criteria: {
globalOperator: "AND",
groups: [],
},
formula: {},
notification: {},
availableEvents: [],
isLoadingEvents: false,
eventsError: null,
};
const CampaignRuleContext = createContext<CampaignRuleContextType | undefined>(undefined);
export const CampaignRuleProvider = ({ children }: { children: ReactNode }) => {
const [state, setState] = useState<CampaignRuleState>(initialState);
const [currentStep, setCurrentStep] = useState(0);
useEffect(() => {
const fetchEvents = async () => {
setState((prev) => ({ ...prev, isLoadingEvents: true, eventsError: null }));
try {
const res = await fetch('/api/v1/events');
if (!res.ok) throw new Error('Failed to fetch events');
const data = await res.json();
setState((prev) => ({ ...prev, availableEvents: data, isLoadingEvents: false }));
} catch (err: any) {
setState((prev) => ({ ...prev, eventsError: err.message, isLoadingEvents: false }));
}
};
fetchEvents();
}, []);
const updateState = (section: keyof CampaignRuleState, payload: any) => {
setState((prev) => ({
...prev,
[section]: {
...prev[section],
...payload,
},
}));
};
const setStep = (step: number) => {
setCurrentStep(step);
};
return (
<CampaignRuleContext.Provider value={{ state, updateState, currentStep, setStep }}>
{children}
</CampaignRuleContext.Provider>
);
};
export const useCampaignRule = () => {
const context = useContext(CampaignRuleContext);
if (!context) {
throw new Error("useCampaignRule must be used within a CampaignRuleProvider");
}
return context;
};