feat:table:schedule and fix table

This commit is contained in:
Anang Yusman 2024-12-09 02:24:14 +07:00
commit 8bbe1a1fff
100 changed files with 4700 additions and 563 deletions

View File

@ -3,7 +3,7 @@ import { Card, CardContent } from "@/components/ui/card";
import MediahubTable from "../planning/mediahub/table-mediahub/mediahub-table";
import { Button } from "@/components/ui/button";
import { UploadIcon } from "lucide-react";
import BlogTable from "./table-blog/blog-table";
import BlogTable from "./table/blog-table";
const BlogPage = async () => {
return (

View File

@ -285,40 +285,46 @@ const BlogTable = () => {
)}
</TableBody>
</Table>
<div className="flex items-center justify-center py-4 gap-2 flex-none">
<Button
variant="outline"
size="icon"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
className="w-8 h-8"
>
<ChevronLeft className="w-4 h-4" />
</Button>
{table.getPageOptions().map((page, pageIndex) => (
<div className="flex items-center justify-end py-4 px-10">
<div className="flex-1 text-sm text-muted-foreground">
{table.getFilteredSelectedRowModel().rows.length} of{" "}
{table.getFilteredRowModel().rows.length} row(s) selected.
</div>
<div className="flex items-center justify-center py-4 gap-2 flex-none">
<Button
key={`basic-data-table-${pageIndex}`}
onClick={() => table.setPageIndex(pageIndex)}
variant="outline"
size="icon"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
className="w-8 h-8"
variant={
table.getState().pagination.pageIndex === pageIndex
? "default"
: "outline"
}
>
{page + 1}
<ChevronLeft className="w-4 h-4" />
</Button>
))}
<Button
variant="outline"
size="icon"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
className="w-8 h-8"
>
<ChevronRight className="w-4 h-4" />
</Button>
{table.getPageOptions().map((page, pageIndex) => (
<Button
key={`basic-data-table-${pageIndex}`}
onClick={() => table.setPageIndex(pageIndex)}
size="icon"
className="w-8 h-8"
variant={
table.getState().pagination.pageIndex === pageIndex
? "default"
: "outline"
}
>
{page + 1}
</Button>
))}
<Button
variant="outline"
size="icon"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
className="w-8 h-8"
>
<ChevronRight className="w-4 h-4" />
</Button>
</div>
</div>
</div>
);

View File

@ -0,0 +1,84 @@
import { Button } from '@/components/ui/button';
import { Table } from '@tanstack/react-table';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import { useSearchParams } from 'next/navigation';
import { useRouter } from 'next/navigation';
import React from 'react';
interface DataTablePaginationProps {
table: Table<any>;
totalPage: number; // Total jumlah halaman
totalData: number; // Total jumlah data
visiblePageCount?: number; // Jumlah halaman yang ditampilkan (default 5)
}
const TablePagination = ({ table, totalPage, totalData, visiblePageCount = 5 }: DataTablePaginationProps) => {
const router = useRouter();
const searchParams = useSearchParams();
const [currentPageIndex, setCurrentPageIndex] = React.useState<number>(1);
React.useEffect(() => {
const pageFromUrl = searchParams?.get('page');
if (pageFromUrl) {
setCurrentPageIndex(Number(pageFromUrl));
}
}, [searchParams]);
// Hitung startPage dan endPage, disesuaikan untuk dimulai dari 1
const startPage = Math.max(1, currentPageIndex - Math.floor(visiblePageCount / 2));
const endPage = Math.min(totalPage, startPage + visiblePageCount - 1);
const handlePageChange = (pageIndex: number) => {
// Perbarui query parameter di URL
const searchParams = new URLSearchParams(window.location.search);
searchParams.set('page', (pageIndex).toString()); // Menyimpan halaman sebagai 1-based index
router.push(`${window.location.pathname}?${searchParams.toString()}`);
// Pindahkan halaman di tabel
table.setPageIndex(pageIndex);
setCurrentPageIndex(pageIndex + 1); // Update state untuk halaman saat ini
};
return (
<div className="flex items-center justify-end py-4 px-10">
<div className="flex-1 text-sm text-muted-foreground">
{table.getFilteredSelectedRowModel().rows.length} of{" "}
{totalData} row(s) selected.
</div>
<div className="flex items-center gap-2 flex-none">
<Button
variant="outline"
size="icon"
onClick={() => handlePageChange(1)}
disabled={currentPageIndex === 1}
className='w-8 h-8'
>
<ChevronLeft className='w-4 h-4' />
</Button>
{Array.from({ length: endPage - startPage + 1 }, (_, index) => startPage + index).map((pageIndex) => (
<Button
key={`page-${pageIndex}`}
onClick={() => handlePageChange(pageIndex)}
size="icon"
className="w-8 h-8"
variant={currentPageIndex === pageIndex ? 'default' : 'outline'}
>
{pageIndex}
</Button>
))}
<Button
variant="outline"
size="icon"
onClick={() => handlePageChange(totalPage)}
disabled={currentPageIndex === totalPage}
className='w-8 h-8'
>
<ChevronRight className='w-4 h-4' />
</Button>
</div>
</div>
);
};
export default TablePagination;

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Blog",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,36 @@
import SiteBreadcrumb from "@/components/site-breadcrumb";
import { Card, CardContent } from "@/components/ui/card";
import MediahubTable from "../planning/mediahub/table-mediahub/mediahub-table";
import { Button } from "@/components/ui/button";
import { UploadIcon } from "lucide-react";
import BlogTable from "./table/blog-table";
const BlogPage = async () => {
return (
<div>
<SiteBreadcrumb />
<div className="space-y-4">
<Card className="py-4 px-3">
<div className="flex flex-row justify-between items-center">
<div className="flex-1 text-xl font-medium text-default-900">
Table Indeks
</div>
<div>
<Button color="primary" className="text-white">
<UploadIcon />
Tambah Indeks
</Button>
</div>
</div>
</Card>
<Card>
<CardContent className="p-0">
<BlogTable />
</CardContent>
</Card>
</div>
</div>
);
};
export default BlogPage;

View File

@ -0,0 +1,333 @@
"use client";
import * as React from "react";
import {
ColumnDef,
ColumnFiltersState,
PaginationState,
SortingState,
VisibilityState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table";
import { Button } from "@/components/ui/button";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
Badge,
ChevronLeft,
ChevronRight,
Eye,
MoreVertical,
Search,
SquarePen,
Trash2,
TrendingDown,
TrendingUp,
} from "lucide-react";
import { cn } from "@/lib/utils";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
export type CompanyData = {
no: number;
title: string;
category: string;
createdAt: string;
tags: string;
statusName: string;
};
import { data } from "./data";
import { Input } from "@/components/ui/input";
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
import { paginationBlog } from "@/service/blog/blog";
export const columns: ColumnDef<CompanyData>[] = [
{
accessorKey: "no",
header: "No",
cell: ({ row }) => (
<div className="flex items-center gap-5">
<div className="flex-1 text-start">
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
{row.getValue("no")}
</h4>
</div>
</div>
),
},
{
accessorKey: "title",
header: "Judul",
cell: ({ row }) => (
<div className="flex items-center gap-5">
<div className="flex-1 text-start">
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
{row.getValue("title")}
</h4>
</div>
</div>
),
},
{
accessorKey: "categoryName",
header: "Kategori ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("categoryName")}</span>
),
},
{
accessorKey: "createdAt",
header: "Tanggal Unggah ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("createdAt")}</span>
),
},
{
accessorKey: "tags",
header: "Tag ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("tags")}</span>
),
},
{
accessorKey: "statusName",
header: "Status",
cell: ({ row }) => {
return (
<span className="whitespace-nowrap text-blue-600">
{row.getValue("statusName")}
</span>
);
},
},
{
id: "actions",
accessorKey: "action",
header: "Actions",
enableHiding: false,
cell: ({ row }) => {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
size="icon"
className="bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent"
>
<span className="sr-only">Open menu</span>
<MoreVertical className="h-4 w-4 text-default-800" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="p-0" align="end">
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<Eye className="w-4 h-4 me-1.5" />
View
</DropdownMenuItem>
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<SquarePen className="w-4 h-4 me-1.5" />
Edit
</DropdownMenuItem>
<DropdownMenuItem className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none">
<Trash2 className="w-4 h-4 me-1.5" />
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
},
},
];
const BlogTable = () => {
const [blogTable, setBlogTable] = React.useState<CompanyData[]>([]);
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
);
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({});
const [rowSelection, setRowSelection] = React.useState({});
const [pagination, setPagination] = React.useState<PaginationState>({
pageIndex: 0,
pageSize: 10,
});
const [page, setPage] = React.useState(1);
const [totalPage, setTotalPage] = React.useState(1);
const [limit, setLimit] = React.useState(10);
const table = useReactTable({
data: blogTable,
columns,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
onPaginationChange: setPagination,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
pagination,
},
});
React.useEffect(() => {
initState();
}, [page, limit]);
async function initState() {
try {
const res = await paginationBlog(limit, page);
const data = res.data.data.content.map((item: any, index: number) => ({
no: (page - 1) * limit + index + 1,
title: item.title,
categoryName: item.categoryName,
tags: item.tags,
assignmentType: item.assignmentType?.name || "-",
createdAt: item.createdAt,
statusName: item.statusName,
}));
setBlogTable(data);
setTotalPage(res.data.totalPages);
} catch (error) {
console.error("Error fetching tasks:", error);
}
}
return (
<div className="w-full overflow-x-auto">
<div className="flex justify-between items-center py-4 px-5">
<div>
<InputGroup merged>
<InputGroupText className="bg-transparent dark:border-secondary dark:group-focus-within:border-secondary">
<Search className=" h-4 w-4 dark:text-white" />
</InputGroupText>
<Input
type="text"
placeholder="Search Judul..."
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white"
/>
</InputGroup>
</div>
<div className="flex-none">
<Input
placeholder="Filter Status..."
value={
(table.getColumn("status")?.getFilterValue() as string) ?? ""
}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
table.getColumn("status")?.setFilterValue(event.target.value)
}
className="max-w-sm "
/>
</div>
</div>
<Table className="overflow-hidden">
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id} className="bg-default-200">
{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"}
className="h-[75px]"
>
{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 results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
<div className="flex items-center justify-end py-4 px-10">
<div className="flex-1 text-sm text-muted-foreground">
{table.getFilteredSelectedRowModel().rows.length} of{" "}
{table.getFilteredRowModel().rows.length} row(s) selected.
</div>
<div className="flex items-center justify-center py-4 gap-2 flex-none">
<Button
variant="outline"
size="icon"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
className="w-8 h-8"
>
<ChevronLeft className="w-4 h-4" />
</Button>
{table.getPageOptions().map((page, pageIndex) => (
<Button
key={`basic-data-table-${pageIndex}`}
onClick={() => table.setPageIndex(pageIndex)}
size="icon"
className="w-8 h-8"
variant={
table.getState().pagination.pageIndex === pageIndex
? "default"
: "outline"
}
>
{page + 1}
</Button>
))}
<Button
variant="outline"
size="icon"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
className="w-8 h-8"
>
<ChevronRight className="w-4 h-4" />
</Button>
</div>
</div>
</div>
);
};
export default BlogTable;

View File

@ -0,0 +1,65 @@
export const data = [
{
title: "Ops Mantap Praja & Pilkada 2024",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
status: "Terkirim",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Ops Mantap Praja & Pilkada 2024",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Ops Mantap Praja & Pilkada 2024",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
];

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Blog",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,36 @@
import SiteBreadcrumb from "@/components/site-breadcrumb";
import { Card, CardContent } from "@/components/ui/card";
import MediahubTable from "../planning/mediahub/table-mediahub/mediahub-table";
import { Button } from "@/components/ui/button";
import { UploadIcon } from "lucide-react";
import BlogTable from "./table/blog-table";
const BlogPage = async () => {
return (
<div>
<SiteBreadcrumb />
<div className="space-y-4">
<Card className="py-4 px-3">
<div className="flex flex-row justify-between items-center">
<div className="flex-1 text-xl font-medium text-default-900">
Table Indeks
</div>
<div>
<Button color="primary" className="text-white">
<UploadIcon />
Tambah Indeks
</Button>
</div>
</div>
</Card>
<Card>
<CardContent className="p-0">
<BlogTable />
</CardContent>
</Card>
</div>
</div>
);
};
export default BlogPage;

View File

@ -0,0 +1,333 @@
"use client";
import * as React from "react";
import {
ColumnDef,
ColumnFiltersState,
PaginationState,
SortingState,
VisibilityState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table";
import { Button } from "@/components/ui/button";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
Badge,
ChevronLeft,
ChevronRight,
Eye,
MoreVertical,
Search,
SquarePen,
Trash2,
TrendingDown,
TrendingUp,
} from "lucide-react";
import { cn } from "@/lib/utils";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
export type CompanyData = {
no: number;
title: string;
category: string;
createdAt: string;
tags: string;
statusName: string;
};
import { data } from "./data";
import { Input } from "@/components/ui/input";
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
import { paginationBlog } from "@/service/blog/blog";
export const columns: ColumnDef<CompanyData>[] = [
{
accessorKey: "no",
header: "No",
cell: ({ row }) => (
<div className="flex items-center gap-5">
<div className="flex-1 text-start">
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
{row.getValue("no")}
</h4>
</div>
</div>
),
},
{
accessorKey: "title",
header: "Judul",
cell: ({ row }) => (
<div className="flex items-center gap-5">
<div className="flex-1 text-start">
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
{row.getValue("title")}
</h4>
</div>
</div>
),
},
{
accessorKey: "categoryName",
header: "Kategori ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("categoryName")}</span>
),
},
{
accessorKey: "createdAt",
header: "Tanggal Unggah ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("createdAt")}</span>
),
},
{
accessorKey: "tags",
header: "Tag ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("tags")}</span>
),
},
{
accessorKey: "statusName",
header: "Status",
cell: ({ row }) => {
return (
<span className="whitespace-nowrap text-blue-600">
{row.getValue("statusName")}
</span>
);
},
},
{
id: "actions",
accessorKey: "action",
header: "Actions",
enableHiding: false,
cell: ({ row }) => {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
size="icon"
className="bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent"
>
<span className="sr-only">Open menu</span>
<MoreVertical className="h-4 w-4 text-default-800" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="p-0" align="end">
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<Eye className="w-4 h-4 me-1.5" />
View
</DropdownMenuItem>
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<SquarePen className="w-4 h-4 me-1.5" />
Edit
</DropdownMenuItem>
<DropdownMenuItem className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none">
<Trash2 className="w-4 h-4 me-1.5" />
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
},
},
];
const BlogTable = () => {
const [blogTable, setBlogTable] = React.useState<CompanyData[]>([]);
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
);
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({});
const [rowSelection, setRowSelection] = React.useState({});
const [pagination, setPagination] = React.useState<PaginationState>({
pageIndex: 0,
pageSize: 10,
});
const [page, setPage] = React.useState(1);
const [totalPage, setTotalPage] = React.useState(1);
const [limit, setLimit] = React.useState(10);
const table = useReactTable({
data: blogTable,
columns,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
onPaginationChange: setPagination,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
pagination,
},
});
React.useEffect(() => {
initState();
}, [page, limit]);
async function initState() {
try {
const res = await paginationBlog(limit, page);
const data = res.data.data.content.map((item: any, index: number) => ({
no: (page - 1) * limit + index + 1,
title: item.title,
categoryName: item.categoryName,
tags: item.tags,
assignmentType: item.assignmentType?.name || "-",
createdAt: item.createdAt,
statusName: item.statusName,
}));
setBlogTable(data);
setTotalPage(res.data.totalPages);
} catch (error) {
console.error("Error fetching tasks:", error);
}
}
return (
<div className="w-full overflow-x-auto">
<div className="flex justify-between items-center py-4 px-5">
<div>
<InputGroup merged>
<InputGroupText className="bg-transparent dark:border-secondary dark:group-focus-within:border-secondary">
<Search className=" h-4 w-4 dark:text-white" />
</InputGroupText>
<Input
type="text"
placeholder="Search Judul..."
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white"
/>
</InputGroup>
</div>
<div className="flex-none">
<Input
placeholder="Filter Status..."
value={
(table.getColumn("status")?.getFilterValue() as string) ?? ""
}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
table.getColumn("status")?.setFilterValue(event.target.value)
}
className="max-w-sm "
/>
</div>
</div>
<Table className="overflow-hidden">
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id} className="bg-default-200">
{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"}
className="h-[75px]"
>
{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 results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
<div className="flex items-center justify-end py-4 px-10">
<div className="flex-1 text-sm text-muted-foreground">
{table.getFilteredSelectedRowModel().rows.length} of{" "}
{table.getFilteredRowModel().rows.length} row(s) selected.
</div>
<div className="flex items-center justify-center py-4 gap-2 flex-none">
<Button
variant="outline"
size="icon"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
className="w-8 h-8"
>
<ChevronLeft className="w-4 h-4" />
</Button>
{table.getPageOptions().map((page, pageIndex) => (
<Button
key={`basic-data-table-${pageIndex}`}
onClick={() => table.setPageIndex(pageIndex)}
size="icon"
className="w-8 h-8"
variant={
table.getState().pagination.pageIndex === pageIndex
? "default"
: "outline"
}
>
{page + 1}
</Button>
))}
<Button
variant="outline"
size="icon"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
className="w-8 h-8"
>
<ChevronRight className="w-4 h-4" />
</Button>
</div>
</div>
</div>
);
};
export default BlogTable;

View File

@ -0,0 +1,65 @@
export const data = [
{
title: "Ops Mantap Praja & Pilkada 2024",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
status: "Terkirim",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Ops Mantap Praja & Pilkada 2024",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Ops Mantap Praja & Pilkada 2024",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
];

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Blog",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,36 @@
import SiteBreadcrumb from "@/components/site-breadcrumb";
import { Card, CardContent } from "@/components/ui/card";
import MediahubTable from "../planning/mediahub/table-mediahub/mediahub-table";
import { Button } from "@/components/ui/button";
import { UploadIcon } from "lucide-react";
import BlogTable from "./table/blog-table";
const BlogPage = async () => {
return (
<div>
<SiteBreadcrumb />
<div className="space-y-4">
<Card className="py-4 px-3">
<div className="flex flex-row justify-between items-center">
<div className="flex-1 text-xl font-medium text-default-900">
Table Indeks
</div>
<div>
<Button color="primary" className="text-white">
<UploadIcon />
Tambah Indeks
</Button>
</div>
</div>
</Card>
<Card>
<CardContent className="p-0">
<BlogTable />
</CardContent>
</Card>
</div>
</div>
);
};
export default BlogPage;

View File

@ -0,0 +1,333 @@
"use client";
import * as React from "react";
import {
ColumnDef,
ColumnFiltersState,
PaginationState,
SortingState,
VisibilityState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table";
import { Button } from "@/components/ui/button";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
Badge,
ChevronLeft,
ChevronRight,
Eye,
MoreVertical,
Search,
SquarePen,
Trash2,
TrendingDown,
TrendingUp,
} from "lucide-react";
import { cn } from "@/lib/utils";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
export type CompanyData = {
no: number;
title: string;
category: string;
createdAt: string;
tags: string;
statusName: string;
};
import { data } from "./data";
import { Input } from "@/components/ui/input";
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
import { paginationBlog } from "@/service/blog/blog";
export const columns: ColumnDef<CompanyData>[] = [
{
accessorKey: "no",
header: "No",
cell: ({ row }) => (
<div className="flex items-center gap-5">
<div className="flex-1 text-start">
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
{row.getValue("no")}
</h4>
</div>
</div>
),
},
{
accessorKey: "title",
header: "Judul",
cell: ({ row }) => (
<div className="flex items-center gap-5">
<div className="flex-1 text-start">
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
{row.getValue("title")}
</h4>
</div>
</div>
),
},
{
accessorKey: "categoryName",
header: "Kategori ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("categoryName")}</span>
),
},
{
accessorKey: "createdAt",
header: "Tanggal Unggah ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("createdAt")}</span>
),
},
{
accessorKey: "tags",
header: "Tag ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("tags")}</span>
),
},
{
accessorKey: "statusName",
header: "Status",
cell: ({ row }) => {
return (
<span className="whitespace-nowrap text-blue-600">
{row.getValue("statusName")}
</span>
);
},
},
{
id: "actions",
accessorKey: "action",
header: "Actions",
enableHiding: false,
cell: ({ row }) => {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
size="icon"
className="bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent"
>
<span className="sr-only">Open menu</span>
<MoreVertical className="h-4 w-4 text-default-800" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="p-0" align="end">
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<Eye className="w-4 h-4 me-1.5" />
View
</DropdownMenuItem>
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<SquarePen className="w-4 h-4 me-1.5" />
Edit
</DropdownMenuItem>
<DropdownMenuItem className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none">
<Trash2 className="w-4 h-4 me-1.5" />
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
},
},
];
const BlogTable = () => {
const [blogTable, setBlogTable] = React.useState<CompanyData[]>([]);
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
);
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({});
const [rowSelection, setRowSelection] = React.useState({});
const [pagination, setPagination] = React.useState<PaginationState>({
pageIndex: 0,
pageSize: 10,
});
const [page, setPage] = React.useState(1);
const [totalPage, setTotalPage] = React.useState(1);
const [limit, setLimit] = React.useState(10);
const table = useReactTable({
data: blogTable,
columns,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
onPaginationChange: setPagination,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
pagination,
},
});
React.useEffect(() => {
initState();
}, [page, limit]);
async function initState() {
try {
const res = await paginationBlog(limit, page);
const data = res.data.data.content.map((item: any, index: number) => ({
no: (page - 1) * limit + index + 1,
title: item.title,
categoryName: item.categoryName,
tags: item.tags,
assignmentType: item.assignmentType?.name || "-",
createdAt: item.createdAt,
statusName: item.statusName,
}));
setBlogTable(data);
setTotalPage(res.data.totalPages);
} catch (error) {
console.error("Error fetching tasks:", error);
}
}
return (
<div className="w-full overflow-x-auto">
<div className="flex justify-between items-center py-4 px-5">
<div>
<InputGroup merged>
<InputGroupText className="bg-transparent dark:border-secondary dark:group-focus-within:border-secondary">
<Search className=" h-4 w-4 dark:text-white" />
</InputGroupText>
<Input
type="text"
placeholder="Search Judul..."
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white"
/>
</InputGroup>
</div>
<div className="flex-none">
<Input
placeholder="Filter Status..."
value={
(table.getColumn("status")?.getFilterValue() as string) ?? ""
}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
table.getColumn("status")?.setFilterValue(event.target.value)
}
className="max-w-sm "
/>
</div>
</div>
<Table className="overflow-hidden">
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id} className="bg-default-200">
{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"}
className="h-[75px]"
>
{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 results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
<div className="flex items-center justify-end py-4 px-10">
<div className="flex-1 text-sm text-muted-foreground">
{table.getFilteredSelectedRowModel().rows.length} of{" "}
{table.getFilteredRowModel().rows.length} row(s) selected.
</div>
<div className="flex items-center justify-center py-4 gap-2 flex-none">
<Button
variant="outline"
size="icon"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
className="w-8 h-8"
>
<ChevronLeft className="w-4 h-4" />
</Button>
{table.getPageOptions().map((page, pageIndex) => (
<Button
key={`basic-data-table-${pageIndex}`}
onClick={() => table.setPageIndex(pageIndex)}
size="icon"
className="w-8 h-8"
variant={
table.getState().pagination.pageIndex === pageIndex
? "default"
: "outline"
}
>
{page + 1}
</Button>
))}
<Button
variant="outline"
size="icon"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
className="w-8 h-8"
>
<ChevronRight className="w-4 h-4" />
</Button>
</div>
</div>
</div>
);
};
export default BlogTable;

View File

@ -0,0 +1,65 @@
export const data = [
{
title: "Ops Mantap Praja & Pilkada 2024",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
status: "Terkirim",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Ops Mantap Praja & Pilkada 2024",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Ops Mantap Praja & Pilkada 2024",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
];

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Blog",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,36 @@
import SiteBreadcrumb from "@/components/site-breadcrumb";
import { Card, CardContent } from "@/components/ui/card";
import MediahubTable from "../planning/mediahub/table-mediahub/mediahub-table";
import { Button } from "@/components/ui/button";
import { UploadIcon } from "lucide-react";
import BlogTable from "./table/blog-table";
const BlogPage = async () => {
return (
<div>
<SiteBreadcrumb />
<div className="space-y-4">
<Card className="py-4 px-3">
<div className="flex flex-row justify-between items-center">
<div className="flex-1 text-xl font-medium text-default-900">
Table Indeks
</div>
<div>
<Button color="primary" className="text-white">
<UploadIcon />
Tambah Indeks
</Button>
</div>
</div>
</Card>
<Card>
<CardContent className="p-0">
<BlogTable />
</CardContent>
</Card>
</div>
</div>
);
};
export default BlogPage;

View File

@ -0,0 +1,333 @@
"use client";
import * as React from "react";
import {
ColumnDef,
ColumnFiltersState,
PaginationState,
SortingState,
VisibilityState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table";
import { Button } from "@/components/ui/button";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
Badge,
ChevronLeft,
ChevronRight,
Eye,
MoreVertical,
Search,
SquarePen,
Trash2,
TrendingDown,
TrendingUp,
} from "lucide-react";
import { cn } from "@/lib/utils";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
export type CompanyData = {
no: number;
title: string;
category: string;
createdAt: string;
tags: string;
statusName: string;
};
import { data } from "./data";
import { Input } from "@/components/ui/input";
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
import { paginationBlog } from "@/service/blog/blog";
export const columns: ColumnDef<CompanyData>[] = [
{
accessorKey: "no",
header: "No",
cell: ({ row }) => (
<div className="flex items-center gap-5">
<div className="flex-1 text-start">
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
{row.getValue("no")}
</h4>
</div>
</div>
),
},
{
accessorKey: "title",
header: "Judul",
cell: ({ row }) => (
<div className="flex items-center gap-5">
<div className="flex-1 text-start">
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
{row.getValue("title")}
</h4>
</div>
</div>
),
},
{
accessorKey: "categoryName",
header: "Kategori ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("categoryName")}</span>
),
},
{
accessorKey: "createdAt",
header: "Tanggal Unggah ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("createdAt")}</span>
),
},
{
accessorKey: "tags",
header: "Tag ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("tags")}</span>
),
},
{
accessorKey: "statusName",
header: "Status",
cell: ({ row }) => {
return (
<span className="whitespace-nowrap text-blue-600">
{row.getValue("statusName")}
</span>
);
},
},
{
id: "actions",
accessorKey: "action",
header: "Actions",
enableHiding: false,
cell: ({ row }) => {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
size="icon"
className="bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent"
>
<span className="sr-only">Open menu</span>
<MoreVertical className="h-4 w-4 text-default-800" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="p-0" align="end">
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<Eye className="w-4 h-4 me-1.5" />
View
</DropdownMenuItem>
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<SquarePen className="w-4 h-4 me-1.5" />
Edit
</DropdownMenuItem>
<DropdownMenuItem className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none">
<Trash2 className="w-4 h-4 me-1.5" />
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
},
},
];
const BlogTable = () => {
const [blogTable, setBlogTable] = React.useState<CompanyData[]>([]);
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
);
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({});
const [rowSelection, setRowSelection] = React.useState({});
const [pagination, setPagination] = React.useState<PaginationState>({
pageIndex: 0,
pageSize: 10,
});
const [page, setPage] = React.useState(1);
const [totalPage, setTotalPage] = React.useState(1);
const [limit, setLimit] = React.useState(10);
const table = useReactTable({
data: blogTable,
columns,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
onPaginationChange: setPagination,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
pagination,
},
});
React.useEffect(() => {
initState();
}, [page, limit]);
async function initState() {
try {
const res = await paginationBlog(limit, page);
const data = res.data.data.content.map((item: any, index: number) => ({
no: (page - 1) * limit + index + 1,
title: item.title,
categoryName: item.categoryName,
tags: item.tags,
assignmentType: item.assignmentType?.name || "-",
createdAt: item.createdAt,
statusName: item.statusName,
}));
setBlogTable(data);
setTotalPage(res.data.totalPages);
} catch (error) {
console.error("Error fetching tasks:", error);
}
}
return (
<div className="w-full overflow-x-auto">
<div className="flex justify-between items-center py-4 px-5">
<div>
<InputGroup merged>
<InputGroupText className="bg-transparent dark:border-secondary dark:group-focus-within:border-secondary">
<Search className=" h-4 w-4 dark:text-white" />
</InputGroupText>
<Input
type="text"
placeholder="Search Judul..."
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white"
/>
</InputGroup>
</div>
<div className="flex-none">
<Input
placeholder="Filter Status..."
value={
(table.getColumn("status")?.getFilterValue() as string) ?? ""
}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
table.getColumn("status")?.setFilterValue(event.target.value)
}
className="max-w-sm "
/>
</div>
</div>
<Table className="overflow-hidden">
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id} className="bg-default-200">
{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"}
className="h-[75px]"
>
{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 results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
<div className="flex items-center justify-end py-4 px-10">
<div className="flex-1 text-sm text-muted-foreground">
{table.getFilteredSelectedRowModel().rows.length} of{" "}
{table.getFilteredRowModel().rows.length} row(s) selected.
</div>
<div className="flex items-center justify-center py-4 gap-2 flex-none">
<Button
variant="outline"
size="icon"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
className="w-8 h-8"
>
<ChevronLeft className="w-4 h-4" />
</Button>
{table.getPageOptions().map((page, pageIndex) => (
<Button
key={`basic-data-table-${pageIndex}`}
onClick={() => table.setPageIndex(pageIndex)}
size="icon"
className="w-8 h-8"
variant={
table.getState().pagination.pageIndex === pageIndex
? "default"
: "outline"
}
>
{page + 1}
</Button>
))}
<Button
variant="outline"
size="icon"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
className="w-8 h-8"
>
<ChevronRight className="w-4 h-4" />
</Button>
</div>
</div>
</div>
);
};
export default BlogTable;

View File

@ -0,0 +1,65 @@
export const data = [
{
title: "Ops Mantap Praja & Pilkada 2024",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
status: "Terkirim",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Ops Mantap Praja & Pilkada 2024",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Ops Mantap Praja & Pilkada 2024",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
];

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Blog",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,36 @@
import SiteBreadcrumb from "@/components/site-breadcrumb";
import { Card, CardContent } from "@/components/ui/card";
import MediahubTable from "../planning/mediahub/table-mediahub/mediahub-table";
import { Button } from "@/components/ui/button";
import { UploadIcon } from "lucide-react";
import BlogTable from "./table/blog-table";
const BlogPage = async () => {
return (
<div>
<SiteBreadcrumb />
<div className="space-y-4">
<Card className="py-4 px-3">
<div className="flex flex-row justify-between items-center">
<div className="flex-1 text-xl font-medium text-default-900">
Table Indeks
</div>
<div>
<Button color="primary" className="text-white">
<UploadIcon />
Tambah Indeks
</Button>
</div>
</div>
</Card>
<Card>
<CardContent className="p-0">
<BlogTable />
</CardContent>
</Card>
</div>
</div>
);
};
export default BlogPage;

View File

@ -0,0 +1,333 @@
"use client";
import * as React from "react";
import {
ColumnDef,
ColumnFiltersState,
PaginationState,
SortingState,
VisibilityState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table";
import { Button } from "@/components/ui/button";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
Badge,
ChevronLeft,
ChevronRight,
Eye,
MoreVertical,
Search,
SquarePen,
Trash2,
TrendingDown,
TrendingUp,
} from "lucide-react";
import { cn } from "@/lib/utils";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
export type CompanyData = {
no: number;
title: string;
category: string;
createdAt: string;
tags: string;
statusName: string;
};
import { data } from "./data";
import { Input } from "@/components/ui/input";
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
import { paginationBlog } from "@/service/blog/blog";
export const columns: ColumnDef<CompanyData>[] = [
{
accessorKey: "no",
header: "No",
cell: ({ row }) => (
<div className="flex items-center gap-5">
<div className="flex-1 text-start">
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
{row.getValue("no")}
</h4>
</div>
</div>
),
},
{
accessorKey: "title",
header: "Judul",
cell: ({ row }) => (
<div className="flex items-center gap-5">
<div className="flex-1 text-start">
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
{row.getValue("title")}
</h4>
</div>
</div>
),
},
{
accessorKey: "categoryName",
header: "Kategori ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("categoryName")}</span>
),
},
{
accessorKey: "createdAt",
header: "Tanggal Unggah ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("createdAt")}</span>
),
},
{
accessorKey: "tags",
header: "Tag ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("tags")}</span>
),
},
{
accessorKey: "statusName",
header: "Status",
cell: ({ row }) => {
return (
<span className="whitespace-nowrap text-blue-600">
{row.getValue("statusName")}
</span>
);
},
},
{
id: "actions",
accessorKey: "action",
header: "Actions",
enableHiding: false,
cell: ({ row }) => {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
size="icon"
className="bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent"
>
<span className="sr-only">Open menu</span>
<MoreVertical className="h-4 w-4 text-default-800" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="p-0" align="end">
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<Eye className="w-4 h-4 me-1.5" />
View
</DropdownMenuItem>
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<SquarePen className="w-4 h-4 me-1.5" />
Edit
</DropdownMenuItem>
<DropdownMenuItem className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none">
<Trash2 className="w-4 h-4 me-1.5" />
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
},
},
];
const BlogTable = () => {
const [blogTable, setBlogTable] = React.useState<CompanyData[]>([]);
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
);
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({});
const [rowSelection, setRowSelection] = React.useState({});
const [pagination, setPagination] = React.useState<PaginationState>({
pageIndex: 0,
pageSize: 10,
});
const [page, setPage] = React.useState(1);
const [totalPage, setTotalPage] = React.useState(1);
const [limit, setLimit] = React.useState(10);
const table = useReactTable({
data: blogTable,
columns,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
onPaginationChange: setPagination,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
pagination,
},
});
React.useEffect(() => {
initState();
}, [page, limit]);
async function initState() {
try {
const res = await paginationBlog(limit, page);
const data = res.data.data.content.map((item: any, index: number) => ({
no: (page - 1) * limit + index + 1,
title: item.title,
categoryName: item.categoryName,
tags: item.tags,
assignmentType: item.assignmentType?.name || "-",
createdAt: item.createdAt,
statusName: item.statusName,
}));
setBlogTable(data);
setTotalPage(res.data.totalPages);
} catch (error) {
console.error("Error fetching tasks:", error);
}
}
return (
<div className="w-full overflow-x-auto">
<div className="flex justify-between items-center py-4 px-5">
<div>
<InputGroup merged>
<InputGroupText className="bg-transparent dark:border-secondary dark:group-focus-within:border-secondary">
<Search className=" h-4 w-4 dark:text-white" />
</InputGroupText>
<Input
type="text"
placeholder="Search Judul..."
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white"
/>
</InputGroup>
</div>
<div className="flex-none">
<Input
placeholder="Filter Status..."
value={
(table.getColumn("status")?.getFilterValue() as string) ?? ""
}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
table.getColumn("status")?.setFilterValue(event.target.value)
}
className="max-w-sm "
/>
</div>
</div>
<Table className="overflow-hidden">
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id} className="bg-default-200">
{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"}
className="h-[75px]"
>
{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 results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
<div className="flex items-center justify-end py-4 px-10">
<div className="flex-1 text-sm text-muted-foreground">
{table.getFilteredSelectedRowModel().rows.length} of{" "}
{table.getFilteredRowModel().rows.length} row(s) selected.
</div>
<div className="flex items-center justify-center py-4 gap-2 flex-none">
<Button
variant="outline"
size="icon"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
className="w-8 h-8"
>
<ChevronLeft className="w-4 h-4" />
</Button>
{table.getPageOptions().map((page, pageIndex) => (
<Button
key={`basic-data-table-${pageIndex}`}
onClick={() => table.setPageIndex(pageIndex)}
size="icon"
className="w-8 h-8"
variant={
table.getState().pagination.pageIndex === pageIndex
? "default"
: "outline"
}
>
{page + 1}
</Button>
))}
<Button
variant="outline"
size="icon"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
className="w-8 h-8"
>
<ChevronRight className="w-4 h-4" />
</Button>
</div>
</div>
</div>
);
};
export default BlogTable;

View File

@ -0,0 +1,65 @@
export const data = [
{
title: "Ops Mantap Praja & Pilkada 2024",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
status: "Terkirim",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Ops Mantap Praja & Pilkada 2024",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Ops Mantap Praja & Pilkada 2024",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
];

View File

@ -9,7 +9,7 @@ import RecentActivity from "./routine-task/recent-activity";
import CompanyTable from "./routine-task/routine-task-table";
import TaskTable from "../task/table-task/task-table";
import PressConferenceTable from "../schedule/press-release/table-persrilis/pressrilis-table";
import BlogTable from "../blog/table-blog/blog-table";
import BlogTable from "../blog/table/blog-table";
const DashboardPage = () => {
const t = useTranslations("AnalyticsDashboard");

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Blog",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,36 @@
import SiteBreadcrumb from "@/components/site-breadcrumb";
import { Card, CardContent } from "@/components/ui/card";
import MediahubTable from "../planning/mediahub/table-mediahub/mediahub-table";
import { Button } from "@/components/ui/button";
import { UploadIcon } from "lucide-react";
import BlogTable from "./table/blog-table";
const BlogPage = async () => {
return (
<div>
<SiteBreadcrumb />
<div className="space-y-4">
<Card className="py-4 px-3">
<div className="flex flex-row justify-between items-center">
<div className="flex-1 text-xl font-medium text-default-900">
Table Indeks
</div>
<div>
<Button color="primary" className="text-white">
<UploadIcon />
Tambah Indeks
</Button>
</div>
</div>
</Card>
<Card>
<CardContent className="p-0">
<BlogTable />
</CardContent>
</Card>
</div>
</div>
);
};
export default BlogPage;

View File

@ -0,0 +1,333 @@
"use client";
import * as React from "react";
import {
ColumnDef,
ColumnFiltersState,
PaginationState,
SortingState,
VisibilityState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table";
import { Button } from "@/components/ui/button";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
Badge,
ChevronLeft,
ChevronRight,
Eye,
MoreVertical,
Search,
SquarePen,
Trash2,
TrendingDown,
TrendingUp,
} from "lucide-react";
import { cn } from "@/lib/utils";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
export type CompanyData = {
no: number;
title: string;
category: string;
createdAt: string;
tags: string;
statusName: string;
};
import { data } from "./data";
import { Input } from "@/components/ui/input";
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
import { paginationBlog } from "@/service/blog/blog";
export const columns: ColumnDef<CompanyData>[] = [
{
accessorKey: "no",
header: "No",
cell: ({ row }) => (
<div className="flex items-center gap-5">
<div className="flex-1 text-start">
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
{row.getValue("no")}
</h4>
</div>
</div>
),
},
{
accessorKey: "title",
header: "Judul",
cell: ({ row }) => (
<div className="flex items-center gap-5">
<div className="flex-1 text-start">
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
{row.getValue("title")}
</h4>
</div>
</div>
),
},
{
accessorKey: "categoryName",
header: "Kategori ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("categoryName")}</span>
),
},
{
accessorKey: "createdAt",
header: "Tanggal Unggah ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("createdAt")}</span>
),
},
{
accessorKey: "tags",
header: "Tag ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("tags")}</span>
),
},
{
accessorKey: "statusName",
header: "Status",
cell: ({ row }) => {
return (
<span className="whitespace-nowrap text-blue-600">
{row.getValue("statusName")}
</span>
);
},
},
{
id: "actions",
accessorKey: "action",
header: "Actions",
enableHiding: false,
cell: ({ row }) => {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
size="icon"
className="bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent"
>
<span className="sr-only">Open menu</span>
<MoreVertical className="h-4 w-4 text-default-800" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="p-0" align="end">
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<Eye className="w-4 h-4 me-1.5" />
View
</DropdownMenuItem>
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<SquarePen className="w-4 h-4 me-1.5" />
Edit
</DropdownMenuItem>
<DropdownMenuItem className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none">
<Trash2 className="w-4 h-4 me-1.5" />
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
},
},
];
const BlogTable = () => {
const [blogTable, setBlogTable] = React.useState<CompanyData[]>([]);
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
);
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({});
const [rowSelection, setRowSelection] = React.useState({});
const [pagination, setPagination] = React.useState<PaginationState>({
pageIndex: 0,
pageSize: 10,
});
const [page, setPage] = React.useState(1);
const [totalPage, setTotalPage] = React.useState(1);
const [limit, setLimit] = React.useState(10);
const table = useReactTable({
data: blogTable,
columns,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
onPaginationChange: setPagination,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
pagination,
},
});
React.useEffect(() => {
initState();
}, [page, limit]);
async function initState() {
try {
const res = await paginationBlog(limit, page);
const data = res.data.data.content.map((item: any, index: number) => ({
no: (page - 1) * limit + index + 1,
title: item.title,
categoryName: item.categoryName,
tags: item.tags,
assignmentType: item.assignmentType?.name || "-",
createdAt: item.createdAt,
statusName: item.statusName,
}));
setBlogTable(data);
setTotalPage(res.data.totalPages);
} catch (error) {
console.error("Error fetching tasks:", error);
}
}
return (
<div className="w-full overflow-x-auto">
<div className="flex justify-between items-center py-4 px-5">
<div>
<InputGroup merged>
<InputGroupText className="bg-transparent dark:border-secondary dark:group-focus-within:border-secondary">
<Search className=" h-4 w-4 dark:text-white" />
</InputGroupText>
<Input
type="text"
placeholder="Search Judul..."
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white"
/>
</InputGroup>
</div>
<div className="flex-none">
<Input
placeholder="Filter Status..."
value={
(table.getColumn("status")?.getFilterValue() as string) ?? ""
}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
table.getColumn("status")?.setFilterValue(event.target.value)
}
className="max-w-sm "
/>
</div>
</div>
<Table className="overflow-hidden">
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id} className="bg-default-200">
{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"}
className="h-[75px]"
>
{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 results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
<div className="flex items-center justify-end py-4 px-10">
<div className="flex-1 text-sm text-muted-foreground">
{table.getFilteredSelectedRowModel().rows.length} of{" "}
{table.getFilteredRowModel().rows.length} row(s) selected.
</div>
<div className="flex items-center justify-center py-4 gap-2 flex-none">
<Button
variant="outline"
size="icon"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
className="w-8 h-8"
>
<ChevronLeft className="w-4 h-4" />
</Button>
{table.getPageOptions().map((page, pageIndex) => (
<Button
key={`basic-data-table-${pageIndex}`}
onClick={() => table.setPageIndex(pageIndex)}
size="icon"
className="w-8 h-8"
variant={
table.getState().pagination.pageIndex === pageIndex
? "default"
: "outline"
}
>
{page + 1}
</Button>
))}
<Button
variant="outline"
size="icon"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
className="w-8 h-8"
>
<ChevronRight className="w-4 h-4" />
</Button>
</div>
</div>
</div>
);
};
export default BlogTable;

View File

@ -0,0 +1,65 @@
export const data = [
{
title: "Ops Mantap Praja & Pilkada 2024",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
status: "Terkirim",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Ops Mantap Praja & Pilkada 2024",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Ops Mantap Praja & Pilkada 2024",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
];

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Blog",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,36 @@
import SiteBreadcrumb from "@/components/site-breadcrumb";
import { Card, CardContent } from "@/components/ui/card";
import MediahubTable from "../planning/mediahub/table-mediahub/mediahub-table";
import { Button } from "@/components/ui/button";
import { UploadIcon } from "lucide-react";
import BlogTable from "./table/blog-table";
const BlogPage = async () => {
return (
<div>
<SiteBreadcrumb />
<div className="space-y-4">
<Card className="py-4 px-3">
<div className="flex flex-row justify-between items-center">
<div className="flex-1 text-xl font-medium text-default-900">
Table Indeks
</div>
<div>
<Button color="primary" className="text-white">
<UploadIcon />
Tambah Indeks
</Button>
</div>
</div>
</Card>
<Card>
<CardContent className="p-0">
<BlogTable />
</CardContent>
</Card>
</div>
</div>
);
};
export default BlogPage;

View File

@ -0,0 +1,333 @@
"use client";
import * as React from "react";
import {
ColumnDef,
ColumnFiltersState,
PaginationState,
SortingState,
VisibilityState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table";
import { Button } from "@/components/ui/button";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
Badge,
ChevronLeft,
ChevronRight,
Eye,
MoreVertical,
Search,
SquarePen,
Trash2,
TrendingDown,
TrendingUp,
} from "lucide-react";
import { cn } from "@/lib/utils";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
export type CompanyData = {
no: number;
title: string;
category: string;
createdAt: string;
tags: string;
statusName: string;
};
import { data } from "./data";
import { Input } from "@/components/ui/input";
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
import { paginationBlog } from "@/service/blog/blog";
export const columns: ColumnDef<CompanyData>[] = [
{
accessorKey: "no",
header: "No",
cell: ({ row }) => (
<div className="flex items-center gap-5">
<div className="flex-1 text-start">
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
{row.getValue("no")}
</h4>
</div>
</div>
),
},
{
accessorKey: "title",
header: "Judul",
cell: ({ row }) => (
<div className="flex items-center gap-5">
<div className="flex-1 text-start">
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
{row.getValue("title")}
</h4>
</div>
</div>
),
},
{
accessorKey: "categoryName",
header: "Kategori ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("categoryName")}</span>
),
},
{
accessorKey: "createdAt",
header: "Tanggal Unggah ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("createdAt")}</span>
),
},
{
accessorKey: "tags",
header: "Tag ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("tags")}</span>
),
},
{
accessorKey: "statusName",
header: "Status",
cell: ({ row }) => {
return (
<span className="whitespace-nowrap text-blue-600">
{row.getValue("statusName")}
</span>
);
},
},
{
id: "actions",
accessorKey: "action",
header: "Actions",
enableHiding: false,
cell: ({ row }) => {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
size="icon"
className="bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent"
>
<span className="sr-only">Open menu</span>
<MoreVertical className="h-4 w-4 text-default-800" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="p-0" align="end">
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<Eye className="w-4 h-4 me-1.5" />
View
</DropdownMenuItem>
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<SquarePen className="w-4 h-4 me-1.5" />
Edit
</DropdownMenuItem>
<DropdownMenuItem className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none">
<Trash2 className="w-4 h-4 me-1.5" />
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
},
},
];
const BlogTable = () => {
const [blogTable, setBlogTable] = React.useState<CompanyData[]>([]);
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
);
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({});
const [rowSelection, setRowSelection] = React.useState({});
const [pagination, setPagination] = React.useState<PaginationState>({
pageIndex: 0,
pageSize: 10,
});
const [page, setPage] = React.useState(1);
const [totalPage, setTotalPage] = React.useState(1);
const [limit, setLimit] = React.useState(10);
const table = useReactTable({
data: blogTable,
columns,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
onPaginationChange: setPagination,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
pagination,
},
});
React.useEffect(() => {
initState();
}, [page, limit]);
async function initState() {
try {
const res = await paginationBlog(limit, page);
const data = res.data.data.content.map((item: any, index: number) => ({
no: (page - 1) * limit + index + 1,
title: item.title,
categoryName: item.categoryName,
tags: item.tags,
assignmentType: item.assignmentType?.name || "-",
createdAt: item.createdAt,
statusName: item.statusName,
}));
setBlogTable(data);
setTotalPage(res.data.totalPages);
} catch (error) {
console.error("Error fetching tasks:", error);
}
}
return (
<div className="w-full overflow-x-auto">
<div className="flex justify-between items-center py-4 px-5">
<div>
<InputGroup merged>
<InputGroupText className="bg-transparent dark:border-secondary dark:group-focus-within:border-secondary">
<Search className=" h-4 w-4 dark:text-white" />
</InputGroupText>
<Input
type="text"
placeholder="Search Judul..."
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white"
/>
</InputGroup>
</div>
<div className="flex-none">
<Input
placeholder="Filter Status..."
value={
(table.getColumn("status")?.getFilterValue() as string) ?? ""
}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
table.getColumn("status")?.setFilterValue(event.target.value)
}
className="max-w-sm "
/>
</div>
</div>
<Table className="overflow-hidden">
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id} className="bg-default-200">
{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"}
className="h-[75px]"
>
{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 results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
<div className="flex items-center justify-end py-4 px-10">
<div className="flex-1 text-sm text-muted-foreground">
{table.getFilteredSelectedRowModel().rows.length} of{" "}
{table.getFilteredRowModel().rows.length} row(s) selected.
</div>
<div className="flex items-center justify-center py-4 gap-2 flex-none">
<Button
variant="outline"
size="icon"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
className="w-8 h-8"
>
<ChevronLeft className="w-4 h-4" />
</Button>
{table.getPageOptions().map((page, pageIndex) => (
<Button
key={`basic-data-table-${pageIndex}`}
onClick={() => table.setPageIndex(pageIndex)}
size="icon"
className="w-8 h-8"
variant={
table.getState().pagination.pageIndex === pageIndex
? "default"
: "outline"
}
>
{page + 1}
</Button>
))}
<Button
variant="outline"
size="icon"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
className="w-8 h-8"
>
<ChevronRight className="w-4 h-4" />
</Button>
</div>
</div>
</div>
);
};
export default BlogTable;

View File

@ -0,0 +1,65 @@
export const data = [
{
title: "Ops Mantap Praja & Pilkada 2024",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
status: "Terkirim",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Ops Mantap Praja & Pilkada 2024",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Ops Mantap Praja & Pilkada 2024",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
];

View File

@ -0,0 +1,9 @@
export const metadata = {
title: "Ticketing",
};
const Layout = ({ children }: { children: React.ReactNode }) => {
return <>{children}</>;
};
export default Layout;

View File

@ -0,0 +1,29 @@
import SiteBreadcrumb from "@/components/site-breadcrumb";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { UploadIcon } from "lucide-react";
import TicketingTable from "./table/ticketing-table";
const TicketingPage = async () => {
return (
<div>
<SiteBreadcrumb />
<div className="space-y-4">
<Card className="py-4 px-3">
<div className="flex flex-row justify-between items-center">
<div className="flex-1 text-xl font-medium text-default-900">
Ticketing Table
</div>
</div>
</Card>
<Card>
<CardContent className="p-0">
<TicketingTable />
</CardContent>
</Card>
</div>
</div>
);
};
export default TicketingPage;

View File

@ -0,0 +1,65 @@
export const data = [
{
title: "Ops Mantap Praja & Pilkada 2024",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
status: "Terkirim",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Ops Mantap Praja & Pilkada 2024",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Ops Mantap Praja & Pilkada 2024",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
{
title: "Seputar Prestasi",
status: "Terkirim",
category: "Giat Pimpinan",
date: "15/10/2024 9:11",
tag: "percobaan",
},
];

View File

@ -0,0 +1,303 @@
"use client";
import * as React from "react";
import {
ColumnDef,
ColumnFiltersState,
PaginationState,
SortingState,
VisibilityState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table";
import { Button } from "@/components/ui/button";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import {
ChevronLeft,
ChevronRight,
Eye,
MoreVertical,
Search,
SquarePen,
Trash2,
TrendingDown,
TrendingUp,
} from "lucide-react";
import { cn } from "@/lib/utils";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { data } from "./data";
import { Input } from "@/components/ui/input";
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
import { paginationBlog } from "@/service/blog/blog";
import { ticketingPagination } from "@/service/ticketing/ticketing";
import { Badge } from "@/components/ui/badge";
import TablePagination from "../../blog/table/table-pagination";
import { useRouter, useSearchParams } from "next/navigation";
export const columns: ColumnDef<any>[] = [
{
accessorKey: "no",
header: "No",
cell: ({ row }) => <span>{row.getValue("no")}</span>,
},
{
accessorKey: "referenceNumber",
header: "Ticket Number",
cell: ({ row }) => <span>{row.getValue("referenceNumber")}</span>,
},
{
accessorKey: "title",
header: "Title",
cell: ({ row }) => <span>{row.getValue("title")}</span>,
},
{
accessorKey: "commentFromUserName",
header: "Sender",
cell: ({ row }) => <span>{row.getValue("commentFromUserName")}</span>,
},
{
accessorKey: "type",
header: "Channel",
cell: ({ row }) => {
const type = row.getValue("type") as { name: string };
return <span>{type?.name}</span>;
},
},
{
accessorKey: "createdBy",
header: "Operator",
cell: ({ row }) => {
const createdBy = row.getValue("createdBy") as { fullname: string };
return <span>{createdBy?.fullname}</span>;
},
},
{
accessorKey: "createdAt",
header: "Tanggal Unggah ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("createdAt")}</span>
),
},
{
accessorKey: "status",
header: "Status",
cell: ({ row }) => {
const statusColors: Record<string, string> = {
open: "bg-primary/20 text-primary",
close: "bg-success/20 text-success",
};
const status = row.getValue("status") as { id: number, name: string };;
const statusName = status?.name?.toLocaleLowerCase();
console.log(statusName);
const statusStyles = statusColors[statusName] || "default";
if (statusName) {
return (
<Badge
className={cn("rounded-full px-5",statusStyles)}
>{statusName} </Badge>
);
}
}
},
{
id: "actions",
accessorKey: "action",
header: "Actions",
enableHiding: false,
cell: ({ row }) => {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
size="icon"
className="bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent"
>
<span className="sr-only">Open menu</span>
<MoreVertical className="h-4 w-4 text-default-800" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="p-0" align="end">
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<Eye className="w-4 h-4 me-1.5" />
View
</DropdownMenuItem>
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<SquarePen className="w-4 h-4 me-1.5" />
Edit
</DropdownMenuItem>
<DropdownMenuItem className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none">
<Trash2 className="w-4 h-4 me-1.5" />
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
},
},
];
const TicketingTable = () => {
const router = useRouter();
const searchParams = useSearchParams();
const [ticketData, setTicketData] = React.useState<any[]>([]);
const [totalData, setTotalData] = React.useState<number>(1);
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
);
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({});
const [rowSelection, setRowSelection] = React.useState({});
const [pagination, setPagination] = React.useState<PaginationState>({
pageIndex: 0,
pageSize: 10,
});
const [page, setPage] = React.useState(1);
const [totalPage, setTotalPage] = React.useState(1);
const [limit, setLimit] = React.useState(10);
const table = useReactTable({
data: ticketData,
columns,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
onPaginationChange: setPagination,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
pagination,
},
});
React.useEffect(() => {
const pageFromUrl = searchParams?.get('page');
if (pageFromUrl) {
setPage(Number(pageFromUrl));
}
}, [searchParams]);
React.useEffect(() => {
fetchData();
}, [page, limit]);
async function fetchData() {
try {
const res = await ticketingPagination('', limit, page-1);
const data = res.data?.data;
const contentData = data?.content;
contentData.forEach((item: any, index: number) => {
item.no = (page - 1) * limit + index + 1;
});
console.log("contentData : ", contentData);
setTicketData(contentData);
setTotalData(data?.totalElements);
setTotalPage(data?.totalPages);
} catch (error) {
console.error("Error fetching tasks:", error);
}
}
return (
<div className="w-full overflow-x-auto">
<div className="flex justify-between items-center py-4 px-5">
<div>
<InputGroup merged>
<InputGroupText className="bg-transparent dark:border-secondary dark:group-focus-within:border-secondary">
<Search className=" h-4 w-4 dark:text-white" />
</InputGroupText>
<Input
type="text"
placeholder="Search Judul..."
className="bg-transparent dark:border-secondary dark:placeholder-white/80 dark:focus:border-secondary dark:text-white"
/>
</InputGroup>
</div>
<div className="flex-none">
<Input
placeholder="Filter Status..."
value={
(table.getColumn("status")?.getFilterValue() as string) ?? ""
}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
table.getColumn("status")?.setFilterValue(event.target.value)
}
className="max-w-sm "
/>
</div>
</div>
<Table className="overflow-hidden">
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id} className="bg-default-200">
{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"}
className="h-[75px]"
>
{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 results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
<TablePagination table={table} totalData={totalData} totalPage={totalPage} visiblePageCount={5} />
</div>
);
};
export default TicketingTable;

View File

@ -6,6 +6,8 @@ import { Textarea } from "@/components/ui/textarea";
import Link from "next/link";
import { useParams, usePathname, useRouter } from "next/navigation";
import React, { useState } from "react";
import { Icon } from "@iconify/react/dist/iconify.js";
import { textEllipsis } from "@/utils/globals";
const dummyImage = [
{ id: 1, thumbnail: "/assets/banner-sample.png" },
@ -17,7 +19,7 @@ const dummyImage = [
const dummyData = {
id: 12312,
title: "ahahah",
title: "TITLE",
createdBy: "Mabes",
createdAt: "21-21-2021",
time: "18:23",
@ -26,6 +28,27 @@ const dummyData = {
'<p>Polres Kobar - Polres Kotawaringin Barat (Kobar) memberikan bantuan sosial kepada warga yang berada di Daerah Aliran Sungai (DAS) Arut khususnya yang terdampak banjir, Sabtu (30/11/2024) pagi.</p><p>Kapolda Kalteng Irjen Pol Drs. Djoko Poerwanto melalui Kapolres Kobar AKBP Yusfandi Usman, S.I.K., M.I.K., menjelaskan bahwa pihaknya membagikan 200 paket sembako sebagai bentuk kepedulian kepada masyarakat.</p><p>"Saya bersama personel turun langsung membagikan bantuan berupa paket sembako yang diserahkan kepada masyarakat sekaligus monitoring ke lokasi pinggiran sungai yang mulai sebagain terdampak banjir akibat curah hujan tinggi,” ungkap Kapolres.</p><p>Lebih lanjut, orang nomor satu di Polres Kobar ini, mengungkapkan kegiatan tersebut dilakukan dalam rangka tanggap waspada dan antisipasi bencana banjir di wilayah Kabupaten Kobar.</p><p>“Kami minta masyarakat tetap waspada banjir menyikapi cuaca yang berubah-ubah saat ini, tidak menutup kemungkinan bertambahnya volume air sungai, jika diguyur hujan terus menerus,” jelasnya.</p>',
};
const dummyImageContent = [
{ id: 1, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
{ id: 2, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
{ id: 3, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
{ id: 4, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
{ id: 5, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
{ id: 6, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
{ id: 7, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
{ id: 8, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
{ id: 9, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
];
const dummyDescription = [
{ id: 1, title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", date: "28 November 2024", time: "11.15 WIB", duration: "00:24:55" },
{ id: 2, title: "Kapolres Lahat Himbau Cipta Kondisi Cooling System Pasca Pemungutan Suara Pilkada 2024", date: "28 November 2024", time: "11.15 WIB", duration: "00:24:55" },
{ id: 3, title: "17 Ton Pupuk Bersubsidi yang Akan Diselewengkan ke Banyuasin Berhasil Digagalkan", date: "28 November 2024", time: "11.15 WIB", duration: "00:24:55" },
{ id: 4, title: "Kapolda Sumsel Apelkan 1471 Personel Persiapan Pengamanan Pengawalan Tahan Pungut dan Hitung Suara", date: "28 November 2024", time: "11.15 WIB", duration: "00:24:55" },
{ id: 5, title: "Polrestabes Palembang Berhasil Mengungkap Kasus Penganiayaan Berat di Ilir Barat II", date: "28 November 2024", time: "11.15 WIB", duration: "00:24:55" },
{ id: 6, title: "Tahapan Pilkada di Sumsel Berlangsung Kondusif", date: "28 November 2024", time: "11.15 WIB", duration: "00:24:55" },
];
const DetailInfo = () => {
const [selectedSize, setSelectedSize] = useState<string>("L");
const [selectedTab, setSelectedTab] = useState("video");
@ -43,14 +66,14 @@ const DetailInfo = () => {
];
return (
<div className="min-h-screen p-4 md:p-8">
<div className="min-h-screen px-4 md:px-24 py-4">
{/* Container Utama */}
<div className="rounded-md overflow-hidden md:flex">
{/* Bagian Kiri */}
<div className="md:w-2/3">
<div className="md:w-3/4">
{/* Gambar Utama */}
<div className="relative">
<img src="https://mediahub.polri.go.id/api/media/categories/view-thumbnail?id=93&currentMilis=1732769540018" alt="Main" className="w-full" />
<img src="https://mediahub.polri.go.id/api/media/categories/view-thumbnail?id=93&currentMilis=1732769540018" alt="Main" className="w-full rounded-lg" />
<div className="absolute top-4 left-4"></div>
</div>
@ -61,14 +84,14 @@ const DetailInfo = () => {
key={index}
src="https://mediahub.polri.go.id/api/media/categories/view-thumbnail?id=93&currentMilis=1732769540018"
alt={`Thumbnail ${index + 1}`}
className="w-full h-16 object-cover rounded-md cursor-pointer hover:ring-2 hover:ring-red-600"
className="w-full h-fit object-cover rounded-md cursor-pointer hover:ring-2 hover:ring-red-600"
/>
))}
</div>
</div>
{/* Bagian Kanan */}
<div className="md:w-1/3 p-4 bg-gray-300 rounded-lg mx-4">
<div className="md:w-1/4 p-4 bg-gray-300 rounded-lg mx-4">
<div className="flex flex-col mb-3 items-center justify-center cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg" width="2.5em" height="2.5em" viewBox="0 0 24 24">
<path fill="black" d="m17 18l-5-2.18L7 18V5h10m0-2H7a2 2 0 0 0-2 2v16l7-3l7 3V5a2 2 0 0 0-2-2" />
@ -132,7 +155,7 @@ const DetailInfo = () => {
</div>
{/* Keterangan */}
<div className="md:w-2/3">
<div className="md:w-3/4">
<h1 className="flex flex-row font-bold text-2xl mx-5 my-8">{dummyData.title}</h1>
<div dangerouslySetInnerHTML={{ __html: dummyData.htmlDescription }} />
</div>
@ -145,24 +168,36 @@ const DetailInfo = () => {
</div>
{/* Konten Serupa */}
<div className="w-full">
<div className="space-x-5 flex flex-col p-4">
<div className="flex px-10 flex-col lg:flex-row gap-5 mb-4">
<h2 className="flex items-center text-sm lg:text-xl font-bold bg-[#bb3523] px-4 py-1 rounded-lg text-white">
<span className="text-black ">Konten </span> Serupa
<div className="px-4 lg:px-12 ">
<div className="flex flex-col p-4">
<div className="mx-auto w-full max-w-7xl justify-start flex px-5 flex-col lg:flex-row gap-5 mb-4">
<h2 className="flex items-center text-sm lg:text-xl w-fit font-bold bg-[#bb3523] px-4 py-1 rounded-lg text-white">
<span className="text-black ">Konten </span> Terbaru
</h2>
<Tabs value={selectedTab} onValueChange={setSelectedTab}>
<TabsList>
<TabsTrigger value="video" className="relative text-sm md:text-xl font-bold text-black dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary">
<TabsTrigger
value="video"
className="relative text-sm md:text-xl font-bold text-black dark:text-white dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary"
>
Audio Visual
</TabsTrigger>
<TabsTrigger value="audio" className="relative text-sm md:text-xl font-bold text-black dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary">
<TabsTrigger
value="audio"
className="relative text-sm md:text-xl font-bold text-black dark:text-white dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary"
>
Audio
</TabsTrigger>
<TabsTrigger value="image" className="relative text-sm md:text-xl font-bold text-black dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary">
<TabsTrigger
value="image"
className="relative text-sm md:text-xl font-bold text-black dark:text-white dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary"
>
Foto
</TabsTrigger>
<TabsTrigger value="teks" className="relative text-sm md:text-xl font-bold text-black dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary">
<TabsTrigger
value="teks"
className="relative text-sm md:text-xl font-bold text-black dark:text-white dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary"
>
Teks
</TabsTrigger>
</TabsList>
@ -170,15 +205,21 @@ const DetailInfo = () => {
</div>
<div className="px-10">
{selectedTab == "video" ? (
<Carousel>
<Carousel className="w-full max-w-7xl mx-auto">
<CarouselContent>
{dummyImage.map((image) => (
{dummyImageContent.map((image) => (
<CarouselItem key={image.id} className="md:basis-1/2 lg:basis-1/3">
<Card>
<CardContent className="flex items-center justify-center">
<img src={image.thumbnail} className="h-60 object-cover w-full cursor-pointer" />
</CardContent>
</Card>
<img src={image.thumbnail} className="h-60 object-cover w-full items-center justify-center cursor-pointer" />
<div className="flex flex-row items-center gap-2">
{image.date} {image.time} | <Icon icon="formkit:eye" width="15" height="15" /> 518{" "}
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 20 20">
<path
fill="#f00"
d="M7.707 10.293a1 1 0 1 0-1.414 1.414l3 3a1 1 0 0 0 1.414 0l3-3a1 1 0 0 0-1.414-1.414L11 11.586V6h5a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h5v5.586zM9 4a1 1 0 0 1 2 0v2H9z"
/>
</svg>{" "}
</div>
<div className="font-semibold w-fit">{image.title}</div>
</CarouselItem>
))}
</CarouselContent>
@ -188,13 +229,27 @@ const DetailInfo = () => {
) : selectedTab == "audio" ? (
<Carousel>
<CarouselContent>
{dummyImage.map((image) => (
<CarouselItem key={image.id} className="md:basis-1/2 lg:basis-1/3">
<Card>
<CardContent className="flex items-center justify-center">
<img src={image.thumbnail} className="h-60 object-cover w-full cursor-pointer" />
</CardContent>
</Card>
{dummyDescription.map((description) => (
<CarouselItem key={description.id} className="md:basis-1/2 lg:basis-1/3">
<div className="flex flex-row gap-6">
<a href="#" key={description.id} className="flex flex-col sm:flex-row items-center bg-white dark:bg-gray-800 cursor-pointer shadow-md rounded-lg p-4 gap-4 w-full">
<div className="flex items-center justify-center bg-red-500 text-white rounded-lg w-16 h-8 lg:h-16">
<svg width="32" height="34" viewBox="0 0 32 34" fill="null" xmlns="http://www.w3.org/2000/svg">
<path
d="M23.404 0.452014C23.7033 0.35857 24.0204 0.336816 24.3297 0.388509C24.639 0.440203 24.9318 0.563895 25.1845 0.749599C25.4371 0.935304 25.6426 1.17782 25.7843 1.45756C25.9259 1.73731 25.9998 2.04644 26 2.36001V14.414C25.3462 14.2296 24.6766 14.1064 24 14.046V8.36001L10 12.736V27C10 28.1264 9.6197 29.2197 8.92071 30.1029C8.22172 30.9861 7.24499 31.6075 6.14877 31.8663C5.05255 32.125 3.90107 32.0061 2.88089 31.5287C1.86071 31.0514 1.03159 30.2435 0.52787 29.2361C0.024152 28.2286 -0.124656 27.0806 0.105556 25.9781C0.335768 24.8755 0.931513 23.883 1.79627 23.1613C2.66102 22.4396 3.74413 22.031 4.87009 22.0017C5.99606 21.9724 7.09893 22.3242 8.00001 23V6.73601C7.99982 6.30956 8.13596 5.8942 8.38854 5.55059C8.64112 5.20698 8.99692 4.9531 9.40401 4.82601L23.404 0.452014ZM10 10.64L24 6.26601V2.36001L10 6.73601V10.64ZM5.00001 24C4.20436 24 3.44129 24.3161 2.87869 24.8787C2.31608 25.4413 2.00001 26.2044 2.00001 27C2.00001 27.7957 2.31608 28.5587 2.87869 29.1213C3.44129 29.6839 4.20436 30 5.00001 30C5.79566 30 6.55872 29.6839 7.12133 29.1213C7.68394 28.5587 8.00001 27.7957 8.00001 27C8.00001 26.2044 7.68394 25.4413 7.12133 24.8787C6.55872 24.3161 5.79566 24 5.00001 24ZM32 25C32 27.387 31.0518 29.6761 29.364 31.364C27.6761 33.0518 25.387 34 23 34C20.6131 34 18.3239 33.0518 16.636 31.364C14.9482 29.6761 14 27.387 14 25C14 22.6131 14.9482 20.3239 16.636 18.6361C18.3239 16.9482 20.6131 16 23 16C25.387 16 27.6761 16.9482 29.364 18.6361C31.0518 20.3239 32 22.6131 32 25ZM27.47 24.128L21.482 20.828C21.3298 20.7443 21.1583 20.7016 20.9846 20.7043C20.8108 20.707 20.6408 20.7549 20.4912 20.8433C20.3416 20.9317 20.2176 21.0576 20.1315 21.2086C20.0453 21.3595 20 21.5302 20 21.704V28.304C20 28.4778 20.0453 28.6486 20.1315 28.7995C20.2176 28.9504 20.3416 29.0763 20.4912 29.1647C20.6408 29.2531 20.8108 29.301 20.9846 29.3037C21.1583 29.3064 21.3298 29.2638 21.482 29.18L27.47 25.88C27.6268 25.7937 27.7575 25.6669 27.8486 25.5128C27.9397 25.3587 27.9877 25.183 27.9877 25.004C27.9877 24.825 27.9397 24.6493 27.8486 24.4952C27.7575 24.3412 27.6268 24.2143 27.47 24.128Z"
fill="white"
/>
</svg>
</div>
<div className="flex flex-col flex-1">
<div className="text-gray-500 dark:text-gray-400 flex flex-row text-sm">
{description.date} | <Icon icon="formkit:eye" width="15" height="15" /> 518
</div>
<div className="font-semibold text-gray-900 dark:text-white mt-1 text-sm">{textEllipsis(description.title, 50)}</div>
</div>
</a>
</div>
</CarouselItem>
))}
</CarouselContent>
@ -204,13 +259,19 @@ const DetailInfo = () => {
) : selectedTab == "image" ? (
<Carousel>
<CarouselContent>
{dummyImage.map((image) => (
{dummyImageContent.map((image) => (
<CarouselItem key={image.id} className="md:basis-1/2 lg:basis-1/3">
<Card onClick={() => router.push(`${locale}/image/detail/${image.id}`)}>
<CardContent className="flex items-center justify-center">
<img src={image.thumbnail} className="h-60 object-cover w-full cursor-pointer" />
</CardContent>
</Card>
<img src={image.thumbnail} className="h-60 object-cover w-full items-center justify-center cursor-pointer" />
<div className="flex flex-row items-center gap-2">
{image.date} {image.time} | <Icon icon="formkit:eye" width="15" height="15" /> 518{" "}
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 20 20">
<path
fill="#f00"
d="M7.707 10.293a1 1 0 1 0-1.414 1.414l3 3a1 1 0 0 0 1.414 0l3-3a1 1 0 0 0-1.414-1.414L11 11.586V6h5a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h5v5.586zM9 4a1 1 0 0 1 2 0v2H9z"
/>
</svg>{" "}
</div>
<div className="font-semibold w-fit">{image.title}</div>
</CarouselItem>
))}
</CarouselContent>
@ -220,13 +281,33 @@ const DetailInfo = () => {
) : (
<Carousel>
<CarouselContent>
{dummyImage.map((image) => (
<CarouselItem key={image.id} className="md:basis-1/2 lg:basis-1/3">
<Card>
<CardContent>
<img src={image.thumbnail} className="h-60 object-cover w-full cursor-pointer" />
</CardContent>
</Card>
{dummyImageContent.map((description) => (
<CarouselItem key={description.id} className="md:basis-1/2 lg:basis-1/3">
<div className="md:basis-1/2 lg:basis-1/3">
<a href="#" className="flex flex-col bg-yellow-500 sm:flex-row items-center dark:bg-gray-800 cursor-pointer shadow-md rounded-lg p-4 gap-4 w-full">
<div className="flex items-center justify-center rounded-lg w-16 h-2 lg:h-16">
<svg width="28" height="34" viewBox="0 0 28 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M5.6665 17.4167C5.6665 17.0851 5.7982 16.7672 6.03262 16.5328C6.26704 16.2984 6.58498 16.1667 6.9165 16.1667C7.24802 16.1667 7.56597 16.2984 7.80039 16.5328C8.03481 16.7672 8.1665 17.0851 8.1665 17.4167C8.1665 17.7482 8.03481 18.0661 7.80039 18.3005C7.56597 18.535 7.24802 18.6667 6.9165 18.6667C6.58498 18.6667 6.26704 18.535 6.03262 18.3005C5.7982 18.0661 5.6665 17.7482 5.6665 17.4167ZM6.9165 21.1667C6.58498 21.1667 6.26704 21.2984 6.03262 21.5328C5.7982 21.7672 5.6665 22.0851 5.6665 22.4167C5.6665 22.7482 5.7982 23.0661 6.03262 23.3005C6.26704 23.535 6.58498 23.6667 6.9165 23.6667C7.24802 23.6667 7.56597 23.535 7.80039 23.3005C8.03481 23.0661 8.1665 22.7482 8.1665 22.4167C8.1665 22.0851 8.03481 21.7672 7.80039 21.5328C7.56597 21.2984 7.24802 21.1667 6.9165 21.1667ZM5.6665 27.4167C5.6665 27.0851 5.7982 26.7672 6.03262 26.5328C6.26704 26.2984 6.58498 26.1667 6.9165 26.1667C7.24802 26.1667 7.56597 26.2984 7.80039 26.5328C8.03481 26.7672 8.1665 27.0851 8.1665 27.4167C8.1665 27.7482 8.03481 28.0661 7.80039 28.3005C7.56597 28.535 7.24802 28.6667 6.9165 28.6667C6.58498 28.6667 6.26704 28.535 6.03262 28.3005C5.7982 28.0661 5.6665 27.7482 5.6665 27.4167ZM11.9165 16.1667C11.585 16.1667 11.267 16.2984 11.0326 16.5328C10.7982 16.7672 10.6665 17.0851 10.6665 17.4167C10.6665 17.7482 10.7982 18.0661 11.0326 18.3005C11.267 18.535 11.585 18.6667 11.9165 18.6667H21.0832C21.4147 18.6667 21.7326 18.535 21.9671 18.3005C22.2015 18.0661 22.3332 17.7482 22.3332 17.4167C22.3332 17.0851 22.2015 16.7672 21.9671 16.5328C21.7326 16.2984 21.4147 16.1667 21.0832 16.1667H11.9165ZM10.6665 22.4167C10.6665 22.0851 10.7982 21.7672 11.0326 21.5328C11.267 21.2984 11.585 21.1667 11.9165 21.1667H21.0832C21.4147 21.1667 21.7326 21.2984 21.9671 21.5328C22.2015 21.7672 22.3332 22.0851 22.3332 22.4167C22.3332 22.7482 22.2015 23.0661 21.9671 23.3005C21.7326 23.535 21.4147 23.6667 21.0832 23.6667H11.9165C11.585 23.6667 11.267 23.535 11.0326 23.3005C10.7982 23.0661 10.6665 22.7482 10.6665 22.4167ZM11.9165 26.1667C11.585 26.1667 11.267 26.2984 11.0326 26.5328C10.7982 26.7672 10.6665 27.0851 10.6665 27.4167C10.6665 27.7482 10.7982 28.0661 11.0326 28.3005C11.267 28.535 11.585 28.6667 11.9165 28.6667H21.0832C21.4147 28.6667 21.7326 28.535 21.9671 28.3005C22.2015 28.0661 22.3332 27.7482 22.3332 27.4167C22.3332 27.0851 22.2015 26.7672 21.9671 26.5328C21.7326 26.2984 21.4147 26.1667 21.0832 26.1667H11.9165ZM26.3565 11.0233L16.6415 1.31C16.6157 1.28605 16.5885 1.26378 16.5598 1.24333C16.5392 1.22742 16.5192 1.21074 16.4998 1.19333C16.3852 1.08512 16.2632 0.984882 16.1348 0.893332C16.0922 0.865802 16.0476 0.841298 16.0015 0.819999L15.9215 0.779999L15.8382 0.731666C15.7482 0.679999 15.6565 0.626665 15.5615 0.586665C15.2296 0.454104 14.8783 0.376423 14.5215 0.356665C14.4885 0.354519 14.4557 0.350625 14.4232 0.344999C14.3779 0.338012 14.3323 0.334114 14.2865 0.333332H3.99984C3.11578 0.333332 2.26794 0.684521 1.64281 1.30964C1.01769 1.93476 0.666504 2.78261 0.666504 3.66667V30.3333C0.666504 31.2174 1.01769 32.0652 1.64281 32.6904C2.26794 33.3155 3.11578 33.6667 3.99984 33.6667H23.9998C24.8839 33.6667 25.7317 33.3155 26.3569 32.6904C26.982 32.0652 27.3332 31.2174 27.3332 30.3333V13.38C27.333 12.496 26.9817 11.6483 26.3565 11.0233ZM24.8332 30.3333C24.8332 30.5543 24.7454 30.7663 24.5891 30.9226C24.4328 31.0789 24.2208 31.1667 23.9998 31.1667H3.99984C3.77882 31.1667 3.56686 31.0789 3.41058 30.9226C3.2543 30.7663 3.1665 30.5543 3.1665 30.3333V3.66667C3.1665 3.44565 3.2543 3.23369 3.41058 3.07741C3.56686 2.92113 3.77882 2.83333 3.99984 2.83333H13.9998V10.3333C13.9998 11.2174 14.351 12.0652 14.9761 12.6904C15.6013 13.3155 16.4491 13.6667 17.3332 13.6667H24.8332V30.3333ZM16.4998 4.70166L22.9632 11.1667H17.3332C17.1122 11.1667 16.9002 11.0789 16.7439 10.9226C16.5876 10.7663 16.4998 10.5543 16.4998 10.3333V4.70166Z"
fill="black"
/>
</svg>
</div>
<div className="flex flex-col flex-1">
<div className="text-gray-500 dark:text-gray-400 flex flex-row text-sm">
{description.date} | <Icon icon="formkit:eye" width="15" height="15" /> 518
</div>
<div className="font-semibold text-gray-900 dark:text-white mt-1 text-sm">{textEllipsis(description.title, 50)}</div>
<div className="flex gap-2 items-center text-sm text-red-500 dark:text-red-500">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 512 512">
<path fill="#f00" d="M224 30v256h-64l96 128l96-128h-64V30zM32 434v48h448v-48z" />
</svg>
Download Dokumen
</div>
</div>
</a>
</div>
</CarouselItem>
))}
</CarouselContent>

View File

@ -4,6 +4,8 @@ import { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, Pagi
import { Card, CardContent } from "@/components/ui/card";
import { Checkbox } from "@/components/ui/checkbox";
import { Icon } from "@iconify/react/dist/iconify.js";
import { generateLocalizedPath } from "@/utils/globals";
import { useParams, usePathname, useRouter } from "next/navigation";
const dummyImage = [
{ id: 1, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
@ -37,6 +39,11 @@ const formatPicture = [
];
const FilterPage = () => {
const router = useRouter();
const pathname = usePathname();
const params = useParams();
const locale = params?.locale;
return (
<div className="flex flex-col">
{/* Header */}
@ -124,7 +131,7 @@ const FilterPage = () => {
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
{dummyImage.map((image) => (
<Card key={image.id} className="flex">
<CardContent className="flex flex-col text-xs lg:text-sm">
<CardContent onClick={() => router.push(generateLocalizedPath(`/image/detail/${image.id}`, String(locale)))} className="flex flex-col text-xs lg:text-sm">
<img src={image.thumbnail} className="h-60 object-cover w-full items-center justify-center cursor-pointer" />
<div className="flex flex-row items-center gap-2">
{image.date} {image.time} | <Icon icon="formkit:eye" width="15" height="15" /> 518{" "}

View File

@ -17,7 +17,7 @@ const ImageCard: React.FC<ImageCardProps> = ({ imageUrl, label, title, date }) =
<img src={imageUrl} alt={title} className="w-full h-full object-cover" />
<div className="absolute inset-0 bg-black bg-opacity-30 flex flex-col justify-end p-4 text-white">
<span className="bg-red-600 text-xs font-bold px-2 py-1 rounded">{label}</span>
<h3 className="text-sm font-semibold mt-2 line-clamp-2">{title}</h3>
<h3 className="text-sm font-semibold mt-2 line-clamp-2 w-fit ">{title}</h3>
<span className="text-xs mt-1">{date}</span>
</div>
</div>
@ -73,7 +73,7 @@ const ImageGallery: React.FC = () => {
return (
<>
{/* Hero */}
<div className="max-w-screen-lg mx-auto px-4 py-8 grid grid-cols-1 md:grid-cols-3 gap-4">
<div className="max-w-screen-xl mx-auto px-4 py-8 grid grid-cols-1 md:grid-cols-3 gap-4">
<div className="md:col-span-2">
<ImageCard {...images[0]} />
</div>
@ -83,7 +83,7 @@ const ImageGallery: React.FC = () => {
</div>
</div>
{/* Bottom */}
<div className="w-full">
<div className="px-4 lg:px-24 py-4">
<div className="flex flex-col gap-4">
{imageBottom.map((image) => (
<div key={image.id} className="flex flex-col md:flex-row items-start p-4 bg-white rounded-lg shadow-md hover:shadow-lg">

View File

@ -8,8 +8,9 @@ import React, { useEffect, useState } from "react";
import { format } from "date-fns";
import { cn } from "@/lib/utils";
import { Checkbox } from "@/components/ui/checkbox";
import { Icon } from "@iconify/react/dist/iconify.js";
const Jadwal = () => {
const Schedule = () => {
const city = [
{
key: 1,
@ -64,6 +65,9 @@ const Jadwal = () => {
const [startDate, setStartDate] = useState<Date | undefined>(new Date());
const [dateAWeek, setDateAWeek] = useState<string[]>([]);
const [scheduleSearch, setScheduleSearch] = useState();
const [todayList, setTodayList] = useState([]);
const curr = new Date();
const startDays = (curr.getDay() + 7 - 1) % 7;
@ -190,7 +194,7 @@ const Jadwal = () => {
return (
<>
{/* Awal Komponen Kiri */}
<div className="relative px-4 lg:px-28 md:py-10 py-4 bg-gray-50 dark:bg-slate-800">
<div className="relative px-4 lg:px-10 lg:py-10 py-4 bg-gray-50 dark:bg-slate-800">
<Popover>
<PopoverTrigger asChild>
<Button variant={"outline"} className={cn("w-[240px] py-4 justify-start text-left font-normal", !startDate && "text-muted-foreground")}>
@ -210,10 +214,10 @@ const Jadwal = () => {
</PopoverContent>
</Popover>
<div className="container relative">
<div className="container relative py-4">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<a className="text-black flex flex-row gap-2 py-4 items-center cursor-pointer">
<a className="text-black flex flex-row w-fit gap-2 py-4 items-center cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
<path fill="#000" d="M20 3H4a1 1 0 0 0-1 1v2.227l.008.223a3 3 0 0 0 .772 1.795L8 12.886V21a1 1 0 0 0 1.316.949l6-2l.108-.043A1 1 0 0 0 16 19v-6.586l4.121-4.12A3 3 0 0 0 21 6.171V4a1 1 0 0 0-1-1" />
</svg>
@ -273,337 +277,377 @@ const Jadwal = () => {
</DropdownMenuContent>
</DropdownMenu>
</div>
<div className="flex flex-col lg:flex-row gap-6">
<div className="h-[500px] overflow-y-auto w-3/4 ">
<div className="container-fluid relative">
<div className="grid grid-cols-1 mt-8">
<div className="relative block bg-white dark:bg-slate-900">
<table className="w-full text-sm text-start">
<thead className="text-md">
<tr className="h-full">
<th className="text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[120px]">Time Table</th>
<th className="flex flex-row border h-full border-gray-100 dark:border-gray-700 py-6 min-w-[100px]">
<a className="cursor-pointer h-fit self-center bottom-0" onClick={() => changePrevWeek()}>
<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24">
<path fill="currentColor" d="M12.29 8.71L9.7 11.3a.996.996 0 0 0 0 1.41l2.59 2.59c.63.63 1.71.18 1.71-.71V9.41c0-.89-1.08-1.33-1.71-.7" />
</svg>
</a>{" "}
<div className="flex flex-col">
<p>{dateAWeek[0]?.split("-")[2]}</p>
<p>Monday</p>
</div>
</th>
<th className="text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px]">
<div>{dateAWeek[1]?.split("-")[2]}</div>Tuesday
</th>
<th className="text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px]">
<div>{dateAWeek[2]?.split("-")[2]}</div>Wednesday
</th>
<th className="text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px]">
<div>{dateAWeek[3]?.split("-")[2]}</div>Thursday
</th>
<th className="text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px]">
<div>{dateAWeek[4]?.split("-")[2]}</div>Friday
</th>
<th className="text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px]">
<div>{dateAWeek[5]?.split("-")[2]}</div>Saturday
</th>
<th className="flex flex-row text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px]">
<div className="flex flex-col ">
<p>{dateAWeek[6]?.split("-")[2]}</p>
<p>Sunday</p>
</div>
<a onClick={() => changeNextWeek()} className="cursor-pointer h-fit p-0 m-0 self-center">
<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24">
<path fill="currentColor" d="m11.71 15.29l2.59-2.59a.996.996 0 0 0 0-1.41L11.71 8.7c-.63-.62-1.71-.18-1.71.71v5.17c0 .9 1.08 1.34 1.71.71" />
</svg>
</a>
</th>
</tr>
</thead>
<tbody>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">06:00</th>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<div className="h-[300px] w-3/4 overflow-y-auto">
<div className="container-fluid relative">
<div className="grid grid-cols-1 mt-8">
<div className="relative block bg-white dark:bg-slate-900">
<table className="w-full text-sm text-start">
<thead className="text-md">
<tr className="h-full">
<th className="text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[120px]">Time Table</th>
<th className="flex flex-row border h-full border-gray-100 dark:border-gray-700 py-6 min-w-[100px]">
<a className="cursor-pointer h-fit self-center bottom-0" onClick={() => changePrevWeek()}>
<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24">
<path fill="currentColor" d="M12.29 8.71L9.7 11.3a.996.996 0 0 0 0 1.41l2.59 2.59c.63.63 1.71.18 1.71-.71V9.41c0-.89-1.08-1.33-1.71-.7" />
</svg>
</a>{" "}
<div className="flex flex-col">
<p>{dateAWeek[0]?.split("-")[2]}</p>
<p>Monday</p>
</div>
</th>
<th className="text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px]">
<div>{dateAWeek[1]?.split("-")[2]}</div>Tuesday
</th>
<th className="text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px]">
<div>{dateAWeek[2]?.split("-")[2]}</div>Wednesday
</th>
<th className="text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px]">
<div>{dateAWeek[3]?.split("-")[2]}</div>Thursday
</th>
<th className="text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px]">
<div>{dateAWeek[4]?.split("-")[2]}</div>Friday
</th>
<th className="text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px]">
<div>{dateAWeek[5]?.split("-")[2]}</div>Saturday
</th>
<th className="flex flex-row text-center border border-gray-100 dark:border-gray-700 py-6 min-w-[100px]">
<div className="flex flex-col ">
<p>{dateAWeek[6]?.split("-")[2]}</p>
<p>Sunday</p>
</div>
<a onClick={() => changeNextWeek()} className="cursor-pointer h-fit p-0 m-0 self-center">
<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24">
<path fill="currentColor" d="m11.71 15.29l2.59-2.59a.996.996 0 0 0 0-1.41L11.71 8.7c-.63-.62-1.71-.18-1.71.71v5.17c0 .9 1.08 1.34 1.71.71" />
</svg>
</a>
</th>
</tr>
</thead>
<tbody>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">06:00</th>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">07:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">07:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">08:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">08:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">09:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">09:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">10:00</th>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">10:00</th>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">11:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">11:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">12:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">12:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">13:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">13:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">14:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">14:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">15:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">15:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">16:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">16:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">17:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">17:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">18:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">18:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">19:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">19:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">20:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">20:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">21:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">21:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">22:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">22:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">23:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">23:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">24:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">24:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">01:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">01:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">02:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">02:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">03:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">03:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">04:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">04:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">05:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
</tbody>
</table>
<tr>
<th className="text-center border border-gray-100 dark:border-gray-700 py-5">05:00</th>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="p-3 border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
<td className="border border-gray-100 dark:border-gray-700"></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div className="w-1/4 flex flex-col gap-6">
<div className="relative text-gray-600 dark:text-white">
<input type="text" placeholder="Masukkan Judul Jadwal" className="pl-8 pr-4 py-1 w-full border rounded-full text-sm focus:outline-none" />
<span className="absolute left-2 top-1/2 transform -translate-y-1/2">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
<path fill="currentColor" d="M10.5 2a8.5 8.5 0 1 0 5.262 15.176l3.652 3.652a1 1 0 0 0 1.414-1.414l-3.652-3.652A8.5 8.5 0 0 0 10.5 2M4 10.5a6.5 6.5 0 1 1 13 0a6.5 6.5 0 0 1-13 0" />
</g>
</svg>
</span>
</div>
<div className="card border border-slate-400 p-2 rounded-lg">
<div className="card-header">
<a className="accordion-icon">
<h5 className="py-2 theme-text text-left">
Jadwal Hari Ini
<span className="float-right">
<Icon icon="fa:angle-down" className="ml-1" />
</span>
</h5>
</a>
</div>
</div>
<div className="card border border-slate-400 p-2 rounded-lg">
<div className="card-header">
<a className="accordion-icon">
<h5 className="py-2 theme-text text-left">
Jadwal Sebelumnya
<span className="float-right">
<Icon icon="fa:angle-down" className="ml-1" />
</span>
</h5>
</a>
</div>
</div>
<div className="card border border-slate-400 p-2 rounded-lg">
<div className="card-header">
<a className="accordion-icon">
<h5 className="py-2 theme-text text-left">
Jadwal Selanjutnya
<span className="float-right">
<Icon icon="fa:angle-down" className="ml-1" />
</span>
</h5>
</a>
</div>
</div>
</div>
</div>
</div>
{/* Akhir Komponen Kiri */}
{/* Awal Komponent Kanan */}
<div className="w-1/4">
<div>
<h1>HALO</h1>
</div>
</div>
{/* Akhir Komponen Kanan */}
</>
);
};
export default Jadwal;
export default Schedule;

View File

@ -6,7 +6,8 @@ import { Textarea } from "@/components/ui/textarea";
import Link from "next/link";
import { useParams, usePathname, useRouter } from "next/navigation";
import React, { useState } from "react";
import { Icon } from "@iconify/react/dist/iconify.js";
import { textEllipsis } from "@/utils/globals";
const dummyImage = [
{ id: 1, thumbnail: "/assets/banner-sample.png" },
@ -18,7 +19,7 @@ const dummyImage = [
const dummyData = {
id: 12312,
title: "ahahah",
title: "TITLE",
createdBy: "Mabes",
createdAt: "21-21-2021",
time: "18:23",
@ -27,6 +28,27 @@ const dummyData = {
'<p>Polres Kobar - Polres Kotawaringin Barat (Kobar) memberikan bantuan sosial kepada warga yang berada di Daerah Aliran Sungai (DAS) Arut khususnya yang terdampak banjir, Sabtu (30/11/2024) pagi.</p><p>Kapolda Kalteng Irjen Pol Drs. Djoko Poerwanto melalui Kapolres Kobar AKBP Yusfandi Usman, S.I.K., M.I.K., menjelaskan bahwa pihaknya membagikan 200 paket sembako sebagai bentuk kepedulian kepada masyarakat.</p><p>"Saya bersama personel turun langsung membagikan bantuan berupa paket sembako yang diserahkan kepada masyarakat sekaligus monitoring ke lokasi pinggiran sungai yang mulai sebagain terdampak banjir akibat curah hujan tinggi,” ungkap Kapolres.</p><p>Lebih lanjut, orang nomor satu di Polres Kobar ini, mengungkapkan kegiatan tersebut dilakukan dalam rangka tanggap waspada dan antisipasi bencana banjir di wilayah Kabupaten Kobar.</p><p>“Kami minta masyarakat tetap waspada banjir menyikapi cuaca yang berubah-ubah saat ini, tidak menutup kemungkinan bertambahnya volume air sungai, jika diguyur hujan terus menerus,” jelasnya.</p>',
};
const dummyImageContent = [
{ id: 1, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
{ id: 2, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
{ id: 3, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
{ id: 4, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
{ id: 5, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
{ id: 6, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
{ id: 7, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
{ id: 8, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
{ id: 9, thumbnail: "/assets/banner-sample.png", date: "17 MEI 2024", title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", time: "18.00 WIB" },
];
const dummyDescription = [
{ id: 1, title: "Kapolres Batam Berikan pengarahan pagi kepada para anggota dan staf yang terkait", date: "28 November 2024", time: "11.15 WIB", duration: "00:24:55" },
{ id: 2, title: "Kapolres Lahat Himbau Cipta Kondisi Cooling System Pasca Pemungutan Suara Pilkada 2024", date: "28 November 2024", time: "11.15 WIB", duration: "00:24:55" },
{ id: 3, title: "17 Ton Pupuk Bersubsidi yang Akan Diselewengkan ke Banyuasin Berhasil Digagalkan", date: "28 November 2024", time: "11.15 WIB", duration: "00:24:55" },
{ id: 4, title: "Kapolda Sumsel Apelkan 1471 Personel Persiapan Pengamanan Pengawalan Tahan Pungut dan Hitung Suara", date: "28 November 2024", time: "11.15 WIB", duration: "00:24:55" },
{ id: 5, title: "Polrestabes Palembang Berhasil Mengungkap Kasus Penganiayaan Berat di Ilir Barat II", date: "28 November 2024", time: "11.15 WIB", duration: "00:24:55" },
{ id: 6, title: "Tahapan Pilkada di Sumsel Berlangsung Kondusif", date: "28 November 2024", time: "11.15 WIB", duration: "00:24:55" },
];
const DetailVideo = () => {
const [selectedSize, setSelectedSize] = useState<string>("L");
const [selectedTab, setSelectedTab] = useState("video");
@ -44,14 +66,14 @@ const DetailVideo = () => {
];
return (
<div className="min-h-screen p-4 md:p-8">
<div className="min-h-screen px-4 md:px-24 py-4">
{/* Container Utama */}
<div className="rounded-md overflow-hidden md:flex">
{/* Bagian Kiri */}
<div className="md:w-2/3">
<div className="md:w-3/4">
{/* Gambar Utama */}
<div className="relative">
<img src="https://mediahub.polri.go.id/api/media/categories/view-thumbnail?id=93&currentMilis=1732769540018" alt="Main" className="w-full" />
<img src="https://mediahub.polri.go.id/api/media/categories/view-thumbnail?id=93&currentMilis=1732769540018" alt="Main" className="w-full rounded-lg" />
<div className="absolute top-4 left-4"></div>
</div>
@ -62,14 +84,14 @@ const DetailVideo = () => {
key={index}
src="https://mediahub.polri.go.id/api/media/categories/view-thumbnail?id=93&currentMilis=1732769540018"
alt={`Thumbnail ${index + 1}`}
className="w-full h-16 object-cover rounded-md cursor-pointer hover:ring-2 hover:ring-red-600"
className="w-full h-fit object-cover rounded-md cursor-pointer hover:ring-2 hover:ring-red-600"
/>
))}
</div>
</div>
{/* Bagian Kanan */}
<div className="md:w-1/3 p-4 bg-gray-300 rounded-lg mx-4">
<div className="md:w-1/4 p-4 bg-gray-300 rounded-lg mx-4">
<div className="flex flex-col mb-3 items-center justify-center cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg" width="2.5em" height="2.5em" viewBox="0 0 24 24">
<path fill="black" d="m17 18l-5-2.18L7 18V5h10m0-2H7a2 2 0 0 0-2 2v16l7-3l7 3V5a2 2 0 0 0-2-2" />
@ -133,7 +155,7 @@ const DetailVideo = () => {
</div>
{/* Keterangan */}
<div className="md:w-2/3">
<div className="md:w-3/4">
<h1 className="flex flex-row font-bold text-2xl mx-5 my-8">{dummyData.title}</h1>
<div dangerouslySetInnerHTML={{ __html: dummyData.htmlDescription }} />
</div>
@ -146,24 +168,36 @@ const DetailVideo = () => {
</div>
{/* Konten Serupa */}
<div className="w-full">
<div className="space-x-5 flex flex-col p-4">
<div className="flex px-10 flex-col lg:flex-row gap-5 mb-4">
<h2 className="flex items-center text-sm lg:text-xl font-bold bg-[#bb3523] px-4 py-1 rounded-lg text-white">
<span className="text-black ">Konten </span> Serupa
<div className="px-4 lg:px-12 ">
<div className="flex flex-col p-4">
<div className="mx-auto w-full max-w-7xl justify-start flex px-5 flex-col lg:flex-row gap-5 mb-4">
<h2 className="flex items-center text-sm lg:text-xl w-fit font-bold bg-[#bb3523] px-4 py-1 rounded-lg text-white">
<span className="text-black ">Konten </span> Terbaru
</h2>
<Tabs value={selectedTab} onValueChange={setSelectedTab}>
<TabsList>
<TabsTrigger value="video" className="relative text-sm md:text-xl font-bold text-black dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary">
<TabsTrigger
value="video"
className="relative text-sm md:text-xl font-bold text-black dark:text-white dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary"
>
Audio Visual
</TabsTrigger>
<TabsTrigger value="audio" className="relative text-sm md:text-xl font-bold text-black dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary">
<TabsTrigger
value="audio"
className="relative text-sm md:text-xl font-bold text-black dark:text-white dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary"
>
Audio
</TabsTrigger>
<TabsTrigger value="image" className="relative text-sm md:text-xl font-bold text-black dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary">
<TabsTrigger
value="image"
className="relative text-sm md:text-xl font-bold text-black dark:text-white dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary"
>
Foto
</TabsTrigger>
<TabsTrigger value="teks" className="relative text-sm md:text-xl font-bold text-black dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary">
<TabsTrigger
value="teks"
className="relative text-sm md:text-xl font-bold text-black dark:text-white dark:bg-transparent before:absolute before:top-full before:left-0 before:h-px before:w-full data-[state=active]:before:bg-primary"
>
Teks
</TabsTrigger>
</TabsList>
@ -171,15 +205,21 @@ const DetailVideo = () => {
</div>
<div className="px-10">
{selectedTab == "video" ? (
<Carousel>
<Carousel className="w-full max-w-7xl mx-auto">
<CarouselContent>
{dummyImage.map((image) => (
{dummyImageContent.map((image) => (
<CarouselItem key={image.id} className="md:basis-1/2 lg:basis-1/3">
<Card>
<CardContent className="flex items-center justify-center">
<img src={image.thumbnail} className="h-60 object-cover w-full cursor-pointer" />
</CardContent>
</Card>
<img src={image.thumbnail} className="h-60 object-cover w-full items-center justify-center cursor-pointer" />
<div className="flex flex-row items-center gap-2">
{image.date} {image.time} | <Icon icon="formkit:eye" width="15" height="15" /> 518{" "}
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 20 20">
<path
fill="#f00"
d="M7.707 10.293a1 1 0 1 0-1.414 1.414l3 3a1 1 0 0 0 1.414 0l3-3a1 1 0 0 0-1.414-1.414L11 11.586V6h5a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h5v5.586zM9 4a1 1 0 0 1 2 0v2H9z"
/>
</svg>{" "}
</div>
<div className="font-semibold w-fit">{image.title}</div>
</CarouselItem>
))}
</CarouselContent>
@ -189,13 +229,27 @@ const DetailVideo = () => {
) : selectedTab == "audio" ? (
<Carousel>
<CarouselContent>
{dummyImage.map((image) => (
<CarouselItem key={image.id} className="md:basis-1/2 lg:basis-1/3">
<Card>
<CardContent className="flex items-center justify-center">
<img src={image.thumbnail} className="h-60 object-cover w-full cursor-pointer" />
</CardContent>
</Card>
{dummyDescription.map((description) => (
<CarouselItem key={description.id} className="md:basis-1/2 lg:basis-1/3">
<div className="flex flex-row gap-6">
<a href="#" key={description.id} className="flex flex-col sm:flex-row items-center bg-white dark:bg-gray-800 cursor-pointer shadow-md rounded-lg p-4 gap-4 w-full">
<div className="flex items-center justify-center bg-red-500 text-white rounded-lg w-16 h-8 lg:h-16">
<svg width="32" height="34" viewBox="0 0 32 34" fill="null" xmlns="http://www.w3.org/2000/svg">
<path
d="M23.404 0.452014C23.7033 0.35857 24.0204 0.336816 24.3297 0.388509C24.639 0.440203 24.9318 0.563895 25.1845 0.749599C25.4371 0.935304 25.6426 1.17782 25.7843 1.45756C25.9259 1.73731 25.9998 2.04644 26 2.36001V14.414C25.3462 14.2296 24.6766 14.1064 24 14.046V8.36001L10 12.736V27C10 28.1264 9.6197 29.2197 8.92071 30.1029C8.22172 30.9861 7.24499 31.6075 6.14877 31.8663C5.05255 32.125 3.90107 32.0061 2.88089 31.5287C1.86071 31.0514 1.03159 30.2435 0.52787 29.2361C0.024152 28.2286 -0.124656 27.0806 0.105556 25.9781C0.335768 24.8755 0.931513 23.883 1.79627 23.1613C2.66102 22.4396 3.74413 22.031 4.87009 22.0017C5.99606 21.9724 7.09893 22.3242 8.00001 23V6.73601C7.99982 6.30956 8.13596 5.8942 8.38854 5.55059C8.64112 5.20698 8.99692 4.9531 9.40401 4.82601L23.404 0.452014ZM10 10.64L24 6.26601V2.36001L10 6.73601V10.64ZM5.00001 24C4.20436 24 3.44129 24.3161 2.87869 24.8787C2.31608 25.4413 2.00001 26.2044 2.00001 27C2.00001 27.7957 2.31608 28.5587 2.87869 29.1213C3.44129 29.6839 4.20436 30 5.00001 30C5.79566 30 6.55872 29.6839 7.12133 29.1213C7.68394 28.5587 8.00001 27.7957 8.00001 27C8.00001 26.2044 7.68394 25.4413 7.12133 24.8787C6.55872 24.3161 5.79566 24 5.00001 24ZM32 25C32 27.387 31.0518 29.6761 29.364 31.364C27.6761 33.0518 25.387 34 23 34C20.6131 34 18.3239 33.0518 16.636 31.364C14.9482 29.6761 14 27.387 14 25C14 22.6131 14.9482 20.3239 16.636 18.6361C18.3239 16.9482 20.6131 16 23 16C25.387 16 27.6761 16.9482 29.364 18.6361C31.0518 20.3239 32 22.6131 32 25ZM27.47 24.128L21.482 20.828C21.3298 20.7443 21.1583 20.7016 20.9846 20.7043C20.8108 20.707 20.6408 20.7549 20.4912 20.8433C20.3416 20.9317 20.2176 21.0576 20.1315 21.2086C20.0453 21.3595 20 21.5302 20 21.704V28.304C20 28.4778 20.0453 28.6486 20.1315 28.7995C20.2176 28.9504 20.3416 29.0763 20.4912 29.1647C20.6408 29.2531 20.8108 29.301 20.9846 29.3037C21.1583 29.3064 21.3298 29.2638 21.482 29.18L27.47 25.88C27.6268 25.7937 27.7575 25.6669 27.8486 25.5128C27.9397 25.3587 27.9877 25.183 27.9877 25.004C27.9877 24.825 27.9397 24.6493 27.8486 24.4952C27.7575 24.3412 27.6268 24.2143 27.47 24.128Z"
fill="white"
/>
</svg>
</div>
<div className="flex flex-col flex-1">
<div className="text-gray-500 dark:text-gray-400 flex flex-row text-sm">
{description.date} | <Icon icon="formkit:eye" width="15" height="15" /> 518
</div>
<div className="font-semibold text-gray-900 dark:text-white mt-1 text-sm">{textEllipsis(description.title, 50)}</div>
</div>
</a>
</div>
</CarouselItem>
))}
</CarouselContent>
@ -205,13 +259,19 @@ const DetailVideo = () => {
) : selectedTab == "image" ? (
<Carousel>
<CarouselContent>
{dummyImage.map((image) => (
{dummyImageContent.map((image) => (
<CarouselItem key={image.id} className="md:basis-1/2 lg:basis-1/3">
<Card onClick={() => router.push(`${locale}/image/detail/${image.id}`)}>
<CardContent className="flex items-center justify-center">
<img src={image.thumbnail} className="h-60 object-cover w-full cursor-pointer" />
</CardContent>
</Card>
<img src={image.thumbnail} className="h-60 object-cover w-full items-center justify-center cursor-pointer" />
<div className="flex flex-row items-center gap-2">
{image.date} {image.time} | <Icon icon="formkit:eye" width="15" height="15" /> 518{" "}
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 20 20">
<path
fill="#f00"
d="M7.707 10.293a1 1 0 1 0-1.414 1.414l3 3a1 1 0 0 0 1.414 0l3-3a1 1 0 0 0-1.414-1.414L11 11.586V6h5a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h5v5.586zM9 4a1 1 0 0 1 2 0v2H9z"
/>
</svg>{" "}
</div>
<div className="font-semibold w-fit">{image.title}</div>
</CarouselItem>
))}
</CarouselContent>
@ -221,13 +281,33 @@ const DetailVideo = () => {
) : (
<Carousel>
<CarouselContent>
{dummyImage.map((image) => (
<CarouselItem key={image.id} className="md:basis-1/2 lg:basis-1/3">
<Card>
<CardContent>
<img src={image.thumbnail} className="h-60 object-cover w-full cursor-pointer" />
</CardContent>
</Card>
{dummyImageContent.map((description) => (
<CarouselItem key={description.id} className="md:basis-1/2 lg:basis-1/3">
<div className="md:basis-1/2 lg:basis-1/3">
<a href="#" className="flex flex-col bg-yellow-500 sm:flex-row items-center dark:bg-gray-800 cursor-pointer shadow-md rounded-lg p-4 gap-4 w-full">
<div className="flex items-center justify-center rounded-lg w-16 h-2 lg:h-16">
<svg width="28" height="34" viewBox="0 0 28 34" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M5.6665 17.4167C5.6665 17.0851 5.7982 16.7672 6.03262 16.5328C6.26704 16.2984 6.58498 16.1667 6.9165 16.1667C7.24802 16.1667 7.56597 16.2984 7.80039 16.5328C8.03481 16.7672 8.1665 17.0851 8.1665 17.4167C8.1665 17.7482 8.03481 18.0661 7.80039 18.3005C7.56597 18.535 7.24802 18.6667 6.9165 18.6667C6.58498 18.6667 6.26704 18.535 6.03262 18.3005C5.7982 18.0661 5.6665 17.7482 5.6665 17.4167ZM6.9165 21.1667C6.58498 21.1667 6.26704 21.2984 6.03262 21.5328C5.7982 21.7672 5.6665 22.0851 5.6665 22.4167C5.6665 22.7482 5.7982 23.0661 6.03262 23.3005C6.26704 23.535 6.58498 23.6667 6.9165 23.6667C7.24802 23.6667 7.56597 23.535 7.80039 23.3005C8.03481 23.0661 8.1665 22.7482 8.1665 22.4167C8.1665 22.0851 8.03481 21.7672 7.80039 21.5328C7.56597 21.2984 7.24802 21.1667 6.9165 21.1667ZM5.6665 27.4167C5.6665 27.0851 5.7982 26.7672 6.03262 26.5328C6.26704 26.2984 6.58498 26.1667 6.9165 26.1667C7.24802 26.1667 7.56597 26.2984 7.80039 26.5328C8.03481 26.7672 8.1665 27.0851 8.1665 27.4167C8.1665 27.7482 8.03481 28.0661 7.80039 28.3005C7.56597 28.535 7.24802 28.6667 6.9165 28.6667C6.58498 28.6667 6.26704 28.535 6.03262 28.3005C5.7982 28.0661 5.6665 27.7482 5.6665 27.4167ZM11.9165 16.1667C11.585 16.1667 11.267 16.2984 11.0326 16.5328C10.7982 16.7672 10.6665 17.0851 10.6665 17.4167C10.6665 17.7482 10.7982 18.0661 11.0326 18.3005C11.267 18.535 11.585 18.6667 11.9165 18.6667H21.0832C21.4147 18.6667 21.7326 18.535 21.9671 18.3005C22.2015 18.0661 22.3332 17.7482 22.3332 17.4167C22.3332 17.0851 22.2015 16.7672 21.9671 16.5328C21.7326 16.2984 21.4147 16.1667 21.0832 16.1667H11.9165ZM10.6665 22.4167C10.6665 22.0851 10.7982 21.7672 11.0326 21.5328C11.267 21.2984 11.585 21.1667 11.9165 21.1667H21.0832C21.4147 21.1667 21.7326 21.2984 21.9671 21.5328C22.2015 21.7672 22.3332 22.0851 22.3332 22.4167C22.3332 22.7482 22.2015 23.0661 21.9671 23.3005C21.7326 23.535 21.4147 23.6667 21.0832 23.6667H11.9165C11.585 23.6667 11.267 23.535 11.0326 23.3005C10.7982 23.0661 10.6665 22.7482 10.6665 22.4167ZM11.9165 26.1667C11.585 26.1667 11.267 26.2984 11.0326 26.5328C10.7982 26.7672 10.6665 27.0851 10.6665 27.4167C10.6665 27.7482 10.7982 28.0661 11.0326 28.3005C11.267 28.535 11.585 28.6667 11.9165 28.6667H21.0832C21.4147 28.6667 21.7326 28.535 21.9671 28.3005C22.2015 28.0661 22.3332 27.7482 22.3332 27.4167C22.3332 27.0851 22.2015 26.7672 21.9671 26.5328C21.7326 26.2984 21.4147 26.1667 21.0832 26.1667H11.9165ZM26.3565 11.0233L16.6415 1.31C16.6157 1.28605 16.5885 1.26378 16.5598 1.24333C16.5392 1.22742 16.5192 1.21074 16.4998 1.19333C16.3852 1.08512 16.2632 0.984882 16.1348 0.893332C16.0922 0.865802 16.0476 0.841298 16.0015 0.819999L15.9215 0.779999L15.8382 0.731666C15.7482 0.679999 15.6565 0.626665 15.5615 0.586665C15.2296 0.454104 14.8783 0.376423 14.5215 0.356665C14.4885 0.354519 14.4557 0.350625 14.4232 0.344999C14.3779 0.338012 14.3323 0.334114 14.2865 0.333332H3.99984C3.11578 0.333332 2.26794 0.684521 1.64281 1.30964C1.01769 1.93476 0.666504 2.78261 0.666504 3.66667V30.3333C0.666504 31.2174 1.01769 32.0652 1.64281 32.6904C2.26794 33.3155 3.11578 33.6667 3.99984 33.6667H23.9998C24.8839 33.6667 25.7317 33.3155 26.3569 32.6904C26.982 32.0652 27.3332 31.2174 27.3332 30.3333V13.38C27.333 12.496 26.9817 11.6483 26.3565 11.0233ZM24.8332 30.3333C24.8332 30.5543 24.7454 30.7663 24.5891 30.9226C24.4328 31.0789 24.2208 31.1667 23.9998 31.1667H3.99984C3.77882 31.1667 3.56686 31.0789 3.41058 30.9226C3.2543 30.7663 3.1665 30.5543 3.1665 30.3333V3.66667C3.1665 3.44565 3.2543 3.23369 3.41058 3.07741C3.56686 2.92113 3.77882 2.83333 3.99984 2.83333H13.9998V10.3333C13.9998 11.2174 14.351 12.0652 14.9761 12.6904C15.6013 13.3155 16.4491 13.6667 17.3332 13.6667H24.8332V30.3333ZM16.4998 4.70166L22.9632 11.1667H17.3332C17.1122 11.1667 16.9002 11.0789 16.7439 10.9226C16.5876 10.7663 16.4998 10.5543 16.4998 10.3333V4.70166Z"
fill="black"
/>
</svg>
</div>
<div className="flex flex-col flex-1">
<div className="text-gray-500 dark:text-gray-400 flex flex-row text-sm">
{description.date} | <Icon icon="formkit:eye" width="15" height="15" /> 518
</div>
<div className="font-semibold text-gray-900 dark:text-white mt-1 text-sm">{textEllipsis(description.title, 50)}</div>
<div className="flex gap-2 items-center text-sm text-red-500 dark:text-red-500">
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 512 512">
<path fill="#f00" d="M224 30v256h-64l96 128l96-128h-64V30zM32 434v48h448v-48z" />
</svg>
Download Dokumen
</div>
</div>
</a>
</div>
</CarouselItem>
))}
</CarouselContent>

View File

@ -6,8 +6,9 @@ import PopularContent from "@/components/landing-page/popular-content";
import ContentCategory from "@/components/landing-page/content-category";
import Coverage from "@/components/landing-page/coverage";
import Navbar from "@/components/landing-page/navbar";
import Hero from "@/components/landing-page/Hero";
import Hero from "@/components/landing-page/hero";
import Footer from "@/components/landing-page/footer";
import Division from "@/components/landing-page/division";
const Home = ({ params: { locale } }: { params: { locale: string } }) => {
return (
@ -19,6 +20,7 @@ const Home = ({ params: { locale } }: { params: { locale: string } }) => {
<PopularContent />
<ContentCategory />
<Coverage />
<Division />
<Footer />
</>
);

View File

@ -1,4 +1,4 @@
"use client";
"use client"
import React, { useState } from "react";
import ThemeSwitcher from "@/components/partials/header/theme-switcher";
@ -21,6 +21,13 @@ const Navbar = () => {
const pathname = usePathname();
const params = useParams();
const locale = params?.locale;
const [language, setLanguage] = useState<"id" | "en">("id");
const [isOpen, setIsOpen] = useState(false);
const handleLanguageChange = (lang: "id" | "en") => {
setLanguage(lang);
setIsOpen(false);
};
return (
<div className="bg-white dark:bg-black shadow-md sticky top-0 z-50">
@ -214,31 +221,55 @@ const Navbar = () => {
/>
</a>
</div>
<select
className="bg-transparent dark:text-white text-black border-none focus:outline-none"
defaultValue="Indonesia"
>
<option>Indonesia</option>
<option>English</option>
</select>
<div className="relative inline-block text-left">
{/* Tombol Utama */}
<button onClick={() => setIsOpen(!isOpen)} className="flex items-center space-x-2 p-2 text-gray-700 bg-slate-200 rounded-lg">
<img
src={language === "id" ? "https://upload.wikimedia.org/wikipedia/commons/9/9f/Flag_of_Indonesia.svg" : "https://upload.wikimedia.org/wikipedia/en/a/a4/Flag_of_the_United_States.svg"}
alt={language === "id" ? "Ind" : "Eng"}
className="w-3 h-3"
/>
<span>{language === "id" ? "Ind" : "Eng"}</span>
<span className="text-gray-500">
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 32 32">
<path fill="currentColor" d="M8.037 11.166L14.5 22.36c.825 1.43 2.175 1.43 3 0l6.463-11.195c.826-1.43.15-2.598-1.5-2.598H9.537c-1.65 0-2.326 1.17-1.5 2.6z" />
</svg>
</span>
</button>
{/* Dropdown Menu */}
{isOpen && (
<div className="absolute right-0 mt-2 w-auto bg-slate-200 border rounded-md shadow-lg z-10">
<button onClick={() => handleLanguageChange("id")} className={`flex items-center space-x-2 w-full px-4 py-2 ${language === "id" ? "font-medium" : ""}`}>
<img src="https://upload.wikimedia.org/wikipedia/commons/9/9f/Flag_of_Indonesia.svg" alt="Indonesia" className="w-5 h-5" />
<span>Ind</span>
</button>
<button onClick={() => handleLanguageChange("en")} className={`flex items-center space-x-2 w-full px-4 py-2 ${language === "en" ? "font-medium" : ""}`}>
<img src="https://upload.wikimedia.org/wikipedia/en/a/a4/Flag_of_the_United_States.svg" alt="English" className="w-5 h-5" />
<span>Eng</span>
</button>
</div>
)}
</div>
<ThemeSwitcher />
<div className="relative text-gray-600 dark:text-white">
<input
type="text"
placeholder="Pencarian"
className="pl-8 pr-4 py-1 border rounded-full text-sm focus:outline-none"
/>
<span className="absolute left-2 top-1/2 transform -translate-y-1/2">
🔍
<input type="text" placeholder="Pencarian" className="pl-8 pr-4 py-1 w-28 text-[13px] border rounded-full focus:outline-none" />
<span className="absolute left-4 top-1/2 transform -translate-y-1/2">
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24">
<path
fill="currentColor"
fill-rule="evenodd"
d="M14.385 15.446a6.751 6.751 0 1 1 1.06-1.06l5.156 5.155a.75.75 0 1 1-1.06 1.06zM6.46 13.884a5.25 5.25 0 1 1 7.43-.005l-.005.005l-.005.004a5.25 5.25 0 0 1-7.42-.004"
clip-rule="evenodd"
/>
</svg>
</span>
</div>
<div className="flex items-center space-x-2">
<button className="px-4 py-1 bg-[#bb3523] text-white font-semibold rounded-md hover:bg-red-700">
<Link href="/in/auth" className="px-4 py-1 bg-[#bb3523] text-white font-semibold rounded-md hover:bg-red-700">
Masuk
</button>
<button className="px-4 py-1 border border-[#bb3523] text-[#bb3523] font-semibold rounded-md hover:bg-red-600 hover:text-white">
Daftar
</button>
</Link>
<button className="px-4 py-1 border border-[#bb3523] text-[#bb3523] font-semibold rounded-md hover:bg-red-600 hover:text-white">Daftar</button>
</div>
</div>
</div>
@ -407,14 +438,12 @@ const Navbar = () => {
/>
</div>
<div className="flex flex-col space-y-2">
<Link href={"/auth"}>
<button className="w-full px-4 py-1 bg-[#bb3523] text-white font-semibold rounded-md hover:bg-red-700 md:flex">
Masuk
</button>
<Link href="/auth" className="w-full px-4 py-1 bg-[#bb3523] text-white font-semibold rounded-md hover:bg-red-700 md:flex">
Masuk
</Link>
<button className="w-full px-4 py-1 border border-[#bb3523] text-[#bb3523] font-semibold rounded-md hover:bg-[#bb3523] md:flex hover:text-white">
<Link href="#" className="w-full px-4 py-1 border border-[#bb3523] text-[#bb3523] font-semibold rounded-md hover:bg-[#bb3523] md:flex hover:text-white">
Daftar
</button>
</Link>
</div>
</div>
)}

View File

@ -0,0 +1,102 @@
import React, { useState } from "react";
import { Button } from "../ui/button";
const Division = () => {
const [searchTerm, setSearchTerm] = useState("");
const [seeAllValue, setSeeAllValue] = useState(false);
const regions = [
{ name: "SIBER", logo: "/assets/satker/siber.png" },
{ name: "DIVKUM", logo: "/assets/satker/divkum.png" },
{ name: "PUSKEU", logo: "/assets/satker/puskeu.png" },
{ name: "SSDM", logo: "/assets/satker/ssdm.png" },
{ name: "ITWASUM", logo: "/assets/satker/itwasum.png" },
{ name: "STIK-PTIK", logo: "/assets/satker/stik-ptik.png" },
{ name: "SATUAN KERJA POLRI", logo: "/assets/satker/satuan-kerja-polri.png" },
{ name: "BRIMOB", logo: "/assets/satker/brimob.png" },
{ name: "DIV HUMAS", logo: "/assets/satker/div-humas.png" },
{ name: "PUSLITBANG", logo: "/assets/satker/puslitbang.png" },
{ name: "BINMAS", logo: "/assets/satker/binmas.png" },
{ name: "DIV TIK", logo: "/assets/satker/div-tik.png" },
{ name: "SPRIPIM", logo: "/assets/satker/spripim.png" },
{ name: "DIVPROPRAM", logo: "/assets/satker/div-propram.png" },
{ name: "KORPS SABHARA BAHARKAM", logo: "/assets/satker/khorp-sabhara-baharkam.png" },
{ name: "PUSDOKKES", logo: "/assets/satker/pusdokkes.png" },
{ name: "BAHARKAM", logo: "/assets/satker/baharkam.png" },
{ name: "POLAIRUD", logo: "/assets/satker/polairud.png" },
{ name: "POLAIR", logo: "/assets/satker/polair.png" },
{ name: "POLUDARA", logo: "/assets/satker/poludara.png" },
{ name: "LEMDIKLAT", logo: "/assets/satker/lemdiklat.png" },
{ name: "AKPOL", logo: "/assets/satker/akpol.png" },
{ name: "KORLANTAS", logo: "/assets/satker/korlantas.png" },
{ name: "PUSINAFIS", logo: "/assets/satker/pusinafis.png" },
{ name: "PUSJARAH", logo: "/assets/satker/pusjarah.png" },
{ name: "PUSIKNAS", logo: "/assets/satker/pusiknas.png" },
{ name: "SLOG", logo: "/assets/satker/slog.png" },
{ name: "BAINTELKAM", logo: "/assets/satker/baintelkam.jpg" },
{ name: "BARESKRIM", logo: "/assets/satker/bareskrim.png" },
{ name: "DIVHUBINTER", logo: "/assets/satker/divhubinter.png" },
{ name: "SETUM", logo: "/assets/satker/setum.png" },
{ name: "PUSLABFOR", logo: "/assets/satker/puslabfor.png" },
{ name: "DENSUS 88", logo: "/assets/satker/densus88.png" },
{ name: "SAHLI KAPOLRI", logo: "/assets/satker/sahli-kapolri.png" },
{ name: "SOPS", logo: "/assets/satker/sops.png" },
{ name: "SRENA", logo: "/assets/satker/srena.png" },
{ name: "SESPIM POLRI", logo: "/assets/satker/sespim-polri.png" },
{ name: "SETUPA POLRI", logo: "/assets/satker/setupa-polri.png" },
];
return (
<div className="max-w-screen-xl mx-auto px-4 lg:px-12 py-6">
{/* Header */}
<h2 className="text-center text-2xl font-bold text-gray-800 dark:text-white mb-4">
Liputan <span className="text-[#bb3523]">Satker</span>
</h2>
<div className="h-1 w-48 bg-[#bb3523] mx-auto mb-6 rounded"></div>
{/* Pencarian */}
<div className="flex items-center justify-center gap-4 mb-6">
<input
type="text"
placeholder="Pencarian"
className="w-full max-w-sm px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-[#bb3523] focus:outline-none"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
<button className="px-2 lg:px-4 lg:py-2 bg-[#bb3523] text-white rounded-md hover:bg-red-700">Cari Liputan &gt;</button>
</div>
{/* Grid Wilayah */}
<div className="grid grid-cols-3 md:grid-cols-4 lg:grid-cols-7 gap-6">
{regions.map((region, index) =>
!seeAllValue ? (
index < 7 ? (
<div key={index} className="flex flex-col items-center text-center group">
<div className="relative w-20 h-20 rounded-full border-2 border-[#bb3523] overflow-hidden mb-2 flex items-center justify-center">
<img src={region.logo} alt={region.name} className="w-3/4 h-3/4 object-contain group-hover:scale-110 transition-transform duration-300" />
</div>
<p className="text-md font-semibold">{region.name}</p>
</div>
) : (
""
)
) : (
<div key={index} className="flex flex-col items-center text-center group">
<div className="relative w-20 h-20 rounded-full border-2 border-[#bb3523] overflow-hidden mb-2 flex items-center justify-center">
<img src={region.logo} alt={region.name} className="w-3/4 h-3/4 object-contain group-hover:scale-110 transition-transform duration-300" />
</div>
<p className="text-md font-semibold">{region.name}</p>
</div>
)
)}
</div>
<div className="flex justify-center py-5">
<Button onClick={() => setSeeAllValue(!seeAllValue)} className="bg-white hover:bg-[#bb3523] text-[#bb3523] hover:text-white border-2 border-[#bb3523]">
Lihat Lebih {seeAllValue ? "Sedikit" : "Banyak"}
</Button>
</div>
</div>
);
};
export default Division;

View File

@ -8,9 +8,10 @@ import {
CarouselPrevious,
} from "@/components/ui/carousel";
import Link from "next/link";
import { usePathname, useRouter } from "next/navigation";
import { useParams, usePathname, useRouter } from "next/navigation";
import { Icon } from "@iconify/react/dist/iconify.js";
import { textEllipsis } from "@/utils/globals";
import { generateLocalizedPath } from "@/utils/globals";
const dummyImage = [
{
@ -141,6 +142,8 @@ const NewContent = () => {
const [selectedTab, setSelectedTab] = useState("video");
const router = useRouter();
const pathname = usePathname();
const params = useParams();
const locale = params?.locale;
return (
<div className="px-4 lg:px-16 ">
@ -183,30 +186,22 @@ const NewContent = () => {
<Carousel className="w-full max-w-7xl mx-auto">
<CarouselContent>
{dummyImage.map((image) => (
<CarouselItem
key={image.id}
className="md:basis-1/2 lg:basis-1/3"
>
<img
src={image.thumbnail}
className="h-60 object-cover w-full items-center justify-center cursor-pointer"
/>
<div className="flex flex-row items-center gap-2">
{image.date} {image.time} |{" "}
<Icon icon="formkit:eye" width="15" height="15" /> 518{" "}
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 20 20"
>
<path
fill="#f00"
d="M7.707 10.293a1 1 0 1 0-1.414 1.414l3 3a1 1 0 0 0 1.414 0l3-3a1 1 0 0 0-1.414-1.414L11 11.586V6h5a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h5v5.586zM9 4a1 1 0 0 1 2 0v2H9z"
/>
</svg>{" "}
</div>
<div className="font-semibold w-fit">{image.title}</div>
<CarouselItem key={image.id} className="md:basis-1/2 lg:basis-1/3">
<Link href={generateLocalizedPath(`/video/detail/${image.id}`, String(locale))} className="relative group rounded-md overflow-hidden shadow-md hover:shadow-lg">
<img src={image.thumbnail} className="w-full h-32 lg:h-60 object-cover group-hover:scale-100 transition-transform duration-300" />
<div className="absolute bottom-0 left-0 right-0 bg-gradient-to-r from-black to-slate-500 text-white p-2">
<h1 className="text-sm font-semibold truncate">{image.title}</h1>
<p className="flex flex-row items-center text-sm gap-2">
{image.date} {image.time} | <Icon icon="formkit:eye" width="15" height="15" /> 518{" "}
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 20 20">
<path
fill="#f00"
d="M7.707 10.293a1 1 0 1 0-1.414 1.414l3 3a1 1 0 0 0 1.414 0l3-3a1 1 0 0 0-1.414-1.414L11 11.586V6h5a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h5v5.586zM9 4a1 1 0 0 1 2 0v2H9z"
/>
</svg>{" "}
</p>
</div>
</Link>
</CarouselItem>
))}
</CarouselContent>
@ -264,30 +259,22 @@ const NewContent = () => {
<Carousel>
<CarouselContent>
{dummyImage.map((image) => (
<CarouselItem
key={image.id}
className="md:basis-1/2 lg:basis-1/3"
>
<img
src={image.thumbnail}
className="h-60 object-cover w-full items-center justify-center cursor-pointer"
/>
<div className="flex flex-row items-center gap-2">
{image.date} {image.time} |{" "}
<Icon icon="formkit:eye" width="15" height="15" /> 518{" "}
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 20 20"
>
<path
fill="#f00"
d="M7.707 10.293a1 1 0 1 0-1.414 1.414l3 3a1 1 0 0 0 1.414 0l3-3a1 1 0 0 0-1.414-1.414L11 11.586V6h5a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h5v5.586zM9 4a1 1 0 0 1 2 0v2H9z"
/>
</svg>{" "}
</div>
<div className="font-semibold w-fit">{image.title}</div>
<CarouselItem key={image.id} className="md:basis-1/2 lg:basis-1/3">
<Link href={generateLocalizedPath(`/image/detail/${image.id}`, String(locale))} className="relative group rounded-md overflow-hidden shadow-md hover:shadow-lg">
<img src={image.thumbnail} className="w-full h-32 lg:h-60 object-cover group-hover:scale-100 transition-transform duration-300" />
<div className="absolute bottom-0 left-0 right-0 bg-gradient-to-r from-black to-slate-500 text-white p-2">
<h1 className="text-sm font-semibold truncate">{image.title}</h1>
<p className="flex flex-row items-center text-sm gap-2">
{image.date} {image.time} | <Icon icon="formkit:eye" width="15" height="15" /> 518{" "}
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 20 20">
<path
fill="#f00"
d="M7.707 10.293a1 1 0 1 0-1.414 1.414l3 3a1 1 0 0 0 1.414 0l3-3a1 1 0 0 0-1.414-1.414L11 11.586V6h5a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h5v5.586zM9 4a1 1 0 0 1 2 0v2H9z"
/>
</svg>{" "}
</p>
</div>
</Link>
</CarouselItem>
))}
</CarouselContent>

View File

@ -77,14 +77,21 @@ const PopularContent = () => {
<CarouselContent>
{dummyImage.map((image) => (
<CarouselItem key={image.id} className="md:basis-1/2 lg:basis-1/3">
<img src={image.thumbnail} className="h-60 object-cover w-full items-center justify-center cursor-pointer" />
<Link href={generateLocalizedPath("/video/detail", String(locale))} className="flex flex-row items-center gap-2">
{image.date} {image.time} | <Icon icon="formkit:eye" width="15" height="15" /> 518{" "}
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 20 20">
<path fill="#f00" d="M7.707 10.293a1 1 0 1 0-1.414 1.414l3 3a1 1 0 0 0 1.414 0l3-3a1 1 0 0 0-1.414-1.414L11 11.586V6h5a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h5v5.586zM9 4a1 1 0 0 1 2 0v2H9z" />
</svg>{" "}
<Link href={generateLocalizedPath(`/video/detail/${image.id}`, String(locale))} className="relative group rounded-md overflow-hidden shadow-md hover:shadow-lg">
<img src={image.thumbnail} className="w-full h-32 lg:h-60 object-cover group-hover:scale-100 transition-transform duration-300" />
<div className="absolute bottom-0 left-0 right-0 bg-gradient-to-r from-black to-slate-500 text-white p-2">
<h1 className="text-sm font-semibold truncate">{image.title}</h1>
<p className="flex flex-row items-center text-sm gap-2">
{image.date} {image.time} | <Icon icon="formkit:eye" width="15" height="15" /> 518{" "}
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 20 20">
<path
fill="#f00"
d="M7.707 10.293a1 1 0 1 0-1.414 1.414l3 3a1 1 0 0 0 1.414 0l3-3a1 1 0 0 0-1.414-1.414L11 11.586V6h5a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h5v5.586zM9 4a1 1 0 0 1 2 0v2H9z"
/>
</svg>{" "}
</p>
</div>
</Link>
<div className="font-semibold w-fit">{image.title}</div>
</CarouselItem>
))}
</CarouselContent>
@ -126,14 +133,21 @@ const PopularContent = () => {
<CarouselContent>
{dummyImage.map((image) => (
<CarouselItem key={image.id} className="md:basis-1/2 lg:basis-1/3">
<img src={image.thumbnail} className="h-60 object-cover w-full items-center justify-center cursor-pointer" />
<div className="flex flex-row items-center gap-2">
{image.date} {image.time} | <Icon icon="formkit:eye" width="15" height="15" /> 518{" "}
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 20 20">
<path fill="#f00" d="M7.707 10.293a1 1 0 1 0-1.414 1.414l3 3a1 1 0 0 0 1.414 0l3-3a1 1 0 0 0-1.414-1.414L11 11.586V6h5a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h5v5.586zM9 4a1 1 0 0 1 2 0v2H9z" />
</svg>{" "}
</div>
<div className="font-semibold w-fit">{image.title}</div>
<Link href={generateLocalizedPath(`/image/detail/${image.id}`, String(locale))} className="relative group rounded-md overflow-hidden shadow-md hover:shadow-lg">
<img src={image.thumbnail} className="w-full h-32 lg:h-60 object-cover group-hover:scale-100 transition-transform duration-300" />
<div className="absolute bottom-0 left-0 right-0 bg-gradient-to-r from-black to-slate-500 text-white p-2">
<h1 className="text-sm font-semibold truncate">{image.title}</h1>
<p className="flex flex-row items-center text-sm gap-2">
{image.date} {image.time} | <Icon icon="formkit:eye" width="15" height="15" /> 518{" "}
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 20 20">
<path
fill="#f00"
d="M7.707 10.293a1 1 0 1 0-1.414 1.414l3 3a1 1 0 0 0 1.414 0l3-3a1 1 0 0 0-1.414-1.414L11 11.586V6h5a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h5v5.586zM9 4a1 1 0 0 1 2 0v2H9z"
/>
</svg>{" "}
</p>
</div>
</Link>
</CarouselItem>
))}
</CarouselContent>

View File

@ -25,12 +25,12 @@ const Logo = () => {
if (config.sidebar === "two-column" || !isDesktop) return null;
return (
<Link href="/dashboard/analytics" className="flex gap-2 items-center ">
<Link href="/" className="flex items-center">
{/* <DashCodeLogo className=" text-default-900 h-8 w-8 [&>path:nth-child(3)]:text-background [&>path:nth-child(2)]:text-background" />
{(!config?.collapsed || hovered) && (
<h1 className="text-xl font-semibold text-default-900 ">D</h1>
)} */}
<img src="/../images/all-img/mediahub-logo.png" alt="logo" width={150} />
<img className="w-100" src="/../images/all-img/mediahub-logo.png" alt="logo" width={150} />
</Link>
);
};

View File

@ -11,17 +11,9 @@ const DashCodeFooter = async () => {
<FooterContent>
<div className=' md:flex justify-between text-default-600 hidden'>
<div className="text-center ltr:md:text-start rtl:md:text-right text-sm">
COPYRIGHT &copy; {new Date().getFullYear()} DashCode, All rights Reserved
</div>
<div className="ltr:md:text-right rtl:md:text-end text-center text-sm">
Hand-crafted & Made by{" "}
<a
href="https://codeshaper.net"
target="_blank"
className="text-primary font-semibold"
>
Codeshaper
</a>
COPYRIGHT &copy; {new Date().getFullYear()} Media Hub, All rights Reserved
</div>
</div>
<div className='flex md:hidden justify-around items-center'>

View File

@ -64,7 +64,7 @@ export default function LocalSwitcher() {
<span className='font-medium text-sm text-default-600 dark:text-default-700'>In</span>
</div>
</SelectItem>
<SelectItem value="ar">
{/* <SelectItem value="ar">
<div className='flex items-center gap-1'>
<Image
src="/images/all-img/flag-2.png"
@ -75,7 +75,7 @@ export default function LocalSwitcher() {
/>
<span className='font-medium text-sm text-default-600 dark:text-default-700'>Ar</span>
</div>
</SelectItem>
</SelectItem> */}
</SelectContent>
</Select>

View File

@ -137,7 +137,7 @@ const MenuItem = ({ href, label, icon, active, id, collapsed }: MenuItemProps) =
>
<Link href={href}>
<Icon icon={icon} className={cn('h-5 w-5 ', {
'me-2': !collapsed || hovered
'me-4': !collapsed || hovered
})} />
{(!collapsed || hovered) && (
<p

View File

@ -11,7 +11,7 @@ const MenuWidget = () => {
<div className="dark">
<div className="bg-default-50 mb-16 mt-24 p-4 relative text-center rounded-2xl text-white">
<Image className="mx-auto relative -mt-[73px]" alt="" src="/images/svg/rabit.svg" priority width={99} height={114} />
{/* <Image className="mx-auto relative -mt-[73px]" alt="" src="/images/svg/rabit.svg" priority width={99} height={114} />
<div className="max-w-[160px] mx-auto mt-6">
<div className="">Unlimited Access</div>
<div className="text-xs font-light">
@ -22,7 +22,7 @@ const MenuWidget = () => {
<Button size="sm" fullWidth className=' bg-white text-default-50 hover:bg-background/90'>
Upgrade
</Button>
</div>
</div> */}
</div>
</div>
)

View File

@ -61,7 +61,7 @@ export function MenuClassic({ }) {
return (
<>
{isDesktop && (
<div className="flex items-center justify-between px-4 py-4">
<div className="flex items-center justify-center mt-2 px-4 py-4">
<Logo />
<SidebarHoverToggle />
</div>
@ -71,7 +71,7 @@ export function MenuClassic({ }) {
<ScrollArea className="[&>div>div[style]]:!block" dir={direction}>
{isDesktop && (
{/* {isDesktop && (
<div className={cn(' space-y-3 mt-6 ', {
'px-4': !collapsed || hovered,
'text-center': collapsed || !hovered
@ -81,9 +81,9 @@ export function MenuClassic({ }) {
<SearchBar />
</div>
)}
)} */}
<nav className="mt-8 h-full w-full">
<nav className="mt-4 h-full w-full">
<ul className=" h-full flex flex-col min-h-[calc(100vh-48px-36px-16px-32px)] lg:min-h-[calc(100vh-32px-40px-32px)] items-start space-y-1 px-4">
{menuList?.map(({ groupLabel, menus }, index) => (
<li className={cn("w-full", groupLabel ? "" : "")} key={index}>

View File

@ -31,8 +31,8 @@ const SidebarContent = ({ children }: { children: React.ReactNode }) => {
return (
<aside
onMouseEnter={() => config.sidebar === 'classic' && setHoverConfig({ hovered: true })}
onMouseLeave={() => config.sidebar === 'classic' && setHoverConfig({ hovered: false })}
onMouseEnter={() => config.sidebar === 'draggable' && setHoverConfig({ hovered: true })}
onMouseLeave={() => config.sidebar === 'draggable' && setHoverConfig({ hovered: false })}
className={cn('fixed z-50 w-[248px] bg-sidebar shadow-base xl:block hidden ', sidebarTheme, {
'w-[72px]': config.collapsed && config.sidebar !== 'compact',

View File

@ -11,7 +11,7 @@ const SidebarHoverToggle = () => {
const [config, setConfig] = useConfig();
const isDesktop = useMediaQuery("(min-width: 1280px)");
if (config.sidebar !== 'classic' || !isDesktop) {
if (config.sidebar !== 'draggable' || !isDesktop) {
return null
}

View File

@ -14,7 +14,7 @@ export function SidebarToggle() {
const collapsed = config.collapsed
const isDesktop = useMediaQuery('(min-width: 1280px)')
if (!isDesktop) return null
if (config.sidebar === 'two-column' && !config.hasSubMenu || config.menuHidden || config.layout === "horizontal" || config.sidebar === 'classic') {
if (config.sidebar === 'two-column' && !config.hasSubMenu || config.menuHidden || config.layout === "horizontal" || config.sidebar === 'draggable' ) {
return null
}
if (config.sidebar === 'two-column') {

View File

@ -42,7 +42,7 @@ export const defaultConfig: Config = {
showSwitcher: true,
subMenu: false,
hasSubMenu: false,
sidebarTheme: 'light',
sidebarTheme: 'dark',
headerTheme: 'light',
sidebarBgImage: undefined,
radius: 0.5,

View File

@ -1,3 +1,5 @@
import { getCookiesDecrypt } from "./utils";
export type SubChildren = {
href: string;
label: string;
@ -29,9 +31,14 @@ export type Group = {
};
export function getMenuList(pathname: string, t: any): Group[] {
return [
const roleId = getCookiesDecrypt("urie");
const levelNumber = getCookiesDecrypt("ulne");
const userLevelId = getCookiesDecrypt("ulie");
let menusSelected = [
{
groupLabel: t("dashboard"),
groupLabel: t("apps"),
id: "dashboard",
menus: [
{
@ -51,34 +58,34 @@ export function getMenuList(pathname: string, t: any): Group[] {
{
id: "content",
href: "/content/image",
label: "konten",
label: t("content"),
active: pathname.includes("/content"),
icon: "line-md:youtube",
submenus: [
{
href: "/content/image",
label: "image",
label: t("image"),
active: pathname === "/content/image",
icon: "ic:outline-image",
children: [],
},
{
href: "/content/audio-visual",
label: "audio visual",
label: t("video"),
active: pathname === "/content/audio-visual",
icon: "line-md:youtube",
children: [],
},
{
href: "/content/teks",
label: "teks",
label: t("text"),
active: pathname === "/content/teks",
icon: "heroicons:document",
children: [],
},
{
href: "/content/audio",
label: "audio",
label: t("audio"),
active: pathname === "/content/audio",
icon: "heroicons:share",
children: [],
@ -108,7 +115,7 @@ export function getMenuList(pathname: string, t: any): Group[] {
{
id: "agenda-setting",
href: "/agenda-setting",
label: "agenda setting",
label: t("agenda-setting"),
active: pathname.includes("/agenda-setting"),
icon: "iconoir:journal-page",
submenus: [],
@ -122,7 +129,7 @@ export function getMenuList(pathname: string, t: any): Group[] {
{
id: "planning",
href: "/planning",
label: "perencanaan",
label: t("planning"),
active: pathname.includes("/planning"),
icon: "pajamas:planning",
submenus: [
@ -151,7 +158,7 @@ export function getMenuList(pathname: string, t: any): Group[] {
{
id: "task",
href: "/task",
label: "penugasan",
label: t("task"),
active: pathname.includes("/task"),
icon: "fluent:clipboard-task-add-24-regular",
submenus: [],
@ -165,7 +172,7 @@ export function getMenuList(pathname: string, t: any): Group[] {
{
id: "schedule",
href: "/schedule",
label: "schedule",
label: t("schedule"),
active: pathname.includes("/schedule"),
icon: "uil:schedule",
submenus: [
@ -201,7 +208,7 @@ export function getMenuList(pathname: string, t: any): Group[] {
{
id: "blog",
href: "/blog",
label: "indeks",
label: t("blog"),
active: pathname.includes("/blog"),
icon: "fluent:clipboard-text-32-regular",
submenus: [],
@ -215,7 +222,7 @@ export function getMenuList(pathname: string, t: any): Group[] {
{
id: "curatedcontent",
href: "/curated-content",
label: "kurasi konten",
label: t("curated-content"),
active: pathname.includes("/curated-content"),
icon: "pixelarticons:calendar-text",
submenus: [],
@ -229,7 +236,7 @@ export function getMenuList(pathname: string, t: any): Group[] {
{
id: "communication",
href: "/communication",
label: "komunikasi",
label: t("communication"),
active: pathname.includes("/communication"),
icon: "token:chat",
submenus: [],
@ -243,7 +250,7 @@ export function getMenuList(pathname: string, t: any): Group[] {
{
id: "contest",
href: "/contest",
label: "lomba",
label: t("contest"),
active: pathname.includes("/contest"),
icon: "ic:outline-emoji-events",
submenus: [],
@ -1373,6 +1380,148 @@ export function getMenuList(pathname: string, t: any): Group[] {
],
},
];
if (Number(roleId) == 9) {
menusSelected = [
{
groupLabel: t("apps"),
id: "dashboard",
menus: [
{
id: "dashboard",
href: "/dashboard",
label: t("dashboard"),
active: pathname.includes("/dashboard"),
icon: "material-symbols:dashboard",
submenus: [],
},
],
},
{
groupLabel: "",
id: "ticketing",
menus: [
{
id: "ticketing",
href: "/ticketing",
label: t("ticketing"),
active: pathname.includes("/ticketing"),
icon: "mdi:ticket-outline",
submenus: [],
},
],
},
{
groupLabel: "",
id: "knowledge-base",
menus: [
{
id: "knowledge-base",
href: "/knowledge-base",
label: t("knowledge-base"),
active: pathname.includes("/knowledge-base"),
icon: "hugeicons:knowledge-02",
submenus: [],
},
],
},
{
groupLabel: "",
id: "faq",
menus: [
{
id: "faq",
href: "/frequently-asked-question",
label: t("faq"),
active: pathname.includes("/frequently-asked-question"),
icon: "wpf:faq",
submenus: [],
},
],
},
{
groupLabel: "",
id: "communication",
menus: [
{
id: "communication",
href: "/communication",
label: t("communication"),
active: pathname.includes("/communication"),
icon: "icon-park-outline:communication",
submenus: [
{
href: "/communication/questions",
label: t("questions"),
active: pathname.includes("/communication/questions"),
icon: "solar:inbox-line-outline",
children: [],
},
{
href: "/communication/internal",
label: t("internal"),
active: pathname.includes("/communication/internal"),
icon: "ri:chat-private-line",
children: [],
},
{
href: "/communication/forward",
label: t("forward"),
active: pathname.includes("/communication/forward"),
icon: "ri:share-forward-2-fill",
children: [],
},
{
href: "/communication/collaboration",
label: t("collaboration"),
active: pathname.includes("/communication/collaboration"),
icon: "clarity:employee-group-line",
children: [],
},
{
href: "/communication/account-report",
label: t("account-report"),
active: pathname.includes("/communication/account-report"),
icon: "uiw:user-delete",
children: [],
},
],
},
],
},
{
groupLabel: "",
id: "settings",
menus: [
{
id: "settings",
href: "/settings",
label: t("settings"),
active: pathname.includes("/settings"),
icon: "uil:setting",
submenus: [
{
href: "/settings/feedback",
label: t("feedback"),
active: pathname.includes("/settings/feedback"),
icon: "clarity:employee-group-line",
children: [],
},
{
href: "/settings/social-media",
label: t("social-media"),
active: pathname.includes("/settings/social-media"),
icon: "clarity:employee-group-line",
children: [],
},
],
},
],
}
]
}
return menusSelected;
}
export function getHorizontalMenuList(pathname: string, t: any): Group[] {
return [

View File

@ -125,6 +125,29 @@
},
"Menu": {
"dashboard": "Dashboard",
"content": "Content",
"image": "Image",
"video": "Video",
"audio": "Audio",
"text": "Text",
"agenda-setting": "Agenda Setting",
"task": "Task",
"planning": "Planning",
"schedule": "Schedule",
"curated-content": "Curated Content",
"communication": "Communication",
"contest": "Contest",
"ticketing": "Ticketing",
"knowledge-base": "Knowledge Base",
"faq": "FAQ",
"questions": "Questions",
"internal": "Internal Questions",
"forward": "Forward",
"collaboration": "Collaboration",
"account-report": "Account Report",
"settings": "Settings",
"feedback": "Feedback",
"social-media": "Social media",
"analytics": "Analytics",
"banking": "Banking",
"crm": "Crm",
@ -155,11 +178,9 @@
"utility": "utility",
"blankPage": "Blank Page",
"blog": "Blog",
"faq": "Faq",
"invoice": "Invoice",
"pricing": "Pricing",
"profile": "Profile",
"settings": "Settings",
"elements": "Elements",
"components": "Components",
"avatar": "Avatar",

View File

@ -125,6 +125,29 @@
},
"Menu": {
"dashboard": "Dashboard",
"content": "Konten",
"image": "Foto",
"video": "Audio Visual",
"audio": "Audio",
"text": "Teks",
"agenda-setting": "Agenda Setting",
"task": "Penugasan",
"planning": "Perencanaan",
"schedule": "Jadwal",
"curated-content": "Kurasi Konten",
"communication": "Komunikasi",
"contest": "Kontes",
"ticketing": "Ticketing",
"knowledge-base": "Knowledge Base",
"faq": "FAQ",
"questions": "Questions",
"internal": "Internal Questions",
"forward": "Forward",
"collaboration": "Collaboration",
"account-report": "Account Report",
"settings": "Settings",
"feedback": "Feedback",
"social-media": "Social media",
"analytics": "Analytics",
"banking": "Banking",
"crm": "Crm",
@ -155,11 +178,9 @@
"utility": "utility",
"blankPage": "Blank Page",
"blog": "Blog",
"faq": "Faq",
"invoice": "Invoice",
"pricing": "Pricing",
"profile": "Profile",
"settings": "Settings",
"elements": "Elements",
"components": "Components",
"avatar": "Avatar",

3
package-lock.json generated
View File

@ -6638,6 +6638,7 @@
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
@ -8551,6 +8552,7 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
"integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
"dev": true,
"engines": {
"node": ">=14"
},
@ -13149,6 +13151,7 @@
"version": "3.4.16",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.16.tgz",
"integrity": "sha512-TI4Cyx7gDiZ6r44ewaJmt0o6BrMCT5aK5e0rmJ/G9Xq3w7CX/5VXl/zIPEJZFUK5VEqwByyhqNPycPlvcK4ZNw==",
"dev": true,
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
"arg": "^5.0.2",

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@ -0,0 +1,8 @@
import { title } from "process";
import { httpGetInterceptor } from "../http-config/http-interceptor-service";
export async function ticketingPagination(title: string = '', size: number, page: number) {
return await httpGetInterceptor(
`/ticketing/pagination?enablePage=1&page=${page}&size=${size}&title=${title}`
);
}