feat: slicing modal for backoffice 'data pengiriman hadiah' page

This commit is contained in:
Hafid Nur
2025-03-31 17:32:30 +07:00
parent ecec423d30
commit 3b979119ed
2 changed files with 227 additions and 150 deletions
@@ -0,0 +1,71 @@
import { Button } from '@imphnen-frontend-service/ui/atoms';
import { InputForm, Modal } from '@imphnen-frontend-service/ui/molecules';
interface IModalProcessDelivery {
isOpen: boolean;
onClose: () => void;
onProcessDelivery?: () => void;
}
const ModalProcessDelivery = ({ isOpen, onClose }: IModalProcessDelivery) => {
return (
<Modal
className="min-w-[400px] bg-primary-50 rounded-lg p-[40px] flex flex-col gap-8 text-center"
isOpen={isOpen}
onClose={onClose}
disableEscapeKeyDown={true}
>
<Modal.Header>
<h2 className="text-p1 font-semibold text-primary-500 mb-3">
Delivery Process
</h2>
<p className="text-p3 text-neutral-400">
Lakukan pengiriman hadiah gacha untuk pengguna di bawah ini, jika
sudah ubah status menjadi Delivered.
</p>
</Modal.Header>
<Modal.Content className="flex flex-col gap-8">
<div className="flex flex-col gap-4">
<InputForm
label="Nama Lengkap"
type="text"
placeholder="Masukkan Nama Lengkap"
value="Ahmad Wiyana"
size="lg"
className="w-full"
/>
<InputForm
label="Item yang didapatkan"
type="text"
placeholder="Masukkan Nama Item"
value="Lanyard + ID Card"
size="lg"
className="w-full"
/>
<InputForm
label="Alamat Pengiriman"
type="text"
placeholder="Masukkan Alamat Pengiriman"
value="Jl. Pantai Cibaduyut Indah"
size="lg"
className="w-full"
/>
<InputForm
label="Status"
type="text"
placeholder="Isi Status Pengiriman"
value="Lanyard + ID Card"
size="lg"
className="w-full"
/>
</div>
<Button variant="primary" size="lg" className="w-full">
Proses Pengiriman
</Button>
</Modal.Content>
</Modal>
);
};
export default ModalProcessDelivery;
+39 -33
View File
@@ -1,6 +1,6 @@
import * as React from 'react';
import { FC, ReactElement, useState } from 'react';
import { FC, Fragment, ReactElement, useState } from 'react';
import {
FilterOutlined,
SearchOutlined,
@@ -17,13 +17,15 @@ import {
useReactTable,
RowSelectionState,
} from '@tanstack/react-table';
import ModalProcessDelivery from './_components/modal-process-item';
type Status = 'valid' | 'invalid' | 'unchecked';
type OrderValid = 'valid' | 'invalid' | 'unchecked';
type Status = 'undelivered' | 'delivered';
interface Prize {
id: number;
name: string;
orderValid: Status;
orderValid: OrderValid;
items: string;
address: string;
status: Status;
@@ -46,17 +48,25 @@ const mockData: Prize[] = Array.from({ length: 90 }, (_, i) => ({
? 'invalid'
: i % 5 === 0
? 'unchecked'
: 'valid') as Status,
: 'valid') as OrderValid,
items: items[i % items.length],
address: 'Jl. Pantai Cibaduyut Indah',
status: (i % 3 === 0
? 'unchecked'
: i % 5 === 0
? 'invalid'
: 'valid') as Status,
status: (i % 3 === 0 ? 'undelivered' : 'delivered') as Status,
}));
const columns: ColumnDef<Prize>[] = [
export const Components: FC = (): ReactElement => {
const [showModalProcessDelivery, setShowModalProcessDelivery] =
useState(false);
const [pagination, setPagination] = React.useState<PaginationState>({
pageIndex: 0,
pageSize: 9,
});
const [rowSelection, setRowSelection] = React.useState<RowSelectionState>({});
const [showFilter, setShowFilter] = useState(false);
const columns: ColumnDef<Prize>[] = [
{
id: 'select',
header: ({ table }) => (
@@ -89,12 +99,12 @@ const columns: ColumnDef<Prize>[] = [
accessorKey: 'orderValid',
cell: ({ row }) => {
const status = row.original.orderValid;
const statusColors: Record<Status, string> = {
const statusColors: Record<OrderValid, string> = {
valid: 'bg-success-200 text-success-500',
invalid: 'bg-danger-200 text-danger-500',
unchecked: 'bg-warning-200 text-warning-900',
};
const statusText: Record<Status, string> = {
const statusText: Record<OrderValid, string> = {
valid: 'Valid',
invalid: 'Invalid',
unchecked: 'Unchecked',
@@ -122,14 +132,12 @@ const columns: ColumnDef<Prize>[] = [
cell: ({ row }) => {
const status = row.original.status;
const statusColors: Record<Status, string> = {
valid: 'bg-success-200 text-success-500',
invalid: 'bg-danger-200 text-danger-500',
unchecked: 'bg-warning-200 text-warning-900',
delivered: 'bg-success-200 text-success-500',
undelivered: 'bg-danger-200 text-danger-500',
};
const statusText: Record<Status, string> = {
valid: 'Valid',
invalid: 'Invalid',
unchecked: 'Unchecked',
delivered: 'Delivered',
undelivered: 'Undelivered',
};
return (
<div
@@ -147,8 +155,7 @@ const columns: ColumnDef<Prize>[] = [
variant="primary"
size="sm"
onClick={(e) => {
e.stopPropagation();
// handleUpdate(row.id);
setShowModalProcessDelivery(true);
}}
className="flex items-center gap-2 w-full"
>
@@ -156,16 +163,7 @@ const columns: ColumnDef<Prize>[] = [
</Button>
),
},
];
export const Components: FC = (): ReactElement => {
const [pagination, setPagination] = React.useState<PaginationState>({
pageIndex: 0,
pageSize: 9,
});
const [rowSelection, setRowSelection] = React.useState<RowSelectionState>({});
const [showFilter, setShowFilter] = useState(false);
];
const table = useReactTable({
data: mockData,
@@ -184,12 +182,12 @@ export const Components: FC = (): ReactElement => {
});
return (
<Fragment>
<main className="w-full px-[48px] py-[40px] flex flex-col gap-8">
{/* Header */}
<header className="bg-white py-4 px-8 rounded-lg shadow p-4">
<h1 className="text-p2 font-semibold">Data Pengiriman Hadiah</h1>
</header>
{/* Account Table Section */}
<section className="flex flex-col gap-6 p-8 bg-white rounded-md">
{/* Search and Filter */}
@@ -203,7 +201,6 @@ export const Components: FC = (): ReactElement => {
<SearchOutlined />
</div>
</div>
<div className="relative">
<Button
variant="primary"
@@ -221,11 +218,20 @@ export const Components: FC = (): ReactElement => {
)}
</div>
</div>
{/* Table */}
<DataTable data={mockData} columns={columns} table={table} />
</section>
</main>
{/* Modal Process Delivery */}
<ModalProcessDelivery
isOpen={showModalProcessDelivery}
onClose={() => setShowModalProcessDelivery(false)}
onProcessDelivery={() => {
console.log('Item added');
}}
/>
</Fragment>
);
};