Kundenseite: Kundenansicht oeffnen, letzter Login, Preview per Einmal-Link

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-01 19:44:50 +00:00
1 parent 370724a9a7
commit fce2f41463
7 files changed
+92 -7

No files matched your search

+1 -1
View File
@@ -91,7 +91,7 @@ export default function AssignedProjectCard({ project, onUnassign, showActions =
)}
</div>
<div style={{ display: 'flex', gap: 8, alignItems: 'center', flexShrink: 0 }}>
<PreviewLinkButton href={project.previewUrl} />
<PreviewLinkButton href={project.previewUrl} subdomain={project.subdomain} />
<GiteaLinkButton href={project.giteaRepoUrl} />
{showActions && onUnassign && (
<button
+14 -1
View File
@@ -1,11 +1,24 @@
import { FaEye } from 'react-icons/fa6'
import { createPreviewLink } from '../lib/teamApi'
import { openInNewTab } from '../lib/openInNewTab'
export default function PreviewLinkButton({ href, title = 'Preview oeffnen', size = 16 }) {
// Mit subdomain holt der Knopf einen Einmal-Link vom Portal (Mitarbeiter sind dort nicht mehr angemeldet);
// ohne subdomain bleibt er ein einfacher Link.
export default function PreviewLinkButton({ href, subdomain, title = 'Preview oeffnen', size = 16 }) {
if (!href) return null
const open = (event) => {
if (!subdomain) return
event.preventDefault()
openInNewTab(() => createPreviewLink({ subdomain, previewUrl: href })).catch((err) =>
window.alert(err.message || 'Die Preview konnte nicht geöffnet werden.')
)
}
return (
<a
href={href}
onClick={open}
target="_blank"
rel="noopener noreferrer"
title={title}
@@ -0,0 +1,33 @@
import { useState } from 'react'
import { FaArrowUpRightFromSquare, FaSpinner } from 'react-icons/fa6'
import { Button } from '../ui'
import { createKundenansichtLink } from '../../lib/teamApi'
import { openInNewTab } from '../../lib/openInNewTab'
/** Kundenansicht im Portal in einem neuen Tab öffnen (Einmal-Link). Ohne Portal-Zugang ausgegraut. */
export default function KundenansichtButton({ customer, variant = 'primary' }) {
const [busy, setBusy] = useState(false)
const hasAccess = Boolean(customer?.portalAccessEnabled && customer?.appwriteUserId)
const open = async () => {
setBusy(true)
try {
await openInNewTab(() => createKundenansichtLink(customer.$id))
} catch (err) {
window.alert(err.message || 'Die Kundenansicht konnte nicht geöffnet werden.')
} finally {
setBusy(false)
}
}
return (
<Button
variant={variant}
onClick={open}
disabled={!hasAccess || busy}
title={hasAccess ? 'Portal so öffnen, wie der Kunde es sieht' : 'Kein Portal-Zugang'}
>
{busy ? <FaSpinner className="spinner" /> : <FaArrowUpRightFromSquare />} Kundenansicht öffnen
</Button>
)
}