@@ -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