feat: add JMAP Calendar integration with month/week/day/agenda views

Full calendar support via JMAP Calendars (RFC 8984):
- Event create/edit/delete with recurrence rules and reminders
- Multi-day event spanning, column-based overlap layout
- Locale-aware date formatting, first day of week and time format settings
- Real-time updates via push notifications
- ARIA accessibility, input validation, color sanitization
- Keyboard shortcuts, mobile touch targets, focus trap
- ICU pluralization for all 8 supported languages
This commit is contained in:
Matthieu MALVACHE
2026-02-16 20:34:29 +01:00
committed by Matthieu MALVACHE
parent fb414bf2c9
commit e6f67c24cb
28 changed files with 3922 additions and 39 deletions
+5 -1
View File
@@ -10,11 +10,12 @@ import { EmailSettings } from '@/components/settings/email-settings';
import { AccountSettings } from '@/components/settings/account-settings';
import { IdentitySettings } from '@/components/settings/identity-settings';
import { VacationSettings } from '@/components/settings/vacation-settings';
import { CalendarSettings } from '@/components/settings/calendar-settings';
import { AdvancedSettings } from '@/components/settings/advanced-settings';
import { useAuthStore } from '@/stores/auth-store';
import { cn } from '@/lib/utils';
type Tab = 'appearance' | 'email' | 'account' | 'identities' | 'vacation' | 'advanced';
type Tab = 'appearance' | 'email' | 'account' | 'identities' | 'vacation' | 'calendar' | 'advanced';
export default function SettingsPage() {
const router = useRouter();
@@ -23,6 +24,7 @@ export default function SettingsPage() {
const [activeTab, setActiveTab] = useState<Tab>('appearance');
const supportsVacation = client?.supportsVacationResponse() ?? false;
const supportsCalendar = client?.supportsCalendars() ?? false;
const tabs: { id: Tab; label: string }[] = [
{ id: 'appearance', label: t('tabs.appearance') },
@@ -30,6 +32,7 @@ export default function SettingsPage() {
{ id: 'account', label: t('tabs.account') },
{ id: 'identities', label: t('tabs.identities') },
...(supportsVacation ? [{ id: 'vacation' as Tab, label: t('tabs.vacation') }] : []),
...(supportsCalendar ? [{ id: 'calendar' as Tab, label: t('tabs.calendar') }] : []),
{ id: 'advanced', label: t('tabs.advanced') },
];
@@ -89,6 +92,7 @@ export default function SettingsPage() {
{activeTab === 'account' && <AccountSettings />}
{activeTab === 'identities' && <IdentitySettings />}
{activeTab === 'vacation' && <VacationSettings />}
{activeTab === 'calendar' && <CalendarSettings />}
{activeTab === 'advanced' && <AdvancedSettings />}
</div>
</div>