EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
DomainTableRow.jsx
Go to the documentation of this file.
1const getStatusBadge = (status) => {
2 const badges = {
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' }
7 };
8 const badge = badges[status] || badges.active;
9 return <span className={`badge ${badge.class}`}>{badge.label}</span>;
10};
11
12const getDomainTypeBadge = (domainType) => {
13 if (domainType === 'dns_only') {
14 return <span className="badge badge-info" title="DNS management only">DNS Only</span>;
15 }
16 return <span className="badge badge-success" title="Full registration management">Registered</span>;
17};
18
19const getLockBadge = (locked) => {
20 if (locked === true) {
21 return (
22 <span className="badge" style={{ background: '#4CAF50', color: 'white' }} title="Domain is locked (protected from transfer)">
23 🔒 Locked
24 </span>
25 );
26 } else if (locked === false) {
27 return (
28 <span className="badge" style={{ background: '#FF9800', color: 'white' }} title="Domain is unlocked (can be transferred)">
29 🔓 Unlocked
30 </span>
31 );
32 }
33 return <span className="badge badge-secondary">-</span>;
34};
35
36const getRegistrarLogo = (registrar) => {
37 const logos = {
38 enom: '🌐',
39 moniker: '🔷',
40 cloudflare: '☁️',
41 other: '🌍'
42 };
43 return logos[registrar] || logos.other;
44};
45
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') {
50 try {
51 metadata = JSON.parse(metadata);
52 } catch (e) {
53 console.error(`Failed to parse metadata for ${domain.domain_name}:`, e);
54 metadata = {};
55 }
56 }
57
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;
61
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);
65 }
66
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;
73 }
74
75 return (
76 <tr>
77 <td>
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>
82 {hasCloudflare && (
83 <span title="Using Cloudflare DNS" style={{ fontSize: '16px' }}>☁️</span>
84 )}
85 </div>
86 <div style={{ display: 'flex', gap: '4px', fontSize: '12px' }}>
87 {getDomainTypeBadge(domainType)}
88 {domainType === 'registered' && getLockBadge(locked)}
89 </div>
90 </div>
91 </td>
92 {isRootTenant && (
93 <td>
94 <span className="badge badge-info">{domain.tenant_subdomain || 'N/A'}</span>
95 </td>
96 )}
97 <td>{domain.customer_name || 'N/A'}</td>
98 <td style={{ textTransform: 'capitalize' }}>{domain.registrar}</td>
99 <td>
100 <div>
101 {domain.expiration_date ? (
102 <>
103 {new Date(domain.expiration_date).toLocaleDateString()}
104 {isExpiringSoon && (
105 <span className="badge badge-warning" style={{ marginLeft: '8px', fontSize: '11px' }}>
106 {daysUntilExpiry} days
107 </span>
108 )}
109 {daysUntilExpiry < 0 && (
110 <span className="badge badge-error" style={{ marginLeft: '8px', fontSize: '11px' }}>
111 Expired
112 </span>
113 )}
114 </>
115 ) : (
116 <span style={{ color: 'var(--text-secondary)' }}>N/A</span>
117 )}
118 </div>
119 </td>
120 <td>{getStatusBadge(domain.status)}</td>
121 <td>
122 {domainType === 'registered' ? (
123 metadata.auto_renew ? (
124 <span className="badge badge-success">Yes</span>
125 ) : (
126 <span className="badge badge-secondary">No</span>
127 )
128 ) : (
129 <span className="badge badge-secondary">-</span>
130 )}
131 </td>
132 <td>{domain.contract_title || '-'}</td>
133 <td>
134 <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
135 {/* DNS Management - available for all */}
136 <button
137 className="btn btn-sm"
138 onClick={() => onManageDNS(domain)}
139 title="Manage DNS Records"
140 style={{ background: '#2196F3', color: 'white' }}
141 >
142 <span className="material-symbols-outlined">dns</span>
143 </button>
144
145 {/* Domain Management - only for registered domains */}
146 {domainType === 'registered' && onManage && (
147 <button
148 className="btn btn-sm"
149 onClick={() => onManage(domain)}
150 title="Domain Management (Lock, Transfer Code, Auto-Renew)"
151 style={{ background: '#9C27B0', color: 'white' }}
152 >
153 <span className="material-symbols-outlined">settings</span>
154 </button>
155 )}
156
157 {/* Edit */}
158 <button
159 className="btn btn-sm btn-secondary"
160 onClick={() => onEdit(domain)}
161 title="Edit domain"
162 >
163 <span className="material-symbols-outlined">edit</span>
164 </button>
165
166 {/* Delete */}
167 <button
168 className="btn btn-sm btn-error"
169 onClick={() => onDelete(domain.domain_id)}
170 title="Delete domain"
171 >
172 <span className="material-symbols-outlined">delete</span>
173 </button>
174 </div>
175 </td>
176 </tr>
177 );
178}