Files
edr-platform/apps/edr-freight-web/backoffice/src/user-management/components/content/PrefixSuffixTable.tsx
2026-07-10 10:41:48 +03:00

247 lines
8.8 KiB
TypeScript

// PrefixSuffixTable.tsx
import React, { useState } from "react";
import { Button } from "@/shared/common/ui/button";
import { Pencil, Trash2, X } from "lucide-react";
import { t } from "i18next";
import { Input } from "@/shared/common/ui/input";
import { Label } from "@/shared/common/ui/label";
import { prefixSuffixService } from "@/user-management/services/api/prefixSuffixService";
import { useQueryClient } from "@tanstack/react-query";
interface PrefixSuffixTableProps {
items: any[];
isLoading: boolean;
onEdit: (item: any) => void;
onDelete: (id: string, type: string, recordType: string) => void;
showPositionColumn?: boolean;
showCountColumn?: boolean;
positions?: any[];
}
export const PrefixSuffixTable = ({
items,
isLoading,
onEdit,
onDelete,
showPositionColumn = false,
showCountColumn = false,
positions = [],
}: PrefixSuffixTableProps) => {
const queryClient = useQueryClient();
const getPositionName = (positionId: string) => {
const pos = positions.find((p) => p.id === positionId);
return pos?.name?.en || pos?.name?.am || positionId;
};
const [countPopup, setCountPopup] = useState<{
itemId: string;
currentCount: number;
} | null>(null);
const [countValue, setCountValue] = useState("");
// 1. Helper to get count from either source
const getCount = (item: any): number | undefined => {
return item.recordSequences?.[0]?.count ?? item.count ?? undefined;
};
// 2. Helper to get sequence ID from either source
const getSequenceId = (item: any): string | undefined => {
return item.recordSequences?.[0]?.id ?? item.sequenceId ?? undefined;
};
// 3. Updated openCountPopup
const openCountPopup = (item: any) => {
const currentCount = getCount(item) ?? 0;
const sequenceId = getSequenceId(item);
if (!sequenceId) {
console.error("No sequence ID found for item:", item);
return;
}
setCountPopup({ itemId: sequenceId, currentCount });
setCountValue(String(currentCount));
};
const closeCountPopup = () => {
setCountPopup(null);
setCountValue("");
queryClient.invalidateQueries({
queryKey: ["prefixes-by-position"],
});
queryClient.invalidateQueries({
queryKey: ["unit-reference-numbers"],
});
};
const handleCountSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (!countPopup) return;
const newCount = parseInt(countValue, 10);
if (isNaN(newCount) || newCount < 0) return;
prefixSuffixService.updateCount(countPopup.itemId, newCount).then(() => {
closeCountPopup();
});
};
return (
<div className="overflow-x-auto border rounded-lg dark:border-gray-600">
<table className="min-w-full text-sm text-left">
<thead className="bg-gray-50 dark:bg-gray-700 border-b dark:border-gray-600">
<tr>
<th className="px-4 py-3 dark:text-white">#</th>
<th className="px-4 py-3 dark:text-white">{t("header.amharic")}</th>
<th className="px-4 py-3 dark:text-white">{t("header.english")}</th>
<th className="px-4 py-3 dark:text-white">
{t("contentManagement.type")}
</th>
{showPositionColumn && (
<th className="px-4 py-3 dark:text-white">
{t("contentManagement.position")}
</th>
)}
{showCountColumn && (
<th className="px-4 py-3 dark:text-white">
{t("contentManagement.count")}
</th>
)}
<th className="px-4 py-3 dark:text-white">
{t("userRecord.Actions")}
</th>
</tr>
</thead>
<tbody>
{isLoading ? (
<tr>
<td
colSpan={showPositionColumn ? 6 : 5}
className="text-center py-8 text-gray-500 dark:text-gray-400">
{t("contentManagement.loading")}
</td>
</tr>
) : items.length === 0 ? (
<tr>
<td
colSpan={showPositionColumn ? 6 : 5}
className="text-center py-8 text-gray-500 dark:text-gray-400">
{t("contentManagement.noRec")}
</td>
</tr>
) : (
items.map((item, idx) => {
return (
<tr
key={item.id}
className="border-b hover:bg-gray-50 dark:hover:bg-gray-700 dark:border-gray-600">
<td className="px-4 py-3 dark:text-gray-300">{idx + 1}</td>
<td className="px-4 py-3 dark:text-gray-300">
{item.name?.am || "-"}
</td>
<td className="px-4 py-3 dark:text-gray-300">
{item.name?.en || "-"}
</td>
<td className="px-4 py-3 capitalize dark:text-gray-300">
{item.type}
{item.isForCC && (
<span className="ml-1 text-xs text-purple-600 dark:text-purple-400">
(CC)
</span>
)}
</td>
{showPositionColumn && (
<td className="px-4 py-3 dark:text-gray-300">
{item.positionId ? getPositionName(item.positionId) : "-"}
</td>
)}
{showCountColumn && (
<td className="px-4 py-3 dark:text-gray-300">
{(() => {
const count = getCount(item);
if (count === undefined) return "-";
return (
<button
onClick={() => openCountPopup(item)}
className="text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300 underline cursor-pointer">
{count}
</button>
);
})()}
</td>
)}
<td className="px-4 py-3">
<div className="flex gap-2">
<Button
variant="ghost"
size="sm"
onClick={() => onEdit(item)}>
<Pencil className="h-4 w-4" />
</Button>
<Button
variant="ghost"
size="sm"
className="text-red-600 hover:text-red-800 dark:text-red-400 dark:hover:text-red-300"
onClick={() =>
onDelete(item.id, item.type, item.recordTypeKey)
}>
<Trash2 className="h-4 w-4" />
</Button>
</div>
</td>
</tr>
);
})
)}
</tbody>
</table>
{/* Count Update Popup */}
{countPopup && (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-6 w-80">
<div className="flex justify-between items-center mb-4">
<h3 className="text-lg font-semibold dark:text-white">
{t("contentManagement.updateCount")}
</h3>
<button
onClick={closeCountPopup}
className="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200">
<X className="h-5 w-5" />
</button>
</div>
<form onSubmit={handleCountSubmit}>
<div className="space-y-2 mb-4">
<Label htmlFor="countValue" className="dark:text-gray-200">
{t("contentManagement.value")} *
</Label>
<Input
id="countValue"
type="number"
min="0"
value={countValue}
onChange={(e) => setCountValue(e.target.value)}
placeholder={t("contentManagement.enterValue")}
className="dark:bg-gray-700 dark:border-gray-600 dark:text-white"
/>
<p className="text-xs text-gray-500 dark:text-gray-400">
{t("contentManagement.currentCount")}:{" "}
{countPopup.currentCount}
</p>
</div>
<div className="flex gap-2 justify-end">
<Button
type="button"
variant="outline"
onClick={closeCountPopup}>
{t("common.cancel")}
</Button>
<Button type="submit">{t("common.submit")}</Button>
</div>
</form>
</div>
</div>
)}
</div>
);
};