chore: remove dead code, unused CSS, unused components, and clean up git tracking

- Remove storage/logs/ and prod.log from git tracking; add to .gitignore
- Remove unused AvatarCarousel and ArticleSlider components
- Remove unused SkeletonTable export from ui.tsx
- Remove unused ChevronDown import from admin layout
- Remove 13 unused CSS classes (icon-base, nav-*, navigation-icon*, .app.dark,
  text-body, transition-base, card-base, admin-info-grid, .coin.*)
- Remove duplicate translation keys (openMenu/closeMenu in en.json)
- Fix admin-bans to use Prisma-generated bans_type enum
- Create shared AdminPageHeader component and formatDate utility
- Add logger and generateRequestId for structured logging
- All 58 tests pass, typecheck clean, build succeeds
This commit is contained in:
openhands committed 2026-07-08 13:27:01 +02:00
1 parent c5db7f5156
commit fc57fb06d1
18 files changed
+40 -2551

No files matched your search

+4
View File
@@ -6,3 +6,7 @@ next-env.d.ts
*.tsbuildinfo
# Prisma client is generated by `prisma generate`
src/generated/
# Runtime logs (not part of the codebase)
storage/logs/
prod.log
*.log
-14
View File
@@ -1,14 +0,0 @@
> atomcms-next@ start /var/www/atom-nexst
> next start
▲ Next.js 16.2.10
- Local: http://localhost:3000
- Network: http://5.252.100.130:3000
✓ Ready in 108ms
prisma:error
Invalid `prisma.websiteLoginLogs.create()` invocation:
The table `website_login_logs` does not exist in the current database.
 ELIFECYCLE  Command failed.
+2 -1
View File
@@ -5,8 +5,9 @@ import { requireStaffRateLimited as requireStaff } from "@/lib/admin/guard";
import { prisma } from "@/lib/prisma";
import { rcon } from "@/lib/services/rcon";
import { logStaffActivity } from "@/lib/services/staff-activity";
import type { $Enums } from "@/generated/prisma/client";
type BanType = "account" | "ip" | "machine" | "super";
type BanType = $Enums.bans_type;
const BAN_TYPES: ReadonlySet<string> = new Set(["account", "ip", "machine", "super"]);
const PERMANENT_SECONDS = 100 * 365 * 24 * 3600;
+1 -1
View File
@@ -11,7 +11,7 @@ import {
Store, ShoppingCart, Receipt, Ticket, CreditCard, Gem, Award, Trophy, Calendar,
Radio, History,
Terminal, Monitor, Bell, FileText, Filter, Wrench, Settings, DoorOpen, Mail, Palette, Cog,
ChevronDown, LogOut,
LogOut,
} from "lucide-react";
export const dynamic = "force-dynamic";
+1 -80
View File
File diff suppressed because it is too large. Load diff
+21
View File
@@ -0,0 +1,21 @@
import type { LucideIcon } from "lucide-react";
interface AdminPageHeaderProps {
icon: LucideIcon;
title: string;
subtitle: string;
}
export function AdminPageHeader({ icon: Icon, title, subtitle }: AdminPageHeaderProps) {
return (
<div className="flex items-center gap-3 mb-6">
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-[var(--color-primary)]/20 to-[var(--color-primary)]/5 grid place-items-center">
<Icon size={20} className="text-[var(--color-primary)]" />
</div>
<div>
<h1 className="m-0 text-xl font-extrabold text-[var(--color-text)]">{title}</h1>
<p className="m-0 text-xs text-[var(--color-text-muted)] mt-0.5">{subtitle}</p>
</div>
</div>
);
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+1 -23
View File
@@ -135,26 +135,4 @@ export function SkeletonCard({ lines = 3 }: { lines?: number }) {
);
}
export function SkeletonTable({ rows = 5 }: { rows?: number }) {
return (
<div className="content-card" style={{ padding: "0.5rem 1rem 1rem" }}>
{Array.from({ length: rows }).map((_, i) => (
<div key={i} style={{ display: "flex", alignItems: "center", gap: "0.75rem", padding: "0.6rem 0", borderTop: i > 0 ? "1px solid color-mix(in srgb, var(--color-text-muted) 12%, transparent)" : undefined }}>
{i === 0 ? (
<>
<Skeleton style={{ height: "12px", width: "30%" }} />
<Skeleton style={{ height: "12px", width: "20%" }} />
<Skeleton style={{ height: "12px", width: "25%", marginLeft: "auto" }} />
</>
) : (
<>
<Skeleton style={{ width: "28px", height: "28px", borderRadius: "8px" }} />
<Skeleton style={{ height: "14px", width: "35%" }} />
<Skeleton style={{ height: "14px", width: "20%", marginLeft: "auto" }} />
</>
)}
</div>
))}
</div>
);
}
+9
View File
@@ -0,0 +1,9 @@
/** Format a Date as 'YYYY-MM-DD HH:MM:SS' — used across admin and radio pages. */
export function formatDateTime(d: Date | null | undefined): string {
return d ? d.toISOString().slice(0, 19).replace("T", " ") : "";
}
/** Format a Date as 'YYYY-MM-DD' — used across radio list pages. */
export function formatDate(d: Date | null | undefined): string {
return d ? d.toISOString().slice(0, 10) : "";
}
+1 -3
View File
@@ -21,9 +21,7 @@
"admin": "Admin",
"openMenu": "Open menu",
"closeMenu": "Close menu",
"drawBadge": "Draw badge",
"openMenu": "Open menu",
"closeMenu": "Close menu"
"drawBadge": "Draw badge"
},
"header": {
"online": "{count} {hotel} online",
@@ -1,13 +0,0 @@
<!-- To: [email protected] | From: | Subject: Verify your email · Epicnabbo -->
<div style="font-family:sans-serif;line-height:1.5;color:#0f172a">
<h2 style="margin:0 0 0.5rem">Verify your email</h2>
<p>Welcome to Epicnabbo! Confirm this email address to finish setting up your account.</p>
<p style="margin:1.25rem 0">
<a href="https://epicnabbo.nl/verify?token=5e21ef6e09952e9bb7257d54c1fe896713c0f05e6d92a1f8669869d875ab2693&email=juanedavid%40hotmail.com"
style="display:inline-block;padding:0.6rem 1.2rem;border-radius:8px;background:#eeb425;color:#1a1a2e;font-weight:700;text-decoration:none">
Verify email
</a>
</p>
<p style="color:#64748b;font-size:0.875rem">If the button doesn't work, paste this link into your browser:</p>
<p style="color:#64748b;font-size:0.875rem;word-break:break-all">https://epicnabbo.nl/verify?token=5e21ef6e09952e9bb7257d54c1fe896713c0f05e6d92a1f8669869d875ab2693&email=juanedavid%40hotmail.com</p>
</div>
-74
View File
@@ -1,74 +0,0 @@

╔═══════════════════════════════════════════════════════════════════════════╗
║ ║
║ ███████╗███╗ ███╗ █████╗ ██████╗ ████████╗ ║
║ ██╔════╝████╗ ████║██╔══██╗██╔══██╗╚══██╔══╝ ║
║ █████╗ ██╔████╔██║███████║██████╔╝ ██║ ║
║ ██╔══╝ ██║╚██╔╝██║██╔══██║██╔══██╗ ██║ ║
║ ███████╗██║ ╚═╝ ██║██║ ██║██║ ██║ ██║ ║
║ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ║
║ ║
╠═══════════════════════════════════════════════════════════════════════════╣
║  Emulator / Nitro-V3 / Nitro-V3-Render ║
║  Updater by Remco — epicnabbo.nl ║
╠═══════════════════════════════════════════════════════════════════════════╣
║ Branch: main (2 detected) │ 19:21 ║
╚═══════════════════════════════════════════════════════════════════════════╝

 UPDATE 
1) 🚀 Quick Update — branch: main
2) ⚡ Full Update (choose branch)
3) ⚙ Emulator Only
4) ⚙ Nitro-V3 Client Only
5) ⚙ Renderer Only
6) ⚙ Configs Only
 TOOLS 
7) 🔀 Switch Branch
8) 🗄 Database
9) 🛡 Backup / Restore
10) 🔧 Services
11) 📊 Status
12) ♥ Health Check
13) 🧹 Clean
14) 👁 Logs
15) ⚙ Config
 ADVANCED 
16) 🖥 Git Log
17) 🌐 Compare Branches
18) ⏱ Cron Scheduler
0) Exit
Select [0-18]:
Update: Full
1) Dev
2) main (current)
3) Custom
Branch [1-3]:
Branch: Dev Mode: Full
➜ Start update? [Y/n]
➜ Site: https://epicnabbo.nl:3000 | Branch: Dev | Mode: full
[2026-07-02 19:21:32] [INFO] Site: https://epicnabbo.nl:3000 | Branch: Dev | Mode: full
➜ Log: /var/www/atom-nexst/storage/logs/update-20260702-192111.log
[2026-07-02 19:21:32] [INFO] Log: /var/www/atom-nexst/storage/logs/update-20260702-192111.log
 Step 1/8 — System Diagnostics 
✔ All commands available
[2026-07-02 19:21:32] [OK] All commands available
✔ All directories exist
[2026-07-02 19:21:32] [OK] All directories exist
✔ 123GB disk available
[2026-07-02 19:21:32] [OK] 123GB disk available
 ERROR  DB connection failed
[2026-07-02 19:21:32] [FATAL] DB connection failed
[?12l[?25h ⚠ Update had errors
[2026-07-02 19:21:32] [WARN] Update had errors
Press Enter to continue...[?12l[?25h[?12l[?25h
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff