106 lines
3.2 KiB
TypeScript
106 lines
3.2 KiB
TypeScript
'use client'
|
|
|
|
import { useEffect, useState } from 'react'
|
|
import { authFetch } from '../../../utils/authFetch'
|
|
|
|
const apiBase = (process.env.NEXT_PUBLIC_API_BASE_URL || '').replace(/\/+$/, '')
|
|
|
|
export function useAboActiveContractHtml() {
|
|
const [html, setHtml] = useState<string | null>(null)
|
|
const [loading, setLoading] = useState(false)
|
|
const [error, setError] = useState<string | null>(null)
|
|
|
|
useEffect(() => {
|
|
let active = true
|
|
|
|
;(async () => {
|
|
setLoading(true)
|
|
setError(null)
|
|
try {
|
|
const url = `${apiBase}/api/contracts/abo/active`
|
|
const res = await authFetch(url, {
|
|
method: 'GET',
|
|
headers: { Accept: 'application/json' },
|
|
credentials: 'include',
|
|
})
|
|
|
|
const ct = res.headers.get('content-type') || ''
|
|
const isJson = ct.includes('application/json')
|
|
|
|
try {
|
|
console.info('[useAboActiveContractHtml] response meta', {
|
|
url,
|
|
status: res.status,
|
|
ok: res.ok,
|
|
contentType: ct,
|
|
isJson,
|
|
})
|
|
} catch {}
|
|
|
|
if (isJson) {
|
|
const payload: any = await res.json().catch(() => null)
|
|
|
|
try {
|
|
console.info('[useAboActiveContractHtml] response json keys', payload && typeof payload === 'object' ? Object.keys(payload) : payload)
|
|
} catch {}
|
|
|
|
if (!res.ok) {
|
|
const msg = payload?.message || payload?.error || `Failed to load contract: ${res.status}`
|
|
throw new Error(msg)
|
|
}
|
|
|
|
const foundRaw = payload?.found ?? payload?.data?.found
|
|
const found = typeof foundRaw === 'boolean' ? foundRaw : undefined
|
|
|
|
const htmlRaw = payload?.html ?? payload?.data?.html
|
|
const htmlValue = typeof htmlRaw === 'string' ? htmlRaw : ''
|
|
|
|
const isFound = (typeof found === 'boolean') ? found : Boolean(htmlValue)
|
|
|
|
try {
|
|
console.info('[useAboActiveContractHtml] parsed json', {
|
|
success: payload?.success,
|
|
found: isFound,
|
|
htmlLength: htmlValue ? htmlValue.length : 0,
|
|
htmlPreview: htmlValue ? `${htmlValue.slice(0, 200)}${htmlValue.length > 200 ? '…' : ''}` : '',
|
|
})
|
|
} catch {}
|
|
|
|
if (active) setHtml(isFound && htmlValue ? htmlValue : null)
|
|
return
|
|
}
|
|
|
|
// Fallback: older endpoints returned raw HTML.
|
|
const text = await res.text().catch(() => '')
|
|
|
|
try {
|
|
console.info('[useAboActiveContractHtml] response text preview', {
|
|
status: res.status,
|
|
ok: res.ok,
|
|
textLength: text.length,
|
|
textPreview: text ? `${text.slice(0, 200)}${text.length > 200 ? '…' : ''}` : '',
|
|
})
|
|
} catch {}
|
|
|
|
if (!res.ok) {
|
|
throw new Error(text || `Failed to load contract: ${res.status}`)
|
|
}
|
|
if (active) setHtml(text || null)
|
|
} catch (e: any) {
|
|
if (active) {
|
|
setHtml(null)
|
|
setError(e?.message || 'Failed to load contract preview.')
|
|
}
|
|
} finally {
|
|
if (active) setLoading(false)
|
|
}
|
|
})()
|
|
|
|
return () => {
|
|
active = false
|
|
}
|
|
}, [])
|
|
|
|
return { html, loading, error }
|
|
}
|