110 lines
3.0 KiB
TypeScript
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>
|
|
);
|
|
}
|