- Menu
"use client"
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { PlusIcon } from "lucide-react";
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogTitle,
DialogFooter,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { useEffect, useState } from "react";
interface Menuitem {
id_menu: number;
nama_menu: string;
harga: number;
menu_image: string;
id_kategori:number;
}
const Features05Page = () => {
const [menus, setMenu] = useState
- Meja
import { useEffect, useState } from "react";
import { Button } from "../ui/button";
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "../ui/dialog";
import { Input } from "../ui/input";
import { Label } from "@/components/ui/label";
import { PlusIcon } from "lucide-react";
const features = [
{
title: "Identify Opportunities",
description: "Find untapped areas to explore effortlessly.",
},
{
title: "Build Authority",
description: "Craft content that resonates and inspires trust.",
},
{
title: "Instant Insights",
description: "Get actionable insights instantly at a glance.",
},
];
interface MejaItem {
id_meja: number;
no_meja: number;
kapasitas: number;
image_meja: string;
}
const Features02Page = () => {
const [mejas, setMeja] = useState([]);
const [no_meja, setNomeja] = useState("");
const [id_meja, setIDMeja] = useState("");
const [kapasitas, setKapasitas] = useState("");
const [imageMeja, setImageMeja] = useState(null);
const [open, setOpen] = useState(false);
useEffect(() => {
const token = localStorage.getItem("adminToken");
try {
fetch("http://127.0.0.1:8000/api/meja/", {
headers: {
Authorization: `Bearer ${token}`,
},
})
.then((response) => response.json())
.then((data: MejaItem[]) => setMeja(data))
.catch((error) => console.log("error ", error));
} catch (error) {
console.log("error ", error);
}
}, []);
const handleSubmit = async () => {
const token = localStorage.getItem("adminToken");
const newForm = new FormData();
newForm.append("no_meja", no_meja);
newForm.append("kapasitas", kapasitas);
if (imageMeja) {
newForm.append("image_meja", imageMeja);
}
try {
const response = await fetch("http://127.0.0.1:8000/api/meja/", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
},
body: newForm,
});
if (!response.ok) {
throw new Error("Gagal menambahkan meja");
}
const data = await response.json();
setMeja((prev) => [...prev, data]);
setNomeja("");
setKapasitas("");
setImageMeja(null);
setOpen(false);
} catch (error) {
console.log(error);
}
};
return (
Daftar Meja
{mejas.map((meja) => (
Nomer Meja : {meja.no_meja}
Kapasitas : {meja.kapasitas}
))}
);
};
export default Features02Page;
- Reservasi
// page
"use client"
import React from "react"
import { ReservationTable } from "./data-table"
export default function ReservationPage() {
return (
Reservation List
)
}
// column.tsx
import { ColumnDef } from "@tanstack/react-table"
import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import { ArrowUpDown, Edit, Trash2 } from "lucide-react"
import { Reservation } from "./data-table"
export function getReservationColumns(
handleUpdateClick: (reservation: Reservation) => void,
handleDeleteClick: (reservation: Reservation) => void
): ColumnDef[] {
return [
{
id: "select",
header: ({ table }) => (
table.toggleAllPageRowsSelected(!!value)}
aria-label="Select all"
/>
),
cell: ({ row }) => (
row.toggleSelected(!!value)}
aria-label="Select row"
/>
),
enableSorting: false,
enableHiding: false,
},
{
header: "ID",
cell: ({ row }) => {row.index + 1}
,
},
{
accessorKey: "nama_customer",
header: ({ column }) => (
),
cell: ({ row }) => {row.getValue("nama_customer")}
,
},
{
accessorKey: "tanggal_reservasi",
header: ({ column }) => (
),
cell: ({ row }) => {
const date = new Date(row.getValue("tanggal_reservasi"))
return {date.toLocaleDateString("en-GB")}
},
},
{
accessorKey: "status",
header: "Status",
cell: ({ row }) => {
const status = row.getValue("status") as string
const statusClass = {
booked: "text-blue-600",
confirmed: "text-green-600",
pending: "text-amber-600",
cancelled: "text-red-600",
}[status.toLowerCase()] || ""
return {status}
},
},
{
accessorKey: "id_meja",
header: "Table No.",
cell: ({ row }) => Table {row.getValue("id_meja")}
,
},
{
id: "actions",
enableHiding: false,
header: "Actions",
cell: ({ row }) => {
const reservation = row.original
return (
)
},
},
]
}
// data table
"use client";
import React, { use, useState } from "react";
import {
ColumnFiltersState,
SortingState,
VisibilityState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table";
import { Input } from "@/components/ui/input";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { getReservationColumns } from "./column";
import { Button } from "@/components/ui/button";
import { PlusIcon } from "lucide-react";
import {
Dialog,
DialogContent,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { DialogFooter, DialogHeader } from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import { log } from "console";
import { Select, SelectContent, SelectItem } from "@/components/ui/select";
import { SelectTrigger, SelectValue } from "@radix-ui/react-select";
export type Reservation = {
id_reservasi: number;
nama_customer: string;
tanggal_reservasi: string;
status: string;
id_meja: number;
id_admin: number;
};
export function ReservationTable() {
const [data, setData] = React.useState([]);
const [loading, setLoading] = React.useState(true);
const [error, setError] = React.useState(null);
const [sorting, setSorting] = React.useState([]);
const [columnFilters, setColumnFilters] = React.useState(
[]
);
const [columnVisibility, setColumnVisibility] =
React.useState({});
const [rowSelection, setRowSelection] = React.useState({});
const [id_admin, setIdAdmin] = useState("");
const [nama_customer, setNama] = useState("");
const [tanggal_reservasi, setTanggal] = useState("");
const [status, setStatus] = useState("");
const [id_meja, setMeja] = useState("");
const fetchReservations = async () => {
try {
setLoading(true);
const token = localStorage.getItem("adminToken");
const response = await fetch("http://localhost:8000/api/reservasi/", {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
});
if (!response.ok) throw new Error("Failed to fetch reservation data");
const result = await response.json();
setData(Array.isArray(result) ? result : [result]);
} catch (err) {
setError("Failed to load reservations. Please try again later.");
} finally {
setLoading(false);
}
};
React.useEffect(() => {
fetchReservations();
}, []);
const handleSubmit = async () => {
const formData = new FormData();
formData.append("id_admin", id_admin);
formData.append("nama_customer", nama_customer);
formData.append("tanggal_reservasi", tanggal_reservasi);
formData.append("status", status);
formData.append("id_meja", id_meja);
const token = localStorage.getItem("adminToken");
try {
const response = await fetch("http://127.0.0.1:8000/api/reservasi/", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
},
body: formData,
});
if (!response.ok) {
throw new Error("Gagal menambahkan reservasi");
}
const data = await response.json();
setData((prev) => [...prev, data]);
setIdAdmin("");
setNama("");
setStatus("");
setTanggal("");
setMeja("");
} catch (err) {
console.log("Error ", err);
}
};
const columns = getReservationColumns(
(r) => console.log("Update", r),
(r) => console.log("Delete", r)
);
const table = useReactTable({
data,
columns,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
},
});
if (loading)
return (
Loading reservation data...
);
if (error)
return (
{error}
);
return (
{table.getHeaderGroups().map((headerGroup) => (
{headerGroup.headers.map((header) => (
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
))}
))}
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
{row.getVisibleCells().map((cell) => (
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
))}
))
) : (
No results.
)}
);
}
- Report
'use client'
import ProductCard from "@/components/reportcard"
import { DataTableDemo } from "./table"
export default function Report(){
return(
)
}
// table.tsx
"use client"
import React, { useEffect, useState } from "react"
import {
ColumnDef,
ColumnFiltersState,
SortingState,
VisibilityState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table"
import { ArrowUpDown, ChevronDown, MoreHorizontal } from "lucide-react"
import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { Input } from "@/components/ui/input"
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table"
// 1. Tipe data
export type Payment = {
id: string
nama_customer: string
grand_total: number
status_pembayaran: "Pending" | "Processing" | "Success" | "Failed"
}
// 2. Kolom tetap sama
export const columns: ColumnDef[] = [
{
id: "select",
header: ({ table }) => (
table.toggleAllPageRowsSelected(!!value)}
aria-label="Select all"
/>
),
cell: ({ row }) => (
row.toggleSelected(!!value)}
aria-label="Select row"
/>
),
enableSorting: false,
enableHiding: false,
},
{
accessorKey: "status_pembayaran",
header: "Status",
cell: ({ row }) => (
{row.getValue("status_pembayaran")}
),
},
{
accessorKey: "nama_customer",
header: ({ column }) => (
),
cell: ({ row }) => {row.getValue("nama_customer")}
,
},
{
accessorKey: "grand_total",
header: () => Amount
,
cell: ({ row }) => {
const amount = parseFloat(row.getValue("grand_total"))
return {amount}
},
},
{
id: "actions",
enableHiding: false,
cell: ({ row }) => {
const payment = row.original
return (
Actions
navigator.clipboard.writeText(payment.id)}
>
Copy payment ID
View customer
View payment details
)
},
},
]
// 3. Komponen utama
export function DataTableDemo() {
const [data, setData] = useState([])
const [loading, setLoading] = useState(true)
const [sorting, setSorting] = useState([])
const [columnFilters, setColumnFilters] = useState([])
const [columnVisibility, setColumnVisibility] = useState({})
const [rowSelection, setRowSelection] = useState({})
// 4. Fetch API saat mount
useEffect(() => {
const fetchData = async () => {
const token = localStorage.getItem("adminToken")
try {
const res = await fetch("http://127.0.0.1:8000/api/report/",{
headers:{
Authorization : `Bearer ${token}`
}
})
const json = await res.json()
setData(json)
} catch (error) {
console.error("Failed to fetch data", error)
} finally {
setLoading(false)
}
}
fetchData()
}, [])
const table = useReactTable({
data,
columns,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
},
})
return (
table.getColumn("nama_customer")?.setFilterValue(event.target.value)
}
className="max-w-sm"
/>
{table
.getAllColumns()
.filter((column) => column.getCanHide())
.map((column) => (
column.toggleVisibility(!!value)
}
>
{column.id}
))}
{table.getHeaderGroups().map((headerGroup) => (
{headerGroup.headers.map((header) => (
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
))}
))}
{loading ? (
Loading...
) : table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
{row.getVisibleCells().map((cell) => (
{flexRender(cell.column.columnDef.cell, cell.getContext())}
))}
))
) : (
No results.
)}
{table.getFilteredSelectedRowModel().rows.length} of{" "}
{table.getFilteredRowModel().rows.length} row(s) selected.
)
}