Черновики форм создания сохраняются в localStorage
Модалки по жёлтым кнопкам «Добавить» (типы заявок, доступ к заявкам, маршруты, шаги маршрута) теряли введённое при случайном клике по подложке. Теперь черновик живёт в localStorage (useFormDraft) и переживает закрытие окна, «Отмену» и F5. Сбрасывается после успешного сохранения или кнопкой «Очистить» в подвале модалки. Формы редактирования не персистятся — всегда открываются с данными сервера. Попутно убраны Sass-предупреждения mixed-decls в Card.module.scss. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,22 @@ function isPlainObject(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Значение из localStorage под key, мелко смёрженное с initial (см. useLocalStorageState),
|
||||
* или initial, если записи нет / она битая / localStorage недоступен.
|
||||
*/
|
||||
export function readLocalStorage<T>(key: string, initial: T): T {
|
||||
try {
|
||||
const raw = window.localStorage.getItem(key);
|
||||
if (!raw) return initial;
|
||||
|
||||
const parsed = JSON.parse(raw) as T;
|
||||
return isPlainObject(initial) && isPlainObject(parsed) ? { ...initial, ...parsed } as T : parsed;
|
||||
} catch {
|
||||
return initial;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Как React.useState, но значение переживает перезагрузку страницы — хранится
|
||||
* в localStorage под key. Падение доступа к localStorage (приватный режим,
|
||||
@@ -15,17 +31,7 @@ function isPlainObject(value: unknown): value is Record<string, unknown> {
|
||||
* первом же .map/.trim по этому полю), а подставится дефолт из initial.
|
||||
*/
|
||||
export function useLocalStorageState<T>(key: string, initial: T): [T, React.Dispatch<React.SetStateAction<T>>] {
|
||||
const [value, setValue] = React.useState<T>(() => {
|
||||
try {
|
||||
const raw = window.localStorage.getItem(key);
|
||||
if (!raw) return initial;
|
||||
|
||||
const parsed = JSON.parse(raw) as T;
|
||||
return isPlainObject(initial) && isPlainObject(parsed) ? { ...initial, ...parsed } as T : parsed;
|
||||
} catch {
|
||||
return initial;
|
||||
}
|
||||
});
|
||||
const [value, setValue] = React.useState<T>(() => readLocalStorage(key, initial));
|
||||
|
||||
React.useEffect(() => {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user