mirror of
https://github.com/christianvidalwolf-prog/Craze-Data-check.git
synced 2026-08-03 14:05:25 +02:00
Enhance Undo system with 5-step history and TopBar badge
This commit is contained in:
+19
-11
@@ -32,7 +32,7 @@ export default function App() {
|
|||||||
hasUnsavedChanges: false
|
hasUnsavedChanges: false
|
||||||
});
|
});
|
||||||
const [activeModule, setActiveModule] = useState<'descriptions' | 'matrix' | 'dimensions'>('descriptions');
|
const [activeModule, setActiveModule] = useState<'descriptions' | 'matrix' | 'dimensions'>('descriptions');
|
||||||
const [undoState, setUndoState] = useState<{ data: ExcelRow[], message: string } | null>(null);
|
const [undoHistory, setUndoHistory] = useState<{ data: ExcelRow[], message: string }[]>([]);
|
||||||
const [editingRowIndex, setEditingRowIndex] = useState<number | null>(null);
|
const [editingRowIndex, setEditingRowIndex] = useState<number | null>(null);
|
||||||
const [isLoadingDefault, setIsLoadingDefault] = useState(true);
|
const [isLoadingDefault, setIsLoadingDefault] = useState(true);
|
||||||
const [defaultLoadError, setDefaultLoadError] = useState<string | null>(null);
|
const [defaultLoadError, setDefaultLoadError] = useState<string | null>(null);
|
||||||
@@ -248,20 +248,27 @@ export default function App() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const captureState = (message: string) => {
|
const captureState = (message: string) => {
|
||||||
setUndoState({
|
setUndoHistory(prev => {
|
||||||
data: JSON.parse(JSON.stringify(appState.data)), // Deep copy
|
const newState = {
|
||||||
message
|
data: JSON.parse(JSON.stringify(appState.data)), // Deep copy
|
||||||
|
message
|
||||||
|
};
|
||||||
|
// Keep only last 5 steps
|
||||||
|
const newHistory = [newState, ...prev].slice(0, 5);
|
||||||
|
return newHistory;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUndo = () => {
|
const handleUndo = () => {
|
||||||
if (!undoState) return;
|
if (undoHistory.length === 0) return;
|
||||||
|
|
||||||
|
const [lastAction, ...remainingHistory] = undoHistory;
|
||||||
setAppState(prev => ({
|
setAppState(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
data: undoState.data,
|
data: lastAction.data,
|
||||||
hasUnsavedChanges: true
|
hasUnsavedChanges: true
|
||||||
}));
|
}));
|
||||||
setUndoState(null);
|
setUndoHistory(remainingHistory);
|
||||||
};
|
};
|
||||||
|
|
||||||
const stats = useMemo(() => {
|
const stats = useMemo(() => {
|
||||||
@@ -305,9 +312,10 @@ export default function App() {
|
|||||||
hasUnsavedChanges={appState.hasUnsavedChanges}
|
hasUnsavedChanges={appState.hasUnsavedChanges}
|
||||||
userEmail={session.user.email}
|
userEmail={session.user.email}
|
||||||
onSignOut={handleSignOut}
|
onSignOut={handleSignOut}
|
||||||
canUndo={!!undoState}
|
canUndo={undoHistory.length > 0}
|
||||||
onUndo={handleUndo}
|
onUndo={handleUndo}
|
||||||
undoMessage={undoState?.message}
|
undoMessage={undoHistory[0]?.message}
|
||||||
|
undoSteps={undoHistory.length}
|
||||||
/>
|
/>
|
||||||
<div className="flex flex-1 overflow-hidden">
|
<div className="flex flex-1 overflow-hidden">
|
||||||
<Sidebar activeModule={activeModule} setActiveModule={setActiveModule} />
|
<Sidebar activeModule={activeModule} setActiveModule={setActiveModule} />
|
||||||
@@ -360,9 +368,9 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<UndoToast
|
<UndoToast
|
||||||
undoState={undoState}
|
undoState={undoHistory[0] || null}
|
||||||
onUndo={handleUndo}
|
onUndo={handleUndo}
|
||||||
onClose={() => setUndoState(null)}
|
onClose={() => setUndoHistory([])}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{editingRowIndex !== null && (
|
{editingRowIndex !== null && (
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ interface TopBarProps {
|
|||||||
canUndo: boolean;
|
canUndo: boolean;
|
||||||
onUndo: () => void;
|
onUndo: () => void;
|
||||||
undoMessage?: string;
|
undoMessage?: string;
|
||||||
|
undoSteps: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function TopBar({ stats, onExport, hasData, hasUnsavedChanges, userEmail, onSignOut, canUndo, onUndo, undoMessage }: TopBarProps) {
|
export function TopBar({ stats, onExport, hasData, hasUnsavedChanges, userEmail, onSignOut, canUndo, onUndo, undoMessage, undoSteps }: TopBarProps) {
|
||||||
return (
|
return (
|
||||||
<header className="bg-[#020812] border-b border-slate-700/30 h-32 flex items-center justify-between px-10 shrink-0 z-10 shadow-2xl">
|
<header className="bg-[#020812] border-b border-slate-700/30 h-32 flex items-center justify-between px-10 shrink-0 z-10 shadow-2xl">
|
||||||
<div className="flex items-center -ml-4">
|
<div className="flex items-center -ml-4">
|
||||||
@@ -73,10 +74,15 @@ export function TopBar({ stats, onExport, hasData, hasUnsavedChanges, userEmail,
|
|||||||
<button
|
<button
|
||||||
onClick={onUndo}
|
onClick={onUndo}
|
||||||
title={`Undo: ${undoMessage}`}
|
title={`Undo: ${undoMessage}`}
|
||||||
className="flex items-center gap-2 px-4 py-2 bg-amber-600 hover:bg-amber-700 text-white rounded-md text-sm font-bold transition-all shadow-lg shadow-amber-900/40 animate-in fade-in zoom-in duration-300"
|
className="flex items-center gap-2 px-4 py-2 bg-amber-600 hover:bg-amber-700 text-white rounded-md text-sm font-bold transition-all shadow-lg shadow-amber-900/40 animate-in fade-in zoom-in duration-300 relative group"
|
||||||
>
|
>
|
||||||
<Undo2 className="w-4 h-4" />
|
<Undo2 className="w-4 h-4" />
|
||||||
BACK / UNDO
|
BACK / UNDO
|
||||||
|
{undoSteps > 1 && (
|
||||||
|
<span className="absolute -top-1 -right-1 bg-white text-amber-700 text-[10px] w-4 h-4 rounded-full flex items-center justify-center shadow-md">
|
||||||
|
{undoSteps}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user