48 lines
2.0 KiB
React
48 lines
2.0 KiB
React
import { useEffect, useState } from 'react'
|
|
import { Card, Badge } from '../ui'
|
|
import { getCustomerAboStatus } from '../../lib/teamApi'
|
|
import { fmtDate, productLabelOf } from '../../lib/format'
|
|
import { storageLabel } from '../../lib/storageFormat'
|
|
import StundenkontoLeiste from './StundenkontoLeiste'
|
|
|
|
// Abo-Status eines Kunden (Reiter "Abo & Angebote"): Appwrite-Spiegel des Stripe-Abos, fuer alle Mitarbeiter
|
|
export default function AboStatusCard({ customerId }) {
|
|
const [abo, setAbo] = useState(null)
|
|
const [error, setError] = useState(null)
|
|
|
|
useEffect(() => {
|
|
let alive = true
|
|
setAbo(null)
|
|
setError(null)
|
|
getCustomerAboStatus(customerId)
|
|
.then((a) => { if (alive) setAbo(a) })
|
|
.catch((err) => { if (alive) setError(err.message || 'Abo konnte nicht geladen werden.') })
|
|
return () => { alive = false }
|
|
}, [customerId])
|
|
|
|
// Nur ein aktives Wartungs-Abo hat ein Stundenkonto (das Hosting-Abo nicht)
|
|
const mitKonto = Boolean(abo && abo.productKey === 'wartung' && abo.active)
|
|
|
|
return (
|
|
<Card title="Abo">
|
|
{error && <div className="msg err" role="alert">{error}</div>}
|
|
{!abo && !error && <div className="loading">Wird geladen …</div>}
|
|
{abo && !abo.status && <p className="muted">kein Abo</p>}
|
|
{abo && abo.status && (
|
|
<dl className={mitKonto ? 'kv mb-2' : 'kv'}>
|
|
<dt>Abo</dt>
|
|
<dd className="flex items-center gap-2 wrap">
|
|
{productLabelOf(abo.productKey)}
|
|
<Badge tone={abo.active ? 'ok' : 'danger'}>{abo.active ? 'aktiv' : abo.status}</Badge>
|
|
</dd>
|
|
<dt>Leistungsbeginn</dt><dd>{fmtDate(abo.serviceStart)}</dd>
|
|
{abo.active && <><dt>Nächste Abbuchung</dt><dd>{fmtDate(abo.currentPeriodEnd)}</dd></>}
|
|
{abo.cancelAt && <><dt>Gekündigt zum</dt><dd>{fmtDate(abo.cancelAt)}</dd></>}
|
|
<dt>Zusatzspeicher</dt><dd>{storageLabel(abo.storageUnits)}</dd>
|
|
</dl>
|
|
)}
|
|
{mitKonto && <StundenkontoLeiste customerId={customerId} />}
|
|
</Card>
|
|
)
|
|
}
|