Skip to content

Commit 8525ac5

Browse files
committed
🚡🔮 ↝ [SSP-66 SSM-124 SSM-125]: Planet generator import/export with atmos and biome data
1 parent 72505a1 commit 8525ac5

File tree

3 files changed

+134
-84
lines changed

3 files changed

+134
-84
lines changed

app/tests/page.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
"use client";
22

3+
import { PlanetGenerator } from "@/components/Data/Generator/Astronomers/PlanetHunters/PlanetGenerator";
34
import AlertComponent from "@/components/Structures/Missions/Milestones/Alerts/Alerts";
45

56
export default function TestPage() {
67
return (
78
<div className="min-h-screen bg-black text-white p-4 space-y-8">
8-
<AlertComponent />
9+
{/* <AlertComponent /> */}
10+
<PlanetGenerator classificationId={"40"} author={""} />
911
</div>
1012
);
1113
};

components/Data/Generator/Astronomers/PlanetHunters/PlanetGenerator.tsx

Lines changed: 73 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import { useState, useEffect } from "react"
44
import { Canvas } from "@react-three/fiber"
55
import { OrbitControls, Stars, Environment } from "@react-three/drei"
66
import { PlanetShader } from "./PlanetShader"
7-
import { SettingsPanel } from "./SettingsPanel";
7+
import { SettingsPanel } from "./SettingsPanel"
88
import { Cog } from "lucide-react"
99
import { Button } from "@/components/ui/button"
1010
import { type PlanetStats, calculateDensity, defaultPlanetStats, mergeWithDefaults } from "@/lib/planet-physics"
11+
import { useSupabaseClient } from "@supabase/auth-helpers-react"
1112

1213
export interface PlanetGeneratorProps {
1314
classificationConfig?: any
@@ -28,17 +29,44 @@ export function PlanetGenerator({
2829
classificationConfig,
2930
content,
3031
}: PlanetGeneratorProps) {
31-
// Initialize planet stats from planetConfiguration if provided, otherwise use defaults
32-
const initialPlanetStats = planetConfiguration
33-
? mergeWithDefaults(planetConfiguration)
34-
: {
35-
...defaultPlanetStats,
36-
...(biome ? { biome } : {}),
37-
...(type ? { type } : {}),
38-
}
32+
const supabase = useSupabaseClient();
3933

4034
const [showSettings, setShowSettings] = useState(false)
41-
const [planetStats, setPlanetStats] = useState<PlanetStats>(initialPlanetStats)
35+
const [planetStats, setPlanetStats] = useState<PlanetStats>(
36+
planetConfiguration
37+
? mergeWithDefaults(planetConfiguration)
38+
: {
39+
...defaultPlanetStats,
40+
...(biome ? { biome } : {}),
41+
...(type ? { type } : {}),
42+
}
43+
)
44+
45+
// Fetch classification configuration and overwrite mass/radius if exportedValue is present
46+
useEffect(() => {
47+
const fetchExportedValues = async () => {
48+
const idAsNumber = parseInt(classificationId)
49+
if (isNaN(idAsNumber)) return
50+
51+
const { data, error } = await supabase
52+
.from("classifications")
53+
.select("classificationConfiguration")
54+
.eq("id", idAsNumber)
55+
.single()
56+
57+
if (error || !data?.classificationConfiguration?.exportedValue) return
58+
59+
const { exportedValue } = data.classificationConfiguration
60+
61+
setPlanetStats((prev) => ({
62+
...prev,
63+
...(exportedValue.mass && { mass: exportedValue.mass }),
64+
...(exportedValue.radius && { radius: exportedValue.radius }),
65+
}))
66+
}
67+
68+
fetchExportedValues()
69+
}, [classificationId])
4270

4371
// Update density when mass or radius changes
4472
useEffect(() => {
@@ -51,42 +79,43 @@ export function PlanetGenerator({
5179
return (
5280
<div className="flex-1 w-full h-screen relative">
5381
<div className="absolute top-4 left-4 z-10 text-green-400 font-mono p-2 rounded border border-green-500/30 text-sm">
54-
<div>
55-
<span className="text-green-500/70">ID:</span> {classificationId}
56-
</div>
57-
<div>
58-
<span className="text-green-500/70">AUTHOR:</span> {author}
59-
</div>
60-
{type && (
6182
<div>
62-
<span className="text-green-500/70">TYPE:</span> {type}
83+
<span className="text-green-500/70">ID:</span> {classificationId}
6384
</div>
64-
)}
65-
{biome && (
6685
<div>
67-
<span className="text-green-500/70">BIOME:</span> {biome}
86+
<span className="text-green-500/70">AUTHOR:</span> {author}
6887
</div>
69-
)}
88+
{type && (
89+
<div>
90+
<span className="text-green-500/70">TYPE:</span> {type}
91+
</div>
92+
)}
93+
{biome && (
94+
<div>
95+
<span className="text-green-500/70">BIOME:</span> {biome}
96+
</div>
97+
)}
7098
</div>
7199

72100
{classificationConfig && (
73-
<pre className="text-xs text-white/70">{JSON.stringify(classificationConfig, null, 2)}</pre>
74-
)}
101+
<pre className="text-xs text-white/70">
102+
{JSON.stringify(classificationConfig, null, 2)}
103+
</pre>
104+
)}
75105

76106
<Canvas camera={{ position: [0, 0, 10], fov: 45 }}>
77-
{/* <color attach="background" args={["#020209"]} /> */}
78-
<ambientLight intensity={0.4} />
79-
<pointLight position={[10, 10, 10]} intensity={2} />
80-
<pointLight position={[-10, -10, -10]} intensity={0.5} color="#b0c4de" />
81-
<directionalLight position={[5, 5, 5]} intensity={1.5} castShadow />
82-
<Environment preset="sunset" />
83-
<PlanetShader planetStats={planetStats} />
84-
<Stars radius={100} depth={50} count={5000} factor={4} saturation={0} fade speed={1} />
85-
<OrbitControls enableZoom={true} enablePan={true} enableRotate={true} />
86-
<mesh position={[0, 0, -15]}>
87-
<sphereGeometry args={[5, 32, 32]} />
88-
<meshBasicMaterial color="#4060ff" transparent opacity={0.03} />
89-
</mesh>
107+
<ambientLight intensity={0.4} />
108+
<pointLight position={[10, 10, 10]} intensity={2} />
109+
<pointLight position={[-10, -10, -10]} intensity={0.5} color="#b0c4de" />
110+
<directionalLight position={[5, 5, 5]} intensity={1.5} castShadow />
111+
<Environment preset="sunset" />
112+
<PlanetShader planetStats={planetStats} />
113+
<Stars radius={100} depth={50} count={5000} factor={4} saturation={0} fade speed={1} />
114+
<OrbitControls enableZoom={true} enablePan={true} enableRotate={true} />
115+
<mesh position={[0, 0, -15]}>
116+
<sphereGeometry args={[5, 32, 32]} />
117+
<meshBasicMaterial color="#4060ff" transparent opacity={0.03} />
118+
</mesh>
90119
</Canvas>
91120

92121
<Button
@@ -95,17 +124,17 @@ export function PlanetGenerator({
95124
className="absolute top-4 right-4 bg-black/50 hover:bg-black/70 text-white"
96125
onClick={() => setShowSettings(!showSettings)}
97126
>
98-
<Cog className="h-4 w-4" />
127+
<Cog className="h-4 w-4" />
99128
</Button>
100129

101130
{showSettings && (
102131
<SettingsPanel
103-
planetStats={planetStats}
104-
setPlanetStats={setPlanetStats}
105-
classificationId={classificationId}
106-
author={author}
107-
/>
132+
planetStats={planetStats}
133+
setPlanetStats={setPlanetStats}
134+
classificationId={classificationId}
135+
author={author}
136+
/>
108137
)}
109138
</div>
110-
)
139+
);
111140
};

components/Data/Generator/Astronomers/PlanetHunters/SettingsPanel.tsx

Lines changed: 58 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
} from "@/lib/planet-physics";
2222
import { Download, Upload, Copy, Palette, Plus, Trash2, AlertCircle } from "lucide-react"
2323
import { getAllBiomes, adjustParametersForBiome, getParameterRange, type BiomeRanges } from "@/lib/biome-data"
24+
import { useSession, useSupabaseClient } from "@supabase/auth-helpers-react"
2425

2526
interface SettingsPanelProps {
2627
planetStats: PlanetStats
@@ -35,6 +36,9 @@ export function SettingsPanel({
3536
classificationId = "UNCLASSIFIED",
3637
author = "UNKNOWN",
3738
}: SettingsPanelProps) {
39+
const supabase = useSupabaseClient();
40+
const session = useSession();
41+
3842
const planetType = determinePlanetType(planetStats.mass, planetStats.radius)
3943
const [importExportText, setImportExportText] = useState("")
4044
const [selectedBiome, setSelectedBiome] = useState(planetStats.biome || "Rocky Highlands")
@@ -61,8 +65,8 @@ export function SettingsPanel({
6165
...planetStats,
6266
[key]: value,
6367
...(key === "liquidEnabled" && value === true ? { waterLevel: Math.max(planetStats.waterLevel || 0, 0.5) } : {}),
64-
})
65-
}
68+
});
69+
};
6670

6771
// Apply biome constraints when biome changes
6872
useEffect(() => {
@@ -111,46 +115,61 @@ export function SettingsPanel({
111115
setNewLandmark({ ...newLandmark, coordinates: { ...newLandmark.coordinates, ...value } })
112116
} else {
113117
setNewLandmark({ ...newLandmark, [field]: value })
114-
}
115-
}
116-
117-
// Export planet configuration
118-
const exportPlanetConfig = () => {
119-
// Create a metadata object with classification info
120-
const metadata = {
121-
classificationId,
122-
author,
123-
type: planetStats.type || "Unknown",
124-
biome: planetStats.biome || "Unknown",
125-
exportDate: new Date().toISOString(),
126-
}
118+
};
119+
};
127120

128-
// Start with metadata
129-
let config = `// Planet Configuration Export\n`
130-
config += `// Classification: ${metadata.classificationId}\n`
131-
config += `// Author: ${metadata.author}\n`
132-
config += `// Export Date: ${metadata.exportDate}\n\n`
133-
134-
// Add planet stats
121+
const exportPlanetConfig = async () => {
122+
const exportObject: Record<string, any> = {};
123+
135124
Object.entries(planetStats).forEach(([key, value]) => {
136125
if (value !== undefined && value !== null) {
137-
if (key === "customColors" && value && Object.keys(value).length > 0) {
138-
config += `${key}: ${JSON.stringify(value)}\n`
139-
} else if (key === "landmarks" && Array.isArray(value) && value.length > 0) {
140-
config += `${key}: ${JSON.stringify(value)}\n`
141-
} else if (typeof value === "number") {
142-
config += `${key}: ${value.toFixed(2)}\n`
126+
if (typeof value === "number") {
127+
exportObject[key] = Number(value.toFixed(2));
143128
} else if (typeof value === "boolean") {
144-
config += `${key}: ${value ? "true" : "false"}\n`
145-
} else if (typeof value === "object" && key !== "customColors" && key !== "landmarks") {
146-
config += `${key}: ${JSON.stringify(value)}\n`
147-
} else if (typeof value !== "object") {
148-
config += `${key}: ${value}\n`
129+
exportObject[key] = value;
130+
} else if (typeof value === "object" && !Array.isArray(value)) {
131+
exportObject[key] = value;
132+
} else {
133+
exportObject[key] = value;
149134
}
150135
}
151-
})
152-
setImportExportText(config)
153-
}
136+
});
137+
138+
const exportText = Object.entries(exportObject)
139+
.map(([key, value]) =>
140+
typeof value === "object" ? `${key}: ${JSON.stringify(value)}` : `${key}: ${value}`
141+
)
142+
.join("\n");
143+
144+
setImportExportText(exportText);
145+
146+
const idAsNumber = parseInt(classificationId);
147+
if (isNaN(idAsNumber)) return;
148+
149+
const { data, error: fetchError } = await supabase
150+
.from("classifications")
151+
.select("classificationConfiguration")
152+
.eq("id", idAsNumber)
153+
.single();
154+
155+
if (fetchError || !data?.classificationConfiguration) {
156+
console.error("Failed to fetch existing configuration:", fetchError);
157+
return;
158+
}
159+
160+
const updatedConfig = {
161+
...data.classificationConfiguration,
162+
exportedValue: exportObject,
163+
};
164+
165+
const { error: updateError } = await supabase
166+
.from("classifications")
167+
.update({ classificationConfiguration: updatedConfig })
168+
.eq("id", idAsNumber);
169+
170+
if (updateError) console.error("Failed to export config:", updateError);
171+
};
172+
154173

155174
// Import planet configuration
156175
const importPlanetConfig = () => {
@@ -190,13 +209,13 @@ export function SettingsPanel({
190209
if (completeStats.customColors) setCustomColors(completeStats.customColors as any)
191210
} catch (error) {
192211
console.error("Error importing planet configuration:", error)
193-
}
194-
}
212+
};
213+
};
195214

196215
// Get parameter range for the current biome
197216
const getRange = (parameter: keyof BiomeRanges): [number, number] => {
198217
return getParameterRange(selectedBiome, parameter)
199-
}
218+
};
200219

201220
return (
202221
<div className="absolute top-0 left-0 h-full w-96 bg-black/90 text-green-400 p-6 overflow-y-auto font-mono border-r border-green-500/30">

0 commit comments

Comments
 (0)