86 lines
3.0 KiB
React
86 lines
3.0 KiB
React
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>
|
||
)
|
||
}
|