Skip to content

Commit eb0302e

Browse files
authored
Merge pull request #496 from MarvyNwaokobia/feat/keyboard-shortcut-copy-link
Feat/keyboard shortcut copy link
2 parents 3cd78eb + 6addfd2 commit eb0302e

File tree

4 files changed

+42
-4
lines changed

4 files changed

+42
-4
lines changed

frontend/messages/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@
198198
"clearFromDateFilter": "Clear from date filter",
199199
"clearToDateFilter": "Clear to date filter",
200200
"clearAll": "Clear all",
201+
"linkCopied": "Payment link copied to clipboard!",
201202
"showingResults": "Showing {shown} of {total} payments",
202203
"filteredSuffix": "(filters applied)",
203204
"tableStatus": "Status",

frontend/messages/es.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@
198198
"clearFromDateFilter": "Borrar filtro de fecha inicial",
199199
"clearToDateFilter": "Borrar filtro de fecha final",
200200
"clearAll": "Borrar todo",
201+
"linkCopied": "¡Enlace de pago copiado al portapapeles!",
201202
"showingResults": "Mostrando {shown} de {total} pagos",
202203
"filteredSuffix": "(con filtros)",
203204
"tableStatus": "Estado",

frontend/messages/pt.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@
198198
"clearFromDateFilter": "Limpar filtro de data inicial",
199199
"clearToDateFilter": "Limpar filtro de data final",
200200
"clearAll": "Limpar tudo",
201+
"linkCopied": "Link de pagamento copiado para a área de transferência!",
201202
"showingResults": "Mostrando {shown} de {total} pagamentos",
202203
"filteredSuffix": "(com filtros)",
203204
"tableStatus": "Status",

frontend/src/app/(authenticated)/payment-history/page.tsx

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,29 @@ export default function PaymentHistoryPage() {
109109
const page = 1;
110110
const [totalCount, setTotalCount] = useState(0);
111111
const [selectedPayment, setSelectedPayment] = useState<string | null>(null);
112+
const [hoveredPayment, setHoveredPayment] = useState<string | null>(null);
112113
const [isModalOpen, setIsModalOpen] = useState(false);
113114
const [isSheetOpen, setIsSheetOpen] = useState(false);
114115
const [flashedIds, setFlashedIds] = useState<Set<string>>(new Set());
115116

117+
useEffect(() => {
118+
const handleKeyDown = (e: KeyboardEvent) => {
119+
// Check for Cmd+C (Mac) or Ctrl+C (Windows/Linux)
120+
if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "c") {
121+
if (hoveredPayment) {
122+
e.preventDefault();
123+
const origin = typeof window !== "undefined" ? window.location.origin : "";
124+
const link = `${origin}/pay/${hoveredPayment}`;
125+
navigator.clipboard.writeText(link);
126+
toast.success(t("linkCopied"));
127+
}
128+
}
129+
};
130+
131+
window.addEventListener("keydown", handleKeyDown);
132+
return () => window.removeEventListener("keydown", handleKeyDown);
133+
}, [hoveredPayment, t]);
134+
116135
const updateFilters = useCallback(
117136
(nextFilters: FilterState) => {
118137
const params = buildSearchParams(nextFilters);
@@ -845,15 +864,31 @@ export default function PaymentHistoryPage() {
845864
<tr
846865
key={payment.id}
847866
onClick={() => handlePaymentClick(payment.id)}
848-
className={`cursor-pointer transition-colors hover:bg-white/5 ${flashedIds.has(payment.id)
867+
onMouseEnter={() => setHoveredPayment(payment.id)}
868+
onMouseLeave={() => setHoveredPayment(null)}
869+
className={`group relative cursor-pointer transition-colors hover:bg-white/5 ${flashedIds.has(payment.id)
849870
? "animate-payment-confirmed bg-green-500/10"
850871
: ""
851872
}`}
852873
>
853874
<td className="px-4 py-3">
854-
<code className="text-xs text-slate-400">
855-
{payment.id.slice(0, 8)}...
856-
</code>
875+
<div className="flex items-center gap-2">
876+
<code className="text-xs text-slate-400">
877+
{payment.id.slice(0, 8)}...
878+
</code>
879+
{hoveredPayment === payment.id && (
880+
<span className="animate-in fade-in zoom-in duration-200 pointer-events-none absolute left-2 top-1 z-10 hidden rounded-md border border-white/10 bg-black/80 px-2 py-0.5 text-[10px] font-medium text-slate-300 shadow-xl lg:flex items-center gap-1.5 backdrop-blur-sm">
881+
<kbd className="rounded border border-white/20 bg-white/5 px-1 font-sans text-[9px] text-white">
882+
883+
</kbd>{" "}
884+
+{" "}
885+
<kbd className="rounded border border-white/20 bg-white/5 px-1 font-sans text-[9px] text-white">
886+
C
887+
</kbd>{" "}
888+
to copy link
889+
</span>
890+
)}
891+
</div>
857892
</td>
858893
<td className="px-4 py-3">
859894
<span

0 commit comments

Comments
 (0)