feat:add table penugasan,perencanaan,indeks,agenda setting

This commit is contained in:
Anang Yusman 2024-11-29 19:41:23 +07:00
parent 655c72ee25
commit 73cc425d6a
16 changed files with 1553 additions and 88 deletions

View File

@ -12,26 +12,27 @@ import { Calendar } from "@/components/ui/calendar";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { Plus } from "lucide-react";
import { Checkbox } from "@/components/ui/checkbox";
import { CalendarEvent, CalendarCategory } from "./data"
import {
EventContentArg,
} from '@fullcalendar/core'
import { CalendarEvent, CalendarCategory } from "./data";
import { EventContentArg } from "@fullcalendar/core";
import EventModal from "./event-modal";
import { useTranslations } from "next-intl";
const wait = () => new Promise((resolve) => setTimeout(resolve, 1000));
interface CalendarViewProps {
events: CalendarEvent[];
categories: CalendarCategory[];
}
const CalendarView = ({ events, categories }: CalendarViewProps) => {
const [selectedCategory, setSelectedCategory] = useState<string[] | null>(null);
const [selectedCategory, setSelectedCategory] = useState<string[] | null>(
null
);
const [selectedEventDate, setSelectedEventDate] = useState<Date | null>(null);
const [selectedEvent, setSelectedEvent] = useState<CalendarEvent | null>(null);
const [draggableInitialized, setDraggableInitialized] = useState<boolean>(false);
const t = useTranslations("CalendarApp")
const [selectedEvent, setSelectedEvent] = useState<CalendarEvent | null>(
null
);
const [draggableInitialized, setDraggableInitialized] =
useState<boolean>(false);
const t = useTranslations("CalendarApp");
// event canvas state
const [sheetOpen, setSheetOpen] = useState<boolean>(false);
const [date, setDate] = React.useState<Date>(new Date());
@ -103,30 +104,22 @@ const t = useTranslations("CalendarApp")
if (selectedCategory && selectedCategory.includes(category)) {
setSelectedCategory(selectedCategory.filter((c) => c !== category));
} else {
setSelectedCategory([...selectedCategory || [], category]);
setSelectedCategory([...(selectedCategory || []), category]);
}
};
const handleClassName = (arg: EventContentArg) => {
if (arg.event.extendedProps.calendar === "holiday") {
if (arg.event.extendedProps.calendar === "national") {
return "destructive";
}
else if (arg.event.extendedProps.calendar === "business") {
} else if (arg.event.extendedProps.calendar === "polda") {
return "primary";
} else if (arg.event.extendedProps.calendar === "personal") {
} else if (arg.event.extendedProps.calendar === "polres") {
return "success";
} else if (arg.event.extendedProps.calendar === "family") {
} else if (arg.event.extendedProps.calendar === "international") {
return "info";
} else if (arg.event.extendedProps.calendar === "etc") {
return "info";
} else if (arg.event.extendedProps.calendar === "meeting") {
return "warning";
}
else {
} else {
return "primary";
}
};
const filteredEvents = events?.filter((event) =>
@ -144,7 +137,7 @@ const t = useTranslations("CalendarApp")
className="dark:bg-background dark:text-foreground"
>
<Plus className="w-4 h-4 me-1" />
{t("addEvent")}
{"Tambahkan Agenda baru"}
</Button>
</CardHeader>
<div className="px-3">
@ -160,14 +153,14 @@ const t = useTranslations("CalendarApp")
<div id="external-events" className=" space-y-1.5 mt-6 px-4">
<p className="text-sm font-medium text-default-700 mb-3">
{t("shortDesc")}
{t("shortDesc")}
</p>
{dragEvents.map((event) => (
<ExternalDraggingevent key={event.id} event={event} />
))}
</div>
<div className="py-4 text-default-800 font-semibold text-xs uppercase mt-4 mb-2 px-4">
{t("filter")}
{t("filter")}
</div>
<ul className="space-y-3 px-4">
<li className=" flex gap-3">

View File

@ -10,14 +10,14 @@ const nextMonth = date.getMonth() === 11 ? new Date(date.getFullYear() + 1, 0, 1
const prevMonth = date.getMonth() === 11 ? new Date(date.getFullYear() - 1, 0, 1) : new Date(date.getFullYear(), date.getMonth() - 1, 1)
export const calendarEvents = [
{
id: faker.string.uuid() ,
id: faker.string.uuid(),
title: "All Day Event",
start: date,
end: nextDay,
allDay: false,
//className: "warning",
extendedProps: {
calendar: "business",
calendar: "polda",
},
},
{
@ -28,7 +28,7 @@ export const calendarEvents = [
allDay: true,
//className: "success",
extendedProps: {
calendar: "personal",
calendar: "national",
},
},
{
@ -39,7 +39,7 @@ export const calendarEvents = [
end: new Date(date.getFullYear(), date.getMonth() + 1, -7),
// className: "info",
extendedProps: {
calendar: "family",
calendar: "polres",
},
},
{
@ -50,7 +50,7 @@ export const calendarEvents = [
allDay: true,
//className: "primary",
extendedProps: {
calendar: "meeting",
calendar: "polres",
},
},
{
@ -61,7 +61,7 @@ export const calendarEvents = [
allDay: true,
// className: "danger",
extendedProps: {
calendar: "holiday",
calendar: "polda",
},
},
{
@ -72,84 +72,65 @@ export const calendarEvents = [
allDay: true,
//className: "primary",
extendedProps: {
calendar: "business",
calendar: "international",
},
},
];
export const calendarCategories = [
export const calendarCategories = [
{
label: "Business",
value: "business",
label: "Nasional",
value: "national",
activeClass: "ring-primary-500 bg-primary-500",
className: "group-hover:border-blue-500",
},
{
label: "Personal",
value: "personal",
label: "Polda",
value: "polda",
activeClass: "ring-success-500 bg-success-500",
className: " group-hover:border-green-500",
},
{
label: "Holiday",
value: "holiday",
label: "Polres",
value: "polres",
activeClass: "ring-danger-500 bg-danger-500",
className: " group-hover:border-red-500",
},
{
label: "Family",
value: "family",
label: "Internasional",
value: "international",
activeClass: "ring-info-500 bg-info-500",
className: " group-hover:border-cyan-500",
},
{
label: "Meeting",
value: "meeting",
activeClass: "ring-warning-500 bg-warning-500",
className: " group-hover:border-yellow-500",
},
{
label: "Etc",
value: "etc",
activeClass: "ring-info-500 bg-info-500",
className: " group-hover:border-cyan-500",
}
];
export const categories = [
{
label: "Business",
value: "business",
className: "data-[state=checked]:bg-primary data-[state=checked]:ring-primary",
label: "Nasional",
value: "national",
className:
"data-[state=checked]:bg-primary data-[state=checked]:ring-primary",
},
{
label: "Personal",
value: "personal",
label: "Polda",
value: "polda",
className: "data-[state=checked]:bg-success data-[state=checked]:ring-success",
className:
"data-[state=checked]:bg-success data-[state=checked]:ring-success",
},
{
label: "Holiday",
value: "holiday",
className: "data-[state=checked]:bg-destructive data-[state=checked]:ring-destructive ",
label: "Polres",
value: "polres",
className:
"data-[state=checked]:bg-destructive data-[state=checked]:ring-destructive ",
},
{
label: "Family",
value: "family",
label: "Internasional",
value: "international",
className: "data-[state=checked]:bg-info data-[state=checked]:ring-info ",
},
{
label: "Meeting",
value: "meeting",
className: "data-[state=checked]:bg-warning data-[state=checked]:ring-warning",
},
{
label: "Etc",
value: "etc",
className: "data-[state=checked]:bg-info data-[state=checked]:ring-info",
}
];
export type CalendarEvent = (typeof calendarEvents)[number]
export type CalendarCategory = (typeof calendarCategories)[number]
export type Category = (typeof categories)[number]
export type CalendarEvent = (typeof calendarEvents)[number];
export type CalendarCategory = (typeof calendarCategories)[number];
export type Category = (typeof categories)[number];

View File

@ -1,5 +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/mediahub-table";
const BlogPage = async () => {
return <div></div>;
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,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,284 @@
"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 = {
title: string;
category: string;
date: string;
tag: string;
status: string;
};
import { data } from "./data";
import { Input } from "@/components/ui/input";
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
export const columns: ColumnDef<CompanyData>[] = [
{
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: "category",
header: "Kategori ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("category")}</span>
),
},
{
accessorKey: "date",
header: "Tanggal Unggah ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("date")}</span>
),
},
{
accessorKey: "tag",
header: "Tag ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("tag")}</span>
),
},
{
accessorKey: "status",
header: "Status",
cell: ({ row }) => {
return (
<span className="whitespace-nowrap text-blue-600">
{row.getValue("status")}
</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 [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: 6,
});
const table = useReactTable({
data,
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,
},
});
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-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>
);
};
export default BlogTable;

View File

@ -15,19 +15,19 @@ const RecentActivity = () => {
<div className="flex flex-col gap-5">
<div className="flex flex-row items-center gap-3">
<ImageIcon size={40} className="text-blue-700" />
<p className="text-2xl">0 FOTO</p>
<p className="text-xl">0 FOTO</p>
</div>
<div className="flex flex-row items-center gap-3">
<YoutubeIcon size={40} className="text-blue-700" />
<p className="text-2xl">0 AUDIO VISUAL</p>
<p className="text-xl">0 AUDIO VISUAL</p>
</div>
<div className="flex flex-row items-center gap-3">
<DockIcon size={40} className="text-blue-700" />
<p className="text-2xl">0 TEXT</p>
<p className="text-xl">0 TEXT</p>
</div>
<div className="flex flex-row items-center gap-3">
<MicIcon size={40} className="text-blue-700" />
<p className="text-2xl">0 AUDIO</p>
<p className="text-xl">0 AUDIO</p>
</div>
</div>
);

View File

@ -45,7 +45,7 @@ const DashboardPage = () => {
<div className="lg:col-span-4 col-span-12">
<Card>
<CardHeader className="flex flex-row items-center">
<CardTitle className="flex-1">
<CardTitle className="flex-1 text-lg">
{"Total Produksi Konten"}
</CardTitle>
<DashboardDropdown />

View File

@ -1,5 +1,30 @@
import SiteBreadcrumb from "@/components/site-breadcrumb";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { UploadIcon } from "lucide-react";
import TaskTable from "../../task/table-task/task-table";
import MediahubTable from "./table-mediahub/mediahub-table";
const MediahubPage = async () => {
return <div></div>;
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">
Perencanaan : Kanal MediaHub
</div>
</div>
</Card>
<Card>
<CardContent className="p-0">
<MediahubTable />
</CardContent>
</Card>
</div>
</div>
);
};
export default MediahubPage;

View File

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

View File

@ -0,0 +1,268 @@
"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 = {
title: string;
date: string;
status: string;
};
import { data } from "./data";
import { Input } from "@/components/ui/input";
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
export const columns: ColumnDef<CompanyData>[] = [
{
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: "date",
header: "Tanggal Unggah ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("date")}</span>
),
},
{
accessorKey: "status",
header: "Status",
cell: ({ row }) => {
return (
<span className="whitespace-nowrap text-blue-600">
{row.getValue("status")}
</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 MediahubTable = () => {
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: 6,
});
const table = useReactTable({
data,
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,
},
});
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-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>
);
};
export default MediahubTable;

View File

@ -1,5 +1,27 @@
import SiteBreadcrumb from "@/components/site-breadcrumb";
import { Card, CardContent } from "@/components/ui/card";
import MedsosTable from "./table-medsos/medsos-table";
const MedsosMediahubPage = async () => {
return <div></div>;
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">
Perencanaan : Kanal Medsos
</div>
</div>
</Card>
<Card>
<CardContent className="p-0">
<MedsosTable />
</CardContent>
</Card>
</div>
</div>
);
};
export default MedsosMediahubPage;

View File

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

View File

@ -0,0 +1,268 @@
"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 = {
title: string;
date: string;
status: string;
};
import { data } from "./data";
import { Input } from "@/components/ui/input";
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
export const columns: ColumnDef<CompanyData>[] = [
{
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: "date",
header: "Tanggal Unggah ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("date")}</span>
),
},
{
accessorKey: "status",
header: "Status",
cell: ({ row }) => {
return (
<span className="whitespace-nowrap text-blue-600">
{row.getValue("status")}
</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 MedsosTable = () => {
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: 6,
});
const table = useReactTable({
data,
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,
},
});
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-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>
);
};
export default MedsosTable;

View File

@ -1,5 +1,35 @@
import { Card, CardContent } from "@/components/ui/card";
import TaskTable from "./table-task/task-table";
import { Button } from "@/components/ui/button";
import { UploadIcon } from "lucide-react";
import SiteBreadcrumb from "@/components/site-breadcrumb";
const TaskPage = async () => {
return <div></div>;
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 Penugasan
</div>
<div>
<Button color="primary" className="text-white">
<UploadIcon />
Buat Penugasan
</Button>
</div>
</div>
</Card>
<Card>
<CardContent className="p-0">
<TaskTable />
</CardContent>
</Card>
</div>
</div>
);
};
export default TaskPage;

View File

@ -0,0 +1,106 @@
export const data = [
{
title: "Giat Pimpinan",
code: "PNMH-1287",
status: "paid",
date: "$231.26",
category: "amplifikasi",
typeTask: "Mediahub",
},
{
title: "Liputan Kegiatan",
code: "PNMH-1287",
status: "due",
date: "$432.81",
category: "amplifikasi",
typeTask: "Mediahub",
},
{
title: "Giat Pimpinan",
code: "PNMH-1287",
status: "due",
date: "$437.65",
category: "amplifikasi",
typeTask: "Mediahub",
},
{
title: "Pers Rilis",
code: "PNMH-1287",
status: "canceled",
date: "$387.55",
category: "amplifikasi",
typeTask: "Mediahub",
},
{
title: "Giat Pimpinan",
code: "PNMH-1287",
status: "canceled",
date: "$489.80",
category: "amplifikasi",
typeTask: "Mediahub",
},
{
title: "Liputan Kegiatan",
code: "PNMH-1287",
status: "canceled",
date: "$421.45",
category: "amplifikasi",
typeTask: "Mediahub",
},
{
title: "Pers Rilis",
code: "PNMH-1287",
status: "canceled",
date: "$207.61",
category: "amplifikasi",
typeTask: "Mediahub",
},
{
title: "Giat Pimpinan",
code: "PNMH-1287",
status: "paid",
date: "$392.86",
category: "amplifikasi",
typeTask: "Mediahub",
},
{
title: "Pers Rilis",
code: "PNMH-1287",
status: "paid",
date: "$162.87",
category: "amplifikasi",
typeTask: "Mediahub",
},
{
title: "Giat Pimpinan",
code: "PNMH-1287",
status: "paid",
date: "$268.58",
category: "amplifikasi",
typeTask: "Mediahub",
},
{
title: "Liputan Kegiatan",
code: "PNMH-1287",
status: "paid",
date: "$369.19",
category: "amplifikasi",
typeTask: "Mediahub",
},
{
title: "Liputan Kegiatan",
code: "PNMH-1287",
status: "paid",
date: "$420.87",
category: "amplifikasi",
typeTask: "Mediahub",
},
{
title: "Giat Pimpinan",
code: "PNMH-1287",
status: "paid",
date: "$420.26",
category: "amplifikasi",
typeTask: "Mediahub",
},
];

View File

@ -0,0 +1,298 @@
"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 = {
title: string;
code: string;
typeTask: string;
category: string;
date: string;
status: string;
};
import { data } from "./data";
import { Input } from "@/components/ui/input";
import { InputGroup, InputGroupText } from "@/components/ui/input-group";
export const columns: ColumnDef<CompanyData>[] = [
{
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: "code",
header: "Kode ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("code")}</span>
),
},
{
accessorKey: "typeTask",
header: "Kode ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("typeTask")}</span>
),
},
{
accessorKey: "category",
header: "Jenis Tugas ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("category")}</span>
),
},
{
accessorKey: "date",
header: "Tanggal Unggah ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("date")}</span>
),
},
{
accessorKey: "status",
header: "Status",
cell: ({ row }) => {
const statusColors: Record<CompanyData["status"], string> = {
paid: "bg-success/20 text-success",
due: "bg-warning/20 text-warning",
canceled: "bg-destructive/20 text-destructive",
};
const status = row.getValue<CompanyData["status"]>("status");
return (
<Badge className={cn("rounded-full px-5", statusColors[status])}>
{status}
</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 TaskTable = () => {
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: 6,
});
const table = useReactTable({
data,
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,
},
});
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-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>
);
};
export default TaskTable;