From 67f308538084abad70507b4528f007db2d52ad3c Mon Sep 17 00:00:00 2001 From: wayanrivan Date: Mon, 21 Apr 2025 09:02:25 +0700 Subject: [PATCH 01/17] update blank in detail transaction --- .../blocks/DetailApprovalTransaction.tsx | 30 +++++++++++-------- .../blocks/DetailTransaction.tsx | 14 ++++----- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/pages/transaction/approval-transaction/blocks/DetailApprovalTransaction.tsx b/src/pages/transaction/approval-transaction/blocks/DetailApprovalTransaction.tsx index 848eb7c..1e56268 100644 --- a/src/pages/transaction/approval-transaction/blocks/DetailApprovalTransaction.tsx +++ b/src/pages/transaction/approval-transaction/blocks/DetailApprovalTransaction.tsx @@ -30,7 +30,6 @@ const DetailApprovalTransaction = () => { const response = await GetData(`${API_URL}/transaction/history/detail/${selectedTransactionId}`, { id: selectedTransactionId }); - console.log(response?.data); setTransactionDetails(response?.data); } catch (error) { console.error('Error fetching transaction', error); @@ -121,11 +120,14 @@ const DetailApprovalTransaction = () => {

Full Name

-

{transactionDetails?.origin_customer.fullname}

+

+ {transactionDetails?.origin_customer?.fullname ?? "-"} +

+

Amount

-

{new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(transactionDetails?.purchase.amount)}

+

{new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(transactionDetails?.purchase?.amount) ?? new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(transactionDetails?.transfer.amount)}

Fee

@@ -292,7 +294,9 @@ const DetailApprovalTransaction = () => {

Full Name

-

{transactionDetails?.origin_customer.fullname}

+

+ {transactionDetails?.origin_customer?.fullname ?? "-"} +

Amount

@@ -347,10 +351,10 @@ const DetailApprovalTransaction = () => {

{transactionDetails?.description}

-
-

Name

-

{transactionDetails?.type?.name || '-'}

-
+
+

Name

+

{transactionDetails?.type?.name || '-'}

+

Reference

@@ -370,19 +374,21 @@ const DetailApprovalTransaction = () => {

Full Name

-

{transactionDetails?.origin_customer.fullname}

+

+ {transactionDetails?.origin_customer?.fullname ?? "-"} +

Phone Number

-

{transactionDetails?.origin_customer.msisdn}

+

{transactionDetails?.origin_customer?.msisdn ?? "-"}

Email

-

{transactionDetails?.origin_customer.email}

+

{transactionDetails?.origin_customer?.email ?? "-"}

Username

-

{transactionDetails?.origin_customer.username}

+

{transactionDetails?.origin_customer?.username ?? "-"}

diff --git a/src/pages/transaction/history-transaction/blocks/DetailTransaction.tsx b/src/pages/transaction/history-transaction/blocks/DetailTransaction.tsx index 6d774d7..b9cc2fa 100644 --- a/src/pages/transaction/history-transaction/blocks/DetailTransaction.tsx +++ b/src/pages/transaction/history-transaction/blocks/DetailTransaction.tsx @@ -120,11 +120,11 @@ const DetailTransaction = () => {

Full Name

-

{transactionDetails?.origin_customer.fullname}

+

{transactionDetails?.origin_customer?.fullname ?? "-"}

Amount

-

{new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(transactionDetails?.purchase.amount)}

+

{new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(transactionDetails?.purchase?.amount) ?? new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(transactionDetails?.transfer.amount)}

Fee

@@ -291,7 +291,7 @@ const DetailTransaction = () => {

Full Name

-

{transactionDetails?.origin_customer.fullname}

+

{transactionDetails?.origin_customer?.fullname ?? "-"}

Amount

@@ -367,19 +367,19 @@ const DetailTransaction = () => {

Full Name

-

{transactionDetails?.origin_customer.fullname}

+

{transactionDetails?.origin_customer?.fullname ?? "-"}

Phone Number

-

{transactionDetails?.origin_customer.msisdn}

+

{transactionDetails?.origin_customer?.msisdn ?? "-"}

Email

-

{transactionDetails?.origin_customer.email}

+

{transactionDetails?.origin_customer?.email ?? "-"}

Username

-

{transactionDetails?.origin_customer.username}

+

{transactionDetails?.origin_customer?.username ?? "-"}

From db97899e176620bcdcce6796af6da1c0e003ee60 Mon Sep 17 00:00:00 2001 From: wayanrivan Date: Mon, 21 Apr 2025 09:13:08 +0700 Subject: [PATCH 02/17] update blank page --- .../blocks/DetailApprovalTransaction.tsx | 47 +++++++++++------- .../blocks/DetailTransaction.tsx | 49 ++++++++++++------- 2 files changed, 61 insertions(+), 35 deletions(-) diff --git a/src/pages/transaction/approval-transaction/blocks/DetailApprovalTransaction.tsx b/src/pages/transaction/approval-transaction/blocks/DetailApprovalTransaction.tsx index 1e56268..755580a 100644 --- a/src/pages/transaction/approval-transaction/blocks/DetailApprovalTransaction.tsx +++ b/src/pages/transaction/approval-transaction/blocks/DetailApprovalTransaction.tsx @@ -397,24 +397,37 @@ const DetailApprovalTransaction = () => { {activeTab === 'destinationcustomer' && (

Destination Customer

-
-
-

Name

-

{transactionDetails?.transfer.destination_customer.fullname}

+ + {transactionDetails?.transfer?.destination_customer ? ( +
+
+

Name

+

+ {transactionDetails.transfer.destination_customer.fullname ?? "-"} +

+
+
+

MSISDN

+

+ {transactionDetails.transfer.destination_customer.msisdn ?? "-"} +

+
+
+

Email

+

+ {transactionDetails.transfer.destination_customer.email ?? "-"} +

+
+
+

Username

+

+ {transactionDetails.transfer.destination_customer.username ?? "-"} +

+
-
-

MSISDN

-

{transactionDetails?.transfer.destination_customer.msisdn}

-
-
-

Email

-

{transactionDetails?.transfer.destination_customer.email}

-
-
-

Username

-

{transactionDetails?.transfer.destination_customer.username}

-
-
+ ) : ( +

No data available

+ )}
)} diff --git a/src/pages/transaction/history-transaction/blocks/DetailTransaction.tsx b/src/pages/transaction/history-transaction/blocks/DetailTransaction.tsx index b9cc2fa..079aaf6 100644 --- a/src/pages/transaction/history-transaction/blocks/DetailTransaction.tsx +++ b/src/pages/transaction/history-transaction/blocks/DetailTransaction.tsx @@ -388,24 +388,37 @@ const DetailTransaction = () => { {activeTab === 'destinationcustomer' && (

Destination Customer

-
-
-

Name

-

{transactionDetails?.transfer.destination_customer.fullname}

+ + {transactionDetails?.transfer?.destination_customer ? ( +
+
+

Name

+

+ {transactionDetails.transfer.destination_customer.fullname ?? "-"} +

+
+
+

MSISDN

+

+ {transactionDetails.transfer.destination_customer.msisdn ?? "-"} +

+
+
+

Email

+

+ {transactionDetails.transfer.destination_customer.email ?? "-"} +

+
+
+

Username

+

+ {transactionDetails.transfer.destination_customer.username ?? "-"} +

+
-
-

MSISDN

-

{transactionDetails?.transfer.destination_customer.msisdn}

-
-
-

Email

-

{transactionDetails?.transfer.destination_customer.email}

-
-
-

Username

-

{transactionDetails?.transfer.destination_customer.username}

-
-
+ ) : ( +

No data available

+ )}
)} @@ -430,7 +443,7 @@ const DetailTransaction = () => {

Destination Wallet

{!transactionDetails?.transfer ? ( -
No Data available
+
No Data available
) : (
From 814bf9f04f6e1b6605c2f060fd44cda7ae7564fb Mon Sep 17 00:00:00 2001 From: Raja Oktafrianto Date: Mon, 21 Apr 2025 09:53:09 +0700 Subject: [PATCH 03/17] change notification sorting by creation date --- src/pages/notification/blocks/AddDialog.tsx | 4 +++- src/pages/notification/hooks/ManageNotificationContext.tsx | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pages/notification/blocks/AddDialog.tsx b/src/pages/notification/blocks/AddDialog.tsx index 38527a4..8f3b248 100644 --- a/src/pages/notification/blocks/AddDialog.tsx +++ b/src/pages/notification/blocks/AddDialog.tsx @@ -262,7 +262,9 @@ const AddDialog = () => {
- +
{['info', 'promo'].map((type) => ( + + +
@@ -79,10 +103,16 @@ const ListToolbar = () => { onClick={() => { const today = new Date(); const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1); + + setSearchValue(''); settrxDate({ from: formatDate(firstDayOfMonth), to: formatDate(today), }); + + table.getColumn('code')?.setFilterValue(''); + table.setPageIndex(0); + reload(); }} > diff --git a/src/pages/transaction/approval-transaction/hooks/ApprovalTransactionContext.tsx b/src/pages/transaction/approval-transaction/hooks/ApprovalTransactionContext.tsx index 5c74f68..6ac3b2e 100644 --- a/src/pages/transaction/approval-transaction/hooks/ApprovalTransactionContext.tsx +++ b/src/pages/transaction/approval-transaction/hooks/ApprovalTransactionContext.tsx @@ -63,6 +63,15 @@ const ApprovalTransactionProvider = ({ children }: { children: React.ReactNode } const columns = useMemo[]>( () => [ + { + accessorKey: 'code', + header: ({ column }) => , + enableSorting: false, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, { accessorKey: 'transaction_date', header: ({ column }) => , @@ -164,12 +173,12 @@ const ApprovalTransactionProvider = ({ children }: { children: React.ReactNode } }, { accessorKey: 'status_approve', - header: 'Status', + header: 'Status Approval', cell: ({ row }) => { const statusCode = row.original.status_approve; let label = ''; let badgeClass = ''; - + switch (statusCode) { case 'Y': label = 'APPROVED'; @@ -184,14 +193,14 @@ const ApprovalTransactionProvider = ({ children }: { children: React.ReactNode } badgeClass = 'bg-gray-100 text-gray-800'; break; } - + return ( {label} ); }, - }, + }, { id: 'actions', header: ({ column }) => , @@ -234,43 +243,69 @@ const ApprovalTransactionProvider = ({ children }: { children: React.ReactNode } const getTransactionLists = async (page: number, limit: number, sorting: any, filter: any) => { try { - let startdate, enddate; + const today = new Date(); + const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1); - if (!filter || filter.length === 0) { - const today = new Date(); - const nextWeek = new Date(); - nextWeek.setDate(today.getDate() + 7); - startdate = today.toISOString().split('T')[0]; - enddate = nextWeek.toISOString().split('T')[0]; - } else { - startdate = filter[0]?.value?.from; - enddate = filter[0]?.value?.to; + // Default values + let startdate = firstDayOfMonth.toISOString().split('T')[0]; + let enddate = today.toISOString().split('T')[0]; + let transactioncode = ''; + // let transactionstatus = ''; + + if (Array.isArray(filter)) { + filter.forEach((f: any) => { + // console.log(f.id); + if (f.id === 'transaction_date' && f.value?.from && f.value?.to) { + startdate = f.value.from; + enddate = f.value.to; + } + + if (f.id === 'code' && f.value) { + transactioncode = f.value; + } + + // if (f.id === 'status' && f.value) { + // transactionstatus = f.value; + // } + }); } const formattedFilter = { "Transactions.transaction_date": { from: `${startdate} 00:00:00`, - to: `${enddate} 23:59:59`, + to: `${enddate} 23:59:59` }, + "Transactions.code": { + like: `%${transactioncode}%` + }, + "Transactions.status_approve": { in: ["W", "Y", "N"] }, + // "Transactions.status": { + // like: `%${transactionstatus}%` + // } }; + const response = await GetData(`${API_URL}/transaction/history`, { limit, page: page + 1, with_deleted: false, order_field: "Transactions.created_at", order_direction: 'DESC', - filter: JSON.stringify(formattedFilter), + filter: JSON.stringify(formattedFilter) }); - setTransaction(response?.data?.list || []); - return { - data: response?.data?.list || [], - totalCount: response?.data?.total_count || 0, - }; + if (!response || !response.data) { + console.warn('No data received:', response); + return { data: [], totalCount: 0 }; + } + + setTransaction(response.data.list); + return { data: response.data.list, totalCount: response.data.total_count }; + } catch (error) { console.error('Error fetching transaction', error); + return { data: [], totalCount: 0 }; // optional: fail-safe fallback } }; diff --git a/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx b/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx index aeb3e0d..9138911 100644 --- a/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx +++ b/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx @@ -3,6 +3,13 @@ import { useTransactionContext } from '../hooks/useTransactionContext'; import { Button } from '@/components/ui/button'; import { useCallback, useState, useEffect } from 'react'; import { toast } from 'sonner'; +// import { +// Select, +// SelectContent, +// SelectItem, +// SelectTrigger, +// SelectValue, +// } from '@/components/ui/select'; const ListToolbar = () => { const { table, reload } = useDataGrid(); @@ -10,11 +17,39 @@ const ListToolbar = () => { // Set the initial state for trxDate const [trxDate, settrxDate] = useState({ from: '', to: '' }); + const [searchValue, setSearchValue] = useState( + (table.getColumn('code')?.getFilterValue() as string) ?? '' + ); + + + // const [statusValue, setStatusValue] = useState( + // (table.getColumn('status')?.getFilterValue() as string) ?? '' + // ); + // Function to format date to YYYY-MM-DD const formatDate = (date: Date): string => { return date.toISOString().split('T')[0]; }; + useEffect(() => { + const timer = setTimeout(() => { + table.getColumn('code')?.setFilterValue(searchValue); + table.setPageIndex(0); + }, 200); + + return () => clearTimeout(timer); + }, [searchValue, table]); + + // useEffect(() => { + // const timer = setTimeout(() => { + // table.getColumn('status')?.setFilterValue(statusValue); + // table.setPageIndex(0); + // }, 200); + // return () => clearTimeout(timer); + // }, [statusValue, table]); + + + // useEffect to set the default date values useEffect(() => { const today = new Date(); @@ -69,6 +104,33 @@ const ListToolbar = () => { name="to" /> + + {/* */} + + +
@@ -79,10 +141,18 @@ const ListToolbar = () => { onClick={() => { const today = new Date(); const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1); + + setSearchValue(''); + // setStatusValue(''); settrxDate({ from: formatDate(firstDayOfMonth), to: formatDate(today), }); + + table.getColumn('code')?.setFilterValue(''); + // table.getColumn('status')?.setFilterValue(''); + table.setPageIndex(0); + reload(); }} > diff --git a/src/pages/transaction/history-transaction/hooks/TransactionContext.tsx b/src/pages/transaction/history-transaction/hooks/TransactionContext.tsx index b9eeb9e..6b02b50 100644 --- a/src/pages/transaction/history-transaction/hooks/TransactionContext.tsx +++ b/src/pages/transaction/history-transaction/hooks/TransactionContext.tsx @@ -70,15 +70,15 @@ const TransactionProvider = ({ children }: { children: React.ReactNode }) => { const columns = useMemo[]>( () => [ - // { - // accessorKey: 'transaction_date', - // header: ({ column }) => , - // enableSorting: false, - // enableHiding: false, - // meta: { - // headerClassName: 'w-[250px]' - // } - // }, + { + accessorKey: 'code', + header: ({ column }) => , + enableSorting: false, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, { accessorKey: 'transaction_date', header: ({ column }) => , @@ -242,30 +242,47 @@ const TransactionProvider = ({ children }: { children: React.ReactNode }) => { const getTransactionLists = async (page: number, limit: number, sorting: any, filter: any) => { try { - let startdate; - let enddate; - let formattedFilter; + const today = new Date(); + const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1); - if (filter == undefined || filter.length == 0) { - const today = new Date(); + // Default values + let startdate = firstDayOfMonth.toISOString().split('T')[0]; + let enddate = today.toISOString().split('T')[0]; + let transactioncode = ''; + // let transactionstatus = ''; - // Tanggal 1 di bulan sekarang - const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1); + if (Array.isArray(filter)) { + filter.forEach((f: any) => { + // console.log(f.id); + if (f.id === 'transaction_date' && f.value?.from && f.value?.to) { + startdate = f.value.from; + enddate = f.value.to; + } - startdate = firstDayOfMonth.toISOString().split('T')[0]; - enddate = today.toISOString().split('T')[0]; - } else if (filter != undefined || filter.length != 0) { - startdate = filter[0].value.from; - enddate = filter[0].value.to; + if (f.id === 'code' && f.value) { + transactioncode = f.value; + } + + // if (f.id === 'status' && f.value) { + // transactionstatus = f.value; + // } + }); } - formattedFilter = { + const formattedFilter = { "Transactions.transaction_date": { - from: startdate + " 00:00:00", - to: enddate + " 23:59:59" - } + from: `${startdate} 00:00:00`, + to: `${enddate} 23:59:59` + }, + "Transactions.code": { + like: `%${transactioncode}%` + }, + // "Transactions.status": { + // like: `%${transactionstatus}%` + // } }; + const response = await GetData(`${API_URL}/transaction/history`, { limit, page: page + 1, @@ -275,13 +292,21 @@ const TransactionProvider = ({ children }: { children: React.ReactNode }) => { filter: JSON.stringify(formattedFilter) }); - setTransaction(response?.data.list); - return { data: response?.data.list, totalCount: response?.data.total_count }; + if (!response || !response.data) { + console.warn('No data received:', response); + return { data: [], totalCount: 0 }; + } + + setTransaction(response.data.list); + return { data: response.data.list, totalCount: response.data.total_count }; + } catch (error) { console.error('Error fetching transaction', error); + return { data: [], totalCount: 0 }; // optional: fail-safe fallback } }; + return ( Date: Mon, 21 Apr 2025 11:21:22 +0700 Subject: [PATCH 05/17] add card balance on dashboard module - escrow and master agent only --- .../dashboards/home/DashboardHomePage.tsx | 44 +++++++++ .../dashboards/home/blocks/BalanceCard.tsx | 94 +++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 src/pages/dashboards/home/blocks/BalanceCard.tsx diff --git a/src/pages/dashboards/home/DashboardHomePage.tsx b/src/pages/dashboards/home/DashboardHomePage.tsx index 4884ebb..856d7d1 100644 --- a/src/pages/dashboards/home/DashboardHomePage.tsx +++ b/src/pages/dashboards/home/DashboardHomePage.tsx @@ -16,14 +16,26 @@ import { useFetchYear } from './hooks/useFetchYear'; import { get5LastYear } from '@/utils/Date'; import { staticChartData } from './staticChart'; import { Helmet } from 'react-helmet'; +import BalanceCard from './blocks/BalanceCard'; +import { getAuth } from '@/auth'; +import { useCallApi } from '@/hooks'; +import { apiConfig } from '@/config/api.config'; // sum -> nominal, count-> total type CountType = 'sum' | 'count'; type ChartType = 'line' | 'bar'; type ChartLegend = 'true' | 'false'; +type RoleType = { + id: string; + name: string; +}; + +const API_URL_DASHBOARD = apiConfig.service_dashboard; + const DashboardHomePage = () => { const selectYear = get5LastYear(); + const { GetData } = useCallApi(); const [initialYear, setInitialYear] = useState(''); const [selectedYear, setSelectedYear] = useState(''); const [count, setCount] = useState('sum'); @@ -33,6 +45,31 @@ const DashboardHomePage = () => { from: new Date(), to: new Date() }); + const [roles, setRoles] = useState([]); + const parsedUser = getAuth()?.user; + const idCustomer = parsedUser?.customer?.id; + const roleCustomer = parsedUser.idRole; + const currentRole = roles.find((role) => role.id === roleCustomer)?.name?.toLowerCase(); + console.log(currentRole); + + useEffect(() => { + async function fetchRoles(sorting: any) { + try { + const response = await GetData(`${API_URL_DASHBOARD}/user_role/list`, { + limit: 100, + page: 1, + with_deleted: false, + order_field: sorting[0].id, + order_direction: sorting[0].desc == false ? 'ASC' : 'DESC' + }); + setRoles(response?.data.list); + } catch (error) { + console.error('Error fetching roles', error); + } + } + + fetchRoles([{ id: 'name', desc: false }]); + }, []); // Menyusun tanggal awal dan akhir berdasarkan selectedYear useEffect(() => { @@ -144,6 +181,13 @@ const DashboardHomePage = () => { TPAY | Dashboard + {/* Account Balance Cards */} + {currentRole === 'escrow' || currentRole === 'master agent' ? ( +
+ +
+ ) : null} +
diff --git a/src/pages/dashboards/home/blocks/BalanceCard.tsx b/src/pages/dashboards/home/blocks/BalanceCard.tsx new file mode 100644 index 0000000..87aaaf6 --- /dev/null +++ b/src/pages/dashboards/home/blocks/BalanceCard.tsx @@ -0,0 +1,94 @@ +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { apiConfig } from '@/config/api.config'; +import { useCallApi } from '@/hooks'; +import { CreditCard, Wallet } from 'lucide-react'; +import { useEffect, useState } from 'react'; + +type WalletResponse = { + amount: number; + id_wallet: string; + wallet: string; + credit_limit: number; + monthly_limit: number; +}; + +interface BalanceCardProps { + id: string; +} + +const API_URL_WALLET = apiConfig.service_wallet; + +const BalanceCard = ({ id }: BalanceCardProps) => { + const { GetData } = useCallApi(); + const [wallets, setWallets] = useState([]); + + const formatCurrency = (value: number) => { + return new Intl.NumberFormat('en-US', { + style: 'currency', + currency: 'USD' + }).format(value); + }; + + const getColorClass = (amount: number) => { + if (amount > 5000) return 'bg-emerald-500'; + if (amount > 0) return 'bg-blue-500'; + return 'bg-red-500'; + }; + + useEffect(() => { + async function fetchAccountBalances() { + try { + const response = await GetData(`${API_URL_WALLET}/dashboard/balance/account/${id}`, { + id: id + }); + if (response?.status === true) { + setWallets(response.data); + } + } catch (error) { + console.error('Error fetching account balances', error); + } + } + + fetchAccountBalances(); + }, [id]); + + return ( +
+ {wallets.map((wallet) => { + const colorClass = getColorClass(wallet.amount); + const isNegative = wallet.amount < 0; + + return ( +
+
+
+
+

{wallet.wallet}

+ {wallet.wallet.includes('Credit') ? ( + + ) : ( + + )} +
+

+ {formatCurrency(wallet.amount)} +

+ +
+
Credit Limit:
+
{wallet.credit_limit}
+
Monthly Limit:
+
{wallet.monthly_limit}
+
+
+
+ ); + })} +
+ ); +}; + +export default BalanceCard; From bc883640584fe80694aedbe153b864252d86e716 Mon Sep 17 00:00:00 2001 From: Wikzyy Date: Mon, 21 Apr 2025 11:38:57 +0700 Subject: [PATCH 06/17] update remove fetch roles to optimize performance --- .../dashboards/home/DashboardHomePage.tsx | 38 ++----------------- 1 file changed, 4 insertions(+), 34 deletions(-) diff --git a/src/pages/dashboards/home/DashboardHomePage.tsx b/src/pages/dashboards/home/DashboardHomePage.tsx index 856d7d1..22d69b9 100644 --- a/src/pages/dashboards/home/DashboardHomePage.tsx +++ b/src/pages/dashboards/home/DashboardHomePage.tsx @@ -26,16 +26,8 @@ type CountType = 'sum' | 'count'; type ChartType = 'line' | 'bar'; type ChartLegend = 'true' | 'false'; -type RoleType = { - id: string; - name: string; -}; - -const API_URL_DASHBOARD = apiConfig.service_dashboard; - const DashboardHomePage = () => { const selectYear = get5LastYear(); - const { GetData } = useCallApi(); const [initialYear, setInitialYear] = useState(''); const [selectedYear, setSelectedYear] = useState(''); const [count, setCount] = useState('sum'); @@ -45,31 +37,9 @@ const DashboardHomePage = () => { from: new Date(), to: new Date() }); - const [roles, setRoles] = useState([]); - const parsedUser = getAuth()?.user; - const idCustomer = parsedUser?.customer?.id; - const roleCustomer = parsedUser.idRole; - const currentRole = roles.find((role) => role.id === roleCustomer)?.name?.toLowerCase(); - console.log(currentRole); - - useEffect(() => { - async function fetchRoles(sorting: any) { - try { - const response = await GetData(`${API_URL_DASHBOARD}/user_role/list`, { - limit: 100, - page: 1, - with_deleted: false, - order_field: sorting[0].id, - order_direction: sorting[0].desc == false ? 'ASC' : 'DESC' - }); - setRoles(response?.data.list); - } catch (error) { - console.error('Error fetching roles', error); - } - } - - fetchRoles([{ id: 'name', desc: false }]); - }, []); + const currentRole = getAuth()?.role_name; + const idCustomer = getAuth()?.user.customer?.id; + // console.log(currentRole); // Menyusun tanggal awal dan akhir berdasarkan selectedYear useEffect(() => { @@ -182,7 +152,7 @@ const DashboardHomePage = () => { {/* Account Balance Cards */} - {currentRole === 'escrow' || currentRole === 'master agent' ? ( + {currentRole === 'Escrow' || currentRole === 'Master Agent' ? (
From a24312a6dec330c3f0074cc10a72bef523faa91b Mon Sep 17 00:00:00 2001 From: Wikzyy Date: Mon, 21 Apr 2025 14:37:42 +0700 Subject: [PATCH 07/17] update styling balance card component --- src/pages/dashboards/home/blocks/BalanceCard.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/dashboards/home/blocks/BalanceCard.tsx b/src/pages/dashboards/home/blocks/BalanceCard.tsx index 87aaaf6..97b43d1 100644 --- a/src/pages/dashboards/home/blocks/BalanceCard.tsx +++ b/src/pages/dashboards/home/blocks/BalanceCard.tsx @@ -30,8 +30,8 @@ const BalanceCard = ({ id }: BalanceCardProps) => { }; const getColorClass = (amount: number) => { - if (amount > 5000) return 'bg-emerald-500'; - if (amount > 0) return 'bg-blue-500'; + if (amount > 0) return 'bg-amber-300'; + if (amount > 500) return 'bg-blue-500'; return 'bg-red-500'; }; From 7f87e0ee44c8aaadf2944eac6247ea5821fbc2cd Mon Sep 17 00:00:00 2001 From: Wikzyy Date: Mon, 21 Apr 2025 15:01:15 +0700 Subject: [PATCH 08/17] fix grid balance card component --- src/pages/dashboards/home/blocks/BalanceCard.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/pages/dashboards/home/blocks/BalanceCard.tsx b/src/pages/dashboards/home/blocks/BalanceCard.tsx index 97b43d1..6391139 100644 --- a/src/pages/dashboards/home/blocks/BalanceCard.tsx +++ b/src/pages/dashboards/home/blocks/BalanceCard.tsx @@ -29,6 +29,10 @@ const BalanceCard = ({ id }: BalanceCardProps) => { }).format(value); }; + const formatNumberWithDots = (value: number) => { + return value.toLocaleString('id-ID'); + }; + const getColorClass = (amount: number) => { if (amount > 0) return 'bg-amber-300'; if (amount > 500) return 'bg-blue-500'; @@ -79,9 +83,11 @@ const BalanceCard = ({ id }: BalanceCardProps) => {
Credit Limit:
-
{wallet.credit_limit}
+
{formatNumberWithDots(wallet.credit_limit)}
+
+
Monthly Limit:
-
{wallet.monthly_limit}
+
{formatNumberWithDots(wallet.monthly_limit)}
From 2db0287cc28084ad77524626c37d10f79f0bb3b8 Mon Sep 17 00:00:00 2001 From: wayanrivan Date: Mon, 21 Apr 2025 15:39:09 +0700 Subject: [PATCH 09/17] update for filter transaction --- .../blocks/ListToolbar.tsx | 36 ++++++++ .../hooks/ApprovalTransactionContext.tsx | 36 ++++---- .../blocks/ListToolbar.tsx | 89 ++++++++++++------- .../hooks/TransactionContext.tsx | 60 ++++++++++--- 4 files changed, 160 insertions(+), 61 deletions(-) diff --git a/src/pages/transaction/approval-transaction/blocks/ListToolbar.tsx b/src/pages/transaction/approval-transaction/blocks/ListToolbar.tsx index d5b36ea..fd4ec89 100644 --- a/src/pages/transaction/approval-transaction/blocks/ListToolbar.tsx +++ b/src/pages/transaction/approval-transaction/blocks/ListToolbar.tsx @@ -3,6 +3,13 @@ import { useTransactionContext } from '../hooks/useApprovalTransactionContext'; import { Button } from '@/components/ui/button'; import { useCallback, useState, useEffect } from 'react'; import { toast } from 'sonner'; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select'; const ListToolbar = () => { const { table, reload } = useDataGrid(); @@ -10,6 +17,18 @@ const ListToolbar = () => { // Set the initial state for trxDate const [trxDate, settrxDate] = useState({ from: '', to: '' }); + const [statusApproval, setStatusApproval] = useState( + (table.getColumn('status_approve')?.getFilterValue() as string) ?? '' + ); + + useEffect(() => { + const timer = setTimeout(() => { + table.getColumn('status_approve')?.setFilterValue(statusApproval); + table.setPageIndex(0); + }, 200); + return () => clearTimeout(timer); + }, [statusApproval, table]); + // Function to format date to YYYY-MM-DD const formatDate = (date: Date): string => { return date.toISOString().split('T')[0]; @@ -83,6 +102,22 @@ const ListToolbar = () => { /> + + - {/* */} + + + -
@@ -143,16 +168,20 @@ const ListToolbar = () => { const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1); setSearchValue(''); - // setStatusValue(''); + setStatusValue(''); + setTypeValue(''); settrxDate({ from: formatDate(firstDayOfMonth), to: formatDate(today), }); - table.getColumn('code')?.setFilterValue(''); - // table.getColumn('status')?.setFilterValue(''); - table.setPageIndex(0); + table.setColumnFilters([ + { id: 'code', value: '' }, + { id: 'status', value: '' }, + { id: 'kind', value: '' }, + ]); + table.setPageIndex(0); reload(); }} > diff --git a/src/pages/transaction/history-transaction/hooks/TransactionContext.tsx b/src/pages/transaction/history-transaction/hooks/TransactionContext.tsx index 6b02b50..dba40bd 100644 --- a/src/pages/transaction/history-transaction/hooks/TransactionContext.tsx +++ b/src/pages/transaction/history-transaction/hooks/TransactionContext.tsx @@ -79,6 +79,25 @@ const TransactionProvider = ({ children }: { children: React.ReactNode }) => { headerClassName: 'w-[250px]' } }, + { + accessorFn: (row) => { + switch (row.kind) { + case 'T': return 'TRANSFER'; + case 'P': return 'PURCHASE'; + case 'W': return 'WITHDRAW'; + case 'U': return 'TOP UP'; + case 'R': return 'RETURN'; + default: return '_'; + } + }, + accessorKey: 'kind', + header: ({ column }) => , + enableSorting: false, + enableHiding: false, + meta: { + headerClassName: 'w-[250px]' + } + }, { accessorKey: 'transaction_date', header: ({ column }) => , @@ -249,11 +268,12 @@ const TransactionProvider = ({ children }: { children: React.ReactNode }) => { let startdate = firstDayOfMonth.toISOString().split('T')[0]; let enddate = today.toISOString().split('T')[0]; let transactioncode = ''; - // let transactionstatus = ''; + let transactionstatus = ''; + let type = '' if (Array.isArray(filter)) { + // console.log(filter); filter.forEach((f: any) => { - // console.log(f.id); if (f.id === 'transaction_date' && f.value?.from && f.value?.to) { startdate = f.value.from; enddate = f.value.to; @@ -263,25 +283,37 @@ const TransactionProvider = ({ children }: { children: React.ReactNode }) => { transactioncode = f.value; } - // if (f.id === 'status' && f.value) { - // transactionstatus = f.value; - // } + if (f.id === 'status' && f.value) { + transactionstatus = f.value; + } + + if (f.id === 'kind' && f.value) { + type = f.value; + } }); } - const formattedFilter = { + // Build filter object dynamically + const formattedFilter: any = { "Transactions.transaction_date": { from: `${startdate} 00:00:00`, to: `${enddate} 23:59:59` - }, - "Transactions.code": { - like: `%${transactioncode}%` - }, - // "Transactions.status": { - // like: `%${transactionstatus}%` - // } + } }; + if (transactioncode) { + formattedFilter["Transactions.code"] = { + like: `%${transactioncode}%` + }; + } + + if (transactionstatus) { + formattedFilter["Transactions.status"] = transactionstatus; + } + + if (type) { + formattedFilter["Transactions.kind"] = type; + } const response = await GetData(`${API_URL}/transaction/history`, { limit, @@ -302,7 +334,7 @@ const TransactionProvider = ({ children }: { children: React.ReactNode }) => { } catch (error) { console.error('Error fetching transaction', error); - return { data: [], totalCount: 0 }; // optional: fail-safe fallback + return { data: [], totalCount: 0 }; } }; From 6a81242a6867ea512d215c60f5d8fe0561b95f5c Mon Sep 17 00:00:00 2001 From: wayanrivan Date: Mon, 21 Apr 2025 15:44:11 +0700 Subject: [PATCH 10/17] update for filter transaction --- .../blocks/ListToolbar.tsx | 18 +++++++++--------- .../history-transaction/blocks/ListToolbar.tsx | 3 +++ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/pages/transaction/approval-transaction/blocks/ListToolbar.tsx b/src/pages/transaction/approval-transaction/blocks/ListToolbar.tsx index fd4ec89..2bf79e0 100644 --- a/src/pages/transaction/approval-transaction/blocks/ListToolbar.tsx +++ b/src/pages/transaction/approval-transaction/blocks/ListToolbar.tsx @@ -16,18 +16,17 @@ const ListToolbar = () => { // Set the initial state for trxDate const [trxDate, settrxDate] = useState({ from: '', to: '' }); - const [statusApproval, setStatusApproval] = useState( (table.getColumn('status_approve')?.getFilterValue() as string) ?? '' ); useEffect(() => { - const timer = setTimeout(() => { - table.getColumn('status_approve')?.setFilterValue(statusApproval); - table.setPageIndex(0); - }, 200); - return () => clearTimeout(timer); - }, [statusApproval, table]); + const timer = setTimeout(() => { + table.getColumn('status_approve')?.setFilterValue(statusApproval); + table.setPageIndex(0); + }, 200); + return () => clearTimeout(timer); + }, [statusApproval, table]); // Function to format date to YYYY-MM-DD const formatDate = (date: Date): string => { @@ -139,7 +138,9 @@ const ListToolbar = () => { const today = new Date(); const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1); + // Resetting all filters setSearchValue(''); + setStatusApproval(''); settrxDate({ from: formatDate(firstDayOfMonth), to: formatDate(today), @@ -149,7 +150,7 @@ const ListToolbar = () => { table.getColumn('status_approve')?.setFilterValue(''); table.setPageIndex(0); - reload(); + reload(); // Reload table data }} > @@ -159,7 +160,6 @@ const ListToolbar = () => {
); - }; export default ListToolbar; diff --git a/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx b/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx index 1050d07..1ca2b79 100644 --- a/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx +++ b/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx @@ -164,9 +164,11 @@ const ListToolbar = () => { variant="outline" className="h-7.5" onClick={() => { + // Preserve trxDate values (from, to) and reset others const today = new Date(); const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1); + // Only reset filters excluding from and to setSearchValue(''); setStatusValue(''); setTypeValue(''); @@ -175,6 +177,7 @@ const ListToolbar = () => { to: formatDate(today), }); + // Reset other filters except for date range table.setColumnFilters([ { id: 'code', value: '' }, { id: 'status', value: '' }, From bbe1433984fd24ac662eb434ba66cf821bea797d Mon Sep 17 00:00:00 2001 From: wayanrivan Date: Mon, 21 Apr 2025 16:08:55 +0700 Subject: [PATCH 11/17] update --- .../transaction/approval-transaction/blocks/ApprovalDialog.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pages/transaction/approval-transaction/blocks/ApprovalDialog.tsx b/src/pages/transaction/approval-transaction/blocks/ApprovalDialog.tsx index 8968cd2..fa63bac 100644 --- a/src/pages/transaction/approval-transaction/blocks/ApprovalDialog.tsx +++ b/src/pages/transaction/approval-transaction/blocks/ApprovalDialog.tsx @@ -20,11 +20,13 @@ import { import { doSaveLogActivity } from '@/actions/GlobalActions'; import { toast } from 'sonner'; import { Input } from '@/components/ui/input'; +import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; const API_URL = apiConfig.transaction; const ApprovalDialog = () => { const { GetData, PostData } = useCallApi(); + const { table, reload } = useDataGrid(); const { showApprovalDialog, @@ -83,6 +85,7 @@ const ApprovalDialog = () => { }; doSaveLogActivity(createActivity); setShowApprovalDialog(false); + reload(); } else { setAlert({ show: true, message: response?.message }); } From 507b76a5405c5942def7c1b79de36d4de0f37842 Mon Sep 17 00:00:00 2001 From: wayanrivan Date: Mon, 21 Apr 2025 16:18:02 +0700 Subject: [PATCH 12/17] update --- .../blocks/ApprovalDialog.tsx | 4 +-- .../blocks/ListToolbar.tsx | 28 +++++++++---------- .../hooks/TransactionContext.tsx | 14 +++++----- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/pages/transaction/approval-transaction/blocks/ApprovalDialog.tsx b/src/pages/transaction/approval-transaction/blocks/ApprovalDialog.tsx index fa63bac..2371696 100644 --- a/src/pages/transaction/approval-transaction/blocks/ApprovalDialog.tsx +++ b/src/pages/transaction/approval-transaction/blocks/ApprovalDialog.tsx @@ -26,7 +26,7 @@ const API_URL = apiConfig.transaction; const ApprovalDialog = () => { const { GetData, PostData } = useCallApi(); - const { table, reload } = useDataGrid(); + // const { table, reload } = useDataGrid(); const { showApprovalDialog, @@ -85,7 +85,7 @@ const ApprovalDialog = () => { }; doSaveLogActivity(createActivity); setShowApprovalDialog(false); - reload(); + // reload(); } else { setAlert({ show: true, message: response?.message }); } diff --git a/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx b/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx index 1ca2b79..49bdb4a 100644 --- a/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx +++ b/src/pages/transaction/history-transaction/blocks/ListToolbar.tsx @@ -19,9 +19,9 @@ const ListToolbar = () => { (table.getColumn('code')?.getFilterValue() as string) ?? '' ); - const [statusValue, setStatusValue] = useState( - (table.getColumn('status')?.getFilterValue() as string) ?? '' - ); + // const [statusValue, setStatusValue] = useState( + // (table.getColumn('status')?.getFilterValue() as string) ?? '' + // ); const [typeValue, setTypeValue] = useState( (table.getState().columnFilters.find(f => f.id === 'kind')?.value as string) ?? '' @@ -40,13 +40,13 @@ const ListToolbar = () => { return () => clearTimeout(timer); }, [searchValue, table]); - useEffect(() => { - const timer = setTimeout(() => { - table.getColumn('status')?.setFilterValue(statusValue); - table.setPageIndex(0); - }, 200); - return () => clearTimeout(timer); - }, [statusValue, table]); + // useEffect(() => { + // const timer = setTimeout(() => { + // table.getColumn('status')?.setFilterValue(statusValue); + // table.setPageIndex(0); + // }, 200); + // return () => clearTimeout(timer); + // }, [statusValue, table]); useEffect(() => { const timer = setTimeout(() => { @@ -113,7 +113,7 @@ const ListToolbar = () => { /> - + */}
diff --git a/src/pages/transfer/transfertype/blocks/EditDialog.tsx b/src/pages/transfer/transfertype/blocks/EditDialog.tsx index 28e2296..a6070bf 100644 --- a/src/pages/transfer/transfertype/blocks/EditDialog.tsx +++ b/src/pages/transfer/transfertype/blocks/EditDialog.tsx @@ -605,6 +605,9 @@ const EditDialog = () => { Top Up Master Agent Top Up Agent Purchase Loja + Disbursment Escrow + Disbursment Master Agent + Disbursment Agent
diff --git a/src/pages/transfer/transfertype/hooks/ManageTransferTypeContext.tsx b/src/pages/transfer/transfertype/hooks/ManageTransferTypeContext.tsx index a21febf..cae8c34 100644 --- a/src/pages/transfer/transfertype/hooks/ManageTransferTypeContext.tsx +++ b/src/pages/transfer/transfertype/hooks/ManageTransferTypeContext.tsx @@ -80,7 +80,7 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React const [selectedTransferType, setSelectedTransferType] = useState(null); const [transferType, setTransferType] = useState(null); const [searchTerm, setSearchTerm] = useState(''); - + const debouncedSearchTerm = useDebounce(searchTerm, 200); const handleEditDialog = useCallback((show: boolean, selected_transfertype: string | null) => { @@ -183,10 +183,13 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React AM: 'Return Agent Merchant', AE: 'Return Agent Emoney', R: 'Reward Point', - TE:'Top Up Escrow', - TM:'Top Up Master Agent', - TA:'Top Up Agent', - PL:'Purchase Loja' + TE: 'Top Up Escrow', + TM: 'Top Up Master Agent', + TA: 'Top Up Agent', + PL: 'Purchase Loja', + DE: 'Disbursment Escrow', + DM: 'Disbursment Master Agent', + DA: 'Disbursment Agent' }; return mapping[row.type] || 'Unknown'; @@ -256,7 +259,7 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React const orderDirection = sorting.length > 0 ? (sorting[0].desc ? 'DESC' : 'ASC') : 'DESC'; const searchFilter = debouncedSearchTerm ? { any: debouncedSearchTerm.toLowerCase() } : {}; - + filter = filter.length == 0 ? searchFilter : { any: filter[0].value?.toLowerCase() }; const response = await GetData(`${API_URL}/transactiontype/list`, { @@ -310,4 +313,4 @@ const ManageTransferTypeContextProvider = ({ children }: { children: React.React }; export { ManageTransferTypeContext, ManageTransferTypeContextProvider }; -export type { TransferType }; \ No newline at end of file +export type { TransferType }; From 81fa2579c351163dfb7b2e831f9a911f467fe663 Mon Sep 17 00:00:00 2001 From: Wikzyy Date: Mon, 21 Apr 2025 17:40:40 +0700 Subject: [PATCH 14/17] update styling balance card component --- src/pages/dashboards/home/blocks/BalanceCard.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/dashboards/home/blocks/BalanceCard.tsx b/src/pages/dashboards/home/blocks/BalanceCard.tsx index 6391139..e349fbd 100644 --- a/src/pages/dashboards/home/blocks/BalanceCard.tsx +++ b/src/pages/dashboards/home/blocks/BalanceCard.tsx @@ -33,9 +33,9 @@ const BalanceCard = ({ id }: BalanceCardProps) => { return value.toLocaleString('id-ID'); }; - const getColorClass = (amount: number) => { - if (amount > 0) return 'bg-amber-300'; - if (amount > 500) return 'bg-blue-500'; + const getColorClass = (amount: number, walletType: string) => { + if (walletType.toLowerCase().includes('point account')) return 'bg-amber-300'; + // if (amount > 3125) return 'bg-amber-300'; return 'bg-red-500'; }; @@ -59,7 +59,7 @@ const BalanceCard = ({ id }: BalanceCardProps) => { return (
{wallets.map((wallet) => { - const colorClass = getColorClass(wallet.amount); + const colorClass = getColorClass(wallet.amount, wallet.wallet); const isNegative = wallet.amount < 0; return ( From a79255b582cf69c5d595201c2a710a2fa0a1ae7a Mon Sep 17 00:00:00 2001 From: bagusajisaputroo Date: Mon, 21 Apr 2025 17:53:13 +0700 Subject: [PATCH 15/17] changed headerTopBar --- src/layouts/demo2/header/HeaderTopbar.tsx | 71 +++++++++++++---------- 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/src/layouts/demo2/header/HeaderTopbar.tsx b/src/layouts/demo2/header/HeaderTopbar.tsx index 44a6057..2364423 100644 --- a/src/layouts/demo2/header/HeaderTopbar.tsx +++ b/src/layouts/demo2/header/HeaderTopbar.tsx @@ -1,9 +1,10 @@ -import { useRef } from 'react'; +import { useRef, useEffect, useState } from 'react'; import { KeenIcon } from '@/components/keenicons'; import { toAbsoluteUrl } from '@/utils'; import { Menu, MenuItem, MenuToggle } from '@/components'; import { DropdownUser } from '@/partials/dropdowns/user'; import { useLanguage } from '@/i18n'; +import { getAuth } from '@/auth'; const HeaderTopbar = () => { const itemChatRef = useRef(null); @@ -14,38 +15,44 @@ const HeaderTopbar = () => { const handleDropdownChatShow = () => { window.dispatchEvent(new Event('resize')); }; - + console.log(getAuth()) return ( -
- - - - - - {DropdownUser({ menuItemRef: itemUserRef })} - - -
+
+
+ {getAuth()?.user.username} + {getAuth()?.role_name} +
+ + + + + User avatar + + {DropdownUser({ menuItemRef: itemUserRef })} + + +
+ ); }; -export { HeaderTopbar }; +export { HeaderTopbar }; \ No newline at end of file From ff1843eec25c12b1784f42c2477ce0d8ff857354 Mon Sep 17 00:00:00 2001 From: bagusajisaputroo Date: Mon, 21 Apr 2025 17:56:17 +0700 Subject: [PATCH 16/17] headertopbar --- src/layouts/demo2/header/HeaderTopbar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/demo2/header/HeaderTopbar.tsx b/src/layouts/demo2/header/HeaderTopbar.tsx index 2364423..5ef3aab 100644 --- a/src/layouts/demo2/header/HeaderTopbar.tsx +++ b/src/layouts/demo2/header/HeaderTopbar.tsx @@ -43,7 +43,7 @@ const HeaderTopbar = () => { User avatar From 103b7bb750f767b9d5a4343fbc158a229f58bb7e Mon Sep 17 00:00:00 2001 From: Raja Oktafrianto Date: Mon, 21 Apr 2025 18:24:56 +0700 Subject: [PATCH 17/17] fixing refresh & sorting manage groups --- src/pages/groups/Column.tsx | 69 ++++++++++++++++++++++++++--- src/pages/groups/ListToolbar.tsx | 44 +++++++++++-------- src/pages/groups/ManageGroups.tsx | 72 +++++++++++++++++++++++-------- 3 files changed, 143 insertions(+), 42 deletions(-) diff --git a/src/pages/groups/Column.tsx b/src/pages/groups/Column.tsx index 2f6fe7f..3d1a1e0 100644 --- a/src/pages/groups/Column.tsx +++ b/src/pages/groups/Column.tsx @@ -1,5 +1,8 @@ import { KeenIcon } from '@/components'; +import { Button } from '@/components/ui/button'; import { ColumnDef } from '@tanstack/react-table'; +import { ArrowUpDown } from 'lucide-react'; +import moment from 'moment'; export type Group = { no: number; @@ -12,27 +15,81 @@ export type Group = { export const getColumns = (handleUpdate: (data: any) => void): ColumnDef[] => [ { accessorKey: 'no', - header: 'ID' + header: ({ column }) => { + return ( + + ); + } }, { accessorKey: 'created_at', - header: 'Created Date', - cell: ({ row }) => new Date(row.original.created_at).toLocaleDateString() + header: ({ column }) => { + return ( + + ); + }, + cell: ({ row }) => moment(row.original.created_at).format('YYYY-MM-DD HH:mm:ss') }, { accessorKey: 'name', - header: 'Name' + header: ({ column }) => { + return ( + + ); + } }, { accessorKey: 'status', - header: 'Status' + header: 'Status', + cell: ({ row }) => { + const isActive = row.original.status === 'Y'; + + return ( + + {isActive ? 'Active' : 'inactive'} + + ); + } }, { accessorKey: 'description', - header: 'Description' + header: ({ column }) => { + return ( + + ); + } }, { id: 'actions', + header: 'Actions', cell: ({ row }) => { const dataMembers = row.original; diff --git a/src/pages/groups/ListToolbar.tsx b/src/pages/groups/ListToolbar.tsx index 793f4c9..9d3dd1a 100644 --- a/src/pages/groups/ListToolbar.tsx +++ b/src/pages/groups/ListToolbar.tsx @@ -1,8 +1,20 @@ import { DefaultTooltip, KeenIcon, useDataGrid } from '@/components'; import { Button } from '@/components/ui/button'; +import React, { useState } from 'react'; -const ListToolBar = ({ createGroup }: { createGroup: () => void }) => { - const { table, reload } = useDataGrid(); +interface ListToolBarProps { + createGroup: () => void; + onReload: () => void; + isReloading: boolean; +} + +const ListToolBar = ({ createGroup, onReload, isReloading }: ListToolBarProps) => { + const { table } = useDataGrid(); + const [usernameFilter, setUsernameFilter] = useState(''); + const handleUsernameChange = (e: React.ChangeEvent) => { + setUsernameFilter(e.target.value); + table.getColumn('name')?.setFilterValue(e.target.value); + }; return (
@@ -14,29 +26,25 @@ const ListToolBar = ({ createGroup }: { createGroup: () => void }) => { table.getColumn('name')?.setFilterValue(event.target.value)} + value={usernameFilter} + onChange={handleUsernameChange} + className="input input-sm w-40" /> - {/* - - */}
- -
diff --git a/src/pages/groups/ManageGroups.tsx b/src/pages/groups/ManageGroups.tsx index d03966f..32841c2 100644 --- a/src/pages/groups/ManageGroups.tsx +++ b/src/pages/groups/ManageGroups.tsx @@ -24,8 +24,10 @@ import CloseIcon from '@mui/icons-material/Close'; import Divider from '@mui/material/Divider'; import ConfirmDialog from '@/components/confirm'; import { toast } from 'sonner'; -import { Container, DataGridProvider } from '@/components'; +import { Container, DataGridProvider, LoaderTransparant } from '@/components'; import { ListToolBar } from './ListToolbar'; +import { RefreshCw } from 'lucide-react'; +import { setgroups } from 'process'; // import { DialogHeader } from '@/components/ui/dialog'; // import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; const BASE_URL = apiConfig.service_customer; @@ -42,37 +44,52 @@ let initGroup = { const ManageGroups = () => { const [isDialogOpen, setIsDialogOpen] = useState(false); + const [loading, setLoading] = useState(false); const [dataGroup, setDataGroup] = useState([]); const [formData, setFormData] = useState(initGroup); const [pageIndex, setPageIndex] = useState(1); const [pageSize, setPageSize] = useState(10); const [dialogType, setDialogType] = useState(''); const [dialogOpen, setDialogOpen] = useState(false); + const [isReloading, setIsReloading] = useState(false); + // const closeDialog = () => { + // setIsDialogOpen(false); + // setgroups(initGroup); + // }; useEffect(() => { + setLoading(true); fetchGroups(); + setLoading(false); }, []); - async function fetchGroups() { + async function fetchGroups(): Promise { try { let groups = await axios.get(`${BASE_URL}/groups/list`, { params: { - limit: pageSize, - page: pageIndex, + limit: 20, + page: 1, with_deleted: false, - order_field: 'name', - order_direction: 'ASC' + order_field: 'created_at', + order_direction: 'DESC' } }); let temp = 1; let resGroups = groups.data.data.list.map((el: any) => { el.no = temp++; + if (el.date_birth) { + const d = new Date(el.date_birth); + el.date_birth = d.toLocaleString('sv-SE'); + } return el; - }) + }); setDataGroup(resGroups); } catch (error: any) { alert(error.message); console.log(error); + } finally { + setLoading(false); + setIsReloading(false); } } @@ -127,6 +144,11 @@ const ManageGroups = () => { setDialogOpen(true); }; + const handleReload = () => { + setIsReloading(true); + fetchGroups(); + }; + const handleYes = async () => { try { if (dialogType === 'create') { @@ -153,12 +175,19 @@ const ManageGroups = () => { console.log(error); toast.error(error.message); } finally { - await fetchGroups(); setDialogOpen(false); closeDialog(); + await fetchGroups(); + setLoading(false); } }; + function setShowAddDialog(el: any) { + setIsDialogOpen(el); + } + + if (loading) return ; + return ( <> @@ -191,21 +220,28 @@ const ManageGroups = () => { {/*
*/} -
- {/* */} + +
+ {isReloading && ( +
+
+ + Refreshing data... +
+
+ )} } + toolbar={ + + } layout={{ card: true }} - sorting={[{ id: 'created_at', desc: true }]} serverSide={false} onRowSelectionChange={(selected, table: any) => { const selectedRow = table.getSelectedRowModel().rows[0];