fix: menu item/category create, demo banner reach, token refresh, blog publish
Dashboard & API bug fixes for owner-reported breakage: - MenuController validators (PosValidators): NameEn was required but the dashboard sends null when blank, so every manual menu-item create failed and category create failed 100% (the form never sends nameEn). Now optional. - DemoDataBanner: only showed when a cafe was exactly empty, so showcase-seeded cafes (2-3 cats / 3-5 items) could never trigger the one-click seed. Widened gate to sparse menus (<5 cats && <10 items) and added a clear "nothing to add" message when already populated. - client.ts: added one-time JWT refresh-and-retry on 401 (shared in-flight promise) before bouncing to /login. Expired access tokens silently broke ticket list, add-table, and other reads. - Surface API errors as toasts on menu + table mutations (were swallowed silently, so failures looked like "nothing happens"). - Admin blog editor: saving an edit dropped IsPublished (defaulted false, silently unpublishing the post on every save); now persisted with a toggle. Also hoisted the inner Field component to module scope - it was remounting every input on each keystroke and dropping focus. - Admin integrations: replaced raw radio gateway selector with a styled RadioDot matching the iOS toggles. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -12,7 +12,8 @@ import { CategoryVisual } from "@/components/menu/category-visual";
|
||||
import { CategoryMediaFields } from "@/components/menu/category-media-fields";
|
||||
import type { CategoryIconSelection } from "@/components/menu/category-preset-picker";
|
||||
import { DEFAULT_CATEGORY_ICON_STYLE } from "@/lib/category-icon-presets";
|
||||
import { apiGet, apiPatch, apiPost } from "@/lib/api/client";
|
||||
import { ApiClientError, apiGet, apiPatch, apiPost } from "@/lib/api/client";
|
||||
import { notify } from "@/lib/notify";
|
||||
import { useAuthStore } from "@/lib/stores/auth.store";
|
||||
import { useBranchStore } from "@/lib/stores/branch.store";
|
||||
import { formatCurrency, formatNumber } from "@/lib/format";
|
||||
@@ -183,6 +184,11 @@ function Modal({
|
||||
export function MenuAdminScreen() {
|
||||
const t = useTranslations("menuAdmin");
|
||||
const tCommon = useTranslations("common");
|
||||
const tNotify = useTranslations("notify");
|
||||
const showError = (err: unknown) =>
|
||||
notify.error(
|
||||
err instanceof ApiClientError ? err.message : tNotify("errorGeneric")
|
||||
);
|
||||
const isRtl = useIsRtl();
|
||||
const locale = useLocale();
|
||||
const numberLocale = locale === "en" ? "en-US" : "fa-IR";
|
||||
@@ -267,6 +273,7 @@ export function MenuAdminScreen() {
|
||||
setItemModalOpen(false);
|
||||
invalidateMenu();
|
||||
},
|
||||
onError: showError,
|
||||
});
|
||||
|
||||
const updateItemMutation = useMutation({
|
||||
@@ -284,12 +291,14 @@ export function MenuAdminScreen() {
|
||||
setItemModalOpen(false);
|
||||
invalidateMenu();
|
||||
},
|
||||
onError: showError,
|
||||
});
|
||||
|
||||
const toggleItemMutation = useMutation({
|
||||
mutationFn: ({ id, isAvailable }: { id: string; isAvailable: boolean }) =>
|
||||
apiPatch(`/api/cafes/${cafeId}/menu/items/${id}/availability`, { isAvailable }),
|
||||
onSuccess: invalidateMenu,
|
||||
onError: showError,
|
||||
});
|
||||
|
||||
const addCategoryMutation = useMutation({
|
||||
@@ -307,6 +316,7 @@ export function MenuAdminScreen() {
|
||||
setCatModalOpen(false);
|
||||
invalidateMenu();
|
||||
},
|
||||
onError: showError,
|
||||
});
|
||||
|
||||
const updateCategoryMutation = useMutation({
|
||||
@@ -322,6 +332,7 @@ export function MenuAdminScreen() {
|
||||
setCatModalOpen(false);
|
||||
invalidateMenu();
|
||||
},
|
||||
onError: showError,
|
||||
});
|
||||
|
||||
// ── Modal openers ──────────────────────────────────────────────────────────
|
||||
@@ -451,7 +462,7 @@ export function MenuAdminScreen() {
|
||||
) : (
|
||||
/* ── Catalog tab ─────────────────────────────────────────────────── */
|
||||
<div className="flex min-h-0 flex-col gap-4">
|
||||
{categories.length === 0 && items.length === 0 && (
|
||||
{categories.length < 5 && items.length < 10 && (
|
||||
<DemoDataBanner
|
||||
invalidateKeys={[
|
||||
["menu-categories", cafeId],
|
||||
|
||||
Reference in New Issue
Block a user