A second channel to the same dialog engine as the Telegram bot: consent, onboarding, scales and check-ins come from app/dialog; the bot is unchanged. - API: /auth/emias (doctor's one-time connect code via EmiasMock), /auth/emias/demo (synthetic personas), /auth/anonymous (random token, nothing stored in the identity DB), /crisis/resources from crisis.yaml - web/: React + TS + Vite, mobile-first, safe areas, hash routing, tokens and texts isolated for a Capacitor mobile build Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
79 lines
2.2 KiB
TypeScript
79 lines
2.2 KiB
TypeScript
// Minimal line icon set (24px grid, 1.75 stroke). Decorative by default: pass `label` to expose to screen readers.
|
|
|
|
const paths = {
|
|
check: <path d="M5 12.5l4.5 4.5L19 7.5" />,
|
|
minus: <path d="M6 12h12" />,
|
|
phone: (
|
|
<path d="M6.6 3.8h2.6l1.4 4-2 1.4a12 12 0 0 0 5.9 5.9l1.4-2 4 1.4v2.6c0 1-.8 1.8-1.8 1.8A15.8 15.8 0 0 1 4.8 5.6c0-1 .8-1.8 1.8-1.8z" />
|
|
),
|
|
arrowLeft: <path d="M19 12H5m6-6l-6 6 6 6" />,
|
|
arrowRight: <path d="M5 12h14m-6-6l6 6-6 6" />,
|
|
send: <path d="M4 12l16-8-6 16-2.5-6.5L4 12z" />,
|
|
info: (
|
|
<>
|
|
<circle cx="12" cy="12" r="9" />
|
|
<path d="M12 11v5m0-8.5v.5" />
|
|
</>
|
|
),
|
|
alert: (
|
|
<>
|
|
<path d="M12 3.5l9.5 16.5h-19L12 3.5z" />
|
|
<path d="M12 10v4.5m0 2.5v.5" />
|
|
</>
|
|
),
|
|
lock: (
|
|
<>
|
|
<rect x="5" y="10.5" width="14" height="10" rx="1.5" />
|
|
<path d="M8.5 10.5V7.5a3.5 3.5 0 0 1 7 0v3" />
|
|
</>
|
|
),
|
|
pill: (
|
|
<>
|
|
<rect x="3.5" y="8.5" width="17" height="7" rx="3.5" transform="rotate(-45 12 12)" />
|
|
<path d="M9.5 9.5l5 5" />
|
|
</>
|
|
),
|
|
pulse: <path d="M3 12h4l2-5 4 10 2-5h6" />,
|
|
doctor: (
|
|
<>
|
|
<circle cx="12" cy="7.5" r="3.5" />
|
|
<path d="M5 20.5c0-3.9 3.1-6.5 7-6.5s7 2.6 7 6.5" />
|
|
<path d="M12 15.5v3m-1.5-1.5h3" />
|
|
</>
|
|
),
|
|
close: <path d="M6 6l12 12M18 6L6 18" />,
|
|
logout: <path d="M14 4h4.5A1.5 1.5 0 0 1 20 5.5v13a1.5 1.5 0 0 1-1.5 1.5H14M10 8l-4 4 4 4M6 12h10" />,
|
|
} as const;
|
|
|
|
export type IconName = keyof typeof paths;
|
|
|
|
export function Icon({ name, size = 20, label }: { name: IconName; size?: number; label?: string }) {
|
|
return (
|
|
<svg
|
|
width={size}
|
|
height={size}
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth={1.75}
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
role={label ? "img" : undefined}
|
|
aria-label={label}
|
|
aria-hidden={label ? undefined : true}
|
|
focusable="false"
|
|
>
|
|
{paths[name]}
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
export function LogoMark({ size = 32 }: { size?: number }) {
|
|
return (
|
|
<svg width={size} height={size} viewBox="0 0 32 32" aria-hidden="true" focusable="false">
|
|
<rect width="32" height="32" rx="6" fill="var(--c-primary)" />
|
|
<path d="M13 7h6v6h6v6h-6v6h-6v-6H7v-6h6z" fill="#fff" />
|
|
</svg>
|
|
);
|
|
}
|