Submitting form in react modal not working - no event triggered - javascript

I leverage the npm package react-modal (https://www.npmjs.com/package/react-modal).
I want to submit a form that resides within the modal.
For some reason when clicking on 'Abschicken', nothing happens. The handleSubmitfunction is never triggered as I do not see any console logs.
What do I miss here?
import { useState, useRef } from "react";
import Modal from "react-modal";
import LogoHori from "../../../public/images/logo_hori.png";
import Image from "next/image";
const customStyles = {
content: {
top: "50%",
left: "50%",
right: "auto",
bottom: "auto",
marginRight: "-50%",
transform: "translate(-50%, -50%)",
position: "absolute",
},
overlay: { zIndex: 1000 },
};
Modal.setAppElement("#__next");
// Make sure to bind modal to your appElement (https://reactcommunity.org/react-modal/accessibility/)
const ContactModal = ({ buttonStyles }) => {
const [modalIsOpen, setIsOpen] = useState(false);
const [isValidEmail, setIsValidEmail] = useState(true);
const [successfulSubmission, setSuccessfulSubmission] = useState("");
const lastNameInputElement = useRef();
const firstNameInputElement = useRef();
const emailInputElement = useRef();
const messageInputElement = useRef();
const validate = (email) => {
const expression =
/(?!.*\.{2})^([a-z\d!#$%&'*+\-\/=?^_`{|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+(\.[a-z\d!#$%&'*+\-\/=?^_`{|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)*|"((([\t]*\r\n)?[\t]+)?([\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|\\[\x01-\x09\x0b\x0c\x0d-\x7f\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))*(([\t]*\r\n)?[\t]+)?")#(([a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|[a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF][a-z\d\-._~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*[a-z\d\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])\.)+([a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|[a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF][a-z\d\-._~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]*[a-z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])\.?$/i;
return expression.test(String(email).toLowerCase());
};
function openModal() {
setIsOpen(true);
}
function afterOpenModal() {
// references are now sync'd and can be accessed.
}
function closeModal() {
setIsOpen(false);
}
const handleSubmit = async (event) => {
console.log("clicked");
event.preventDefault();
const data = {
lastName: lastNameInputElement.current?.value,
firstName: firstNameInputElement.current?.value,
email: emailInputElement.current?.value,
message: messageInputElement.current?.value,
};
if (!validate(data.email)) {
setIsValidEmail(false);
return;
}
setIsValidEmail(true);
console.log(data);
const requestOptions = {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(data),
};
try {
const result = await fetch(
"https://someEndpoint",
requestOptions
);
if (result.status == 200) {
setSuccessfulSubmission(true);
setTimeout(closeModal, 5000);
} else {
throw new Error();
}
} catch {
console.log(error);
setSuccessfulSubmission(false);
}
};
return (
<div>
<button className={buttonStyles} onClick={openModal}>
Anfrage
</button>
<Modal
isOpen={modalIsOpen}
onAfterOpen={afterOpenModal}
onRequestClose={closeModal}
style={customStyles}
contentLabel="Nido Surf"
>
<div className="w-[300px] md:w-[600px]">
<Image src={LogoHori} alt="nido-surf-logo" width={300} />
<form action="Post" onSubmit={handleSubmit} className="mt-5 flex flex-col justify-between">
<label htmlFor="name" className="font-bold mb-2">
Nachname
</label>
<input
ref={lastNameInputElement}
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 focus:outline-none focus:shadow-outline"
id="name"
type="text"
placeholder="Nachname"
/>
<label htmlFor="firstname" className="font-bold my-2">
Vorname
</label>
<input
ref={firstNameInputElement}
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 focus:outline-none focus:shadow-outline"
id="firstname"
type="text"
placeholder="Vorname"
/>
<label htmlFor="email" className="font-bold my-2">
Email-Adresse
</label>
<input
ref={emailInputElement}
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 focus:outline-none focus:shadow-outline"
id="email"
type="text"
placeholder="Email-Adresse"
/>
{!isValidEmail && (
<p className="text-secondary-red-200">
Deine Email-Adresse ist ungültig!
</p>
)}
<label htmlFor="message" className="font-bold my-2">
Nachricht
</label>
<textarea
ref={messageInputElement}
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 focus:outline-none focus:shadow-outline"
name="message"
id="message"
cols="30"
rows="10"
></textarea>
</form>
<div className="mt-5 flex gap-x-4 justify-center items-center">
<button
type="submit"
className="w-full text-white rounded-md py-4 hover:bg-secondary-green-300 bg-secondary-green-400"
>
Senden
</button>
<button
className="w-full text-white rounded-md py-4 hover:bg-secondary-red-100 bg-secondary-red-300"
onClick={closeModal}
>
Abbrechen
</button>
</div>
</div>
</Modal>
</div>
);
};
export default ContactModal;

It's not triggering the submit event because your button is not inside the form. Move the below div above the closing tag of form. Also, notice this type="button" on the second button:
<div className="mt-5 flex gap-x-4 justify-center items-center">
<button
type="submit"
className="w-full text-white rounded-md py-4 hover:bg-secondary-green-300 bg-secondary-green-400"
>
Senden
</button>
<button
className="w-full text-white rounded-md py-4 hover:bg-secondary-red-100 bg-secondary-red-300"
onClick={closeModal}
type="button"
>
Abbrechen
</button>
</div>

Related

fetched data from firestore as initial value of useState it gives me udefined value

I want to set the fetched data from firestore as initial value of useState but it gives me undefined value because I want to update user profile and I don't know the user edits or updates which property because I want to keep the other properties of the user the same, only change the edited one.
I've tried this code, but it gives me this error:
Uncaught (in promise) FirebaseError: Function updateDoc() called with invalid data. Unsupported field value: undefined (found in field surname in document users/DQjpLaKYVgVuH9TeqNomIEyuMJB2)
import React, { useState, useEffect } from 'react';
import { useAuthState } from 'react-firebase-hooks/auth';
import { doc, onSnapshot, updateDoc } from "firebase/firestore";
import { auth, db } from '../../firebase';
export default function Form({ setEditForm }) {
const [user, setUser] = useState([]);
const [currentUser] = useAuthState(auth);
// fetching user information from firestore
useEffect(() => {
const getUser = async () => {
const docRef = await doc(db, 'users', currentUser.uid)
try {
await onSnapshot(docRef, (doc) => {
setUser({
...doc.data(), id: doc.id
})
})
} catch (e) {
console.log(e)
}
}
getUser()
}, [])
const [name, setName] = useState(user.firstName);
const [surname, setSurname] = useState(user.surname);
const [biography, setBiography] = useState(user.biography);
const [location, setLocation] = useState(user.location);
// updating user's profile
const updateProfile = async (e) => {
e.preventDefault();
const docRef = doc(db, 'users', currentUser.uid);
await updateDoc(docRef, {
firstName: name,
surname: surname,
biography: biography,
location: location
})
}
console.log(user)
return (
<form
onSubmit={updateProfile}
className="flex flex-col w-4/6 lg:w-3/6"
>
<div className="lg:flex lg:flex-row lg:justify-between lg:gap-6">
<div className="lg:flex lg:flex-col lg:w-1/2">
<h2 className="text-left text-[#4699C2] font-bold py-2">Name: </h2>
<div className="border border-gray-300 rounded-md">
<input
type="text"
placeholder={name}
value={name}
onChange={(e) => setName(e.target.value)}
className="w-full py-2 px-4 opacity-50 focus:opacity-100"
/>
</div>
</div>
<div className="lg:flex lg:flex-col lg:w-1/2">
<h2 className="text-left text-[#4699C2] font-bold py-2">Surname: </h2>
<div className="border border-gray-300 rounded-md">
<input
type="text"
placeholder={surname}
value={surname}
onChange={(e) => setSurname(e.target.value)}
className="opacity-50 px-4 focus:opacity-100 w-full py-2"
/>
</div>
</div>
</div>
<h2 className="text-left text-[#4699C2] font-bold py-2">Biograhpy: </h2>
<div className="border border-gray-300 rounded-md">
<textarea
onChange={(e) => setBiography(e.target.value)}
className="opacity-50 px-4 focus:opacity-100 w-full py-4"
>
{biography}
</textarea>
</div>
<h2 className="text-left text-[#4699C2] font-bold py-2">Location: </h2>
<div className="border border-gray-300 rounded-md">
<input
placeholder={location}
value={location}
onChange={(e) => setLocation(e.target.value)}
className="opacity-50 px-4 focus:opacity-100 w-full py-2"
/>
</div>
<div className="flex flex-row justify-center py-4">
<input
type="submit"
value="SAVE"
className="bg-[#4699C2] text-white fong-bold w-24 py-3 rounded-full mx-4 font-bold hover:bg-[#026FC2] hover:shadow-lg focus:bg-[#026FC2] focus:shadow-lg focus:outline-none focus:ring-0 active:bg-[#026FC2] active:shadow-lg transition duration-150 ease-in-out"
/>
<input
onClick={() => {
setEditForm(false);
}}
type="reset"
value="CANCEL"
className="bg-[#4699C2] cursor-pointer lg:bg-white hover:bg-[#026FC2] hover:text-white hover:shadow-lg focus:bg-[#026FC2] focus:shadow-lg focus:outline-none focus:ring-0 focus:text-white active:bg-[#026FC2] active:shadow-lg transition duration-150 ease-in-out text-white lg:text-[#4699C2] lg:border lg:border-[#4699C2] fong-bold w-24 py-3 rounded-full font-bold"
/>
</div>
</form>
);
}
Answering this as community wiki, As suggested by #yograjtandel, instead of storing the response in one single state, first declare all the states like name, biography, surname, etc... to null. then in useState set all the states ex. setName(doc.data().Name).

How do i pass Livewire property value to my <script> tag javascript in blade.php view file of the Livewire component?

I am trying to open a hosted page from a payment gateway provider. 2 parameters are required by the page.
I have successfully created the parameters and saved them in my database but when I try to pass the data to my script it does not pass the value of the variable in blade.php view file.
blade.php view:
<?php
namespace App\Http\Livewire\Open;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use Livewire\Component;
use App\Models\OpenTransactions;
class NewDeposit extends Component
{
public $op_id;
public $op_amount;
public $op_udf;
public $op_attempts;
public $op_sub_accounts_id;
public $op_entity;
public $op_status;
public $op_contact_number;
public $op_email_id;
public $op_mtx;
public $op_currency;
public $op_customer_id;
public $apiKey;
public $mydata;
public function mount(Request $request){
$this->op_mtx = Str::uuid()->toString();
$this->op_currency = "INR";
$this->op_amount =$request->get('op_amount');
$this->op_email_id =$request->get('op_email_id');
}
public function render()
{
return view('livewire.open.new-deposit');
}
public function createNewDepositOpen(Request $request)
{
$apiKey = config('app.open_key');
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . $apiKey,
'accept' => 'application/json',
'content-type' => 'application/json',
])->post('https://sandbox-icp-api.bankopen.co/api/payment_token',[
'amount' => $this->op_amount,
'mtx' => $this->op_mtx,
'currency' => $this->op_currency,
'udf' => $this->op_udf,
'contact_number' => $this->op_contact_number,
'email_id' => $this->op_email_id
]);
$mydata = json_decode($response->getBody()->getContents(), true);
//dd($mydata);
$newpayload = OpenTransactions::create([
'op_mtx' => $mydata['mtx'],
'op_amount' => $mydata['amount'],
'op_udf' => $mydata['udf'] ?? null,
'op_contact_number' => Arr::get($mydata, 'customer.contact_number'),
'op_email_id' => Arr::get($mydata, 'customer.email_id'),
'op_currency' => $mydata['currency'],
'op_id' => $mydata['id'],
'op_attempts' => $mydata['attempts'],
'op_sub_accounts_id' => $mydata['sub_accounts_id'],
'op_entity' => $mydata['entity'],
'op_status' => $mydata['status'],
'op_customer_id' => Arr::get($mydata, 'customer.id')
]);
//dd($newpayload);
$this->emit('token_create');
}
}
Livewire Component:
<div>
{{-- Care about people's approval and you will be their prisoner. --}}
<div class="flex min-h-full items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<div class="w-full max-w-md space-y-8">
<div>
<img
class="mx-auto h-12 w-auto"
src="https://tailwindui.com/img/logos/mark.svg?color=indigo&shade=600"
alt="Your Company"
/>
<h2
class="mt-6 text-center text-3xl font-bold tracking-tight text-gray-900"
>
Deposit
</h2>
<p class="mt-2 text-center text-sm text-gray-600">
<a
href="#"
class="font-medium text-indigo-600 hover:text-indigo-500"
></a>
</p>
</div>
<form
wire:submit.prevent="createNewDepositOpen"
class="mt-8 space-y-6"
method="POST"
>
<input type="hidden" name="remember" value="true" />
<div class="-space-y-px rounded-md shadow-sm">
<div>
<label for="op_email_id" class="sr-only">Email address</label>
<input
wire:model="op_email_id"
id="op_email_id"
name="op_email_id"
type="email"
autocomplete="email"
required
class="relative block w-full appearance-none rounded-none rounded-t-md border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:z-10 focus:border-indigo-500 focus:outline-none focus:ring-indigo-500 sm:text-sm"
placeholder="Email address"
/>
</div>
<div class="mt-2">
<label for="op_contact_number" class="sr-only">Mobile Number</label>
<input
wire:model="op_contact_number"
id="op_contact_number"
name="op_contact_number"
type="tel"
pattern="^[6-9]\d{9}$"
required
class="relative block w-full appearance-none rounded-none rounded-b-md border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:z-10 focus:border-indigo-500 focus:outline-none focus:ring-indigo-500 sm:text-sm"
placeholder="Enter 10 digit Mobile No."
/>
</div>
<div class="mt-2">
<label for="op_amount" class="sr-only">amount</label>
<input
wire:model="op_amount"
id="op_amount"
name="op_amount"
type="number"
required
class="relative block w-full appearance-none rounded-none rounded-b-md border border-gray-300 px-3 py-2 text-gray-900 placeholder-gray-500 focus:z-10 focus:border-indigo-500 focus:outline-none focus:ring-indigo-500 sm:text-sm"
placeholder="Amount"
/>
</div>
</div>
<div>
<button
type="submit"
class="group relative flex w-full justify-center rounded-md border border-transparent bg-indigo-600 py-2 px-4 text-sm font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
>
<span class="absolute inset-y-0 left-0 flex items-center pl-3">
<!-- Heroicon name: mini/lock-closed -->
</span>
Next
</button>
</div>
</form>
</div>
</div>
<script type="text/javascript">
window.onload = function () {
Livewire.on("token_create", () => {
//You can bind the Layer.checkout initialization script to a button click event.
//Binding inside a click event open Layer payment page on click of a button
Layer.checkout(
{
token: "#js($op_id)",
accesskey: "#js($apiKey)",
theme: {
logo: "https://open-logo.png",
color: "#3d9080",
error_color: "#ff2b2b",
},
},
function (response) {
if (response.status == "captured") {
// response.payment_token_id
// response.payment_id
window.location.href = "success_redirect_url"
} else if (response.status == "created") {
} else if (response.status == "pending") {
} else if (response.status == "failed") {
window.location.href = "failure_redirect_url"
} else if (response.status == "cancelled") {
window.location.href = "cancel_redirect_url"
}
},
function (err) {
//integration errors
}
)
})
}
</script>
</div>
I am pretty sure you can just pass it like any blade variable:
token: "{{$op_id}}",
accesskey: "{{$apiKey}}" ,
theme: {
logo : "https://open-logo.png",
color: "#3d9080",
error_color : "#ff2b2b"

How to return multiple function in react in JSX format

I'm trying to return a few functions in react but I'm unable to perform as I wanted.
return (
loadingMessage(),
errorMessage(),
loginForm(),
performRedirect()
)
}
I want to return my functions as above but when try this my app directly calls the last function performRedirect(). I don't know whether am I running this correctly or not.
please find the whole code below.
import React, { useState } from "react";
import { Link, Navigate } from "react-router-dom";
import {signin, authenticate, isAutheticated} from "../auth/helper/index"
const Login = () => {
const [values, setValues] = useState({
username: "",
password: "",
error: "",
loading: false,
didRedirect: false,
});
const {username, password, error, loading, didRedirect} = values;
const {user} = isAutheticated();
const handleChange = name => event => {
setValues({ ...values, error: false, [name]: event.target.value });
};
const onSubmit = event => {
event.preventDefault();
setValues({ ...values, error: false, loading: true });
signin({ username, password })
.then(data => {
if (data.error) {
setValues({ ...values, error: data.error, loading: false });
} else {
authenticate(data, () => {
setValues({
...values,
didRedirect: true
});
});
}
})
.catch(console.log("signin request failed", error, user));
};
const performRedirect = () => {
//TODO: do a redirect here
if (didRedirect) {
if (user && user.role === 1) {
return <p>redirect to admin</p>;
} else {
return <p>redirect to user dashboard</p>;
}
}
if (isAutheticated()) {
return <Navigate to="/" />;
}
};
const loadingMessage = () => {
return (
loading && (
<div className="alert alert-info">
<h2>Loading...</h2>
</div>
)
);
};
const errorMessage = () => {
return (
<div className="row">
<div className="col-md-6 offset-sm-3 text-left">
<div
className="alert alert-danger"
style={{ display: error ? "" : "none" }}
>
{error}
</div>
</div>
</div>
);
};
const loginForm = () => {
return (
<div className='bg-gray-200'>
<div className="flex items-center h-screen w-full">
<div className="w-80 bg-white rounded-2xl p-6 m-0 md:max-w-sm md:mx-auto border border-slate-300 shadow-sm">
<div align='center' className='mt-3 mb-3 items-center content-center'> <img src={require('./../data/logo.jpg')} width="120px"/></div>
<span className="block w-full text-xl uppercase font-bold mb-4 text-center">Sign in to EMS
</span>
<form className="mb-0" action="/" method="post">
<div className="mb-4 md:w-full">
<label for="email" className="block text-xs mb-1 text-left text-gray-500">Username</label>
<input onChange={handleChange("username")} className="bg-gray-100 w-full border rounded-2xl px-4 py-2 outline-none focus:shadow-outline text-left text-xs" type="text" name="username" id="username" placeholder="Username" value={username}/>
</div>
<div className="mb-6 md:w-full relative">
<div className='flex w-full'>
<label for="password" className="block text-xs mb-1 text-center text-gray-500">Password</label>
<a className="text-xs text-right text-[#58a6ff] absolute right-0" href="/login">Forgot password?</a></div>
<input onChange={handleChange("password")} className="bg-gray-100 w-full border rounded-2xl px-4 py-2 outline-none focus:shadow-outline text-left text-xs" type="password" name="password" id="password" placeholder="Password" value={password}/>
</div>
<div className="mb-6 md:w-full relative">
<div className='flex w-full'>
<p className="block text-xs mb-1 text-center text-gray-500">{JSON.stringify(values)}</p>
</div>
<button className="bg-green-500 hover:bg-green-700 shadow-lg text-white uppercase text-sm font-semibold px-4 py-2 rounded-2xl text-center items-center w-full" onClick={onSubmit}>Login</button>
</form>
</div>
</div>
</div>
);
};
return (
loadingMessage(),
errorMessage(),
loginForm(),
performRedirect()
)
}
export default Login
Please someone help me on this?
You can modify your return statement with an array value [] like below
return [
loadingMessage(),
errorMessage(),
loginForm(),
performRedirect()
]
Another way, you can render those JSX functions by {} and wrap them into <React.Fragment></React.Fragment> (Or simpler version <></>)
return (
<React.Fragment>
{loadingMessage()}
{errorMessage()}
{loginForm()}
{performRedirect()}
</React.Fragment>)
like this:
return (
<>
{loadingMessage()}
{errorMessage()}
{loginForm()}
{performRedirect()}
</>
)

Unable to set up razorpay payment gateway

I have built a checkout page where on clicking the pay button a payment page should render. But due to some issue I can't find why?
The checkout page:
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
import Link from 'next/link'
import React, { useState, useEffect } from 'react'
import Head from 'next/head'
import Script from 'next/script'
import { AiFillMinusCircle, AiFillPlusCircle } from 'react-icons/ai'
import { BsFillBagCheckFill } from 'react-icons/bs'
import { ToastContainer, toast } from 'react-toastify'
import 'react-toastify/dist/ReactToastify.css';
const Checkout = ({ cart, clearCart, subTotal, addToCart, removeFromCart }) => {
const [name, setName] = useState('')
const [email, setEmail] = useState('')
const [address, setAddress] = useState('')
const [phone, setPhone] = useState('')
const [pincode, setPincode] = useState('')
const [city, setCity] = useState('')
const [state, setState] = useState('')
const [disabled, setDisabled] = useState(true)
const [user, setUser] = useState({ value: null })
useEffect(() => {
const myuser = JSON.parse(localStorage.getItem('myuser'));
if (myuser && myuser.token) {
setUser(myuser)
setEmail(myuser.email)
fetchData(myuser.token)
}
}, [])
useEffect(() => {
if (name.length > 3 && email.length > 3 && address.length > 3 && phone.length > 3 && pincode.length > 3) {
setDisabled(false)
}
else {
setDisabled(true)
}
}, [name, email, address, phone, pincode])
const fetchData = async (token) => {
let data = { token: token }
let a = await fetch(`${process.env.NEXT_PUBLIC_HOST}/api/getuser`, {
method: 'POST', // or 'PUT'
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
let res = await a.json()
setName(res.name)
setAddress(res.address)
setPincode(res.pincode)
setPhone(res.phone)
getPinCode(res.pincode)
}
const getPinCode = async (pincode) => {
let url = 'https://api.postalpincode.in/pincode/' + pincode
let pins = await fetch(url, {
Method: 'GET'
})
let pinJson = await pins.json()
if (pinJson[0].Status == 'Success') {
setState(pinJson[0].PostOffice[0].State)
setCity(pinJson[0].PostOffice[0].District)
}
else {
setState('')
setCity('')
}
}
const handleChange = async (e) => {
if (e.target.name == 'name') {
setName(e.target.value)
}
else if (e.target.name == 'email') {
setEmail(e.target.value)
}
else if (e.target.name == 'address') {
setAddress(e.target.value)
}
else if (e.target.name == 'phone') {
setPhone(e.target.value)
}
else if (e.target.name == 'pincode') {
setPincode(e.target.value)
if (e.target.value.length == 6) {
getPinCode(e.target.value)
}
}
}
const initializeRazorpay = () => {
return new Promise((resolve) => {
const script = document.createElement("script");
script.src = "https://checkout.razorpay.com/v1/checkout.js";
console.log("intialzeRazorpay")
script.onload = () => {
resolve(true);
};
script.onerror = () => {
resolve(false);
};
document.body.appendChild(script);
});
};
const makePayment = async () => {
const res = await initializeRazorpay();
let oid = Math.floor(Math.random() * Date.now());
if (!res) {
alert("Your are offline.... Razorpay SDK Failed to load");
return;
}
const pdata = { cart, subTotal: subTotal, oid, email: email, name, address, pincode, phone, state, city };
let data = await fetch(`${process.env.NEXT_PUBLIC_HOST}/api/pretransaction`, {
method: 'POST', // or 'PUT'
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(pdata),
})
if (!data.success) {
toast.error(data.err, {
position: "top-center",
autoClose: 3000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
});
}
else {
var options = {
key: process.env.RAZORPAY_KEY, // Enter the Key ID generated from the Dashboard
name: "Pixelwear",
currency: "INR",
amount: data.amount,
order_id: data.id,
description: "Thank You for your test donation",
image: "/logo.png",
handler: function (response) {
// Validate payment at server - using webhooks is a better idea
alert(response.razorpay_payment_id)
alert(response.razorpay_order_id);
alert(response.razorpay_signature);
},
prefill: {
name: name,
email: email,
contact: phone,
},
};
const paymentObject = new window.Razorpay(options);
paymentObject.open();
}
};
return (
<>
<div className='container px-2 sm:m-auto'>
<ToastContainer
position="top-center"
autoClose={5000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
/>
<Head><meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0" /></Head>
<h1 className='font-bold text-3xl my-8 text-center'>Checkout</h1>
<h2 className='font-semibold text-xl'>1. Delivery Details</h2>
<div className="mx-auto flex my-2">
<div className="px-2 w-1/2">
<div className="mb-4">
<label htmlFor="name" className="leading-7 text-sm text-gray-600">Name</label>
<input value={name} onChange={handleChange} type="text" id="name" name="name" className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" />
</div>
</div>
<div className="px-2 w-1/2">
<div className="mb-4">
<label htmlFor="email" className="leading-7 text-sm text-gray-600">Email</label>
{user && user.token ? <input value={user.email} type="email" id="email" name="email" className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" readOnly /> : <input value={email} onChange={handleChange} type="email" id="email" name="email" className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" />}
</div>
</div>
</div>
<div className="px-2 w-full">
<div className="mb-4">
<label htmlFor="address" className="leading-7 text-sm text-gray-600">Address</label>
<textarea onChange={handleChange} value={address} name="address" id="address" cols="30" rows="2" className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"></textarea>
</div>
</div>
<div className="mx-auto flex my-2">
<div className="px-2 w-1/2">
<div className="mb-4">
<label htmlFor="phone" className="leading-7 text-sm text-gray-600">Phone</label>
<input value={phone} onChange={handleChange} placeholder="Your 10 digit phone number" type="phone" id="phone" name="phone" className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" />
</div>
</div>
<div className="px-2 w-1/2">
<div className="mb-4">
<label htmlFor="pincode" className="leading-7 text-sm text-gray-600">Pincode</label>
<input value={pincode} onChange={handleChange} type="text" id="pincode" name="pincode" className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" />
</div>
</div>
</div>
<div className="mx-auto flex my-2">
<div className="px-2 w-1/2">
<div className="mb-4">
<label htmlFor="state" className="leading-7 text-sm text-gray-600">State</label>
<input onChange={handleChange} value={state} type="text" id="state" name="state" className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" />
</div>
</div>
<div className="px-2 w-1/2">
<div className="mb-4">
<label htmlFor="city" className="leading-7 text-sm text-gray-600">District</label>
<input onChange={handleChange} value={city} type="text" id="city" name="city" className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" />
</div>
</div>
</div>
<h2 className='font-semibold text-xl'>2. Review Cart Items & Pay</h2>
<div className="sideCart bg-blue-100 p-6 m-2">
<ol className='list-decimal font-semibold'>
{Object.keys(cart).length == 0 && <div className='my-4 font-semibold'>Your cart is Empty!</div>}
{Object.keys(cart).map((k) => {
return <li key={k}>
<div className="item flex my-5">
<div className='font-semibold'>{cart[k].name} ({cart[k].size}/{cart[k].variant})</div>
<div className='flex items-center justify-center w-1/3 font-semibold text-lg'>
<AiFillMinusCircle onClick={() => { removeFromCart(k, 1, cart[k].price, cart[k].name, cart[k].size, cart[k].variant, cart[k].category, cart[k].img) }} className='cursor-pointer text-blue-500' /><span className='mx-2 text-sm' >{cart[k].qty}</span>
<AiFillPlusCircle onClick={() => { addToCart(k, 1, cart[k].price, cart[k].name, cart[k].size, cart[k].variant, cart[k].category, cart[k].img) }} className='cursor-pointer text-blue-500' /></div>
</div>
</li>
})}
</ol>
<span className="font-bold">Subtotal: ₹{subTotal}</span>
</div>
<div className="mx-4">
<Link href={'/checkout'} ><button disabled={disabled} onClick={makePayment} className="disabled:bg-indigo-300 flex mr-2 text-white bg-indigo-500 border-0 py-2 px-2 focus:outline-none hover:bg-indigo-600 rounded text-sm"><BsFillBagCheckFill className='m-1' />Pay ₹{subTotal}</button></Link>
</div>
</div>
</>
)
}
export default Checkout
pretransaction page:
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
import Order from "../../models/Order"
import Product from "../../models/Product"
import connectDb from "../../middleware/mongoose"
require('dotenv').config()
const Razorpay = require("razorpay");
const shortid = require("shortid");
const handler = async (req, res) => {
if (req.method == 'POST') {
//Check if the pincode is serviceable
let url = 'https://api.postalpincode.in/pincode/' + req.body.pincode
let pins = await fetch(url, {
Method: 'GET'
})
let pinJson = await pins.json()
if (pinJson[0].Status != 'Success') {
res.status(200).json({ success: false, "error": "The pincode you have entered is not serviceable.", cartClear: false })
return
}
//Check if the cart is tampered
let product, sumTotal = 0;
let cart = req.body.cart;
if (req.body.subTotal <= 0) {
res.status(200).json({ success: false, "error": "Your Cart is empty. Please build your cart and try again!", cartClear: false })
return
}
for (let item in cart) {
product = await Product.findOne({ slug: item })
sumTotal += cart[item].price * cart[item].qty
//Check if the cart items are out of stock
if (product.availableQty < cart[item].qty) {
res.status(200).json({ success: false, "error": "Some items in your cart are out of stock.", cartClear: true })
return
}
if (product.price != cart[item].price) {
res.status(200).json({ success: false, "error": "price of some items in cart have changed", cartClear: true })
return
}
}
if (sumTotal != req.body.subTotal) {
res.status(200).json({ success: false, "error": "price of some items in cart have changed", cartClear: true })
return
}
//Check if the details are valid
if (req.body.phone.length !== 10 || !Number.isInteger(Number(req.body.phone))) {
res.status(200).json({ success: false, "error": "Please enter your 10 digit phone number", cartClear: false })
return
}
if (req.body.pincode.length !== 6 || !Number.isInteger(Number(req.body.pincode))) {
res.status(200).json({ success: false, "error": "Please enter your 6 digit pincode", cartClear: false })
return
}
const razorpay = new Razorpay({
key_id: process.env.RAZORPAY_KEY,
key_secret: process.env.RAZORPAY_SECRET,
});
const payment_capture = 1;
const amount = req.body.subTotal;
const currency = "INR";
const options = {
amount: (amount * 100).toString(),
currency,
receipt: shortid.generate(),
payment_capture,
};
try {
const response = await razorpay.orders.create(options);
// Initiate an order corresponding to the order id
let order = new Order({
email: req.body.email,
name: req.body.name,
phone: req.body.phone,
orderId: response.id,
address: req.body.address,
district: req.body.city,
state: req.body.state,
pincode: req.body.pincode,
amount: req.body.subTotal,
products: req.body.cart,
})
await order.save()
res.status(200).json({
success: true,
id: response.id,
currency: response.currency,
amount: response.amount,
});
return
} catch (err) {
console.log(err);
res.status(400).json({ success: false , err: err});
return
}
}
}
export default connectDb(handler);
Everything is working fine, but when I click on the pay button the razorpay page is not rendering.
And in the console it is showing one error, Invalid HMR message: {"event":"serverOnlyChanges","pages":["/api/pretransaction"]}.
Console Image
How to fix this error?

How to make Dropdown in ReactJs from Query and get the value

Sorry if I ask again, I try to make dropdown from array in my database then use the dropdown to take the value I want looping the array to the dropdown in here but still not showed
//tipe akademik
//define state
const [postsTipe, setPostsTipe] = useState([]);
//useEffect hook
useEffect(() => {
//panggil method "fetchData"
fectDataTipe();
}, []);
//function "fetchData"
const fectDataTipe = async () => {
//fetching
const responseTipe = await axios.get('http://localhost:3000/api/tipe_akademik');
//get response data
const dataTipe = await responseTipe.data.data;
//assign response data to state "posts"
setPostsTipe(dataTipe);
}
const Dropdown = () => {
// dropdown props
const [dropdownPopoverShow, setDropdownPopoverShow] = React.useState(false);
const btnDropdownRef = React.createRef();
const popoverDropdownRef = React.createRef();
const openDropdownPopover = () => {
createPopper(btnDropdownRef.current, popoverDropdownRef.current, {
placement: "bottom-start",
});
setDropdownPopoverShow(true);
};
const closeDropdownPopover = () => {
setDropdownPopoverShow(false);
};
return (
<>
<a
className="text-blueGray-500 block"
href="#pablo"
ref={btnDropdownRef}
onClick={(e) => {
e.preventDefault();
dropdownPopoverShow ? closeDropdownPopover() : openDropdownPopover();
}} >
<div class="relative inline-block text-left">
<div>
<button type="button" class="inline-flex justify-center w-full rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-indigo-500" id="menu-button" aria-expanded="true" aria-haspopup="true">
Tipe Akademik
</button>
</div>
</div>
</a>
<div
ref={popoverDropdownRef}
className={
(dropdownPopoverShow ? "block " : "hidden ") +
"bg-white text-base z-50 float-left py-2 list-none text-left rounded shadow-lg min-w-48"
}
>
{postsTipe.map((kategori)=> {
return(<>
<a
href="#pablo"
className={
"text-sm py-2 px-4 font-normal block w-full whitespace-nowrap bg-transparent text-blueGray-700"
}
onClick={(e) => e.preventDefault()}
>
{kategori.tipe_akademik}
</a> /</> )})}
</div>
</>
);
};
export default Dropdown;
Then I call it to my input form with import from dropdown and I want take the value in form and its still wrong. I dont know how to take the the value from import the dropdown named TipeDropdown
import TipeDropdown from "components/Dropdowns/Dropdown";
method "storePost"
const storePost = async (e) => {
e.preventDefault();
//send data to server
await axios.post('http://localhost:3000/api/akademik_a/store', {
tipeA: TipeA,
})
.then(() => {
//redirect
history.push('/admin/dafgur');
})
.catch((error) => {
//assign validation on state
setValidation(error.response.data);
})
};
export default function InputAkademik({ color }) {
return (
<>
<form onSubmit={ storePost }
<input className="border-0 px-3 py-3 placeholder-blueGray-300 text-blueGray-600 bg-white rounded text-sm shadow focus:outline-none focus:ring w-full ease-linear transition-all duration-150"
placeholder="" />
<div className="field mt-5">
<label className="label">Tipe Akademik</label>
<div className="controls">
<TipeDropdown value={TipeA} onChange={(e) => setTipe(e.target.value)}/>
<input type="text" className="border-0 px-3 py-3 placeholder-blueGray-300 text-blueGray-600 bg-white rounded text-sm shadow focus:outline-none focus:ring w-full ease-linear transition-all duration-150" placeholder="" value={TipeInput} onChange={(e) => TipeInput(e.target.value)} />
</div>
</div> </div>
</>
);
};

Categories