diff --git a/package.json b/package.json index 43c45d3..bc73844 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "date-fns": "^3.0.0", "formik": "^2.4.6", "helmet": "^8.1.0", + "html2canvas": "^1.4.1", "https": "^1.0.0", "leaflet": "^1.9.4", "lucide-react": "^0.456.0", diff --git a/public/media/images/card.png b/public/media/images/card.png new file mode 100644 index 0000000..2ec5af6 Binary files /dev/null and b/public/media/images/card.png differ diff --git a/src/pages/members/agent-balance/AgentBalance.tsx b/src/pages/members/agent-balance/AgentBalance.tsx index 1c03506..ee5971b 100644 --- a/src/pages/members/agent-balance/AgentBalance.tsx +++ b/src/pages/members/agent-balance/AgentBalance.tsx @@ -2,6 +2,7 @@ import { DataTable } from '@/components/ui/DataTable'; import { getColumns } from './Column'; import { apiConfig } from '@/config/api.config'; import axios, { AxiosResponse } from 'axios'; +import html2canvas from 'html2canvas'; import { Helmet } from 'react-helmet'; import { DialogContent, @@ -18,7 +19,7 @@ import { Breadcrumbs, Link } from '@mui/material'; -import { useState, useEffect } from 'react'; +import { useState, useEffect, useRef } from 'react'; import CloseIcon from '@mui/icons-material/Close'; import Divider from '@mui/material/Divider'; import ConfirmDialog from '@/components/confirm'; @@ -27,6 +28,7 @@ import { Container, DataGridLoader, DataGridProvider, LoaderTransparant } from ' import { ListToolBar } from './ListToolbar'; import { RefreshCw } from 'lucide-react'; import { setgroups } from 'process'; +import { toAbsoluteUrl } from '@/utils'; const BASE_URL = apiConfig.service_customer; let initBalance = { @@ -51,6 +53,8 @@ const AgentBalance = () => { const [dialogType, setDialogType] = useState(''); const [dialogOpen, setDialogOpen] = useState(false); const [isReloading, setIsReloading] = useState(false); + const [barcode, setBarcode] = useState(''); + // const [selectedMember, setSelectedMember] = useState(initBalance); useEffect(() => { fetchAgentBalance(); @@ -94,7 +98,9 @@ const AgentBalance = () => { openDialog(); } - const handleUpdate = (group: any) => { + const handleUpdate = async (data: any) => { + await getQrCode(data.id); + setFormData(data) setDialogType('update'); setIsDialogOpen(true); }; @@ -104,6 +110,18 @@ const AgentBalance = () => { fetchAgentBalance(); }; + async function getQrCode(customerId:any): Promise { + try { + setBarcode(`https://img.freepik.com/free-vector/scan-me-qr-code_78370-2915.jpg?semt=ais_hybrid&w=740`) + let getToken = await axios.get(`${BASE_URL}/token/get`, { params: { id: customerId }}); + console.log(getToken.data.data); + // setBarcode(getToken.data.data.qrCode); + } catch (error: any) { + toast.warning(error.message) + console.log(error); + } + } + if (loading) return ; return ( @@ -160,78 +178,134 @@ const AgentBalance = () => { {/* */} - {/* - -
- - {dialogType === 'create' ? 'Create New Group' : 'Update Group'} - - - - -
- -
-
-
- - -
-
- - - - } - label="Yes" - /> - } - label="No" - /> - - -
-
- - -
- -
+ + +
+
-
*/} +
); }; +const PaymentCard = ({ barcode, agent_name, customerId }:any) => { + const cardRef:any = useRef(null); + // useEffect(() => { + // fetchToken(); + // }, []); + + // async function fetchToken(): Promise { + // try { + // let getToken = await axios.get(`${BASE_URL}/token/get`, { params: { id: customerId }}); + // console.log(getToken.data.data); + // // setBarcode(getToken.data.data.qrCode); + // setBarcode(`https://img.freepik.com/free-vector/scan-me-qr-code_78370-2915.jpg?semt=ais_hybrid&w=740`) + // } catch (error: any) { + // toast.warning(error.message) + // console.log(error); + // } + // } + + const handleDownload = async () => { + if (!cardRef.current) return; + + const img = cardRef.current.querySelector('img'); + if (!img || !img.complete) { + // Wait until the barcode image has fully loaded + await new Promise((resolve) => { + img.onload = resolve; + }); + } + + const canvas = await html2canvas(cardRef.current, { + useCORS: true, // Important for external images + }); + + const dataUrl = canvas.toDataURL('image/png'); + const link = document.createElement('a'); + link.href = dataUrl; + link.download = `${agent_name}_barcode_card.png`; + link.click(); + }; + + + return ( +
+ {/* Card content to render */} +
+
+

+ {agent_name} +

+ + {barcode && ( + Barcode + )} +
+
+ + {/* Download Button */} + +
+ ); + + return ( +
+
+

+ {agent_name} +

+ {barcode && ( + Barcode + )} +
+
+ ); + + // return ( + //
+ // {/* Background Card Image */} + // Card Template + + // {/* Content Overlay */} + //
+ // {/* Agent Name at Top */} + //

+ // {agent_name} + //

+ + // {/* Barcode */} + // {barcode && ( + // Barcode + // )} + //
+ //
+ // ); +}; + export default AgentBalance; diff --git a/src/pages/members/agent-balance/Column.tsx b/src/pages/members/agent-balance/Column.tsx index a188e8b..53b75a8 100644 --- a/src/pages/members/agent-balance/Column.tsx +++ b/src/pages/members/agent-balance/Column.tsx @@ -143,4 +143,15 @@ export const getColumns = (handleUpdate: (data: any) => void): ColumnDef { + const dataMembers = row.original; + return ( + + ); + } + } ]; diff --git a/src/pages/members/manage-members/ManageMembers.tsx b/src/pages/members/manage-members/ManageMembers.tsx index 42937ae..0e58214 100644 --- a/src/pages/members/manage-members/ManageMembers.tsx +++ b/src/pages/members/manage-members/ManageMembers.tsx @@ -121,22 +121,7 @@ const ManageMembers = () => { sorting: any, filter: any ) => { - // [ SAMPLE - // { - // "id": "username", - // "value": "d" - // }, - // { - // "id": "group_name", - // "value": "Bank" - // }, - // { - // "id": "msisdn", - // "value": "88" - // } - // ] sorting = sorting.length == 0 ? [{ id: 'name', desc: true }] : sorting; - // filter = filter.length ? { any: filter[0].value?.toLowerCase() } : {}; filter = filter.length ? filter : {}; const res = await axios.get(`${BASE_URL}/customer/list`, { diff --git a/src/pages/members/manage-members/blocks/DetailMember.tsx b/src/pages/members/manage-members/blocks/DetailMember.tsx index f00a005..64e8fa0 100644 --- a/src/pages/members/manage-members/blocks/DetailMember.tsx +++ b/src/pages/members/manage-members/blocks/DetailMember.tsx @@ -49,7 +49,7 @@ const DetailMember = ({ showAddDialog, setShowAddDialog, handleSubmit, initialDa img: '' }); const [banks] = useState([ - { name: 'BNCTL',id: 'BNCTL' }, { name: 'BRI',id: 'BRI' }, { name: 'BNU',id: 'BNU' }, { name: 'Mandiri',id: 'Mandiri' } + { name: 'BNCTL',id: 'BNCTL' }, { name: 'BRI',id: 'BRI' }, { name: 'BNU',id: 'BNU' }, { name: 'MANDIRI',id: 'MANDIRI' } ]) const parentRef = useRef(null); const [alert, setAlert] = useState({ @@ -214,7 +214,7 @@ const DetailMember = ({ showAddDialog, setShowAddDialog, handleSubmit, initialDa {(formData.id || dialogType === "create") ? generateImage(formData, handleChange, 'Photo', 'photouser', previewImg, setPreviewImg): ''} {(formData.id || dialogType === "create") ? generateList(formData, handleChange, genders, 'gender', 'Gender', true, false): ''} {(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Date of Birth', 'date_birth', 'date', true, viewOnly): ''} - {(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Phone Number', 'msisdn', 'text', true, dialogType === "create"||false): ''} + {(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Phone Number', 'msisdn', 'text', true, dialogType === "create"?false:true): ''} {(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Email', 'email', 'text', true, viewOnly): ''} {/* {generateList(formData, handleChange, status, 'status', 'Status', null, true)} */} {(formData.id || dialogType === "create") ? generateInput(formData, handleChange, 'Mother Fullname', 'mother_fullname', 'text', true, viewOnly): ''}