Refresh Suggest hotel label from live CMS setting.
Local Build and Deploy / deploy (push) Successful in 56s

Avoid stale SSR/Redis cache keeping Suggest IT after habbo_gamedata_hotel changes.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
SimoandCursor committed 2026-07-17 22:36:10 +02:00
1 parent 785c1b6976
commit a798999440
5 files changed
+49 -10

No files matched your search

+4 -4
View File
@@ -55,7 +55,7 @@ export const saveManagedSettings = adminAction(
}), }),
), ),
); );
siteSettings.reload(); await siteSettings.reload();
if (entries.some(([key]) => key === HABBO_GAMEDATA_HOTEL_SETTING_KEY)) { if (entries.some(([key]) => key === HABBO_GAMEDATA_HOTEL_SETTING_KEY)) {
clearHabboItCache(); clearHabboItCache();
clearBadgeCache(); clearBadgeCache();
@@ -77,7 +77,7 @@ export async function updateSetting(formData: FormData): Promise<void> {
); );
if (!key) return; if (!key) return;
await prisma.websiteSetting.update({ where: { key }, data: { value } }); await prisma.websiteSetting.update({ where: { key }, data: { value } });
siteSettings.reload(); await siteSettings.reload();
bustGamedataCachesIfNeeded(key); bustGamedataCachesIfNeeded(key);
revalidatePath("/admin/settings"); revalidatePath("/admin/settings");
} }
@@ -102,7 +102,7 @@ export async function createSetting(formData: FormData): Promise<void> {
update: { value }, update: { value },
create: { key, value, comment: comment || null }, create: { key, value, comment: comment || null },
}); });
siteSettings.reload(); await siteSettings.reload();
bustGamedataCachesIfNeeded(key); bustGamedataCachesIfNeeded(key);
revalidatePath("/admin/settings"); revalidatePath("/admin/settings");
} }
@@ -114,7 +114,7 @@ export async function deleteSetting(formData: FormData): Promise<void> {
.trim(); .trim();
if (!key) return; if (!key) return;
await prisma.websiteSetting.delete({ where: { key } }); await prisma.websiteSetting.delete({ where: { key } });
siteSettings.reload(); await siteSettings.reload();
bustGamedataCachesIfNeeded(key); bustGamedataCachesIfNeeded(key);
revalidatePath("/admin/settings"); revalidatePath("/admin/settings");
} }
@@ -83,6 +83,39 @@ export function CatalogTranslateTab({
useEffect(() => { useEffect(() => {
setActiveHotel(normalizeHabboGamedataHotel(gamedataHotel)); setActiveHotel(normalizeHabboGamedataHotel(gamedataHotel));
}, [gamedataHotel]); }, [gamedataHotel]);
// Always refresh from CMS settings so the button label tracks hotel changes
// without requiring a full page remount after saving Settings.
useEffect(() => {
let cancelled = false;
async function refreshHotel() {
try {
const res = await fetch("/api/admin/catalog/suggest", {
cache: "no-store",
});
if (!res.ok) return;
const data = (await res.json()) as { hotel?: string };
if (!cancelled && typeof data.hotel === "string") {
setActiveHotel(normalizeHabboGamedataHotel(data.hotel));
}
} catch {
// keep prop/default
}
}
void refreshHotel();
const onFocus = () => void refreshHotel();
const onVisibility = () => {
if (document.visibilityState === "visible") void refreshHotel();
};
window.addEventListener("focus", onFocus);
document.addEventListener("visibilitychange", onVisibility);
return () => {
cancelled = true;
window.removeEventListener("focus", onFocus);
document.removeEventListener("visibilitychange", onVisibility);
};
}, []);
const hotelShort = habboGamedataHotelShort(activeHotel); const hotelShort = habboGamedataHotelShort(activeHotel);
const hotelLabel = habboGamedataHotelLabel(activeHotel); const hotelLabel = habboGamedataHotelLabel(activeHotel);
+2
View File
@@ -8,6 +8,8 @@ import { loadCatalogItemsData } from "@/lib/services/catalog-items-loader";
import { getAncestors } from "@/lib/services/catalog-tree"; import { getAncestors } from "@/lib/services/catalog-tree";
import { CatalogDetailTabs } from "./catalog-detail-tabs"; import { CatalogDetailTabs } from "./catalog-detail-tabs";
export const dynamic = "force-dynamic";
export default async function CatalogEditPage({ export default async function CatalogEditPage({
params, params,
}: { }: {
+3 -3
View File
@@ -7,9 +7,9 @@ vi.mock("@/lib/prisma", () => ({
import { siteSettings } from "./site-settings"; import { siteSettings } from "./site-settings";
beforeEach(() => { beforeEach(async () => {
findMany.mockReset(); findMany.mockReset();
siteSettings.reload(); await siteSettings.reload();
}); });
describe("siteSettings", () => { describe("siteSettings", () => {
@@ -39,7 +39,7 @@ describe("siteSettings", () => {
await siteSettings.get("hotel_name"); await siteSettings.get("hotel_name");
await siteSettings.getBool("hotel_name"); await siteSettings.getBool("hotel_name");
expect(findMany).toHaveBeenCalledTimes(1); expect(findMany).toHaveBeenCalledTimes(1);
siteSettings.reload(); await siteSettings.reload();
await siteSettings.get("hotel_name"); await siteSettings.get("hotel_name");
expect(findMany).toHaveBeenCalledTimes(2); expect(findMany).toHaveBeenCalledTimes(2);
}); });
+7 -3
View File
@@ -84,13 +84,17 @@ class SiteSettings {
create: { key, value }, create: { key, value },
update: { value }, update: { value },
}); });
this.reload(); await this.reload();
} }
reload(): void { async reload(): Promise<void> {
this.cache = null; this.cache = null;
if (redis) { if (redis) {
redis.del(REDIS_CACHE_KEY).catch(() => {}); try {
await redis.del(REDIS_CACHE_KEY);
} catch {
// non-critical
}
} }
} }
} }