Merge branch 'production'

This commit is contained in:
Dobromir Popov
2024-04-27 01:39:51 +03:00
7 changed files with 99 additions and 74 deletions

View File

@ -228,3 +228,8 @@ last login. pubs.
otchet - za denq otchet - za denq
делете цонфирм делете цонфирм
статистика - фкс (янка) + posledno vlizane статистика - фкс (янка) + posledno vlizane
заместник, предпочитание в миналото - да не може.
Да иска потвърждение преди да заместиш някой
да не се виждат непубликуваните смени в Моите смени
да не се виждат старите предпочитания ако не си админ в публишерс

View File

@ -286,7 +286,7 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o
const slots = []; const slots = [];
let currentTime = start; let currentTime = start;
const baseDate = new Date(2000, 0, 1); // Use a constant date for all time comparisons const baseDate = new Date(Date.UTC(2000, 0, 1, 0, 0, 0));
while (isBefore(currentTime, end)) { while (isBefore(currentTime, end)) {
let slotStart = normalizeTime(currentTime, baseDate); let slotStart = normalizeTime(currentTime, baseDate);

View File

@ -9,6 +9,7 @@ const common = require('src/helpers/common');
import AvailabilityForm from "../availability/AvailabilityForm"; import AvailabilityForm from "../availability/AvailabilityForm";
import { TrashIcon, PencilSquareIcon } from "@heroicons/react/24/outline"; import { TrashIcon, PencilSquareIcon } from "@heroicons/react/24/outline";
import { Availability, AvailabilityType } from "@prisma/client";
@ -58,7 +59,10 @@ export default function AvailabilityList({ publisher, showNew }) {
{items?.sort((a, b) => new Date(a.startTime) - new Date(b.startTime)).map(item => ( {items?.sort((a, b) => new Date(a.startTime) - new Date(b.startTime)).map(item => (
<tr key={item.id} availability={item} disabled={!item.isActive} className={`${item.isFromPreviousMonth ? 'bg-yellow-200' : ''} ${!item.isActive ? 'opacity-50' : ''}`}> <tr key={item.id} availability={item} disabled={!item.isActive} className={`${item.isFromPreviousMonth ? 'bg-yellow-200' : ''} ${!item.isActive ? 'opacity-50' : ''}`}>
<td className="px-6 py-4 whitespace-nowrap"> <td className="px-6 py-4 whitespace-nowrap">
{item.dayOfMonth ? `${common.getDateFormated(new Date(item.startTime))}` : `Всеки(Всяка) ${common.getDayOfWeekName(new Date(item.startTime))}`} {item.type == AvailabilityType.OneTime ? `${common.getDateFormated(new Date(item.startTime))}` :
item.type == AvailabilityType.Weekly ? `Всеки(Всяка) ${common.getDayOfWeekName(new Date(item.startTime))}` : "месечно"
}
{/* {common.getDateFormated(new Date(item.startTime))} */} {/* {common.getDateFormated(new Date(item.startTime))} */}
</td> </td>
<td className="px-6 py-4 whitespace-nowrap"> <td className="px-6 py-4 whitespace-nowrap">
@ -118,14 +122,14 @@ export default function AvailabilityList({ publisher, showNew }) {
} }
export const getServerSideProps = async () => { // export const getServerSideProps = async () => {
const { data: items } = await axiosInstance.get( // const { data: items } = await axiosInstance.get(
common.getBaseUrl("/api/data/availabilities") // common.getBaseUrl("/api/data/availabilities")
); // );
return { // return {
props: { // props: {
items, // items,
}, // },
}; // };
}; // };

View File

@ -211,7 +211,7 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
if (!start || !end) return; if (!start || !end) return;
//readonly for past dates (ToDo: if not admin) //readonly for past dates (ToDo: if not admin)
//if (startdate < new Date() || end < new Date() || startdate > end) return; if (startdate < new Date() || end < new Date() || startdate > end) return;
// Check if start and end are on the same day // Check if start and end are on the same day
if (startdate.toDateString() !== enddate.toDateString()) { if (startdate.toDateString() !== enddate.toDateString()) {
@ -275,6 +275,7 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
}; };
// REDRAW (PAGING) STYLES FOR THE EVENT DEFINED HERE
const eventStyleGetter = (event, start, end, isSelected) => { const eventStyleGetter = (event, start, end, isSelected) => {
//console.log("eventStyleGetter: " + event); //console.log("eventStyleGetter: " + event);
@ -296,10 +297,13 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
//gray //gray
backgroundColor = '#a0aec0'; backgroundColor = '#a0aec0';
} }
if (event.isActive) { if (event.isActive) {
switch (event.type) { switch (event.type) {
case 'assignment': case 'assignment':
backgroundColor = event.isConfirmed ? '#48bb78' : '#f6e05e'; // green-500 and yellow-300 from Tailwind CSS // backgroundColor = '#48bb78' // always green-500 as we don't pass isConfirmed correctly
//backgroundColor = event.isConfirmed ? '#48bb78' : '#f6e05e'; // green-500 and yellow-300 from Tailwind CSS
break; break;
case 'recurring': case 'recurring':
backgroundColor = '#63b3ed'; // blue-300 from Tailwind CSS backgroundColor = '#63b3ed'; // blue-300 from Tailwind CSS
@ -315,7 +319,7 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
return { return {
style: { style: {
backgroundColor, backgroundColor,
opacity: 0.8, opacity: event.startTime < new Date() ? 0.5 : 1,
color: 'white', color: 'white',
border: '0px', border: '0px',
display: 'block', display: 'block',
@ -323,7 +327,7 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
}; };
} }
// Custom Components // INITIAL STYLE FOR THE EVENT DEFINED HERE
const EventWrapper = ({ event, style }) => { const EventWrapper = ({ event, style }) => {
const [isHovered, setIsHovered] = useState(false); const [isHovered, setIsHovered] = useState(false);
let eventStyle = { let eventStyle = {
@ -342,7 +346,7 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
// bgColor = "bg-orange-500"; // bgColor = "bg-orange-500";
// } // }
if (event.type === "assignment") { if (event.type === "assignment") {
bgColor = event.isBySystem ? "bg-red-500" : (event.isConfirmed ? "bg-green-500" : "bg-yellow-500"); bgColor = event.isBySystem ? "bg-red-500" : (event.isConfirmed || true ? "bg-green-500" : "bg-yellow-500");
//event.title = event.publisher.name; //ToDo: add other publishers names //event.title = event.publisher.name; //ToDo: add other publishers names
//event.title = common.getTimeFomatted(event.startTime) + " - " + common.getTimeFomatted(event.endTime); //event.title = common.getTimeFomatted(event.startTime) + " - " + common.getTimeFomatted(event.endTime);
@ -365,6 +369,7 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
} }
} }
eventStyle = { eventStyle = {
...style, ...style,
// backgroundColor: bgColorClass, // backgroundColor: bgColorClass,
@ -376,7 +381,9 @@ const AvCalendar = ({ publisherId, events, selectedDate }) => {
overflow: 'hidden', // Hide overflowed content overflow: 'hidden', // Hide overflowed content
textOverflow: 'ellipsis' // Add ellipsis to text that's too long to fit textOverflow: 'ellipsis' // Add ellipsis to text that's too long to fit
}; };
if (event.date < new Date()) {
eventStyle.opacity = 0.5;
}
} }
const onDelete = (event) => { const onDelete = (event) => {

View File

@ -2,7 +2,7 @@ import axiosServer from '../../../../src/axiosServer';
import NewPubPage from "../new"; import NewPubPage from "../new";
export default NewPubPage; export default NewPubPage;
import { Assignment, Shift, UserRole } from "prisma/prisma-client"; import { Assignment, Shift, UserRole, AvailabilityType } from "prisma/prisma-client";
// import { monthNamesBG } from "~/src/helpers/const" // import { monthNamesBG } from "~/src/helpers/const"
import { monthNamesBG } from "src/helpers/const"; import { monthNamesBG } from "src/helpers/const";
@ -55,6 +55,7 @@ export const getServerSideProps = async (context) => {
// item.availabilities = item.availabilities // item.availabilities = item.availabilities
// .sort((a, b) => b.startTime - a.startTime); // .sort((a, b) => b.startTime - a.startTime);
item.availabilities = item.availabilities.filter((a) => new Date(a.startTime) >= new Date() || a.type == AvailabilityType.Weekly);
item.assignments = item.assignments item.assignments = item.assignments
.sort((a, b) => b.startTime - a.startTime) .sort((a, b) => b.startTime - a.startTime)
.reduce((acc, assignment: Assignment) => { .reduce((acc, assignment: Assignment) => {

View File

@ -87,30 +87,33 @@ export default function MySchedulePage({ assignments }) {
)} )}
</dd> </dd>
</div> </div>
<div className="bg-gray-50 px-4 py-5 grid grid-cols-1 sm:grid-cols-3 gap-4 xs:gap-1 px-6 xs:py-1"> {!assignment.isOld &&
<dt className="text-sm font-medium text-gray-500">Действия</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<button
className="mr-2 mb-2 inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 disabled"
disabled={true}
// disabled={assignment.isInGoogleCalendar}
onClick={() => SaveEventsInGoogleCalendar(assignment)}
>
Добави в календар
</button>
<button
className="mr-2 mb-2 inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
onClick={() => {
setАssignment(assignment);
setIsModalOpen(true)
}}
>
Избери Заместник
</button>
<SearchReplacement shiftId={assignment.shift.id} assignmentId={assignment.id} /> <div className="bg-gray-50 px-4 py-5 grid grid-cols-1 sm:grid-cols-3 gap-4 xs:gap-1 px-6 xs:py-1">
</dd> <dt className="text-sm font-medium text-gray-500">Действия</dt>
</div> <dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
<button
className="mr-2 mb-2 inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 disabled"
disabled={true}
// disabled={assignment.isInGoogleCalendar}
onClick={() => SaveEventsInGoogleCalendar(assignment)}
>
Добави в календар
</button>
<button
className="mr-2 mb-2 inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
onClick={() => {
setАssignment(assignment);
setIsModalOpen(true)
}}
>
Избери Заместник
</button>
<SearchReplacement shiftId={assignment.shift.id} assignmentId={assignment.id} />
</dd>
</div>
}
</dl> </dl>
</div> </div>
</div> </div>
@ -205,22 +208,25 @@ export const getServerSideProps = async (context) => {
}, },
}); });
const assignments = publisher?.assignments.filter(assignment => assignment.shift.startTime >= lastSunday) || []; const assignments = publisher?.assignments.filter(a => a.shift.startTime >= lastSunday && a.shift.isPublished) || [];
const transformedAssignments = assignments?.map(assignment => {
if (assignment.shift && assignment.shift.startTime) { const transformedAssignments = assignments?.sort((a, b) => a.shift.startTime - b.shift.startTime)
return { .map(assignment => {
...assignment, if (assignment.shift && assignment.shift.startTime) {
dateStr: assignment.shift.startTime.toLocaleDateString("bg-BG", { day: "numeric", month: "long" }), return {
shift: { ...assignment,
...assignment.shift, isOld: assignment.shift.startTime < new Date(),
startTime: assignment.shift.startTime.toISOString(), dateStr: assignment.shift.startTime.toLocaleDateString("bg-BG", { day: "numeric", month: "long" }),
endTime: assignment.shift.endTime.toISOString(), shift: {
}, ...assignment.shift,
}; startTime: assignment.shift.startTime.toISOString(),
} endTime: assignment.shift.endTime.toISOString(),
return assignment; },
}); };
}
return assignment;
});

View File

@ -38,22 +38,24 @@ export default function NewPubPage(item: Publisher) {
//------------------pages\cart\publishers\edit\[id].tsx------------------ //------------------pages\cart\publishers\edit\[id].tsx------------------
export const getServerSideProps = async (context) => { // export const getServerSideProps = async (context) => {
const axios = await axiosServer(context); // const axios = await axiosServer(context);
context.res.setHeader("Cache-Control", "s-maxage=1, stale-while-revalidate"); // context.res.setHeader("Cache-Control", "s-maxage=1, stale-while-revalidate");
if (!context.query || !context.query.id) { // if (!context.query || !context.query.id) {
return { // return {
props: {} // props: {}
}; // };
} // }
var url = process.env.NEXT_PUBLIC_PUBLIC_URL + "/api/data/publishers/" + context.query.id + "?include=availabilities,shifts"; // var url = process.env.NEXT_PUBLIC_PUBLIC_URL + "/api/data/publishers/" + context.query.id + "?include=availabilities,shifts";
console.log("GET PUBLISHER FROM:" + url) // console.log("GET PUBLISHER FROM:" + url)
const { data } = await axios.get(url); // const { data } = await axios.get(url);
return { // //filter old availabilities
props: { // data.availabilities = data.availabilities.filter((a) => new Date(a.startTime) >= new Date());
data // return {
}, // props: {
}; // data
}; // },
// };
// };