// frontend/src/pages/bellcloud/devices/tabs/WarrantyTab.jsx import Button from '@/components/ui/Button' import StatusBadge from '@/components/ui/StatusBadge' import { fmtDateMedium, fmtDateLong } from '@/lib/formatters' // ─── Helpers ────────────────────────────────────────────────────────────────── function parseDate(val) { if (!val) return null // Firestore Timestamp object if (typeof val === 'object' && typeof val.seconds === 'number') { return new Date(val.seconds * 1000) } const d = new Date(val) return isNaN(d.getTime()) ? null : d } function addDays(date, days) { if (!date || !days) return null const d = new Date(date) d.setDate(d.getDate() + Number(days)) return d } function daysUntil(date) { if (!date) return null return Math.ceil((date.getTime() - Date.now()) / 86400000) } /** 0–100 how much of the period has ELAPSED */ function calcProgress(start, end) { if (!start || !end) return null const total = end.getTime() - start.getTime() if (total <= 0) return 100 const elapsed = Date.now() - start.getTime() return Math.min(100, Math.max(0, Math.round((elapsed / total) * 100))) } /** Remaining portion (inverse of elapsed) */ function calcRemaining(start, end) { const p = calcProgress(start, end) return p === null ? null : 100 - p } function daysLabel(days) { if (days == null || days === 0) return '—' if (days % 365 === 0) { const y = days / 365 return `${y} year${y !== 1 ? 's' : ''}` } if (days % 30 === 0) { const m = days / 30 return `${m} month${m !== 1 ? 's' : ''}` } return `${days} day${days !== 1 ? 's' : ''}` } // ─── Glass surface styles ───────────────────────────────────────────────────── const GLASS = { background: 'rgba(28, 32, 38, 0.30)', backdropFilter: 'var(--blur-modal)', WebkitBackdropFilter: 'var(--blur-modal)', border: '1px solid var(--color-border)', boxShadow: 'var(--shadow-card), var(--shadow-md)', borderRadius: 'var(--radius-xl)', } const GLASS_ELEVATED = { background: 'rgba(28, 32, 38, 0.40)', backdropFilter: 'var(--blur-modal)', WebkitBackdropFilter: 'var(--blur-modal)', border: '1px solid var(--color-border)', boxShadow: 'var(--shadow-sm)', borderRadius: 'var(--radius-lg)', } // ─── Primitives ─────────────────────────────────────────────────────────────── function SectionLabel({ children }) { return ( {children} ) } function InfoCell({ label, children }) { return (
{label} {children ?? '—'}
) } function ProgressBar({ value, color = 'var(--color-primary)', label, showPct = true }) { const pct = Math.max(0, Math.min(100, value ?? 0)) return (
{(label || showPct) && (
{label && ( {label} )} {showPct && ( {pct}% )}
)}
) } function Divider() { return
} function DetailRow({ label, value, valueColor }) { return (
{label} {value ?? '—'}
) } // ─── Subscription Hero ──────────────────────────────────────────────────────── function SubscriptionHero({ sub, canEdit, onEditSubscription, deviceUsers }) { const subscrStart = parseDate(sub?.subscrStart) const subscrEnd = addDays(subscrStart, sub?.subscrDuration) const daysLeft = daysUntil(subscrEnd) const remaining = calcRemaining(subscrStart, subscrEnd) const isActive = daysLeft === null || daysLeft > 0 const tier = sub?.subscrTier || null const progressColor = daysLeft === null ? 'var(--color-primary)' : daysLeft > 60 ? 'var(--color-success)' : daysLeft > 14 ? 'var(--color-warning)' : 'var(--color-danger)' // Registered users = actual device users count passed from parent const regUsers = Array.isArray(deviceUsers) ? deviceUsers.length : null const maxUsers = sub?.maxUsers ?? null const hwOutputs = sub?.hw_outputs ?? null const maxOutputs = sub?.maxOutputs ?? null return (
{/* Left accent glow */}