upgraded modal

This commit is contained in:
jassim 2025-11-04 17:47:50 +05:30
parent 226fdc3948
commit c2fe1a3ca6
2 changed files with 254 additions and 7 deletions

View File

@ -1433,3 +1433,159 @@
font-size: 13px; font-size: 13px;
} }
} }
/* Hookpilot Status Modal */
.hookpilot-modal-overlay {
z-index: 10000;
}
.hookpilot-modal-content {
max-width: 500px;
text-align: center;
}
.hookpilot-modal-header {
padding: 32px 24px 24px;
border-bottom: 1px solid #e2e8f0;
}
.hookpilot-modal-header h3 {
margin: 0;
font-size: 24px;
font-weight: 700;
color: #1e293b;
}
.hookpilot-modal-body {
padding: 32px 24px;
}
.hookpilot-message {
font-size: 16px;
color: #475569;
margin: 0 0 16px 0;
line-height: 1.6;
}
.hookpilot-error-details {
background: #fef2f2;
border: 1px solid #fecaca;
border-radius: 8px;
padding: 16px;
margin: 16px 0;
}
.hookpilot-error-details p {
margin: 0;
color: #dc2626;
font-size: 14px;
line-height: 1.5;
font-family: 'Courier New', monospace;
}
.hookpilot-subtext {
font-size: 14px;
color: #64748b;
margin: 16px 0 0 0;
font-style: italic;
}
.hookpilot-spinner {
margin: 24px auto;
width: 48px;
height: 48px;
border: 4px solid #e2e8f0;
border-top: 4px solid #3b82f6;
border-radius: 50%;
animation: hookpilot-spin 0.8s linear infinite;
}
@keyframes hookpilot-spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.hookpilot-modal-actions {
margin-top: 24px;
display: flex;
justify-content: center;
gap: 12px;
}
.hookpilot-modal-btn {
padding: 12px 32px;
font-size: 15px;
font-weight: 600;
border: none;
border-radius: 8px;
cursor: pointer;
transition: all 0.2s ease;
background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
color: white;
box-shadow: 0 2px 4px rgba(59, 130, 246, 0.2);
}
.hookpilot-modal-btn:hover {
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(59, 130, 246, 0.3);
}
.hookpilot-modal-btn:active {
transform: translateY(0);
}
/* Success state styling */
.hookpilot-modal-content.hookpilot-success .hookpilot-modal-header {
background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%);
border-bottom: 2px solid #10b981;
}
.hookpilot-modal-content.hookpilot-success .hookpilot-modal-header h3 {
color: #065f46;
}
/* Error state styling */
.hookpilot-modal-content.hookpilot-error .hookpilot-modal-header {
background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%);
border-bottom: 2px solid #ef4444;
}
.hookpilot-modal-content.hookpilot-error .hookpilot-modal-header h3 {
color: #991b1b;
}
/* Warning state styling */
.hookpilot-modal-content.hookpilot-warning .hookpilot-modal-header {
background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);
border-bottom: 2px solid #f59e0b;
}
.hookpilot-modal-content.hookpilot-warning .hookpilot-modal-header h3 {
color: #92400e;
}
/* Sending state styling */
.hookpilot-modal-content.hookpilot-sending .hookpilot-modal-header {
background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
border-bottom: 2px solid #3b82f6;
}
.hookpilot-modal-content.hookpilot-sending .hookpilot-modal-header h3 {
color: #1e40af;
}
/* Responsive adjustments */
@media (max-width: 600px) {
.hookpilot-modal-content {
max-width: 90%;
margin: 20px;
}
.hookpilot-modal-header h3 {
font-size: 20px;
}
.hookpilot-message {
font-size: 15px;
}
}

View File

@ -10,6 +10,7 @@ function UnifiedAnalysis({ analysisData }) {
const [currentPage, setCurrentPage] = useState(1) const [currentPage, setCurrentPage] = useState(1)
const [itemsPerPage, setItemsPerPage] = useState(25) const [itemsPerPage, setItemsPerPage] = useState(25)
const [selectedDomain, setSelectedDomain] = useState(null) // Track which domain modal is open const [selectedDomain, setSelectedDomain] = useState(null) // Track which domain modal is open
const [hookpilotModal, setHookpilotModal] = useState({ show: false, status: 'sending', message: '', error: '' }) // Hookpilot status modal
if (!analysisData) return null if (!analysisData) return null
@ -31,8 +32,13 @@ function UnifiedAnalysis({ analysisData }) {
const hasKeywordOpportunities = informationalGapKeywords.length > 0 const hasKeywordOpportunities = informationalGapKeywords.length > 0
const handleSendToHookpilot = async () => { const handleSendToHookpilot = async () => {
// Initial alert to inform user // Show sending modal
alert('⏳ Sending data to Hookpilot...\n\nYou will be notified once the operation completes or if any issues occur.') setHookpilotModal({
show: true,
status: 'sending',
message: 'Sending data to Hookpilot...',
error: ''
})
setSending(true) setSending(true)
setHookpilotStatus(null) setHookpilotStatus(null)
@ -41,22 +47,41 @@ function UnifiedAnalysis({ analysisData }) {
const result = await sendToHookpilot(analysisData) const result = await sendToHookpilot(analysisData)
setHookpilotStatus(result) setHookpilotStatus(result)
// Success alert // Show success or warning modal
if (result.success) { if (result.success) {
alert('✅ Success!\n\nData has been successfully sent to Hookpilot.') setHookpilotModal({
show: true,
status: 'success',
message: 'Data has been successfully sent to Hookpilot!',
error: ''
})
} else { } else {
alert('⚠️ Warning!\n\nData was sent but Hookpilot returned an unexpected response. Please check the status below.') setHookpilotModal({
show: true,
status: 'warning',
message: 'Data was sent but Hookpilot returned an unexpected response.',
error: 'Please check the status below for more details.'
})
} }
} catch (error) { } catch (error) {
setHookpilotStatus({ success: false, error: error.message }) setHookpilotStatus({ success: false, error: error.message })
// Error alert // Show error modal
alert(`❌ Error!\n\nFailed to send data to Hookpilot:\n\n${error.message}`) setHookpilotModal({
show: true,
status: 'error',
message: 'Failed to send data to Hookpilot',
error: error.message
})
} finally { } finally {
setSending(false) setSending(false)
} }
} }
const closeHookpilotModal = useCallback(() => {
setHookpilotModal({ show: false, status: '', message: '', error: '' })
}, [])
// Use gap keywords directly (no tabs needed) // Use gap keywords directly (no tabs needed)
const currentKeywords = informationalGapKeywords const currentKeywords = informationalGapKeywords
@ -712,6 +737,72 @@ function UnifiedAnalysis({ analysisData }) {
</div> </div>
</div> </div>
)} )}
{/* Hookpilot Status Modal */}
{hookpilotModal.show && (
<div
className="modal-overlay hookpilot-modal-overlay"
onClick={hookpilotModal.status !== 'sending' ? closeHookpilotModal : undefined}
>
<div
className={`modal-content hookpilot-modal-content hookpilot-${hookpilotModal.status}`}
onClick={(e) => e.stopPropagation()}
>
<div className="modal-header hookpilot-modal-header">
{hookpilotModal.status === 'sending' && (
<>
<h3> Sending to Hookpilot</h3>
<div className="hookpilot-spinner"></div>
</>
)}
{hookpilotModal.status === 'success' && (
<>
<h3> Success!</h3>
<button className="modal-close" onClick={closeHookpilotModal}></button>
</>
)}
{hookpilotModal.status === 'warning' && (
<>
<h3> Warning</h3>
<button className="modal-close" onClick={closeHookpilotModal}></button>
</>
)}
{hookpilotModal.status === 'error' && (
<>
<h3> Error</h3>
<button className="modal-close" onClick={closeHookpilotModal}></button>
</>
)}
</div>
<div className="modal-body hookpilot-modal-body">
<p className="hookpilot-message">{hookpilotModal.message}</p>
{hookpilotModal.error && (
<div className="hookpilot-error-details">
<p>{hookpilotModal.error}</p>
</div>
)}
{hookpilotModal.status === 'sending' && (
<p className="hookpilot-subtext">
You will be notified once the operation completes or if any issues occur.
</p>
)}
{hookpilotModal.status !== 'sending' && (
<div className="hookpilot-modal-actions">
<button
className="hookpilot-modal-btn"
onClick={closeHookpilotModal}
>
Close
</button>
</div>
)}
</div>
</div>
</div>
)}
</div> </div>
) )
} }