From 4b7e929470c6f3f29ee697ed63be3a4d025a9654 Mon Sep 17 00:00:00 2001
From: Mark Siazon <67873853+Iron-Mark@users.noreply.github.com>
Date: Wed, 1 Jul 2026 11:01:34 +0800
Subject: [PATCH] chore: polish admin tables and live smoke checks
---
docs/demo-checklist.md | 1 +
package.json | 1 +
scripts/run-live-smoke.js | 42 +++++++++
src/components/ui/table.tsx | 96 +++++++++++++++++++++
src/components/ui/tabs.tsx | 2 +-
src/pages/admin/accounts/index.tsx | 68 ++++++++-------
src/pages/admin/approvals/index.tsx | 77 +++++++++--------
src/pages/admin/audit-logs/index.tsx | 58 +++++++------
src/pages/admin/dashboard/index.tsx | 10 ++-
src/pages/faculty/profile/ProfileHeader.tsx | 4 +-
src/pages/faculty/uploaded/index.tsx | 2 +-
11 files changed, 266 insertions(+), 95 deletions(-)
create mode 100644 scripts/run-live-smoke.js
create mode 100644 src/components/ui/table.tsx
diff --git a/docs/demo-checklist.md b/docs/demo-checklist.md
index 9646bfa..9940523 100644
--- a/docs/demo-checklist.md
+++ b/docs/demo-checklist.md
@@ -89,6 +89,7 @@ Local command:
```bash
npm run seo:check
npm run links:check
+npm run smoke:live
```
## Build Preview Commands
diff --git a/package.json b/package.json
index 4755dc1..381f17f 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
"security:scan": "node scripts/check-secrets.js",
"seo:check": "node scripts/check-seo.js",
"links:check": "node scripts/check-links.js",
+ "smoke:live": "node scripts/run-live-smoke.js",
"preview": "vite preview",
"preview:pages": "node scripts/serve-pages-preview.js",
"test": "vitest --config vitest.config.ts"
diff --git a/scripts/run-live-smoke.js b/scripts/run-live-smoke.js
new file mode 100644
index 0000000..98f03c1
--- /dev/null
+++ b/scripts/run-live-smoke.js
@@ -0,0 +1,42 @@
+import { spawnSync } from 'node:child_process';
+import { existsSync } from 'node:fs';
+import { join } from 'node:path';
+
+const liveUrl = 'https://iron-mark.github.io/Hackathon-Smart-Profile-Management-System/';
+const liveBasePath = '/Hackathon-Smart-Profile-Management-System/';
+const smokeSpecs = [
+ 'tests/deep-links.spec.ts',
+ 'tests/seo.spec.ts',
+ 'tests/public-demo-responsive.spec.ts',
+];
+
+const command = join(
+ process.cwd(),
+ 'node_modules',
+ 'playwright',
+ 'cli.js'
+);
+
+if (!existsSync(command)) {
+ console.error('Playwright is not installed. Run npm ci before live smoke checks.');
+ process.exit(1);
+}
+
+const result = spawnSync(
+ process.execPath,
+ [command, 'test', ...smokeSpecs, '--reporter=line'],
+ {
+ stdio: 'inherit',
+ env: {
+ ...process.env,
+ PLAYWRIGHT_BASE_URL: liveUrl,
+ PLAYWRIGHT_BASE_PATH: liveBasePath,
+ },
+ }
+);
+
+if (result.error) {
+ console.error(result.error.message);
+}
+
+process.exit(result.status ?? 1);
diff --git a/src/components/ui/table.tsx b/src/components/ui/table.tsx
new file mode 100644
index 0000000..537a3cd
--- /dev/null
+++ b/src/components/ui/table.tsx
@@ -0,0 +1,96 @@
+import * as React from "react"
+
+import { cn } from "@/lib/utils"
+
+function Table({ className, ...props }: React.ComponentProps<"table">) {
+ return (
+
+ )
+}
+
+function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
+ return
+}
+
+function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
+ return (
+
+ )
+}
+
+function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
+ return (
+ tr]:last:border-b-0", className)}
+ {...props}
+ />
+ )
+}
+
+function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
+ return (
+
+ )
+}
+
+function TableHead({ className, ...props }: React.ComponentProps<"th">) {
+ return (
+ |
+ )
+}
+
+function TableCell({ className, ...props }: React.ComponentProps<"td">) {
+ return (
+ |
+ )
+}
+
+function TableCaption({ className, ...props }: React.ComponentProps<"caption">) {
+ return (
+
+ )
+}
+
+export {
+ Table,
+ TableBody,
+ TableCaption,
+ TableCell,
+ TableFooter,
+ TableHead,
+ TableHeader,
+ TableRow,
+}
diff --git a/src/components/ui/tabs.tsx b/src/components/ui/tabs.tsx
index fb01e0a..7bb16fe 100644
--- a/src/components/ui/tabs.tsx
+++ b/src/components/ui/tabs.tsx
@@ -14,7 +14,7 @@ const TabsList = React.forwardRef<
-
-
-
- | Name |
- Email |
- Role |
- Status |
- Actions |
-
-
-
+
+
+
+ Name
+ Email
+ Role
+ Status
+ Actions
+
+
+
{isLoading ? (
Array.from({ length: 3 }).map((_, i) => (
-
- |
- |
- |
- |
- |
-
+
+
+
+
+
+
+
+
+
))
) : (
users.map((user) => {
const deleteBlockReason = getDeleteBlockReason(user);
return (
-
- | {user.name} |
- {user.email} |
- {user.type || "faculty"} |
-
+
+ {user.name}
+ {user.email}
+ {user.type || "faculty"}
+
Active
- |
-
+
+
- |
-
+
+
);
})
)}
-
-
+
+
{!isLoading && users.length === 0 && (
diff --git a/src/pages/admin/approvals/index.tsx b/src/pages/admin/approvals/index.tsx
index 149404c..8edb59d 100644
--- a/src/pages/admin/approvals/index.tsx
+++ b/src/pages/admin/approvals/index.tsx
@@ -5,6 +5,14 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { SidebarProvider } from "@/components/ui/sidebar";
import { Badge } from "@/components/ui/badge";
import { Skeleton } from "@/components/ui/skeleton";
+import {
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableHeader,
+ TableRow,
+} from "@/components/ui/table";
import getFromDatabase from "@/tools/database/getFromDatabase";
import updateDatabase from "@/tools/database/updateDatabase";
import getFileFromFolder from "@/tools/buckets/getFileFromFolder";
@@ -101,42 +109,43 @@ export default function AdminApprovalsPage() {
Faculty Submissions
-
-
-
- | Faculty Name |
- Document Type |
- File Name |
- Date Submitted |
- Status |
- Actions |
-
-
-
+
+
+
+ Faculty Name
+ Document Type
+ File Name
+ Date Submitted
+ Status
+ Actions
+
+
+
{isLoading ? (
Array.from({ length: 5 }).map((_, i) => (
-
- |
- |
- |
- |
- |
- |
-
+
+
+
+
+
+
+
+
+
+
))
) : (
submissions.map((submission) => (
-
- | {submission.facultyName} |
- {submission.document_type} |
- {submission.file_name} |
-
+ {submission.facultyName}
+ {submission.document_type}
+ {submission.file_name}
+
{new Date(submission.submitted_at).toLocaleDateString()}
- |
-
+
+
{submission.status}
- |
-
+
+
{submission.status === "Pending" && (
<>
- |
-
+
+
))
)}
-
-
+
+
{!isLoading && submissions.length === 0 && (
No submissions found.
diff --git a/src/pages/admin/audit-logs/index.tsx b/src/pages/admin/audit-logs/index.tsx
index fc258d4..523fad7 100644
--- a/src/pages/admin/audit-logs/index.tsx
+++ b/src/pages/admin/audit-logs/index.tsx
@@ -12,6 +12,14 @@ import {
SelectValue,
} from "@/components/ui/select";
import { Skeleton } from "@/components/ui/skeleton";
+import {
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableHeader,
+ TableRow,
+} from "@/components/ui/table";
import getFromDatabase from "@/tools/database/getFromDatabase";
interface AuditLog {
@@ -133,39 +141,39 @@ export default function AdminAuditLogsPage() {
-
-
-
- | Timestamp |
- User |
- Action |
- Details |
-
-
-
+
+
+
+ Timestamp
+ User
+ Action
+ Details
+
+
+
{isLoading ? (
Array.from({ length: 5 }).map((_, i) => (
-
- |
- |
- |
- |
-
+
+
+
+
+
+
))
) : (
filteredLogs.map((log) => (
-
- |
+
+
{new Date(log.timestamp).toLocaleString()}
- |
- {log.user_email} |
- {log.action} |
- {log.details} |
-
+
+ {log.user_email}
+ {log.action}
+ {log.details}
+
))
)}
-
-
+
+
{!isLoading && filteredLogs.length === 0 && (
diff --git a/src/pages/admin/dashboard/index.tsx b/src/pages/admin/dashboard/index.tsx
index 222acc6..943114f 100644
--- a/src/pages/admin/dashboard/index.tsx
+++ b/src/pages/admin/dashboard/index.tsx
@@ -205,7 +205,7 @@ export default function AdminDashboard() {
Active Sessions (24h)
- Recent seeded login activity
+ Recent seeded login activity
{isLoading ? : activeSessions}
@@ -218,7 +218,7 @@ export default function AdminDashboard() {
Pending Approvals
- Credentials waiting for review
+ Credentials waiting for review
{isLoading ? : pendingApprovals}
@@ -276,7 +276,11 @@ export default function AdminDashboard() {
))}
-
+