From 827595ef00846b32c291f952cdbaaad9f2f84d0f Mon Sep 17 00:00:00 2001 From: openhands Date: Tue, 21 Jul 2026 16:52:58 +0200 Subject: [PATCH] fix: mobile responsiveness for all admin pages - DataTable: overflow-x-auto on table wrapper (affects users, rooms, tickets) - Radio: overflow-x-auto wrappers around all 3 tables (shouts, applications, schedules) - Catalog items: responsive grids (grid-cols-1 sm:grid-cols-3) in Add/Edit dialogs - Catalog tabs: TabsList overflow-x-auto for narrow screens - Import clone: pagination flex-wrap to prevent overlap on small screens --- .../catalog/[id]/catalog-detail-tabs.tsx | 2 +- .../catalog-items-table.tsx | 2761 +++++++++-------- .../import/clone/import-clone-client.tsx | 2 +- src/app/admin/radio/page.tsx | 215 +- src/components/admin/data-table.tsx | 2 +- 5 files changed, 1504 insertions(+), 1478 deletions(-) diff --git a/src/app/admin/catalog/[id]/catalog-detail-tabs.tsx b/src/app/admin/catalog/[id]/catalog-detail-tabs.tsx index 260b0594..3ccf3824 100644 --- a/src/app/admin/catalog/[id]/catalog-detail-tabs.tsx +++ b/src/app/admin/catalog/[id]/catalog-detail-tabs.tsx @@ -69,7 +69,7 @@ export function CatalogDetailTabs({ }: CatalogDetailTabsProps) { return ( - + Settings diff --git a/src/app/admin/catalog/[id]/catalog-items-table/catalog-items-table.tsx b/src/app/admin/catalog/[id]/catalog-items-table/catalog-items-table.tsx index 13d44e47..ad59421d 100644 --- a/src/app/admin/catalog/[id]/catalog-items-table/catalog-items-table.tsx +++ b/src/app/admin/catalog/[id]/catalog-items-table/catalog-items-table.tsx @@ -736,7 +736,7 @@ export function CatalogItemsTable({ /> -
+
-
+
-
+
-
+
setSearchQuery(e.target.value)} + className="pl-9 h-9" + /> + {searchQuery && ( + + )} +
+ )} + + + {items.length === 0 ? ( +
+

+ No items in this page. +

+ {canEdit && ( - {hasOrderChanges && ( - <> - - - - )} - {modifiedItems.length > 0 && ( - <> - - - - )} - - router.refresh()} - /> - - - - - Add Catalog Item - - - setNewItem((p) => ({ ...p, [key]: value })) - } - /> - - - - - )} -
-
- - {/* Unsaved changes banner */} - {hasUnsavedChanges && ( -
- - You have unsaved changes ( - {modifiedItems.length > 0 - ? `${modifiedItems.length} item(s) modified` - : ""} - {modifiedItems.length > 0 && hasOrderChanges ? ", " : ""} - {hasOrderChanges ? "order changed" : ""}). Press{" "} - - Ctrl+S - {" "} - to save. - -
- )} - - {/* Search bar */} - {items.length > 0 && ( -
- - setSearchQuery(e.target.value)} - className="pl-9 h-9" - /> - {searchQuery && ( - - )} -
- )} - - - {items.length === 0 ? ( -
-

- No items in this page. + )} +

+ ) : filteredItems.length === 0 ? ( +

+ No items match "{searchQuery}".

- {canEdit && ( - - )} -
- ) : filteredItems.length === 0 ? ( -

- No items match "{searchQuery}". -

- ) : viewMode === "grid" ? ( - openEditDialog(item) : undefined} - /> - ) : ( - -
- - - - {canEdit && } - {canEdit && ( - - 0 && - selected.size === filteredItems.length - } - onCheckedChange={toggleAll} - aria-label="Select all" - /> - - )} - - ID - Name - Item IDs - Item Name - Price - Amt - Status - {canEdit && ( - Actions - )} - - - i.id)} - strategy={verticalListSortingStrategy} - > - - {orderedFilteredItems.map((item) => { - const pts = getPointsLabel(item.pointsType); - const edit = inlineEdits[item.id]; - const modified = isItemModified(item); - const isSaving = savingItemId === item.id; - const furniInfo = getFurniInfo(item); - const sortableDisabled = !canEdit || !!searchQuery; - return ( - - {({ dragHandleProps }) => ( - <> - {canEdit && ( + ) : viewMode === "grid" ? ( + openEditDialog(item) : undefined} + /> + ) : ( + +
+
+ + + {canEdit && } + {canEdit && ( + + 0 && + selected.size === filteredItems.length + } + onCheckedChange={toggleAll} + aria-label="Select all" + /> + + )} + + ID + Name + Item IDs + Item Name + Price + Amt + Status + {canEdit && ( + Actions + )} + + + i.id)} + strategy={verticalListSortingStrategy} + > + + {orderedFilteredItems.map((item) => { + const pts = getPointsLabel(item.pointsType); + const edit = inlineEdits[item.id]; + const modified = isItemModified(item); + const isSaving = savingItemId === item.id; + const furniInfo = getFurniInfo(item); + const sortableDisabled = !canEdit || !!searchQuery; + return ( + + {({ dragHandleProps }) => ( + <> + {canEdit && ( + + {!sortableDisabled ? ( +
+ +
+ ) : ( +
+ )} + + )} + {canEdit && ( + + toggleOne(item.id)} + aria-label={`Select item ${item.id}`} + /> + + )} - {!sortableDisabled ? ( -
- + + + + {item.id} + + + {item.catalogName || ( + + unnamed + + )} + + + {item.itemIds} + + + {item.baseItemName || "-"} + + + {canEdit ? ( +
+ + updateInline( + item.id, + "costCredits", + parseInt(e.target.value, 10) || 0, + ) + } + className="h-8 text-xs w-16" + title="Credits" + /> + + c + + + updateInline( + item.id, + "costPoints", + parseInt(e.target.value, 10) || 0, + ) + } + className="h-8 text-xs w-16" + title="Points" + /> + + {pts.label.charAt(0)} +
) : ( -
- )} - - )} - {canEdit && ( - - toggleOne(item.id)} - aria-label={`Select item ${item.id}`} - /> - - )} - - - - - {item.id} - - - {item.catalogName || ( - - unnamed - - )} - - - {item.itemIds} - - - {item.baseItemName || "-"} - - - {canEdit ? ( -
- - updateInline( - item.id, - "costCredits", - parseInt(e.target.value, 10) || 0, - ) - } - className="h-8 text-xs w-16" - title="Credits" - /> - - c - - - updateInline( - item.id, - "costPoints", - parseInt(e.target.value, 10) || 0, - ) - } - className="h-8 text-xs w-16" - title="Points" - /> - - {pts.label.charAt(0)} - -
- ) : ( -
- {item.costCredits > 0 && ( - - - {item.costCredits} - - )} - {item.costPoints > 0 && ( - - - {item.costPoints} - - )} - {item.costCredits === 0 && - item.costPoints === 0 && ( - - Free +
+ {item.costCredits > 0 && ( + + + {item.costCredits} )} -
- )} - - - {canEdit ? ( - - updateInline( - item.id, - "amount", - parseInt(e.target.value, 10) || 1, - ) - } - className="h-8 text-xs w-16" - /> - ) : ( - {item.amount} - )} - - -
- - {item.haveOffer === "1" - ? "Offer" - : "No Offer"} - - {item.limitedStack > 0 && ( - - LTD {item.limitedSells}/ - {item.limitedStack} - + {item.costPoints > 0 && ( + + + {item.costPoints} + + )} + {item.costCredits === 0 && + item.costPoints === 0 && ( + + Free + + )} +
)} - {item.clubOnly === "1" && ( - - HC - - )} -
-
- {canEdit && ( + -
- {modified && ( - <> - - - + {canEdit ? ( + + updateInline( + item.id, + "amount", + parseInt(e.target.value, 10) || 1, + ) + } + className="h-8 text-xs w-16" + /> + ) : ( + + {item.amount} + + )} + + +
+ + {item.haveOffer === "1" + ? "Offer" + : "No Offer"} + + {item.limitedStack > 0 && ( + + LTD {item.limitedSells}/ + {item.limitedStack} + + )} + {item.clubOnly === "1" && ( + + HC + )} - - - -
- )} - - )} - - ); - })} - - -
-
- - {activeDragId !== null && - (() => { - const dragged = items.find((i) => i.id === activeDragId); - if (!dragged) return null; - const info = getFurniInfo(dragged); - return ( -
- -
-

- {dragged.catalogName || - dragged.baseName || - `#${dragged.id}`} -

-

- #{dragged.id} -

-
-
- ); - })()} -
-
- )} - - {/* ── Edit Item Dialog (tabbed: Catalog Settings + Furniture Settings) ── */} - {editingItem && ( - { - if (!open) { - setEditingItem(null); - setEditingBase(null); - } - }} - > - - - Edit Item #{editingItem.id} - - - {/* Read-only identity fields */} -
-
- -
- {editingItem.catalogName || ( - - unnamed - - )} -
-
-
- -
- {editingItem.itemIds} -
-
+ {canEdit && ( + +
+ {modified && ( + <> + + + + )} + + + + +
+
+ )} + + )} + + ); + })} + + +
+ + {activeDragId !== null && + (() => { + const dragged = items.find((i) => i.id === activeDragId); + if (!dragged) return null; + const info = getFurniInfo(dragged); + return ( +
+ +
+

+ {dragged.catalogName || + dragged.baseName || + `#${dragged.id}`} +

+

+ #{dragged.id} +

+
+
+ ); + })()} +
+ + )} - - - - Catalog Settings - - - Furniture Settings - {!editingBase && ( - - (N/A) - - )} - - - - {/* ── Catalog Settings Tab ── */} - -
-
- - - setEditingItem( - (p) => - p && { - ...p, - costCredits: parseInt(e.target.value, 10) || 0, - }, - ) - } - /> -
-
- - - setEditingItem( - (p) => - p && { - ...p, - costPoints: parseInt(e.target.value, 10) || 0, - }, - ) - } - /> -
-
- - -
-
- -
-
- - - setEditingItem( - (p) => - p && { - ...p, - amount: parseInt(e.target.value, 10) || 1, - }, - ) - } - /> -
-
- - - setEditingItem( - (p) => - p && { - ...p, - orderNumber: parseInt(e.target.value, 10) || 0, - }, - ) - } - /> -
-
- - - setEditingItem( - (p) => - p && { - ...p, - offerId: parseInt(e.target.value, 10), - }, - ) - } - /> -
-
- -
-
- - - setEditingItem( - (p) => - p && { - ...p, - limitedSells: parseInt(e.target.value, 10) || 0, - }, - ) - } - /> -
-
- - - setEditingItem( - (p) => - p && { - ...p, - limitedStack: parseInt(e.target.value, 10) || 0, - }, - ) - } - /> -
-
- -
-
- - -
-
- - -
-
+ {/* ── Edit Item Dialog (tabbed: Catalog Settings + Furniture Settings) ── */} + {editingItem && ( + { + if (!open) { + setEditingItem(null); + setEditingBase(null); + } + }} + > + + + Edit Item #{editingItem.id} + + {/* Read-only identity fields */} +
- - - setEditingItem( - (p) => p && { ...p, extradata: e.target.value }, - ) - } - placeholder="Optional extra data" - /> + +
+ {editingItem.catalogName || ( + + unnamed + + )} +
-
- - - setEditingItem((p) => p && { ...p, songId: id }) - } - /> -

- Select a soundtrack to play when this item is used - in-game. Uploaded from /admin/sounds. -

+ +
+ {editingItem.itemIds} +
- +
- {/* ── Furniture Settings Tab (items_base) ── */} - {editingBase && ( - - {/* Identity */} -
-

- Identity -

-
-
- -
- {editingBase.id} -
-
-
- - - setEditingBase( - (p) => - p && { - ...p, - spriteId: parseInt(e.target.value, 10) || 0, - }, - ) - } - /> -
-
- - -
-
-
+ + + + Catalog Settings + + + Furniture Settings + {!editingBase && ( + + (N/A) + + )} + + - {/* Dimensions */} -
-

- Dimensions -

-
-
- - - setEditingBase( - (p) => - p && { - ...p, - width: parseInt(e.target.value, 10) || 0, - }, - ) - } - /> -
-
- - - setEditingBase( - (p) => - p && { - ...p, - length: parseInt(e.target.value, 10) || 0, - }, - ) - } - /> -
-
- - - setEditingBase( - (p) => - p && { - ...p, - stackHeight: - parseFloat(e.target.value) || 0, - }, - ) - } - /> -
-
-
- - {/* Interaction */} -
-

- Interaction -

-
-
- - - setEditingBase( - (p) => p && { ...p, interactionType: v }, - ) - } - types={interactionTypes} - /> -
-
- - - setEditingBase( - (p) => - p && { - ...p, - interactionModesCount: - parseInt(e.target.value, 10) || 0, - }, - ) - } - /> -
-
-
- - {/* Permissions */} -
-

- Permissions -

-
- - setEditingBase( - (p) => p && { ...p, allowStack: v ? 1 : 0 }, - ) - } - /> - - setEditingBase( - (p) => p && { ...p, allowSit: v ? 1 : 0 }, - ) - } - /> - - setEditingBase( - (p) => p && { ...p, allowLay: v ? 1 : 0 }, - ) - } - /> - - setEditingBase( - (p) => p && { ...p, allowWalk: v ? 1 : 0 }, - ) - } - /> - - setEditingBase( - (p) => p && { ...p, allowGift: v ? 1 : 0 }, - ) - } - /> - - setEditingBase( - (p) => p && { ...p, allowTrade: v ? 1 : 0 }, - ) - } - /> - - setEditingBase( - (p) => p && { ...p, allowRecycle: v ? 1 : 0 }, - ) - } - /> - - setEditingBase( + {/* ── Catalog Settings Tab ── */} + +
+
+ + + setEditingItem( (p) => - p && { ...p, allowMarketplaceSell: v ? 1 : 0 }, + p && { + ...p, + costCredits: + parseInt(e.target.value, 10) || 0, + }, ) } /> - - setEditingBase( +
+
+ + + setEditingItem( (p) => - p && { ...p, allowInventoryStack: v ? 1 : 0 }, + p && { + ...p, + costPoints: parseInt(e.target.value, 10) || 0, + }, + ) + } + /> +
+
+ + +
+
+ +
+
+ + + setEditingItem( + (p) => + p && { + ...p, + amount: parseInt(e.target.value, 10) || 1, + }, + ) + } + /> +
+
+ + + setEditingItem( + (p) => + p && { + ...p, + orderNumber: + parseInt(e.target.value, 10) || 0, + }, + ) + } + /> +
+
+ + + setEditingItem( + (p) => + p && { + ...p, + offerId: parseInt(e.target.value, 10), + }, ) } />
- {/* Extra */} -
-

- Extra -

-
-
+
+
+ + + setEditingItem( + (p) => + p && { + ...p, + limitedSells: + parseInt(e.target.value, 10) || 0, + }, + ) + } + /> +
+
+ + + setEditingItem( + (p) => + p && { + ...p, + limitedStack: + parseInt(e.target.value, 10) || 0, + }, + ) + } + /> +
+
+ +
+
+ + +
+
+ + +
+
+ +
+ + + setEditingItem( + (p) => p && { ...p, extradata: e.target.value }, + ) + } + placeholder="Optional extra data" + /> +
+ +
+ + + setEditingItem((p) => p && { ...p, songId: id }) + } + /> +

+ Select a soundtrack to play when this item is used + in-game. Uploaded from /admin/sounds. +

+
+ + + {/* ── Furniture Settings Tab (items_base) ── */} + {editingBase && ( + + {/* Identity */} +
+

+ Identity +

+
- + +
+ {editingBase.id} +
+
+
+ setEditingBase( (p) => - p && { ...p, vendingIds: e.target.value }, + p && { + ...p, + spriteId: + parseInt(e.target.value, 10) || 0, + }, ) } - placeholder="0" />
- + + +
+
+
+ + {/* Dimensions */} +
+

+ Dimensions +

+
+
+ setEditingBase( (p) => - p && { ...p, customparams: e.target.value }, + p && { + ...p, + width: parseInt(e.target.value, 10) || 0, + }, + ) + } + /> +
+
+ + + setEditingBase( + (p) => + p && { + ...p, + length: parseInt(e.target.value, 10) || 0, + }, + ) + } + /> +
+
+ + + setEditingBase( + (p) => + p && { + ...p, + stackHeight: + parseFloat(e.target.value) || 0, + }, + ) + } + /> +
+
+
+ + {/* Interaction */} +
+

+ Interaction +

+
+
+ + + setEditingBase( + (p) => p && { ...p, interactionType: v }, + ) + } + types={interactionTypes} + /> +
+
+ + + setEditingBase( + (p) => + p && { + ...p, + interactionModesCount: + parseInt(e.target.value, 10) || 0, + }, + ) + } + /> +
+
+
+ + {/* Permissions */} +
+

+ Permissions +

+
+ + setEditingBase( + (p) => p && { ...p, allowStack: v ? 1 : 0 }, + ) + } + /> + + setEditingBase( + (p) => p && { ...p, allowSit: v ? 1 : 0 }, + ) + } + /> + + setEditingBase( + (p) => p && { ...p, allowLay: v ? 1 : 0 }, + ) + } + /> + + setEditingBase( + (p) => p && { ...p, allowWalk: v ? 1 : 0 }, + ) + } + /> + + setEditingBase( + (p) => p && { ...p, allowGift: v ? 1 : 0 }, + ) + } + /> + + setEditingBase( + (p) => p && { ...p, allowTrade: v ? 1 : 0 }, + ) + } + /> + + setEditingBase( + (p) => p && { ...p, allowRecycle: v ? 1 : 0 }, + ) + } + /> + + setEditingBase( + (p) => + p && { + ...p, + allowMarketplaceSell: v ? 1 : 0, + }, + ) + } + /> + + setEditingBase( + (p) => + p && { ...p, allowInventoryStack: v ? 1 : 0 }, + ) + } + /> +
+
+ + {/* Extra */} +
+

+ Extra +

+
+
+
+ + + setEditingBase( + (p) => + p && { ...p, vendingIds: e.target.value }, + ) + } + placeholder="0" + /> +
+
+ + + setEditingBase( + (p) => + p && { + ...p, + customparams: e.target.value, + }, + ) + } + placeholder="" + /> +
+
+
+
+ + + setEditingBase( + (p) => + p && { + ...p, + effectIdMale: + parseInt(e.target.value, 10) || 0, + }, + ) + } + /> +
+
+ + + setEditingBase( + (p) => + p && { + ...p, + effectIdFemale: + parseInt(e.target.value, 10) || 0, + }, + ) + } + /> +
+
+
+ + + setEditingBase( + (p) => + p && { + ...p, + clothingOnWalk: e.target.value, + }, ) } placeholder="" />
-
-
- - - setEditingBase( - (p) => - p && { - ...p, - effectIdMale: - parseInt(e.target.value, 10) || 0, - }, - ) - } - /> -
-
- - - setEditingBase( - (p) => - p && { - ...p, - effectIdFemale: - parseInt(e.target.value, 10) || 0, - }, - ) - } - /> -
-
-
- - - setEditingBase( - (p) => - p && { ...p, clothingOnWalk: e.target.value }, - ) - } - placeholder="" - /> -
-
- - )} - - - {/* Action buttons */} -
- - + + + {/* Action buttons */} +
+ + +
+ +
+ )} + {/* ── Move Items Dialog ── */} + { + if (!open) { + setMoveOpen(false); + setMoveTargetPageId(null); + } + }} + > + + + + Move {selected.size} item(s) to another page + + +
+ + +
+ + +
- )} - {/* ── Move Items Dialog ── */} - { - if (!open) { - setMoveOpen(false); - setMoveTargetPageId(null); - } - }} - > - - - - Move {selected.size} item(s) to another page - - -
- - -
- - -
-
-
-
- {/* ── Move Single Item Dialog ── */} - { - if (!open) { - setMoveOneId(null); - setMoveOneTarget(null); - } - }} - > - - - Move Item to another page - -
- {/* Item info */} - {moveOneItem && ( -
- -
-

- {moveOneItem.catalogName || moveOneItem.baseName} -

-

- #{moveOneItem.id} · {moveOneItem.baseItemName || "—"} - {moveOneItem.baseItem?.interactionType && - ` · ${moveOneItem.baseItem.interactionType}`} -

+ {/* ── Move Single Item Dialog ── */} + { + if (!open) { + setMoveOneId(null); + setMoveOneTarget(null); + } + }} + > + + + Move Item to another page + +
+ {/* Item info */} + {moveOneItem && ( +
+ +
+

+ {moveOneItem.catalogName || moveOneItem.baseName} +

+

+ #{moveOneItem.id} · {moveOneItem.baseItemName || "—"} + {moveOneItem.baseItem?.interactionType && + ` · ${moveOneItem.baseItem.interactionType}`} +

+
-
- )} - - - {moveOneSuggestions.length > 0 && ( -

- Suggestions based on previous moves for similar items. -

- )} -
- - -
-
- -
- - {/* ── Bulk Price Dialog ── */} - - - - Bulk Price Update - -

- {selected.size > 0 - ? `Apply to ${selected.size} selected item(s).` - : `Apply to all ${filteredItems.length} visible item(s).`} -

-
-
- - -
-
- - -
-
- - - setBulkPriceValue(parseFloat(e.target.value) || 0) - } - placeholder={ - bulkPriceMode === "percent" ? "e.g. 10 for +10%" : "e.g. 5" - } + )} + + - {bulkPriceMode === "percent" && ( -

- Use negative values to decrease (e.g. -20 for -20%) -

- )} - {bulkPriceMode === "add" && ( -

- Use negative values to subtract + {moveOneSuggestions.length > 0 && ( +

+ Suggestions based on previous moves for similar items.

)} +
+ + +
-
- - + +
+ + {/* ── Bulk Price Dialog ── */} + + + + Bulk Price Update + +

+ {selected.size > 0 + ? `Apply to ${selected.size} selected item(s).` + : `Apply to all ${filteredItems.length} visible item(s).`} +

+
+
+ + +
+
+ + +
+
+ + + setBulkPriceValue(parseFloat(e.target.value) || 0) + } + placeholder={ + bulkPriceMode === "percent" + ? "e.g. 10 for +10%" + : "e.g. 5" + } + /> + {bulkPriceMode === "percent" && ( +

+ Use negative values to decrease (e.g. -20 for -20%) +

+ )} + {bulkPriceMode === "add" && ( +

+ Use negative values to subtract +

+ )} +
+
+ + +
-
- - - - + + + + ); } diff --git a/src/app/admin/import/clone/import-clone-client.tsx b/src/app/admin/import/clone/import-clone-client.tsx index 11423b7a..870315ab 100644 --- a/src/app/admin/import/clone/import-clone-client.tsx +++ b/src/app/admin/import/clone/import-clone-client.tsx @@ -876,7 +876,7 @@ function FurniGrid({ source }: FurniGridProps) { {/* Pagination */} {total > PER_PAGE && ( -
+
Page {page} / {lastPage} diff --git a/src/app/admin/radio/page.tsx b/src/app/admin/radio/page.tsx index 75989c56..fc5ba970 100644 --- a/src/app/admin/radio/page.tsx +++ b/src/app/admin/radio/page.tsx @@ -34,7 +34,6 @@ type Schedule = { isActive: boolean; }; - function formatTime(d: Date | null): string { return d ? d.toISOString().slice(11, 16) : "\u2014"; } @@ -108,22 +107,14 @@ export default async function AdminRadioPage() { return (
- + 0 ? "warn" : "ok"} icon="📝" /> - + ) : ( - - - - - - - - - - - {shouts.map((s) => ( - - - - - - +
+
ID{t("user")}{t("message")}{t("posted")} -
- {String(s.id)} - {String(s.userId)}{s.message} - {formatDate(s.createdAt, "datetime", "\u2014")} - -
- - -
-
+ + + + + + + - ))} - -
ID{t("user")}{t("message")}{t("posted")}
+ + + {shouts.map((s) => ( + + + {String(s.id)} + + {String(s.userId)} + {s.message} + + {formatDate(s.createdAt, "datetime", "\u2014")} + + +
+ + +
+ + + ))} + + +
)} @@ -186,42 +179,44 @@ export default async function AdminRadioPage() { {t("noApplications")}

) : ( - - - - - - - - - - - - - - - {applications.map((a) => ( - - - - - - - - - +
+
ID{t("user")}{t("realName")}{t("age")}{t("style")}Discord{t("status")}{t("applied")}
{String(a.id)}{String(a.userId)}{a.realName}{a.age}{a.musicStyle ?? "\u2014"}{a.discordUsername ?? "\u2014"} - - {a.status} - - - {formatDate(a.createdAt, "datetime", "\u2014")} -
+ + + + + + + + + + - ))} - -
ID{t("user")}{t("realName")}{t("age")}{t("style")}Discord{t("status")}{t("applied")}
+ + + {applications.map((a) => ( + + {String(a.id)} + {String(a.userId)} + {a.realName} + {a.age} + {a.musicStyle ?? "\u2014"} + {a.discordUsername ?? "\u2014"} + + + {a.status} + + + + {formatDate(a.createdAt, "datetime", "\u2014")} + + + ))} + + +
)} @@ -234,38 +229,40 @@ export default async function AdminRadioPage() { {t("noSchedules")}

) : ( - - - - - - - - - - - - - - {schedules.map((sc) => ( - - - - - - - - +
+
ID{t("user")}{t("day")}{t("start")}{t("end")}{t("show")}{t("active")}
{String(sc.id)}{String(sc.userId)}{sc.day}{formatTime(sc.startTime)}{formatTime(sc.endTime)}{sc.showName ?? "\u2014"} - - {sc.isActive ? t("active") : t("inactive")} - -
+ + + + + + + + + - ))} - -
ID{t("user")}{t("day")}{t("start")}{t("end")}{t("show")}{t("active")}
+ + + {schedules.map((sc) => ( + + {String(sc.id)} + {String(sc.userId)} + {sc.day} + {formatTime(sc.startTime)} + {formatTime(sc.endTime)} + {sc.showName ?? "\u2014"} + + + {sc.isActive ? t("active") : t("inactive")} + + + + ))} + + +
)} diff --git a/src/components/admin/data-table.tsx b/src/components/admin/data-table.tsx index 38908e62..6829ea23 100644 --- a/src/components/admin/data-table.tsx +++ b/src/components/admin/data-table.tsx @@ -414,7 +414,7 @@ export function DataTable({
{/* Table */} -
+