feat: create in app calendar #94

Merged
dominik merged 8 commits from feat/24-create_in_app_calendar into main 2025-06-26 20:35:01 +00:00
10 changed files with 1896 additions and 56 deletions

View file

@ -56,20 +56,25 @@
"next-auth": "^5.0.0-beta.25", "next-auth": "^5.0.0-beta.25",
"next-swagger-doc": "^0.4.1", "next-swagger-doc": "^0.4.1",
"next-themes": "^0.4.6", "next-themes": "^0.4.6",
"react": "^19.0.0", "react": "^19.1.0",
"react-big-calendar": "^1.18.0",
"react-datepicker": "^8.4.0",
"react-day-picker": "^9.7.0", "react-day-picker": "^9.7.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
"react-error-boundary": "^6.0.0",
"react-hook-form": "^7.56.4", "react-hook-form": "^7.56.4",
"sonner": "^2.0.5", "sonner": "^2.0.5",
"swagger-ui-react": "^5.24.1", "swagger-ui-react": "^5.24.1",
"tailwind-merge": "^3.2.0", "tailwind-merge": "^3.2.0",
"zod": "^3.25.60" "zod": "^3.25.60",
"zod-validation-error": "^3.5.2"
}, },
"devDependencies": { "devDependencies": {
"@eslint/eslintrc": "3.3.1", "@eslint/eslintrc": "3.3.1",
"@tailwindcss/postcss": "4.1.10", "@tailwindcss/postcss": "4.1.10",
"@types/node": "22.15.33", "@types/node": "22.15.33",
"@types/react": "19.1.8", "@types/react": "19.1.8",
"@types/react-big-calendar": "^1",
"@types/react-dom": "19.1.6", "@types/react-dom": "19.1.6",
"@types/swagger-ui-react": "5", "@types/swagger-ui-react": "5",
"@types/webpack-env": "1.18.8", "@types/webpack-env": "1.18.8",

View file

@ -1,22 +1,17 @@
'use client'; 'use client';
import { RedirectButton } from '@/components/buttons/redirect-button'; import Calendar from '@/components/calendar';
import { useGetApiUserMe } from '@/generated/api/user/user'; import { useGetApiUserMe } from '@/generated/api/user/user';
export default function Home() { export default function Home() {
const { data, isLoading } = useGetApiUserMe(); const { data } = useGetApiUserMe();
return ( return (
<div className='flex flex-col items-center justify-center h-full'> <div className='max-h-full'>
<div> <Calendar
<h1> userId={data?.data.user?.id}
Hello{' '} height='calc(100svh - 50px - (var(--spacing) * 2 * 5))'
{isLoading ? 'Loading...' : data?.data.user?.name || 'Unknown User'} />
</h1>
<RedirectButton redirectUrl='/logout' buttonText='Logout' />
<RedirectButton redirectUrl='/settings' buttonText='Settings' />
<RedirectButton redirectUrl='/events/new' buttonText='New Event' />
</div>
</div> </div>
); );
} }

View file

@ -136,15 +136,15 @@ export const GET = auth(async function GET(req, { params }) {
start_time: 'asc', start_time: 'asc',
}, },
select: { select: {
id: requestUserId === requestedUserId ? true : false, id: true,
reason: requestUserId === requestedUserId ? true : false, reason: true,
start_time: true, start_time: true,
end_time: true, end_time: true,
is_recurring: requestUserId === requestedUserId ? true : false, is_recurring: true,
recurrence_end_date: requestUserId === requestedUserId ? true : false, recurrence_end_date: true,
rrule: requestUserId === requestedUserId ? true : false, rrule: true,
created_at: requestUserId === requestedUserId ? true : false, created_at: true,
updated_at: requestUserId === requestedUserId ? true : false, updated_at: true,
}, },
}, },
}, },
@ -167,6 +167,7 @@ export const GET = auth(async function GET(req, { params }) {
calendar.push({ ...event.meeting, type: 'event' }); calendar.push({ ...event.meeting, type: 'event' });
} else { } else {
calendar.push({ calendar.push({
id: event.meeting.id,
start_time: event.meeting.start_time, start_time: event.meeting.start_time,
end_time: event.meeting.end_time, end_time: event.meeting.end_time,
type: 'blocked_private', type: 'blocked_private',
@ -182,6 +183,7 @@ export const GET = auth(async function GET(req, { params }) {
calendar.push({ ...event, type: 'event' }); calendar.push({ ...event, type: 'event' });
} else { } else {
calendar.push({ calendar.push({
id: event.id,
start_time: event.start_time, start_time: event.start_time,
end_time: event.end_time, end_time: event.end_time,
type: 'blocked_private', type: 'blocked_private',
@ -190,23 +192,35 @@ export const GET = auth(async function GET(req, { params }) {
} }
for (const slot of requestedUser.blockedSlots) { for (const slot of requestedUser.blockedSlots) {
calendar.push({ if (requestUserId === requestedUserId) {
start_time: slot.start_time, calendar.push({
end_time: slot.end_time, start_time: slot.start_time,
id: slot.id, end_time: slot.end_time,
reason: slot.reason, id: slot.id,
is_recurring: slot.is_recurring, reason: slot.reason,
recurrence_end_date: slot.recurrence_end_date, is_recurring: slot.is_recurring,
rrule: slot.rrule, recurrence_end_date: slot.recurrence_end_date,
created_at: slot.created_at, rrule: slot.rrule,
updated_at: slot.updated_at, created_at: slot.created_at,
type: updated_at: slot.updated_at,
requestUserId === requestedUserId ? 'blocked_owned' : 'blocked_private', type: 'blocked_owned',
}); });
} else {
calendar.push({
start_time: slot.start_time,
end_time: slot.end_time,
id: slot.id,
type: 'blocked_private',
});
}
} }
return returnZodTypeCheckedResponse(UserCalendarResponseSchema, { return returnZodTypeCheckedResponse(UserCalendarResponseSchema, {
success: true, success: true,
calendar, calendar: calendar.filter(
(event, index, self) =>
self.findIndex((e) => e.id === event.id && e.type === event.type) ===
index,
),
}); });
}); });

View file

@ -13,23 +13,28 @@ export const BlockedSlotSchema = zod
start_time: eventStartTimeSchema, start_time: eventStartTimeSchema,
end_time: eventEndTimeSchema, end_time: eventEndTimeSchema,
type: zod.literal('blocked_private'), type: zod.literal('blocked_private'),
id: zod.string(),
}) })
.openapi('BlockedSlotSchema', { .openapi('BlockedSlotSchema', {
description: 'Blocked time slot in the user calendar', description: 'Blocked time slot in the user calendar',
}); });
export const OwnedBlockedSlotSchema = BlockedSlotSchema.extend({ export const OwnedBlockedSlotSchema = zod
id: zod.string(), .object({
reason: zod.string().nullish(), start_time: eventStartTimeSchema,
is_recurring: zod.boolean().default(false), end_time: eventEndTimeSchema,
recurrence_end_date: zod.date().nullish(), id: zod.string(),
rrule: zod.string().nullish(), reason: zod.string().nullish(),
created_at: zod.date().nullish(), is_recurring: zod.boolean().default(false),
updated_at: zod.date().nullish(), recurrence_end_date: zod.date().nullish(),
type: zod.literal('blocked_owned'), rrule: zod.string().nullish(),
}).openapi('OwnedBlockedSlotSchema', { created_at: zod.date().nullish(),
description: 'Blocked slot owned by the user', updated_at: zod.date().nullish(),
}); type: zod.literal('blocked_owned'),
})
.openapi('OwnedBlockedSlotSchema', {
description: 'Blocked slot owned by the user',
});
export const VisibleSlotSchema = EventSchema.omit({ export const VisibleSlotSchema = EventSchema.omit({
organizer: true, organizer: true,

256
src/components/calendar.tsx Normal file
View file

@ -0,0 +1,256 @@
'use client';
import { Calendar as RBCalendar, momentLocalizer } from 'react-big-calendar';
import withDragAndDrop from 'react-big-calendar/lib/addons/dragAndDrop';
import moment from 'moment';
import '@/components/react-big-calendar.css';
import 'react-big-calendar/lib/addons/dragAndDrop/styles.css';
import CustomToolbar from '@/components/custom-toolbar';
import React from 'react';
import { useGetApiUserUserCalendar } from '@/generated/api/user/user';
import { useRouter } from 'next/navigation';
import { usePatchApiEventEventID } from '@/generated/api/event/event';
import { useSession } from 'next-auth/react';
import { UserCalendarSchemaItem } from '@/generated/api/meetup.schemas';
import { QueryErrorResetBoundary } from '@tanstack/react-query';
import { ErrorBoundary } from 'react-error-boundary';
import { Button } from '@/components/ui/button';
import { fromZodIssue } from 'zod-validation-error/v4';
import type { $ZodIssue } from 'zod/v4/core';
moment.updateLocale('en', {
week: {
dow: 1,
doy: 4,
},
});
const DaDRBCalendar = withDragAndDrop<
{
id: string;
start: Date;
end: Date;
type: UserCalendarSchemaItem['type'];
},
{
id: string;
title: string;
type: UserCalendarSchemaItem['type'];
}
>(RBCalendar);
const localizer = momentLocalizer(moment);
export default function Calendar({
userId,
height,
}: {
userId?: string;
height: string;
}) {
return (
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
fallbackRender={({ resetErrorBoundary, error }) => (
<div className='flex flex-col items-center justify-center h-full'>
There was an error!
<p className='text-red-500'>
{typeof error === 'string'
? error
: error.errors
.map((e: $ZodIssue) => fromZodIssue(e).toString())
.join(', ')}
</p>
<Button onClick={() => resetErrorBoundary()}>Try again</Button>
</div>
)}
>
{userId ? (
<CalendarWithUserEvents userId={userId} height={height} />
) : (
<CalendarWithoutUserEvents height={height} />
)}
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
);
}
function CalendarWithUserEvents({
userId,
height,
}: {
userId: string;
height: string;
}) {
const sesstion = useSession();
const [currentView, setCurrentView] = React.useState<
'month' | 'week' | 'day' | 'agenda' | 'work_week'
>('week');
const [currentDate, setCurrentDate] = React.useState<Date>(new Date());
const router = useRouter();
const { data, refetch, error, isError } = useGetApiUserUserCalendar(
userId,
{
start: moment(currentDate)
.startOf(
currentView === 'agenda'
? 'month'
: currentView === 'work_week'
? 'week'
: currentView,
)
.toISOString(),
end: moment(currentDate)
.endOf(
currentView === 'agenda'
? 'month'
: currentView === 'work_week'
? 'week'
: currentView,
)
.toISOString(),
},
{
query: {
refetchOnWindowFocus: true,
refetchOnReconnect: true,
refetchOnMount: true,
},
},
);
if (isError) {
throw error.response?.data || 'Failed to fetch calendar data';
}
const { mutate: patchEvent } = usePatchApiEventEventID({
mutation: {
throwOnError(error) {
throw error.response?.data || 'Failed to update event';
},
},
});
return (
<DaDRBCalendar
localizer={localizer}
culture='de-DE'
defaultView='week'
components={{
toolbar: CustomToolbar,
}}
style={{
height: height,
}}
onView={setCurrentView}
view={currentView}
date={currentDate}
onNavigate={(date) => {
setCurrentDate(date);
}}
events={
data?.data.calendar.map((event) => ({
id: event.id,
title: event.type === 'event' ? event.title : 'Blocker',
start: new Date(event.start_time),
end: new Date(event.end_time),
type: event.type,
})) ?? []
}
onSelectEvent={(event) => {
router.push(`/events/${event.id}`);
}}
onSelectSlot={(slotInfo) => {
router.push(
`/events/new?start=${slotInfo.start.toISOString()}&end=${slotInfo.end.toISOString()}`,
);
}}
resourceIdAccessor={(event) => event.id}
resourceTitleAccessor={(event) => event.title}
startAccessor={(event) => event.start}
endAccessor={(event) => event.end}
selectable={sesstion.data?.user?.id === userId}
onEventDrop={(event) => {
const { start, end, event: droppedEvent } = event;
if (droppedEvent.type === 'blocked_private') return;
const startISO = new Date(start).toISOString();
const endISO = new Date(end).toISOString();
patchEvent(
{
eventID: droppedEvent.id,
data: {
start_time: startISO,
end_time: endISO,
},
},
{
onSuccess: () => {
refetch();
},
onError: (error) => {
console.error('Error updating event:', error);
},
},
);
}}
onEventResize={(event) => {
const { start, end, event: resizedEvent } = event;
if (resizedEvent.type === 'blocked_private') return;
const startISO = new Date(start).toISOString();
const endISO = new Date(end).toISOString();
if (startISO === endISO) {
console.warn('Start and end times are the same, skipping resize.');
return;
}
patchEvent(
{
eventID: resizedEvent.id,
data: {
start_time: startISO,
end_time: endISO,
},
},
{
onSuccess: () => {
refetch();
},
onError: (error) => {
console.error('Error resizing event:', error);
},
},
);
}}
/>
);
}
function CalendarWithoutUserEvents({ height }: { height: string }) {
const [currentView, setCurrentView] = React.useState<
'month' | 'week' | 'day' | 'agenda' | 'work_week'
>('week');
const [currentDate, setCurrentDate] = React.useState<Date>(new Date());
return (
<DaDRBCalendar
localizer={localizer}
culture='de-DE'
defaultView='week'
style={{
height: height,
}}
components={{
toolbar: CustomToolbar,
}}
onView={setCurrentView}
view={currentView}
date={currentDate}
onNavigate={(date) => {
setCurrentDate(date);
}}
/>
);
}

View file

@ -0,0 +1,114 @@
/* Container der Toolbar */
.custom-toolbar {
display: flex;
flex-direction: column;
gap: 12px;
padding: calc(var(--spacing) * 2);
padding-left: calc(50px + var(--spacing));
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
/* Anzeige des aktuellen Datums (Monat und Jahr) */
.custom-toolbar .current-date {
font-weight: bold;
font-size: 12px;
text-align: center;
color: #ffffff;
background-color: #717171;
height: 37px;
border-radius: 11px;
}
/* Navigationsbereich (Today, Prev, Next) */
.custom-toolbar .navigation-controls {
display: flex;
gap: 8px;
justify-content: center;
}
.custom-toolbar .navigation-controls button {
padding: 8px 12px;
color: #ffffff;
border: none;
border-radius: 11px;
font-size: 12px;
cursor: pointer;
transition: background-color 0.2s;
}
.custom-toolbar .navigation-controls button:hover {
background-color: #1976d2;
}
.custom-toolbar .navigation-controls button:active {
background-color: #1565c0;
}
/* Dropdown-Bereich für Woche und Jahr */
.custom-toolbar .dropdowns {
display: flex;
gap: 8px;
justify-content: center;
height: 30px;
font-size: 10px;
margin-top: 3.5px;
border-radius: 11px;
}
.custom-toolbar .dropdowns select {
padding: 8px 12px;
border-radius: 11px;
font-size: 10px;
background-color: #555555;
color: #ffffff;
cursor: pointer;
transition: border-color 0.2s;
}
.custom-toolbar .dropdowns select:hover {
border-color: #999;
}
.right-section,
.view-switcher {
background-color: #717171;
height: 48px;
border-radius: 11px;
justify-items: center;
align-items: center;
}
.custom-toolbar .navigation-controls .handleWeek button {
background-color: #717171;
height: 30px;
width: 30px;
margin-bottom: 3.5px;
}
.view-change,
.right-section {
background-color: #717171;
height: 48px;
padding: 0 8px;
border-radius: 11px;
justify-items: center;
}
.right-section .datepicker-box {
color: #000000;
background-color: #c6c6c6;
height: 36px;
border-radius: 11px;
font-size: 12px;
align-self: center;
}
.datepicker {
text-align: center;
height: 30px;
}
.datepicker-box {
z-index: 5;
}

View file

@ -0,0 +1,260 @@
import React, { useState, useEffect } from 'react';
import './custom-toolbar.css';
import { Button } from '@/components/ui/button';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import { NavigateAction } from 'react-big-calendar';
interface CustomToolbarProps {
//Aktuell angezeigtes Datum
date: Date;
//Aktuelle Ansicht
view: 'month' | 'week' | 'day' | 'agenda' | 'work_week';
onNavigate: (action: NavigateAction, newDate?: Date) => void;
//Ansichtwechsel
onView: (newView: 'month' | 'week' | 'day' | 'agenda' | 'work_week') => void;
}
const CustomToolbar: React.FC<CustomToolbarProps> = ({
date,
view,
onNavigate,
onView,
}) => {
//ISO-Wochennummer eines Datums ermitteln
const getISOWeek = (date: Date): number => {
const tmp = new Date(date.getTime());
//Datum so verschieben, dass der nächste Donnerstag erreicht wird (ISO: Woche beginnt am Montag)
tmp.setDate(tmp.getDate() + 4 - (tmp.getDay() || 7));
const yearStart = new Date(tmp.getFullYear(), 0, 1);
const weekNo = Math.ceil(
((tmp.getTime() - yearStart.getTime()) / 86400000 + 1) / 7,
);
return weekNo;
};
//ISO-Wochenjahr eines Datums ermitteln
const getISOWeekYear = (date: Date): number => {
const tmp = new Date(date.getTime());
tmp.setDate(tmp.getDate() + 4 - (tmp.getDay() || 7));
return tmp.getFullYear();
};
//Ermittlung der Anzahl der Wochen im Jahr
const getISOWeeksInYear = (year: number): number => {
const d = new Date(year, 11, 31);
const week = getISOWeek(d);
return week === 1 ? getISOWeek(new Date(year, 11, 24)) : week;
};
const getDateOfISOWeek = (week: number, year: number): Date => {
const jan1 = new Date(year, 0, 1);
const dayOfWeek = jan1.getDay();
const isoDayOfWeek = dayOfWeek === 0 ? 7 : dayOfWeek;
let firstMonday: Date;
if (isoDayOfWeek <= 4) {
//1. Januar gehört zur ersten ISO-Woche (Montag dieser Woche bestimmen)
firstMonday = new Date(year, 0, 1 - isoDayOfWeek + 1);
} else {
//Ansonsten liegt der erste Montag in der darauffolgenden Woche
firstMonday = new Date(year, 0, 1 + (8 - isoDayOfWeek));
}
firstMonday.setDate(firstMonday.getDate() + (week - 1) * 7);
return firstMonday;
};
//Lokaler State für Woche und ISO-Wochenjahr (statt des reinen Kalenderjahrs)
const [selectedWeek, setSelectedWeek] = useState<number>(getISOWeek(date));
const [selectedYear, setSelectedYear] = useState<number>(
getISOWeekYear(date),
);
//Auswahl aktualisieren, wenn sich die Prop "date" ändert
useEffect(() => {
setSelectedWeek(getISOWeek(date));
setSelectedYear(getISOWeekYear(date));
}, [date]);
//Start (Montag) und Ende (Sonntag) der aktuell angezeigten Woche berechnen
const weekStartDate = getDateOfISOWeek(selectedWeek, selectedYear);
const weekEndDate = new Date(weekStartDate);
weekEndDate.setDate(weekStartDate.getDate() + 6);
//Ansichtwechsel
const handleViewChange = (newView: 'month' | 'week' | 'day' | 'agenda') => {
onView(newView);
};
//Today-Button aktualisiert das Datum im DatePicker auf das heutige
const handleToday = () => {
const today = new Date();
setSelectedDate(today);
setSelectedWeek(getISOWeek(today));
setSelectedYear(getISOWeekYear(today));
onNavigate('TODAY', today);
};
//Pfeiltaste nach Vorne
const handleNext = () => {
let newDate: Date;
if (view === 'day' || view === 'agenda') {
newDate = new Date(date);
newDate.setDate(newDate.getDate() + 1);
} else if (view === 'week') {
let newWeek = selectedWeek + 1;
let newYear = selectedYear;
if (newWeek > getISOWeeksInYear(selectedYear)) {
newYear = selectedYear + 1;
newWeek = 1;
}
setSelectedWeek(newWeek);
setSelectedYear(newYear);
newDate = getDateOfISOWeek(newWeek, newYear);
} else if (view === 'month') {
newDate = new Date(date.getFullYear(), date.getMonth() + 1, 1);
} else {
newDate = new Date(date);
}
//Datum im DatePicker aktualisieren
setSelectedDate(newDate);
onNavigate('DATE', newDate);
};
//Pfeiltaste nach Hinten
const handlePrev = () => {
let newDate: Date;
if (view === 'day' || view === 'agenda') {
newDate = new Date(date);
newDate.setDate(newDate.getDate() - 1);
} else if (view === 'week') {
let newWeek = selectedWeek - 1;
let newYear = selectedYear;
if (newWeek < 1) {
newYear = selectedYear - 1;
newWeek = getISOWeeksInYear(newYear);
}
setSelectedWeek(newWeek);
setSelectedYear(newYear);
newDate = getDateOfISOWeek(newWeek, newYear);
} else if (view === 'month') {
newDate = new Date(date.getFullYear(), date.getMonth() - 1, 1);
} else {
newDate = new Date(date);
}
//Datum im DatePicker aktualisieren
setSelectedDate(newDate);
onNavigate('DATE', newDate);
};
const [selectedDate, setSelectedDate] = useState<Date | null>(new Date());
const handleDateChange = (date: Date | null) => {
setSelectedDate(date);
if (date) {
if (view === 'week') {
const newWeek = getISOWeek(date);
const newYear = getISOWeekYear(date);
setSelectedWeek(newWeek);
setSelectedYear(newYear);
const newDate = getDateOfISOWeek(newWeek, newYear);
onNavigate('DATE', newDate);
} else if (view === 'day') {
onNavigate('DATE', date);
} else if (view === 'month') {
const newDate = new Date(date.getFullYear(), date.getMonth(), 1);
onNavigate('DATE', newDate);
} else if (view === 'agenda') {
onNavigate('DATE', date);
}
}
};
return (
<div
className='custom-toolbar'
style={{ display: 'flex', flexDirection: 'initial', gap: '8px' }}
>
<div className='view-change'>
<div className='view-switcher' style={{ display: 'flex', gap: '8px' }}>
<Button
//className='hover:bg-orange-600 hover:text-white'
type='submit'
variant='primary'
onClick={() => handleViewChange('month')}
size={'default'}
>
Month
</Button>
<Button
//className='hover:bg-orange-600 hover:text-white'
type='submit'
variant='primary'
onClick={() => handleViewChange('week')}
size={'default'}
>
Week
</Button>
<Button
//className='hover:bg-orange-600 hover:text-white'
type='submit'
variant='primary'
onClick={() => handleViewChange('day')}
size={'default'}
>
Day
</Button>
<Button
//className='hover:bg-orange-600 hover:text-white'
type='submit'
variant='primary'
onClick={() => handleViewChange('agenda')}
size={'default'}
>
Agenda
</Button>
</div>
</div>
<div
className='right-section'
style={{ display: 'flex', flexDirection: 'initial', gap: '8px' }}
>
<div
className='navigation-controls'
style={{ display: 'flex', gap: '8px' }}
>
<div className='handleWeek'>
<button onClick={handlePrev}>&lt;</button>
<button onClick={handleNext}>&gt;</button>
</div>
<div className='today'>
<Button
//className='hover:bg-orange-600 hover:text-white'
type='submit'
variant='secondary'
onClick={() => handleToday()}
size={'default'}
>
Today
</Button>
</div>
</div>
<div className='datepicker-box'>
<DatePicker
className='datepicker'
selected={selectedDate}
onChange={handleDateChange}
calendarStartDay={1}
locale='de-DE'
dateFormat='dd.MM.yyyy'
showWeekNumbers={true}
/>
</div>
</div>
</div>
);
};
export default CustomToolbar;

View file

@ -45,7 +45,7 @@ export default function Header({
<UserDropdown /> <UserDropdown />
</span> </span>
</header> </header>
<main>{children}</main> <main className='max-h-full overflow-y-auto p-5'>{children}</main>
</div> </div>
); );
} }

View file

@ -0,0 +1,930 @@
@charset "UTF-8";
.rbc-btn {
color: inherit;
font: inherit;
margin: 0;
}
button.rbc-btn {
overflow: visible;
text-transform: none;
-webkit-appearance: button;
-moz-appearance: button;
appearance: button;
cursor: pointer;
}
button[disabled].rbc-btn {
cursor: not-allowed;
}
button.rbc-input::-moz-focus-inner {
border: 0;
padding: 0;
}
.rbc-calendar {
-webkit-box-sizing: border-box;
box-sizing: border-box;
height: 100%;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-align: stretch;
-ms-flex-align: stretch;
align-items: stretch;
}
.rbc-m-b-negative-3 {
margin-bottom: -3px;
}
.rbc-h-full {
height: 100%;
}
.rbc-calendar *,
.rbc-calendar *:before,
.rbc-calendar *:after {
-webkit-box-sizing: inherit;
box-sizing: inherit;
}
.rbc-abs-full,
.rbc-row-bg {
overflow: hidden;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.rbc-ellipsis,
.rbc-show-more,
.rbc-row-segment .rbc-event-content,
.rbc-event-label {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.rbc-rtl {
direction: rtl;
}
.rbc-off-range {
color: #999999;
}
.rbc-off-range-bg {
background: #e6e6e6;
}
.rbc-header {
overflow: hidden;
-webkit-box-flex: 1;
-ms-flex: 1 0 0%;
flex: 1 0 0%;
text-overflow: ellipsis;
white-space: nowrap;
padding: 0 3px;
text-align: center;
vertical-align: middle;
font-weight: bold;
font-size: 90%;
min-height: 0;
border-bottom: 1px solid #ddd;
}
.rbc-header + .rbc-header {
border-left: 1px solid #c6c6c6; /*#ddd*/
}
.rbc-rtl .rbc-header + .rbc-header {
border-left-width: 0;
border-right: 1px solid #ddd;
}
.rbc-header > a,
.rbc-header > a:active,
.rbc-header > a:visited {
color: inherit;
text-decoration: none;
}
.rbc-button-link {
color: inherit;
background: none;
margin: 0;
padding: 0;
border: none;
cursor: pointer;
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
}
.rbc-row-content {
position: relative;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-user-select: none;
z-index: 4;
}
.rbc-row-content-scrollable {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
height: 100%;
}
.rbc-row-content-scrollable .rbc-row-content-scroll-container {
height: 100%;
overflow-y: scroll;
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
/* Hide scrollbar for Chrome, Safari and Opera */
}
.rbc-row-content-scrollable
.rbc-row-content-scroll-container::-webkit-scrollbar {
display: none;
}
.rbc-today {
background-color: #5770ff; /*#eaf6ff*/
}
/*Own changes 10*/
.rbc-allday-cell .rbc-row-bg .rbc-day-bg.rbc-today {
background-color: transparent !important;
/*border: none !important;*/
}
/*Own changes 10*/
/*Own changes 11*/
.rbc-time-header-cell .rbc-header:first-child.rbc-today {
border-top-left-radius: 11px !important;
}
.rbc-time-header-cell .rbc-header:last-child.rbc-today {
border-top-right-radius: 11px !important;
}
/*Own changes 11*/
.rbc-toolbar {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
margin-bottom: 10px;
font-size: 16px;
}
.rbc-toolbar .rbc-toolbar-label {
-webkit-box-flex: 1;
-ms-flex-positive: 1;
flex-grow: 1;
padding: 0 10px;
text-align: center;
/*Own changes 01*/
background-color: #717171;
color: #ffffff;
/*Own changes 01*/
}
.rbc-toolbar button {
color: #373a3c;
display: inline-block;
margin: 0;
text-align: center;
vertical-align: middle;
background: none;
background-image: none;
border: 1px solid #ccc;
padding: 0.375rem 1rem;
border-radius: 4px;
line-height: normal;
white-space: nowrap;
}
.rbc-toolbar button:active,
.rbc-toolbar button.rbc-active {
background-image: none;
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
background-color: #e6e6e6;
border-color: #adadad;
}
.rbc-toolbar button:active:hover,
.rbc-toolbar button:active:focus,
.rbc-toolbar button.rbc-active:hover,
.rbc-toolbar button.rbc-active:focus {
color: #373a3c;
background-color: #d4d4d4;
border-color: #8c8c8c;
}
.rbc-toolbar button:focus {
color: #373a3c;
background-color: #e6e6e6;
border-color: #adadad;
}
.rbc-toolbar button:hover {
color: #373a3c;
cursor: pointer;
background-color: #e6e6e6;
border-color: #adadad;
}
.rbc-btn-group {
display: inline-block;
white-space: nowrap;
}
.rbc-btn-group > button:first-child:not(:last-child) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
/*Own changes 02*/
background-color: #c6c6c6;
color: #000000;
/*Own changes 02*/
}
.rbc-btn-group > button:last-child:not(:first-child) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
/*Own changes 03*/
background-color: #c6c6c6;
color: #000000;
/*Own changes 03*/
}
.rbc-rtl .rbc-btn-group > button:first-child:not(:last-child) {
border-radius: 4px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.rbc-rtl .rbc-btn-group > button:last-child:not(:first-child) {
border-radius: 4px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.rbc-btn-group > button:not(:first-child):not(:last-child) {
border-radius: 0;
/*Own changes 04*/
background-color: #c6c6c6;
color: #000000;
/*Own changes 04*/
}
.rbc-btn-group button + button {
margin-left: -1px;
}
.rbc-rtl .rbc-btn-group button + button {
margin-left: 0;
margin-right: -1px;
}
.rbc-btn-group + .rbc-btn-group,
.rbc-btn-group + button {
margin-left: 10px;
}
@media (max-width: 767px) {
.rbc-toolbar {
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
}
}
.rbc-event,
.rbc-day-slot .rbc-background-event {
border: none;
-webkit-box-sizing: border-box;
box-sizing: border-box;
-webkit-box-shadow: none;
box-shadow: none;
margin: 0;
padding: 2px 5px;
background-color: #3174ad;
border-radius: 5px;
color: #fff;
cursor: pointer;
width: 100%;
text-align: left;
}
.rbc-slot-selecting .rbc-event,
.rbc-slot-selecting .rbc-day-slot .rbc-background-event,
.rbc-day-slot .rbc-slot-selecting .rbc-background-event {
cursor: inherit;
pointer-events: none;
}
.rbc-event.rbc-selected,
.rbc-day-slot .rbc-selected.rbc-background-event {
background-color: #265985;
}
.rbc-event:focus,
.rbc-day-slot .rbc-background-event:focus {
outline: 5px auto #3b99fc;
}
.rbc-event-label {
font-size: 80%;
}
.rbc-event-overlaps {
-webkit-box-shadow: -1px 1px 5px 0px rgba(51, 51, 51, 0.5);
box-shadow: -1px 1px 5px 0px rgba(51, 51, 51, 0.5);
}
.rbc-event-continues-prior {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.rbc-event-continues-after {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.rbc-event-continues-earlier {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.rbc-event-continues-later {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.rbc-row {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
}
.rbc-row-segment {
padding: 0 1px 1px 1px;
}
.rbc-selected-cell {
background-color: rgba(0, 0, 0, 0.1);
}
.rbc-show-more {
background-color: rgba(255, 255, 255, 0.3);
z-index: 4;
font-weight: bold;
font-size: 85%;
height: auto;
line-height: normal;
color: #3174ad;
}
.rbc-show-more:hover,
.rbc-show-more:focus {
color: #265985;
}
.rbc-month-view {
position: relative;
border: 1px solid #ddd;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-flex: 1;
-ms-flex: 1 0 0px;
flex: 1 0 0;
width: 100%;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-user-select: none;
height: 100%;
}
.rbc-month-header {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
}
.rbc-month-row {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
position: relative;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-flex: 1;
-ms-flex: 1 0 0px;
flex: 1 0 0;
-ms-flex-preferred-size: 0px;
flex-basis: 0px;
overflow: hidden;
height: 100%;
}
.rbc-month-row + .rbc-month-row {
border-top: 1px solid #ddd;
}
.rbc-date-cell {
-webkit-box-flex: 1;
-ms-flex: 1 1 0px;
flex: 1 1 0;
min-width: 0;
padding-right: 5px;
text-align: right;
}
.rbc-date-cell.rbc-now {
font-weight: bold;
}
.rbc-date-cell > a,
.rbc-date-cell > a:active,
.rbc-date-cell > a:visited {
color: inherit;
text-decoration: none;
}
.rbc-row-bg {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
-webkit-box-flex: 1;
-ms-flex: 1 0 0px;
flex: 1 0 0;
overflow: hidden;
right: 1px;
}
.rbc-day-bg {
-webkit-box-flex: 1;
-ms-flex: 1 0 0%;
flex: 1 0 0%;
}
.rbc-day-bg + .rbc-day-bg {
border-left: 1px solid #ddd;
}
.rbc-rtl .rbc-day-bg + .rbc-day-bg {
border-left-width: 0;
border-right: 1px solid #ddd;
}
.rbc-overlay {
position: absolute;
z-index: 5;
border: 1px solid #e5e5e5;
background-color: #fff;
-webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.25);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.25);
padding: 10px;
}
.rbc-overlay > * + * {
margin-top: 1px;
}
.rbc-overlay-header {
border-bottom: 1px solid #e5e5e5;
margin: -10px -10px 5px -10px;
padding: 2px 10px;
}
.rbc-agenda-view {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-flex: 1;
-ms-flex: 1 0 0px;
flex: 1 0 0;
overflow: auto;
}
.rbc-agenda-view table.rbc-agenda-table {
width: 100%;
border: 1px solid #ddd;
border-spacing: 0;
border-collapse: collapse;
}
.rbc-agenda-view table.rbc-agenda-table tbody > tr > td {
padding: 5px 10px;
vertical-align: top;
}
.rbc-agenda-view table.rbc-agenda-table .rbc-agenda-time-cell {
padding-left: 15px;
padding-right: 15px;
text-transform: lowercase;
}
.rbc-agenda-view table.rbc-agenda-table tbody > tr > td + td,
.rbc-agenda-view table.rbc-agenda-table tbody > tr > td.rbc-agenda-time-cell {
border-left: 1px solid #ddd;
}
.rbc-rtl .rbc-agenda-view table.rbc-agenda-table tbody > tr > td + td {
border-left-width: 0;
border-right: 1px solid #ddd;
}
.rbc-agenda-view table.rbc-agenda-table tbody > tr + tr {
border-top: 1px solid #ddd;
}
.rbc-agenda-view table.rbc-agenda-table thead > tr > th {
padding: 3px 5px;
text-align: left;
border-bottom: 1px solid #ddd;
}
.rbc-rtl .rbc-agenda-view table.rbc-agenda-table thead > tr > th {
text-align: right;
}
.rbc-agenda-time-cell {
text-transform: lowercase;
}
.rbc-agenda-time-cell .rbc-continues-after:after {
content: ' »';
}
.rbc-agenda-time-cell .rbc-continues-prior:before {
content: '« ';
}
.rbc-agenda-date-cell,
.rbc-agenda-time-cell {
white-space: nowrap;
}
.rbc-agenda-event-cell {
width: 100%;
}
.rbc-time-column {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
min-height: 100%;
/*Own changes 06*/
background-color: #383838;
/*Own changes 06*/
}
.rbc-time-column .rbc-timeslot-group {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
}
.rbc-timeslot-group {
border-bottom: 1px solid #8d8d8d; /*#ddd*/
min-height: 40px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-flow: column nowrap;
flex-flow: column nowrap;
}
.rbc-time-gutter,
.rbc-header-gutter {
-webkit-box-flex: 0;
-ms-flex: none;
flex: none;
/*Own changes 07*/
background-color: #8d8d8d;
/*Own changes 07*/
}
.rbc-label {
padding: 0 5px;
}
.rbc-day-slot {
position: relative;
}
.rbc-day-slot .rbc-events-container {
bottom: 0;
left: 0;
position: absolute;
right: 0;
margin-right: 10px;
top: 0;
}
.rbc-day-slot .rbc-events-container.rbc-rtl {
left: 10px;
right: 0;
}
.rbc-day-slot .rbc-event,
.rbc-day-slot .rbc-background-event {
border: 1px solid #265985;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
max-height: 100%;
min-height: 20px;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-flow: column wrap;
flex-flow: column wrap;
-webkit-box-align: start;
-ms-flex-align: start;
align-items: flex-start;
overflow: hidden;
position: absolute;
}
.rbc-day-slot .rbc-background-event {
opacity: 0.75;
}
.rbc-day-slot .rbc-event-label {
-webkit-box-flex: 0;
-ms-flex: none;
flex: none;
padding-right: 5px;
width: auto;
}
.rbc-day-slot .rbc-event-content {
width: 100%;
-webkit-box-flex: 1;
-ms-flex: 1 1 0px;
flex: 1 1 0;
word-wrap: break-word;
line-height: 1;
height: 100%;
min-height: 1em;
}
.rbc-day-slot .rbc-time-slot {
border-top: 1px solid #383838; /*#f7f7f7*/
}
.rbc-time-view-resources .rbc-time-gutter,
.rbc-time-view-resources .rbc-time-header-gutter {
position: sticky;
left: 0;
background-color: white;
border-right: 1px solid #ddd;
z-index: 10;
margin-right: -1px;
}
.rbc-time-view-resources .rbc-time-header {
overflow: hidden;
}
.rbc-time-view-resources .rbc-time-header-content {
min-width: auto;
-webkit-box-flex: 1;
-ms-flex: 1 0 0px;
flex: 1 0 0;
-ms-flex-preferred-size: 0px;
flex-basis: 0px;
}
.rbc-time-view-resources .rbc-time-header-cell-single-day {
display: none;
}
.rbc-time-view-resources .rbc-day-slot {
min-width: 140px;
}
.rbc-time-view-resources .rbc-header,
.rbc-time-view-resources .rbc-day-bg {
width: 140px;
-webkit-box-flex: 1;
-ms-flex: 1 1 0px;
flex: 1 1 0;
-ms-flex-preferred-size: 0 px;
flex-basis: 0 px;
}
.rbc-time-header-content + .rbc-time-header-content {
margin-left: -1px;
}
.rbc-time-slot {
-webkit-box-flex: 1;
-ms-flex: 1 0 0px;
flex: 1 0 0;
}
.rbc-time-slot.rbc-now {
font-weight: bold;
}
.rbc-day-header {
text-align: center;
}
.rbc-slot-selection {
z-index: 10;
position: absolute;
background-color: rgba(0, 0, 0, 0.5);
color: white;
font-size: 75%;
width: 100%;
padding: 3px;
}
.rbc-slot-selecting {
cursor: move;
}
.rbc-time-view {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
width: 100%;
min-height: 0;
}
.rbc-time-view .rbc-time-gutter {
white-space: nowrap;
text-align: right;
}
.rbc-time-view .rbc-allday-cell {
-webkit-box-sizing: content-box;
box-sizing: content-box;
width: 100%;
height: 100%;
position: relative;
/*Own changes 05*/
background-color: #555555;
/*Own changes 05*/
}
.rbc-time-view .rbc-allday-cell + .rbc-allday-cell {
border-left: 1px solid #ddd;
}
.rbc-time-view .rbc-allday-events {
position: relative;
z-index: 4;
}
.rbc-time-view .rbc-row {
-webkit-box-sizing: border-box;
box-sizing: border-box;
min-height: 20px;
}
.rbc-time-header {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-flex: 0;
-ms-flex: 0 0 auto;
flex: 0 0 auto;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
}
.rbc-rtl .rbc-time-header.rbc-overflowing {
border-right-width: 0;
border-left: 1px solid #ddd;
}
.rbc-time-header > .rbc-row:first-child {
border-bottom: 1px solid #ddd;
}
.rbc-time-header > .rbc-row.rbc-row-resource {
border-bottom: 1px solid #ddd;
}
.rbc-time-header-cell-single-day {
display: none;
}
.rbc-time-header-content {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
min-width: 0;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
border-left: 1px solid #ddd;
/*Own changes 08*/
background-color: #c6c6c6;
color: #000000;
border-top-left-radius: 11px;
border-top-right-radius: 11px;
/*Own changes 08*/
}
.rbc-rtl .rbc-time-header-content {
border-left-width: 0;
border-right: 1px solid #ddd;
}
.rbc-time-header-content > .rbc-row.rbc-row-resource {
border-bottom: 1px solid #ddd;
-ms-flex-negative: 0;
flex-shrink: 0;
}
.rbc-time-content {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-flex: 1;
-ms-flex: 1 0 0%;
flex: 1 0 0%;
-webkit-box-align: start;
-ms-flex-align: start;
align-items: flex-start;
width: 100%;
overflow-y: auto;
position: relative;
}
.rbc-time-header-content {
border-bottom: 2px solid #717171; /*#ddd*/
}
.rbc-time-column :last-child {
border-bottom: 0;
}
.rbc-time-content > .rbc-time-gutter {
-webkit-box-flex: 0;
-ms-flex: none;
flex: none;
/*Own changes 09*/
border-top-left-radius: 11px;
border-bottom-left-radius: 11px;
/*Own changes 09*/
}
.rbc-time-content > * + * > * {
border-left: 1px solid #c6c6c6; /*#ddd*/
}
.rbc-rtl .rbc-time-content > * + * > * {
border-left-width: 0;
border-right: 1px solid #ddd;
}
.rbc-time-content > .rbc-day-slot {
width: 100%;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-user-select: none;
}
.rbc-current-time-indicator {
position: absolute;
z-index: 3;
left: 0;
right: 0;
height: 1px;
background-color: #74ad31;
pointer-events: none;
}
.rbc-resource-grouping.rbc-time-header-content {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
}
.rbc-resource-grouping .rbc-row .rbc-header {
width: 141px;
}
/*# sourceMappingURL=react-big-calendar.css.map */

277
yarn.lock
View file

@ -156,7 +156,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@babel/runtime@npm:^7.3.1": "@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.8, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.8.7":
version: 7.27.6 version: 7.27.6
resolution: "@babel/runtime@npm:7.27.6" resolution: "@babel/runtime@npm:7.27.6"
checksum: 10c0/89726be83f356f511dcdb74d3ea4d873a5f0cf0017d4530cb53aa27380c01ca102d573eff8b8b77815e624b1f8c24e7f0311834ad4fb632c90a770fda00bd4c8 checksum: 10c0/89726be83f356f511dcdb74d3ea4d873a5f0cf0017d4530cb53aa27380c01ca102d573eff8b8b77815e624b1f8c24e7f0311834ad4fb632c90a770fda00bd4c8
@ -539,7 +539,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@floating-ui/react-dom@npm:^2.0.0": "@floating-ui/react-dom@npm:^2.0.0, @floating-ui/react-dom@npm:^2.1.3":
version: 2.1.3 version: 2.1.3
resolution: "@floating-ui/react-dom@npm:2.1.3" resolution: "@floating-ui/react-dom@npm:2.1.3"
dependencies: dependencies:
@ -551,6 +551,20 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@floating-ui/react@npm:^0.27.3":
version: 0.27.12
resolution: "@floating-ui/react@npm:0.27.12"
dependencies:
"@floating-ui/react-dom": "npm:^2.1.3"
"@floating-ui/utils": "npm:^0.2.9"
tabbable: "npm:^6.0.0"
peerDependencies:
react: ">=17.0.0"
react-dom: ">=17.0.0"
checksum: 10c0/da453965074bd4ded8e3de97ceb2c0833df8df2ecd9eff5ae4d336413443ea5abde5c9e37b092956901b97e7b47f9138d51d4896fa82da68e77eb0090289bf64
languageName: node
linkType: hard
"@floating-ui/utils@npm:^0.2.9": "@floating-ui/utils@npm:^0.2.9":
version: 0.2.9 version: 0.2.9
resolution: "@floating-ui/utils@npm:0.2.9" resolution: "@floating-ui/utils@npm:0.2.9"
@ -1267,6 +1281,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@popperjs/core@npm:^2.11.6":
version: 2.11.8
resolution: "@popperjs/core@npm:2.11.8"
checksum: 10c0/4681e682abc006d25eb380d0cf3efc7557043f53b6aea7a5057d0d1e7df849a00e281cd8ea79c902a35a414d7919621fc2ba293ecec05f413598e0b23d5a1e63
languageName: node
linkType: hard
"@prisma/client@npm:^6.9.0": "@prisma/client@npm:^6.9.0":
version: 6.10.1 version: 6.10.1
resolution: "@prisma/client@npm:6.10.1" resolution: "@prisma/client@npm:6.10.1"
@ -2175,6 +2196,17 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@restart/hooks@npm:^0.4.7":
version: 0.4.16
resolution: "@restart/hooks@npm:0.4.16"
dependencies:
dequal: "npm:^2.0.3"
peerDependencies:
react: ">=16.8.0"
checksum: 10c0/b6a0f1db046cdec28737092ab5defdfb25fad498d37d218646f7f123aed02a5078b1c89ae631bda14d9ee35f7bb8c9e0f15379b1a45003144dc30cd15e8ba668
languageName: node
linkType: hard
"@rtsao/scc@npm:^1.1.0": "@rtsao/scc@npm:^1.1.0":
version: 1.1.0 version: 1.1.0
resolution: "@rtsao/scc@npm:1.1.0" resolution: "@rtsao/scc@npm:1.1.0"
@ -3282,6 +3314,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/date-arithmetic@npm:*":
version: 4.1.4
resolution: "@types/date-arithmetic@npm:4.1.4"
checksum: 10c0/4ee68b5a422bd5f1cf08923d18a08db558e653bbdc597677e0465a330f1e807da0e79b06b72651b62b19b4b922a779470f84657cbd765805f84f33af518b408f
languageName: node
linkType: hard
"@types/es-aggregate-error@npm:^1.0.2": "@types/es-aggregate-error@npm:^1.0.2":
version: 1.0.6 version: 1.0.6
resolution: "@types/es-aggregate-error@npm:1.0.6" resolution: "@types/es-aggregate-error@npm:1.0.6"
@ -3348,6 +3387,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/prop-types@npm:*":
version: 15.7.15
resolution: "@types/prop-types@npm:15.7.15"
checksum: 10c0/b59aad1ad19bf1733cf524fd4e618196c6c7690f48ee70a327eb450a42aab8e8a063fbe59ca0a5701aebe2d92d582292c0fb845ea57474f6a15f6994b0e260b2
languageName: node
linkType: hard
"@types/ramda@npm:~0.30.0": "@types/ramda@npm:~0.30.0":
version: 0.30.2 version: 0.30.2
resolution: "@types/ramda@npm:0.30.2" resolution: "@types/ramda@npm:0.30.2"
@ -3357,6 +3403,17 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/react-big-calendar@npm:^1":
version: 1.16.2
resolution: "@types/react-big-calendar@npm:1.16.2"
dependencies:
"@types/date-arithmetic": "npm:*"
"@types/prop-types": "npm:*"
"@types/react": "npm:*"
checksum: 10c0/a2ea4116b999cf8dac014fdc4a9f0c10fb2fd9d9886857e93649c0a601057e93e73e3d9096a756b76e227e08f68e4c979f91bf4cfd96692aea3ab7f3df0745d0
languageName: node
linkType: hard
"@types/react-dom@npm:19.1.6": "@types/react-dom@npm:19.1.6":
version: 19.1.6 version: 19.1.6
resolution: "@types/react-dom@npm:19.1.6" resolution: "@types/react-dom@npm:19.1.6"
@ -3366,7 +3423,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/react@npm:*, @types/react@npm:19.1.8": "@types/react@npm:*, @types/react@npm:19.1.8, @types/react@npm:>=16.9.11":
version: 19.1.8 version: 19.1.8
resolution: "@types/react@npm:19.1.8" resolution: "@types/react@npm:19.1.8"
dependencies: dependencies:
@ -3440,6 +3497,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/warning@npm:^3.0.0":
version: 3.0.3
resolution: "@types/warning@npm:3.0.3"
checksum: 10c0/82c1235bd05d7f6940f80012404844e225d589ad338aa4585b231a2c8deacc695b683f4168757c82c10047b81854cbeaaeefd60536dd67bb48f8a65e20410652
languageName: node
linkType: hard
"@types/webpack-env@npm:1.18.8": "@types/webpack-env@npm:1.18.8":
version: 1.18.8 version: 1.18.8
resolution: "@types/webpack-env@npm:1.18.8" resolution: "@types/webpack-env@npm:1.18.8"
@ -4521,6 +4585,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"clsx@npm:^1.2.1":
version: 1.2.1
resolution: "clsx@npm:1.2.1"
checksum: 10c0/34dead8bee24f5e96f6e7937d711978380647e936a22e76380290e35486afd8634966ce300fc4b74a32f3762c7d4c0303f442c3e259f4ce02374eb0c82834f27
languageName: node
linkType: hard
"clsx@npm:^2.1.1": "clsx@npm:^2.1.1":
version: 2.1.1 version: 2.1.1
resolution: "clsx@npm:2.1.1" resolution: "clsx@npm:2.1.1"
@ -4809,6 +4880,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"date-arithmetic@npm:^4.1.0":
version: 4.1.0
resolution: "date-arithmetic@npm:4.1.0"
checksum: 10c0/697774a1a6a1b226004b5527326599c01a095bf715a0d43089e0493a565a91e7f4342b1b73b855c0e7b0caaf4bc947a61bc35ec60d162d52ef3c3c08eab26b6e
languageName: node
linkType: hard
"date-fns-jalali@npm:4.1.0-0": "date-fns-jalali@npm:4.1.0-0":
version: 4.1.0-0 version: 4.1.0-0
resolution: "date-fns-jalali@npm:4.1.0-0" resolution: "date-fns-jalali@npm:4.1.0-0"
@ -4823,7 +4901,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"dayjs@npm:^1.10.4": "dayjs@npm:^1.10.4, dayjs@npm:^1.11.7":
version: 1.11.13 version: 1.11.13
resolution: "dayjs@npm:1.11.13" resolution: "dayjs@npm:1.11.13"
checksum: 10c0/a3caf6ac8363c7dade9d1ee797848ddcf25c1ace68d9fe8678ecf8ba0675825430de5d793672ec87b24a69bf04a1544b176547b2539982275d5542a7955f35b7 checksum: 10c0/a3caf6ac8363c7dade9d1ee797848ddcf25c1ace68d9fe8678ecf8ba0675825430de5d793672ec87b24a69bf04a1544b176547b2539982275d5542a7955f35b7
@ -4908,6 +4986,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"dequal@npm:^2.0.3":
version: 2.0.3
resolution: "dequal@npm:2.0.3"
checksum: 10c0/f98860cdf58b64991ae10205137c0e97d384c3a4edc7f807603887b7c4b850af1224a33d88012009f150861cbee4fa2d322c4cc04b9313bee312e47f6ecaa888
languageName: node
linkType: hard
"detect-libc@npm:^2.0.3, detect-libc@npm:^2.0.4": "detect-libc@npm:^2.0.3, detect-libc@npm:^2.0.4":
version: 2.0.4 version: 2.0.4
resolution: "detect-libc@npm:2.0.4" resolution: "detect-libc@npm:2.0.4"
@ -4956,6 +5041,16 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"dom-helpers@npm:^5.2.0, dom-helpers@npm:^5.2.1":
version: 5.2.1
resolution: "dom-helpers@npm:5.2.1"
dependencies:
"@babel/runtime": "npm:^7.8.7"
csstype: "npm:^3.0.2"
checksum: 10c0/f735074d66dd759b36b158fa26e9d00c9388ee0e8c9b16af941c38f014a37fc80782de83afefd621681b19ac0501034b4f1c4a3bff5caa1b8667f0212b5e124c
languageName: node
linkType: hard
"dompurify@npm:=3.2.4": "dompurify@npm:=3.2.4":
version: 3.2.4 version: 3.2.4
resolution: "dompurify@npm:3.2.4" resolution: "dompurify@npm:3.2.4"
@ -6211,6 +6306,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"globalize@npm:^0.1.1":
version: 0.1.1
resolution: "globalize@npm:0.1.1"
checksum: 10c0/6d4687e7c52a38e7f16f77339aef9b3364c34ce8cc1c8b8495b76418013252eaf5b2453fbc2d8bb9e6e56c739262665484dc7ac51b729501ff0a3b822730116b
languageName: node
linkType: hard
"globals@npm:^14.0.0": "globals@npm:^14.0.0":
version: 14.0.0 version: 14.0.0
resolution: "globals@npm:14.0.0" resolution: "globals@npm:14.0.0"
@ -6526,7 +6628,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"invariant@npm:^2.2.2": "invariant@npm:^2.2.2, invariant@npm:^2.2.4":
version: 2.2.4 version: 2.2.4
resolution: "invariant@npm:2.2.4" resolution: "invariant@npm:2.2.4"
dependencies: dependencies:
@ -7318,6 +7420,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"lodash-es@npm:^4.17.21":
version: 4.17.21
resolution: "lodash-es@npm:4.17.21"
checksum: 10c0/fb407355f7e6cd523a9383e76e6b455321f0f153a6c9625e21a8827d10c54c2a2341bd2ae8d034358b60e07325e1330c14c224ff582d04612a46a4f0479ff2f2
languageName: node
linkType: hard
"lodash.debounce@npm:^4": "lodash.debounce@npm:^4":
version: 4.0.8 version: 4.0.8
resolution: "lodash.debounce@npm:4.0.8" resolution: "lodash.debounce@npm:4.0.8"
@ -7489,6 +7598,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"luxon@npm:^3.2.1":
version: 3.6.1
resolution: "luxon@npm:3.6.1"
checksum: 10c0/906d57a9dc4d1de9383f2e9223e378c298607c1b4d17b6657b836a3cd120feb1c1de3b5d06d846a3417e1ca764de8476e8c23b3cd4083b5cdb870adcb06a99d5
languageName: node
linkType: hard
"magic-string@npm:^0.30.17": "magic-string@npm:^0.30.17":
version: 0.30.17 version: 0.30.17
resolution: "magic-string@npm:0.30.17" resolution: "magic-string@npm:0.30.17"
@ -7586,6 +7702,7 @@ __metadata:
"@tanstack/react-query": "npm:^5.80.7" "@tanstack/react-query": "npm:^5.80.7"
"@types/node": "npm:22.15.33" "@types/node": "npm:22.15.33"
"@types/react": "npm:19.1.8" "@types/react": "npm:19.1.8"
"@types/react-big-calendar": "npm:^1"
"@types/react-dom": "npm:19.1.6" "@types/react-dom": "npm:19.1.6"
"@types/swagger-ui-react": "npm:5" "@types/swagger-ui-react": "npm:5"
"@types/webpack-env": "npm:1.18.8" "@types/webpack-env": "npm:1.18.8"
@ -7608,9 +7725,12 @@ __metadata:
postcss: "npm:8.5.6" postcss: "npm:8.5.6"
prettier: "npm:3.5.3" prettier: "npm:3.5.3"
prisma: "npm:6.10.1" prisma: "npm:6.10.1"
react: "npm:^19.0.0" react: "npm:^19.1.0"
react-big-calendar: "npm:^1.18.0"
react-datepicker: "npm:^8.4.0"
react-day-picker: "npm:^9.7.0" react-day-picker: "npm:^9.7.0"
react-dom: "npm:^19.0.0" react-dom: "npm:^19.0.0"
react-error-boundary: "npm:^6.0.0"
react-hook-form: "npm:^7.56.4" react-hook-form: "npm:^7.56.4"
sonner: "npm:^2.0.5" sonner: "npm:^2.0.5"
swagger-ui-react: "npm:^5.24.1" swagger-ui-react: "npm:^5.24.1"
@ -7621,9 +7741,17 @@ __metadata:
tw-animate-css: "npm:1.3.4" tw-animate-css: "npm:1.3.4"
typescript: "npm:^5.8.3" typescript: "npm:^5.8.3"
zod: "npm:^3.25.60" zod: "npm:^3.25.60"
zod-validation-error: "npm:^3.5.2"
languageName: unknown languageName: unknown
linkType: soft linkType: soft
"memoize-one@npm:^6.0.0":
version: 6.0.0
resolution: "memoize-one@npm:6.0.0"
checksum: 10c0/45c88e064fd715166619af72e8cf8a7a17224d6edf61f7a8633d740ed8c8c0558a4373876c9b8ffc5518c2b65a960266adf403cc215cb1e90f7e262b58991f54
languageName: node
linkType: hard
"merge-stream@npm:^2.0.0": "merge-stream@npm:^2.0.0":
version: 2.0.0 version: 2.0.0
resolution: "merge-stream@npm:2.0.0" resolution: "merge-stream@npm:2.0.0"
@ -7808,6 +7936,22 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"moment-timezone@npm:^0.5.40":
version: 0.5.48
resolution: "moment-timezone@npm:0.5.48"
dependencies:
moment: "npm:^2.29.4"
checksum: 10c0/ab14ec9d94bc33f29ac18e5417b7f8aca0b17130b952c5cc9697b8fea839e5ece9313af5fd3c9703a05db472b1560ddbfc7ad2aa24aac9afd047d6da6c3c6033
languageName: node
linkType: hard
"moment@npm:^2.29.4":
version: 2.30.1
resolution: "moment@npm:2.30.1"
checksum: 10c0/865e4279418c6de666fca7786607705fd0189d8a7b7624e2e56be99290ac846f90878a6f602e34b4e0455c549b85385b1baf9966845962b313699e7cb847543a
languageName: node
linkType: hard
"ms@npm:^2.1.1, ms@npm:^2.1.3": "ms@npm:^2.1.1, ms@npm:^2.1.3":
version: 2.1.3 version: 2.1.3
resolution: "ms@npm:2.1.3" resolution: "ms@npm:2.1.3"
@ -8657,7 +8801,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"prop-types@npm:^15.8.1": "prop-types@npm:^15.7.2, prop-types@npm:^15.8.1":
version: 15.8.1 version: 15.8.1
resolution: "prop-types@npm:15.8.1" resolution: "prop-types@npm:15.8.1"
dependencies: dependencies:
@ -8773,6 +8917,33 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"react-big-calendar@npm:^1.18.0":
version: 1.19.4
resolution: "react-big-calendar@npm:1.19.4"
dependencies:
"@babel/runtime": "npm:^7.20.7"
clsx: "npm:^1.2.1"
date-arithmetic: "npm:^4.1.0"
dayjs: "npm:^1.11.7"
dom-helpers: "npm:^5.2.1"
globalize: "npm:^0.1.1"
invariant: "npm:^2.2.4"
lodash: "npm:^4.17.21"
lodash-es: "npm:^4.17.21"
luxon: "npm:^3.2.1"
memoize-one: "npm:^6.0.0"
moment: "npm:^2.29.4"
moment-timezone: "npm:^0.5.40"
prop-types: "npm:^15.8.1"
react-overlays: "npm:^5.2.1"
uncontrollable: "npm:^7.2.1"
peerDependencies:
react: ^16.14.0 || ^17 || ^18 || ^19
react-dom: ^16.14.0 || ^17 || ^18 || ^19
checksum: 10c0/78730e6396c06a27b24af860fa64d063f6407ccd12546116eb8cb2f274d827891c68a701b9c83f9903f63e5dea03fb6a3dd46d6a0a9186b3ab2f7e1d994fe86b
languageName: node
linkType: hard
"react-copy-to-clipboard@npm:5.1.0": "react-copy-to-clipboard@npm:5.1.0":
version: 5.1.0 version: 5.1.0
resolution: "react-copy-to-clipboard@npm:5.1.0" resolution: "react-copy-to-clipboard@npm:5.1.0"
@ -8785,6 +8956,20 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"react-datepicker@npm:^8.4.0":
version: 8.4.0
resolution: "react-datepicker@npm:8.4.0"
dependencies:
"@floating-ui/react": "npm:^0.27.3"
clsx: "npm:^2.1.1"
date-fns: "npm:^4.1.0"
peerDependencies:
react: ^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc
react-dom: ^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc
checksum: 10c0/e96ba4f2b54476f66bfa33aa0c21729095c83d293671b07a9ddd96ab48dad85b6530acc5ca016e83ef8907feeebfefb7133bf7a02dc550175c48c5d9f66d70ac
languageName: node
linkType: hard
"react-day-picker@npm:^9.7.0": "react-day-picker@npm:^9.7.0":
version: 9.7.0 version: 9.7.0
resolution: "react-day-picker@npm:9.7.0" resolution: "react-day-picker@npm:9.7.0"
@ -8821,6 +9006,17 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"react-error-boundary@npm:^6.0.0":
version: 6.0.0
resolution: "react-error-boundary@npm:6.0.0"
dependencies:
"@babel/runtime": "npm:^7.12.5"
peerDependencies:
react: ">=16.13.1"
checksum: 10c0/1914d600dee95a14f14af4afe9867b0d35c26c4f7826d23208800ba2a99728659029aad60a6ef95e13430b4d79c2c4c9b3585f50bf508450478760d2e4e732d8
languageName: node
linkType: hard
"react-hook-form@npm:^7.56.4": "react-hook-form@npm:^7.56.4":
version: 7.58.1 version: 7.58.1
resolution: "react-hook-form@npm:7.58.1" resolution: "react-hook-form@npm:7.58.1"
@ -8868,6 +9064,32 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"react-lifecycles-compat@npm:^3.0.4":
version: 3.0.4
resolution: "react-lifecycles-compat@npm:3.0.4"
checksum: 10c0/1d0df3c85af79df720524780f00c064d53a9dd1899d785eddb7264b378026979acbddb58a4b7e06e7d0d12aa1494fd5754562ee55d32907b15601068dae82c27
languageName: node
linkType: hard
"react-overlays@npm:^5.2.1":
version: 5.2.1
resolution: "react-overlays@npm:5.2.1"
dependencies:
"@babel/runtime": "npm:^7.13.8"
"@popperjs/core": "npm:^2.11.6"
"@restart/hooks": "npm:^0.4.7"
"@types/warning": "npm:^3.0.0"
dom-helpers: "npm:^5.2.0"
prop-types: "npm:^15.7.2"
uncontrollable: "npm:^7.2.1"
warning: "npm:^4.0.3"
peerDependencies:
react: ">=16.3.0"
react-dom: ">=16.3.0"
checksum: 10c0/61836490040cfcdebc792b6eddcfac47b7b7e159f99304165371e9eb389a6875f20ddba3433421413ccfb918e8da6042ab2829f9b1f6f5dd9f8476aa16ddcfbe
languageName: node
linkType: hard
"react-redux@npm:^9.2.0": "react-redux@npm:^9.2.0":
version: 9.2.0 version: 9.2.0
resolution: "react-redux@npm:9.2.0" resolution: "react-redux@npm:9.2.0"
@ -8954,7 +9176,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"react@npm:^19.0.0": "react@npm:^19.1.0":
version: 19.1.0 version: 19.1.0
resolution: "react@npm:19.1.0" resolution: "react@npm:19.1.0"
checksum: 10c0/530fb9a62237d54137a13d2cfb67a7db6a2156faed43eecc423f4713d9b20c6f2728b026b45e28fcd72e8eadb9e9ed4b089e99f5e295d2f0ad3134251bdd3698 checksum: 10c0/530fb9a62237d54137a13d2cfb67a7db6a2156faed43eecc423f4713d9b20c6f2728b026b45e28fcd72e8eadb9e9ed4b089e99f5e295d2f0ad3134251bdd3698
@ -10041,6 +10263,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"tabbable@npm:^6.0.0":
version: 6.2.0
resolution: "tabbable@npm:6.2.0"
checksum: 10c0/ced8b38f05f2de62cd46836d77c2646c42b8c9713f5bd265daf0e78ff5ac73d3ba48a7ca45f348bafeef29b23da7187c72250742d37627883ef89cbd7fa76898
languageName: node
linkType: hard
"tailwind-merge@npm:^3.2.0": "tailwind-merge@npm:^3.2.0":
version: 3.3.1 version: 3.3.1
resolution: "tailwind-merge@npm:3.3.1" resolution: "tailwind-merge@npm:3.3.1"
@ -10510,6 +10739,20 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"uncontrollable@npm:^7.2.1":
version: 7.2.1
resolution: "uncontrollable@npm:7.2.1"
dependencies:
"@babel/runtime": "npm:^7.6.3"
"@types/react": "npm:>=16.9.11"
invariant: "npm:^2.2.4"
react-lifecycles-compat: "npm:^3.0.4"
peerDependencies:
react: ">=15.0.0"
checksum: 10c0/81473e892027a99f1ead6b9afd16db65097651cd36c4b6db710728f206f1fc4b82ba9170ecb4a1127a23857e01ba51c0194d0a7cfeecfea61ba9418e0276cb56
languageName: node
linkType: hard
"undici-types@npm:~6.21.0": "undici-types@npm:~6.21.0":
version: 6.21.0 version: 6.21.0
resolution: "undici-types@npm:6.21.0" resolution: "undici-types@npm:6.21.0"
@ -10737,6 +10980,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"warning@npm:^4.0.3":
version: 4.0.3
resolution: "warning@npm:4.0.3"
dependencies:
loose-envify: "npm:^1.0.0"
checksum: 10c0/aebab445129f3e104c271f1637fa38e55eb25f968593e3825bd2f7a12bd58dc3738bb70dc8ec85826621d80b4acfed5a29ebc9da17397c6125864d72301b937e
languageName: node
linkType: hard
"web-streams-polyfill@npm:^3.0.3": "web-streams-polyfill@npm:^3.0.3":
version: 3.3.3 version: 3.3.3
resolution: "web-streams-polyfill@npm:3.3.3" resolution: "web-streams-polyfill@npm:3.3.3"
@ -11035,6 +11287,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"zod-validation-error@npm:^3.5.2":
version: 3.5.2
resolution: "zod-validation-error@npm:3.5.2"
peerDependencies:
zod: ^3.25.0
checksum: 10c0/da50926ec91c7ad2880bacc5010a53c42de58f73f7c4629baad8132695c4daf74dd68620787198da81aca85134471182ed4c566b5fc9bc5349aefd8540946d57
languageName: node
linkType: hard
"zod@npm:^3.25.60": "zod@npm:^3.25.60":
version: 3.25.67 version: 3.25.67
resolution: "zod@npm:3.25.67" resolution: "zod@npm:3.25.67"