import * as Yup from 'yup'; import { useFormik } from 'formik'; import { useNavigate, useParams } from 'react-router-dom'; import { useEffect, useState } from 'react'; import { useLazyQuery, useReactiveVar } from '@apollo/client'; import { Navigate } from 'react-router'; import { roleVar } from '../../graphql/state'; import { Wrapper } from './styles'; import { Alert, Box, Button, Input, Spinner, Text } from '../../components'; import { ArrowLeft } from '../../assets'; import { GetProjectByIdQuery, GetProjectByIdQueryVariables, ProjectOutput, } from '../../graphql/types'; import { GET_PROJECT_BY_ID } from '../../graphql/project.api'; type Transaction = { amount: number; created: boolean; selectedOption: number; _id: string; }; type TransactionData = { transactions: Array; remaining_amount: number; amount: number; project_id: string; status: boolean; total_amount: number; _id: string; }; const Payments = () => { const role = useReactiveVar(roleVar); const navigate = useNavigate(); const { id } = useParams<{ id: string }>(); const [project, setProject] = useState(); const [success, setSuccess] = useState(false); const [error, setError] = useState(''); const [transactionsData, setTransactionsData] = useState(); const [selectedChunk, setSelectedChunk] = useState(); const [paymentLoading, setPaymentLoading] = useState(false); const [getProject, { loading: projectLoading }] = useLazyQuery< GetProjectByIdQuery, GetProjectByIdQueryVariables >(GET_PROJECT_BY_ID, { onCompleted({ getProjectById }) { setProject(getProjectById); } }); useEffect(() => { (async () => { if (id) { getProject({ variables: { id } }); try { const transactionsResult = await ( await fetch(`${import.meta.env.VITE_PAYMENT_API}/transactions`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ project_id: id }), }) ).json(); if (transactionsResult) setTransactionsData(transactionsResult); } catch (err) { console.error(err); } } })(); // eslint-disable-next-line }, [id]); const paymentForm = useFormik({ initialValues: { number: '', expMonth: '', expYear: '', cvc: '', }, validationSchema: Yup.object().shape({ number: Yup.number() .typeError('Card Number must be a number') .required('Card Number is required'), expMonth: Yup.number() .typeError('Expiary Month must be a number') .required('Expiary Month is required'), expYear: Yup.number() .typeError('Expiary Year must be a number') .required('Expiary Year is required'), cvc: Yup.number() .typeError('CVC must be a number') .required('CVC is required'), }), onSubmit: async ({ number, expMonth, expYear, cvc }, { resetForm }) => { try { setPaymentLoading(true); let amount = 0; switch (selectedChunk) { case 0: { amount = (project?.paymentOption.optOne! * project?.totalPrice!) / 100; break; } case 1: { amount = (project?.paymentOption.optTwo! * project?.totalPrice!) / 100; break; } case 2: { amount = (project?.paymentOption.optThree! * project?.totalPrice!) / 100; break; } default: break; } const transactionsResult = await ( await fetch(`${import.meta.env.VITE_PAYMENT_API}/charge`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ project_id: project?.id, total_amount: project?.totalPrice, selectedOption: selectedChunk, amount, card: { number, exp_month: expMonth, exp_year: expYear, cvc, }, }), }) ).json(); if (transactionsResult) { setPaymentLoading(false); setTransactionsData(transactionsResult); setSuccess(true); setSelectedChunk(undefined); resetForm(); setTimeout(() => setSuccess(false), 3000); } } catch (err) { setPaymentLoading(false); setError(err as string); setSelectedChunk(undefined); resetForm(); setTimeout(() => setError(''), 3000); } }, }); return role === 'client' ? ( <> {!projectLoading ? (