refactor: complete application rewrite with modern UI
This commit is contained in:
@@ -1,41 +1,57 @@
|
||||
import { Env } from "../models/Env";
|
||||
import { ConfigReader } from "../models/ConfigReader";
|
||||
import { Config } from "../models/Config";
|
||||
import { ConfigBuilder } from "../builders/ConfigBuilder";
|
||||
import { useRef } from 'react';
|
||||
import { Upload, Download, FilePlus, File } from 'lucide-react';
|
||||
import { Button } from '../components/ui';
|
||||
import { Config } from '../models/Config';
|
||||
import { ConfigReader } from '../models/ConfigReader';
|
||||
import { ConfigBuilder } from '../builders/ConfigBuilder';
|
||||
import { Env } from '../models/Env';
|
||||
|
||||
export function FileChooser(props: { onSelected: (x: Config) => void, config?: Config }) {
|
||||
async function handleFile(x: React.ChangeEvent<HTMLInputElement>) {
|
||||
let file = x.target.files![0];
|
||||
interface FileChooserProps {
|
||||
onSelected: (config: Config) => void;
|
||||
config?: Config;
|
||||
}
|
||||
|
||||
console.log(file.name, file.type, file.size, "supported:", ConfigReader.isSupportedFormat(file));
|
||||
let reader = new ConfigReader();
|
||||
let cfg = await reader.parseFromFile(file);
|
||||
export function FileChooser({ onSelected, config }: FileChooserProps) {
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
async function handleFileChange(event: React.ChangeEvent<HTMLInputElement>) {
|
||||
const file = event.target.files?.[0];
|
||||
if (!file) return;
|
||||
|
||||
console.log(file.name, file.type, file.size, 'supported:', ConfigReader.isSupportedFormat(file));
|
||||
|
||||
const reader = new ConfigReader();
|
||||
const cfg = await reader.parseFromFile(file);
|
||||
|
||||
if (cfg !== null) {
|
||||
props.onSelected(cfg);
|
||||
onSelected(cfg);
|
||||
}
|
||||
|
||||
// Reset input
|
||||
if (fileInputRef.current) {
|
||||
fileInputRef.current.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
function handleNew(){
|
||||
let cfg = new Config();
|
||||
cfg.addEnvs([new Env(0, "DEFAULT", [])]);
|
||||
cfg.addTemplate("{}");
|
||||
props.onSelected(cfg);
|
||||
function handleNew() {
|
||||
const cfg = new Config();
|
||||
cfg.setEnvs([new Env(0, 'DEFAULT', [])]);
|
||||
cfg.setTemplate('{}');
|
||||
onSelected(cfg);
|
||||
}
|
||||
|
||||
function handleDownload() {
|
||||
if (!props.config) {
|
||||
alert("No configuration loaded");
|
||||
if (!config) {
|
||||
alert('No configuration loaded');
|
||||
return;
|
||||
}
|
||||
|
||||
const xmlContent = ConfigBuilder.buildFullXml(props.config);
|
||||
const xmlContent = ConfigBuilder.buildFullXml(config);
|
||||
const filename = ConfigBuilder.generateFilename();
|
||||
|
||||
// Create blob and download
|
||||
const blob = new Blob([xmlContent], { type: "text/xml" });
|
||||
|
||||
const blob = new Blob([xmlContent], { type: 'text/xml' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement("a");
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = filename;
|
||||
document.body.appendChild(link);
|
||||
@@ -45,25 +61,60 @@ export function FileChooser(props: { onSelected: (x: Config) => void, config?: C
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="col-2">
|
||||
<button className="btn btn-primary" onClick={handleNew} >Create new</button>
|
||||
</div>
|
||||
<div className="col-auto">
|
||||
<button
|
||||
className="btn btn-success"
|
||||
onClick={handleDownload}
|
||||
disabled={!props.config}
|
||||
title="Download full config template"
|
||||
>
|
||||
⬇ Download
|
||||
</button>
|
||||
</div>
|
||||
<div className="col-1">or</div>
|
||||
<div className="bg-white rounded-xl shadow-md p-4 border border-slate-200">
|
||||
<div className="flex items-center gap-4 flex-wrap">
|
||||
{/* Logo/Brand */}
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-10 h-10 bg-gradient-to-br from-blue-500 to-blue-600 rounded-lg flex items-center justify-center">
|
||||
<File className="w-6 h-6 text-white" />
|
||||
</div>
|
||||
<span className="font-bold text-xl text-slate-800">Configucci</span>
|
||||
</div>
|
||||
|
||||
<div className="col">
|
||||
<input className="form-control" type="file" id="formFile" onChange={handleFile} />
|
||||
</div >
|
||||
</>
|
||||
<div className="h-8 w-px bg-slate-200" />
|
||||
|
||||
{/* Action Buttons */}
|
||||
<div className="flex items-center gap-2 flex-1">
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={handleNew}
|
||||
icon={FilePlus}
|
||||
size="sm"
|
||||
>
|
||||
New Config
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="success"
|
||||
onClick={handleDownload}
|
||||
icon={Download}
|
||||
size="sm"
|
||||
disabled={!config}
|
||||
title="Download full config template"
|
||||
>
|
||||
Download
|
||||
</Button>
|
||||
|
||||
<span className="text-slate-400 text-sm">or</span>
|
||||
|
||||
{/* File Upload */}
|
||||
<div className="flex-1">
|
||||
<label
|
||||
className="flex items-center justify-center gap-2 px-4 py-2 border-2 border-dashed border-slate-300 rounded-lg cursor-pointer hover:border-blue-400 hover:bg-blue-50 transition-all duration-200"
|
||||
>
|
||||
<Upload className="w-4 h-4 text-slate-400" />
|
||||
<span className="text-sm text-slate-600">Upload XML Config</span>
|
||||
<input
|
||||
ref={fileInputRef}
|
||||
type="file"
|
||||
className="hidden"
|
||||
accept=".xml,text/xml"
|
||||
onChange={handleFileChange}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user