feat(calendar): add reminder functionality for events with notifications
Some checks failed
Build & Push Docker Image / build (push) Has been cancelled

This commit is contained in:
2026-03-04 10:18:43 +01:00
parent ce2cf499dc
commit 8823f8789e
9 changed files with 192 additions and 8 deletions

View File

@@ -1,6 +1,6 @@
import { useState, useEffect, useMemo } from 'react';
import {
ChevronLeft, ChevronRight, Plus, Clock, Video,
ChevronLeft, ChevronRight, Plus, Clock, Video, Bell,
Loader2, Download, Share2, Globe, Trash2, Edit, X, UserPlus, Send, ExternalLink,
} from 'lucide-react';
import api from '../services/api';
@@ -32,7 +32,7 @@ export default function Calendar() {
// Create/Edit form
const [form, setForm] = useState({
title: '', description: '', start_time: '', end_time: '',
room_uid: '', color: '#6366f1',
room_uid: '', color: '#6366f1', reminder_minutes: null,
});
const [saving, setSaving] = useState(false);
@@ -157,7 +157,7 @@ export default function Calendar() {
title: '', description: '',
start_time: toLocalDateTimeStr(start),
end_time: toLocalDateTimeStr(end),
room_uid: '', color: '#6366f1',
room_uid: '', color: '#6366f1', reminder_minutes: null,
});
setEditingEvent(null);
setShowCreate(true);
@@ -171,6 +171,7 @@ export default function Calendar() {
end_time: toLocalDateTimeStr(new Date(ev.end_time)),
room_uid: ev.room_uid || '',
color: ev.color || '#6366f1',
reminder_minutes: ev.reminder_minutes ?? null,
});
setEditingEvent(ev);
setShowDetail(null);
@@ -494,7 +495,10 @@ export default function Calendar() {
className="text-xs px-2 py-1.5 rounded text-white font-medium cursor-pointer hover:opacity-80 transition-opacity"
style={{ backgroundColor: ev.color || '#6366f1' }}
>
<div className="truncate">{ev.title}</div>
<div className="flex items-center gap-1 truncate">
{ev.reminder_minutes && <Bell size={9} className="flex-shrink-0 opacity-70" />}
<span className="truncate">{ev.title}</span>
</div>
<div className="opacity-80 text-[10px]">{formatTime(ev.start_time)} - {formatTime(ev.end_time)}</div>
</div>
))}
@@ -570,6 +574,26 @@ export default function Calendar() {
<p className="text-xs text-th-text-s mt-1">{t('calendar.linkedRoomHint')}</p>
</div>
<div>
<label className="block text-sm font-medium text-th-text mb-1.5">{t('calendar.reminderLabel')}</label>
<div className="relative">
<Bell size={15} className="absolute left-3 top-1/2 -translate-y-1/2 text-th-text-s pointer-events-none" />
<select
value={form.reminder_minutes ?? ''}
onChange={e => setForm({ ...form, reminder_minutes: e.target.value === '' ? null : Number(e.target.value) })}
className="input-field pl-9"
>
<option value="">{t('calendar.reminderNone')}</option>
<option value="5">{t('calendar.reminder5')}</option>
<option value="15">{t('calendar.reminder15')}</option>
<option value="30">{t('calendar.reminder30')}</option>
<option value="60">{t('calendar.reminder60')}</option>
<option value="120">{t('calendar.reminder120')}</option>
<option value="1440">{t('calendar.reminder1440')}</option>
</select>
</div>
</div>
<div>
<label className="block text-sm font-medium text-th-text mb-1.5">{t('calendar.color')}</label>
<div className="flex gap-2">