1import { useState, useEffect } from 'react';
2import { apiFetch } from '../../../lib/api';
3import { notifySuccess, notifyError } from '../../../utils/notifications';
4import DomainRequestDetailModal from './DomainRequestDetailModal';
5import './DomainRequests.css';
7export default function DomainRequestsTable() {
8 const [requests, setRequests] = useState([]);
9 const [loading, setLoading] = useState(true);
10 const [selectedRequest, setSelectedRequest] = useState(null);
11 const [showDetailModal, setShowDetailModal] = useState(false);
12 const [statusFilter, setStatusFilter] = useState('pending');
18 const loadRequests = async () => {
21 const params = new URLSearchParams();
22 if (statusFilter) params.append('status', statusFilter);
24 console.log('[DomainRequests] Fetching with status filter:', statusFilter);
25 const res = await apiFetch(`/domain-requests?${params.toString()}`);
27 throw new Error(`HTTP ${res.status}: ${res.statusText}`);
29 const data = await res.json();
30 console.log('[DomainRequests] Received data:', data);
31 const requestsList = Array.isArray(data) ? data : data.requests || [];
32 console.log('[DomainRequests] Parsed requests list:', requestsList, 'Length:', requestsList.length);
33 setRequests(requestsList);
35 console.error('Error loading domain requests:', err);
36 await notifyError('Load Failed', 'Failed to load domain registration requests');
43 const openDetailModal = (request) => {
44 setSelectedRequest(request);
45 setShowDetailModal(true);
48 const closeDetailModal = () => {
49 setShowDetailModal(false);
50 setSelectedRequest(null);
53 const handleRequestProcessed = () => {
54 loadRequests(); // Reload list after approval/denial
58 const getStatusBadge = (status) => {
59 const statusColors = {
60 pending: { bg: '#fff3e0', text: '#e65100', label: 'Pending' },
61 approved: { bg: '#e8f5e9', text: '#2e7d32', label: 'Approved' },
62 denied: { bg: '#ffebee', text: '#c62828', label: 'Denied' },
63 registered: { bg: '#e3f2fd', text: '#1565c0', label: 'Registered' },
64 failed: { bg: '#fce4ec', text: '#ad1457', label: 'Failed' }
67 const style = statusColors[status] || statusColors.pending;
83 const formatDate = (dateString) => {
84 if (!dateString) return '-';
85 return new Date(dateString).toLocaleDateString('en-US', {
93 return <div>Loading domain registration requests...</div>;
96 console.log('[DomainRequests] Rendering with', requests.length, 'requests');
99 <div className="domain-requests-container">
100 <div className="requests-header">
101 <h2>Domain Registration Requests</h2>
102 <div className="filter-controls">
103 <label>Status:</label>
106 onChange={(e) => setStatusFilter(e.target.value)}
107 style={{ padding: '6px 12px', borderRadius: '4px' }}
109 <option value="">All</option>
110 <option value="pending">Pending</option>
111 <option value="approved">Approved</option>
112 <option value="denied">Denied</option>
113 <option value="registered">Registered</option>
114 <option value="failed">Failed</option>
119 {requests.length === 0 ? (
120 <div className="no-requests">
121 <span className="material-symbols-outlined">inbox</span>
122 <p>No domain registration requests found</p>
125 <div className="table-container">
126 <table className="data-table">
140 {requests.map((request) => (
141 <tr key={request.request_id}>
143 <strong>{request.domain_name}</strong>
146 <span className={`badge ${request.domain_type === 'dns-only' ? 'badge-info' : 'badge-primary'}`}>
147 {request.domain_type === 'dns-only' ? 'DNS Only' : 'Registration'}
150 <td>{request.customer_name || '-'}</td>
152 {request.domain_type === 'dns-only' ? '-' : `${request.years} year${request.years !== 1 ? 's' : ''}`}
155 {request.domain_type === 'dns-only' ? 'Free' : (request.price ? `$${request.price} ${request.currency}` : '-')}
158 <div style={{ fontSize: '0.9em' }}>
159 {formatDate(request.requested_at)}
160 {request.requested_by_name && (
161 <div style={{ color: '#666', fontSize: '0.9em' }}>
162 by {request.requested_by_name}
167 <td>{getStatusBadge(request.status)}</td>
170 className="btn btn-sm"
171 onClick={() => openDetailModal(request)}
183 {showDetailModal && selectedRequest && (
184 <DomainRequestDetailModal
185 request={selectedRequest}
186 onClose={closeDetailModal}
187 onRequestProcessed={handleRequestProcessed}