2025-08-09 07:10:04 -04:00
|
|
|
import React, { useState, useEffect, Suspense, lazy } from "react";
|
|
|
|
|
import { toast } from 'react-toastify';
|
2025-07-31 19:28:59 -04:00
|
|
|
import { DataTable } from "primereact/datatable";
|
|
|
|
|
import { Column } from "primereact/column";
|
|
|
|
|
import { Dropdown } from "primereact/dropdown";
|
|
|
|
|
import { Button } from "@mui/joy";
|
2025-08-01 15:17:25 -04:00
|
|
|
import { Dialog } from "primereact/dialog";
|
2025-07-31 20:25:02 -04:00
|
|
|
import { confirmDialog, ConfirmDialog } from "primereact/confirmdialog";
|
2025-07-31 19:28:59 -04:00
|
|
|
import BreadcrumbNav from "./BreadcrumbNav";
|
|
|
|
|
|
2025-07-31 20:25:02 -04:00
|
|
|
|
2025-07-31 19:28:59 -04:00
|
|
|
const STATUS_OPTIONS = ["Pending", "Completed", "Failed"];
|
|
|
|
|
const TYPE_OPTIONS = ["Artist", "Album", "Track"];
|
|
|
|
|
|
|
|
|
|
const initialRequests = [
|
|
|
|
|
{
|
|
|
|
|
id: 1,
|
|
|
|
|
type: "Artist",
|
|
|
|
|
artist: "Bring Me The Horizon",
|
|
|
|
|
album: "",
|
|
|
|
|
track: "",
|
|
|
|
|
status: "Pending",
|
2025-08-01 15:17:25 -04:00
|
|
|
details: {
|
|
|
|
|
requestedBy: "codey",
|
|
|
|
|
timestamp: "2025-07-01T12:00:00Z",
|
|
|
|
|
comments: "",
|
|
|
|
|
},
|
2025-07-31 19:28:59 -04:00
|
|
|
},
|
|
|
|
|
{
|
2025-08-01 15:29:27 -04:00
|
|
|
id: 2,
|
2025-07-31 19:28:59 -04:00
|
|
|
type: "Track",
|
|
|
|
|
artist: "We Butter The Bread With Butter",
|
|
|
|
|
album: "Das Album",
|
|
|
|
|
track: "20 km/h",
|
|
|
|
|
status: "Failed",
|
2025-08-01 15:17:25 -04:00
|
|
|
details: {
|
|
|
|
|
requestedBy: "codey",
|
|
|
|
|
timestamp: "2025-06-11T09:00:00Z",
|
|
|
|
|
comments: "Track not found in external database.",
|
|
|
|
|
},
|
2025-07-31 19:28:59 -04:00
|
|
|
},
|
|
|
|
|
{
|
2025-08-01 15:17:25 -04:00
|
|
|
id: 3,
|
2025-07-31 19:28:59 -04:00
|
|
|
type: "Track",
|
2025-08-01 15:17:25 -04:00
|
|
|
artist: "We Butter The Bread With Butter",
|
|
|
|
|
album: "Das Album",
|
|
|
|
|
track: "20 km/h",
|
2025-07-31 19:28:59 -04:00
|
|
|
status: "Completed",
|
2025-08-01 15:17:25 -04:00
|
|
|
details: {
|
|
|
|
|
requestedBy: "codey",
|
|
|
|
|
timestamp: "2025-06-11T09:00:00Z",
|
2025-08-01 15:29:27 -04:00
|
|
|
comments: "Track retrieved successfully.",
|
2025-08-01 15:17:25 -04:00
|
|
|
},
|
2025-07-31 19:28:59 -04:00
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
2025-08-01 15:17:25 -04:00
|
|
|
|
2025-07-31 19:28:59 -04:00
|
|
|
export default function RequestManagement() {
|
|
|
|
|
const [requests, setRequests] = useState(initialRequests);
|
|
|
|
|
const [filterType, setFilterType] = useState(null);
|
|
|
|
|
const [filterStatus, setFilterStatus] = useState(null);
|
|
|
|
|
const [filteredRequests, setFilteredRequests] = useState(initialRequests);
|
2025-08-01 15:17:25 -04:00
|
|
|
const [selectedRequest, setSelectedRequest] = useState(null);
|
|
|
|
|
const [isDialogVisible, setIsDialogVisible] = useState(false);
|
|
|
|
|
|
2025-07-31 19:28:59 -04:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
let filtered = [...requests];
|
|
|
|
|
if (filterType) {
|
|
|
|
|
filtered = filtered.filter((r) => r.type === filterType);
|
|
|
|
|
}
|
|
|
|
|
if (filterStatus) {
|
|
|
|
|
filtered = filtered.filter((r) => r.status === filterStatus);
|
|
|
|
|
}
|
|
|
|
|
setFilteredRequests(filtered);
|
|
|
|
|
}, [filterType, filterStatus, requests]);
|
|
|
|
|
|
2025-08-01 15:29:27 -04:00
|
|
|
const getStatusTextColor = (status) => {
|
|
|
|
|
switch (status) {
|
|
|
|
|
case "Pending":
|
|
|
|
|
return "text-yellow-500";
|
|
|
|
|
case "Completed":
|
|
|
|
|
return "text-green-500";
|
|
|
|
|
case "Failed":
|
|
|
|
|
return "text-red-500";
|
|
|
|
|
default:
|
|
|
|
|
return "text-neutral-500";
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2025-07-31 19:28:59 -04:00
|
|
|
const confirmDelete = (requestId) => {
|
|
|
|
|
confirmDialog({
|
|
|
|
|
message: "Are you sure you want to delete this request?",
|
|
|
|
|
header: "Confirm Delete",
|
|
|
|
|
icon: "pi pi-exclamation-triangle",
|
|
|
|
|
accept: () => deleteRequest(requestId),
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const deleteRequest = (requestId) => {
|
|
|
|
|
setRequests((prev) => prev.filter((r) => r.id !== requestId));
|
|
|
|
|
toast.success("Request deleted");
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const statusBodyTemplate = (rowData) => {
|
|
|
|
|
let colorClass = "";
|
|
|
|
|
|
|
|
|
|
switch (rowData.status) {
|
|
|
|
|
case "Pending":
|
|
|
|
|
colorClass = "bg-yellow-300 text-yellow-900";
|
|
|
|
|
break;
|
|
|
|
|
case "Completed":
|
|
|
|
|
colorClass = "bg-green-300 text-green-900";
|
|
|
|
|
break;
|
|
|
|
|
case "Failed":
|
|
|
|
|
colorClass = "bg-red-300 text-red-900";
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
colorClass = "bg-gray-300 text-gray-900";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<span
|
|
|
|
|
className={`inline-block px-3 py-1 rounded-full font-semibold text-sm ${colorClass}`}
|
|
|
|
|
aria-label={`Status: ${rowData.status}`}
|
|
|
|
|
>
|
|
|
|
|
{rowData.status}
|
|
|
|
|
</span>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const actionBodyTemplate = (rowData) => {
|
|
|
|
|
return (
|
|
|
|
|
<Button
|
|
|
|
|
color="danger"
|
|
|
|
|
size="sm"
|
|
|
|
|
onClick={() => confirmDelete(rowData.id)}
|
|
|
|
|
variant="outlined"
|
|
|
|
|
>
|
|
|
|
|
Delete
|
|
|
|
|
</Button>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div
|
|
|
|
|
className="bg-white dark:bg-neutral-900 dark:text-neutral-100 rounded-xl shadow-md border border-neutral-200 dark:border-neutral-700 p-6 space-y-6"
|
|
|
|
|
style={{ display: "inline-block" }}
|
|
|
|
|
>
|
|
|
|
|
<style>{`
|
|
|
|
|
.p-datatable {
|
|
|
|
|
background-color: white;
|
|
|
|
|
color: #1a1a1a;
|
|
|
|
|
border-color: #ccc;
|
|
|
|
|
}
|
|
|
|
|
.p-datatable-header {
|
|
|
|
|
background-color: #f9f9f9;
|
|
|
|
|
color: #333;
|
|
|
|
|
border-bottom: 1px solid #ccc;
|
|
|
|
|
}
|
|
|
|
|
.p-datatable-thead > tr > th {
|
|
|
|
|
background-color: #f0f0f0;
|
|
|
|
|
color: #222;
|
|
|
|
|
border-bottom: 1px solid #ccc;
|
|
|
|
|
}
|
|
|
|
|
.p-datatable-tbody > tr > td {
|
|
|
|
|
border-bottom: 1px solid #eee;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Dark mode improvements with brighter text */
|
|
|
|
|
[data-theme="dark"] .p-datatable {
|
|
|
|
|
background-color: #121212;
|
|
|
|
|
color: #f0f0f0; /* brighter text */
|
|
|
|
|
border-color: #333;
|
|
|
|
|
}
|
|
|
|
|
[data-theme="dark"] .p-datatable-header {
|
|
|
|
|
background-color: #1f1f1f;
|
|
|
|
|
color: #f5f5f5; /* brighter */
|
|
|
|
|
border-bottom: 1px solid #444;
|
|
|
|
|
}
|
|
|
|
|
[data-theme="dark"] .p-datatable-thead > tr > th {
|
|
|
|
|
background-color: #222222;
|
|
|
|
|
color: #f5f5f5; /* brighter */
|
|
|
|
|
border-bottom: 1px solid #555;
|
|
|
|
|
}
|
|
|
|
|
[data-theme="dark"] .p-datatable-tbody > tr {
|
|
|
|
|
background-color: #1a1a1a;
|
|
|
|
|
border-bottom: 1px solid #333;
|
|
|
|
|
transition: background-color 0.2s ease;
|
|
|
|
|
color: #f0f0f0; /* brighter text */
|
|
|
|
|
}
|
|
|
|
|
/* Zebra stripes */
|
|
|
|
|
[data-theme="dark"] .p-datatable-tbody > tr:nth-child(odd) {
|
|
|
|
|
background-color: #181818;
|
|
|
|
|
color: #f0f0f0;
|
|
|
|
|
}
|
|
|
|
|
/* Hover effect */
|
|
|
|
|
[data-theme="dark"] .p-datatable-tbody > tr:hover {
|
|
|
|
|
background-color: #333333;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
color: #fff; /* brightest on hover */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Dropdown inside dark mode */
|
|
|
|
|
[data-theme="dark"] .p-dropdown,
|
|
|
|
|
[data-theme="dark"] .p-dropdown-label,
|
|
|
|
|
[data-theme="dark"] .p-dropdown-panel,
|
|
|
|
|
[data-theme="dark"] .p-dropdown-item {
|
|
|
|
|
background-color: #2a2a2a !important;
|
|
|
|
|
color: #f0f0f0 !important; /* brighter */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Buttons */
|
|
|
|
|
[data-theme="dark"] .p-button {
|
|
|
|
|
background-color: transparent !important;
|
|
|
|
|
color: #f0f0f0 !important; /* brighter */
|
|
|
|
|
border-color: #555 !important;
|
|
|
|
|
transition: background-color 0.2s ease;
|
|
|
|
|
}
|
|
|
|
|
[data-theme="dark"] .p-button:hover {
|
|
|
|
|
background-color: #555 !important;
|
|
|
|
|
color: #fff !important;
|
|
|
|
|
}
|
|
|
|
|
[data-theme="dark"] .p-button.p-button-danger {
|
|
|
|
|
border-color: #ff4d4f !important;
|
|
|
|
|
color: #ff4d4f !important;
|
|
|
|
|
}
|
|
|
|
|
[data-theme="dark"] .p-button.p-button-danger:hover {
|
|
|
|
|
background-color: #ff4d4f !important;
|
|
|
|
|
color: #fff !important;
|
|
|
|
|
}
|
|
|
|
|
/* ===== PrimeReact Paginator Light Mode ===== */
|
|
|
|
|
.p-paginator {
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
color: #1a1a1a;
|
|
|
|
|
border-top: 1px solid #ddd;
|
|
|
|
|
}
|
|
|
|
|
.p-paginator .p-paginator-page,
|
|
|
|
|
.p-paginator .p-paginator-next,
|
|
|
|
|
.p-paginator .p-paginator-prev {
|
|
|
|
|
color: #1a1a1a;
|
|
|
|
|
border: none;
|
|
|
|
|
background: transparent;
|
|
|
|
|
}
|
|
|
|
|
.p-paginator .p-highlight {
|
|
|
|
|
background-color: #007bff;
|
|
|
|
|
color: white;
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ===== PrimeReact Paginator Dark Mode ===== */
|
|
|
|
|
[data-theme="dark"] .p-paginator {
|
|
|
|
|
background-color: #121212;
|
|
|
|
|
color: #f0f0f0;
|
|
|
|
|
border-top: 1px solid #333;
|
|
|
|
|
}
|
|
|
|
|
[data-theme="dark"] .p-paginator .p-paginator-page,
|
|
|
|
|
[data-theme="dark"] .p-paginator .p-paginator-next,
|
|
|
|
|
[data-theme="dark"] .p-paginator .p-paginator-prev {
|
|
|
|
|
color: #ccc;
|
|
|
|
|
border: none;
|
|
|
|
|
background: transparent;
|
|
|
|
|
}
|
|
|
|
|
[data-theme="dark"] .p-paginator .p-paginator-page:hover,
|
|
|
|
|
[data-theme="dark"] .p-paginator .p-paginator-next:hover,
|
|
|
|
|
[data-theme="dark"] .p-paginator .p-paginator-prev:hover {
|
|
|
|
|
background-color: #333;
|
|
|
|
|
color: #fff;
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
}
|
|
|
|
|
[data-theme="dark"] .p-paginator .p-highlight {
|
|
|
|
|
background-color: #3b82f6; /* Tailwind blue-500 */
|
|
|
|
|
color: white;
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
}
|
|
|
|
|
.p-paginator .p-paginator-first,
|
|
|
|
|
.p-paginator .p-paginator-last {
|
|
|
|
|
color: #1a1a1a;
|
|
|
|
|
background: transparent;
|
|
|
|
|
border: none;
|
|
|
|
|
}
|
|
|
|
|
.p-paginator .p-paginator-first:hover,
|
|
|
|
|
.p-paginator .p-paginator-last:hover {
|
|
|
|
|
background-color: #f0f0f0;
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Dark Mode: First/Last page buttons */
|
|
|
|
|
[data-theme="dark"] .p-paginator .p-paginator-first,
|
|
|
|
|
[data-theme="dark"] .p-paginator .p-paginator-last {
|
|
|
|
|
color: #ccc;
|
|
|
|
|
background: transparent;
|
|
|
|
|
border: none;
|
|
|
|
|
}
|
|
|
|
|
[data-theme="dark"] .p-paginator .p-paginator-first:hover,
|
|
|
|
|
[data-theme="dark"] .p-paginator .p-paginator-last:hover {
|
|
|
|
|
background-color: #333;
|
|
|
|
|
color: #fff;
|
|
|
|
|
border-radius: 6px;
|
2025-07-31 20:25:02 -04:00
|
|
|
}
|
|
|
|
|
/* ConfirmDialog - Light Theme */
|
|
|
|
|
.p-confirm-dialog {
|
|
|
|
|
background-color: #ffffff;
|
|
|
|
|
color: #1a1a1a;
|
|
|
|
|
border: 1px solid #ccc;
|
|
|
|
|
}
|
|
|
|
|
.p-confirm-dialog .p-dialog-header {
|
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
|
color: #222;
|
|
|
|
|
}
|
|
|
|
|
.p-confirm-dialog .p-dialog-content {
|
|
|
|
|
background-color: #ffffff;
|
|
|
|
|
color: #333;
|
|
|
|
|
}
|
|
|
|
|
.p-confirm-dialog .p-dialog-footer {
|
|
|
|
|
background-color: #fafafa;
|
|
|
|
|
border-top: 1px solid #ddd;
|
|
|
|
|
}
|
|
|
|
|
.p-confirm-dialog .p-button {
|
|
|
|
|
border-radius: 0.5rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ConfirmDialog - Dark Theme */
|
|
|
|
|
[data-theme='dark'] .p-confirm-dialog {
|
|
|
|
|
background-color: #2a2a2a;
|
|
|
|
|
color: #e5e5e5;
|
|
|
|
|
border: 1px solid #444;
|
|
|
|
|
}
|
|
|
|
|
[data-theme='dark'] .p-confirm-dialog .p-dialog-header {
|
|
|
|
|
background-color: #1f1f1f;
|
|
|
|
|
color: #ddd;
|
|
|
|
|
}
|
|
|
|
|
[data-theme='dark'] .p-confirm-dialog .p-dialog-content {
|
|
|
|
|
background-color: #2a2a2a;
|
|
|
|
|
color: #ccc;
|
|
|
|
|
}
|
|
|
|
|
[data-theme='dark'] .p-confirm-dialog .p-dialog-footer {
|
|
|
|
|
background-color: #242424;
|
|
|
|
|
border-top: 1px solid #333;
|
|
|
|
|
}
|
|
|
|
|
[data-theme='dark'] .p-confirm-dialog .p-button {
|
|
|
|
|
background-color: transparent !important;
|
|
|
|
|
color: #ddd !important;
|
|
|
|
|
border-color: #555 !important;
|
|
|
|
|
}
|
|
|
|
|
[data-theme='dark'] .p-confirm-dialog .p-button.p-button-danger {
|
|
|
|
|
color: #ff4d4f !important;
|
|
|
|
|
border-color: #ff4d4f !important;
|
|
|
|
|
}
|
|
|
|
|
[data-theme='dark'] .p-dialog-title {
|
|
|
|
|
color: #eee;
|
|
|
|
|
}
|
|
|
|
|
[data-theme='dark'] .p-dialog-header-icon {
|
|
|
|
|
color: #ccc;
|
|
|
|
|
}
|
2025-08-01 15:17:25 -04:00
|
|
|
/* PrimeReact Dialog Theming */
|
|
|
|
|
.p-dialog {
|
|
|
|
|
background-color: #ffffff;
|
|
|
|
|
color: #000000;
|
|
|
|
|
}
|
2025-07-31 20:25:02 -04:00
|
|
|
|
2025-08-01 15:17:25 -04:00
|
|
|
[data-theme="dark"] .p-dialog {
|
|
|
|
|
background-color: #1e1e1e;
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-theme="dark"] .p-dialog .p-dialog-header {
|
|
|
|
|
background-color: #1e1e1e;
|
|
|
|
|
border-bottom: 1px solid #444;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-theme="dark"] .p-dialog .p-dialog-content {
|
|
|
|
|
background-color: #2a2a2a;
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-theme="dark"] .p-dialog .p-dialog-footer {
|
|
|
|
|
background-color: #1e1e1e;
|
|
|
|
|
border-top: 1px solid #444;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-07-31 20:25:02 -04:00
|
|
|
`}</style>
|
2025-07-31 19:28:59 -04:00
|
|
|
<BreadcrumbNav currentPage="management" />
|
|
|
|
|
<h2 className="text-3xl font-semibold" style={{ marginTop: 0 }}>
|
|
|
|
|
Media Request Management
|
|
|
|
|
</h2>
|
|
|
|
|
|
|
|
|
|
<div className="flex flex-wrap gap-6 mb-6">
|
|
|
|
|
<Dropdown
|
|
|
|
|
value={filterType}
|
|
|
|
|
options={[
|
|
|
|
|
{ label: "All Types", value: null },
|
|
|
|
|
...TYPE_OPTIONS.map((t) => ({ label: t, value: t })),
|
|
|
|
|
]}
|
|
|
|
|
onChange={(e) => setFilterType(e.value)}
|
|
|
|
|
placeholder="Filter by Type"
|
|
|
|
|
className="min-w-[180px]"
|
|
|
|
|
/>
|
|
|
|
|
<Dropdown
|
|
|
|
|
value={filterStatus}
|
|
|
|
|
options={[
|
|
|
|
|
{ label: "All Statuses", value: null },
|
|
|
|
|
...STATUS_OPTIONS.map((s) => ({ label: s, value: s })),
|
|
|
|
|
]}
|
|
|
|
|
onChange={(e) => setFilterStatus(e.value)}
|
|
|
|
|
placeholder="Filter by Status"
|
|
|
|
|
className="min-w-[180px]"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<DataTable
|
|
|
|
|
value={filteredRequests}
|
|
|
|
|
paginator
|
|
|
|
|
rows={10}
|
|
|
|
|
removableSort
|
|
|
|
|
sortMode="multiple"
|
|
|
|
|
emptyMessage="No requests found."
|
|
|
|
|
rowClassName="!py-4"
|
|
|
|
|
className="min-w-full bg-white dark:bg-neutral-900 text-neutral-900 dark:text-neutral-100"
|
2025-08-01 15:17:25 -04:00
|
|
|
onRowClick={(e) => {
|
|
|
|
|
setSelectedRequest(e.data);
|
|
|
|
|
setIsDialogVisible(true);
|
|
|
|
|
}}
|
2025-07-31 19:28:59 -04:00
|
|
|
>
|
|
|
|
|
<Column field="id" header="ID" sortable style={{ width: "5rem" }} />
|
|
|
|
|
<Column field="type" header="Type" sortable />
|
|
|
|
|
<Column field="artist" header="Artist" sortable />
|
|
|
|
|
<Column field="album" header="Album" sortable />
|
|
|
|
|
<Column field="track" header="Track" sortable />
|
|
|
|
|
<Column
|
|
|
|
|
field="status"
|
|
|
|
|
header="Status"
|
|
|
|
|
body={statusBodyTemplate}
|
|
|
|
|
style={{ width: "10rem", textAlign: "center" }}
|
|
|
|
|
sortable
|
|
|
|
|
/>
|
|
|
|
|
<Column
|
|
|
|
|
body={actionBodyTemplate}
|
|
|
|
|
header="Actions"
|
|
|
|
|
style={{ width: "9rem", textAlign: "center" }}
|
|
|
|
|
/>
|
|
|
|
|
</DataTable>
|
2025-07-31 20:25:02 -04:00
|
|
|
<ConfirmDialog />
|
2025-08-01 15:17:25 -04:00
|
|
|
<Dialog
|
|
|
|
|
header="Request Details"
|
|
|
|
|
visible={isDialogVisible}
|
|
|
|
|
style={{ width: "500px" }}
|
|
|
|
|
onHide={() => setIsDialogVisible(false)}
|
|
|
|
|
breakpoints={{ '960px': '95vw' }}
|
2025-08-01 15:29:27 -04:00
|
|
|
modal
|
|
|
|
|
dismissableMask
|
2025-08-01 15:17:25 -04:00
|
|
|
>
|
|
|
|
|
{selectedRequest && (
|
|
|
|
|
<div className="space-y-4 text-sm">
|
|
|
|
|
<p><strong>ID:</strong> {selectedRequest.id}</p>
|
|
|
|
|
<p><strong>Type:</strong> {selectedRequest.type}</p>
|
|
|
|
|
<p><strong>Artist:</strong> {selectedRequest.artist}</p>
|
|
|
|
|
{selectedRequest.album && <p><strong>Album:</strong> {selectedRequest.album}</p>}
|
|
|
|
|
{selectedRequest.track && <p><strong>Track:</strong> {selectedRequest.track}</p>}
|
2025-08-01 15:29:27 -04:00
|
|
|
<p className="text-sm flex items-center gap-2">
|
|
|
|
|
<span className="font-semibold">Status:</span>
|
|
|
|
|
<span
|
|
|
|
|
className={`px-2 py-0.5 rounded-full text-xs font-bold ${selectedRequest.status === "Pending"
|
|
|
|
|
? "bg-yellow-100 text-yellow-800 dark:bg-yellow-800 dark:text-yellow-100"
|
|
|
|
|
: selectedRequest.status === "Completed"
|
|
|
|
|
? "bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100"
|
|
|
|
|
: "bg-red-100 text-red-800 dark:bg-red-800 dark:text-red-100"
|
|
|
|
|
}`}
|
|
|
|
|
>
|
|
|
|
|
{selectedRequest.status}
|
|
|
|
|
</span>
|
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
2025-08-01 15:17:25 -04:00
|
|
|
{selectedRequest.details && (
|
|
|
|
|
<>
|
|
|
|
|
<p><strong>Requested By:</strong> {selectedRequest.details.requestedBy}</p>
|
|
|
|
|
<p><strong>Timestamp:</strong> {new Date(selectedRequest.details.timestamp).toLocaleString()}</p>
|
|
|
|
|
{selectedRequest.details.comments && (
|
|
|
|
|
<p><strong>Comments:</strong> {selectedRequest.details.comments}</p>
|
|
|
|
|
)}
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</Dialog>
|
|
|
|
|
|
|
|
|
|
|
2025-07-31 19:28:59 -04:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|