payment-backoffice/app/dashboard/admin/matcher/MatcherPageClient.tsx
2025-12-08 08:49:59 +01:00

110 lines
3.0 KiB
TypeScript

"use client";
import React, { useState, useCallback } from "react";
import { useRouter } from "next/navigation";
import {
Box,
Typography,
Select,
MenuItem,
FormControl,
InputLabel,
Alert,
} from "@mui/material";
import MatcherBoard from "./MatcherBoard/MatcherBoard";
import { MATCH_CONFIGS } from "./constants";
import { MatchableEntity, MatchConfig } from "./types";
import toast from "react-hot-toast";
interface MatcherPageClientProps {
initialSourceItems: MatchableEntity[];
initialTargetItems: MatchableEntity[];
initialMatchType: string;
config: MatchConfig;
}
export default function MatcherPageClient({
initialSourceItems,
initialTargetItems,
initialMatchType,
config: initialConfig,
}: MatcherPageClientProps) {
const router = useRouter();
const [matchType, setMatchType] = useState(initialMatchType);
const [sourceItems, setSourceItems] = useState(initialSourceItems);
const [targetItems, setTargetItems] = useState(initialTargetItems);
const currentConfig = MATCH_CONFIGS[matchType] || initialConfig;
const handleMatchTypeChange = (newType: string) => {
setMatchType(newType);
// Update URL and reload page to fetch new data via SSR
router.push(`/dashboard/admin/matcher?type=${newType}`);
router.refresh();
};
const handleMatch = useCallback(
async (sourceId: string, targetId: string) => {
try {
// TODO: Call API endpoint to save the match
// For now, just show a toast
toast.success(
`Matched ${currentConfig.sourceLabel} to ${currentConfig.targetLabel}`
);
console.log("Match:", {
sourceId,
targetId,
matchType,
});
} catch (error) {
toast.error("Failed to save match");
console.error("Error saving match:", error);
}
},
[currentConfig, matchType]
);
return (
<Box sx={{ p: 3, width: "100%" }}>
<Box
sx={{
mb: 3,
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<Typography variant="h4" sx={{ fontWeight: 600 }}>
Entity Matcher
</Typography>
<FormControl sx={{ minWidth: 250 }}>
<InputLabel>Match Type</InputLabel>
<Select
value={matchType}
label="Match Type"
onChange={e => handleMatchTypeChange(e.target.value)}
>
{Object.entries(MATCH_CONFIGS).map(([key, config]) => (
<MenuItem key={key} value={key}>
{config.sourceLabel} {config.targetLabel}
</MenuItem>
))}
</Select>
</FormControl>
</Box>
<Alert severity="info" sx={{ mb: 3 }}>
Drag items from the left column to the right column to create matches.
You can also drag items back to remove matches.
</Alert>
<MatcherBoard
sourceItems={sourceItems}
targetItems={targetItems}
config={currentConfig}
onMatch={handleMatch}
/>
</Box>
);
}