Import source: src/context/HistoryContext
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import { createContext, useContext, useState, useCallback, type ReactNode } from 'react';
|
||||
import type { QRState } from '../types';
|
||||
|
||||
export interface HistoryEntry {
|
||||
id: number;
|
||||
type: QRState['selectedType'];
|
||||
label: string;
|
||||
snapshot: Pick<QRState, 'qrColor' | 'bgColor' | 'pattern' | 'theme' | 'gradientEnabled' | 'gradientColor2' | 'cornerSquareStyle' | 'cornerDotStyle' | 'logoDataUrl'>;
|
||||
formData: QRState['formData'];
|
||||
savedAt: number;
|
||||
}
|
||||
|
||||
interface HistoryCtx {
|
||||
history: HistoryEntry[];
|
||||
push: (state: QRState, label: string) => void;
|
||||
remove: (id: number) => void;
|
||||
clear: () => void;
|
||||
}
|
||||
|
||||
const KEY = 'cqrc_history';
|
||||
const MAX = 20;
|
||||
|
||||
function load(): HistoryEntry[] {
|
||||
try { return JSON.parse(localStorage.getItem(KEY) ?? '[]'); } catch { return []; }
|
||||
}
|
||||
function save(h: HistoryEntry[]) {
|
||||
try { localStorage.setItem(KEY, JSON.stringify(h)); } catch { /* storage full */ }
|
||||
}
|
||||
|
||||
const HistoryContext = createContext<HistoryCtx>({ history: [], push: () => {}, remove: () => {}, clear: () => {} });
|
||||
|
||||
export function HistoryProvider({ children }: { children: ReactNode }) {
|
||||
const [history, setHistory] = useState<HistoryEntry[]>(load);
|
||||
|
||||
const push = useCallback((state: QRState, label: string) => {
|
||||
setHistory(prev => {
|
||||
const entry: HistoryEntry = {
|
||||
id: Date.now(),
|
||||
type: state.selectedType,
|
||||
label: label.slice(0, 60),
|
||||
snapshot: {
|
||||
qrColor: state.qrColor, bgColor: state.bgColor, pattern: state.pattern,
|
||||
theme: state.theme, gradientEnabled: state.gradientEnabled,
|
||||
gradientColor2: state.gradientColor2, cornerSquareStyle: state.cornerSquareStyle,
|
||||
cornerDotStyle: state.cornerDotStyle, logoDataUrl: state.logoDataUrl,
|
||||
},
|
||||
formData: state.formData,
|
||||
savedAt: Date.now(),
|
||||
};
|
||||
const next = [entry, ...prev.filter(e => e.label !== label)].slice(0, MAX);
|
||||
save(next);
|
||||
return next;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const remove = useCallback((id: number) => {
|
||||
setHistory(prev => { const next = prev.filter(e => e.id !== id); save(next); return next; });
|
||||
}, []);
|
||||
|
||||
const clear = useCallback(() => { setHistory([]); localStorage.removeItem(KEY); }, []);
|
||||
|
||||
return <HistoryContext.Provider value={{ history, push, remove, clear }}>{children}</HistoryContext.Provider>;
|
||||
}
|
||||
|
||||
export const useHistory = () => useContext(HistoryContext);
|
||||
Reference in New Issue
Block a user