feat(admin): reorganize housekeeping and strengthen shared workflows
This commit is contained in:
1 parent
35f66d879f
commit
a070004e7b
35 files changed
+1667
-462
No files matched your search
@@ -1,7 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useTransition } from "react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useRef, useState, useTransition } from "react";
|
||||
import { toast } from "sonner";
|
||||
import type { ActionResult } from "@/lib/safe-action-shared";
|
||||
|
||||
@@ -35,13 +36,19 @@ interface RunOptions {
|
||||
* run(() => deleteNews(id), { redirectTo: '/admin/news' })
|
||||
*/
|
||||
export function useServerAction(options: UseServerActionOptions = {}) {
|
||||
const t = useTranslations("pages.admin.actions");
|
||||
const locked = useRef(false);
|
||||
const [fieldErrors, setFieldErrors] = useState<Record<string, string[]>>({});
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const router = useRouter();
|
||||
|
||||
function run(action: () => Promise<unknown>, opts: RunOptions = {}) {
|
||||
if (locked.current) return;
|
||||
locked.current = true;
|
||||
setFieldErrors({});
|
||||
const {
|
||||
successMessage = "Saved successfully.",
|
||||
errorMessage = "An error occurred.",
|
||||
successMessage = t("saved"),
|
||||
errorMessage = t("error"),
|
||||
redirectTo,
|
||||
onSuccess,
|
||||
onError,
|
||||
@@ -61,16 +68,24 @@ export function useServerAction(options: UseServerActionOptions = {}) {
|
||||
else router.refresh();
|
||||
}
|
||||
} else {
|
||||
toast.error(result.error || errorMessage);
|
||||
setFieldErrors(result.fieldErrors ?? {});
|
||||
toast.error(result.error || errorMessage, {
|
||||
description:
|
||||
Object.values(result.fieldErrors ?? {})
|
||||
.flat()
|
||||
.join(" · ") || undefined,
|
||||
});
|
||||
onError?.();
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("[useServerAction] Unexpected error:", err);
|
||||
toast.error(errorMessage);
|
||||
onError?.();
|
||||
} finally {
|
||||
locked.current = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return { run, isPending };
|
||||
return { run, isPending, fieldErrors };
|
||||
}
|
||||
Reference in new issue
Block a user