From ed3cead3dbd80a663c43f15aa58ddbb599d502e1 Mon Sep 17 00:00:00 2001 From: N Rohith Reddy Date: Sun, 4 Oct 2026 02:18:37 +0530 Subject: [PATCH 1/3] feat: add share result translations --- src/locales/en.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/locales/en.json b/src/locales/en.json index c72f96d..db82ac7 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -172,6 +172,10 @@ "results.copy": "Copy Result", "results.copyAria": "Copy comparison results to clipboard", "results.pointsLead": "+{points} points", + "results.share": "Share", + "results.shareAria": "Share comparison link", + "results.shareSuccess": "Link shared!", + "results.shareError": "Failed to share link", "score.rawLabel": "Raw: {value}", "results.scoreVersion": "Score version", "section.language": "Language-focused Score", From a7acc4ea7a8ee569af5ab04863fe8edb6f2349a5 Mon Sep 17 00:00:00 2001 From: N Rohith Reddy Date: Sun, 4 Oct 2026 02:18:53 +0530 Subject: [PATCH 2/3] feat: add Arabic share result translations --- src/locales/ar.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/locales/ar.json b/src/locales/ar.json index a2cd485..f581900 100644 --- a/src/locales/ar.json +++ b/src/locales/ar.json @@ -172,6 +172,10 @@ "results.copy": "نسخ النتيجة", "results.copyAria": "نسخ نتائج المقارنة إلى الحافظة", "results.pointsLead": "+{points} نقطة", + "results.share": "مشاركة", + "results.shareAria": "مشاركة رابط المقارنة", + "results.shareSuccess": "تمت مشاركة الرابط!", + "results.shareError": "فشلت مشاركة الرابط", "score.rawLabel": "الدرجة الخام: {value}", "results.scoreVersion": "إصدار التقييم", "section.language": "النتيجة اللغوية", From 2cddf62630b5f2d10f73731cc13a53d64aa2897f Mon Sep 17 00:00:00 2001 From: N Rohith Reddy Date: Sun, 4 Oct 2026 02:19:08 +0530 Subject: [PATCH 3/3] feat: add share button to result dashboard --- .../components/result-dashboard.tsx | 58 ++++++++++++++++++- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/src/features/comparison/components/result-dashboard.tsx b/src/features/comparison/components/result-dashboard.tsx index 7572dac..93b5292 100644 --- a/src/features/comparison/components/result-dashboard.tsx +++ b/src/features/comparison/components/result-dashboard.tsx @@ -1,9 +1,9 @@ "use client"; -import { useMemo } from "react"; +import { useMemo, useState, useRef } from "react"; import Link from "next/link"; import type { Route } from "next"; -import { Check, Copy, ExternalLink, Trophy } from "lucide-react"; +import { Check, Copy, ExternalLink, Trophy, Share2, XCircle } from "lucide-react"; import { useSearchParams } from "next/navigation"; import { useClipboardCopy } from "@/hooks"; import { Avatar } from "@/components/layout/avatar"; @@ -63,6 +63,34 @@ export function ResultDashboard({ const { t } = useTranslation(); const searchParams = useSearchParams(); const { copied, copy } = useClipboardCopy(); + const { copy: copyShare } = useClipboardCopy(); + const [shareState, setShareState] = useState<"idle" | "success" | "error">("idle"); + const shareTimerRef = useRef | null>(null); + + const setShareFeedback = (state: "success" | "error") => { + setShareState(state); + if (shareTimerRef.current) clearTimeout(shareTimerRef.current); + shareTimerRef.current = setTimeout(() => setShareState("idle"), 2000); + }; + + const handleShare = async () => { + const url = window.location.href; + try { + if (navigator.share) { + await navigator.share({ url }); + setShareFeedback("success"); + } else { + const success = await copyShare(url); + setShareFeedback(success ? "success" : "error"); + } + } catch (err: unknown) { + if (err instanceof Error && err.name === "AbortError") { + return; + } + setShareFeedback("error"); + } + }; + const methodologyHref = useMemo(() => { const query = searchParams.toString(); return query ? `/scoring-methodology?${query}` : "/scoring-methodology"; @@ -454,7 +482,31 @@ export function ResultDashboard({ ) : null} -
+
+