refactor: complete application rewrite with modern UI

This commit is contained in:
sokol
2026-02-19 22:55:26 +03:00
parent 271b530fa1
commit a6cc5a9827
26 changed files with 3036 additions and 794 deletions

View File

@@ -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;