Spaces:
Sleeping
Sleeping
File size: 2,384 Bytes
eddc354 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | export const AUTOSAVE_KEY = "frivolite-studio-v1";
export const PROJECTS_KEY = "realknot-projects-v1";
export type StoredProject = {
id: string;
/** Владелец схемы — id пользователя из auth-service. */
ownerId: string;
title: string;
updatedAt: number;
elements: number;
thumb: string;
data: unknown;
};
const safe = <T,>(fn: () => T, fallback: T): T => {
try {
return fn();
} catch {
return fallback;
}
};
/** SUPABASE: `supabase.from("projects").select("*")` (RLS по owner_id). */
export const listAllProjects = (): StoredProject[] =>
safe(() => {
const raw = localStorage.getItem(PROJECTS_KEY);
const arr = raw ? (JSON.parse(raw) as StoredProject[]) : [];
return arr
.map((p) => ({ ...p, ownerId: p.ownerId ?? "admin" }))
.sort((a, b) => b.updatedAt - a.updatedAt);
}, []);
export const listProjects = (ownerId: string): StoredProject[] =>
listAllProjects().filter((p) => p.ownerId === ownerId);
const write = (list: StoredProject[]) =>
safe(() => localStorage.setItem(PROJECTS_KEY, JSON.stringify(list)), undefined);
export const upsertProject = (p: StoredProject) => {
const list = listAllProjects().filter((x) => x.id !== p.id);
list.unshift(p);
write(list);
return listProjects(p.ownerId);
};
export const removeProject = (id: string, ownerId: string) => {
write(listAllProjects().filter((x) => x.id !== id));
return listProjects(ownerId);
};
export const renameProject = (id: string, title: string, ownerId: string) => {
write(listAllProjects().map((x) => (x.id === id ? { ...x, title } : x)));
return listProjects(ownerId);
};
/** Удаление всех схем пользователя (например, при удалении аккаунта). */
export const removeProjectsOfOwner = (ownerId: string) => {
write(listAllProjects().filter((x) => x.ownerId !== ownerId));
};
export const countProjectsByOwner = (): Record<string, number> =>
listAllProjects().reduce<Record<string, number>>((acc, p) => {
acc[p.ownerId] = (acc[p.ownerId] ?? 0) + 1;
return acc;
}, {});
export const formatStamp = (ts: number) =>
new Date(ts).toLocaleString("ru-RU", {
day: "2-digit",
month: "2-digit",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
});
export const newId = () => Math.random().toString(36).slice(2, 10);
|