Add assignment UI change in calendar

This commit is contained in:
Dobromir Popov
2024-06-28 19:47:59 +03:00
parent 8a52a2fa98
commit f8ae3d0072
6 changed files with 215 additions and 187 deletions

View File

@ -6,7 +6,7 @@ import e from 'express';
import ProtectedRoute from './protectedRoute';
import { UserRole } from '@prisma/client';
function PwaManager({ subs }) {
function PwaManager({ userId, subs }) {
//ToDo: for iOS, try to use apn? https://github.com/node-apn/node-apn/blob/master/doc/apn.markdown
const isSupported = () =>
'Notification' in window &&
@ -271,6 +271,37 @@ function PwaManager({ subs }) {
{ action: 'close', title: 'Затвори', icon: '❌' }]
})
});
/*
await fetch('/api/notify', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
id: pub.id,
message: "Тестово съобщение",
title: "Това е тестово съобщение от https://sofia.mwitnessing.com",
actions: [
{ action: 'OK', title: 'OK', icon: '✅' },
{ action: 'close', title: 'Затвори', icon: '❌' }
]
// actions: [
// {
// title: 'Open URL',
// action: 'open_url',
// icon: '/images/open-url.png'
// },
// {
// title: 'Dismiss',
// action: 'dismiss',
// icon: '/images/dismiss.png'
// }
// ]
})
})
*/
};
// async function sendTestReminder(event: MouseEvent<HTMLButtonElement, MouseEvent>): Promise<void> {
@ -382,7 +413,7 @@ function PwaManager({ subs }) {
>
Тестово уведомление
</button>
</div>
</div >
{isAdmin &&
<div>
{/* <button
@ -403,28 +434,31 @@ function PwaManager({ subs }) {
</button> */}
</div>
}
{notificationPermission !== "granted" && (
<button
onClick={togglePushNotifications}
className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out ${notificationPermission === "denied" ? 'bg-red-500 hover:bg-red-700 text-white' : 'bg-green-500 hover:bg-green-700 text-white'
}`}
>
{notificationPermission === "denied" ? 'Notifications Denied!' : 'Enable Notifications'}
</button>
)}
{
notificationPermission !== "granted" && (
<button
onClick={togglePushNotifications}
className={`text-xs py-1 px-2 rounded-full focus:outline-none transition duration-150 ease-in-out ${notificationPermission === "denied" ? 'bg-red-500 hover:bg-red-700 text-white' : 'bg-green-500 hover:bg-green-700 text-white'
}`}
>
{notificationPermission === "denied" ? 'Notifications Denied!' : 'Enable Notifications'}
</button>
)
}
{isAdmin && <div>
<div>
<a href="https://t.me/mwhitnessing_bot" className="inline-flex items-center ml-4" target="_blank">
<img src="/content/icons/telegram-svgrepo-com.svg" alt="Телеграм" width="32" height="32" className="align-middle" />
<span className="align-middle">Телеграм</span>
</a>
{
isAdmin && <div>
<div>
<a href="https://t.me/mwhitnessing_bot" className="inline-flex items-center ml-4" target="_blank">
<img src="/content/icons/telegram-svgrepo-com.svg" alt="Телеграм" width="32" height="32" className="align-middle" />
<span className="align-middle">Телеграм</span>
</a>
<a href="/api/auth/apple-signin" className="inline-flex items-center ml-4 bg-gray-100 button" target="_blank">
<span className="align-middle">Apple sign-in</span>
</a>
<a href="/api/auth/apple-signin" className="inline-flex items-center ml-4 bg-gray-100 button" target="_blank">
<span className="align-middle">Apple sign-in</span>
</a>
</div>
</div>
</div>
}
</>
);

View File

@ -303,7 +303,8 @@ export default function PublisherForm({ item, me }) {
{/* In-App notifications group */}
<div className="mb-4">
<h3 className="text-md font-semibold mb-2">Известия в приложението</h3>
<PwaManager />
<PwaManager userId={publisher.userId || session.user.id} />
</div>
</fieldset>
</div>

View File

@ -0,0 +1,128 @@
//Refactor ToDo: show the whole month instead of just the current week by showing the shift start time in front of the rows, and show all shifts in the month from the first to the last week in the cell where we show one shift now
function PublisherShiftsModal({ publisher, shifts, onClose }) {
const monthInfo = common.getMonthDatesInfo(new Date(value));
const monthShifts = shifts.filter(shift => {
const shiftDate = new Date(shift.startTime);
return shiftDate > monthInfo.firstDay && shiftDate < monthInfo.lastDay;
});
const weekShifts = monthShifts.filter(shift => {
const shiftDate = new Date(shift.startTime);
return common.getStartOfWeek(value) <= shiftDate && shiftDate <= common.getEndOfWeek(value);
});
const dayShifts = weekShifts.map(shift => {
const isAvailable = publisher.availabilities?.some(avail =>
avail.startTime <= shift.startTime && avail.endTime >= shift.endTime
);
let color = isAvailable ? getColorForShift(shift) : 'bg-gray-300';
if (shift.isFromPreviousMonth) {
color += ' border-l-4 border-orange-500 ';
}
if (shift.isFromPreviousAssignment) {
color += ' border-l-4 border-red-500 ';
}
return { ...shift, isAvailable, color };
}).reduce((acc, shift) => {
const dayIndex = new Date(shift.startTime).getDay();
acc[dayIndex] = acc[dayIndex] || [];
acc[dayIndex].push(shift);
return acc;
}, {});
console.log("dayShifts:", dayShifts);
const hasAssignment = (shiftId) => {
// return publisher.assignments.some(ass => ass.shift.id == shiftId);
return publisher.assignments?.some(ass => {
//console.log(`Comparing: ${ass.shift.id} to ${shiftId}: ${ass.shift.id === shiftId}`);
return ass.shift.id === shiftId;
});
};
useEffect(() => {
const handleKeyDown = (event) => {
if (event.key === 'Escape') {
console.log('ESC: closing modal.');
onClose(); // Call the onClose function when ESC key is pressed
}
};
// Add event listener
window.addEventListener('keydown', handleKeyDown);
// Remove event listener on cleanup
return () => {
window.removeEventListener('keydown', handleKeyDown);
};
}, [onClose]); // Include onClose in the dependency array
return (
<div className="fixed top-0 left-0 w-full h-full flex items-center justify-center bg-black bg-opacity-50 z-50">
<div className="relative bg-white p-8 rounded-lg shadow-xl max-w-xl w-full h-auto overflow-y-auto">
<h2 className="text-xl font-semibold mb-4">График на <span title={publisher.email} className='publisher'>
<strong>{publisher.firstName} {publisher.lastName}</strong>
<span className="publisher-tooltip" onClick={common.copyToClipboard}>{publisher.email}</span>
</span> тази седмица:</h2>
{/* ... Display shifts in a calendar-like UI ... */}
<div className="grid grid-cols-6 gap-4 mb-4">
{Object.entries(dayShifts).map(([dayIndex, shiftsForDay]) => (
<div key={dayIndex} className="flex flex-col space-y-2 justify-end">
{/* Day header */}
<div className="text-center font-medium">{new Date(shiftsForDay[0].startTime).getDate()}-ти</div>
{shiftsForDay.map((shift, index) => {
const assignmentExists = hasAssignment(shift.id);
const availability = publisher.availabilities.find(avail =>
avail.startTime <= shift.startTime && avail.endTime >= shift.endTime
);
const isFromPrevMonth = availability && availability.isFromPreviousMonth;
return (
<div
key={index}
className={`text-sm text-white p-2 rounded-md ${isFromPrevMonth ? 'border-l-6 border-black-500' : ''} ${shift.color} ${assignmentExists ? 'border-2 border-blue-500' : ""} h-24 flex flex-col justify-center`}
>
{common.getTimeRange(shift.startTime, shift.endTime)} {shift.id}
{!assignmentExists && shift.isAvailable && (
<button onClick={() => { addAssignment(publisher, shift.id); }}
className="mt-2 bg-green-500 text-white p-1 rounded hover:bg-green-600 active:bg-green-700 focus:outline-none"
>
добави
</button>
)}
{assignmentExists && (
<button onClick={() => { removeAssignment(publisher, shift.id) }} // Implement the removeAssignment function
className="mt-2 bg-red-500 text-white p-1 rounded hover:bg-red-600 active:bg-red-700 focus:outline-none"
>
махни
</button>
)}
</div>
);
}
)}
</div>
))}
</div>
{/* Close button in the top right corner */}
<button
onClick={onClose}
className="absolute top-3 right-2 p-2 px-3 bg-red-500 text-white rounded-full hover:bg-red-600 active:bg-red-700 focus:outline-none"
>
&times;
</button>
{/* <Link href={`/cart/publishers/edit/${modalPub.id}`}
className="mt-2 bg-blue-500 text-white p-1 rounded hover:bg-blue-600 active:bg-blue-700 focus:outline-none">
<i className="fas fa-edit" />
</Link> */}
{/* Edit button in the top right corner, next to the close button */}
<Link href={`/cart/publishers/edit/${modalPub.id}`} className="absolute top-3 right-12 p-2 bg-blue-500 text-white rounded-full hover:bg-blue-600 active:bg-blue-700 focus:outline-none">
<i className="fas fa-edit" />
</Link>
</div>
</div >
);
}