updated tsconfig changed reactor status

This commit is contained in:
boilerrat 2025-01-10 20:28:35 -05:00
parent 4cecf71d04
commit ece54771b7
2 changed files with 231 additions and 190 deletions

View File

@ -1,90 +1,110 @@
import { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { Activity, Power, Atom, Coffee, TrendingUp, Wallet } from 'lucide-react'; import { Activity, Power, Atom, TrendingUp, Users } from 'lucide-react';
import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts'; import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts';
import type { ReactorStatusProps, TooltipProps, PriceStat } from './types'; import type { ReactorStatusProps } from './types';
import { getEthereumData, formatPrice, getHighLowPrices, formatVolume } from '../../utils/api';
const statusMessages = [ const statusMessages = [
'Mining blocks... literally', 'Consensus protocols maintaining criticality',
'Consensus achieved', 'Smart contracts properly shielded',
'Smart contracts cooling', 'DAOs operating at optimal temperature',
'Tokens well-contained', 'Governance tokens well-contained',
'DAOs running smoothly', 'Web3 radiation levels nominal',
'Radiation levels nominal', 'Blockchain fully operational',
'Governance protocols stable', 'Decentralized cooling systems engaged',
'Core temperature optimal', 'Token emissions within parameters',
'NFTs properly shielded', 'NFT containment field stable',
'Blockchain fully operational' 'Reactor governance optimized'
]; ];
const CustomTooltip = ({ active, payload, label }: TooltipProps) => { // Simulated data for the career timeline
if (active && payload && payload.length && label) { // Generate simulated stability data
const generateStabilityData = () => {
const points = 20;
const data = [];
for (let i = 0; i < points; i++) {
data.push({
time: i,
value: 50 + Math.sin(i / 2) * 20 + (Math.random() * 10 - 5)
});
}
return data;
};
// Generate simulated neutron flux data
const generateFluxData = () => {
const points = 20;
const data = [];
for (let i = 0; i < points; i++) {
data.push({
time: i,
value: 70 + Math.cos(i / 3) * 15 + (Math.random() * 8 - 4)
});
}
return data;
};
const generateTimelineData = () => {
const data = [];
const startYear = 2003;
const currentYear = new Date().getFullYear();
for (let year = startYear; year <= currentYear; year++) {
let value = 30; // Base value
// Add significant career events
if (year === 2003) value += 20; // Started as Boilermaker
if (year === 2005) value += 15; // Red Seal certification
if (year === 2016) value += 25; // Radiation Protection certification
if (year === 2019) value += 20; // EPRI certification
if (year === 2022) value += 30; // Entered Web3 space
data.push({
year: year.toString(),
value: value + Math.random() * 10
});
}
return data;
};
const CustomTooltip = ({ active, payload, label }: any) => {
if (active && payload && payload.length) {
const careerEvents: { [key: string]: string } = {
'2003': 'Started as Boilermaker',
'2005': 'Achieved Red Seal certification',
'2016': 'Obtained Radiation Protection certification',
'2019': 'Earned EPRI certification',
'2022': 'Entered Web3 space and founded DAO Masons'
};
return ( return (
<div className="bg-gray-800 p-2 rounded border border-gray-700"> <div className="bg-gray-800 p-3 rounded-lg border border-gray-700">
<p className="text-blue-400">{formatPrice(payload[0].value)}</p> <p className="text-white font-medium">{label}</p>
<p className="text-gray-400 text-sm"> <p className="text-blue-400">{careerEvents[label] || 'Career progression'}</p>
{new Date(parseInt(label)).toLocaleTimeString()}
</p>
</div> </div>
); );
} }
return null; return null;
}; };
export const ReactorStatus = ({ className = '' }: ReactorStatusProps) => { export const ReactorStatus: React.FC<ReactorStatusProps> = ({
const [power, setPower] = useState(0); }) => {
const [status, setStatus] = useState('Initializing...'); const [power, setPower] = useState(85);
const [coreTemp, setCoreTemp] = useState(1350);
const [blockHeight, setBlockHeight] = useState(18_500_000);
const [radLevel, setRadLevel] = useState(5.5e7);
const [status, setStatus] = useState('Initializing systems...');
const [isAnimating, setIsAnimating] = useState(false); const [isAnimating, setIsAnimating] = useState(false);
const [currentTime, setCurrentTime] = useState(new Date()); const [currentTime, setCurrentTime] = useState(new Date());
const [priceData, setPriceData] = useState<Array<{ time: number; price: number }>>([]); const [timelineData] = useState(generateTimelineData());
const [priceStats, setPriceStats] = useState<PriceStat[]>([
{ label: '24h High', value: '...' }, const careerStats = [
{ label: '24h Low', value: '...' }, { label: 'Years Experience', value: '20+' },
{ label: '24h Volume', value: '...' } { label: 'Major Projects', value: '50+' },
]); { label: 'Grants Secured', value: '$197K' }
const [loading, setLoading] = useState(true); ];
const [error, setError] = useState<string | null>(null);
useEffect(() => { useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
setError(null);
const data = await getEthereumData();
console.log('Received ETH data:', data);
if (!data?.prices?.length) {
throw new Error('Invalid price data received');
}
const formattedPrices = data.prices.map(([timestamp, price]) => ({
time: timestamp,
price
}));
const { high, low } = getHighLowPrices(data.prices);
const volume = data.total_volumes[data.total_volumes.length - 1][1];
console.log('Formatted prices:', formattedPrices);
setPriceData(formattedPrices);
setPriceStats([
{ label: '24h High', value: formatPrice(high) },
{ label: '24h Low', value: formatPrice(low) },
{ label: '24h Volume', value: formatVolume(volume) }
]);
} catch (err) {
console.error('Error fetching ETH data:', err);
setError(err instanceof Error ? err.message : 'Failed to fetch price data');
} finally {
setLoading(false);
}
};
// Initial fetch
fetchData();
// Set up intervals
const intervals = [ const intervals = [
setInterval(() => setCurrentTime(new Date()), 1000), setInterval(() => setCurrentTime(new Date()), 1000),
setInterval(() => { setInterval(() => {
@ -93,158 +113,181 @@ export const ReactorStatus = ({ className = '' }: ReactorStatusProps) => {
return Math.min(Math.max(prev + fluctuation, 60), 100); return Math.min(Math.max(prev + fluctuation, 60), 100);
}); });
}, 3000), }, 3000),
setInterval(() => {
setCoreTemp(() => {
const fluctuation = Math.random() * 20 - 10;
return 1300 + (fluctuation % 100);
});
}, 2000),
setInterval(() => {
setBlockHeight(prev => prev + Math.floor(Math.random() * 3));
}, 5000),
setInterval(() => {
setRadLevel(() => {
const base = 5e7;
const fluctuation = Math.random() * 5e7;
return base + fluctuation;
});
}, 4000),
setInterval(() => { setInterval(() => {
const randomStatus = statusMessages[Math.floor(Math.random() * statusMessages.length)]; const randomStatus = statusMessages[Math.floor(Math.random() * statusMessages.length)];
setStatus(randomStatus); setStatus(randomStatus);
setIsAnimating(true); setIsAnimating(true);
setTimeout(() => setIsAnimating(false), 500); setTimeout(() => setIsAnimating(false), 500);
}, 5000), }, 5000)
setInterval(fetchData, 300000) // Fetch new data every 5 minutes
]; ];
// Cleanup
return () => intervals.forEach(clearInterval); return () => intervals.forEach(clearInterval);
}, []); }, []);
const statusIndicators = [ const formatRadLevel = (level: number) => {
{ label: 'Core Temp', value: '37.2°C' }, return `${(level / 1e7).toFixed(2)}E7 Gy/hr`;
{ label: 'Block Height', value: '#18M' }, };
{ label: 'Rad Level', value: '0.12 μSv' }
];
return ( return (
<div className="max-w-6xl mx-auto"> <div className="max-w-6xl mx-auto">
<div className={`grid grid-cols-1 md:grid-cols-2 gap-6 ${className}`}> <div className="flex items-center gap-4 mb-6">
<Atom size={32} className="text-blue-500" />
<h2 className="text-3xl font-bold bg-gradient-to-r from-blue-500 to-purple-500 bg-clip-text text-transparent">
System Status
</h2>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{/* Reactor Status Panel */} {/* Reactor Status Panel */}
<div className="bg-gray-900 rounded-lg p-6"> <div className="bg-gray-900 rounded-lg p-6">
<div className="flex items-center justify-between mb-6"> <div className="flex items-center justify-between mb-6">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Atom className="text-blue-500 animate-spin" /> <Activity className="text-blue-500" />
<h3 className="text-lg font-bold text-white">Reactor Status</h3> <span className="text-sm text-gray-400 font-mono">
{currentTime.toLocaleTimeString()}
</span>
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Activity className="text-green-500" /> <Power className="text-green-500" />
<span className="text-sm text-gray-400"> <span className="text-sm text-gray-400 font-mono">
{currentTime.toLocaleTimeString()} {power.toFixed(1)}% Capacity
</span> </span>
</div> </div>
</div> </div>
<div className="space-y-6"> {/* Status Message */}
{/* Power Level */} <div className="bg-gray-800/50 rounded-lg p-4 mb-6">
<div className="bg-gray-800 rounded-lg p-4"> <div className={`text-lg font-mono text-blue-400 ${isAnimating ? 'animate-pulse' : ''}`}>
<div className="flex justify-between items-center mb-2"> {status}
<span className="text-gray-400">Power Level</span> </div>
<Power className="text-blue-500" /> </div>
{/* Reactor Metrics */}
<div className="grid grid-cols-3 gap-4 mb-6">
<div className="bg-gray-800/50 rounded-lg p-4 text-center">
<div className="text-sm text-gray-400 mb-2">Core Temp</div>
<div className="text-blue-400 font-mono font-medium">
{coreTemp.toFixed(1)}°C
</div> </div>
<div className="relative h-4 bg-gray-700 rounded-full overflow-hidden"> </div>
<div <div className="bg-gray-800/50 rounded-lg p-4 text-center">
className="absolute h-full bg-blue-500 transition-all duration-1000" <div className="text-sm text-gray-400 mb-2">Block Height</div>
style={{ width: `${power}%` }} <div className="text-blue-400 font-mono font-medium">
/> #{blockHeight.toLocaleString()}
</div> </div>
<div className="mt-2 text-right text-sm text-gray-400"> </div>
{power.toFixed(1)}% Capacity <div className="bg-gray-800/50 rounded-lg p-4 text-center">
<div className="text-sm text-gray-400 mb-2">Rad Level</div>
<div className="text-blue-400 font-mono font-medium">
{formatRadLevel(radLevel)}
</div>
</div>
</div>
{/* Systems Monitor */}
<div className="grid grid-cols-2 gap-4">
<div className="bg-gray-800/50 rounded-lg p-4">
<div className="text-sm text-gray-400 mb-2">Core Stability</div>
<div className="h-[100px]">
<ResponsiveContainer width="100%" height="100%">
<LineChart data={generateStabilityData()}>
<Line
type="natural"
dataKey="value"
stroke="#3B82F6"
strokeWidth={2}
dot={false}
isAnimationActive={true}
/>
</LineChart>
</ResponsiveContainer>
</div> </div>
</div> </div>
{/* Status Message */} <div className="bg-gray-800/50 rounded-lg p-4">
<div className="bg-gray-800 rounded-lg p-4"> <div className="text-sm text-gray-400 mb-2">Neutron Flux</div>
<div className="flex justify-between items-center mb-2"> <div className="h-[100px]">
<span className="text-gray-400">Current Status</span> <ResponsiveContainer width="100%" height="100%">
<Coffee className="text-green-500" /> <LineChart data={generateFluxData()}>
<Line
type="natural"
dataKey="value"
stroke="#8B5CF6"
strokeWidth={2}
dot={false}
isAnimationActive={true}
/>
</LineChart>
</ResponsiveContainer>
</div> </div>
<div className={`text-lg font-medium text-blue-400 ${isAnimating ? 'animate-pulse' : ''}`}>
{status}
</div>
</div>
{/* Activity Indicators */}
<div className="grid grid-cols-3 gap-4">
{statusIndicators.map((item, index) => (
<div key={index} className="bg-gray-800 rounded-lg p-3 text-center">
<div className="text-sm text-gray-400">{item.label}</div>
<div className="text-white font-medium">{item.value}</div>
</div>
))}
</div> </div>
</div> </div>
</div> </div>
{/* ETH Price Monitor */} {/* Career Timeline Panel */}
<div className="bg-gray-900 rounded-lg p-6"> <div className="bg-gray-900 rounded-lg p-6">
<div className="space-y-4 mb-6"> <div className="flex items-center justify-between mb-6">
<div className="flex items-center justify-between"> <div className="flex items-center gap-2">
<div className="flex items-center gap-2"> <TrendingUp className="text-purple-500" />
<TrendingUp className="text-blue-500" /> <h3 className="text-lg font-bold text-white">Career Timeline</h3>
<h3 className="text-lg font-bold text-white">ETH Price Monitor</h3> </div>
</div> <div className="flex items-center gap-2">
<div className="flex items-center gap-2"> <Users className="text-purple-500" />
<Wallet className="text-green-500" /> <span className="text-sm text-gray-400">Career Progression</span>
<span className="text-sm text-gray-400">Live Feed</span>
</div>
</div> </div>
{priceData.length > 0 && (
<div className="bg-gray-800 rounded-lg p-4">
<div className="text-sm text-gray-400 mb-1">Current Price</div>
<div className="text-2xl font-bold text-blue-400">
{formatPrice(priceData[priceData.length - 1].price)}
</div>
</div>
)}
</div> </div>
<div className="space-y-6"> {/* Career Stats */}
{/* Price Chart */} <div className="grid grid-cols-3 gap-4 mb-6">
<div className="bg-gray-800 rounded-lg p-4 h-[300px]"> {careerStats.map((stat, index) => (
{loading ? ( <div key={index} className="bg-gray-800/50 rounded-lg p-4 text-center">
<div className="flex items-center justify-center h-full"> <div className="text-sm text-gray-400">{stat.label}</div>
<div className="text-blue-500 flex items-center gap-2"> <div className="text-purple-400 font-medium mt-1">{stat.value}</div>
<Atom className="animate-spin" size={20} /> </div>
<span>Loading price data...</span> ))}
</div> </div>
</div>
) : error ? (
<div className="flex items-center justify-center h-full">
<div className="text-red-500">{error}</div>
</div>
) : (
<ResponsiveContainer width="100%" height="100%">
<LineChart data={priceData}>
<XAxis
dataKey="time"
stroke="#4B5563"
tick={{ fill: '#9CA3AF', fontSize: 12 }}
tickFormatter={(timestamp) => new Date(timestamp).toLocaleTimeString()}
/>
<YAxis
stroke="#4B5563"
tick={{ fill: '#9CA3AF', fontSize: 12 }}
domain={['auto', 'auto']}
tickFormatter={(value) => formatPrice(value)}
/>
<Tooltip content={<CustomTooltip />} />
<Line
type="monotone"
dataKey="price"
stroke="#3B82F6"
strokeWidth={2}
dot={false}
/>
</LineChart>
</ResponsiveContainer>
)}
</div>
{/* Price Stats */} {/* Timeline Chart */}
<div className="grid grid-cols-3 gap-4"> <div className="bg-gray-800/50 rounded-lg p-4 h-[200px]">
{priceStats.map((item, index) => ( <ResponsiveContainer width="100%" height="100%">
<div key={index} className="bg-gray-800 rounded-lg p-3 text-center"> <LineChart data={timelineData}>
<div className="text-sm text-gray-400">{item.label}</div> <XAxis
<div className="text-white font-medium">{item.value}</div> dataKey="year"
</div> stroke="#4B5563"
))} tick={{ fill: '#9CA3AF', fontSize: 12 }}
</div> />
<YAxis
stroke="#4B5563"
tick={{ fill: '#9CA3AF', fontSize: 12 }}
domain={['auto', 'auto']}
hide
/>
<Tooltip content={<CustomTooltip />} />
<Line
type="monotone"
dataKey="value"
stroke="#8B5CF6"
strokeWidth={2}
dot={false}
/>
</LineChart>
</ResponsiveContainer>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,12 +1,12 @@
{ {
"compilerOptions": { "compilerOptions": {
"incremental": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020", "target": "ES2020",
"useDefineForClassFields": true, "useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"], "lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext", "module": "ESNext",
"skipLibCheck": true, "skipLibCheck": true,
/* Bundler mode */ /* Bundler mode */
"moduleResolution": "bundler", "moduleResolution": "bundler",
"allowImportingTsExtensions": true, "allowImportingTsExtensions": true,
@ -14,13 +14,11 @@
"moduleDetection": "force", "moduleDetection": "force",
"noEmit": true, "noEmit": true,
"jsx": "react-jsx", "jsx": "react-jsx",
/* Linting */ /* Linting */
"strict": true, "strict": true,
"noUnusedLocals": true, "noUnusedLocals": true,
"noUnusedParameters": true, "noUnusedParameters": true,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true
"noUncheckedSideEffectImports": true
}, },
"include": ["src"] "include": ["src"]
} }