feat: speed up admin clone import and enable Cache Components

- Clone import: defer FurnitureData.json writes and append all entries in a
  single batched write instead of one read-modify-write per item, removing
  the main serialization bottleneck for large batches.
- Clone import: raise SSE batch concurrency cap from 5 to 10 and bump the
  clone client/route default from 2 to 6.
- Add a flush hook to runSseBatch so callers can batch deferred work before
  batch_complete is emitted, and surface flush errors as an error event.
- Enable Next.js Cache Components (instant: false opt-out) and silence the
  related build warnings in next.config.ts.
- Switch isomorphic-dompurify to dompurify and refresh dependencies.
This commit is contained in:
openhands committed 2026-08-05 11:10:16 +02:00
1 parent ac9b3e3cb5
commit dc8fb8a6ed
254 files changed
+910 -551

No files matched your search

+4
View File
@@ -5,6 +5,10 @@ import { StatusCard } from "@/components/admin/dashboard";
import { Achievements, db } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
type Achievement = {
name: string;
category: string;
+4
View File
@@ -9,6 +9,10 @@ import { db, WebsiteAds } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { EditAdDeleteButton } from "../edit-ad-delete-button";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function EditAd({
params,
}: {
+4
View File
@@ -5,6 +5,10 @@ import { createAd } from "@/actions/admin-ads";
import { Button } from "@/components/ui/button";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function NewAd() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.PAGES_EDIT, session.user.rank)) {
+4
View File
@@ -9,6 +9,10 @@ import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { AdsTable } from "./ads-table";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function AdminAds() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.PAGES_VIEW, session.user.rank)) {
+4
View File
@@ -8,6 +8,10 @@ import { AlertLogs, db } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
const CRITICAL = new Set(["critical", "error", "danger"]);
const WARNING = new Set(["warning", "warn"]);
@@ -8,6 +8,10 @@ import { Ban, db, User } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { redisCache } from "@/lib/redis-cache";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
type DayRow = {
label: string;
chats: number;
+4
View File
@@ -16,6 +16,10 @@ import {
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { redisCache } from "@/lib/redis-cache";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
type EconomyData = {
totalCredits: number;
totalPixels: number;
+4
View File
@@ -17,6 +17,10 @@ import { Ban, db, Rooms, RoomTradeLog, User } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { redisCache } from "@/lib/redis-cache";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
type AnalyticsData = {
totalUsers: number;
onlineUsers: number;
+4
View File
@@ -9,6 +9,10 @@ import { db, User, WebsiteStaffApplications } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
type ApplicationRow = {
id: bigint;
userId: number;
+4
View File
@@ -9,6 +9,10 @@ import { Button } from "@/components/ui/button";
import { db, WebsiteArticles } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function EditArticle({
params,
searchParams,
+4
View File
@@ -6,6 +6,10 @@ import { createArticle } from "@/actions/admin-articles";
import { ArticleForm } from "@/components/admin/article-form";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function NewArticle({
searchParams,
}: {
+4
View File
@@ -11,6 +11,10 @@ import { db, User, WebsiteArticles } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function AdminArticles({
searchParams,
}: {
+4
View File
@@ -7,6 +7,10 @@ import { Button } from "@/components/ui/button";
import { db, WebsiteBadges } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export const metadata = { title: "Badges" };
export default async function AdminBadges({
+4
View File
@@ -4,6 +4,10 @@ import { db, WebsiteBanner } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { BannersManager } from "./banners-manager";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function BannersPage() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.BANNERS_VIEW, session.user.rank)) {
+4
View File
@@ -11,6 +11,10 @@ import { Ban, db } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function AdminBans() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.BANS_VIEW, session.user.rank)) {
+4
View File
@@ -6,6 +6,10 @@ import { CalendarCampaigns, CalendarRewards, db } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
type Campaign = {
id: number;
name: string;
+4
View File
@@ -7,6 +7,10 @@ import { CalendarCampaigns, CalendarRewards, db } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
type Campaign = {
id: number;
name: string;
+4
View File
@@ -9,6 +9,10 @@ import { loadCatalogItemsData } from "@/lib/services/catalog-items-loader";
import { getAncestors } from "@/lib/services/catalog-tree";
import { CatalogDetailTabs } from "./catalog-detail-tabs";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function CatalogEditPage({
params,
}: {
@@ -4,6 +4,10 @@ import { CatalogItemsBc, CatalogPagesBc, db } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { BcPageDetail } from "../bc-manager";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function BcPageDetailPage({
params: paramsPromise,
}: {
@@ -1,5 +1,9 @@
import { redirect } from "next/navigation";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default function BuilderClubPage() {
redirect("/admin/catalog?catalog=bc");
}
+4
View File
@@ -31,6 +31,10 @@ import { CatalogManagerDialog } from "./catalog-manager-dialog-wrapper";
import { CatalogTable } from "./catalog-table";
import { CatalogViewToggle } from "./catalog-view-toggle";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
async function rawRows<T>(query: ReturnType<typeof sql>): Promise<T[]> {
const [rows] = (await db.execute(query)) as unknown as [T[], unknown];
return rows ?? [];
+4
View File
@@ -18,6 +18,10 @@ import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { siteSettings } from "@/lib/services/site-settings";
import { CommandocentrumControls } from "./commandocentrum-controls";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
function decodeStacktrace(raw: unknown): string {
if (raw == null) return "";
try {
+4
View File
@@ -5,6 +5,10 @@ import { Card, CardContent } from "@/components/ui/card";
import { db, EmulatorErrors } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function EmulatorErrorsPage({
searchParams,
}: {
+4
View File
@@ -10,6 +10,10 @@ import { db, EmulatorErrors, EmulatorSettings } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { HealthCheckClient } from "./health-check-client";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
async function getDevOpsData() {
const now = Math.floor(Date.now() / 1000);
const dayAgo = now - 86400;
+4
View File
@@ -10,6 +10,10 @@ import { Button } from "@/components/ui/button";
import { db, EmailTemplates } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function AdminEmailTemplates() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.PAGES_VIEW, session.user.rank)) {
+4
View File
@@ -10,6 +10,10 @@ import { Button } from "@/components/ui/button";
import { db, EmulatorSettings, EmulatorTexts } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
const TEXTS_LIMIT = 300;
export default async function AdminEmulator() {
+4
View File
@@ -12,6 +12,10 @@ import { EventPrizesManager } from "./event-prizes";
import { EventRegistrations } from "./event-registrations";
import { EventWinnersManager } from "./event-winners";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function EventDetailPage({
params,
}: {
+4
View File
@@ -5,6 +5,10 @@ import { db, WebsiteEventType } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { EventForm } from "../event-form";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function CreateEventPage() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.EVENTS_EDIT, session.user.rank)) {
+4
View File
@@ -7,6 +7,10 @@ import { db, WebsiteEvent, WebsiteEventType } from "@/lib/db";
import { PERMS } from "@/lib/permissions";
import { EventsTable } from "./events-table";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function EventsPage({
params: paramsPromise,
searchParams,
+4
View File
@@ -4,6 +4,10 @@ import { db, WebsiteEventType } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { EventTypesManager } from "./event-types-manager";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function EventTypesPage() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.EVENTS_EDIT, session.user.rank)) {
+4
View File
@@ -4,6 +4,10 @@ import { db, WebsiteSetting } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { FaviconForm } from "./favicon-form";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function AdminFaviconPage() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.SETTINGS_VIEW, session.user.rank)) {
+4
View File
@@ -8,6 +8,10 @@ import { db, Guilds, GuildsForumsThreads, GuildsMembers, User } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function AdminGuildDetailPage({
params,
}: {
+4
View File
@@ -12,6 +12,10 @@ import { db, Guilds, GuildsMembers, User } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function AdminGuildsPage({
searchParams,
}: {
@@ -7,6 +7,10 @@ import { Button } from "@/components/ui/button";
import { db, WebsiteHelpCenterCategories } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function EditHelpQuestion({
params,
searchParams,
@@ -5,6 +5,10 @@ import { createHelpQuestion } from "@/actions/admin-help";
import { Button } from "@/components/ui/button";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function NewHelpQuestion({
searchParams,
}: {
+4
View File
@@ -7,6 +7,10 @@ import { Button } from "@/components/ui/button";
import { db, WebsiteHelpCenterCategories } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function AdminHelpQuestions() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.PAGES_VIEW, session.user.rank)) {
+4
View File
@@ -17,6 +17,10 @@ import {
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { AdminHelpTicketDetail } from "./admin-help-ticket-detail";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function AdminHelpTicketDetailPage({
params,
}: {
+4
View File
@@ -25,6 +25,10 @@ import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { type HelpTicketRow, HelpTicketsTable } from "./help-tickets-table";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function AdminHelpTicketsPage({
searchParams,
}: {
+4
View File
@@ -13,6 +13,10 @@ import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { getAuditLogs } from "@/lib/services/audit";
import { AuditSection, ExportSection } from "./client";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function AdminHousekeeping({
searchParams,
}: {
+4
View File
@@ -2,6 +2,10 @@ import { redirect } from "next/navigation";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { AuditClient } from "./audit-client";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function AuditPage() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.ASSETS_IMPORT, session.user.rank)) {
+4
View File
@@ -2,6 +2,10 @@ import { redirect } from "next/navigation";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { ImportBadgesClient } from "./import-badges-client";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function ImportBadgesPage(_props: {
params: Promise<{ locale: string }>;
}) {
@@ -454,7 +454,7 @@ function FurniGrid({ source }: FurniGridProps) {
{
sourceId: source.id,
classnames: toClone.map((it) => it.classname),
concurrency: 2,
concurrency: 6,
},
(classname) => {
done++;
@@ -545,7 +545,7 @@ function FurniGrid({ source }: FurniGridProps) {
const chunk = names.slice(i, i + CHUNK);
await runSseImport(
"/api/admin/import/clone/batch",
{ sourceId: source.id, classnames: chunk, concurrency: 2 },
{ sourceId: source.id, classnames: chunk, concurrency: 6 },
(classname) => {
done++;
markDone(classname);
+4
View File
@@ -2,6 +2,10 @@ import { redirect } from "next/navigation";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { ImportCloneClient } from "./import-clone-client";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function ImportClonePage(_props: {
params: Promise<{ locale: string }>;
}) {
+4
View File
@@ -2,6 +2,10 @@ import { redirect } from "next/navigation";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { ImportClothingClient } from "./import-clothing-client";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function ImportClothingPage(_props: {
params: Promise<{ locale: string }>;
}) {
+4
View File
@@ -3,6 +3,10 @@ import { redirect } from "next/navigation";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { ImportEffectsClient } from "./import-effects-client";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function ImportEffectsPage(_props: {
params: Promise<{ locale: string }>;
}) {
+4
View File
@@ -4,6 +4,10 @@ import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { getHabboGamedataHotel } from "@/lib/services/habbo-gamedata-hotel";
import { ImportFurniClient } from "./import-furni-client";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function ImportFurniPage(_props: {
params: Promise<{ locale: string }>;
}) {
@@ -2,6 +2,10 @@ import { redirect } from "next/navigation";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { UploadFurniClient } from "./upload-furni-client";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function UploadFurniPage() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.ASSETS_IMPORT, session.user.rank)) {
+4
View File
@@ -15,6 +15,10 @@ import { redirect } from "next/navigation";
import { getTranslations } from "next-intl/server";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function ImportPage() {
const t = await getTranslations("pages.admin.import");
const { session, permissions } = await getAdminContext();
+4
View File
@@ -2,6 +2,10 @@ import { redirect } from "next/navigation";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { ImportPetsClient } from "./import-pets-client";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function ImportPetsPage(_props: {
params: Promise<{ locale: string }>;
}) {
@@ -2,6 +2,10 @@ import { redirect } from "next/navigation";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { RepairIconsClient } from "./repair-icons-client";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function RepairIconsPage() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.ASSETS_IMPORT, session.user.rank)) {
+4
View File
@@ -2,6 +2,10 @@ import { redirect } from "next/navigation";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { SyncAllClient } from "./sync-all-client";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function SyncAllPage() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.ASSETS_IMPORT, session.user.rank)) {
+4
View File
@@ -13,6 +13,10 @@ import { db, WebsiteIpBlacklist, WebsiteIpWhitelist } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
type IpRow = {
id: bigint;
ipAddress: string;
+4
View File
@@ -7,6 +7,10 @@ import { db, ItemsBase } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { ItemsBaseEditForm } from "./items-base-edit-form";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function ItemsBaseDetailPage({
params,
}: {
+4
View File
@@ -7,6 +7,10 @@ import { db, ItemsBase } from "@/lib/db";
import { canAccess, PERMS } from "@/lib/permissions";
import { type ItemsBaseRow, ItemsTable } from "./items-table";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function ItemsBasePage({
params: paramsPromise,
searchParams,
+4 -1
View File
@@ -21,9 +21,12 @@ import { readCsrfCookieToken } from "@/lib/foundation/security";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { siteSettings } from "@/lib/services/site-settings";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
// Request-time auth, existing CSRF cookie, and optional 2FA gate cannot be
// statically rendered. Child admin pages inherit this — leaf force-dynamic is redundant.
export const dynamic = "force-dynamic";
export default async function AdminLayout({
children,
+4
View File
@@ -4,6 +4,10 @@ import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { getAuditLogs } from "@/lib/services/audit";
import { AuditTable } from "./audit-table";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function AuditLogsPage({
params: paramsPromise,
searchParams,
+4
View File
@@ -1,6 +1,10 @@
import { loadChatLogList } from "../_lib/load-ignored-logs";
import { ChatTable } from "./chat-table";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function ChatLogsPage({
searchParams,
}: {
+4
View File
@@ -1,6 +1,10 @@
import { loadCommandLogList } from "../_lib/load-ignored-logs";
import { CommandsTable } from "./commands-table";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function CommandLogsPage({
searchParams,
}: {
+4
View File
@@ -19,6 +19,10 @@ import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { StaffActivitiesTable } from "./staff-activities-table";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
const SORT_MAP = {
when: StaffActivities.createdAt,
staff: StaffActivities.userId,
+4
View File
@@ -1,6 +1,10 @@
import { loadTradeLogList } from "../_lib/load-ignored-logs";
import { TradesTable } from "./trades-table";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function TradeLogsPage({
searchParams,
}: {
+4
View File
@@ -7,6 +7,10 @@ import { Button } from "@/components/ui/button";
import { db, WebsiteSetting } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
const KEYS = [
"maintenance_enabled",
"maintenance_message",
+4
View File
@@ -13,6 +13,10 @@ import { db, MarketplaceItems, User } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function AdminMarketplacePage({
searchParams,
}: {
+4
View File
@@ -2,6 +2,10 @@ import { redirect } from "next/navigation";
import { AdminMediaGrid } from "@/components/admin/media-grid";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function AdminMediaPage() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.PAGES_VIEW, session.user.rank)) {
+4
View File
@@ -11,6 +11,10 @@ import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { siteSettings } from "@/lib/services/site-settings";
import { AdminMenuEditor } from "./admin-menu-editor";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export const metadata = { title: "Admin menu" };
export default async function AdminMenuPage() {
@@ -2,6 +2,10 @@ import { redirect } from "next/navigation";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { ModActionsClient } from "./mod-actions-client";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function QuickActionsPage() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.MODERATION_EDIT, session.user.rank))
@@ -4,6 +4,10 @@ import { Ban, db, SupportTickets, User } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { CfhDetail } from "./cfh-detail";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function CfhDetailPage({
params,
}: {
+4
View File
@@ -17,6 +17,10 @@ import { formatDate } from "@/lib/format-date";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { type CfhRow, CfhTable } from "./cfh-table";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function CfhListPage({
searchParams,
}: {
+4
View File
@@ -17,6 +17,10 @@ import { getMinStaffRank } from "@/lib/admin/min-staff-rank";
import { AdminAuditLog, Ban, db, SupportTickets, User } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
const CFH_STATES: Record<number, { label: string; class: string }> = {
0: {
label: "Open",
+4
View File
@@ -14,6 +14,10 @@ import {
} from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function ModTeamPage() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.MODERATION_VIEW, session.user.rank))
+4
View File
@@ -5,6 +5,10 @@ import { StatusCard } from "@/components/admin/dashboard";
import { db, NavigatorFlatcats, NavigatorPubliccats, Rooms } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
// navigator_flatcats — emulator-owned flat (private-room) categories shown in the
// navigator.
type Flatcat = {
+4
View File
@@ -7,6 +7,10 @@ import { db, User } from "@/lib/db";
import { PERMS } from "@/lib/permissions";
import { OnlineTable } from "./online-table";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function OnlineUsersPage({
params: paramsPromise,
searchParams,
+4
View File
@@ -14,6 +14,10 @@ import { unixNow } from "@/lib/bans";
import { Ban, db, StaffActivities, User, WebsiteArticles } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
type RankCount = { rank: number; count: number };
export default async function AdminDashboard() {
+4
View File
@@ -6,6 +6,10 @@ import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { fetchEmulatorRankForEdit } from "@/lib/services/permission-ranks";
import { RankEditClient } from "./rank-edit-client";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function RankEditPage({
params,
}: {
+4
View File
@@ -5,6 +5,10 @@ import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { fetchEmulatorRankSummaries } from "@/lib/services/permission-ranks";
import { PermissionsList } from "./permissions-list";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function PermissionsPage({
searchParams,
}: {
+4
View File
@@ -11,6 +11,10 @@ import { calcPagination, parseListParams } from "@/lib/admin-helpers";
import { CameraWeb, db, User } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function AdminPhotos({
searchParams,
}: {
+4
View File
@@ -10,6 +10,10 @@ import { PollForm } from "../poll-form";
import { PollQuestionsManager } from "./poll-questions";
import { PollResultsView } from "./poll-results";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function PollDetailPage({
params,
}: {
+4
View File
@@ -3,6 +3,10 @@ import { getTranslations } from "next-intl/server";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { PollForm } from "../poll-form";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function CreatePollPage() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.POLLS_EDIT, session.user.rank)) {
+4
View File
@@ -7,6 +7,10 @@ import { db, WebsitePoll } from "@/lib/db";
import { PERMS } from "@/lib/permissions";
import { PollsTable } from "./polls-table";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function PollsPage({
params: paramsPromise,
searchParams,
+4
View File
@@ -2,6 +2,10 @@ import { redirect } from "next/navigation";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { PrefixesClient } from "./prefixes-client";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function PrefixesPage() {
const { session, permissions } = await getAdminContext();
+4
View File
@@ -10,6 +10,10 @@ import { Button } from "@/components/ui/button";
import { db, RadioApiKeys } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export const metadata = { title: "Radio API Keys" };
type ApiKey = {
+4
View File
@@ -11,6 +11,10 @@ import { Button } from "@/components/ui/button";
import { db, RadioAutoDjPlaylist } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export const metadata = { title: "Radio AutoDJ" };
type Track = {
+4
View File
@@ -11,6 +11,10 @@ import { Button } from "@/components/ui/button";
import { db, RadioBanners } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
type Banner = {
id: bigint;
userId: bigint;
+4
View File
@@ -6,6 +6,10 @@ import { resolveHotelName } from "@/lib/hotel-name";
import { siteSettings } from "@/lib/services/site-settings";
import { EmbedSnippet } from "./embed-snippet";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export const metadata = { title: "Radio Embed" };
export default async function AdminRadioEmbedPage() {
+4
View File
@@ -4,6 +4,10 @@ import { StatusCard } from "@/components/admin/dashboard";
import { db, RadioHistory, User } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
type History = {
id: bigint;
userId: bigint;
+4
View File
@@ -1,6 +1,10 @@
import { redirect } from "next/navigation";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function RadioAdminLayout({
children,
}: {
+4
View File
@@ -6,6 +6,10 @@ import { Button } from "@/components/ui/button";
import { db, RadioShouts } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
type Shout = {
id: bigint;
userId: bigint;
+4
View File
@@ -2,6 +2,10 @@ import { getTranslations } from "next-intl/server";
import { DiagnosticRow, StatusCard } from "@/components/admin/dashboard";
import { siteSettings } from "@/lib/services/site-settings";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export const metadata = { title: "Radio Monitoring" };
const FETCH_TIMEOUT_MS = 4000;
+4
View File
@@ -6,6 +6,10 @@ import { Button } from "@/components/ui/button";
import { db, RadioApplications, RadioSchedules, RadioShouts } from "@/lib/db";
import { formatDate } from "@/lib/format-date";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
type Shout = {
id: bigint;
userId: bigint;
+4
View File
@@ -4,6 +4,10 @@ import { StatusCard } from "@/components/admin/dashboard";
import { Button } from "@/components/ui/button";
import { siteSettings } from "@/lib/services/site-settings";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export const metadata = { title: "Radio Points" };
const DEFAULTS = {
+4
View File
@@ -9,6 +9,10 @@ import { StatusCard } from "@/components/admin/dashboard";
import { Button } from "@/components/ui/button";
import { db, RadioRanks } from "@/lib/db";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
type Rank = {
id: bigint;
name: string;
+4
View File
@@ -7,6 +7,10 @@ import { StatusCard } from "@/components/admin/dashboard";
import { Button } from "@/components/ui/button";
import { db, WebsiteSetting } from "@/lib/db";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
type Field = { key: string; comment: string };
type Group = { title: string; fields: Field[] };
+4
View File
@@ -12,6 +12,10 @@ import { Button } from "@/components/ui/button";
import { db, WebsiteRareValueCategories, WebsiteRareValues } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
const CURRENCY_TYPES = ["diamonds", "credits", "duckets", "points"];
export default async function AdminRareValues() {
+4
View File
@@ -6,6 +6,10 @@ import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { loadRoom } from "../../_lib/load-room";
import { FurniClient } from "./furni-client";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function RoomFurniPage({
params,
}: {
+4
View File
@@ -1,5 +1,9 @@
import { redirect } from "next/navigation";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function RoomLegacyPage({
params,
}: {
+4
View File
@@ -8,6 +8,10 @@ import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { loadRoom } from "../../_lib/load-room";
import { RoomEditForm } from "../../[id]/room-edit-form";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function RoomEditPage({
params,
}: {
+4
View File
@@ -7,6 +7,10 @@ import { db, Rooms } from "@/lib/db";
import { canAccess, PERMS } from "@/lib/permissions";
import { RoomsTable } from "./rooms-table";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function RoomsPage({
params: paramsPromise,
searchParams,
+4
View File
@@ -8,6 +8,10 @@ import { Card, CardContent } from "@/components/ui/card";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { loadRoom } from "../../_lib/load-room";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
const stateVariants: Record<
string,
"default" | "secondary" | "destructive" | "outline"
+4
View File
@@ -9,6 +9,10 @@ import { AdvancedSettingsPanel } from "./advanced-settings-panel";
import { FIELD_DEFAULTS, MANAGED_SETTING_KEYS } from "./cms-settings-config";
import { CmsSettingsForm } from "./cms-settings-form";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export const metadata = { title: "CMS Settings" };
export default async function AdminSettings() {
+4
View File
@@ -8,6 +8,10 @@ import { Button } from "@/components/ui/button";
import { db, WebsiteShopArticles } from "@/lib/db";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function EditShopArticle({
params,
}: {
+4
View File
@@ -6,6 +6,10 @@ import { createShopArticle } from "@/actions/admin-shop";
import { Button } from "@/components/ui/button";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
// TODO: Cache Components adoption. Refactor this route so this opt-out can be removed.
// See: https://nextjs.org/docs/app/guides/migrating-to-cache-components
export const instant = false;
export default async function NewShopArticle() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.SHOP_EDIT, session.user.rank)) {
Loaded 100 of 254 files, more files were not shown because too many files have changed in this diff. Show more