copy to clipboard

This commit is contained in:
john 2025-05-18 22:49:06 +02:00
parent 4878897306
commit bf07b6da4f

View file

@ -1,5 +1,5 @@
import { AuthService } from '../../../auth/authService.ts'
import { useEffect, useState, useRef } from 'react'
import { useEffect, useState, useRef, MouseEvent } from 'react'
import { SignupCode } from '../../../auth/signupCode.ts'
import { Temporal } from '@js-temporal/polyfill'
import Button from '../../../../components/buttons/Button.tsx'
@ -16,6 +16,8 @@ export default function SignupCodesManagementPage({ authService }: SignupCodesMa
const [isLoading, setIsLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
const dialogRef = useRef<HTMLDialogElement>(null)
const [tooltipPosition, setTooltipPosition] = useState<{ x: number; y: number } | null>(null)
const [activeCode, setActiveCode] = useState<string | null>(null)
const fetchCodes = async () => {
try {
@ -61,7 +63,6 @@ export default function SignupCodesManagementPage({ authService }: SignupCodesMa
const formatDate = (date: Temporal.Instant | null) => {
if (!date) return 'Never'
try {
// Convert Temporal.Instant to a JavaScript Date for formatting
const jsDate = new Date(date.epochMilliseconds)
// Format as: "Jan 1, 2023, 12:00 PM"
@ -78,6 +79,36 @@ export default function SignupCodesManagementPage({ authService }: SignupCodesMa
}
}
const copyCodeToClipboard = (code: string, e: MouseEvent) => {
e.preventDefault()
const host = window.location.origin
const url = `${host}?c=${code}`
navigator.clipboard.writeText(url)
.then(() => {
// Optional: Show a success message or notification
console.log('Copied to clipboard:', url)
})
.catch(err => {
console.error('Failed to copy:', err)
})
setTooltipPosition(null)
setActiveCode(null)
}
const showTooltip = (code: string, e: MouseEvent) => {
const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()
setTooltipPosition({
x: rect.left + rect.width / 2,
y: rect.top - 10
})
setActiveCode(code)
}
const hideTooltip = () => {
setTooltipPosition(null)
setActiveCode(null)
}
return (
<>
<div className="flex justify-between items-center mb-4">
@ -99,7 +130,14 @@ export default function SignupCodesManagementPage({ authService }: SignupCodesMa
{codes.map((code) => (
<tr key={code.code} className="hover:bg-gray-50">
<td className="py-2 ">
<code className="bg-primary-100 px-2 py-1 rounded">{code.code}</code>
<button
className="bg-primary-100 px-2 py-1 rounded font-mono text-sm cursor-pointer hover:bg-primary-200 transition-colors"
onClick={(e) => copyCodeToClipboard(code.code, e)}
onMouseEnter={(e) => showTooltip(code.code, e)}
onMouseLeave={hideTooltip}
>
{code.code}
</button>
</td>
<td>{code.email}</td>
<td>{code.redeemedBy || 'Not redeemed'}</td>
@ -182,6 +220,22 @@ export default function SignupCodesManagementPage({ authService }: SignupCodesMa
</div>
</form>
</dialog>
{tooltipPosition && activeCode && (
<dialog
open
className="fixed p-2 bg-gray-800 text-white text-xs rounded shadow-lg z-50"
style={{
left: `${tooltipPosition.x}px`,
top: `${tooltipPosition.y}px`,
transform: 'translate(-50%, -100%)',
margin: 0,
border: 'none',
}}
>
Copy to clipboard
</dialog>
)}
</>
)
}