I am currently learning to build e-commerce webapp with react, the tutorial material I am using used stripe as payment gateway, but I want to use Paystack instead. but I don't know how to code my way through it, perhaps there's a universal method to integrate a payment gateway into react?
Install react-paystack library using NPM or YARN . And this is all you need for the popup setup for more on this in detail view the Paystack documentation from where this code was posted initially Paystack React.
At the moment I can only see a popup implementation for Paystack since Paystack.js is now deprecated.
import React, { useState } from "react"
import { PaystackButton } from "react-paystack"
import "./App.css"
const App = () => {
const publicKey = "pk_test_4fc00f3df93a5f8efeb57bdd70605937312a029e"
const amount = 1000000
const [email, setEmail] = useState("")
const [name, setName] = useState("")
const [phone, setPhone] = useState("")
const componentProps = {
email,
amount,
metadata: {
name,
phone,
},
publicKey,
text: "Buy Now",
onSuccess: () => {
setEmail("")
setName("")
setPhone("")
},
onClose: () => alert("Wait! You need this oil, don't go!!!!"),
}
return (
<div className="App">
<div className="container">
<div className="item">
<div className="overlay-effect"></div>
<img
className="item-image"
src="https://images.unsplash.com/photo-1526947425960-945c6e72858f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2850&q=80"
alt="product"
/>
<div className="item-details">
<p className="item-details__title">Coconut Oil</p>
<p className="item-details__amount">NGN {amount / 100}</p>
</div>
</div>
<div className="checkout">
<div className="checkout-form">
<div className="checkout-field">
<label>Name</label>
<input
type="text"
id="name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</div>
<div className="checkout-field">
<label>Email</label>
<input
type="text"
id="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div className="checkout-field">
<label>Phone</label>
<input
type="text"
id="phone"
value={phone}
onChange={(e) => setPhone(e.target.value)}
/>
</div>
<PaystackButton className="paystack-button" {...componentProps} />
</div>
</div>
</div>
</div>
)
}
export default App
Related
Hello guys so i tried to make global state so the other page can use the state. The problem is i got an error that says:
Login.js:18 Uncaught TypeError: Cannot destructure property 'emailLog' of '(0 , react__WEBPACK_IMPORTED_MODULE_0__.useContext)(...)' as it is undefined.
Im doing this because i want the email from user after logged in and pass them to another page so that i can display the logged in user.
App.js:
export const EmailUser = React.createContext();
function App() {
Axios.defaults.withCredentials = true;
const [invoice, setInvoice] = useState("");
const [currency, setCurrency] = useState("IDR");
const [myFile, setMyFile] = useState("");
const [emailLog, setEmailLog] = useState("");
return (
<EmailUser.Provider value={{ emailLog, setEmailLog }}>
<div className="App">
<BasicExample />
<div className="formInput">
<form method="POST" encType="multipart/form-data" action="http://localhost:3001/upload">
<div className="textUser"></div>
<input
className="inputForm"
defaultValue={emailLog}
type="email"
disabled
name="email"
/>
<input className="inputForm" type="number" placeholder="Invoice No" name="InvoiceNo" />
<input className="inputForm" type="date" name="Invoice_Date" />
<input className="inputForm" type="text" placeholder="Description" name="Description" />
<select
className="selectBox"
name="Currency"
onChange={(e) => {
setCurrency(e.target.value);
}}
>
<option value="IDR">IDR</option>
<option value="USD">USD</option>
<option value="YEN">YEN</option>
</select>
<input className="inputForm" type="number" placeholder="Amount" name="Amount" />
<input
className="custom-file-upload"
multiple
type="file"
name="DocumentFile"
onChange={(e) => {
setMyFile(e.target.value);
}}
/>
<button className="btnSubmit">Submit</button>
</form>
</div>
</div>
</EmailUser.Provider>
);
}
export default App;
Login.js
const Login = () => {
let navigate = useNavigate();
const { emailLog, setEmailLog } = useContext(EmailUser);
const [passwordLog, setPasswordLog] = useState("");
const [loginStatus, setLoginStatus] = useState("");
Axios.defaults.withCredentials = true;
const login = (e) => {
e.preventDefault();
Axios.post("http://localhost:3001/login", {
email: emailLog,
password: passwordLog,
}).then((response) => {
console.log(response);
if (response.data.message) {
alert(response.data.message);
} else {
setLoginStatus(response.data[0].email);
alert("Redirecting");
navigate("/home");
}
});
};
console.log(emailLog);
useEffect(() => {
Axios.get("http://localhost:3001/login").then((response) => {
if (response.data.loggedIn == true) {
setLoginStatus(response.data.email[0].email);
}
});
});
return (
<div>
<img className="wave" src={Wave} />
<img className="wave2" src={WaveV2} />
<div className="wrapper">
<div className="img">{/* <img src={Background}/> */}</div>
<div className="register-content">
<div className="registerForm">
<img src={Avatar} />
<h2 className="title">Welcome</h2>
<div className="input-div one">
<div className="i">
<i className="fas fa-user">
<GrMail />
</i>
</div>
<div className="div">
<input
type="email"
className="input"
placeholder="Email"
required
onChange={(e) => {
setEmailLog(e.target.value);
}}
/>
</div>
</div>
<div className="input-div pass">
<div className="i">
<i className="fas fa-lock">
<AiFillLock />
</i>
</div>
<div className="div">
<input
type="password"
className="input"
placeholder="Password"
required
onChange={(e) => {
setPasswordLog(e.target.value);
}}
/>
</div>
</div>
Don't have an account ?
<button type="submit" className="btn" onClick={login}>
Login
</button>
</div>
</div>
</div>
</div>
);
};
export default Login;
EmailUser context works only with the components that are children of EmailUser.Provider, and it doesn't seem to be the case for Login component. An easy way is to create a separate component, in some EmailUserProvider.js, like so:
import {createContext, useState} from "react"
export const EmailUser = createContext();
export default function EmailUserProvider({children}) {
const [emailLog, setEmailLog] = useState("");
return (
<EmailUser.Provider value={{ emailLog, setEmailLog }}>
{children}
</EmailUser.Provider>
);
}
And make it wrap all the components that would consume it. If I assume all my components and routes are rendered in App and want the context to be global, I would do so:
<EmailUserProvider>
<App/>
</EmailUserProvider>
staffForm.js
import React from 'react'
import { Link } from 'react-router-dom';
const StaffForm = ({handleSubmit},props) => {
// console.log(props);
const title = props.title;
const link =props.link;
return (
<section>
<div class="Employewrapper">
<div class="title">
{title} registration
</div>
<form class="form" onSubmit={handleSubmit} encType='multipart/form-data'>
<div class="inputfield">
<label>First Name</label>
<input required type="text" class="input" name='first_name'/>
</div>
<div class="inputfield">
<label>Last Name</label>
<input required type="text" class="input" name='last_name'/>
</div>
<div class="inputfield">
<label>Email</label>
<input required type="email" class="input" name='email'/>
</div>
<div class="inputfield">
<label>Password</label>
<input required type="password" class="input" name='password'/>
</div>
<div class="inputfield">
<label>Confirm password</label>
<input required type="password" class="input" name='confirm_password'/>
</div>
<div class="inputfield">
<label>Phone</label>
<input required type="tel" class="input" name='phone'/>
</div>
<div class="inputfield">
<label for="file">Profile Picture</label>
<input required type="file" id="file" accept="image/*" class="input" name='profile_picture'/>
</div>
<div class="inputfield">
<label>Birthdate</label>
<input required type="date" class="input" name='birthdate'/>
</div>
<div class="inputfield">
<label for="file">Id Card</label>
<input required type="file" id="file" accept="image/*" class="input" name='identification_card'/>
</div>
<div class="inputfield">
<input required type="submit" class="btn" />
</div>
<Link to={link} className='btn'>Back {title}</Link>
</form>
</div>
</section>
)
}
export default StaffForm;
DeliveryForm.js
import React from 'react'
import { Link } from 'react-router-dom';
import axios from 'axios';
import StaffForm from '../../Components/StaffForm';
import "../../Assets/styles/button.css"
const DeliveryForm = () => {
const url = 'http://127.0.0.1:8000/staff/delivery/';
const handleSubmit = (event)=>{
event.preventDefault();
const data = {
"user": {
"first_name": event.target.first_name.value,
"last_name": event.target.last_name.value,
"email": event.target.email.value,
"password": event.target.password.value,
"confirm_password": event.target.confirm_password.value,
"phone": event.target.phone.value
},
"profile_picture": event.target.profile_picture.files[0],
"birthdate": event.target.birthdate.value,
"identification_card": event.target.identification_card.files[0]
}
axios.request({
method: 'post',
headers: {
"Content-Type": "multipart/form-data",
},
url,
data
}).then(res => {
console.log(res)
})
}
return (
<>
<StaffForm handleSubmit={handleSubmit} title="Delivery" link="/Delivery"/>
</>
)
}
export default DeliveryForm
i have a particular form which i will be using for 3 api's the only difference are the title an the link i know the conventional way of writing props but it seems it not working in this case. on my page its not rendering anything but when i remove the props it works. i tried swithing the position of the props and the {handleSubmit}, when doing that i can see the prop but i can't post.
Just do it as you did with previous things in props.
const StaffForm = (props) => {
const handleSubmit = props.handleSubmit;
const title = props.title;
const link = props.link;
Or you will need to deconstruct everything in one place.
const StaffForm = ({ handleSubmit, title, link }) => {
Why: because props object is the first parameter, always. In my example you deconstruct it, and in your code - you deconstruct only handleSubmit from it and somewhy you were expecting to get a second parameter which you named props. No, only one and only first parameter is your props object.
Additionaly, you can use
const StaffForm = (props) => {
const { handleSubmit, title, link } = props;
or
// Spread operator
const StaffForm = ({handleSubmit, ...props}) => {
const { title, link } = props;
I am having issues with the axios post request. When I click on the Button, nothing happens. What is supposed to happen is that the data that I enter into the input fields is submitted to the API. However, no redirect or anything happens when I click the Button. I am not sure whether the onClick function in the Button is never being triggered or whether the issue lies with the call of axios and then the useNavigate function. I have tried several different ways of using these function but none worked. It might be a syntactic issue as I am a beginner with react. Any help would be appreciated!
Full Code:
import axios from 'axios';
import React, { useState } from 'react';
import { Container, Button } from 'react-bootstrap';
import { useNavigate } from 'react-router-dom';
const AddContact = () => {
const [first_name, setFirstName] = useState("")
const [last_name, setLastName] = useState("")
const [mobile_number, setMobileNumber] = useState("")
const [home_number, setHomeNumber] = useState("")
const [work_number, setWorkNumber] = useState("")
const [email_address, setEmailAddress] = useState("")
const history = useNavigate();
const AddContactInfo = async () => {
let formField = new FormData();
formField.append('first_name', first_name)
formField.append('last_name', last_name)
formField.append('mobile_number', mobile_number)
formField.append('home_number', home_number)
formField.append('work_number', work_number)
formField.append('email_address', email_address)
await axios.post('http://localhost:8000/api/', {
data: formField
}).then(function (response) {
console.log(response.data);
history('/', { replace: true });
})
}
return (
<div>
<h1>Add contact</h1>
<Container>
<div className="form-group">
<input type="text"
className="form-control form-control-lg"
placeholder="Enter Your First Name"
first_name="first_name"
value={first_name}
onChange={(e) => setFirstName(e.target.value)} />
</div>
<div className="form-group">
<input type="text"
className="form-control form-control-lg"
placeholder="Enter Your Last Name"
last_name="last_name"
value={last_name}
onChange={(e) => setLastName(e.target.value)} />
</div>
<div className="form-group">
<input type="text"
className="form-control form-control-lg"
placeholder="Enter Your Mobile Number"
mobile_number="mobile_number"
value={mobile_number}
onChange={(e) => setMobileNumber(e.target.value)} /></div>
<div className="form-group">
<input type="text"
className="form-control form-control-lg"
placeholder="Enter Your Home Number"
home_number="home_number"
value={home_number}
onChange={(e) => setHomeNumber(e.target.value)} /></div>
<div className="form-group">
<input type="text"
className="form-control form-control-lg"
placeholder="Enter Your Work Number"
work_number="work_number"
value={work_number}
onChange={(e) => setWorkNumber(e.target.value)} /></div>
<div className="form-group">
<input type="text"
className="form-control form-control-lg"
placeholder="Enter Your Email Address"
email_address="email_address"
value={email_address}
onChange={(e) => setEmailAddress(e.target.value)} /></div>
<Button onClick={() => { AddContactInfo(); }}>
Add Contact
</Button>
</Container>
</div >
);
};
export default AddContact;
First rename AddContactInfo to addContactInfo and then:
<Button onClick={addContactInfo}>
Add Contact
</Button>
You should correct the method addContactInfo as below:
const AddContactInfo = () => {
let formField = new FormData();
formField.append('first_name', first_name)
formField.append('last_name', last_name)
formField.append('mobile_number', mobile_number)
formField.append('home_number', home_number)
formField.append('work_number', work_number)
formField.append('email_address', email_address)
axios.post('http://localhost:8000/api/', {
data: formField
}).then(function (response) {
console.log(response.data);
history('/', { replace: true });
})
}
Try This:
<Button onClick={AddContactInfo}>
Add Contact
</Button>
import axios from 'axios';
const url = 'http://localhost:8000/api/';
axios.post(url , formField)
.then(response => {
console.log(response.data);
history('/', { replace: true });
})
.catch(({response}) => {
console.log(response);
});
Try calling the function this way :)
<Button onClick={AddContactInfo}>
Add Contact
</Button>
I am brand new to React and things are coming along nicely, but I am getting stuck really badly on this concept. I've been at this point for a couple of days now and I think my brain is just getting overwhelmed by all the new concepts.
I work in a job where I help customers implement some controls that the company sells in their projects. I work with our .NET desktop stuff mostly. My team is doing a side project to create what is basically a StrawPoll clone for the sake of learning React/Node/MongoDB and getting more experience with a full development life cycle since most of what we do is just little code snippets.
I've got some of the basic components set up, but I'm getting really confused when it comes to creating and working with dynamically created components. If someone could show me what to do or explain what to do I would appreciate it so much.
You can find the branch I'm working on here: https://github.com/TylerBarlock/gcCE-Survey/tree/poll-components-cont
The part I'm currently stuck on is in src/Components/Poll/PollCreate.js and PollCreateAnswerOption.js
PollCreate.js:
//Main component for poll creation
import React, { Fragment, useState, useRef } from "react";
import PollCreateAnswerOption from "./PollCreateAnswerOption";
const PollCreate = (props) => {
// const [enteredTitle, setEnteredTitle] = useState("");
// const [enteredDescription, setEnteredDescription] = useState("");
const [enteredAnswer, setEnteredAnswer] = useState("");
const [selectedPrivate, setSelectedPrivate] = useState("");
const [selectedMultiple, setSelectedMultiple] = useState("");
const [selectedLogin, setSelectedLogin] = useState("");
const [selectedIpcheck, setSelectedIpcheck] = useState("");
const enteredTitleRef = useRef();
const enteredDescriptionRef = useRef();
const enteredAnswerRef = useRef();
const titleChangeHandler = (event) => {
//setEnteredTitle(event.target.value);
};
const descriptionChangeHandler = (event) => {
//setEnteredDescription(event.target.value);
};
const answerOptionChangeHandler = (answer) => {
//setEnteredAnswer(answer);
};
const privateSelectedHandler = (event) => {
setSelectedPrivate(event.target.value);
};
const multipleSelectedHandler = (event) => {
setSelectedMultiple(event.target.value);
};
const loginSelectedHandler = (event) => {
setSelectedLogin(event.target.value);
};
const ipcheckSelectedHandler = (event) => {
setSelectedIpcheck(event.target.value);
};
const addAnswerOptionHandler = (event) => {
console.log("add answer clicked");
};
const deleteAnswerOptionHandler = (event) => {
console.log("delete clicked");
};
const onSubmitHandler = (event) => {
//cancel default form submit behavior (reloads page)
event.preventDefault();
const enteredTitle = enteredTitleRef.current.value;
const enteredDescription = enteredDescriptionRef.current.value;
//const enteredAnswer = enteredAnswerRef.current.value;
//object to hold all data about the new poll being created
const newPollData = {
title: enteredTitle,
description: enteredDescription,
answerOptions: [
{
id: enteredAnswer.id,
text: enteredAnswer.text,
},
],
options: {
private: selectedPrivate,
multiple: selectedMultiple,
login: selectedLogin,
ipcheck: selectedIpcheck,
},
};
//send the new poll data up to the Poll component
props.onSaveNewPoll(newPollData);
console.log(newPollData.title);
console.log(newPollData.description);
console.log(newPollData.answerOptions);
};
return (
<React.Fragment>
<form onSubmit={onSubmitHandler}>
<h2 className="mb-4 text-center">Create a Poll</h2>
<div className="text-left">
<div className="grid grid-cols-1 mb-4">
<h4 className="mb-2">Title</h4>
<input
type="text"
placeholder="Ask your question..."
onChange={titleChangeHandler}
ref={enteredTitleRef}
></input>
</div>
</div>
<div className="text-left">
<div className="grid grid-cols-1 mb-4">
<h4 className="mb-2">Description (optional)</h4>
<input
type="text"
placeholder="Describe the poll..."
onChange={descriptionChangeHandler}
ref={enteredDescriptionRef}
></input>
</div>
</div>
<div className="text-left">
<div className="grid grid-cols-1 mb-2 formtext">
<h4 className="mb-2">Answer Options</h4>
<PollCreateAnswerOption
onAnswerOptionChange={answerOptionChangeHandler}
ref={enteredAnswerRef}
onAnswerOptionDelete={deleteAnswerOptionHandler}
/>
<div className="flex">
<input
type="text"
className="mb-3 formtext w-full"
placeholder="Add an answer..."
onChange={answerOptionChangeHandler}
></input>
<button
className="btn-alt-onwhite p-1 h-9"
type="button"
onClick={deleteAnswerOptionHandler}
>
X
</button>
</div>
<div className="flex">
<input
type="text"
className="mb-3 formtext w-full"
placeholder="Add an answer..."
onChange={answerOptionChangeHandler}
></input>
<button
className="btn-alt-onwhite p-1 h-9"
type="button"
onClick={deleteAnswerOptionHandler}
>
X
</button>
</div>
</div>
</div>
<button
className="btn-primary mb-2"
type="button"
onClick={addAnswerOptionHandler}
>
Add Answer
</button>
<div className="text-left">
<div className="grid grid-cols-1 mb-6">
<h4 className="mb-2">Options</h4>
<div className="flex items-center">
<input
type="checkbox"
value=""
className="mx-3"
onChange={privateSelectedHandler}
></input>
<p>Private (only via direct link)</p>
</div>
<div className="flex items-center">
<input
type="checkbox"
value=""
className="mx-3"
onChange={multipleSelectedHandler}
></input>
<p>Allow multiple choices</p>
</div>
<div className="flex items-center">
<input
type="checkbox"
value=""
className="mx-3"
onChange={loginSelectedHandler}
></input>
<p>Voters must log in to vote</p>
</div>
<div className="flex items-center">
<input
type="checkbox"
value=""
className="mx-3"
onChange={ipcheckSelectedHandler}
></input>
<p>Check for duplicate IP</p>
</div>
</div>
</div>
<button type="submit" className="btn-primary mx-2">
Create Poll
</button>
<button type="button" className="btn-alt-onwhite mx-2">
Advanced Settings
</button>
</form>
</React.Fragment>
);
};
export default PollCreate;
PollCreateAnswerOption.js:
import React, { useState, useRef } from "react";
const PollCreateAnswerOption = React.forwardRef((props, ref) => {
const [enteredAnswerOption, setEnteredAnswerOption] = useState();
const answerOptionChangeHandler = (event) => {
setEnteredAnswerOption(event.target.value);
props.onAnswerOptionChange(event.target.value);
};
const deleteAnswerOptionHandler = (event) => {
props.onAnswerOptionDelete(event);
};
return (
<div className="flex">
<input
type="text"
className="mb-3 formtext w-full"
placeholder="Add an answer..."
onChange={answerOptionChangeHandler}
ref={ref}
></input>
<button
className="btn-alt-onwhite p-1 h-9"
type="button"
onClick={deleteAnswerOptionHandler}
>
X
</button>
</div>
);
});
export default PollCreateAnswerOption;
I'm OK with most of the form, but I'm confused on how I should generate 3 PollCreateAnswerOption components, allow the user to add and delete PollCreateAnswerOptions, and then put the data from each of them into my newPollData object.
I apologize in advance if the code is confusing or hard to read. There's a lot of things in here that are half-implemented from me trying all kinds of stuff. I tried to clean it up as much as I could.
There are currently both useState and useRef hooks in place because I don't know which I should use here and I was messing with both.
Thank you in advance to anyone who takes a look at this! I really appreciate the help, and I promise I did a lot of googling and reading before this point, but my brain is just fried at this point...
My code is not working, i am using node and React, the axios is trying to connect with the backend, but it fail.
When i try the connect in console:
image of firefox console
my code is: frontend/pages/login/index.js
import { FiLogIn } from 'react-icons/fi'
import {Link } from 'react-router-dom'
import api from '../../services/api'
import './styles.css'
export default function Login() {
const [name, setName] = useState('')
const [password, setPassword] = useState('')
async function handleLogin(e) {
e.preventDefault()
let data = ({
name,
password}
)
try {
let response = await api.post('session', data)
} catch(err){
console.log(err)
}
}
return (
<div className="login-conteiner">
<header>
<nav>
<div className="navlinks">
<Link to="/"><div className="li">Vega</div></Link>
<Link to="about.html"><div className="li">Sobre</div></Link>
</div>
</nav>
</header>
<main className="login">
<div className="heading">
<span className="blackblock"><h1>Vega Leads</h1></span>
<h2>Visualize todos os Leads <br /> da sua Instiuição <br /> e torne em alunos.</h2><br />
</div>
<div>
<form className="loginForm" id="form" onSubmit={handleLogin}>
<div className="loginItem"><label htmlFor="login">Login </label><input className="formInput" type="text" name="login" id="login"
value={name}
onChange={e => setName(e.target.value)} /></div><br />
<div className="loginItem"><label htmlFor="senha">Senha </label><input className="formInput" type="password" name="password" id="password"
value={password}
onChange={ e => setPassword(e.target.value) } /></div><br />
<button type="submit" className="startButton" id="postForm">Enviar <FiLogIn size={25} color="#11548f" /></button>
</form>
</div>
</main>
</div>
)}
Axios api: frontend/services/api.js
const api = axios.create({
baseURL: 'http://localhost:3333',
})
export default api
If you need more files to resolve my problem, ask me.
Thanks
i resolved the problem.
the problem is in the index of my backend (backend/src/index.js)
i forget the CORS module.
it is my code:
const routes = require('./routes')
const cors = require('cors')
const app = express()
app.use(cors())
app.use(express.json())
app.use(routes)
app.listen(3333)