fix: improve PDF export layout and task block styling
- Separate all-day (external calendar events) from anyday (user tasks without time) using externalProvider field; each gets its own strip - Increase ALL_DAY_H from 22→38px and add NO_TIME_H=28px so both rows are actually visible - Task blocks switch from solid fill to light-tinted background + colored left border (Google Calendar style) — much easier to read in print - Use user's taskColor setting as fallback instead of hardcoded indigo - Show up to 3 items in all-day strip, 2 in anyday strip with overflow count - GRID_H now accounts for both optional strips in height calculation v1.95.2
This commit is contained in:
parent
7ab6dd5aa8
commit
786ccf6921
@ -52,7 +52,8 @@ const FOOTER_H = 18;
|
|||||||
|
|
||||||
// Fixed structural heights
|
// Fixed structural heights
|
||||||
const DAY_HDR_H = 40; // column header: weekday name + date
|
const DAY_HDR_H = 40; // column header: weekday name + date
|
||||||
const ALL_DAY_H = 22; // optional all-day strip
|
const ALL_DAY_H = 38; // all-day strip (external calendar events)
|
||||||
|
const NO_TIME_H = 28; // anyday strip (user tasks without a time)
|
||||||
const TIME_COL_W = 32; // left time-label column
|
const TIME_COL_W = 32; // left time-label column
|
||||||
|
|
||||||
// Derived
|
// Derived
|
||||||
@ -60,12 +61,26 @@ const CONTENT_H = PH - PAD_V * 2 - FOOTER_H; // ≈ 549.28
|
|||||||
const USABLE_W = PW - PAD_H * 2; // ≈ 801.89
|
const USABLE_W = PW - PAD_H * 2; // ≈ 801.89
|
||||||
|
|
||||||
// Fixed colours
|
// Fixed colours
|
||||||
const WHITE = '#ffffff';
|
const WHITE = '#ffffff';
|
||||||
const BORDER = '#e2e8f0';
|
const BORDER = '#e2e8f0';
|
||||||
const MUTED = '#64748b';
|
const MUTED = '#64748b';
|
||||||
const DONE_BG = '#cbd5e1';
|
const DONE_BG = '#e2e8f0';
|
||||||
const STRIPE = '#f9fafb';
|
const DONE_TEXT = '#94a3b8';
|
||||||
|
const STRIPE = '#f9fafb';
|
||||||
const ALLDAY_BG = '#eff6ff';
|
const ALLDAY_BG = '#eff6ff';
|
||||||
|
const NOTIME_BG = '#fafaf9';
|
||||||
|
|
||||||
|
// Lighten a hex color toward white (amount 0–1)
|
||||||
|
function lighten(hex: string, amount: number): string {
|
||||||
|
const h = hex.replace('#', '');
|
||||||
|
const r = parseInt(h.slice(0, 2), 16);
|
||||||
|
const g = parseInt(h.slice(2, 4), 16);
|
||||||
|
const b = parseInt(h.slice(4, 6), 16);
|
||||||
|
const lr = Math.round(r + (255 - r) * amount);
|
||||||
|
const lg = Math.round(g + (255 - g) * amount);
|
||||||
|
const lb = Math.round(b + (255 - b) * amount);
|
||||||
|
return `#${lr.toString(16).padStart(2,'0')}${lg.toString(16).padStart(2,'0')}${lb.toString(16).padStart(2,'0')}`;
|
||||||
|
}
|
||||||
|
|
||||||
// ── Weekday label helpers ─────────────────────────────────────────────────────
|
// ── Weekday label helpers ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
@ -156,12 +171,14 @@ type TaskItem = {
|
|||||||
startTime: string | null;
|
startTime: string | null;
|
||||||
endTime: string | null;
|
endTime: string | null;
|
||||||
completed: boolean;
|
completed: boolean;
|
||||||
|
externalProvider: string | null;
|
||||||
project: { name: string; color: string | null } | null;
|
project: { name: string; color: string | null } | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DayData = {
|
type DayData = {
|
||||||
allDay: TaskItem[];
|
allDay: TaskItem[]; // external all-day calendar events (showAllDay)
|
||||||
timed: TaskItem[];
|
noTime: TaskItem[]; // user tasks with no time (showNoTime)
|
||||||
|
timed: TaskItem[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type WeatherDay = { maxTemp: number | null; code: number | null; };
|
type WeatherDay = { maxTemp: number | null; code: number | null; };
|
||||||
@ -172,6 +189,7 @@ type UserStyle = {
|
|||||||
weekendColorSat: string; // e.g. "#ffc107"
|
weekendColorSat: string; // e.g. "#ffc107"
|
||||||
weekendColorSun: string; // e.g. "#dc2626"
|
weekendColorSun: string; // e.g. "#dc2626"
|
||||||
dateColor: string; // e.g. "#888888"
|
dateColor: string; // e.g. "#888888"
|
||||||
|
taskColor: string; // default task block color when no project
|
||||||
headlineFontWeight: string; // e.g. "900"
|
headlineFontWeight: string; // e.g. "900"
|
||||||
useOswald: boolean; // whether Oswald was successfully registered
|
useOswald: boolean; // whether Oswald was successfully registered
|
||||||
};
|
};
|
||||||
@ -193,6 +211,7 @@ function WeekCalendarPDF({
|
|||||||
startHour,
|
startHour,
|
||||||
endHour,
|
endHour,
|
||||||
showAllDay,
|
showAllDay,
|
||||||
|
showNoTime,
|
||||||
de,
|
de,
|
||||||
userName,
|
userName,
|
||||||
userStyle,
|
userStyle,
|
||||||
@ -204,6 +223,7 @@ function WeekCalendarPDF({
|
|||||||
startHour: number;
|
startHour: number;
|
||||||
endHour: number;
|
endHour: number;
|
||||||
showAllDay: boolean;
|
showAllDay: boolean;
|
||||||
|
showNoTime: boolean;
|
||||||
de: boolean;
|
de: boolean;
|
||||||
userName: string;
|
userName: string;
|
||||||
userStyle: UserStyle;
|
userStyle: UserStyle;
|
||||||
@ -215,14 +235,15 @@ function WeekCalendarPDF({
|
|||||||
const totalMins = numHours * 60;
|
const totalMins = numHours * 60;
|
||||||
|
|
||||||
// Headline font (Oswald if available, else Helvetica-Bold)
|
// Headline font (Oswald if available, else Helvetica-Bold)
|
||||||
const headlineFont = userStyle.useOswald ? 'Oswald' : 'Helvetica-Bold';
|
|
||||||
const headlineFontFamily = userStyle.useOswald ? 'Oswald' : 'Helvetica';
|
const headlineFontFamily = userStyle.useOswald ? 'Oswald' : 'Helvetica';
|
||||||
const headlineFW = userStyle.useOswald
|
const headlineFW = userStyle.useOswald
|
||||||
? (parseInt(userStyle.headlineFontWeight) >= 600 ? 700 : 400)
|
? (parseInt(userStyle.headlineFontWeight) >= 600 ? 700 : 400)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
// GRID_H = remaining space after headers
|
// GRID_H = remaining space after headers and optional strips
|
||||||
const GRID_H = CONTENT_H - DAY_HDR_H - (showAllDay ? ALL_DAY_H : 0);
|
const GRID_H = CONTENT_H - DAY_HDR_H
|
||||||
|
- (showAllDay ? ALL_DAY_H : 0)
|
||||||
|
- (showNoTime ? NO_TIME_H : 0);
|
||||||
|
|
||||||
function minutesToY(mins: number): number {
|
function minutesToY(mins: number): number {
|
||||||
return Math.max(0, (mins / totalMins) * GRID_H);
|
return Math.max(0, (mins / totalMins) * GRID_H);
|
||||||
@ -242,7 +263,7 @@ function WeekCalendarPDF({
|
|||||||
// Responsive day-name size
|
// Responsive day-name size
|
||||||
const dayNameSize = numDays <= 3 ? 16 : numDays <= 5 ? 12 : 9;
|
const dayNameSize = numDays <= 3 ? 16 : numDays <= 5 ? 12 : 9;
|
||||||
|
|
||||||
const calendarH = DAY_HDR_H + (showAllDay ? ALL_DAY_H : 0) + GRID_H;
|
const calendarH = DAY_HDR_H + (showAllDay ? ALL_DAY_H : 0) + (showNoTime ? NO_TIME_H : 0) + GRID_H;
|
||||||
|
|
||||||
const firstDay = days[0];
|
const firstDay = days[0];
|
||||||
const lastDay = days[days.length - 1];
|
const lastDay = days[days.length - 1];
|
||||||
@ -313,11 +334,12 @@ function WeekCalendarPDF({
|
|||||||
style: {
|
style: {
|
||||||
height: ALL_DAY_H,
|
height: ALL_DAY_H,
|
||||||
borderBottomWidth: 1,
|
borderBottomWidth: 1,
|
||||||
borderBottomColor: BORDER,
|
borderBottomColor: '#bfdbfe',
|
||||||
backgroundColor: ALLDAY_BG,
|
backgroundColor: ALLDAY_BG,
|
||||||
alignItems: 'flex-end',
|
alignItems: 'flex-end',
|
||||||
justifyContent: 'center',
|
justifyContent: 'flex-start',
|
||||||
paddingRight: 4,
|
paddingRight: 4,
|
||||||
|
paddingTop: 3,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
React.createElement(Text, {
|
React.createElement(Text, {
|
||||||
@ -332,6 +354,32 @@ function WeekCalendarPDF({
|
|||||||
),
|
),
|
||||||
] : []),
|
] : []),
|
||||||
|
|
||||||
|
// Anyday label spacer
|
||||||
|
...(showNoTime ? [
|
||||||
|
React.createElement(View, {
|
||||||
|
style: {
|
||||||
|
height: NO_TIME_H,
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderBottomColor: BORDER,
|
||||||
|
backgroundColor: NOTIME_BG,
|
||||||
|
alignItems: 'flex-end',
|
||||||
|
justifyContent: 'flex-start',
|
||||||
|
paddingRight: 4,
|
||||||
|
paddingTop: 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
React.createElement(Text, {
|
||||||
|
style: {
|
||||||
|
fontSize: 5.5,
|
||||||
|
fontFamily: 'Helvetica-Bold',
|
||||||
|
color: MUTED,
|
||||||
|
textTransform: 'uppercase',
|
||||||
|
letterSpacing: 0.3,
|
||||||
|
},
|
||||||
|
}, de ? 'Jederzeit' : 'Any Day'),
|
||||||
|
),
|
||||||
|
] : []),
|
||||||
|
|
||||||
// Hour labels (absolute within container)
|
// Hour labels (absolute within container)
|
||||||
React.createElement(View, { style: { height: GRID_H, position: 'relative' } },
|
React.createElement(View, { style: { height: GRID_H, position: 'relative' } },
|
||||||
...Array.from({ length: numHours + 1 }, (_, i) => {
|
...Array.from({ length: numHours + 1 }, (_, i) => {
|
||||||
@ -363,8 +411,9 @@ function WeekCalendarPDF({
|
|||||||
? `${de ? (WMO_DE[weather.code] || '') : (WMO_EN[weather.code] || '')}${weather.maxTemp != null ? ` ${Math.round(weather.maxTemp)}°` : ''}`
|
? `${de ? (WMO_DE[weather.code] || '') : (WMO_EN[weather.code] || '')}${weather.maxTemp != null ? ` ${Math.round(weather.maxTemp)}°` : ''}`
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const allDayTasks = dayData?.allDay || [];
|
const allDayTasks = dayData?.allDay || [];
|
||||||
const timedTasks = dayData?.timed || [];
|
const noTimeTasks = dayData?.noTime || [];
|
||||||
|
const timedTasks = dayData?.timed || [];
|
||||||
|
|
||||||
const dayName = weekdayLabel(d, de, numDays);
|
const dayName = weekdayLabel(d, de, numDays);
|
||||||
const dateStr = dayDateLabel(d, de);
|
const dateStr = dayDateLabel(d, de);
|
||||||
@ -418,7 +467,7 @@ function WeekCalendarPDF({
|
|||||||
}, wLabel) : null,
|
}, wLabel) : null,
|
||||||
),
|
),
|
||||||
|
|
||||||
// ── All-day cell
|
// ── All-day cell (external calendar events)
|
||||||
...(showAllDay ? [
|
...(showAllDay ? [
|
||||||
React.createElement(View, {
|
React.createElement(View, {
|
||||||
style: {
|
style: {
|
||||||
@ -427,33 +476,78 @@ function WeekCalendarPDF({
|
|||||||
borderBottomWidth: 1,
|
borderBottomWidth: 1,
|
||||||
borderBottomColor: '#bfdbfe',
|
borderBottomColor: '#bfdbfe',
|
||||||
paddingHorizontal: 3,
|
paddingHorizontal: 3,
|
||||||
paddingTop: 2,
|
paddingTop: 3,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
...allDayTasks.slice(0, 2).map(t =>
|
...allDayTasks.slice(0, 3).map(t => {
|
||||||
React.createElement(View, {
|
const c = t.completed ? DONE_BG : (t.project?.color || '#3b82f6');
|
||||||
|
return React.createElement(View, {
|
||||||
key: t.id,
|
key: t.id,
|
||||||
style: {
|
style: {
|
||||||
borderRadius: 2,
|
borderRadius: 2,
|
||||||
paddingVertical: 1,
|
paddingVertical: 1.5,
|
||||||
paddingHorizontal: 3,
|
paddingHorizontal: 4,
|
||||||
marginBottom: 1.5,
|
marginBottom: 2,
|
||||||
backgroundColor: t.completed ? DONE_BG : (t.project?.color || '#3b82f6'),
|
backgroundColor: t.completed ? DONE_BG : lighten(c, 0.7),
|
||||||
|
borderLeftWidth: 3,
|
||||||
|
borderLeftColor: c,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
React.createElement(Text, {
|
React.createElement(Text, {
|
||||||
style: {
|
style: {
|
||||||
fontFamily: 'Helvetica-Bold',
|
fontFamily: 'Helvetica-Bold',
|
||||||
fontSize: 6.5,
|
fontSize: 6.5,
|
||||||
color: t.completed ? MUTED : WHITE,
|
color: t.completed ? DONE_TEXT : '#1e293b',
|
||||||
},
|
},
|
||||||
}, (t.title || '').slice(0, 38)),
|
}, (t.title || '').slice(0, 36)),
|
||||||
)
|
);
|
||||||
),
|
}),
|
||||||
allDayTasks.length > 2 ? React.createElement(Text, {
|
allDayTasks.length > 3 ? React.createElement(Text, {
|
||||||
style: { fontSize: 6, color: '#3b82f6', marginTop: 1 },
|
style: { fontSize: 6, color: '#3b82f6', marginTop: 1 },
|
||||||
}, `+${allDayTasks.length - 2} ${de ? 'weitere' : 'more'}`) : null,
|
}, `+${allDayTasks.length - 3} ${de ? 'weitere' : 'more'}`) : null,
|
||||||
|
),
|
||||||
|
] : []),
|
||||||
|
|
||||||
|
// ── No-time cell (anyday tasks)
|
||||||
|
...(showNoTime ? [
|
||||||
|
React.createElement(View, {
|
||||||
|
style: {
|
||||||
|
height: NO_TIME_H,
|
||||||
|
backgroundColor: NOTIME_BG,
|
||||||
|
borderBottomWidth: 1,
|
||||||
|
borderBottomColor: BORDER,
|
||||||
|
paddingHorizontal: 3,
|
||||||
|
paddingTop: 3,
|
||||||
|
overflow: 'hidden',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
...noTimeTasks.slice(0, 2).map(t => {
|
||||||
|
const c = t.completed ? DONE_BG : (t.project?.color || userStyle.taskColor);
|
||||||
|
return React.createElement(View, {
|
||||||
|
key: t.id,
|
||||||
|
style: {
|
||||||
|
borderRadius: 2,
|
||||||
|
paddingVertical: 1.5,
|
||||||
|
paddingHorizontal: 4,
|
||||||
|
marginBottom: 2,
|
||||||
|
backgroundColor: t.completed ? DONE_BG : lighten(c, 0.75),
|
||||||
|
borderLeftWidth: 3,
|
||||||
|
borderLeftColor: c,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
React.createElement(Text, {
|
||||||
|
style: {
|
||||||
|
fontFamily: 'Helvetica-Bold',
|
||||||
|
fontSize: 6.5,
|
||||||
|
color: t.completed ? DONE_TEXT : '#1e293b',
|
||||||
|
},
|
||||||
|
}, (t.title || '').slice(0, 36)),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
noTimeTasks.length > 2 ? React.createElement(Text, {
|
||||||
|
style: { fontSize: 6, color: MUTED, marginTop: 1 },
|
||||||
|
}, `+${noTimeTasks.length - 2} ${de ? 'weitere' : 'more'}`) : null,
|
||||||
),
|
),
|
||||||
] : []),
|
] : []),
|
||||||
|
|
||||||
@ -510,6 +604,7 @@ function WeekCalendarPDF({
|
|||||||
),
|
),
|
||||||
|
|
||||||
// Task blocks (absolute, spanning actual duration)
|
// Task blocks (absolute, spanning actual duration)
|
||||||
|
// Style: light tinted background + colored left border (print-friendly)
|
||||||
...timedTasks.map(t => {
|
...timedTasks.map(t => {
|
||||||
const startMins = parseTimeMinutes(t.startTime)!;
|
const startMins = parseTimeMinutes(t.startTime)!;
|
||||||
const endMins = t.endTime
|
const endMins = t.endTime
|
||||||
@ -526,10 +621,14 @@ function WeekCalendarPDF({
|
|||||||
const rawH = minutesToY(ceMin - csMin);
|
const rawH = minutesToY(ceMin - csMin);
|
||||||
const taskH = Math.max(rawH, 14);
|
const taskH = Math.max(rawH, 14);
|
||||||
|
|
||||||
const color = t.completed ? DONE_BG : (t.project?.color || '#6366f1');
|
const accentColor = t.completed
|
||||||
const textColor = t.completed ? MUTED : WHITE;
|
? DONE_BG
|
||||||
const hasMinutes = t.startTime && !t.startTime.endsWith(':00');
|
: (t.project?.color || userStyle.taskColor);
|
||||||
const isShort = (ceMin - csMin) <= 30;
|
const bgColor = t.completed ? DONE_BG : lighten(accentColor, 0.78);
|
||||||
|
const textColor = t.completed ? DONE_TEXT : '#1e293b';
|
||||||
|
const subColor = t.completed ? DONE_TEXT : accentColor;
|
||||||
|
const hasMinutes = t.startTime && !t.startTime.endsWith(':00');
|
||||||
|
const isShort = (ceMin - csMin) <= 30;
|
||||||
|
|
||||||
return React.createElement(View, {
|
return React.createElement(View, {
|
||||||
key: t.id,
|
key: t.id,
|
||||||
@ -539,9 +638,12 @@ function WeekCalendarPDF({
|
|||||||
left: 2,
|
left: 2,
|
||||||
right: 2,
|
right: 2,
|
||||||
height: taskH - 2,
|
height: taskH - 2,
|
||||||
backgroundColor: color,
|
backgroundColor: bgColor,
|
||||||
borderRadius: 3,
|
borderRadius: 3,
|
||||||
paddingHorizontal: 4,
|
borderLeftWidth: 3,
|
||||||
|
borderLeftColor: accentColor,
|
||||||
|
paddingLeft: 4,
|
||||||
|
paddingRight: 3,
|
||||||
paddingVertical: 2,
|
paddingVertical: 2,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
},
|
},
|
||||||
@ -554,10 +656,9 @@ function WeekCalendarPDF({
|
|||||||
lineHeight: 1.25,
|
lineHeight: 1.25,
|
||||||
},
|
},
|
||||||
}, (t.title || '').slice(0, 44)),
|
}, (t.title || '').slice(0, 44)),
|
||||||
// Show time when block is short or has non-zero minutes
|
|
||||||
(hasMinutes || isShort) && t.startTime
|
(hasMinutes || isShort) && t.startTime
|
||||||
? React.createElement(Text, {
|
? React.createElement(Text, {
|
||||||
style: { fontSize: 6, color: t.completed ? MUTED : 'rgba(255,255,255,0.82)', marginTop: 0.5 },
|
style: { fontSize: 6, color: subColor, marginTop: 0.5 },
|
||||||
}, fmtTime(t.startTime))
|
}, fmtTime(t.startTime))
|
||||||
: null,
|
: null,
|
||||||
);
|
);
|
||||||
@ -634,7 +735,7 @@ export async function GET(request: Request) {
|
|||||||
id: true, name: true, email: true,
|
id: true, name: true, email: true,
|
||||||
timezone: true,
|
timezone: true,
|
||||||
weekdayColor: true, weekendColorSat: true, weekendColorSun: true,
|
weekdayColor: true, weekendColorSat: true, weekendColorSun: true,
|
||||||
dateColor: true, headlineFontWeight: true,
|
dateColor: true, taskColor: true, headlineFontWeight: true,
|
||||||
weatherLat: true, weatherLon: true,
|
weatherLat: true, weatherLon: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -651,6 +752,7 @@ export async function GET(request: Request) {
|
|||||||
weekendColorSat: (user as any).weekendColorSat || '#ffc107',
|
weekendColorSat: (user as any).weekendColorSat || '#ffc107',
|
||||||
weekendColorSun: (user as any).weekendColorSun || '#dc2626',
|
weekendColorSun: (user as any).weekendColorSun || '#dc2626',
|
||||||
dateColor: (user as any).dateColor || '#888888',
|
dateColor: (user as any).dateColor || '#888888',
|
||||||
|
taskColor: (user as any).taskColor || '#6366f1',
|
||||||
headlineFontWeight: (user as any).headlineFontWeight || '900',
|
headlineFontWeight: (user as any).headlineFontWeight || '900',
|
||||||
useOswald: oswaldAvailable,
|
useOswald: oswaldAvailable,
|
||||||
};
|
};
|
||||||
@ -678,21 +780,28 @@ export async function GET(request: Request) {
|
|||||||
const dk = localDateStr(task.scheduledDate, userTz);
|
const dk = localDateStr(task.scheduledDate, userTz);
|
||||||
if (dk < startDate || dk > endDate) continue;
|
if (dk < startDate || dk > endDate) continue;
|
||||||
|
|
||||||
if (!tasksByDay.has(dk)) tasksByDay.set(dk, { allDay: [], timed: [] });
|
if (!tasksByDay.has(dk)) tasksByDay.set(dk, { allDay: [], noTime: [], timed: [] });
|
||||||
const d = tasksByDay.get(dk)!;
|
const d = tasksByDay.get(dk)!;
|
||||||
const item: TaskItem = {
|
const item: TaskItem = {
|
||||||
id: task.id, title: task.title, startTime: task.startTime,
|
id: task.id, title: task.title, startTime: task.startTime,
|
||||||
endTime: task.endTime ?? null, completed: task.completed, project: task.project,
|
endTime: task.endTime ?? null, completed: task.completed,
|
||||||
|
externalProvider: (task as any).externalProvider ?? null,
|
||||||
|
project: task.project,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!task.startTime) {
|
if (!task.startTime) {
|
||||||
if (showNoTime) d.allDay.push(item);
|
// External calendar all-day events → allDay strip; user tasks → noTime strip
|
||||||
|
if (item.externalProvider) {
|
||||||
|
if (showAllDay) d.allDay.push(item);
|
||||||
|
} else {
|
||||||
|
if (showNoTime) d.noTime.push(item);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const h = parseInt(task.startTime.split(':')[0], 10);
|
const h = parseInt(task.startTime.split(':')[0], 10);
|
||||||
if (h >= startHour && h < endHour) {
|
if (h >= startHour && h < endHour) {
|
||||||
d.timed.push(item);
|
d.timed.push(item);
|
||||||
} else if (showNoTime) {
|
} else if (showNoTime) {
|
||||||
d.allDay.push(item);
|
d.noTime.push(item); // tasks outside the time range → anyday strip
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -722,7 +831,7 @@ export async function GET(request: Request) {
|
|||||||
const pdfBuffer = await renderToBuffer(
|
const pdfBuffer = await renderToBuffer(
|
||||||
React.createElement(WeekCalendarPDF, {
|
React.createElement(WeekCalendarPDF, {
|
||||||
pages, tasksByDay, weatherByDay,
|
pages, tasksByDay, weatherByDay,
|
||||||
startHour, endHour, showAllDay, de,
|
startHour, endHour, showAllDay, showNoTime, de,
|
||||||
userName: user.name || user.email || '',
|
userName: user.name || user.email || '',
|
||||||
userStyle,
|
userStyle,
|
||||||
totalPages: pages.length,
|
totalPages: pages.length,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user