86 lines
2.3 KiB
React
86 lines
2.3 KiB
React
import { useState } from 'react'
|
||
import { FaEye, FaEyeSlash, FaCheck } from 'react-icons/fa6'
|
||
|
||
/**
|
||
* Anzeige mit Auge: Klick kopiert den Wert und schaltet Sichtbarkeit um.
|
||
*/
|
||
export default function CopyableCredential({ value }) {
|
||
const [visible, setVisible] = useState(false)
|
||
const [copied, setCopied] = useState(false)
|
||
const text = (value || '').trim()
|
||
|
||
if (!text) {
|
||
return <span style={{ color: '#9ca3af' }}>–</span>
|
||
}
|
||
|
||
const handleClick = async (e) => {
|
||
e.preventDefault()
|
||
e.stopPropagation()
|
||
setVisible((v) => !v)
|
||
try {
|
||
await navigator.clipboard.writeText(text)
|
||
} catch {
|
||
const ta = document.createElement('textarea')
|
||
ta.value = text
|
||
ta.setAttribute('readonly', '')
|
||
ta.style.position = 'fixed'
|
||
ta.style.left = '-9999px'
|
||
document.body.appendChild(ta)
|
||
ta.select()
|
||
document.execCommand('copy')
|
||
document.body.removeChild(ta)
|
||
}
|
||
setCopied(true)
|
||
setTimeout(() => setCopied(false), 2000)
|
||
}
|
||
|
||
const masked = '•'.repeat(Math.min(Math.max(text.length, 8), 16))
|
||
const display = visible ? text : masked
|
||
|
||
return (
|
||
<span
|
||
className="copyable-credential"
|
||
style={{ display: 'inline-flex', alignItems: 'center', gap: '6px', maxWidth: '100%' }}
|
||
>
|
||
<span
|
||
style={{
|
||
fontFamily: visible ? 'inherit' : 'monospace',
|
||
letterSpacing: visible ? 'normal' : '1px',
|
||
overflow: 'hidden',
|
||
textOverflow: 'ellipsis',
|
||
whiteSpace: 'nowrap',
|
||
maxWidth: '180px',
|
||
}}
|
||
title={visible ? text : 'Klick auf das Auge zum Anzeigen und Kopieren'}
|
||
>
|
||
{display}
|
||
</span>
|
||
<button
|
||
type="button"
|
||
className="btn"
|
||
onClick={handleClick}
|
||
title={copied ? 'Kopiert!' : 'Anzeigen und in Zwischenablage kopieren'}
|
||
style={{
|
||
padding: '2px 6px',
|
||
minWidth: '28px',
|
||
lineHeight: 1,
|
||
flexShrink: 0,
|
||
}}
|
||
aria-label={copied ? 'Kopiert' : 'Anzeigen und kopieren'}
|
||
>
|
||
{copied ? (
|
||
<FaCheck style={{ color: '#059669' }} />
|
||
) : visible ? (
|
||
<FaEyeSlash />
|
||
) : (
|
||
<FaEye />
|
||
)}
|
||
</button>
|
||
</span>
|
||
)
|
||
}
|
||
|
||
export function getCustomerPortalPassword(customer) {
|
||
return customer?.portalPassword || customer?.password || ''
|
||
}
|