import { useState, useEffect } from 'react'; import { Calendar as CalendarIcon, Users, Wifi, Copy, CheckCheck } from 'lucide-react'; import { calendarAPI } from '../services/api'; import { useConfig } from '../contexts/ConfigContext'; function CopyButton({ text }) { const [copied, setCopied] = useState(false); const copy = () => { navigator.clipboard.writeText(text); setCopied(true); setTimeout(() => setCopied(false), 1500); }; return ( ); } function InfoRow({ label, value }) { return (
{label}
{value}
); } function Calendar() { const { domain = 'cell', service_ips = {}, service_configs = {} } = useConfig(); const cellHost = `calendar.${domain}`; const calendarIp = service_ips.vip_calendar || '172.20.0.21'; const dnsIp = service_ips.dns || '172.20.0.3'; const calendarPort = service_configs.calendar?.port ?? 5232; const [users, setUsers] = useState([]); const [status, setStatus] = useState(null); const [isLoading, setIsLoading] = useState(true); useEffect(() => { fetchCalendarData(); }, []); const fetchCalendarData = async () => { try { const [usersResponse, statusResponse] = await Promise.all([ calendarAPI.getUsers(), calendarAPI.getStatus() ]); setUsers(usersResponse.data); setStatus(statusResponse.data); } catch (error) { console.error('Failed to fetch calendar data:', error); } finally { setIsLoading(false); } }; if (isLoading) { return (
); } return (

Calendar & Contacts

Radicale CalDAV / CardDAV server

{/* Connection Info */}

Connect your device

Use these settings in your calendar / contacts app (iOS, Android, Thunderbird, etc.)

Requires VPN connection. DNS server must be set to {dnsIp}.

{/* iOS / Android quick guide */}

Quick setup guide

iOS (Settings → Calendar → Accounts)

  1. Add Account → Other → Add CalDAV Account
  2. Server: {cellHost}
  3. Enter username & password
  4. For contacts: Add CardDAV Account, same server

Android (DAVx⁵ app)

  1. Install DAVx⁵ from Play Store / F-Droid
  2. Login with URL: http://{cellHost}/
  3. Select calendars & address books to sync

Thunderbird

  1. Calendar → New Calendar → On the Network
  2. Format: CalDAV, Location: http://{cellHost}/
{/* Status */}

Service Status

{status ? (
Radicale: Running
CalDAV: Active
CardDAV: Active
) : (

Status unavailable

)}
{/* Users */}

Calendar Users

{users.length > 0 ? ( users.map((user, index) => (
{user.username} {user.calendars || 0} calendars
)) ) : (

No calendar users configured

)}
); } export default Calendar;