diff --git a/components/ErrorBoundary.tsx b/components/ErrorBoundary.tsx index 4c62e98..2dbbd89 100644 --- a/components/ErrorBoundary.tsx +++ b/components/ErrorBoundary.tsx @@ -1,10 +1,14 @@ import React from 'react'; -const logger = require('../src/logger'); class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; + this.logger = null; + + if (typeof window === 'undefined') { + this.logger = require('../src/logger'); + } } static getDerivedStateFromError(error) { @@ -13,14 +17,16 @@ class ErrorBoundary extends React.Component { } componentDidCatch(error, info) { - // You can also log the error to an error reporting service + // Log the error to an error reporting service console.error(error, info); - logger.error(error, info); + if (this.logger) { + this.logger.error(`${error}: ${info.componentStack}`); + } } render() { if (this.state.hasError) { - // You can render any custom fallback UI + // Render any custom fallback UI return

Нещо се обърка при изтриването. Моля, опитай отново и се свържете с нас ако проблема продължи.

; } @@ -28,4 +34,4 @@ class ErrorBoundary extends React.Component { } } -export default ErrorBoundary; \ No newline at end of file +export default ErrorBoundary; diff --git a/components/layout.tsx b/components/layout.tsx index 77f1073..39d91c5 100644 --- a/components/layout.tsx +++ b/components/layout.tsx @@ -10,6 +10,7 @@ import Body from 'next/document' import { ToastContainer } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; import { set } from "date-fns" +import ErrorBoundary from "./ErrorBoundary"; export default function Layout({ children }) { const router = useRouter(); @@ -61,7 +62,9 @@ export default function Layout({ children }) {
- {children} + + {children} +
{/* Modal container */}
diff --git a/pages/api/index.ts b/pages/api/index.ts index f26e8cc..9b7a855 100644 --- a/pages/api/index.ts +++ b/pages/api/index.ts @@ -511,6 +511,7 @@ export async function getMonthlyStatistics(selectFields, filterDate) { export async function filterPublishersNew_Available(selectFields, filterDate, isExactTime = false, isForTheMonth = false, isWithStats = true, includeOldAvailabilities = false) { return dataHelper.filterPublishersNew(selectFields, filterDate, isExactTime, isForTheMonth, false, isWithStats, includeOldAvailabilities); + // async function filterPublishersNew(selectFields, filterDate, isExactTime = false, isForTheMonth = false, noEndDateFilter = false, isWithStats = true, includeOldAvailabilities = false, id = null, filterAvailabilitiesByDate = true) } // availabilites filter: diff --git a/pages/cart/publishers/stats.tsx b/pages/cart/publishers/stats.tsx index 0e10c77..6b9d615 100644 --- a/pages/cart/publishers/stats.tsx +++ b/pages/cart/publishers/stats.tsx @@ -324,10 +324,22 @@ export default ContactsPage; export const getServerSideProps = async (context) => { const allPublishers = await data.getAllPublishersWithStatisticsMonth(new Date()); - //merge first and last name + // Merge first and last name and serialize Date objects allPublishers.forEach(publisher => { publisher.name = `${publisher.firstName} ${publisher.lastName}`; + + if (publisher.currentMonthAvailability) { + publisher.currentMonthAvailability = publisher.currentMonthAvailability.map(availability => { + return { + ...availability, + startTime: availability.startTime instanceof Date ? availability.startTime.toISOString() : availability.startTime, + endTime: availability.endTime instanceof Date ? availability.endTime.toISOString() : availability.endTime, + dateOfEntry: availability.dateOfEntry instanceof Date ? availability.dateOfEntry.toISOString() : availability.dateOfEntry, + }; + }); + } }); + return { props: { allPublishers diff --git a/src/helpers/data.js b/src/helpers/data.js index 4713e0e..00aeeb5 100644 --- a/src/helpers/data.js +++ b/src/helpers/data.js @@ -390,43 +390,7 @@ async function filterPublishersNew(selectFields, filterDate, isExactTime = false ///console.log(`publishers: ${publishers.length}, WhereClause: ${JSON.stringify(whereClause)}`); - // include repeating weekly availabilities. generate occurrences for the month - // convert matching weekly availabilities to availabilities for the day to make further processing easier on the client. - publishers.forEach(pub => { - pub.availabilities = pub.availabilities.map(avail => { - if (avail.dayOfMonth == null) { - if (filterAvailabilitiesByDate && !isForTheMonth) { - // filter out repeating availabilities when on other day of week - if (filterTimeFrom) { - if (avail.dayofweek != dayOfWeekEnum) { - return null; - } - } - } - let newStart = new Date(filterDate); - newStart.setHours(avail.startTime.getHours(), avail.startTime.getMinutes(), 0, 0); - let newEnd = new Date(filterDate); - newEnd.setHours(avail.endTime.getHours(), avail.endTime.getMinutes(), 0, 0); - return { - ...avail, - startTime: newStart, - endTime: newEnd - } - } - else { - if (filterAvailabilitiesByDate && !isForTheMonth) { - if (avail.startTime >= filterTimeFrom && avail.startTime <= filterTimeTo) { - return avail; - } - return null; - } - return avail; - } - }) - .filter(avail => avail !== null); - }); - - + // ---------------------------------------------- statistics ---------------------------------------------- let currentWeekStart, currentWeekEnd; if (isWithStats) { @@ -494,8 +458,45 @@ async function filterPublishersNew(selectFields, filterDate, isExactTime = false return avail.startTime >= filterDate && avail.startTime <= filterTimeTo; }); } - }); + + // ---------------------------------------------- + // include repeating weekly availabilities. generate occurrences for the month + // convert matching weekly availabilities to availabilities for the day to make further processing easier on the client. + publishers.forEach(pub => { + pub.availabilities = pub.availabilities.map(avail => { + if (avail.dayOfMonth == null) { + if (filterAvailabilitiesByDate && !isForTheMonth) { + // filter out repeating availabilities when on other day of week + if (filterTimeFrom) { + if (avail.dayofweek != dayOfWeekEnum) { + return null; + } + } + } + let newStart = new Date(filterDate); + newStart.setHours(avail.startTime.getHours(), avail.startTime.getMinutes(), 0, 0); + let newEnd = new Date(filterDate); + newEnd.setHours(avail.endTime.getHours(), avail.endTime.getMinutes(), 0, 0); + return { + ...avail, + startTime: newStart, + endTime: newEnd + } + } + else { + if (filterAvailabilitiesByDate && !isForTheMonth) { + if (avail.startTime >= filterTimeFrom && avail.startTime <= filterTimeTo) { + return avail; + } + return null; + } + return avail; + } + }) + .filter(avail => avail !== null); + }); + // ToDo: test case/unit test // ToDo: check and validate the filtering and calculations if (isExactTime) { diff --git a/src/logger.js b/src/logger.js index 5cf11b9..5d951b0 100644 --- a/src/logger.js +++ b/src/logger.js @@ -1,11 +1,22 @@ const winston = require('winston'); require('winston-daily-rotate-file'); +const fs = require('fs'); +const path = require('path'); +// Define the logs directory path +const logDirectory = path.join(__dirname, '../logs'); + +// Ensure the logs directory exists +if (!fs.existsSync(logDirectory)) { + fs.mkdirSync(logDirectory); +} + +// Define the log configuration const logConfiguration = { - 'transports': [ + transports: [ new winston.transports.DailyRotateFile({ - filename: './logs/application-%DATE%.log', - datePattern: 'YYYY-MM-DD', // new file is created every hour: 'YYYY-MM-DD-HH' + filename: path.join(logDirectory, 'application-%DATE%.log'), + datePattern: 'YYYY-MM-DD', // new file is created every day zippedArchive: true, maxSize: '20m', maxFiles: '90d', @@ -20,6 +31,7 @@ const logConfiguration = { ) }; +// Create the logger const logger = winston.createLogger(logConfiguration); module.exports = logger;