| import React, { useState } from 'react'; |
| import { ChevronDown, ChevronUp, ShieldAlert, Sparkles, HelpCircle, Lightbulb } from 'lucide-react'; |
|
|
| export default function AnalysisPanel({ report, metrics }) { |
| const [openSection, setOpenSection] = useState('creatures'); |
|
|
| const getStatusColor = (status) => { |
| switch (status?.toLowerCase()) { |
| case 'auspicious': |
| case 'high vitality': |
| case 'safe': |
| return '#50c878'; |
| case 'balanced': |
| case 'neutral': |
| case 'moderate': |
| return '#d4af37'; |
| case 'inauspicious': |
| case 'stagnant': |
| case 'hazardous': |
| default: |
| return '#e53e3e'; |
| } |
| }; |
|
|
| const toggleSection = (section) => { |
| setOpenSection(openSection === section ? null : section); |
| }; |
|
|
| const sections = [ |
| { |
| id: 'creatures', |
| title: '⛰️ Four Celestial Creatures', |
| subtitle: 'Terrain configurations, protection, and viewsheds', |
| data: report.creatures, |
| metricsContent: [ |
| { label: 'Aspect (Facing Direction)', value: `${metrics.aspect_deg}°` }, |
| { label: 'Slope Gradient', value: `${metrics.slope_deg}°` }, |
| { label: 'Backing Ridge Height', value: metrics.relative_backing_elevation_m > 0 ? `+${metrics.relative_backing_elevation_m}m` : 'None' }, |
| { label: 'Front Openness (Bright Hall)', value: `${metrics.front_openness_deg}°` } |
| ] |
| }, |
| { |
| id: 'vitality', |
| title: '🌱 Qi Flow & Microclimate', |
| subtitle: 'Photosynthetic vitality and thermal balance', |
| data: report.vitality, |
| metricsContent: [ |
| { label: 'Vegetation Index (NDVI)', value: metrics.ndvi }, |
| { label: 'Thermal Deviation (LST)', value: `${metrics.lst_deviation_c > 0 ? '+' : ''}${metrics.lst_deviation_c}°C` } |
| ] |
| }, |
| { |
| id: 'water', |
| title: '💧 Water Feng Shui', |
| subtitle: 'Sinuosity, hydrology, and curvature safety', |
| data: report.water, |
| metricsContent: [ |
| { label: 'Water Distance', value: metrics.water_distance_m < 9000 ? `${metrics.water_distance_m}m` : 'None nearby' }, |
| { label: 'Hydrologic Bend Type', value: metrics.water_curve_type === 'concave_embrace' ? 'Embracing (Concave)' : (metrics.water_curve_type === 'convex_bow' ? 'Bow (Convex)' : 'None/Linear') } |
| ] |
| }, |
| { |
| id: 'sha_qi', |
| title: '⚡ Sha Qi & Urban Hazards', |
| subtitle: 'Road clashing, corner knives, and electromagnetic fields', |
| data: report.sha_qi, |
| metricsContent: [ |
| { label: 'T-Junction Road Clashes', value: metrics.sha_qi_t_junctions }, |
| { label: 'Adjacent Corner Knives', value: metrics.sha_qi_building_corners }, |
| { label: 'EMF Proximity Distance', value: `${metrics.emf_distance_m}m` } |
| ] |
| } |
| ]; |
|
|
| return ( |
| <div style={{ display: 'flex', flexDirection: 'column', gap: '12px', width: '100%' }}> |
| {sections.map((sec) => { |
| const isOpen = openSection === sec.id; |
| const statusColor = getStatusColor(sec.data.status); |
| |
| return ( |
| <div key={sec.id} className="glass-panel" style={{ |
| overflow: 'hidden', |
| borderLeft: `4px solid ${statusColor}` |
| }}> |
| {/* Header Accordion Bar */} |
| <div |
| onClick={() => toggleSection(sec.id)} |
| style={{ |
| padding: '16px', |
| cursor: 'pointer', |
| display: 'flex', |
| justifyContent: 'space-between', |
| alignItems: 'center', |
| userSelect: 'none', |
| background: isOpen ? 'rgba(255,255,255,0.02)' : 'transparent', |
| transition: 'background 0.2s ease' |
| }} |
| > |
| <div> |
| <h3 style={{ fontSize: '16px', display: 'flex', alignItems: 'center', gap: '8px' }}> |
| {sec.title} |
| <span style={{ |
| fontSize: '10px', |
| fontWeight: 'bold', |
| textTransform: 'uppercase', |
| color: '#fff', |
| backgroundColor: statusColor, |
| padding: '2px 8px', |
| borderRadius: '10px', |
| letterSpacing: '0.05em' |
| }}> |
| {sec.data.status} |
| </span> |
| </h3> |
| <p style={{ fontSize: '12px', color: 'var(--text-secondary)', marginTop: '2px' }}> |
| {sec.subtitle} |
| </p> |
| </div> |
| <div> |
| {isOpen ? <ChevronUp size={18} color="var(--text-secondary)" /> : <ChevronDown size={18} color="var(--text-secondary)" />} |
| </div> |
| </div> |
| |
| {/* Content Body */} |
| {isOpen && ( |
| <div style={{ |
| padding: '16px', |
| borderTop: '1px solid var(--border-glass)', |
| display: 'flex', |
| flexDirection: 'column', |
| gap: '16px', |
| background: 'rgba(0,0,0,0.1)' |
| }}> |
| {/* Micro Metrics Grid */} |
| <div style={{ |
| display: 'grid', |
| gridTemplateColumns: 'repeat(2, 1fr)', |
| gap: '10px', |
| background: 'rgba(255,255,255,0.01)', |
| padding: '10px', |
| borderRadius: '6px', |
| border: '1px solid rgba(255,255,255,0.02)' |
| }}> |
| {sec.metricsContent.map((metric, idx) => ( |
| <div key={idx} style={{ display: 'flex', flexDirection: 'column' }}> |
| <span style={{ fontSize: '10px', color: 'var(--text-muted)', textTransform: 'uppercase' }}> |
| {metric.label} |
| </span> |
| <span style={{ fontSize: '13px', fontWeight: '600', color: 'var(--text-primary)', marginTop: '2px' }}> |
| {metric.value} |
| </span> |
| </div> |
| ))} |
| </div> |
| |
| {/* Explanations Accordion Cards */} |
| <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}> |
| {/* Feng Shui explanation */} |
| <div style={{ |
| padding: '12px', |
| borderRadius: '8px', |
| background: 'linear-gradient(135deg, rgba(34,139,34,0.04) 0%, rgba(0,0,0,0) 100%)', |
| border: '1px solid rgba(80,200,120,0.08)' |
| }}> |
| <h4 style={{ |
| fontSize: '13px', |
| color: 'var(--color-jade-light)', |
| display: 'flex', |
| alignItems: 'center', |
| gap: '6px', |
| marginBottom: '6px' |
| }}> |
| <Sparkles size={14} /> Traditional Feng Shui |
| </h4> |
| <p style={{ fontSize: '12.5px', lineHeight: '1.5', color: '#e2e8f0', fontStyle: 'italic' }}> |
| "{sec.data.feng_shui_exp}" |
| </p> |
| </div> |
| |
| {/* Scientific explanation */} |
| <div style={{ |
| padding: '12px', |
| borderRadius: '8px', |
| background: 'linear-gradient(135deg, rgba(212,175,55,0.04) 0%, rgba(0,0,0,0) 100%)', |
| border: '1px solid rgba(212,175,55,0.1)' |
| }}> |
| <h4 style={{ |
| fontSize: '13px', |
| color: 'var(--color-gold)', |
| display: 'flex', |
| alignItems: 'center', |
| gap: '6px', |
| marginBottom: '6px' |
| }}> |
| <HelpCircle size={14} /> Environmental Science |
| </h4> |
| <p style={{ fontSize: '12.5px', lineHeight: '1.5', color: '#cbd5e0' }}> |
| {sec.data.scientific_exp} |
| </p> |
| </div> |
| </div> |
| |
| {/* Remedies Section */} |
| {sec.data.remedies && sec.data.remedies.length > 0 && ( |
| <div style={{ marginTop: '4px' }}> |
| <h4 style={{ |
| fontSize: '13px', |
| color: 'var(--text-primary)', |
| display: 'flex', |
| alignItems: 'center', |
| gap: '6px', |
| marginBottom: '10px', |
| fontWeight: 'bold', |
| fontFamily: 'var(--font-sans)', |
| textTransform: 'uppercase', |
| letterSpacing: '0.05em' |
| }}> |
| <Lightbulb size={14} color="var(--color-gold)" /> Actionable Remedies & Mitigations |
| </h4> |
| <div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}> |
| {sec.data.remedies.map((rem, idx) => ( |
| <div key={idx} style={{ |
| background: 'rgba(255, 255, 255, 0.02)', |
| border: '1px solid var(--border-glass)', |
| borderRadius: '8px', |
| overflow: 'hidden' |
| }}> |
| <div style={{ |
| padding: '8px 12px', |
| background: 'rgba(255,255,255,0.03)', |
| fontSize: '12px', |
| fontWeight: '600', |
| borderBottom: '1px solid var(--border-glass)', |
| color: 'var(--color-gold)' |
| }}> |
| {rem.title} |
| </div> |
| <div style={{ |
| display: 'grid', |
| gridTemplateColumns: '1fr 1fr', |
| fontSize: '11.5px', |
| lineHeight: '1.4' |
| }}> |
| <div style={{ |
| padding: '10px', |
| borderRight: '1px solid var(--border-glass)', |
| background: 'rgba(34,139,34,0.01)' |
| }}> |
| <div style={{ color: 'var(--color-jade-light)', fontWeight: 'bold', marginBottom: '2px' }}>Feng Shui Master</div> |
| <div style={{ color: '#e2e8f0' }}>{rem.feng_shui}</div> |
| </div> |
| <div style={{ |
| padding: '10px', |
| background: 'rgba(212,175,55,0.01)' |
| }}> |
| <div style={{ color: 'var(--color-gold)', fontWeight: 'bold', marginBottom: '2px' }}>GIS Engineer</div> |
| <div style={{ color: '#cbd5e0' }}>{rem.scientific}</div> |
| </div> |
| </div> |
| </div> |
| ))} |
| </div> |
| </div> |
| )} |
| </div> |
| )} |
| </div> |
| ); |
| })} |
| </div> |
| ); |
| } |
|
|