
added confirmations on schedule DELETE!!! better reports page; log every delete over API, more logging;
189 lines
10 KiB
TypeScript
189 lines
10 KiB
TypeScript
//page to show all repots in the database with a link to the report page
|
||
import axiosInstance from '../../../src/axiosSecure';
|
||
import { useEffect, useState } from "react";
|
||
import toast from "react-hot-toast";
|
||
import { useRouter } from "next/router";
|
||
import Link from "next/link";
|
||
import { useSession } from "next-auth/react"
|
||
//const common = require('src/helpers/common');
|
||
import common from '../../../src/helpers/common';
|
||
import Layout from "../../../components/layout";
|
||
import ProtectedRoute from '../../../components/protectedRoute';
|
||
import { Location, UserRole, ReportType } from "@prisma/client";
|
||
|
||
|
||
export default function Reports() {
|
||
const [reports, setReports] = useState([]);
|
||
const [filteredReports, setFilteredReports] = useState([]);
|
||
|
||
const router = useRouter();
|
||
const { data: session } = useSession();
|
||
|
||
const [filterType, setFilterType] = useState('ServiceReport');
|
||
|
||
const handleFilterChange = (event) => {
|
||
setFilterType(event.target.value);
|
||
console.log("event filter set to:" + event.target.value);
|
||
};
|
||
|
||
|
||
useEffect(() => {
|
||
const isFeedbackType = type => [
|
||
'Feedback_Problem',
|
||
'Feedback_Suggestion',
|
||
'Feedback'
|
||
].includes(type);
|
||
|
||
setFilteredReports(reports.filter(report =>
|
||
filterType === 'Feedback' ? isFeedbackType(report.type) : report.type === filterType
|
||
));
|
||
}, [reports, filterType]);
|
||
|
||
const deleteReport = (id) => {
|
||
axiosInstance
|
||
.delete(`/api/data/reports/${id}`)
|
||
.then((res) => {
|
||
toast.success("Успешно изтрит отчет");
|
||
// router.push("/cart/reports/list");
|
||
setReports(reports.filter(report => report.id !== id));
|
||
})
|
||
.catch((err) => {
|
||
console.log(err);
|
||
});
|
||
};
|
||
|
||
|
||
|
||
const [locations, setLocations] = useState([]);
|
||
useEffect(() => {
|
||
const fetchLocations = async () => {
|
||
try {
|
||
console.log("fetching locations");
|
||
const { data } = await axiosInstance.get("/api/data/locations");
|
||
setLocations(data);
|
||
console.log(data);
|
||
axiosInstance.get(`/api/data/reports?include=publisher,location,shift`)
|
||
.then((res) => {
|
||
// let reports = res.data;
|
||
// reports.forEach((report) => {
|
||
// report.location = data.find((loc) => loc.id === report.locationId);
|
||
// });
|
||
setReports(res.data);
|
||
})
|
||
.catch((err) => {
|
||
console.log(err);
|
||
});
|
||
} catch (error) {
|
||
console.error(error);
|
||
}
|
||
};
|
||
if (!locations.length) {
|
||
fetchLocations();
|
||
}
|
||
}, []);
|
||
return (
|
||
<Layout>
|
||
<ProtectedRoute allowedRoles={[UserRole.POWERUSER, UserRole.ADMIN]}>
|
||
|
||
<div className="h-5/6 grid place-items-start px-4 pt-8">
|
||
<div className="flex flex-col w-full px-4">
|
||
<h1 className="text-2xl font-bold text-center">Отчети</h1>
|
||
<Link href="/cart/reports/report">
|
||
<button className="mt-4 bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded">
|
||
Добави нов отчет
|
||
</button>
|
||
</Link>
|
||
<div className="flex gap-2 mb-4">
|
||
|
||
<label className={`cursor-pointer px-4 py-2 rounded-full ${filterType === 'ServiceReport' ? 'bg-blue-500 text-white' : 'bg-gray-200 text-gray-800'}`}>
|
||
<input type="radio" name="reportType" value="ServiceReport" checked={filterType === 'ServiceReport'} onChange={handleFilterChange} className="sr-only" />
|
||
Отчети
|
||
</label>
|
||
<label className={`cursor-pointer px-4 py-2 rounded-full ${filterType === 'Experience' ? 'bg-blue-500 text-white' : 'bg-gray-200 text-gray-800'}`}>
|
||
<input type="radio" name="reportType" value="Experience" checked={filterType === 'Experience'} onChange={handleFilterChange} className="sr-only" />
|
||
Случка
|
||
</label>
|
||
<label className={`cursor-pointer px-4 py-2 rounded-full ${filterType === 'Feedback' ? 'bg-blue-500 text-white' : 'bg-gray-200 text-gray-800'}`}>
|
||
<input type="radio" name="reportType" value="Feedback" checked={filterType === 'Feedback'} onChange={handleFilterChange} className="sr-only" />
|
||
Отзиви
|
||
</label>
|
||
</div>
|
||
<div className="mt-4 w-full overflow-x-auto">
|
||
<table className="w-full table-auto">
|
||
<thead>
|
||
<tr>
|
||
<th className="px-4 py-2 text-left">От</th>
|
||
<th className="px-4 py-2 text-left">Дата</th>
|
||
<th className="px-4 py-2 text-left" >Място</th>
|
||
<th className="px-4 py-2 text-left">Отчет</th>
|
||
<th className="px-4 py-2 text-left">Действия</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{filteredReports.map((report) => (
|
||
<tr key={report.id}>
|
||
<td className="border px-2 py-2">{report.publisher.firstName + " " + report.publisher.lastName}</td>
|
||
<td className="border px-2 py-2">{common.getDateFormated(new Date(report.date))}
|
||
{report.type === ReportType.ServiceReport ? (report.shift ? " от " + common.getTimeFormatted(report.shift?.startTime) + " ч." : "") : common.getTimeFormatted(report.date)}
|
||
</td>
|
||
<td className="border px-2 py-2">{report.location?.name}
|
||
{report.type === ReportType.ServiceReport ? (report.shift ? "" : "за целия ден") : report.comments}
|
||
</td>
|
||
<td className="border px-2 py-2">
|
||
{(report.type === ReportType.ServiceReport)
|
||
? (
|
||
<>
|
||
<div><strong>Отчет</strong></div>
|
||
Издания: {report.placementCount} <br />
|
||
Разговори: {report.conversationCount} <br />
|
||
Клипове: {report.videoCount} <br />
|
||
Адреси / Телефони: {report.returnVisitInfoCount} <br />
|
||
</>
|
||
) : (report.type === ReportType.Feedback || report.type === ReportType.Feedback_Problem || report.type === ReportType.Feedback_Suggestion) ? (
|
||
<>
|
||
<div>
|
||
<strong style={{ fontWeight: 'bold' }}>Отзив</strong>
|
||
{report.type === "Feedback_Problem" ?
|
||
<span style={{ color: 'red', fontWeight: 'bold' }}> - Проблем</span> :
|
||
report.type === "Feedback_Suggestion" ?
|
||
<span style={{ color: 'blue' }}> - Предложение</span> :
|
||
""}
|
||
</div>
|
||
<div style={{ maxHeight: '960px', maxWidth: '960px', overflow: 'auto' }}>
|
||
<div dangerouslySetInnerHTML={{ __html: report.experienceInfo }} />
|
||
</div>
|
||
</>
|
||
) : (
|
||
<>
|
||
<div><strong>Случка</strong></div>
|
||
<div style={{ maxHeight: '960px', maxWidth: '960px', overflow: 'auto' }}>
|
||
<div dangerouslySetInnerHTML={{ __html: report.experienceInfo }} />
|
||
</div>
|
||
</>
|
||
)
|
||
|
||
}
|
||
</td>
|
||
<td className="border px-4 py-2">
|
||
|
||
<button
|
||
className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded"
|
||
onClick={() => deleteReport(report.id)}
|
||
>
|
||
Изтрий
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
))}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div >
|
||
</div >
|
||
</ProtectedRoute >
|
||
</Layout >
|
||
);
|
||
}
|
||
|
||
|