// Importing necessary libraries and components import { useState, useEffect, useRef } from "@wordpress/element"; import { ruleCategories } from "./rules"; import Rule from "./Rule"; import Switch from "./Switch"; import { Button, Flex, Input, Modal } from "antd"; import { FireFilled, LockFilled, SettingOutlined, UnlockFilled, } from "@ant-design/icons"; import FloatInput from "../../Components/FloatInput"; import { __ } from "@wordpress/i18n"; // Import WordPress translation function import BetterSelect from "../../Components/BetterSelect"; import Tag from "../../Components/Tag"; // Props type definition for the Group component type Props = { index: number; // Index of the group data: { rules: any[]; // Array of rules in the group settings: { error_message: string; // Custom error message for the group }; }; onUpdate: (groupIndex: number, key: string | number, value: any) => void; // Callback to update group data onRemove: Function; // Callback to remove the group onRuleAdd: (rule: string, groupIndex: number) => void; // Callback to add a rule to the group onRuleUpdate: ( groupIndex: number, ruleIndex: number, key: string | number, value: any ) => void; // Callback to update a rule in the group onRuleRemove: (groupIndex: number, ruleIndex: number) => void; // Callback to remove a rule from the group onSwitch: (index: number, o: "AND" | "OR") => void; // Callback to handle switch state changes next: any; // Reference to the next group or rule className?: string; // Optional class name for styling }; const Group = ({ index, data, onUpdate, onRemove, onRuleAdd, onRuleUpdate, onRuleRemove, onSwitch, next, className = "", }: Props) => { // State to manage the visibility of the settings dialog const [showDialog, setShowDialog] = useState(false); // State to confirm deletion of the group const [confirmDelete, setConfirmDelete] = useState(false); // Reference to the error message input field const errorMessageInputRef = useRef(null); // Reset confirmDelete state when the dialog visibility changes useEffect(() => { setConfirmDelete(false); }, [showDialog]); // Function to close the settings dialog const handleDialogClose = () => { setShowDialog(false); }; // Extracting rules from the group data const rules = data.rules; return ( <> {/* Main container for the group */} {/* Render each rule or switch in the group */} {rules.map((rule, ruleIndex) => { const nextRule = rules[ruleIndex + 1] || false; // Reference to the next rule switch (rule.type) { case "rule": return ( onRuleUpdate( index, ruleIndex, key, value ) } onRemove={onRuleRemove} className={ rules.length === 1 ? "tw-mx-1 tw-my-4" : ruleIndex === 0 ? "tw-mx-4 tw-mt-4" : "tw-mx-4" } next={nextRule} > ); case "switch": return ( onSwitch(ruleIndex, state) } /> ); } })} {/* Rule picker to add new rules */}
{/* Settings button */}
setShowDialog(true)} >
{/* Modal for group settings */} setShowDialog(false)} onCancel={() => handleDialogClose()} footer={[ /* Delete button with confirmation */ , /* Cancel button */ , /* Save button */ , ]} afterOpenChange={(open) => { if (open) { errorMessageInputRef.current?.focus(); } }} > {/* Error message input field */}
{next && next.state === "OR" ? ( ) : ( )}
); }; // Props type definition for the RulePicker component type RulePickerProps = { groupIndex: number; // Index of the group onChoose: (rule: string, groupIndex: number) => void; // Callback to choose a rule className?: string; // Optional class name for styling }; const RulePicker = ({ groupIndex, onChoose, className = "", }: RulePickerProps) => { return ( { onChoose(value, groupIndex); // Trigger onChoose callback }} value={null} placeholder={__("Add a rule...", "swift-coupons-for-woocommerce")} options={Object.keys(ruleCategories).map((catId: string) => ({ label: ruleCategories[catId].title, options: [...ruleCategories[catId].rules] .sort((a: any, b: any) => { // Sort by unlocked (true first), then by title alphabetically if (a.unlocked === b.unlocked) { if (a.lock_type === b.lock_type) { return a.title.localeCompare(b.title); } return a.lock_type === "premium" ? -1 : 1; } return a.unlocked ? -1 : 1; }) .map((rule: any) => ({ value: rule.id, label: rule.title, description: rule.description || "No description", dimmed: !rule.unlocked, tags: [ rule.lock_type === "premium" && , rule.unlocked ? ( rule.lock_type !== null && ) : ( ), !rule.unlocked && rule.lock_type !== "premium" && ( {__( "Unlock for FREE!", "swift-coupons-for-woocommerce" )} ), ], })), }))} /> ); }; export default Group;