From ae5896d4400462e1dbb18467945d800986a74ae6 Mon Sep 17 00:00:00 2001 From: "soroush.asadi" Date: Sun, 31 May 2026 23:56:16 +0330 Subject: [PATCH] fix: credentials lost on refresh + admin UI improvements + CI safe deploy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - dashboard layout: wait for Zustand _hasHydrated before redirecting to /login (was redirecting on first render before localStorage was read) - admin shell: same fix using new _hasHydrated on admin auth store - admin-auth.store: add _hasHydrated + onRehydrateStorage to mirror merchant store - AdminPlansScreen: replace direct cache mutation with per-plan PlanCard component that owns its own useState — fixes other plans disappearing after save - AdminSettingsScreen: detect boolean values and render iOS-style Toggle switches - AdminIntegrationsScreen: replace all with Toggle switches; replace OpenAI model text input with setPrice(Number(e.target.value))} + onBlur={flush} + /> + + + + + ); +} + export function AdminPlansScreen() { const t = useTranslations("admin.plans"); const qc = useQueryClient(); @@ -108,38 +177,7 @@ export function AdminPlansScreen() {

{t("title")}

{plans.map((plan) => ( - - - {plan.displayNameFa} -

{plan.tier}

-
- - - - -
+ save.mutate(p)} /> ))}
); @@ -166,17 +204,34 @@ export function AdminSettingsScreen() {

{t("title")}

- {settings.map((s) => ( - -

{s.key}

-

{s.descriptionFa}

- save.mutate({ key: s.key, value: e.target.value })} - /> -
- ))} + {settings.map((s) => { + const isBool = s.value === "true" || s.value === "false"; + return ( + +
+
+

{s.key}

+ {s.descriptionFa ? ( +

{s.descriptionFa}

+ ) : null} +
+ {isBool ? ( + save.mutate({ key: s.key, value: String(v) })} + disabled={save.isPending} + /> + ) : ( + save.mutate({ key: s.key, value: e.target.value })} + /> + )} +
+
+ ); + })}
); @@ -588,23 +643,21 @@ export function AdminIntegrationsScreen() { {t("active")} ) : null} - + {t("enabled")} + - + {t("sandbox")} + {g.id === "zarinpal" ? (