updates
This commit is contained in:
+52
-18
@@ -1,5 +1,5 @@
|
|||||||
const API_BASE =
|
const API_BASE =
|
||||||
"http://localhost:8000";
|
"/api";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -491,12 +491,14 @@ async function handleJoinRoom(event){
|
|||||||
// ---------- calendar (week view) ----------
|
// ---------- calendar (week view) ----------
|
||||||
|
|
||||||
|
|
||||||
const CALENDAR_HOUR_HEIGHT = 48;
|
const CALENDAR_SLOT_HOURS = 2;
|
||||||
|
const CALENDAR_SLOT_HEIGHT = 48;
|
||||||
|
|
||||||
const CALENDAR_START_HOUR = 0;
|
const CALENDAR_START_HOUR = 0;
|
||||||
|
|
||||||
const CALENDAR_END_HOUR = 24;
|
const CALENDAR_END_HOUR = 24;
|
||||||
|
const PIXELS_PER_MINUTE =
|
||||||
|
CALENDAR_SLOT_HEIGHT / (CALENDAR_SLOT_HOURS * 60);
|
||||||
|
|
||||||
function isEventCancelled(event){
|
function isEventCancelled(event){
|
||||||
|
|
||||||
@@ -620,25 +622,31 @@ function buildWeekCalendarHtml(events, offset){
|
|||||||
(CALENDAR_END_HOUR - CALENDAR_START_HOUR) * 60;
|
(CALENDAR_END_HOUR - CALENDAR_START_HOUR) * 60;
|
||||||
|
|
||||||
let trackHeight =
|
let trackHeight =
|
||||||
(CALENDAR_END_HOUR - CALENDAR_START_HOUR) * CALENDAR_HOUR_HEIGHT;
|
((CALENDAR_END_HOUR - CALENDAR_START_HOUR) / CALENDAR_SLOT_HOURS)
|
||||||
|
* CALENDAR_SLOT_HEIGHT;
|
||||||
|
|
||||||
// time gutter
|
// time gutter
|
||||||
|
|
||||||
let hourRows = "";
|
let hourRows = "";
|
||||||
|
|
||||||
|
|
||||||
for(let h = CALENDAR_START_HOUR; h < CALENDAR_END_HOUR; h++){
|
for(
|
||||||
|
let h = CALENDAR_START_HOUR;
|
||||||
|
h < CALENDAR_END_HOUR;
|
||||||
|
h += CALENDAR_SLOT_HOURS
|
||||||
|
){
|
||||||
|
|
||||||
hourRows += `
|
hourRows += `
|
||||||
<div class="calendar-hour-label" style="height:${CALENDAR_HOUR_HEIGHT}px">
|
<div
|
||||||
|
class="calendar-hour-label"
|
||||||
|
style="height:${CALENDAR_SLOT_HEIGHT}px"
|
||||||
|
>
|
||||||
${String(h).padStart(2, "0")}:00
|
${String(h).padStart(2, "0")}:00
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// day columns
|
// day columns
|
||||||
|
|
||||||
let dayColumns =
|
let dayColumns =
|
||||||
@@ -673,13 +681,23 @@ function buildWeekCalendarHtml(events, offset){
|
|||||||
|
|
||||||
let placed =
|
let placed =
|
||||||
dayEvents.map(event => {
|
dayEvents.map(event => {
|
||||||
|
function parseLocalDate(dateString){
|
||||||
|
let parts = dateString.split(/[- :]/);
|
||||||
|
|
||||||
let start =
|
return new Date(
|
||||||
new Date(event.start_time);
|
parts[0],
|
||||||
|
parts[1] - 1,
|
||||||
|
parts[2],
|
||||||
|
parts[3],
|
||||||
|
parts[4]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let start = parseLocalDate(event.start_time);
|
||||||
|
|
||||||
let end =
|
let end =
|
||||||
event.end_time
|
event.end_time
|
||||||
? new Date(event.end_time)
|
? parseLocalDate(event.end_time)
|
||||||
: new Date(start.getTime() + 30 * 60000);
|
: new Date(start.getTime() + 30 * 60000);
|
||||||
|
|
||||||
let startMinutes =
|
let startMinutes =
|
||||||
@@ -715,8 +733,14 @@ function buildWeekCalendarHtml(events, offset){
|
|||||||
let blocksHtml =
|
let blocksHtml =
|
||||||
placed.map(p => {
|
placed.map(p => {
|
||||||
|
|
||||||
let topPct =
|
let topPx =
|
||||||
(p.startMinutes / totalMinutes) * 100;
|
(p.startMinutes - CALENDAR_START_HOUR * 60)
|
||||||
|
* PIXELS_PER_MINUTE;
|
||||||
|
|
||||||
|
|
||||||
|
let heightPx =
|
||||||
|
(p.endMinutes - p.startMinutes)
|
||||||
|
* PIXELS_PER_MINUTE;
|
||||||
|
|
||||||
let heightPct =
|
let heightPct =
|
||||||
((p.endMinutes - p.startMinutes) / totalMinutes) * 100;
|
((p.endMinutes - p.startMinutes) / totalMinutes) * 100;
|
||||||
@@ -732,15 +756,25 @@ function buildWeekCalendarHtml(events, offset){
|
|||||||
|
|
||||||
let timeLabel =
|
let timeLabel =
|
||||||
new Date(p.event.start_time)
|
new Date(p.event.start_time)
|
||||||
.toLocaleTimeString("default", { hour: "2-digit", minute: "2-digit" });
|
.toLocaleTimeString("nl-NL", {
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
hour12: false
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log({
|
||||||
|
title: p.event.title,
|
||||||
|
startMinutes: p.startMinutes,
|
||||||
|
endMinutes: p.endMinutes,
|
||||||
|
topPx,
|
||||||
|
heightPx
|
||||||
|
});
|
||||||
return `
|
return `
|
||||||
<div
|
<div
|
||||||
class="calendar-event ${colorClass}"
|
class="calendar-event ${colorClass}"
|
||||||
style="
|
style="
|
||||||
top:${topPct}%;
|
top:${topPx}px;
|
||||||
height:${heightPct}%;
|
height:${heightPx}px;
|
||||||
left:${leftPct}%;
|
left:${leftPct}%;
|
||||||
width:${widthPct}%;
|
width:${widthPct}%;
|
||||||
z-index:${p.layer + 1};
|
z-index:${p.layer + 1};
|
||||||
|
|||||||
+14
-99
@@ -370,126 +370,61 @@ form {
|
|||||||
/* week grid */
|
/* week grid */
|
||||||
|
|
||||||
.calendar-week {
|
.calendar-week {
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
|
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.calendar-gutter {
|
.calendar-gutter {
|
||||||
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
width: 55px;
|
width: 55px;
|
||||||
|
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
padding-top: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.calendar-hour-label {
|
.calendar-hour-label {
|
||||||
|
height: 48px; /* 2 uur = 48px */
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
|
|
||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
|
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
|
||||||
padding-right: 8px;
|
padding-right: 8px;
|
||||||
|
display: flex;
|
||||||
box-sizing: border-box;
|
justify-content: flex-end;
|
||||||
|
align-items: flex-start;
|
||||||
transform: translateY(-6px);
|
transform: translateY(-6px);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.calendar-days {
|
.calendar-days {
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
min-width: 700px;
|
min-width: 700px;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.calendar-day-column {
|
.calendar-day-column {
|
||||||
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
border-left: 1px solid var(--border);
|
border-left: 1px solid var(--border);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.calendar-day-header {
|
.calendar-day-header {
|
||||||
|
height: 32px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
padding: 6px 0;
|
||||||
padding: 6px 0 10px 0;
|
|
||||||
|
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|
||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.calendar-day-header.today .calendar-day-number {
|
|
||||||
|
|
||||||
color: white;
|
|
||||||
|
|
||||||
background: var(--accent);
|
|
||||||
|
|
||||||
border-radius: 50%;
|
|
||||||
|
|
||||||
padding: 2px 7px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.calendar-day-name {
|
|
||||||
|
|
||||||
text-transform: uppercase;
|
|
||||||
|
|
||||||
font-size: 10px;
|
|
||||||
|
|
||||||
letter-spacing: 0.05em;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.calendar-day-number {
|
|
||||||
|
|
||||||
font-size: 14px;
|
|
||||||
|
|
||||||
font-weight: 600;
|
|
||||||
|
|
||||||
color: var(--text);
|
|
||||||
|
|
||||||
margin-top: 2px;
|
|
||||||
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.calendar-day-track {
|
.calendar-day-track {
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
height: 576px; /* 12 uur zichtbaar × 48px */
|
||||||
|
|
||||||
background-image:
|
background-image:
|
||||||
repeating-linear-gradient(
|
repeating-linear-gradient(
|
||||||
to bottom,
|
to bottom,
|
||||||
@@ -498,14 +433,15 @@ form {
|
|||||||
transparent 1px,
|
transparent 1px,
|
||||||
transparent 48px
|
transparent 48px
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.calendar-event {
|
.calendar-event {
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
||||||
|
left: 4px;
|
||||||
|
right: 4px;
|
||||||
|
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
|
|
||||||
padding: 3px 6px;
|
padding: 3px 6px;
|
||||||
@@ -518,52 +454,31 @@ form {
|
|||||||
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
box-shadow: 0 2px 6px rgba(0,0,0,0.25);
|
box-shadow:
|
||||||
|
0 2px 6px rgba(0,0,0,0.25);
|
||||||
|
|
||||||
opacity: 0.92;
|
opacity: 0.92;
|
||||||
|
|
||||||
border: 1px solid rgba(255,255,255,0.4);
|
border: 1px solid rgba(255,255,255,0.4);
|
||||||
|
|
||||||
transition: opacity 0.15s;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.calendar-event:hover {
|
|
||||||
|
|
||||||
opacity: 1;
|
|
||||||
|
|
||||||
z-index: 99 !important;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.calendar-event-time {
|
.calendar-event-time {
|
||||||
|
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
|
|
||||||
opacity: 0.85;
|
opacity: 0.85;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.calendar-event-title {
|
.calendar-event-title {
|
||||||
|
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.event-confirmed {
|
.event-confirmed {
|
||||||
|
|
||||||
background: #16a34a;
|
background: #16a34a;
|
||||||
|
|||||||
Reference in New Issue
Block a user