77 lines
2.4 KiB
TypeScript
77 lines
2.4 KiB
TypeScript
import { useRef } from 'react';
|
|
import { useCutsceneStore } from '../../store/cutsceneStore';
|
|
import { parseFile, triggerDownload } from '../../utils/fileIO';
|
|
import styles from './LeftPanel.module.css';
|
|
|
|
export default function LeftPanel() {
|
|
const fileInputRef = useRef<HTMLInputElement>(null);
|
|
const { file, selectedCutsceneId, loadFile, addCutscene, deleteCutscene, selectCutscene, getExportData } = useCutsceneStore();
|
|
|
|
function handleFileChange(e: React.ChangeEvent<HTMLInputElement>) {
|
|
const f = e.target.files?.[0];
|
|
if (!f) return;
|
|
const reader = new FileReader();
|
|
reader.onload = (ev) => {
|
|
try {
|
|
const json = JSON.parse(ev.target!.result as string);
|
|
loadFile(parseFile(json));
|
|
} catch {
|
|
alert('Invalid JSON file');
|
|
}
|
|
};
|
|
reader.readAsText(f);
|
|
e.target.value = '';
|
|
}
|
|
|
|
function handleSave() {
|
|
const data = getExportData();
|
|
if (data) triggerDownload(data);
|
|
}
|
|
|
|
function handleDelete(id: string) {
|
|
if (confirm(`Delete cutscene "${id}"?`)) deleteCutscene(id);
|
|
}
|
|
|
|
return (
|
|
<div className={styles.panel}>
|
|
<div className={styles.header}>Cutscenes</div>
|
|
|
|
<div className={styles.actions}>
|
|
<button className={styles.btnPrimary} onClick={() => fileInputRef.current?.click()}>
|
|
Load JSON
|
|
</button>
|
|
<input ref={fileInputRef} type="file" accept=".json" style={{ display: 'none' }} onChange={handleFileChange} />
|
|
<button className={styles.btn} onClick={handleSave} disabled={!file}>
|
|
Save JSON
|
|
</button>
|
|
<button className={styles.btn} onClick={addCutscene}>
|
|
+ New
|
|
</button>
|
|
</div>
|
|
|
|
<div className={styles.list}>
|
|
{!file || file.cutscenes.length === 0 ? (
|
|
<div className={styles.empty}>No cutscenes. Load a JSON or create new.</div>
|
|
) : (
|
|
file.cutscenes.map(c => (
|
|
<div
|
|
key={c.id}
|
|
className={`${styles.item} ${c.id === selectedCutsceneId ? styles.selected : ''}`}
|
|
onClick={() => selectCutscene(c.id)}
|
|
>
|
|
<span className={styles.itemId}>{c.id}</span>
|
|
<button
|
|
className={styles.deleteBtn}
|
|
onClick={(e) => { e.stopPropagation(); handleDelete(c.id); }}
|
|
title="Delete"
|
|
>
|
|
✕
|
|
</button>
|
|
</div>
|
|
))
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|