Files
tickte-system/src/components/VorschauLinkRow.jsx
T

86 lines
3.0 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState } from 'react'
import { copyTextChecked } from './CopyableCredential'
import { erzeugeVorschauLink, schalteVorschauLinkAb } from '../lib/projectAdminApi'
import { vorschauLinkUrl } from '../lib/vorschauLink'
// Geheimer Vorschau-Link im Ticket (Details > Projekte): wer den Link hat, sieht die Seite ohne Login.
export default function VorschauLinkRow({ project, onChanged = () => {} }) {
const [token, setToken] = useState(project.shareToken || '')
const [busy, setBusy] = useState(false)
const [message, setMessage] = useState('')
const url = vorschauLinkUrl({ subdomain: project.subdomain, shareToken: token })
const run = async (action) => {
setBusy(true)
setMessage('')
try {
await action()
onChanged()
} catch (err) {
setMessage(err.message || 'Aktion fehlgeschlagen')
} finally {
setBusy(false)
}
}
const erzeugen = (neu) => {
if (neu && !window.confirm('Neuen Link erzeugen? Der bisherige Link funktioniert dann nicht mehr.')) return
run(async () => {
const r = await erzeugeVorschauLink(project.$id)
setToken(r.shareToken || '')
setMessage(neu ? 'Neuer Link erzeugt, der alte gilt nicht mehr.' : 'Link erstellt.')
})
}
const abschalten = () => {
if (!window.confirm('Link abschalten? Wer ihn hat, kommt dann nicht mehr auf die Seite.')) return
run(async () => {
await schalteVorschauLinkAb(project.$id)
setToken('')
setMessage('Link abgeschaltet.')
})
}
const kopieren = async () => {
try {
await copyTextChecked(url)
setMessage('Link kopiert.')
} catch {
setMessage('Kopieren ging nicht – bitte den Link oben markieren und kopieren.')
}
}
return (
<div className="vorschau-link" data-testid="vorschau-link">
<div className="vorschau-link-head">
<span className="vorschau-link-label">Vorschau-Link</span>
<span className="muted xs">Ohne Login, nur für wen du ihn teilst</span>
</div>
{url ? (
<>
<input
className="input vorschau-link-url"
readOnly
aria-label="Geheimer Vorschau-Link"
value={url}
onFocus={(e) => e.target.select()}
/>
<div className="row-actions">
<button type="button" className="link" onClick={kopieren}>Kopieren</button>
<a className="link" href={url} target="_blank" rel="noopener noreferrer">Öffnen</a>
<button type="button" className="link" disabled={busy} onClick={() => erzeugen(true)}>Neuer Link</button>
<button type="button" className="link link-danger" disabled={busy} onClick={abschalten}>Abschalten</button>
</div>
</>
) : (
<div className="row-actions">
<button type="button" className="link" disabled={busy} onClick={() => erzeugen(false)}>
{busy ? 'Wird erstellt …' : 'Link erstellen'}
</button>
</div>
)}
{message && <p className="msg muted" role="status">{message}</p>}
</div>
)
}