import React, { useEffect } from 'react' import { Box, Button, Stack, SimpleGrid, Flex, Center, Divider, Switch, Text, } from '@chakra-ui/react' import { defineComponent, useActionTrigger } from '@qorebase/app-component' import Item from './components/Item.js' import LoaderItem from './components/LoaderItem.js' import BrowseClass from './components/BrowseClass.js' import { formatCurrency, formatNumber } from './utils/functions.js' import Server from './utils/api-call.js' import { Cart, Order } from './types.js' /* == AMBIGOUSIM_VARIABLES === a. orderId form props and orderHistoryId http call resutl stored on state b. ganara point from props or get user call */ interface IPropsDataValidation { isValid: boolean message: string } export default defineComponent({ name: 'Ganara Cart Component', type: 'list', icon: 'iconX', group: 'list', defaultProps: { header: 'List', orderId: 'Order ID', orderRowId: 'Order Row ID', userId: 'User ID', title: 'Title', price: 'Price', location: 'Location', date: 'Date', actionBrowseClass: [{ type: 'none' }], actionInsertPointHistory: [{ type: 'none' }], actionPayment: [{ type: 'none' }], }, propDefinition: { header: { type: 'string', options: { format: 'text', }, }, orderId: { type: 'string', options: { format: 'text', }, }, orderRowId: { type: 'string', options: { format: 'text', }, }, userId: { type: 'string', options: { format: 'text', }, }, title: { group: 'Design', type: 'expression', options: { format: 'text' } }, price: { group: 'Design', type: 'expression', options: { format: 'text' } }, location: { group: 'Design', type: 'expression', options: { format: 'text' }, }, date: { group: 'Design', type: 'expression', options: { format: 'text' } }, actionBrowseClass: { group: 'Action', type: 'action', label: 'Browse Class', options: [{ type: 'none' }], }, actionInsertPointHistory: { group: 'Action', type: 'action', label: 'Point History', options: [{ type: 'none' }], }, actionPayment: { group: 'Action', type: 'action', label: 'Payment Action', options: [{ type: 'none' }], }, }, Component: (props) => { const client = props.hooks.useClient() const orderId: string | number = props.hooks.useEvaluate( props.properties.orderId, ) const orderRowId: string | number = props.hooks.useEvaluate( props.properties.orderRowId, ) const userId: string | number = props.hooks.useEvaluate( props.properties.userId, ) const [order, setOrder] = React.useState() const [carts, setCarts] = React.useState([]) const [isLoad, setIsLoad] = React.useState(true) const [allSubtotal, setAllSubtotal] = React.useState(0) const [ganaraPoint, setGanaraPoint] = React.useState(0) const [checkedGanaraPoint, setCheckedGanaraPoint] = React.useState( false, ) const [linkPage, setLinkPage] = React.useState('') const [onLoadProcess, setOnLoadProcess] = React.useState(false) const [dataValidation, setDataValidation] = React.useState< IPropsDataValidation >({ isValid: true, message: '' }) React.useEffect(() => { if (!dataValidation.isValid) return if ( (checkedGanaraPoint && ganaraPoint > allSubtotal) || allSubtotal == 0 ) { setLinkPage('Iq2') } else { setLinkPage('ku1') } }, [checkedGanaraPoint, ganaraPoint, allSubtotal, dataValidation]) const actionXenditPayment = useActionTrigger( // props.properties.actionPayment, [ { actionName: 'gcf_xendit_payment', notification: { onSuccess: { description: 'Your request successfully executed', title: 'Success', }, onFail: { description: 'Oops, there is something wrong!', title: 'Failed', }, }, onFail: { type: 'none' }, payload: { ganara_point: checkedGanaraPoint.toString() }, showNotification: false, type: 'trigger_action', }, //@ts-ignore { pageID: `${linkPage}`, rowID: `${orderRowId}`, type: 'jump_to_page', params: { rowId: `${orderRowId}`, }, }, ], props.data.page.row, props.pageSource, ) const actionInsertPointHistory = useActionTrigger( props.properties.actionInsertPointHistory, props.data.page.row, props.pageSource, ) const actionBrowseClass = useActionTrigger( props.properties.actionBrowseClass, props.data.page.row, props.pageSource, ) const getUserData = async (userId: string | number) => { const userData = await Server.getUserData(client, userId) if (userData.length > 0) { setGanaraPoint(userData[0]?.ganara_point) } } const getCartData = async ( userId: number | string, orderRowId: number | string, ) => { try { if (!userId || !orderRowId) return console.log(userId, `userId`) console.log(orderRowId, `orderRowId`) const sourceFromGCF = await client.project.axios.post( `https://staging-qore-data-hair-353194.qore.dev/v1/action/order_history/gcf_order_carts_validation/${orderRowId}`, { args: { userId: userId, orderRowId: orderRowId }, }, { headers: { Accept: 'application/json, text/plain, */*', 'x-qore-engine-admin-secret': 'cBfO0PFdM65CfHTknZT5oYxf3y9G4JCW', 'Content-Type': 'application/json', }, }, ) const status = sourceFromGCF.data.result?.statusText const carts = sourceFromGCF.data.result.data?.carts || [] const order = sourceFromGCF.data.result.data?.order || [] const invalid: any = [] if (status == 200) { setCarts(carts) setOrder(order[0]) setIsLoad(false) let cartSubtotal = 0 for (let i = 0; i < carts.length; i++) { const item = carts[i] let count = Number(item.qty) * Number(item.price) cartSubtotal += count count = 0 if (item.isReachMaxedQuota) { invalid.push(item.isReachMaxedQuota) } } if (invalid.includes(true)) { setDataValidation({ isValid: false, message: "there's Class has reached maximum quota, please remove the class from cart to proceeds", }) } setAllSubtotal(cartSubtotal) } return status } catch (error) { console.log(`empty Cart`) // setCarts([]) setIsLoad(false) console.log(error) } } React.useEffect(() => { if (!orderRowId && userId) { setIsLoad(false) setCarts([]) } if (!userId || !orderRowId) return setIsLoad(true) ;(async () => { await getUserData(userId) await getCartData(userId, orderRowId) })() }, [userId, orderRowId]) const handlePayment = async ( orderRowId: string | number, orderData: { userId: string | number is_use_ganara_point: boolean use_ganara_point: number }, ) => { try { setOnLoadProcess(true) const checkValidationClass = await getCartData( orderData?.userId, orderRowId, ) if (checkValidationClass !== 200) { setDataValidation({ isValid: false, message: 'Oops, a Class is Ended, please Check your class schedule', }) throw new Error('Error') } const { userId, is_use_ganara_point, use_ganara_point } = orderData if (!orderRowId || !userId) return if (is_use_ganara_point && use_ganara_point == 0) return const validateBeforeCheckout = await client.project.axios.post( `https://staging-qore-data-hair-353194.qore.dev/v1/action/order_history/gcf_checkout_cart_validation/${orderRowId}`, { args: { is_use_ganara_point: orderData.is_use_ganara_point, use_ganara_point: orderData.use_ganara_point, userId: orderData.userId, orderId: orderRowId, }, }, { headers: { Accept: 'application/json, text/plain, */*', 'x-qore-engine-admin-secret': 'cBfO0PFdM65CfHTknZT5oYxf3y9G4JCW', 'Content-Type': 'application/json', }, }, ) const httpCallStatus = validateBeforeCheckout.data.result.status const validateResult = validateBeforeCheckout.data.result.response if (httpCallStatus !== 200) { setOnLoadProcess(false) return } if (validateResult.isValid) { console.log('VALIDATION: VALID') console.log('<<< CALL_XENDIT_INVOICE_HERE >>>') await actionXenditPayment.handleClick() setDataValidation({ isValid: true, message: 'OK' }) } else { console.log('VALIDATION: INVALID') setDataValidation({ isValid: false, message: validateResult.message, }) setOnLoadProcess(false) } } catch (error) { console.log(error) } } console.log({ compVersion: '1.1.22', linkPage }) return ( {isLoad ? ( ) : carts.length > 0 ? ( {carts.map((item: any) => ( ))} Purchase Details
Order ID {order?.order_id}
Subtotal {formatCurrency(allSubtotal)}
Ganara Points {checkedGanaraPoint ? Number(ganaraPoint) >= Number(allSubtotal) ? formatNumber(allSubtotal) : formatNumber(ganaraPoint) : 0}
Grand Total {checkedGanaraPoint ? Number(ganaraPoint) >= Number(allSubtotal) ? formatCurrency(0) : formatCurrency(allSubtotal - ganaraPoint) : formatCurrency(allSubtotal)}
{Number(ganaraPoint) == 0 ? ( {Number(allSubtotal) == 0 ? (
Ganara Points { setCheckedGanaraPoint(e.currentTarget.checked) }} data-test="toggle-button" justifyContent="right" />
{formatNumber(ganaraPoint)}
) : (
Ganara Points
{formatNumber(ganaraPoint)}
)}
) : (
Ganara Points { setCheckedGanaraPoint(e.currentTarget.checked) }} data-test="toggle-button" justifyContent="right" />
{formatNumber(ganaraPoint)}
)} {!dataValidation.isValid && ( Oops, {dataValidation.message} ! ) )} Total {checkedGanaraPoint ? Number(ganaraPoint) >= Number(allSubtotal) ? formatCurrency(0) : formatCurrency(allSubtotal - ganaraPoint) : formatCurrency(allSubtotal)}
) : ( )}
) }, })