Merge branch 'develop' into DimentorinAuth

This commit is contained in:
Naufal Azmi
2025-03-28 19:09:37 +07:00
committed by GitHub
39 changed files with 1451 additions and 380 deletions
@@ -0,0 +1,79 @@
import {
AppstoreOutlined,
AuditOutlined,
LogoutOutlined,
UserOutlined,
} from '@ant-design/icons';
import { Button } from '../../atoms';
import { FC, ReactElement } from 'react';
import { Link, useLocation, useNavigate } from 'react-router-dom';
export const BackofficeSidebar: FC = (): ReactElement => {
const location = useLocation();
const navigate = useNavigate();
const isActive = (path: string) => location.pathname.includes(path);
return (
<aside className="sticky top-0 left-0 w-[280px] bg-white min-h-screen py-[60px] px-[28px] shadow-xl flex flex-col justify-between">
<div className="flex flex-col gap-20 justify-between items-center">
{/* Logo */}
<img src="/logos/simple.svg" alt="IMPHNEN Logo" className="w-[150px]" />
{/* Navigation Menu */}
<nav className="flex flex-col gap-4 w-full">
<Link
to="/dashboard"
className={`flex items-center justify-items-start gap-3 px-[8px] py-[10px] ${
isActive('/dashboard')
? 'bg-primary-500 text-white rounded-md'
: 'text-gray-700 hover:bg-gray-100'
}`}
>
<AppstoreOutlined className="text-[20px]" />
<span className="text-p3 font-medium">Dashboard & Set Gacha</span>
</Link>
<Link
to="/accounts"
className={`flex items-center justify-items-start gap-3 px-[8px] py-[10px] ${
isActive('/accounts')
? 'bg-primary-500 text-white rounded-md'
: 'text-gray-700 hover:bg-gray-100'
}`}
>
<UserOutlined className="text-[20px]" />
<span className="text-p3 font-medium">Data Akun</span>
</Link>
<Link
to="/transactions"
className={`flex items-center justify-items-start gap-3 px-[8px] py-[10px] ${
isActive('/transactions')
? 'bg-primary-500 text-white rounded-md'
: 'text-gray-700 hover:bg-gray-100'
}`}
>
<AuditOutlined className="text-[20px]" />
<span className="text-p3 font-medium">Validasi Transaksi</span>
</Link>
</nav>
</div>
{/* Log Out Button */}
<div className="w-full">
<hr className="mb-5 border-primary-200" />
<Button
onClick={() => {
navigate('/');
}}
variant="text"
className="items-start justify-start gap-3 px-[8px] py-[10px] text-gray-700 hover:text-red-500 transition-colors w-full"
>
<LogoutOutlined className="text-[20px]" />
<span className="text-p3 font-medium">Log Out</span>
</Button>
</div>
</aside>
);
};
@@ -0,0 +1 @@
export * from './backoffice-sidebar'
@@ -0,0 +1,123 @@
import type { Meta, StoryObj } from '@storybook/react';
import DataTable from './datatable';
const meta = {
title: 'Organisms/DataTable',
component: DataTable,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
} satisfies Meta<typeof DataTable>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {
data: [
{
id: 1,
name: 'John Doe',
email: 'john@example.com',
phone: '123-456-7890',
address: '123 Main St',
},
{
id: 2,
name: 'Jane Smith',
email: 'jane@example.com',
phone: '987-654-3210',
address: '456 Elm St',
},
{
id: 3,
name: 'John Smith',
email: 'johns@example.com',
phone: '456-789-1230',
address: '789 Cedar St',
},
],
headers: [
{ label: 'ID', key: 'id' },
{ label: 'Name', key: 'name' },
{ label: 'Email', key: 'email' },
{ label: 'Phone', key: 'phone' },
{ label: 'Address', key: 'address' },
],
onRowClick: (item) => console.log('Row clicked:', item),
},
};
export const WithCustomRender: Story = {
args: {
data: [
{
id: 1,
name: 'John Doe',
email: 'john@example.com',
phone: '123-456-7890',
address: '123 Main St',
status: 'active',
},
{
id: 2,
name: 'Jane Smith',
email: 'jane@example.com',
phone: '987-654-3210',
address: '456 Elm St',
status: 'inactive',
},
{
id: 3,
name: 'John Smith',
email: 'johns@example.com',
phone: '456-789-1230',
address: '789 Cedar St',
status: 'active',
},
],
headers: [
{ label: 'ID', key: 'id' },
{ label: 'Name', key: 'name' },
{ label: 'Email', key: 'email' },
{ label: 'Phone', key: 'phone' },
{
label: 'Status',
render: (item) => (
<span
className={`px-2 py-1 rounded-md text-xs ${
item.status === 'active'
? 'bg-green-100 text-green-800'
: 'bg-red-100 text-red-800'
}`}
>
{item.status}
</span>
),
},
{
label: 'Actions',
render: (item) => (
<button
className="px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600"
onClick={(e) => {
e.stopPropagation();
console.log('Edit item with id:', item.id);
}}
>
Edit
</button>
),
},
],
onRowClick: (item) => console.log('Row clicked:', item),
},
};
export const WithoutCheckbox: Story = {
args: {
...Default.args,
showCheckbox: false,
},
};
@@ -0,0 +1,84 @@
import {
PaginationState,
useReactTable,
getCoreRowModel,
getPaginationRowModel,
flexRender,
ColumnDef,
} from '@tanstack/react-table';
import { Pagination } from '../../molecules';
import React from 'react';
interface DataTableProps<T> {
data: T[];
columns: ColumnDef<T>[];
pageSize?: number;
}
export const DataTable = <T,>({
data,
columns,
pageSize = 9,
}: DataTableProps<T>) => {
const [pagination, setPagination] = React.useState<PaginationState>({
pageIndex: 0,
pageSize,
});
const table = useReactTable({
data,
columns,
state: {
pagination,
},
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
onPaginationChange: setPagination,
});
return (
<div className="flex flex-col gap-8">
<div className="w-full overflow-x-auto">
<table className="w-full min-w-full text-base">
<thead className="bg-primary-50 mb-3 text-left">
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<th
key={header.id}
className="py-3 px-5 font-normal first:rounded-l-lg last:rounded-r-lg"
>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</th>
))}
</tr>
))}
</thead>
<tbody className="mt-3">
{table.getRowModel().rows.map((row) => (
<tr key={row.id} className="bg-primary-100 odd:bg-white">
{row.getVisibleCells().map((cell, index) => (
<td
key={cell.id}
className="py-3 px-5 first:rounded-l-lg last:rounded-r-lg"
>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
<Pagination table={table} />
</div>
);
};
export default DataTable;
+1
View File
@@ -0,0 +1 @@
export * from './datatable';
+3 -1
View File
@@ -1,3 +1,5 @@
export * from './navbar';
export * from "./modals-gacha";
export * from "./auth-banner";
export * from "./auth-banner";
export * from './backoffice-sidebar'
export * from './datatable'