325c5ddbf2
- Reminder-Tabelle mit Zeilenschutz (Mandant+Benutzer, Systemlesen fuer den E-Mail-Planer), API reminders (Liste, Anlegen) - Kachel "Erinnerungen", globaler Melder im Portalrahmen (Browser und Desktop, je Faelligkeit einmal) - Desktop: Laufzeit-Berechtigung fuer Benachrichtigungen nur fuer die gespeicherte Server-Adresse - Zugriffsklassifikation nachgemessen Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
112 lines
2.8 KiB
TypeScript
112 lines
2.8 KiB
TypeScript
import type { ReactNode } from 'react';
|
|
|
|
/**
|
|
* Kleines einfarbiges Symbol je Kacheltyp fuer die Kachel-Kopfzeile
|
|
* (Design „Mosaik“). Seit Runde 3 als „Chip“: 16-px-Symbol auf einer
|
|
* 26-px-Flaeche, beides aus der persoenlichen Akzentfarbe abgeleitet
|
|
* (`.widget-icon-chip` in globals.css) — bringt Farbe in die Kacheln, ohne
|
|
* bunt zu werden. `plain` ist das nackte graue Symbol (Vorschlagsknoepfe).
|
|
*/
|
|
const PATHS: Record<string, ReactNode> = {
|
|
calendar: (
|
|
<>
|
|
<rect x="3" y="4" width="18" height="18" rx="2" />
|
|
<path d="M16 2v4M8 2v4M3 10h18" />
|
|
</>
|
|
),
|
|
note: (
|
|
<>
|
|
<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" />
|
|
<path d="M14 2v4a2 2 0 0 0 2 2h4M10 13h6M10 17h6M8 13h.01M8 17h.01" />
|
|
</>
|
|
),
|
|
favorites: (
|
|
<path d="m12 2 3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
|
|
),
|
|
clock: (
|
|
<>
|
|
<circle cx="12" cy="12" r="10" />
|
|
<path d="M12 6v6l4 2" />
|
|
</>
|
|
),
|
|
search: (
|
|
<>
|
|
<circle cx="11" cy="11" r="7" />
|
|
<path d="m20 20-3.5-3.5" />
|
|
</>
|
|
),
|
|
calculator: (
|
|
<>
|
|
<rect x="4" y="2" width="16" height="20" rx="2" />
|
|
<path d="M8 6h8M16 14v4M8 10h.01M12 10h.01M16 10h.01M8 14h.01M12 14h.01M8 18h.01M12 18h.01" />
|
|
</>
|
|
),
|
|
stopwatch: (
|
|
<>
|
|
<circle cx="12" cy="14" r="8" />
|
|
<path d="M10 2h4M12 14l3-3M12 2v4" />
|
|
</>
|
|
),
|
|
'picture-frame': (
|
|
<>
|
|
<rect x="3" y="3" width="18" height="18" rx="2" />
|
|
<circle cx="9" cy="9" r="2" />
|
|
<path d="m21 15-3.1-3.1a2 2 0 0 0-2.8 0L6 21" />
|
|
</>
|
|
),
|
|
xframe: (
|
|
<>
|
|
<rect x="2" y="3" width="20" height="18" rx="2" />
|
|
<path d="M2 8h20M6 5.5h.01M9 5.5h.01" />
|
|
</>
|
|
),
|
|
proxmox: (
|
|
<>
|
|
<rect x="2" y="2" width="20" height="8" rx="2" />
|
|
<rect x="2" y="14" width="20" height="8" rx="2" />
|
|
<path d="M6 6h.01M6 18h.01" />
|
|
</>
|
|
),
|
|
reminder: (
|
|
<>
|
|
<path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9" />
|
|
<path d="M10.3 21a1.94 1.94 0 0 0 3.4 0" />
|
|
</>
|
|
),
|
|
};
|
|
|
|
export function WidgetIcon({
|
|
type,
|
|
variant = 'chip',
|
|
}: {
|
|
type: string;
|
|
variant?: 'chip' | 'plain';
|
|
}) {
|
|
const paths = PATHS[type];
|
|
if (!paths) return null;
|
|
const svg = (
|
|
<svg
|
|
aria-hidden="true"
|
|
data-widget-icon={type}
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width="16"
|
|
height="16"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="1.8"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
className={variant === 'plain' ? 'shrink-0 text-muted-foreground' : 'shrink-0'}
|
|
>
|
|
{paths}
|
|
</svg>
|
|
);
|
|
if (variant === 'plain') return svg;
|
|
return (
|
|
<span aria-hidden="true" className="widget-icon-chip">
|
|
{svg}
|
|
</span>
|
|
);
|
|
}
|