Skip to content

Commit ed2c5bb

Browse files
committed
Refactor App component to implement Stellar Analyzer functionality with detailed star and biome analysis
1 parent bec2645 commit ed2c5bb

1 file changed

Lines changed: 133 additions & 31 deletions

File tree

src/App.jsx

Lines changed: 133 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,137 @@
1-
import { useState } from 'react'
2-
import reactLogo from './assets/react.svg'
3-
import viteLogo from '/vite.svg'
4-
import './App.css'
1+
import { useMemo, useState } from 'react';
52

6-
function App() {
7-
const [count, setCount] = useState(0)
3+
const DATA = {
4+
letters: {
5+
O: { name: 'Blue', drive: 'Indium', desc: 'Hottest, rarest, exotic planets.', color: 'text-indigo-400', bg: 'bg-indigo-900/20', border: 'border-indigo-500' },
6+
B: { name: 'Blue-White', drive: 'Indium', desc: 'Very hot, high-value resources.', color: 'text-blue-300', bg: 'bg-blue-900/20', border: 'border-blue-500' },
7+
A: { name: 'White', drive: 'Cadmium', desc: 'Hot, standard distribution.', color: 'text-slate-100', bg: 'bg-slate-700/20', border: 'border-slate-400' },
8+
F: { name: 'Yellow-White', drive: 'None', desc: 'Warm, high chance of Lush biomes.', color: 'text-yellow-100', bg: 'bg-yellow-600/10', border: 'border-yellow-200' },
9+
G: { name: 'Yellow', drive: 'None', desc: 'Temperate, Earth-like probability.', color: 'text-yellow-400', bg: 'bg-yellow-500/10', border: 'border-yellow-500' },
10+
K: { name: 'Yellow-Orange', drive: 'Emeril', desc: 'Cool, diverse desert/arid types.', color: 'text-orange-400', bg: 'bg-orange-900/20', border: 'border-orange-500' },
11+
M: { name: 'Red', drive: 'Emeril', desc: 'Coolest, common, many dead moons.', color: 'text-red-400', bg: 'bg-red-900/20', border: 'border-red-500' },
12+
E: { name: 'Green', drive: 'Viridium', desc: 'Exotic/Glitch planet specialist.', color: 'text-green-400', bg: 'bg-green-900/20', border: 'border-green-500' },
13+
},
14+
suffixes: {
15+
p: { label: 'Peculiar', note: 'Likely contains Anomalous/Glitch planets.' },
16+
f: { label: 'Fresh', note: 'Water present. Look for oceans.' },
17+
m: { label: 'Metallic', note: 'Increased yield of rare metals.' },
18+
e: { label: 'Emission', note: 'High radiation / Rare element spikes.' },
19+
v: { label: 'Variable', note: 'Unstable star; chaotic weather patterns.' },
20+
}
21+
};
22+
23+
export default function App() {
24+
const [code, setCode] = useState('');
25+
26+
const analysis = useMemo(() => {
27+
const cleaned = code.trim();
28+
const match = cleaned.match(/^([OBAFGKME])([0-9])([a-z]+)?$/i);
29+
if (!match) return null;
30+
31+
const [_, char, tempStr, suffStr] = match;
32+
const starLetter = char.toUpperCase();
33+
const tempDigit = parseInt(tempStr);
34+
const suffixes = (suffStr || '').toLowerCase();
35+
36+
const star = DATA.letters[starLetter];
37+
const traits = suffixes.split('').filter(s => DATA.suffixes[s]).map(s => DATA.suffixes[s]);
38+
39+
// Resource & Biome Logic
40+
const isExtreme = suffixes.includes('e');
41+
const mainMetal = star.drive === 'None' ? 'Copper' : star.drive;
42+
43+
let primaryBiome = "Balanced";
44+
if (tempDigit <= 3) primaryBiome = "Scorched / Desert";
45+
else if (tempDigit >= 7) primaryBiome = "Frozen / Tundra";
46+
else primaryBiome = "Lush / Tropical";
47+
48+
return {
49+
star,
50+
temp: tempDigit,
51+
traits,
52+
projections: {
53+
primaryBiome,
54+
commonMetal: isExtreme ? `Activated ${mainMetal}` : mainMetal,
55+
specialty: suffixes.includes('f') ? "Salt / Cyto-phosphate" : "Carbon / Ferrite"
56+
}
57+
};
58+
}, [code]);
859

960
return (
10-
<>
11-
<div>
12-
<a href="https://vite.dev" target="_blank">
13-
<img src={viteLogo} className="logo" alt="Vite logo" />
14-
</a>
15-
<a href="https://react.dev" target="_blank">
16-
<img src={reactLogo} className="logo react" alt="React logo" />
17-
</a>
18-
</div>
19-
<h1>Vite + React</h1>
20-
<div className="card">
21-
<button onClick={() => setCount((count) => count + 1)}>
22-
count is {count}
23-
</button>
24-
<p>
25-
Edit <code>src/App.jsx</code> and save to test HMR
26-
</p>
61+
<div className="min-h-screen bg-black text-slate-300 font-mono p-4 flex flex-col items-center justify-center">
62+
<div className="w-full max-w-md">
63+
<header className="mb-8 text-center">
64+
<h1 className="text-xs uppercase tracking-[0.3em] text-cyan-500 mb-2">Stellar Analyzer v1.1</h1>
65+
<div className="h-1 w-12 bg-cyan-500 mx-auto"></div>
66+
</header>
67+
68+
<input
69+
type="text"
70+
maxLength={6}
71+
placeholder="ENTER CLASS (e.g. B5pf)"
72+
className="w-full bg-slate-900 border-b-2 border-slate-700 p-4 text-2xl text-center outline-none focus:border-cyan-500 transition-colors uppercase tracking-widest text-white placeholder:opacity-20"
73+
onChange={(e) => setCode(e.target.value)}
74+
value={code}
75+
/>
76+
77+
{analysis ? (
78+
<div className={`mt-8 p-6 border-l-4 rounded-r-lg ${analysis.star.bg} ${analysis.star.border} animate-in fade-in slide-in-from-bottom-4 duration-500`}>
79+
{/* Header Section */}
80+
<div className="flex justify-between items-start mb-4">
81+
<div>
82+
<h2 className={`text-3xl font-black uppercase ${analysis.star.color}`}>{analysis.star.name}</h2>
83+
<p className="text-sm opacity-70">Hyperdrive: <span className="text-white font-bold">{analysis.star.drive}</span></p>
84+
</div>
85+
<div className="text-right">
86+
<span className="text-4xl font-light">{analysis.temp}</span>
87+
<p className="text-[10px] uppercase opacity-50">Heat Index</p>
88+
</div>
89+
</div>
90+
91+
<p className="mb-6 text-sm italic border-b border-white/5 pb-4">"{analysis.star.desc}"</p>
92+
93+
{/* Traits List */}
94+
<div className="space-y-4 mb-6">
95+
{analysis.traits.length > 0 ? analysis.traits.map(t => (
96+
<div key={t.label} className="flex items-start gap-3">
97+
<div className="mt-1 h-2 w-2 bg-cyan-400 rotate-45" />
98+
<div>
99+
<p className="text-xs font-bold uppercase tracking-tighter text-cyan-400">{t.label}</p>
100+
<p className="text-xs opacity-80">{t.note}</p>
101+
</div>
102+
</div>
103+
)) : (
104+
<p className="text-[10px] uppercase opacity-40 italic font-bold">No standard peculiarities detected</p>
105+
)}
106+
</div>
107+
108+
{/* Projection Grid */}
109+
<div className="pt-6 border-t border-white/10">
110+
<h3 className="text-[10px] uppercase tracking-widest text-cyan-500 mb-3 font-bold">Surface Scan Projections</h3>
111+
<div className="grid grid-cols-2 gap-3">
112+
<div className="bg-black/40 p-3 rounded border border-white/5">
113+
<p className="text-[9px] uppercase opacity-50 mb-1">Dominant Biome</p>
114+
<p className="text-xs text-white font-bold">{analysis.projections.primaryBiome}</p>
115+
</div>
116+
<div className="bg-black/40 p-3 rounded border border-white/5">
117+
<p className="text-[9px] uppercase opacity-50 mb-1">Primary Mineral</p>
118+
<p className={`text-xs font-bold ${analysis.star.color}`}>
119+
{analysis.projections.commonMetal}
120+
</p>
121+
</div>
122+
</div>
123+
<p className="mt-3 text-[9px] opacity-40 text-center uppercase">System potential: {analysis.projections.specialty} sources detected</p>
124+
</div>
125+
</div>
126+
) : (
127+
<div className="mt-12 text-center">
128+
<p className="text-xs opacity-40 animate-pulse uppercase tracking-tighter">Awaiting valid spectral coordinates...</p>
129+
<div className="flex justify-center gap-2 mt-4 opacity-20">
130+
{['O', 'B', 'A', 'F', 'G', 'K', 'M', 'E'].map(l => <span key={l} className="text-[10px]">{l}</span>)}
131+
</div>
132+
</div>
133+
)}
27134
</div>
28-
<p className="read-the-docs">
29-
Click on the Vite and React logos to learn more
30-
</p>
31-
</>
32-
)
33-
}
34-
35-
export default App
135+
</div>
136+
);
137+
}

0 commit comments

Comments
 (0)