1const getStatusBadge = (status) => {
3 active: { label: 'Active', class: 'badge-success' },
4 expired: { label: 'Expired', class: 'badge-error' },
5 pending: { label: 'Pending', class: 'badge-warning' },
6 cancelled: { label: 'Cancelled', class: 'badge-secondary' }
8 const badge = badges[status] || badges.active;
9 return <span className={`badge ${badge.class}`}>{badge.label}</span>;
12const getDomainTypeBadge = (domainType) => {
13 if (domainType === 'dns_only') {
14 return <span className="badge badge-info" title="DNS management only">DNS Only</span>;
16 return <span className="badge badge-success" title="Full registration management">Registered</span>;
19const getLockBadge = (locked) => {
20 if (locked === true) {
22 <span className="badge" style={{ background: '#4CAF50', color: 'white' }} title="Domain is locked (protected from transfer)">
26 } else if (locked === false) {
28 <span className="badge" style={{ background: '#FF9800', color: 'white' }} title="Domain is unlocked (can be transferred)">
33 return <span className="badge badge-secondary">-</span>;
36const getRegistrarLogo = (registrar) => {
43 return logos[registrar] || logos.other;
46export default function DomainTableRow({ domain, onEdit, onDelete, onManageDNS, onManage, isRootTenant }) {
47 // Parse metadata if it's a string
48 let metadata = domain.metadata || {};
49 if (typeof metadata === 'string') {
51 metadata = JSON.parse(metadata);
53 console.error(`Failed to parse metadata for ${domain.domain_name}:`, e);
58 const domainType = metadata.domain_type || 'registered'; // Default to registered for backward compatibility
59 const locked = metadata.locked;
60 const hasCloudflare = metadata.has_cloudflare_dns || metadata.cloudflare_zone_id;
62 // Debug log auto_renew for troubleshooting
63 if (metadata.auto_renew !== undefined) {
64 console.log(`[DomainRow] ${domain.domain_name} - auto_renew:`, metadata.auto_renew, 'type:', typeof metadata.auto_renew);
67 // Calculate days until expiry (only for registered domains)
68 let daysUntilExpiry = null;
69 let isExpiringSoon = false;
70 if (domain.expiration_date && domainType === 'registered') {
71 daysUntilExpiry = Math.ceil((new Date(domain.expiration_date) - new Date()) / (1000 * 60 * 60 * 24));
72 isExpiringSoon = daysUntilExpiry <= 30 && daysUntilExpiry > 0;
78 <div style={{ display: 'flex', alignItems: 'center', gap: '8px', flexDirection: 'column', alignItems: 'flex-start' }}>
79 <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
80 <span style={{ fontSize: '20px' }}>{getRegistrarLogo(domain.registrar)}</span>
81 <strong>{domain.domain_name}</strong>
83 <span title="Using Cloudflare DNS" style={{ fontSize: '16px' }}>☁️</span>
86 <div style={{ display: 'flex', gap: '4px', fontSize: '12px' }}>
87 {getDomainTypeBadge(domainType)}
88 {domainType === 'registered' && getLockBadge(locked)}
94 <span className="badge badge-info">{domain.tenant_subdomain || 'N/A'}</span>
97 <td>{domain.customer_name || 'N/A'}</td>
98 <td style={{ textTransform: 'capitalize' }}>{domain.registrar}</td>
101 {domain.expiration_date ? (
103 {new Date(domain.expiration_date).toLocaleDateString()}
105 <span className="badge badge-warning" style={{ marginLeft: '8px', fontSize: '11px' }}>
106 {daysUntilExpiry} days
109 {daysUntilExpiry < 0 && (
110 <span className="badge badge-error" style={{ marginLeft: '8px', fontSize: '11px' }}>
116 <span style={{ color: 'var(--text-secondary)' }}>N/A</span>
120 <td>{getStatusBadge(domain.status)}</td>
122 {domainType === 'registered' ? (
123 metadata.auto_renew ? (
124 <span className="badge badge-success">Yes</span>
126 <span className="badge badge-secondary">No</span>
129 <span className="badge badge-secondary">-</span>
132 <td>{domain.contract_title || '-'}</td>
134 <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
135 {/* DNS Management - available for all */}
137 className="btn btn-sm"
138 onClick={() => onManageDNS(domain)}
139 title="Manage DNS Records"
140 style={{ background: '#2196F3', color: 'white' }}
142 <span className="material-symbols-outlined">dns</span>
145 {/* Domain Management - only for registered domains */}
146 {domainType === 'registered' && onManage && (
148 className="btn btn-sm"
149 onClick={() => onManage(domain)}
150 title="Domain Management (Lock, Transfer Code, Auto-Renew)"
151 style={{ background: '#9C27B0', color: 'white' }}
153 <span className="material-symbols-outlined">settings</span>
159 className="btn btn-sm btn-secondary"
160 onClick={() => onEdit(domain)}
163 <span className="material-symbols-outlined">edit</span>
168 className="btn btn-sm btn-error"
169 onClick={() => onDelete(domain.domain_id)}
170 title="Delete domain"
172 <span className="material-symbols-outlined">delete</span>