diff --git a/components/Data/Generator/Meteorologists/JVH/cloud-classifier.tsx b/components/Data/Generator/Meteorologists/JVH/cloud-classifier.tsx index b318fd14..739eddb0 100644 --- a/components/Data/Generator/Meteorologists/JVH/cloud-classifier.tsx +++ b/components/Data/Generator/Meteorologists/JVH/cloud-classifier.tsx @@ -1,16 +1,22 @@ 'use client' -import { useState } from 'react' +import { useState, useEffect } from 'react' import { Slider } from '@/components/ui/slider' import { Badge } from '@/components/ui/badge' -import { CloudPattern } from '../../../../../types/Generators/JVH/atmosphere' +import { CloudPattern, CloudConfiguration } from '../../../../../types/Generators/JVH/atmosphere' import { cloudCompositions } from '../../../../../data/cloud-compositions' import { Cloud, Wind, TornadoIcon as Hurricane, Waves, Activity } from 'lucide-react' import { CloudCanvas } from './cloud-canvas' import { SciFiPanel } from '../../../../ui/styles/sci-fi/panel' import { SciFiButton } from '../../../../ui/styles/sci-fi/button' +import { ConfigIOPanel } from './configuration' -export default function CloudClassifier() { +interface CloudSignalProps { + classificationConfig?: CloudConfiguration + classificationId: string +}; + +export default function CloudClassifier({ classificationConfig, classificationId }: CloudSignalProps) { const [selectedPatterns, setSelectedPatterns] = useState([]) const [altitude, setAltitude] = useState(500) @@ -18,20 +24,18 @@ export default function CloudClassifier() { { type: 'featureless' as const, icon: , label: 'Featureless' }, { type: 'turbulent' as const, icon: , label: 'Turbulent' }, { type: 'vortex' as const, icon: , label: 'Vortex' }, - { type: 'bands' as const, icon: , label: 'Bands' }, - ] + { type: 'bands' as const, icon: , label: 'Bands' } + ]; const togglePattern = (pattern: CloudPattern) => { - setSelectedPatterns(current => - current.includes(pattern) - ? current.filter(p => p !== pattern) - : [...current, pattern] - ) - } + setSelectedPatterns((current) => + current.includes(pattern) ? current.filter((p) => p !== pattern) : [...current, pattern] + ); + }; const getCompositionAnalysis = () => { const analysis = new Set() - selectedPatterns.forEach(pattern => { + selectedPatterns.forEach((pattern) => { switch (pattern) { case 'featureless': analysis.add('ammonia') @@ -54,10 +58,28 @@ export default function CloudClassifier() { return Array.from(analysis) } + const getCurrentConfig = (): CloudConfiguration => ({ + patterns: selectedPatterns, + altitude, + timestamp: new Date().toISOString() + }) + + const handleImport = (config: CloudConfiguration) => { + setSelectedPatterns(config.patterns) + setAltitude(config.altitude) + } + + // Initialize the component state with classificationConfig if available + useEffect(() => { + if (classificationConfig) { + setSelectedPatterns(classificationConfig.patterns || []) + setAltitude(classificationConfig.altitude || 500) + } + }, [classificationConfig]) + return (
- {/* Header */}
@@ -72,7 +94,6 @@ export default function CloudClassifier() {
- {/* Control Panel */}

Pattern Selection

@@ -110,7 +131,6 @@ export default function CloudClassifier() {
- {/* Visualization Panel */}

Cloud Formation Display

@@ -119,7 +139,12 @@ export default function CloudClassifier() {
- {/* Analysis Panel */} + + {selectedPatterns.length > 0 && (

Composition Analysis

@@ -139,12 +164,12 @@ export default function CloudClassifier() { })}
- {selectedPatterns.map(pattern => ( + {selectedPatterns.map((pattern) => (

- {pattern === 'featureless' && "STATUS: Calm atmospheric region detected"} - {pattern === 'turbulent' && "WARNING: Strong atmospheric activity present"} - {pattern === 'vortex' && "ALERT: Deep storm system identified"} - {pattern === 'bands' && "INFO: Zonal jet streams observed"} + {pattern === 'featureless' && 'STATUS: Calm atmospheric region detected'} + {pattern === 'turbulent' && 'WARNING: Strong atmospheric activity present'} + {pattern === 'vortex' && 'ALERT: Deep storm system identified'} + {pattern === 'bands' && 'INFO: Zonal jet streams observed'}

))}
@@ -153,6 +178,5 @@ export default function CloudClassifier() { )}
- ) -} - + ); +}; \ No newline at end of file diff --git a/components/Data/Generator/Meteorologists/JVH/configuration.tsx b/components/Data/Generator/Meteorologists/JVH/configuration.tsx new file mode 100644 index 00000000..5f9a9b82 --- /dev/null +++ b/components/Data/Generator/Meteorologists/JVH/configuration.tsx @@ -0,0 +1,145 @@ +'use client' + +import { useState } from 'react' +import { SciFiPanel } from '@/components/ui/styles/sci-fi/panel' +import { SciFiButton } from '@/components/ui/styles/sci-fi/button' +import { Textarea } from '@/components/ui/textarea' +import { CloudConfiguration } from '@/types/Generators/JVH/atmosphere' +import { Download, Upload, AlertCircle } from 'lucide-react' +import { useSupabaseClient } from '@supabase/auth-helpers-react' + +interface ConfigIOPanelProps { + currentConfig: CloudConfiguration + classificationId: string + onImport: (config: CloudConfiguration) => void +}; + +export function ConfigIOPanel({ currentConfig, classificationId, onImport }: ConfigIOPanelProps) { + const supabase = useSupabaseClient() + + const [importText, setImportText] = useState('') + const [error, setError] = useState(null) + + const exportConfig = () => { + const configString = JSON.stringify(currentConfig, null, 2) + setImportText(configString) + setError(null) + } + + const [exporting, setExporting] = useState(false) + + const handleExport = async () => { + if (!classificationId) { + console.error('Classification ID not found.') + return + } + + setExporting(true) + try { + const { data, error } = await supabase + .from('classifications') + .select('classificationConfiguration') + .eq('id', classificationId) + .single() + + if (error) throw error + + const currentConfiguration = data?.classificationConfiguration || {} + const cloudData = currentConfiguration.cloudData || {} + + // Combine the new fields with cloudData without nested errors + const updatedConfig = { + ...cloudData, // Keep the original cloud data + patterns: currentConfig.patterns || [], // Add patterns + altitude: currentConfig.altitude || 500, // Add altitude + timestamp: currentConfig.timestamp || new Date().toISOString(), // Add timestamp + } + + const { error: updateError } = await supabase + .from('classifications') + .update({ + classificationConfiguration: updatedConfig + }) + .eq('id', classificationId) + + if (updateError) throw updateError + + alert('Cloud data exported successfully!') + } catch (err) { + console.error('Error exporting cloud data:', err) + alert('Failed to export cloud data.') + } finally { + setExporting(false) + } + + const configString = JSON.stringify(currentConfig, null, 2) + setImportText(configString) + setError(null) + } + + const importConfig = () => { + try { + const config = JSON.parse(importText) as CloudConfiguration + + if (!config.patterns || !Array.isArray(config.patterns)) { + throw new Error('Invalid patterns configuration') + } + if (typeof config.altitude !== 'number' || config.altitude < 0 || config.altitude > 1000) { + throw new Error('Invalid altitude value') + } + if (!config.timestamp) { + throw new Error('Missing timestamp') + } + + onImport(config) + setError(null) + } catch (err) { + setError('Invalid configuration format') + } + } + + return ( + +
+
+

Configuration Transfer

+
+ + + Export + + + + Import + +
+
+ +
+

Current Configuration

+
+            {JSON.stringify(currentConfig, null, 2)}
+          
+
+ +