Create /soutyen page
This commit is contained in:
@@ -0,0 +1,253 @@
|
||||
import {useEffect, useState, forwardRef, useRef} from 'react'
|
||||
import {useRouter} from 'next/router'
|
||||
import PropTypes from 'prop-types'
|
||||
import {loadStripe} from '@stripe/stripe-js'
|
||||
import {Elements} from '@stripe/react-stripe-js'
|
||||
import {Box, Container, Typography, Snackbar, LinearProgress, Paper} from '@mui/material'
|
||||
import MuiAlert from '@mui/material/Alert'
|
||||
import axios from 'axios'
|
||||
|
||||
import HeadLayout from '../components/head-layout'
|
||||
import CheckoutForm from '../components/soutyen/checkout-form'
|
||||
import Presantasyon from '../components/soutyen/presantasyon'
|
||||
import Don from '../components/soutyen/don'
|
||||
import PaymentMethod from '../components/soutyen/payment-method'
|
||||
import Footer from '../components/footer'
|
||||
|
||||
import {appearance} from '../lib/utils/stripe-style'
|
||||
|
||||
const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3001'
|
||||
|
||||
const stripePromise = loadStripe(
|
||||
process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY
|
||||
)
|
||||
|
||||
const Alert = forwardRef(function Alert(props, ref) {
|
||||
return <MuiAlert ref={ref} elevation={6} variant='filled' {...props} />
|
||||
})
|
||||
|
||||
export default function Soutyen({prices, paymentStatus}) {
|
||||
const router = useRouter()
|
||||
const scrollEvent = useRef(null)
|
||||
const [clientSecret, setClientSecret] = useState(null)
|
||||
const [paymentIntent, setPaymentIntent] = useState(null)
|
||||
const [isPaypal, setIsPaypal] = useState(true)
|
||||
const [selectedMontant, setSelectedMontant] = useState(null)
|
||||
const [validMontant, setValidMontant] = useState(null)
|
||||
const [success, setSuccess] = useState(null)
|
||||
const [error, setError] = useState(null)
|
||||
const [open, setOpen] = useState(false)
|
||||
const [payementIsReady, setPaymentIsReady] = useState(false)
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [clientEmail, setClientEmail] = useState('')
|
||||
|
||||
const scrollToBottom = () => {
|
||||
scrollEvent.current?.scrollIntoView({behavior: 'smooth', block: 'end', inline: 'nearest'})
|
||||
}
|
||||
|
||||
const options = {
|
||||
clientSecret,
|
||||
appearance,
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const getClientSecret = async () => {
|
||||
try {
|
||||
const response = await axios.post('/stripe/valid-payment', {
|
||||
id: validMontant,
|
||||
email: clientEmail
|
||||
})
|
||||
setClientSecret(response.data.clientSecret)
|
||||
setPaymentIntent(response.data.paymentIntent)
|
||||
} catch (error_) {
|
||||
setError(error_.message)
|
||||
}
|
||||
}
|
||||
|
||||
if (validMontant) {
|
||||
getClientSecret()
|
||||
}
|
||||
}, [selectedMontant, clientEmail, validMontant])
|
||||
|
||||
const handleClose = (event, reason) => {
|
||||
if (reason === 'clickaway') {
|
||||
return
|
||||
}
|
||||
|
||||
setSuccess(null)
|
||||
setError(null)
|
||||
setOpen(false)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (isPaypal) {
|
||||
setSelectedMontant(null)
|
||||
setValidMontant(null)
|
||||
}
|
||||
}, [isPaypal, setSelectedMontant, setValidMontant])
|
||||
|
||||
useEffect(() => {
|
||||
if (paymentStatus) {
|
||||
switch (paymentStatus) {
|
||||
case 'succeeded':
|
||||
setSuccess('Paiement réussi. Merci pour votre soutien 🥰')
|
||||
break
|
||||
case 'processing':
|
||||
setSuccess('Votre paiement en cours de traitement.')
|
||||
break
|
||||
case 'requires_payment_method':
|
||||
setError('Votre paiement n’a pas abouti, veuillez réessayer.')
|
||||
break
|
||||
default:
|
||||
setError('Une erreur s’est produite.')
|
||||
break
|
||||
}
|
||||
} else {
|
||||
setSuccess(null)
|
||||
setError(null)
|
||||
}
|
||||
}, [paymentStatus, router])
|
||||
|
||||
useEffect(() => {
|
||||
if (success) {
|
||||
setOpen(true)
|
||||
} else {
|
||||
setOpen(false)
|
||||
}
|
||||
}, [success])
|
||||
|
||||
useEffect(() => {
|
||||
if (error) {
|
||||
setOpen(true)
|
||||
} else {
|
||||
setOpen(false)
|
||||
}
|
||||
}, [error])
|
||||
|
||||
useEffect(() => {
|
||||
router.push('/soutyen', undefined, {shallow: true})
|
||||
}, []) // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
useEffect(() => {}, [router.query.payment_intent])
|
||||
|
||||
useEffect(() => {
|
||||
if (!isPaypal || validMontant) {
|
||||
scrollToBottom()
|
||||
}
|
||||
}, [isPaypal, validMontant])
|
||||
|
||||
useEffect(() => {
|
||||
if (payementIsReady) {
|
||||
scrollToBottom()
|
||||
}
|
||||
}, [payementIsReady])
|
||||
|
||||
return (
|
||||
<HeadLayout
|
||||
title='Soutenir Organisation KA Internationale !'
|
||||
tab={4}
|
||||
slug='soutyen'
|
||||
imageUrl='/soutyen.png'
|
||||
imageWidth={500}
|
||||
imageHeight={500}
|
||||
>
|
||||
<Box sx={{display: 'flex', flexDirection: 'column', minHeight: '100vh'}}>
|
||||
<Box sx={{flexGrow: 1, marginTop: 1, marginBottom: 10}}>
|
||||
<Container sx={{marginTop: 1}}>
|
||||
<Typography gutterBottom sx={{fontWeight: 'bold'}} textAlign='center' variant='h4' component='h1'>
|
||||
Soutenir Organisation KA Internationale !
|
||||
</Typography>
|
||||
<Presantasyon />
|
||||
<Paper sx={{padding: 2, marginTop: 3}}>
|
||||
<Typography gutterBottom sx={{fontWeight: 'bold', marginBottom: 2}} textAlign='center' variant='h5' component='h2'>
|
||||
Faire un don
|
||||
</Typography>
|
||||
<Box sx={{textAlign: 'center'}}>
|
||||
<PaymentMethod setIsPaypal={setIsPaypal} />
|
||||
</Box>
|
||||
<Don
|
||||
isPaypal={isPaypal}
|
||||
selectedMontant={selectedMontant}
|
||||
setSelectedMontant={setSelectedMontant}
|
||||
validMontant={validMontant}
|
||||
setValidMontant={setValidMontant}
|
||||
prices={prices}
|
||||
paymentIntent={paymentIntent}
|
||||
clientSecret={clientSecret}
|
||||
setClientSecret={setClientSecret}
|
||||
setPaymentIntent={setPaymentIntent}
|
||||
setIsLoading={setIsLoading}
|
||||
setPaymentIsReady={setPaymentIsReady}
|
||||
error={error}
|
||||
setError={setError}
|
||||
clientEmail={clientEmail}
|
||||
setClientEmail={setClientEmail}
|
||||
/>
|
||||
{isLoading && (
|
||||
<Container maxWidth='sm'>
|
||||
<LinearProgress size={24} style={{width: '100%', marginBottom: 1}} />
|
||||
</Container>
|
||||
)}
|
||||
|
||||
{clientSecret && validMontant && !isPaypal && (
|
||||
<Elements options={options} stripe={stripePromise}>
|
||||
<CheckoutForm
|
||||
setPaymentIsReady={setPaymentIsReady}
|
||||
setError={setError}
|
||||
isLoading={isLoading}
|
||||
setIsLoading={setIsLoading}
|
||||
/>
|
||||
</Elements>
|
||||
)}
|
||||
</Paper>
|
||||
</Container>
|
||||
</Box>
|
||||
<Footer />
|
||||
</Box>
|
||||
<div ref={scrollEvent} id='to-scroll' />
|
||||
{(success || error) && (
|
||||
<Snackbar open={open} autoHideDuration={10_000} onClose={handleClose}>
|
||||
<Alert severity={success ? 'success' : 'error'} onClose={handleClose}>
|
||||
<strong>{success || error}</strong>
|
||||
</Alert>
|
||||
</Snackbar>
|
||||
)}
|
||||
</HeadLayout>
|
||||
)
|
||||
}
|
||||
|
||||
Soutyen.defaultProps = {
|
||||
paymentStatus: null
|
||||
}
|
||||
|
||||
Soutyen.propTypes = {
|
||||
prices: PropTypes.array.isRequired,
|
||||
paymentStatus: PropTypes.string
|
||||
}
|
||||
|
||||
export async function getServerSideProps({query}) {
|
||||
const {payment_intent, payment_intent_client_secret} = query
|
||||
const prices = await fetch(`${SITE_URL}/stripe/dons-list`)
|
||||
let payment
|
||||
if (payment_intent && payment_intent_client_secret) {
|
||||
const paymentResponse = await fetch(`${SITE_URL}/stripe/check-payment`, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({
|
||||
payment_intent
|
||||
})
|
||||
})
|
||||
|
||||
payment = await paymentResponse.json()
|
||||
if (!payment) {
|
||||
throw new Error('Une erreur sest produite')
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
prices: await prices.json(),
|
||||
paymentStatus: payment?.status || null
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user