Files
medassist-ng/frontend/src/components/ShareDialog.tsx
T
Daniel Volz 088a6c1a05 chore: fix all Biome lint warnings and MedDetail intake bell icons (#265)
- Backend: refactor nested ternaries, remove unused imports/any types
- Frontend: fix exhaustive deps, a11y label associations, array index keys,
  empty CSS blocks, unused vars, type annotations
- MedDetail modal: fix intake schedule bell icons not rendering (use unified
  intake source with fallback), place bell inline after person name
- MedDetail modal: revert schedule rows from grid to flexbox layout

Closes #264
2026-02-22 08:52:03 +01:00

169 lines
4.7 KiB
TypeScript

/**
* ShareDialog - Modal for generating share links for medication schedules
* Allows sharing schedule view for a specific person
*/
import { Check, Copy, Link2, X } from "lucide-react";
import { useTranslation } from "react-i18next";
export interface ShareDialogProps {
show: boolean;
sharePeople: string[];
shareSelectedPerson: string;
onShareSelectedPersonChange: (person: string) => void;
shareSelectedDays: number;
onShareSelectedDaysChange: (days: number) => void;
shareGenerating: boolean;
shareLink: string | null;
onShareLinkChange: (link: string | null) => void;
shareCopied: boolean;
onShareCopiedChange: (copied: boolean) => void;
onClose: () => void;
onGenerateShareLink: () => Promise<void>;
onCopyShareLink: () => void;
}
export function ShareDialog({
show,
sharePeople,
shareSelectedPerson,
onShareSelectedPersonChange,
shareSelectedDays,
onShareSelectedDaysChange,
shareGenerating,
shareLink,
onShareLinkChange,
shareCopied,
onShareCopiedChange,
onClose,
onGenerateShareLink,
onCopyShareLink,
}: ShareDialogProps) {
const { t } = useTranslation();
const closeLabel = t("common.close");
const copyLabel = shareCopied ? t("share.copied") : t("share.copyLink");
if (!show) return null;
return (
<div
className="modal-overlay"
onClick={onClose}
onKeyDown={(e) => {
if (e.key === "Escape") onClose();
}}
>
<div
className="modal-content share-dialog-modal"
onClick={(e) => e.stopPropagation()}
onKeyDown={(e) => e.stopPropagation()}
>
<button
type="button"
className="modal-close tooltip-trigger"
onClick={onClose}
aria-label={closeLabel}
data-tooltip={closeLabel}
>
<X size={18} aria-hidden="true" />
</button>
<div className="share-dialog-header">
<h2>
<Link2 size={18} aria-hidden="true" /> {t("share.title")}
</h2>
<p className="share-dialog-description">{t("share.description")}</p>
</div>
{(() => {
if (sharePeople.length === 0) {
return (
<div className="share-dialog-empty">
<p>{t("share.noPeople")}</p>
</div>
);
}
if (shareLink) {
return (
<div className="share-dialog-result">
<p className="share-success">{t("share.linkGenerated")}</p>
<div className="share-link-box">
<input
type="text"
value={shareLink}
readOnly
className="share-link-input"
onClick={(e) => (e.target as HTMLInputElement).select()}
/>
<button
type="button"
className="btn-copy icon-only tooltip-trigger"
onClick={onCopyShareLink}
aria-label={copyLabel}
data-tooltip={copyLabel}
>
{shareCopied ? <Check size={18} aria-hidden="true" /> : <Copy size={18} aria-hidden="true" />}
</button>
</div>
{shareCopied && <span className="share-copied-hint">{t("share.copied")}</span>}
<div className="share-dialog-footer">
<button
className="ghost"
onClick={() => {
onShareLinkChange(null);
onShareCopiedChange(false);
}}
>
{t("share.generateAnother")}
</button>
<button onClick={onClose}>{t("common.close")}</button>
</div>
</div>
);
}
return (
<div className="share-dialog-form">
<div className="form-group">
<label htmlFor="share-person-select">{t("share.selectPerson")}</label>
<select
id="share-person-select"
value={shareSelectedPerson}
onChange={(e) => onShareSelectedPersonChange(e.target.value)}
>
{sharePeople.map((person) => (
<option key={person} value={person}>
{person}
</option>
))}
</select>
</div>
<div className="form-group">
<label htmlFor="share-period-select">{t("share.selectPeriod")}</label>
<select
id="share-period-select"
value={shareSelectedDays}
onChange={(e) => onShareSelectedDaysChange(Number(e.target.value))}
>
<option value={30}>{t("dashboard.schedules.1month")}</option>
<option value={90}>{t("dashboard.schedules.3months")}</option>
<option value={180}>{t("dashboard.schedules.6months")}</option>
</select>
</div>
<div className="share-dialog-footer">
<button className="ghost" onClick={onClose}>
{t("common.close")}
</button>
<button onClick={onGenerateShareLink} disabled={shareGenerating || !shareSelectedPerson}>
{shareGenerating ? t("share.generating") : t("share.generateLink")}
</button>
</div>
</div>
);
})()}
</div>
</div>
);
}