Files
hidden11/components/ShareResult.tsx
T
alexandrev-tibco 0ac9b06a6d
Build and push image / build (push) Successful in 1m20s
Polish sharing experience
2026-05-04 22:28:05 +02:00

97 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useEffect, useMemo, useState } from "react";
import type { Dictionary } from "@/lib/i18n";
import type { Locale } from "@/lib/i18n";
import { buildShareText, buildShareUrl } from "@/lib/share";
import type { DailyProgress, GlobalStats } from "@/lib/types";
import StatsPanel from "./StatsPanel";
type ShareResultProps = {
dateKey: string;
onClose: () => void;
progress: DailyProgress;
locale: Locale;
quote: { author: string; text: Record<Locale, string> };
stats: GlobalStats;
t: Dictionary;
};
export default function ShareResult({ dateKey, locale, onClose, progress, quote, stats, t }: ShareResultProps) {
const [shared, setShared] = useState(false);
const [origin, setOrigin] = useState("https://hidden11.app");
const shareUrl = useMemo(() => buildShareUrl(dateKey, progress, origin), [dateKey, origin, progress]);
const shareText = useMemo(() => buildShareText(dateKey, progress, t, shareUrl), [dateKey, progress, shareUrl, t]);
useEffect(() => {
setOrigin(window.location.origin);
}, []);
async function share() {
if (navigator.share) {
await navigator.share({
title: "hidden11",
text: shareText,
});
setShared(true);
window.setTimeout(() => setShared(false), 1600);
return;
}
window.open(
`https://twitter.com/intent/tweet?text=${encodeURIComponent(shareText)}`,
"_blank",
"noopener,noreferrer",
);
}
return (
<div className="fixed inset-0 z-50 flex items-end bg-black/70 p-3 backdrop-blur-sm sm:items-center sm:justify-center">
<div
className="flex max-h-[92dvh] w-full flex-col overflow-hidden rounded-lg border border-white/10 bg-pitch-950 shadow-2xl sm:max-w-lg"
role="dialog"
aria-modal="true"
aria-labelledby="share-title"
>
<div className="flex items-center justify-between gap-3 border-b border-white/10 p-4">
<div>
<h2 id="share-title" className="text-lg font-black text-white">
{t.share}
</h2>
<p className="mt-0.5 text-sm text-white/55">{t.shareLead}</p>
</div>
<div className="flex items-center gap-2">
<button
type="button"
onClick={share}
className="h-9 rounded-full bg-emerald-400 px-4 text-xs font-black uppercase tracking-wide text-pitch-950 transition hover:bg-emerald-300"
>
{shared ? t.copied : t.shareNow}
</button>
<button
type="button"
onClick={onClose}
className="h-9 w-9 rounded-full border border-white/15 text-lg font-black text-white transition hover:bg-white/10"
aria-label={t.closeModal}
>
×
</button>
</div>
</div>
<div className="min-h-0 flex-1 overflow-y-auto p-4">
<StatsPanel stats={stats} t={t} />
<div className="mt-4 rounded-md border border-emerald-300/20 bg-emerald-300/10 p-3">
<p className="text-sm font-semibold leading-6 text-emerald-50">
{quote.text[locale]}
</p>
<p className="mt-1 text-xs font-bold uppercase text-emerald-100/55">{quote.author}</p>
</div>
<pre className="mt-4 max-h-[38vh] overflow-auto whitespace-pre-wrap rounded-md bg-black/30 p-3 text-sm leading-6 text-white/85">
{shareText}
</pre>
</div>
</div>
</div>
);
}