Merge branch 'production'
This commit is contained in:
1
.env
1
.env
@ -8,6 +8,7 @@ NEXTAUTH_SECRET=ed8a9681efc414df89dfd03cd188ed58
|
|||||||
|
|
||||||
NODE_ENV=development
|
NODE_ENV=development
|
||||||
# mysql
|
# mysql
|
||||||
|
DATABASE=mysql://cart:cartpw@localhost:3306/cart
|
||||||
|
|
||||||
# // owner: dobromir.popov@gmail.com | Специално Свидетелстване София
|
# // owner: dobromir.popov@gmail.com | Специално Свидетелстване София
|
||||||
# // https://console.cloud.google.com/apis/credentials/oauthclient/926212607479-d3m8hm8f8esp3rf1639prskn445sa01v.apps.googleusercontent.com?project=grand-forge-108716
|
# // https://console.cloud.google.com/apis/credentials/oauthclient/926212607479-d3m8hm8f8esp3rf1639prskn445sa01v.apps.googleusercontent.com?project=grand-forge-108716
|
||||||
|
@ -4,7 +4,7 @@ import { toast } from 'react-toastify';
|
|||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import DayOfWeek from "../DayOfWeek";
|
import DayOfWeek from "../DayOfWeek";
|
||||||
import { Location, UserRole } from "@prisma/client";
|
import { ReportType } from "@prisma/client";
|
||||||
const common = require('src/helpers/common');
|
const common = require('src/helpers/common');
|
||||||
|
|
||||||
import { useSession } from "next-auth/react"
|
import { useSession } from "next-auth/react"
|
||||||
@ -97,6 +97,7 @@ export default function ExperienceForm({ publisherId, assgnmentId, existingItem,
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
item.publisher = { connect: { id: pubId } };
|
item.publisher = { connect: { id: pubId } };
|
||||||
item.location = { connect: { id: parseInt(item.locationId) } };
|
item.location = { connect: { id: parseInt(item.locationId) } };
|
||||||
|
item.type = ReportType.Experience;
|
||||||
delete item.locationId;
|
delete item.locationId;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -4,7 +4,7 @@ import { toast } from 'react-toastify';
|
|||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import DayOfWeek from "../DayOfWeek";
|
import DayOfWeek from "../DayOfWeek";
|
||||||
import { Location, UserRole } from "@prisma/client";
|
import { ReportType } from "@prisma/client";
|
||||||
const common = require('src/helpers/common');
|
const common = require('src/helpers/common');
|
||||||
|
|
||||||
import { useSession } from "next-auth/react"
|
import { useSession } from "next-auth/react"
|
||||||
@ -55,7 +55,7 @@ export default function FeedbackForm({ publisherId, onDone }) {
|
|||||||
assignmentId: 0,
|
assignmentId: 0,
|
||||||
publisherId: publisherId,
|
publisherId: publisherId,
|
||||||
date: new Date(),
|
date: new Date(),
|
||||||
placementCount: 0,
|
placementCount: 1,
|
||||||
videoCount: 0,
|
videoCount: 0,
|
||||||
returnVisitInfoCount: 0,
|
returnVisitInfoCount: 0,
|
||||||
conversationCount: 0
|
conversationCount: 0
|
||||||
@ -73,6 +73,8 @@ export default function FeedbackForm({ publisherId, onDone }) {
|
|||||||
const handleSubmit = async (e) => {
|
const handleSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
item.publisher = { connect: { id: pubId } };
|
item.publisher = { connect: { id: pubId } };
|
||||||
|
//ToDo: create dedicated feedback type instead of using placementCount for subtype
|
||||||
|
item.type = item.placementCount === 1 ? ReportType.Feedback_Problem : (item.placementCount === 2 ? ReportType.Feedback_Suggestion : ReportType.Feedback);
|
||||||
delete item.assignmentId;
|
delete item.assignmentId;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -4,6 +4,7 @@ import { toast } from "react-hot-toast";
|
|||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useSession } from "next-auth/react"
|
import { useSession } from "next-auth/react"
|
||||||
|
import { ReportType } from "@prisma/client";
|
||||||
|
|
||||||
const common = require('src/helpers/common');
|
const common = require('src/helpers/common');
|
||||||
|
|
||||||
@ -89,6 +90,7 @@ export default function ReportForm({ shiftId, existingItem, onDone }) {
|
|||||||
item.publisher = { connect: { id: publisherId } };
|
item.publisher = { connect: { id: publisherId } };
|
||||||
item.shift = { connect: { id: parseInt(item.shiftId) } };
|
item.shift = { connect: { id: parseInt(item.shiftId) } };
|
||||||
item.date = new Date(item.date);
|
item.date = new Date(item.date);
|
||||||
|
item.type = ReportType.Report;
|
||||||
delete item.publisherId;
|
delete item.publisherId;
|
||||||
delete item.shiftId;
|
delete item.shiftId;
|
||||||
item.placementCount = parseInt(item.placementCount);
|
item.placementCount = parseInt(item.placementCount);
|
||||||
|
@ -42,10 +42,10 @@ export const authOptions: NextAuthOptions = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
AppleProvider({
|
// AppleProvider({
|
||||||
clientId: process.env.APPLE_APP_ID,
|
// clientId: process.env.APPLE_APP_ID,
|
||||||
clientSecret: process.env.APPLE_SECRET
|
// clientSecret: process.env.APPLE_SECRET
|
||||||
}),
|
// }),
|
||||||
// AzureADProvider({
|
// AzureADProvider({
|
||||||
// clientId: process.env.AZURE_AD_CLIENT_ID,
|
// clientId: process.env.AZURE_AD_CLIENT_ID,
|
||||||
// clientSecret: process.env.AZURE_AD_CLIENT_SECRET,
|
// clientSecret: process.env.AZURE_AD_CLIENT_SECRET,
|
||||||
|
@ -9,16 +9,35 @@ import { useSession } from "next-auth/react"
|
|||||||
import common from '../../../src/helpers/common';
|
import common from '../../../src/helpers/common';
|
||||||
import Layout from "../../../components/layout";
|
import Layout from "../../../components/layout";
|
||||||
import ProtectedRoute from '../../../components/protectedRoute';
|
import ProtectedRoute from '../../../components/protectedRoute';
|
||||||
import { Location, UserRole } from "@prisma/client";
|
import { Location, UserRole, ReportType } from "@prisma/client";
|
||||||
|
|
||||||
|
|
||||||
export default function Reports() {
|
export default function Reports() {
|
||||||
const [reports, setReports] = useState([]);
|
const [reports, setReports] = useState([]);
|
||||||
|
const [filteredReports, setFilteredReports] = useState([]);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { data: session } = useSession();
|
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) => {
|
const deleteReport = (id) => {
|
||||||
axiosInstance
|
axiosInstance
|
||||||
@ -66,7 +85,7 @@ export default function Reports() {
|
|||||||
<Layout>
|
<Layout>
|
||||||
<ProtectedRoute allowedRoles={[UserRole.POWERUSER, UserRole.ADMIN, UserRole.USER, UserRole.EXTERNAL]}>
|
<ProtectedRoute allowedRoles={[UserRole.POWERUSER, UserRole.ADMIN, UserRole.USER, UserRole.EXTERNAL]}>
|
||||||
|
|
||||||
<div className="h-5/6 grid place-items-center">
|
<div className="h-5/6 grid place-items-start px-4 pt-8">
|
||||||
<div className="flex flex-col w-full px-4">
|
<div className="flex flex-col w-full px-4">
|
||||||
<h1 className="text-2xl font-bold text-center">Отчети</h1>
|
<h1 className="text-2xl font-bold text-center">Отчети</h1>
|
||||||
<Link href="/cart/reports/report">
|
<Link href="/cart/reports/report">
|
||||||
@ -74,18 +93,21 @@ export default function Reports() {
|
|||||||
Добави нов отчет
|
Добави нов отчет
|
||||||
</button>
|
</button>
|
||||||
</Link>
|
</Link>
|
||||||
<label className="mr-4">
|
<div className="flex gap-2 mb-4">
|
||||||
<input type="radio" name="reportType" value="ServiceReport" defaultChecked />
|
|
||||||
Отчети
|
<label className={`cursor-pointer px-4 py-2 rounded-full ${filterType === 'ServiceReport' ? 'bg-blue-500 text-white' : 'bg-gray-200 text-gray-800'}`}>
|
||||||
</label>
|
<input type="radio" name="reportType" value="ServiceReport" checked={filterType === 'ServiceReport'} onChange={handleFilterChange} className="sr-only" />
|
||||||
<label className="mr-4">
|
Отчети
|
||||||
<input type="radio" name="reportType" value="Experience" />
|
</label>
|
||||||
Случка
|
<label className={`cursor-pointer px-4 py-2 rounded-full ${filterType === 'Experience' ? 'bg-blue-500 text-white' : 'bg-gray-200 text-gray-800'}`}>
|
||||||
</label>
|
<input type="radio" name="reportType" value="Experience" checked={filterType === 'Experience'} onChange={handleFilterChange} className="sr-only" />
|
||||||
<label className="mr-4">
|
Случка
|
||||||
<input type="radio" name="reportType" value="Feedback" />
|
</label>
|
||||||
Отзиви
|
<label className={`cursor-pointer px-4 py-2 rounded-full ${filterType === 'Feedback' ? 'bg-blue-500 text-white' : 'bg-gray-200 text-gray-800'}`}>
|
||||||
</label>
|
<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">
|
<div className="mt-4 w-full overflow-x-auto">
|
||||||
<table className="w-full table-auto">
|
<table className="w-full table-auto">
|
||||||
<thead>
|
<thead>
|
||||||
@ -98,13 +120,13 @@ export default function Reports() {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{reports.map((report) => (
|
{filteredReports.map((report) => (
|
||||||
<tr key={report.id}>
|
<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">{report.publisher.firstName + " " + report.publisher.lastName}</td>
|
||||||
<td className="border px-2 py-2">{common.getDateFormated(new Date(report.date))}</td>
|
<td className="border px-2 py-2">{common.getDateFormated(new Date(report.date))}</td>
|
||||||
<td className="border px-2 py-2">{report.location?.name}</td>
|
<td className="border px-2 py-2">{report.location?.name}</td>
|
||||||
<td className="border px-2 py-2">
|
<td className="border px-2 py-2">
|
||||||
{(report.experienceInfo === null || report.experienceInfo === "")
|
{(report.type === ReportType.ServiceReport)
|
||||||
? (
|
? (
|
||||||
<>
|
<>
|
||||||
<div><strong>Отчет</strong></div>
|
<div><strong>Отчет</strong></div>
|
||||||
@ -113,9 +135,16 @@ export default function Reports() {
|
|||||||
Клипове: {report.videoCount} <br />
|
Клипове: {report.videoCount} <br />
|
||||||
Адреси / Телефони: {report.returnVisitInfoCount} <br />
|
Адреси / Телефони: {report.returnVisitInfoCount} <br />
|
||||||
</>
|
</>
|
||||||
) : (report.placementCount > 0) ? (
|
) : (report.type === ReportType.Feedback || report.type === ReportType.Feedback_Problem || report.type === ReportType.Feedback_Suggestion) ? (
|
||||||
<>
|
<>
|
||||||
<div><strong>Отзив</strong></div>
|
<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 dangerouslySetInnerHTML={{ __html: report.experienceInfo }} />
|
<div dangerouslySetInnerHTML={{ __html: report.experienceInfo }} />
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE `EventLog` (
|
||||||
|
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||||
|
`date` DATETIME(3) NOT NULL,
|
||||||
|
`publisherId` VARCHAR(191) NULL,
|
||||||
|
`shiftId` INTEGER NULL,
|
||||||
|
`content` VARCHAR(191) NOT NULL,
|
||||||
|
`type` ENUM('AssignnementReplacementRequested', 'AssignnementReplacement', 'SentEmail') NOT NULL,
|
||||||
|
|
||||||
|
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE `EventLog`
|
||||||
|
ADD CONSTRAINT `EventLog_publisherId_fkey` FOREIGN KEY (`publisherId`) REFERENCES `Publisher` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE `EventLog`
|
||||||
|
ADD CONSTRAINT `EventLog_shiftId_fkey` FOREIGN KEY (`shiftId`) REFERENCES `Shift` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
@ -121,6 +121,7 @@ model Publisher {
|
|||||||
comments String?
|
comments String?
|
||||||
reports Report[]
|
reports Report[]
|
||||||
Message Message[]
|
Message Message[]
|
||||||
|
EventLog EventLog[]
|
||||||
}
|
}
|
||||||
|
|
||||||
model Availability {
|
model Availability {
|
||||||
@ -179,6 +180,7 @@ model Shift {
|
|||||||
reportId Int? @unique
|
reportId Int? @unique
|
||||||
Report Report? @relation(fields: [reportId], references: [id])
|
Report Report? @relation(fields: [reportId], references: [id])
|
||||||
isPublished Boolean @default(false) //NEW v1.0.1
|
isPublished Boolean @default(false) //NEW v1.0.1
|
||||||
|
EventLog EventLog[]
|
||||||
|
|
||||||
@@map("Shift")
|
@@map("Shift")
|
||||||
}
|
}
|
||||||
@ -256,6 +258,23 @@ model Message {
|
|||||||
type MessageType @default(Email)
|
type MessageType @default(Email)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum EventLogType {
|
||||||
|
AssignnementReplacementRequested
|
||||||
|
AssignnementReplacement
|
||||||
|
SentEmail
|
||||||
|
}
|
||||||
|
|
||||||
|
model EventLog {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
date DateTime
|
||||||
|
publisherId String?
|
||||||
|
publisher Publisher? @relation(fields: [publisherId], references: [id])
|
||||||
|
shiftId Int?
|
||||||
|
shift Shift? @relation(fields: [shiftId], references: [id])
|
||||||
|
content String
|
||||||
|
type EventLogType
|
||||||
|
}
|
||||||
|
|
||||||
//user auth and session management
|
//user auth and session management
|
||||||
model User {
|
model User {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
|
Reference in New Issue
Block a user