import React, { useState } from "react"; import { IconButton, Box, Typography, Tooltip, TextField, FormControl, InputLabel, Select, MenuItem, SelectChangeEvent, } from "@mui/material"; import DeleteIcon from "@mui/icons-material/Delete"; import SelectAllIcon from "@mui/icons-material/SelectAll"; import DownloadIcon from "@mui/icons-material/Download"; import StarIcon from "@mui/icons-material/Star"; import { useRouter } from "next/router"; import { Favorites, JobQueue } from "./jobs"; import { Job } from "../types"; interface JobTableProps { jobs: Job[]; fetchJobs: () => void; } interface ColorMap { [key: string]: string; } const COLOR_MAP: ColorMap = { Queued: "rgba(255,201,5,0.25)", Scraping: "rgba(3,104,255,0.25)", Completed: "rgba(5,255,51,0.25)", }; const JobTable: React.FC = ({ jobs, fetchJobs }) => { const [selectedJobs, setSelectedJobs] = useState>(new Set()); const [allSelected, setAllSelected] = useState(false); const [searchQuery, setSearchQuery] = useState(""); const [searchMode, setSearchMode] = useState("url"); const [favoriteView, setFavoriteView] = useState(false); const router = useRouter(); const handleDownload = async (ids: string[]) => { const response = await fetch("/api/download", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ ids: ids }), }); if (response.ok) { const blob = await response.blob(); const url = window.URL.createObjectURL(blob); const a = document.createElement("a"); a.style.display = "none"; a.href = url; a.download = `job_${ids.splice(0, 1)}.xlsx`; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); } else { console.error("Failed to download the file."); } }; const handleNavigate = (elements: Object[], url: string, options: any) => { router.push({ pathname: "/", query: { elements: JSON.stringify(elements), url: url, job_options: JSON.stringify(options), }, }); }; const handleSelectJob = (id: string) => { setSelectedJobs((prevSelected) => { const newSelected = new Set(prevSelected); if (newSelected.has(id)) { newSelected.delete(id); } else { newSelected.add(id); } return newSelected; }); }; const handleSelectAll = () => { if (allSelected) { setSelectedJobs(new Set()); } else { const allJobIds = new Set(jobs.map((job) => job.id)); setSelectedJobs(allJobIds); } setAllSelected(!allSelected); }; const handleDeleteSelected = async () => { const response = await fetch("/api/delete-scrape-jobs", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ ids: Array.from(selectedJobs) }), }); if (response.ok) { fetchJobs(); setSelectedJobs(new Set()); } }; const filteredJobs = jobs.filter((job) => { if (searchMode === "url") { return job.url.toLowerCase().includes(searchQuery.toLowerCase()); } else if (searchMode === "id") { return job.id.toLowerCase().includes(searchQuery.toLowerCase()); } else if (searchMode === "status") { return job.status.toLowerCase().includes(searchQuery.toLowerCase()); } return true; }); const favoriteJob = async (ids: string[], field: string, value: any) => { const postBody = { ids: ids, field: field, value: value, }; await fetch("/api/update", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(postBody), }); await fetchJobs(); }; return (
Scrape Jobs handleDownload(Array.from(selectedJobs))} disabled={selectedJobs.size === 0} > setFavoriteView(!favoriteView)} >
setSearchQuery(e.target.value)} className="w-3/4" /> Search Mode
{!favoriteView ? ( ) : ( )}
); }; export default JobTable;