- {/* Summary Cards */}
- {[1, 2, 3, 4].map((item) => (
-
-
-
-
1000
-
- Total Participants
-
-
+ {/* Participants */}
+
+
+ {/* Roll and Reroll */}
+
+
+
+
+
+
1000
+
+ Roll and Reroll
+
+
+
+
+ {/* Redeem */}
+
+
+ {/* Inactive Users */}
+
+
+
+
+
+
1000
+
Inactive Users
+
+
@@ -78,7 +112,7 @@ export const Components: FC = (): ReactElement => {
Delete
@@ -87,7 +121,7 @@ export const Components: FC = (): ReactElement => {
{/* Lebih baik gunakan gambar yang sudah di-clip dengan size height: 78px daripada hard-code object-position dan margin */}
@@ -99,7 +133,7 @@ export const Components: FC = (): ReactElement => {
{/* Right-side illustration */}
diff --git a/apps/backoffice/src/app/prizes/layout.tsx b/apps/backoffice/src/app/prizes/layout.tsx
new file mode 100644
index 0000000..a770c99
--- /dev/null
+++ b/apps/backoffice/src/app/prizes/layout.tsx
@@ -0,0 +1,18 @@
+import { FC, ReactElement } from 'react';
+import { Outlet } from 'react-router-dom';
+import { BackofficeSidebar } from '@imphnen-frontend-service/ui/organisms';
+
+export const AppLayout: FC = (): ReactElement => {
+ return (
+
+ );
+};
+
+export default AppLayout;
diff --git a/apps/backoffice/src/app/prizes/page.tsx b/apps/backoffice/src/app/prizes/page.tsx
new file mode 100644
index 0000000..f7828c4
--- /dev/null
+++ b/apps/backoffice/src/app/prizes/page.tsx
@@ -0,0 +1,232 @@
+import * as React from 'react';
+
+import { FC, ReactElement, useState } from 'react';
+import {
+ FilterOutlined,
+ SearchOutlined,
+ AuditOutlined,
+} from '@ant-design/icons';
+import { Button, Input } from '@imphnen-frontend-service/ui/atoms';
+import { DataTable, Filter } from '@imphnen-frontend-service/ui/organisms';
+
+import {
+ ColumnDef,
+ getCoreRowModel,
+ getPaginationRowModel,
+ PaginationState,
+ useReactTable,
+ RowSelectionState,
+} from '@tanstack/react-table';
+
+type Status = 'valid' | 'invalid' | 'unchecked';
+
+interface Prize {
+ id: number;
+ name: string;
+ orderValid: Status;
+ items: string;
+ address: string;
+ status: Status;
+}
+
+const items = [
+ 'Sertifikat + Laminating',
+ 'Lanyard + ID Card',
+ 'Pin',
+ 'Sticker Isi 3',
+ 'Sticker Isi 5',
+ 'Gelang Karet',
+];
+
+// Mock data for transactions
+const mockData: Prize[] = Array.from({ length: 90 }, (_, i) => ({
+ id: i + 1,
+ name: 'Nama Lengkap',
+ orderValid: (i % 3 === 0
+ ? 'invalid'
+ : i % 5 === 0
+ ? 'unchecked'
+ : 'valid') as Status,
+ items: items[i % items.length],
+ address: 'Jl. Pantai Cibaduyut Indah',
+ status: (i % 3 === 0
+ ? 'unchecked'
+ : i % 5 === 0
+ ? 'invalid'
+ : 'valid') as Status,
+}));
+
+const columns: ColumnDef
[] = [
+ {
+ id: 'select',
+ header: ({ table }) => (
+
+ ),
+ cell: ({ row }) => (
+
+ ),
+ },
+ {
+ header: 'No',
+ accessorKey: 'id',
+ },
+ {
+ header: 'Nama Lengkap',
+ accessorKey: 'name',
+ },
+ {
+ header: 'Order Valid?',
+ accessorKey: 'orderValid',
+ cell: ({ row }) => {
+ const status = row.original.orderValid;
+ const statusColors: Record = {
+ valid: 'bg-success-200 text-success-500',
+ invalid: 'bg-danger-200 text-danger-500',
+ unchecked: 'bg-warning-200 text-warning-900',
+ };
+ const statusText: Record = {
+ valid: 'Valid',
+ invalid: 'Invalid',
+ unchecked: 'Unchecked',
+ };
+ return (
+
+ {statusText[status]}
+
+ );
+ },
+ },
+ {
+ header: 'Items',
+ accessorKey: 'items',
+ },
+ {
+ header: 'Alamat Pengiriman',
+ accessorKey: 'address',
+ },
+ {
+ header: 'Status',
+ accessorKey: 'status',
+ cell: ({ row }) => {
+ const status = row.original.status;
+ const statusColors: Record = {
+ valid: 'bg-success-200 text-success-500',
+ invalid: 'bg-danger-200 text-danger-500',
+ unchecked: 'bg-warning-200 text-warning-900',
+ };
+ const statusText: Record = {
+ valid: 'Valid',
+ invalid: 'Invalid',
+ unchecked: 'Unchecked',
+ };
+ return (
+
+ {statusText[status]}
+
+ );
+ },
+ },
+ {
+ header: 'Action',
+ cell: ({ row }) => (
+ {
+ e.stopPropagation();
+ // handleUpdate(row.id);
+ }}
+ className="flex items-center gap-2 w-full"
+ >
+ Process
+
+ ),
+ },
+];
+
+export const Components: FC = (): ReactElement => {
+ const [pagination, setPagination] = React.useState({
+ pageIndex: 0,
+ pageSize: 9,
+ });
+
+ const [rowSelection, setRowSelection] = React.useState({});
+ const [showFilter, setShowFilter] = useState(false);
+
+ const table = useReactTable({
+ data: mockData,
+ columns,
+ state: {
+ pagination,
+ rowSelection,
+ },
+ enableRowSelection: true,
+ onRowSelectionChange: setRowSelection,
+ getCoreRowModel: getCoreRowModel(),
+ getPaginationRowModel: getPaginationRowModel(),
+ onPaginationChange: setPagination,
+ pageCount: Math.ceil(mockData.length / pagination.pageSize),
+ manualPagination: false,
+ });
+
+ return (
+
+ {/* Header */}
+
+ Data Pengiriman Hadiah
+
+
+ {/* Account Table Section */}
+
+ {/* Search and Filter */}
+
+
+
+
+
setShowFilter(!showFilter)}
+ >
+
+ Filters
+
+ {showFilter && (
+
+ setShowFilter(false)} />
+
+ )}
+
+
+
+ {/* Table */}
+
+
+
+ );
+};
+
+export default Components;
diff --git a/apps/backoffice/src/app/transactions/layout.tsx b/apps/backoffice/src/app/transactions/layout.tsx
index 5d2c643..a770c99 100644
--- a/apps/backoffice/src/app/transactions/layout.tsx
+++ b/apps/backoffice/src/app/transactions/layout.tsx
@@ -7,7 +7,7 @@ export const AppLayout: FC = (): ReactElement => {
-
diff --git a/apps/backoffice/src/app/transactions/page.tsx b/apps/backoffice/src/app/transactions/page.tsx
index fb8428f..a03b161 100644
--- a/apps/backoffice/src/app/transactions/page.tsx
+++ b/apps/backoffice/src/app/transactions/page.tsx
@@ -1,13 +1,12 @@
import * as React from 'react';
-
-import { FC, ReactElement } from 'react';
+import { FC, ReactElement, useState } from 'react';
import {
FilterOutlined,
SearchOutlined,
AuditOutlined,
} from '@ant-design/icons';
import { Button, Input } from '@imphnen-frontend-service/ui/atoms';
-import { DataTable } from '@imphnen-frontend-service/ui/organisms';
+import { DataTable, Filter } from '@imphnen-frontend-service/ui/organisms';
import {
ColumnDef,
@@ -39,7 +38,7 @@ const mockTransactions: Transaction[] = Array.from({ length: 20 }, (_, i) => ({
: 'valid') as TransactionStatus,
}));
-const columns: ColumnDef
[] = [
+const columns: ColumnDef[] = [
{
id: 'select',
header: ({ table }) => (
@@ -77,9 +76,9 @@ const columns: ColumnDef[] = [
cell: ({ row }) => {
const status = row.original.status;
const statusColors: Record = {
- valid: 'bg-success-500 text-white',
- invalid: 'bg-danger-500 text-white',
- unchecked: 'bg-yellow-400 text-black',
+ valid: 'bg-success-200 text-success-500',
+ invalid: 'bg-danger-200 text-danger-500',
+ unchecked: 'bg-warning-200 text-warning-900',
};
const statusText: Record = {
valid: 'Valid',
@@ -88,7 +87,7 @@ const columns: ColumnDef[] = [
};
return (
{statusText[status]}
@@ -120,6 +119,7 @@ export const Components: FC = (): ReactElement => {
});
const [rowSelection, setRowSelection] = React.useState({});
+ const [showFilter, setShowFilter] = useState(false);
const table = useReactTable({
data: mockTransactions,
@@ -140,7 +140,7 @@ export const Components: FC = (): ReactElement => {
return (
{/* Header */}
-
+
@@ -158,14 +158,22 @@ export const Components: FC = (): ReactElement => {
-
-
- Filters
-
+
+
setShowFilter(!showFilter)}
+ >
+
+ Filters
+
+ {showFilter && (
+
+ setShowFilter(false)} />
+
+ )}
+
{/* Table */}
diff --git a/apps/backoffice/src/index.css b/apps/backoffice/src/index.css
index b92b6ea..a477593 100644
--- a/apps/backoffice/src/index.css
+++ b/apps/backoffice/src/index.css
@@ -17,14 +17,14 @@
--color-neutral-50: #f6f6f6;
--color-neutral-100: #e7e7e7;
- --color-neutral-200: #d0d0d0;
- --color-neutral-300: #b7b7b7;
- --color-neutral-400: #9f9f9f;
- --color-neutral-500: #7e7e7e;
+ --color-neutral-200: #d1d1d1;
+ --color-neutral-300: #b0b0b0;
+ --color-neutral-400: #888888;
+ --color-neutral-500: #6d6d6d;
--color-neutral-600: #5d5d5d;
- --color-neutral-700: #4a4a4a;
- --color-neutral-800: #3a3a3a;
- --color-neutral-900: #2f2f2f;
+ --color-neutral-700: #4f4f4f;
+ --color-neutral-800: #454545;
+ --color-neutral-900: #3d3d3d;
--color-neutral-950: #2b2b2b;
--color-success-100: #e0fbd8;
diff --git a/apps/gacha/src/index.css b/apps/gacha/src/index.css
index b92b6ea..a477593 100644
--- a/apps/gacha/src/index.css
+++ b/apps/gacha/src/index.css
@@ -17,14 +17,14 @@
--color-neutral-50: #f6f6f6;
--color-neutral-100: #e7e7e7;
- --color-neutral-200: #d0d0d0;
- --color-neutral-300: #b7b7b7;
- --color-neutral-400: #9f9f9f;
- --color-neutral-500: #7e7e7e;
+ --color-neutral-200: #d1d1d1;
+ --color-neutral-300: #b0b0b0;
+ --color-neutral-400: #888888;
+ --color-neutral-500: #6d6d6d;
--color-neutral-600: #5d5d5d;
- --color-neutral-700: #4a4a4a;
- --color-neutral-800: #3a3a3a;
- --color-neutral-900: #2f2f2f;
+ --color-neutral-700: #4f4f4f;
+ --color-neutral-800: #454545;
+ --color-neutral-900: #3d3d3d;
--color-neutral-950: #2b2b2b;
--color-success-100: #e0fbd8;
diff --git a/libs/ui/.storybook/main.ts b/libs/ui/.storybook/main.ts
index 6b4496c..0b23e83 100644
--- a/libs/ui/.storybook/main.ts
+++ b/libs/ui/.storybook/main.ts
@@ -11,6 +11,10 @@ const config: StorybookConfig = {
},
},
},
+ staticDirs: [
+ '../../../apps/backoffice/public',
+ '../../../apps/gacha/public',
+ '../../../apps/dimentorin/public', ],
};
export default config;
diff --git a/libs/ui/src/atoms/button/button.tsx b/libs/ui/src/atoms/button/button.tsx
index 39483e5..dc831b5 100644
--- a/libs/ui/src/atoms/button/button.tsx
+++ b/libs/ui/src/atoms/button/button.tsx
@@ -51,7 +51,7 @@ export const Button: FC