import { type ColumnDef } from "@tanstack/react-table"; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from "@/components/ui/card"; import { FileText, Building2, Download } from "lucide-react"; import { FormDialog } from "@/components/dialogs/form-dialog"; import { VersionTable } from "@/components/tables/version-table"; import { RequestUpdateMenu } from "@/components/menu/request-update-menu"; import { DeleteMenu } from "@/components/menu/delete-menu"; import { Button } from "@/components/ui/button"; import type { AxiosProgressEvent } from "axios"; import { useState } from "react"; import { SelectDialog } from "@/components/dialogs/select-dialog"; import { DeviceSearchDialog } from "@/components/bars/device-searchbar"; import { UploadVersionForm } from "@/components/forms/upload-file-form"; import type { Room } from "@/types/room"; import { mapRoomsToSelectItems } from "@/helpers/mapRoomToSelectItems"; import { getDeviceFromRoom } from "@/services/device-comm.service"; interface AppManagerTemplateProps { title: string; uploadFormTitle?: string; description: string; data: TData[]; isLoading: boolean; columns: ColumnDef[]; onUpload: ( fd: FormData, config?: { onUploadProgress?: (e: AxiosProgressEvent) => void } ) => Promise; onUpdate?: (targetNames: string[]) => Promise | void; updateLoading?: boolean; onDownload?: (targetNames: string[]) => Promise | void; downloadLoading?: boolean; onDelete?: () => Promise | void; onDeleteFromServer?: () => Promise | void; onDeleteFromRequired?: () => Promise | void; deleteLoading?: boolean; onAddToRequired?: () => Promise | void; addToRequiredLoading?: boolean; onTableInit?: (table: any) => void; rooms?: Room[]; devices?: string[]; } export function AppManagerTemplate({ title, uploadFormTitle, description, data, isLoading, columns, onUpload, onUpdate, updateLoading, onDownload, downloadLoading, onDelete, onDeleteFromServer, onDeleteFromRequired, deleteLoading, onAddToRequired, addToRequiredLoading, onTableInit, rooms = [], devices = [], }: AppManagerTemplateProps) { const [dialogOpen, setDialogOpen] = useState(false); const [dialogType, setDialogType] = useState<"room" | "device" | "download-room" | "download-device" | null>(null); const openRoomDialog = () => { if (rooms.length > 0 && onUpdate) { setDialogType("room"); setDialogOpen(true); } }; const openDeviceDialog = () => { if (onUpdate) { setDialogType("device"); setDialogOpen(true); } }; const openDownloadRoomDialog = () => { if (rooms.length > 0 && onDownload) { setDialogType("download-room"); setDialogOpen(true); } }; const openDownloadDeviceDialog = () => { if (onDownload) { setDialogType("download-device"); setDialogOpen(true); } }; const handleUpdateAll = async () => { if (!onUpdate) return; try { const roomIds = rooms.map((room) => typeof room === "string" ? room : room.name ); const allTargets = [...roomIds, ...devices]; await onUpdate(allTargets); } catch (e) { console.error("Update error:", e); } }; return (
{/* Header */}

{title}

{description}

{(closeDialog) => ( )}
Lịch sử phiên bản Tất cả các phiên bản đã tải lên {(onUpdate || onDelete || onAddToRequired) && (
{onDownload && ( { if (!onDownload) return; const roomIds = rooms.map((room) => typeof room === "string" ? room : room.name ); const allTargets = [...roomIds, ...devices]; onDownload(allTargets); }} loading={downloadLoading} label="Tải xuống" deviceLabel="Tải xuống thiết bị cụ thể" roomLabel="Tải xuống theo phòng" allLabel="Tải xuống tất cả thiết bị" icon={} /> )} {onAddToRequired && ( )}
{onDeleteFromServer && onDeleteFromRequired && ( )}
)}
{/* Dialog chọn phòng */} {dialogType === "room" && ( { setDialogOpen(false); setDialogType(null); setTimeout(() => window.location.reload(), 500); }} title="Chọn phòng" description="Chọn các phòng cần cập nhật" icon={} items={mapRoomsToSelectItems(rooms)} onConfirm={async (selectedItems) => { if (!onUpdate) return; try { await onUpdate(selectedItems); } catch (e) { console.error("Update error:", e); } finally { setDialogOpen(false); setDialogType(null); setTimeout(() => window.location.reload(), 500); } }} /> )} {/* Dialog tìm thiết bị */} {dialogType === "device" && ( { setDialogOpen(false); setDialogType(null); setTimeout(() => window.location.reload(), 500); }} rooms={rooms} fetchDevices={getDeviceFromRoom} onSelect={async (deviceIds) => { if (!onUpdate) { setDialogOpen(false); setDialogType(null); return; } try { await onUpdate(deviceIds); } catch (e) { console.error("Update error:", e); } finally { setDialogOpen(false); setDialogType(null); setTimeout(() => window.location.reload(), 500); } }} /> )} {/* Dialog tải file - chọn phòng */} {dialogType === "download-room" && ( { setDialogOpen(false); setDialogType(null); setTimeout(() => window.location.reload(), 500); }} title="Chọn phòng" description="Chọn các phòng để tải file xuống" icon={} items={mapRoomsToSelectItems(rooms)} onConfirm={async (selectedItems) => { if (!onDownload) return; try { await onDownload(selectedItems); } catch (e) { console.error("Download error:", e); } finally { setDialogOpen(false); setDialogType(null); setTimeout(() => window.location.reload(), 500); } }} /> )} {/* Dialog tải file - tìm thiết bị */} {dialogType === "download-device" && ( { setDialogOpen(false); setDialogType(null); setTimeout(() => window.location.reload(), 500); }} rooms={rooms} fetchDevices={getDeviceFromRoom} onSelect={async (deviceIds) => { if (!onDownload) { setDialogOpen(false); setDialogType(null); return; } try { await onDownload(deviceIds); } catch (e) { console.error("Download error:", e); } finally { setDialogOpen(false); setDialogType(null); setTimeout(() => window.location.reload(), 500); } }} /> )}
); }