UMBRA/frontend/src/components/calendar/PermissionBadge.tsx
Kyle Pope 4e3fd35040 Phase 3: Frontend core for shared calendars
Types: CalendarPermission, SharedCalendarMembership, CalendarMemberInfo,
CalendarInvite, EventLockInfo. Calendar type extended with is_shared.

Hooks: useCalendars extended with shared calendar polling (5s).
useSharedCalendars for member CRUD, invite responses, color updates.
useConnections cascade invalidation on disconnect.

New components: PermissionBadge, CalendarMemberSearch,
CalendarMemberRow, CalendarMemberList, SharedCalendarSection,
SharedCalendarSettings (non-owner dialog with color, members, leave).

Modified: CalendarForm (sharing toggle, member management for owners),
CalendarSidebar (shared calendars section with localStorage visibility),
CalendarPage (shared calendar ID integration in event filtering),
NotificationToaster (calendar_invite toast with accept/decline),
NotificationsPage (calendar_invite inline actions + type icons).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 04:59:13 +08:00

25 lines
980 B
TypeScript

import { Eye, Pencil, Shield } from 'lucide-react';
import type { CalendarPermission } from '@/types';
const config: Record<CalendarPermission, { label: string; icon: typeof Eye; bg: string; text: string }> = {
read_only: { label: 'Read Only', icon: Eye, bg: 'bg-blue-500/10', text: 'text-blue-400' },
create_modify: { label: 'Create/Modify', icon: Pencil, bg: 'bg-amber-500/10', text: 'text-amber-400' },
full_access: { label: 'Full Access', icon: Shield, bg: 'bg-green-500/10', text: 'text-green-400' },
};
interface PermissionBadgeProps {
permission: CalendarPermission;
showIcon?: boolean;
}
export default function PermissionBadge({ permission, showIcon = true }: PermissionBadgeProps) {
const c = config[permission];
const Icon = c.icon;
return (
<span className={`inline-flex items-center gap-1 text-[9px] px-1.5 py-0.5 rounded-full font-medium ${c.bg} ${c.text}`}>
{showIcon && <Icon className="h-3 w-3" />}
{c.label}
</span>
);
}