feat: Implement contract preview loading and refresh functionality in CompanySignContractPage
This commit is contained in:
parent
0d225cb0ac
commit
a450637194
@ -5,6 +5,7 @@ import { useRouter } from 'next/navigation'
|
|||||||
import PageLayout from '../../../components/PageLayout'
|
import PageLayout from '../../../components/PageLayout'
|
||||||
import useAuthStore from '../../../store/authStore'
|
import useAuthStore from '../../../store/authStore'
|
||||||
import { useUserStatus } from '../../../hooks/useUserStatus'
|
import { useUserStatus } from '../../../hooks/useUserStatus'
|
||||||
|
import { API_BASE_URL } from '../../../utils/api'
|
||||||
|
|
||||||
export default function CompanySignContractPage() {
|
export default function CompanySignContractPage() {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@ -23,11 +24,43 @@ export default function CompanySignContractPage() {
|
|||||||
const [submitting, setSubmitting] = useState(false)
|
const [submitting, setSubmitting] = useState(false)
|
||||||
const [success, setSuccess] = useState(false)
|
const [success, setSuccess] = useState(false)
|
||||||
const [error, setError] = useState('')
|
const [error, setError] = useState('')
|
||||||
|
const [previewLoading, setPreviewLoading] = useState(false)
|
||||||
|
const [previewHtml, setPreviewHtml] = useState<string | null>(null)
|
||||||
|
const [previewError, setPreviewError] = useState<string | null>(null)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setDate(new Date().toISOString().slice(0,10))
|
setDate(new Date().toISOString().slice(0,10))
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
// Load latest contract preview for company user
|
||||||
|
useEffect(() => {
|
||||||
|
const loadPreview = async () => {
|
||||||
|
if (!accessToken) return
|
||||||
|
setPreviewLoading(true)
|
||||||
|
setPreviewError(null)
|
||||||
|
try {
|
||||||
|
const res = await fetch(`${API_BASE_URL}/api/contracts/preview/latest`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: { Authorization: `Bearer ${accessToken}` },
|
||||||
|
credentials: 'include'
|
||||||
|
})
|
||||||
|
if (!res.ok) {
|
||||||
|
const text = await res.text().catch(() => '')
|
||||||
|
throw new Error(text || 'Failed to load contract preview')
|
||||||
|
}
|
||||||
|
const html = await res.text()
|
||||||
|
setPreviewHtml(html)
|
||||||
|
} catch (e: any) {
|
||||||
|
console.error('CompanySignContractPage.loadPreview error:', e)
|
||||||
|
setPreviewError(e?.message || 'Failed to load contract preview')
|
||||||
|
setPreviewHtml(null)
|
||||||
|
} finally {
|
||||||
|
setPreviewLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loadPreview()
|
||||||
|
}, [accessToken])
|
||||||
|
|
||||||
const valid = () => {
|
const valid = () => {
|
||||||
const companyValid = companyName.trim().length >= 3 // Min 3 characters for company name
|
const companyValid = companyName.trim().length >= 3 // Min 3 characters for company name
|
||||||
const repNameValid = repName.trim().length >= 3 // Min 3 characters for representative name
|
const repNameValid = repName.trim().length >= 3 // Min 3 characters for representative name
|
||||||
@ -183,15 +216,64 @@ export default function CompanySignContractPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div className="rounded-lg border border-gray-200 h-64 sm:h-72 bg-white flex items-center justify-center relative overflow-hidden">
|
<div className="rounded-lg border border-gray-200 bg-white relative overflow-hidden">
|
||||||
<p className="text-xs text-gray-500 text-center px-6">
|
<div className="flex items-center justify-between p-3 border-b border-gray-200 bg-gray-50">
|
||||||
(Vertragsvorschau / PDF Platzhalter)
|
<h3 className="text-sm font-semibold text-gray-900">Vertragsvorschau (Unternehmen)</h3>
|
||||||
<br/>Company Contract PDF would render here.
|
<div className="flex items-center gap-2">
|
||||||
</p>
|
<button
|
||||||
<div className="absolute inset-x-0 bottom-0 p-3 bg-gradient-to-t from-white via-white/90 to-transparent text-[11px] text-gray-500 text-center">
|
type="button"
|
||||||
Scroll preview (disabled in mock)
|
onClick={() => {
|
||||||
|
if (!previewHtml) return
|
||||||
|
const blob = new Blob([previewHtml], { type: 'text/html' })
|
||||||
|
const url = URL.createObjectURL(blob)
|
||||||
|
window.open(url, '_blank', 'noopener,noreferrer')
|
||||||
|
}}
|
||||||
|
disabled={!previewHtml}
|
||||||
|
className="inline-flex items-center rounded-md bg-gray-100 hover:bg-gray-200 text-gray-900 px-2.5 py-1.5 text-xs disabled:opacity-60"
|
||||||
|
>
|
||||||
|
Open in new tab
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={async () => {
|
||||||
|
if (!accessToken) return
|
||||||
|
setPreviewLoading(true)
|
||||||
|
setPreviewError(null)
|
||||||
|
try {
|
||||||
|
const res = await fetch(`${API_BASE_URL}/api/contracts/preview/latest`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: { Authorization: `Bearer ${accessToken}` },
|
||||||
|
credentials: 'include'
|
||||||
|
})
|
||||||
|
if (!res.ok) {
|
||||||
|
const text = await res.text().catch(() => '')
|
||||||
|
throw new Error(text || 'Failed to reload preview')
|
||||||
|
}
|
||||||
|
const html = await res.text()
|
||||||
|
setPreviewHtml(html)
|
||||||
|
} catch (e: any) {
|
||||||
|
setPreviewError(e?.message || 'Failed to reload preview')
|
||||||
|
} finally {
|
||||||
|
setPreviewLoading(false)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
disabled={previewLoading}
|
||||||
|
className="inline-flex items-center rounded-md bg-indigo-600 hover:bg-indigo-500 text-white px-2.5 py-1.5 text-xs disabled:opacity-60"
|
||||||
|
>
|
||||||
|
{previewLoading ? 'Lade…' : 'Refresh'}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{previewLoading ? (
|
||||||
|
<div className="h-72 flex items-center justify-center text-xs text-gray-500">Lade Vorschau…</div>
|
||||||
|
) : previewError ? (
|
||||||
|
<div className="h-72 flex items-center justify-center text-xs text-red-600 px-4 text-center">{previewError}</div>
|
||||||
|
) : previewHtml ? (
|
||||||
|
<iframe title="Company Contract Preview" className="w-full h-72" srcDoc={previewHtml} />
|
||||||
|
) : (
|
||||||
|
<div className="h-72 flex items-center justify-center text-xs text-gray-500">Keine Vorschau verfügbar.</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user