Refactor AssetsPage and introduce a new EditableTable component

Signed-off-by: Jonathan <contact@grafikart.fr>
This commit is contained in:
Jonathan
2025-11-14 12:44:27 +01:00
committed by Émile Ré
parent 218566505b
commit cb5daab175
4 changed files with 447 additions and 236 deletions

View File

@@ -1,31 +1,39 @@
import { z, ZodError, type ZodTypeAny } from "zod";
import { useMemo, useState } from "react";
import { useCallback, useMemo, useState } from "react";
export function useStateWithSchema<T extends ZodTypeAny>(
schema: T,
initialValue: z.infer<T>,
) {
const [state, setState] = useState(initialValue);
const errors = useMemo(() => {
const [value, errors] = useMemo((): [z.infer<T>, Record<string, string>] => {
try {
schema.parse(state);
return {};
return [schema.parse(state), {}];
} catch (error) {
if (error instanceof ZodError) {
return Object.fromEntries(
error.issues.map((issue) => [issue.path.join("."), issue.message]) ??
[],
);
return [
state,
Object.fromEntries(
error.issues.map((issue) => [
issue.path.join("."),
issue.message,
]) ?? [],
),
];
}
return {};
return [state, {}];
}
}, [state, schema]);
return [
state,
(key: keyof z.infer<T>, value: z.infer<T>[typeof key]) => {
setState((prevState) => ({ ...prevState, [key]: value }));
},
return {
rawValue: value,
value,
errors,
] as const;
update: useCallback(
(key: keyof z.infer<T>, value: z.infer<T>[typeof key]) => {
setState((prevState) => ({ ...prevState, [key]: value }));
},
[],
),
};
}