refactor: complete application rewrite with modern UI
This commit is contained in:
132
src/App.tsx
132
src/App.tsx
@@ -1,17 +1,15 @@
|
||||
import { useState } from 'react'
|
||||
import './App.css'
|
||||
import 'bootstrap/dist/css/bootstrap.css'
|
||||
import { Env } from './models/Env'
|
||||
import Environment from "./componets/env"
|
||||
import Content from './componets/content'
|
||||
import { FileChooser } from './componets/FileChooser'
|
||||
import { Config } from "./models/Config"
|
||||
import logo from './assets/cgg.png'
|
||||
import { useState } from 'react';
|
||||
import { File } from 'lucide-react';
|
||||
import { Env } from './models/Env';
|
||||
import { Environment } from './componets/env/Environment';
|
||||
import { Content } from './componets/content/Content';
|
||||
import { FileChooser } from './componets/FileChooser';
|
||||
import { Config } from './models/Config';
|
||||
|
||||
class AppState {
|
||||
private constructor(
|
||||
public config: Config = new Config(),
|
||||
) { }
|
||||
) {}
|
||||
|
||||
static readonly Instance = new AppState();
|
||||
|
||||
@@ -23,7 +21,7 @@ class AppState {
|
||||
// Simulate async save with 1 second delay
|
||||
return await new Promise<number>((resolve) => {
|
||||
setTimeout(() => {
|
||||
console.log("Saved env:", env.name);
|
||||
console.log('Saved env:', env.name);
|
||||
resolve(0);
|
||||
}, 1000);
|
||||
});
|
||||
@@ -41,9 +39,9 @@ function App() {
|
||||
|
||||
async function handleEnvChanged(env: Env) {
|
||||
// Optimistic update - update React state immediately
|
||||
setEnvs(prevEnvs => {
|
||||
setEnvs((prevEnvs) => {
|
||||
const newEnvs = [...prevEnvs];
|
||||
const idx = newEnvs.findIndex(x => x.id === env.id);
|
||||
const idx = newEnvs.findIndex((x) => x.id === env.id);
|
||||
if (idx > -1) {
|
||||
newEnvs[idx] = env;
|
||||
}
|
||||
@@ -51,10 +49,9 @@ function App() {
|
||||
});
|
||||
|
||||
// Also update config.envs and template to keep them in sync
|
||||
setConfig(prevConfig => {
|
||||
setConfig((prevConfig) => {
|
||||
const newConfig = new Config();
|
||||
newConfig.envs = prevConfig.envs.map(e => e.id === env.id ? env : e);
|
||||
// Update template JSON with params from this environment
|
||||
newConfig.envs = prevConfig.envs.map((e) => (e.id === env.id ? env : e));
|
||||
newConfig.template = prevConfig.template;
|
||||
newConfig.updateTemplateFromEnv(env);
|
||||
return newConfig;
|
||||
@@ -70,8 +67,8 @@ function App() {
|
||||
|
||||
function handleEnvAdded(env: Env): number {
|
||||
const newIdx = envs.length;
|
||||
setEnvs(prevEnvs => [...prevEnvs, env]);
|
||||
setConfig(prevConfig => {
|
||||
setEnvs((prevEnvs) => [...prevEnvs, env]);
|
||||
setConfig((prevConfig) => {
|
||||
const newConfig = new Config();
|
||||
newConfig.envs = [...prevConfig.envs, env];
|
||||
newConfig.template = prevConfig.template;
|
||||
@@ -81,63 +78,80 @@ function App() {
|
||||
}
|
||||
|
||||
function handleEnvRemoved(envId: number) {
|
||||
setEnvs(prevEnvs => prevEnvs.filter(e => e.id !== envId));
|
||||
setConfig(prevConfig => {
|
||||
setEnvs((prevEnvs) => prevEnvs.filter((e) => e.id !== envId));
|
||||
setConfig((prevConfig) => {
|
||||
const newConfig = new Config();
|
||||
newConfig.envs = prevConfig.envs.filter(e => e.id !== envId);
|
||||
newConfig.envs = prevConfig.envs.filter((e) => e.id !== envId);
|
||||
newConfig.template = prevConfig.template;
|
||||
return newConfig;
|
||||
});
|
||||
}
|
||||
|
||||
function handleTemplateSaved(newContent: string) {
|
||||
setConfig(prevConfig => {
|
||||
setConfig((prevConfig) => {
|
||||
const newConfig = new Config();
|
||||
newConfig.envs = prevConfig.envs;
|
||||
newConfig.addTemplate(newContent);
|
||||
newConfig.setTemplate(newContent);
|
||||
return newConfig;
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<main className="container-fluid m-2">
|
||||
<div className="row mb-2">
|
||||
<FileChooser onSelected={x => {
|
||||
AppState.Instance.loadConfig(x);
|
||||
setEnvs(x.envs);
|
||||
setConfig(x);
|
||||
}} config={config} />
|
||||
<div className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-100">
|
||||
<main className="container mx-auto px-4 py-6 max-w-7xl">
|
||||
{/* Header */}
|
||||
<div className="mb-6">
|
||||
<FileChooser
|
||||
onSelected={(x) => {
|
||||
AppState.Instance.loadConfig(x);
|
||||
setEnvs(x.envs);
|
||||
setConfig(x);
|
||||
}}
|
||||
config={config}
|
||||
/>
|
||||
</div>
|
||||
{envs.length > 0 ?
|
||||
(<div className="row">
|
||||
<section id="env" className='col-4 me-1'>
|
||||
<Environment
|
||||
envs={envs}
|
||||
onChanged={async (e) => await handleEnvChanged(e)}
|
||||
onSelected={handleEnvSelected}
|
||||
onAdd={handleEnvAdded}
|
||||
onRemove={handleEnvRemoved} />
|
||||
</section>
|
||||
<section id="content" className="col-8 col-xl-7 border-start ms-1">
|
||||
<Content env={currentEnv} config={config} onTemplateSaved={handleTemplateSaved} />
|
||||
</section>
|
||||
</div>)
|
||||
:
|
||||
(
|
||||
<div className="row justify-content-center pt-5" >
|
||||
<div className="col-1 pt-5">
|
||||
<img src={logo} alt="" style={{ opacity: 0.2, transform: 'scale(1.8)' }} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)}
|
||||
{envs.length > 0 ? (
|
||||
<div className="grid grid-cols-1 lg:grid-cols-12 gap-6">
|
||||
{/* Environment Panel */}
|
||||
<section className="lg:col-span-5 xl:col-span-4">
|
||||
<div className="sticky top-6">
|
||||
<Environment
|
||||
envs={envs}
|
||||
onChanged={async (e) => await handleEnvChanged(e)}
|
||||
onSelected={handleEnvSelected}
|
||||
onAdd={handleEnvAdded}
|
||||
onRemove={handleEnvRemoved}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Content Panel */}
|
||||
<section className="lg:col-span-7 xl:col-span-8">
|
||||
<Content
|
||||
env={currentEnv}
|
||||
config={config}
|
||||
onTemplateSaved={handleTemplateSaved}
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
) : (
|
||||
/* Empty State */
|
||||
<div className="flex flex-col items-center justify-center py-20">
|
||||
<div className="w-24 h-24 bg-gradient-to-br from-blue-400 to-blue-600 rounded-2xl flex items-center justify-center mb-6 shadow-lg">
|
||||
<File className="w-12 h-12 text-white opacity-80" />
|
||||
</div>
|
||||
<h2 className="text-2xl font-bold text-slate-700 mb-2">
|
||||
No Configuration Loaded
|
||||
</h2>
|
||||
<p className="text-slate-500 text-center max-w-md">
|
||||
Create a new configuration or upload an existing XML file to get started
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
</>
|
||||
)
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App
|
||||
|
||||
|
||||
|
||||
export default App;
|
||||
|
||||
Reference in New Issue
Block a user