feat: add license page for admin

This commit is contained in:
hanif salafi 2025-12-21 23:30:19 +07:00
parent 6fe7dffe47
commit 23ec7834b3
6 changed files with 336 additions and 0 deletions

View File

@ -0,0 +1,255 @@
"use client";
import * as React from "react";
import {
ColumnDef,
flexRender,
getCoreRowModel,
useReactTable,
} from "@tanstack/react-table";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { useTranslations } from "next-intl";
import { Icon } from "@iconify/react";
interface LicenseComponent {
id: string;
serialNumber: string;
licensor: string;
product: string;
customer: string;
capacity: string;
}
const LicenseTable = () => {
const t = useTranslations("Menu");
const [licenseData, setLicenseData] = React.useState<LicenseComponent[]>([]);
React.useEffect(() => {
// Static license data from XML file
const licenseComponents: LicenseComponent[] = [
{
id: "1",
serialNumber: "IDC-ML-134360021025",
licensor: "SmartFace Tech Private Limited",
product: "Intelligent Digital Content",
customer: "HUMAS POLRI Indonesia",
capacity: "Unlimited"
},
{
id: "2",
serialNumber: "ANV-ML-90370021025",
licensor: "SmartFace Tech Private Limited",
product: "Analytics and Visualization",
customer: "HUMAS POLRI Indonesia",
capacity: "Unlimited"
},
{
id: "3",
serialNumber: "CORA-L1.1-134400021025",
licensor: "SmartFace Tech Private Limited",
product: "Content Curation",
customer: "HUMAS POLRI Indonesia",
capacity: "Unlimited"
},
{
id: "4",
serialNumber: "TEMA-ML-134500021025",
licensor: "SmartFace Tech Private Limited",
product: "Content Management",
customer: "HUMAS POLRI Indonesia",
capacity: "Unlimited"
},
{
id: "5",
serialNumber: "ERI-L1.1-134900021025",
licensor: "SmartFace Tech Private Limited",
product: "Emergency Issue",
customer: "HUMAS POLRI Indonesia",
capacity: "Unlimited"
},
{
id: "6",
serialNumber: "FEC-L1.1-134800021025",
licensor: "SmartFace Tech Private Limited",
product: "Feedback Center",
customer: "HUMAS POLRI Indonesia",
capacity: "Unlimited"
},
{
id: "7",
serialNumber: "OPTIC-L.1.1-134600021025",
licensor: "SmartFace Tech Private Limited",
product: "Optimization Content",
customer: "HUMAS POLRI Indonesia",
capacity: "Unlimited"
},
{
id: "8",
serialNumber: "PREC-L1.1-134700021025",
licensor: "SmartFace Tech Private Limited",
product: "Press Conference",
customer: "HUMAS POLRI Indonesia",
capacity: "Unlimited"
}
];
setLicenseData(licenseComponents);
}, []);
const columns: ColumnDef<LicenseComponent>[] = [
{
accessorKey: "id",
header: "No",
cell: ({ row }) => (
<div className="font-medium">{row.getValue("id")}</div>
),
},
{
accessorKey: "product",
header: "Product",
cell: ({ row }) => (
<div className="font-medium">{row.getValue("product")}</div>
),
},
{
accessorKey: "serialNumber",
header: "Serial Number",
cell: ({ row }) => (
<div className="font-mono text-sm">{row.getValue("serialNumber")}</div>
),
},
{
accessorKey: "licensor",
header: "Licensor",
cell: ({ row }) => <div>{row.getValue("licensor")}</div>,
},
{
accessorKey: "customer",
header: "Customer",
cell: ({ row }) => <div>{row.getValue("customer")}</div>,
},
{
accessorKey: "capacity",
header: "Capacity",
cell: ({ row }) => (
<div className="flex items-center gap-2">
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
{row.getValue("capacity")}
</span>
</div>
),
},
];
const table = useReactTable({
data: licenseData,
columns,
getCoreRowModel: getCoreRowModel(),
});
return (
<Card>
<CardHeader>
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<Icon icon="heroicons:key" className="w-6 h-6 text-primary" />
<CardTitle>{t("license")} Information</CardTitle>
</div>
</div>
<p className="text-sm text-muted-foreground mt-2">
License details for SmartFace Tech products - Valid start from 2025
</p>
</CardHeader>
<CardContent>
<div className="rounded-md border">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<TableHead key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</TableHead>
))}
</TableRow>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}
data-state={row.getIsSelected() && "selected"}
>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
</TableCell>
))}
</TableRow>
))
) : (
<TableRow>
<TableCell
colSpan={columns.length}
className="h-24 text-center"
>
No license data available.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
{licenseData.length > 0 && (
<div className="mt-4 p-4 bg-muted/50 rounded-lg">
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div className="flex items-center gap-2">
<Icon icon="heroicons:building-office" className="w-5 h-5 text-primary" />
<div>
<p className="text-sm font-medium">Customer</p>
<p className="text-sm text-muted-foreground">{licenseData[0]?.customer}</p>
</div>
</div>
<div className="flex items-center gap-2">
<Icon icon="heroicons:building-library" className="w-5 h-5 text-primary" />
<div>
<p className="text-sm font-medium">Licensor</p>
<p className="text-sm text-muted-foreground">{licenseData[0]?.licensor}</p>
</div>
</div>
<div className="flex items-center gap-2">
<Icon icon="heroicons:cube" className="w-5 h-5 text-primary" />
<div>
<p className="text-sm font-medium">Total Components</p>
<p className="text-sm text-muted-foreground">{licenseData.length} Products Licensed</p>
</div>
</div>
</div>
</div>
)}
</CardContent>
</Card>
);
};
export default LicenseTable;

View File

@ -0,0 +1,13 @@
"use client";
import SiteBreadcrumb from "@/components/site-breadcrumb";
import LicenseTable from "./component/table";
export default function LicensePage() {
return (
<>
<SiteBreadcrumb />
<LicenseTable />
</>
);
}

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="US-ASCII"?>
<SmartFace_License>
<Component Id="1">
<SerialNumber>IDC-ML-134360021025</SerialNumber>
<Licensor>SmartFace Tech Private Limited</Licensor>
<Product>Intelligent Digital Content</Product>
<Customer>HUMAS POLRI Indonesia</Customer>
<Capacity>Unlimited</Capacity>
</Component>
<Component Id="2">
<SerialNumber>ANV-ML-90370021025</SerialNumber>
<Licensor>SmartFace Tech Private Limited</Licensor>
<Product>Analytics and Visualization</Product>
<Customer>HUMAS POLRI Indonesia</Customer>
<Capacity>Unlimited</Capacity>
</Component>
<Component Id="3">
<SerialNumber>CORA-L1.1-134400021025</SerialNumber>
<Licensor>SmartFace Tech Private Limited</Licensor>
<Product>Content Curation</Product>
<Customer>HUMAS POLRI Indonesia</Customer>
<Capacity>Unlimited</Capacity>
</Component>
<Component Id="4">
<SerialNumber>TEMA-ML-134500021025</SerialNumber>
<Licensor>SmartFace Tech Private Limited</Licensor>
<Product>Content Management</Product>
<Customer>HUMAS POLRI Indonesia</Customer>
<Capacity>Unlimited</Capacity>
</Component>
<Component Id="5">
<SerialNumber>ERI-L1.1-134900021025</SerialNumber>
<Licensor>SmartFace Tech Private Limited</Licensor>
<Product>Emergency Issue</Product>
<Customer>HUMAS POLRI Indonesia</Customer>
<Capacity>Unlimited</Capacity>
</Component>
<Component Id="6">
<SerialNumber>FEC-L1.1-134800021025</SerialNumber>
<Licensor>SmartFace Tech Private Limited</Licensor>
<Product>Feedback Center</Product>
<Customer>HUMAS POLRI Indonesia</Customer>
<Capacity>Unlimited</Capacity>
</Component>
<Component Id="7">
<SerialNumber>OPTIC-L.1.1-134600021025</SerialNumber>
<Licensor>SmartFace Tech Private Limited</Licensor>
<Product>Optimization Content</Product>
<Customer>HUMAS POLRI Indonesia</Customer>
<Capacity>Unlimited</Capacity>
</Component>
<Component Id="8">
<SerialNumber>PREC-L1.1-134700021025</SerialNumber>
<Licensor>SmartFace Tech Private Limited</Licensor>
<Product>Press Conference</Product>
<Customer>HUMAS POLRI Indonesia</Customer>
<Capacity>Unlimited</Capacity>
</Component>
</SmartFace_License>

View File

@ -3888,6 +3888,13 @@ export function getMenuList(pathname: string, t: any): Group[] {
icon: "heroicons:arrow-trending-up",
children: [],
},
{
href: "/admin/settings/license",
label: t("license"),
active: pathname === "/admin/settings/license",
icon: "heroicons:key",
children: [],
},
// {
// href: "/admin/settings/tag",
// label: "Tag",

View File

@ -178,6 +178,7 @@
"collaboration": "Collaboration",
"account-report": "Account Report",
"settings": "Settings",
"license": "License",
"feedback": "Feedback",
"survey": "Survey",
"content-production": "Content Production",

View File

@ -179,6 +179,7 @@
"collaboration": "Kolaborasi",
"account-report": "Pelaporan Akun",
"settings": "Pengaturan",
"license": "Lisensi",
"feedback": "Feedback",
"survey": "Survey",
"content-production": "Produksi Konten",