setting fundraisng and donor
This commit is contained in:
parent
739dfc8700
commit
8720dc73fd
|
|
@ -1,9 +1,8 @@
|
|||
import React from 'react';
|
||||
//import React from 'react';
|
||||
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
|
||||
import Navbar from './Components/Navbar';
|
||||
|
||||
import Contact from './Components/Contact';
|
||||
import Footer from './Components/Footer';
|
||||
import FormBuilder from './Components/FormBuilder';
|
||||
import AboutUs from './Components/AboutUs';
|
||||
import './App.css';
|
||||
|
|
@ -17,6 +16,7 @@ function App() {
|
|||
<Router>
|
||||
<Navbar />
|
||||
<Routes>
|
||||
<Route path="/" element={<Home />} />
|
||||
<Route path="/home" element={<Home />} />
|
||||
|
||||
<Route path="/aboutUs" element={<AboutUs />} />
|
||||
|
|
|
|||
|
|
@ -1,17 +1,14 @@
|
|||
import React from "react";
|
||||
import {
|
||||
Container,
|
||||
Typography,
|
||||
Box,
|
||||
Grid,
|
||||
Paper,
|
||||
|
||||
Button,
|
||||
Icon,
|
||||
|
||||
} from "@mui/material";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
const AboutUs = () => {
|
||||
const navigate = useNavigate();
|
||||
return (
|
||||
<div style={{ padding: "40px 0", backgroundColor: "#f9f9f9" }}>
|
||||
<Container maxWidth="lg">
|
||||
|
|
@ -25,7 +22,7 @@ const AboutUs = () => {
|
|||
<Typography variant="h5" sx={{ marginBottom: 3, fontWeight: "bold" }}>
|
||||
Our History
|
||||
</Typography>
|
||||
<Typography variant="body1" paragraph>
|
||||
<Typography variant="body1" paragraph style={{ textAlign: "justify" }}>
|
||||
Vertivel Educational Trust was founded in 2010 with a vision to
|
||||
provide quality education to underprivileged children in rural
|
||||
and underserved areas. Over the years, the trust has grown into
|
||||
|
|
@ -43,14 +40,14 @@ const AboutUs = () => {
|
|||
<Typography variant="h5" sx={{ marginBottom: 3, fontWeight: "bold" }}>
|
||||
Our Achievements
|
||||
</Typography>
|
||||
<Typography variant="body1" paragraph>
|
||||
<Typography variant="body1" paragraph >
|
||||
- Provided scholarships to over 100 students.
|
||||
<br />
|
||||
- Established 10 schools across rural regions.
|
||||
<br />
|
||||
- Partnered with top universities to offer vocational training.
|
||||
<br />
|
||||
- Awarded "Best Educational NGO" in 2018.
|
||||
- Awarded "Best Educational NGO" in 2018.
|
||||
<br />
|
||||
</Typography>
|
||||
</Box>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from "react";
|
||||
import { Box, Typography, Grid, Paper } from "@mui/material";
|
||||
//import React from "react";
|
||||
import { Typography, Grid, Paper } from "@mui/material";
|
||||
import './CustomerCountCard.css'
|
||||
|
||||
const CustomerCountCard = () => {
|
||||
|
|
@ -27,7 +27,7 @@ const CustomerCountCard = () => {
|
|||
</Grid>
|
||||
<Grid item>
|
||||
<Typography
|
||||
variant="h5"
|
||||
variant="h6"
|
||||
sx={{
|
||||
fontWeight: "medium",
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import React from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Button, Typography, Box } from '@mui/material';
|
||||
import './Donate.css'
|
||||
|
|
@ -23,9 +22,13 @@ const Donate = () => {
|
|||
margin: 'auto'
|
||||
}}
|
||||
>
|
||||
<h1 className="heading-border-bottom" sx={{ marginBottom: '20px', fontWeight: 'bold' }}>
|
||||
Your Donation Can Make a Difference
|
||||
</h1>
|
||||
<Typography
|
||||
variant="h1"
|
||||
className="heading-border-bottom"
|
||||
sx={{ marginBottom: '20px', fontWeight: 'bold' }}
|
||||
>
|
||||
<h2>Your Donation Can Make a Difference</h2>
|
||||
</Typography>
|
||||
<Typography variant="body1" sx={{ marginBottom: '20px' }}>
|
||||
Join us in our mission to help those in need. By becoming a donor, you can contribute to
|
||||
creating a positive impact in the lives of many.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import React from "react";
|
||||
import { Model } from "survey-core";
|
||||
import { Survey } from "survey-react-ui";
|
||||
import "survey-core/defaultV2.min.css";
|
||||
|
|
|
|||
|
|
@ -200,6 +200,18 @@ input:focus {
|
|||
.form-button:hover:not(:disabled) {
|
||||
opacity: 0.9;
|
||||
}
|
||||
.bank-details {
|
||||
text-align: left;
|
||||
background-color: #f9f9f9;
|
||||
padding: 15px;
|
||||
margin: 15px 0;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 8px;
|
||||
line-height: 1.6;
|
||||
font-size: 0.95rem;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.container-box {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { useState } from "react";
|
||||
import "./FundDrive.css";
|
||||
// Inside src/Components/FundDrive.jsx
|
||||
import { submitVvvetForm } from "../vvvetApi";
|
||||
//import { submitVvvetForm } from "../vvvetApi";
|
||||
import axios from "axios";
|
||||
import './form-step2.css';
|
||||
|
||||
|
||||
|
||||
|
|
@ -15,14 +16,35 @@ const FundDrive = () => {
|
|||
age: "",
|
||||
dob: "",
|
||||
category: "",
|
||||
pan: "",
|
||||
customCategory: "",
|
||||
pan: "",
|
||||
images: [],
|
||||
bankHolderName: "",
|
||||
bankName: "",
|
||||
accountNumber: "",
|
||||
ifscCode: "",
|
||||
fundAmount: "",
|
||||
accountNumber: "",
|
||||
images: []
|
||||
paymentMethod: "",
|
||||
studentName: "",
|
||||
standard: "",
|
||||
parentName: "",
|
||||
parentPhone: "",
|
||||
feeDocument: null,
|
||||
patientName: "",
|
||||
cause: "",
|
||||
hospitalName: "",
|
||||
location: "",
|
||||
attenderName: "",
|
||||
medicalCertificate: null,
|
||||
medicalDocument: null,
|
||||
disasterName: "",
|
||||
disasterPlace: "",
|
||||
disasterPhone: "",
|
||||
disasterDocument: null,
|
||||
generalName: "",
|
||||
generalPlace: "",
|
||||
generalPhone: "",
|
||||
generalDocument: null
|
||||
});
|
||||
const [isPanVerified, setIsPanVerified] = useState(false); // To track PAN verification status
|
||||
const [verificationError, setVerificationError] = useState("");
|
||||
|
|
@ -49,10 +71,7 @@ const FundDrive = () => {
|
|||
});
|
||||
};
|
||||
|
||||
const handleImageUpload = (event) => {
|
||||
const files = Array.from(event.target.files);
|
||||
setFormData({ ...formData, images: [...formData.images, ...files] });
|
||||
};
|
||||
|
||||
|
||||
const handleNext = () => {
|
||||
setStep(step + 1);
|
||||
|
|
@ -72,53 +91,14 @@ const FundDrive = () => {
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// const verifyPan = async () => {
|
||||
// try {
|
||||
// const formDataForPan = new FormData();
|
||||
// formDataForPan.append("pan", formData.pan);
|
||||
// formDataForPan.append("panImage", panImage); // panImage must be a File object
|
||||
|
||||
// const response = await axios.post(
|
||||
// "http://localhost:5002/api/verify-pan",
|
||||
// formDataForPan,
|
||||
// {
|
||||
// headers: {
|
||||
// "Content-Type": "multipart/form-data",
|
||||
// },
|
||||
// withCredentials: true, // Ensures credentials (cookies) are sent
|
||||
// }
|
||||
// );
|
||||
// console.log("vathuten da punda",response.data); // Check the backend response
|
||||
|
||||
// const isValid = response.data.verified;
|
||||
// setIsPanVerified(isValid);
|
||||
|
||||
// if (!isValid) {
|
||||
// setVerificationError("PAN number and uploaded image do not match.");
|
||||
// }
|
||||
|
||||
// return isValid;
|
||||
// } catch (error) {
|
||||
// setVerificationError("An error occurred during PAN verification.");
|
||||
// console.error(error);
|
||||
// return false;
|
||||
// }
|
||||
// };
|
||||
|
||||
|
||||
const verifyPan = async () => {
|
||||
try {
|
||||
// Validate PAN format client-side first
|
||||
const panRegex = /^[A-Z]{5}[0-9]{4}[A-Z]{1}$/;
|
||||
if (!panRegex.test(formData.pan)) {
|
||||
setVerificationError("Invalid PAN format. It should be in the format ABCDE1234F.");
|
||||
setVerificationError("Invalid PAN format.");
|
||||
setIsPanVerified(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!panImage) {
|
||||
setVerificationError("Please upload a PAN card image.");
|
||||
setIsPanVerified(false);
|
||||
|
|
@ -129,27 +109,17 @@ const FundDrive = () => {
|
|||
formDataForPan.append("pan", formData.pan);
|
||||
formDataForPan.append("panImage", panImage);
|
||||
|
||||
// Show loading state if needed
|
||||
// setIsLoading(true);
|
||||
|
||||
const response = await axios.post(
|
||||
"http://localhost:5002/api/verify-pan",
|
||||
formDataForPan,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
headers: { "Content-Type": "multipart/form-data" },
|
||||
}
|
||||
);
|
||||
|
||||
// Hide loading state
|
||||
// setIsLoading(false);
|
||||
|
||||
console.log("PAN verification response:", response.data);
|
||||
|
||||
if (response.data.verified) {
|
||||
setIsPanVerified(true);
|
||||
setVerificationError(""); // Clear any previous errors
|
||||
setVerificationError("");
|
||||
return true;
|
||||
} else {
|
||||
setIsPanVerified(false);
|
||||
|
|
@ -157,68 +127,123 @@ const FundDrive = () => {
|
|||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
// Hide loading state
|
||||
// setIsLoading(false);
|
||||
|
||||
console.error("Error verifying PAN:", error);
|
||||
|
||||
// Handle specific error cases
|
||||
if (error.response) {
|
||||
// The server responded with an error status
|
||||
setVerificationError(error.response.data.message || "PAN verification failed. Server returned an error.");
|
||||
} else if (error.request) {
|
||||
// The request was made but no response was received
|
||||
setVerificationError("Cannot connect to the verification service. Please try again later.");
|
||||
} else {
|
||||
// Something else caused the error
|
||||
setVerificationError("An error occurred during PAN verification.");
|
||||
}
|
||||
|
||||
setVerificationError(
|
||||
error.response?.data?.message || "Error connecting to PAN verification service."
|
||||
);
|
||||
setIsPanVerified(false);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// const handleSubmit = async (e) => {
|
||||
// e.preventDefault();
|
||||
|
||||
// if (!isPanVerified) {
|
||||
// const verified = await verifyPan();
|
||||
// if (!verified) {
|
||||
// alert("PAN not verified. Please verify before submitting.");
|
||||
// return;
|
||||
// }
|
||||
// if (!verified) return;
|
||||
// }
|
||||
|
||||
// try {
|
||||
// await submitVvvetForm(formData);
|
||||
// alert('Form submitted successfully');
|
||||
// await axios.post("http://localhost:5002/api/users/add", formData);
|
||||
// // Ensure this sends the form data to your backend
|
||||
// setStep(5); // Show the thank-you screen
|
||||
// } catch (error) {
|
||||
// console.error("Error submitting form:", error);
|
||||
// alert('Error submitting form');
|
||||
// // You can optionally show an inline error message instead of alert
|
||||
// }
|
||||
// };
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
// Verify PAN first if not verified
|
||||
if (!isPanVerified) {
|
||||
const verified = await verifyPan();
|
||||
if (!verified) {
|
||||
alert("PAN not verified. Please verify before submitting.");
|
||||
return;
|
||||
if (!verified) return;
|
||||
}
|
||||
|
||||
try {
|
||||
const formSubmissionData = new FormData();
|
||||
|
||||
// Append all string fields except files
|
||||
for (const key in formData) {
|
||||
const value = formData[key];
|
||||
if (value !== null && value !== undefined) {
|
||||
// Check if value is a File or object, skip files here
|
||||
if (value instanceof File) continue;
|
||||
if (typeof value === "object") continue;
|
||||
|
||||
formSubmissionData.append(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
// Proceed with form submission (assuming `submitVvvetForm` is defined)
|
||||
try {
|
||||
await submitVvvetForm(formData); // Make sure this function is defined elsewhere
|
||||
alert("Form submitted successfully!");
|
||||
// Append files (file inputs) separately
|
||||
const fileFields = ["feeDoc", "medicalPhoto", "medicalDoc", "document"];
|
||||
fileFields.forEach((field) => {
|
||||
if (formData[field]) {
|
||||
formSubmissionData.append(field, formData[field]);
|
||||
}
|
||||
});
|
||||
|
||||
// Also append panImage again if you want backend to receive it on form submit
|
||||
if (panImage) {
|
||||
formSubmissionData.append("panImage", panImage);
|
||||
}
|
||||
|
||||
const response = await axios.post(
|
||||
"http://localhost:5002/api/fundraising/submit",
|
||||
formSubmissionData,
|
||||
{
|
||||
headers: { "Content-Type": "multipart/form-data" },
|
||||
}
|
||||
);
|
||||
|
||||
console.log("Form submission response:", response.data);
|
||||
|
||||
// On success, move to thank-you step
|
||||
setStep(4);
|
||||
} catch (error) {
|
||||
console.error("Error submitting form:", error);
|
||||
alert("Error submitting form");
|
||||
alert("Error submitting form. Please try again.");
|
||||
}
|
||||
};
|
||||
const isStep2Valid = () => {
|
||||
const { category, customCategory, customReason } = formData;
|
||||
|
||||
if (!category) return false;
|
||||
|
||||
if (category === "Others") {
|
||||
return customCategory?.trim() && customReason?.trim();
|
||||
}
|
||||
|
||||
const requiredFieldsByCategory = {
|
||||
"Medical Fundraising": ["patientName", "cause", "hospitalName", "location", "phoneNumber", "attenderName", "amount", "medicalPhoto", "medicalDoc"],
|
||||
"Education & Scholarships": ["studentName", "standard", "parentsName", "parentsPhone", "amount", "feeDoc"],
|
||||
"Disaster Relief & Aid": ["name", "place", "phoneNumber", "amount", "document"],
|
||||
"Memorial & Tribute Funds": ["name", "place", "phoneNumber", "amount", "document"],
|
||||
"Community Development": ["name", "place", "phoneNumber", "amount", "document"],
|
||||
"Social Causes": ["name", "place", "phoneNumber", "amount", "document"],
|
||||
"Religious & Faith-Based Giving": ["name", "place", "phoneNumber", "amount", "document"],
|
||||
"Crowdfunding for Needs": ["name", "place", "phoneNumber", "amount", "document"],
|
||||
"Nonprofit & NGO Fundraising": ["name", "place", "phoneNumber", "amount", "document"]
|
||||
};
|
||||
|
||||
const fields = requiredFieldsByCategory[category];
|
||||
if (!fields) return true;
|
||||
|
||||
return fields.every(field => {
|
||||
const value = formData[field];
|
||||
return value && (typeof value === "string" ? value.trim() : true);
|
||||
});
|
||||
};
|
||||
const handleFileChange = (e) => {
|
||||
const { name, files } = e.target;
|
||||
setFormData(prev => ({ ...prev, [name]: files[0] }));
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
|
|
@ -339,7 +364,7 @@ const FundDrive = () => {
|
|||
)}
|
||||
|
||||
|
||||
{step === 2 && (
|
||||
{/* {step === 2 && (
|
||||
<div className="form-container-box">
|
||||
<h4>Step 2:Select a category</h4>
|
||||
{categories.map((item, index) => (
|
||||
|
|
@ -377,8 +402,175 @@ const FundDrive = () => {
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)} */}
|
||||
{step === 2 && (
|
||||
<div className="form-container-box">
|
||||
<h4>Step 2: Select a category</h4>
|
||||
|
||||
<select
|
||||
name="category"
|
||||
value={formData.category}
|
||||
onChange={handleInputChange}
|
||||
className="dropdown-input"
|
||||
required
|
||||
>
|
||||
<option value="">-- Select a Category --</option>
|
||||
{categories.map((item, index) => (
|
||||
<option key={index} value={item}>{item}</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
{formData.category === "Others" && (
|
||||
<>
|
||||
<label>Custom Category</label>
|
||||
<input
|
||||
type="text"
|
||||
name="customCategory"
|
||||
placeholder="Specify the category"
|
||||
value={formData.customCategory}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
className="custom-category-input"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Medical Fundraising */}
|
||||
{formData.category === "Medical Fundraising" && (
|
||||
<>
|
||||
<h5>Medical Fundraising Details</h5>
|
||||
<label>Patient Name</label>
|
||||
<input type="text" name="patientName" value={formData.patientName} onChange={handleInputChange} required />
|
||||
|
||||
<label>Cause</label>
|
||||
<input type="text" name="cause" value={formData.cause} onChange={handleInputChange} required />
|
||||
|
||||
<label>Hospital Name</label>
|
||||
<input type="text" name="hospitalName" value={formData.hospitalName} onChange={handleInputChange} required />
|
||||
|
||||
<label>Location</label>
|
||||
<input type="text" name="location" value={formData.location} onChange={handleInputChange} required />
|
||||
|
||||
<label>Phone Number</label>
|
||||
<input type="tel" name="phoneNumber" value={formData.phoneNumber} onChange={handleInputChange} required />
|
||||
|
||||
<label>Attender Name</label>
|
||||
<input type="text" name="attenderName" value={formData.attenderName} onChange={handleInputChange} required />
|
||||
|
||||
<label>Amount Needed</label>
|
||||
<input type="number" name="amount" value={formData.amount} onChange={handleInputChange} required />
|
||||
|
||||
<label>Medical Certificate</label>
|
||||
<input type="file" name="medicalPhoto" accept="image/*" onChange={handleFileChange} required />
|
||||
|
||||
<label>Medical Document</label>
|
||||
<input type="file" name="medicalDoc" accept=".pdf,.doc,.docx" onChange={handleFileChange} required />
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Education & Scholarships */}
|
||||
{formData.category === "Education & Scholarships" && (
|
||||
<>
|
||||
<h5>Education & Scholarships Details</h5>
|
||||
<label>Student Name</label>
|
||||
<input type="text" name="studentName" value={formData.studentName} onChange={handleInputChange} required />
|
||||
|
||||
<label>Standard</label>
|
||||
<input type="text" name="standard" value={formData.standard} onChange={handleInputChange} required />
|
||||
|
||||
<label>Parent's Name</label>
|
||||
<input type="text" name="parentsName" value={formData.parentsName} onChange={handleInputChange} required />
|
||||
|
||||
<label>Parent's Phone</label>
|
||||
<input type="tel" name="parentsPhone" value={formData.parentsPhone} onChange={handleInputChange} required />
|
||||
|
||||
<label>Amount Needed</label>
|
||||
<input type="number" name="amount" value={formData.amount} onChange={handleInputChange} required />
|
||||
|
||||
<label>Fee Document</label>
|
||||
<input type="file" name="feeDoc" accept=".pdf,.doc,.docx" onChange={handleFileChange} required />
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Disaster Relief */}
|
||||
{formData.category === "Disaster Relief & Aid" && (
|
||||
<>
|
||||
<h5>Disaster Relief Details</h5>
|
||||
<label>Name</label>
|
||||
<input type="text" name="name" value={formData.name} onChange={handleInputChange} required />
|
||||
|
||||
<label>Place</label>
|
||||
<input type="text" name="place" value={formData.place} onChange={handleInputChange} required />
|
||||
|
||||
<label>Phone Number</label>
|
||||
<input type="tel" name="phoneNumber" value={formData.phoneNumber} onChange={handleInputChange} required />
|
||||
|
||||
<label>Amount Needed</label>
|
||||
<input type="number" name="amount" value={formData.amount} onChange={handleInputChange} required />
|
||||
|
||||
<label>Relief Document</label>
|
||||
<input type="file" name="document" accept=".pdf,.doc,.docx" onChange={handleFileChange} required />
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Common template for general categories */}
|
||||
{[
|
||||
"Memorial & Tribute Funds",
|
||||
"Community Development",
|
||||
"Social Causes",
|
||||
"Religious & Faith-Based Giving",
|
||||
"Crowdfunding for Needs",
|
||||
"Nonprofit & NGO Fundraising"
|
||||
].includes(formData.category) && (
|
||||
<>
|
||||
<h5>Fundraising Details</h5>
|
||||
<label>Name</label>
|
||||
<input type="text" name="name" value={formData.name} onChange={handleInputChange} required />
|
||||
|
||||
<label>Place</label>
|
||||
<input type="text" name="place" value={formData.place} onChange={handleInputChange} required />
|
||||
|
||||
<label>Phone Number</label>
|
||||
<input type="tel" name="phoneNumber" value={formData.phoneNumber} onChange={handleInputChange} required />
|
||||
|
||||
<label>Amount Needed</label>
|
||||
<input type="number" name="amount" value={formData.amount} onChange={handleInputChange} required />
|
||||
|
||||
<label>Support Document</label>
|
||||
<input type="file" name="document" accept=".pdf,.doc,.docx" onChange={handleFileChange} required />
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Others Reason */}
|
||||
{formData.category === "Others" && (
|
||||
<>
|
||||
<h5>Other Fundraising Reason</h5>
|
||||
<label>Reason</label>
|
||||
<textarea
|
||||
name="customReason"
|
||||
placeholder="Specify your reason"
|
||||
value={formData.customReason}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className="button-group">
|
||||
<button type="button" className="form-button back-button" onClick={handleBack}>Back</button>
|
||||
<button
|
||||
type="button"
|
||||
className="form-button next-button"
|
||||
onClick={handleNext}
|
||||
disabled={!isStep2Valid()}
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
|
||||
{/* {step === 3 && (
|
||||
<div className="upload-section-box">
|
||||
|
|
@ -399,104 +591,10 @@ const FundDrive = () => {
|
|||
<img key={index} src={URL.createObjectURL(image)} alt={`Proof ${index + 1}`} className="uploaded-image" />
|
||||
))}
|
||||
</div> */}
|
||||
|
||||
{step === 3 && (
|
||||
<div className="upload-section-box">
|
||||
<h4>Step 3: Upload an Image</h4>
|
||||
<h3 className="upload-title">
|
||||
{formData.category === "Others" ? formData.customCategory : formData.category}
|
||||
</h3>
|
||||
|
||||
{/* Common image upload */}
|
||||
<div className="upload-box">
|
||||
<input
|
||||
type="file"
|
||||
multiple
|
||||
accept="image/*"
|
||||
onChange={handleImageUpload}
|
||||
className="file-input"
|
||||
/>
|
||||
<p className="upload-placeholder">Click or Drag & Drop to upload images</p>
|
||||
</div>
|
||||
|
||||
{/* Section-specific forms with headings */}
|
||||
{formData.category === "Medical Fundraising" && (
|
||||
<>
|
||||
<h4 className="section-heading">Upload Medical Details</h4>
|
||||
<input type="text" placeholder="Patient Name" className="form-field" />
|
||||
<input type="text" placeholder="Patient Contact Number" className="form-field" />
|
||||
</>
|
||||
)}
|
||||
|
||||
{formData.category === "Education & Scholarships" && (
|
||||
<>
|
||||
<h4 className="section-heading">Upload Student Details</h4>
|
||||
<input type="text" placeholder="Student Name" className="form-field" />
|
||||
<input type="text" placeholder="Standard/Class" className="form-field" />
|
||||
</>
|
||||
)}
|
||||
|
||||
{formData.category === "Disaster Relief & Aid" && (
|
||||
<>
|
||||
<h4 className="section-heading">Upload Relief Information</h4>
|
||||
<input type="text" placeholder="Cause/Place Affected" className="form-field" />
|
||||
</>
|
||||
)}
|
||||
|
||||
{formData.category === "Memorial & Tribute Funds" && (
|
||||
<>
|
||||
<h4 className="section-heading">Upload Tribute Details</h4>
|
||||
<input type="text" placeholder="Person Honored" className="form-field" />
|
||||
</>
|
||||
)}
|
||||
|
||||
{[
|
||||
"Community Development",
|
||||
"Social Causes",
|
||||
"Religious & Faith-Based Giving",
|
||||
"Crowdfunding for Needs",
|
||||
"Nonprofit & NGO Fundraising",
|
||||
].includes(formData.category) && (
|
||||
<>
|
||||
<h4 className="section-heading">Upload Cause Information</h4>
|
||||
<input type="text" placeholder="Cause Details" className="form-field" />
|
||||
</>
|
||||
)}
|
||||
|
||||
{formData.category === "Others" && (
|
||||
<>
|
||||
<h4 className="section-heading">Upload Custom Details</h4>
|
||||
<input type="text" placeholder="Describe your cause" className="form-field" />
|
||||
<input type="file" className="form-field" />
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Image preview */}
|
||||
<div className="image-preview">
|
||||
{formData.images.map((image, index) => (
|
||||
<img
|
||||
key={index}
|
||||
src={URL.createObjectURL(image)}
|
||||
alt={`Proof ${index + 1}`}
|
||||
className="uploaded-image"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="button-group">
|
||||
<button type="button" className="form-button back-button" onClick={handleBack}>Back</button>
|
||||
<button
|
||||
type="button"
|
||||
className="form-button next-button"
|
||||
onClick={handleNext}
|
||||
disabled={!formData.category || (formData.category === "Others" && !formData.customCategory.trim())}
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{step === 4 && (
|
||||
<div className="bank-details-section-box">
|
||||
<h4>Step 4: Banking Details</h4>
|
||||
<h4>Step 3: Banking Details</h4>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">Bank Account Holder Name</label>
|
||||
|
|
@ -527,8 +625,15 @@ const FundDrive = () => {
|
|||
placeholder="Bank Account Number"
|
||||
className="form-field"
|
||||
value={formData.accountNumber}
|
||||
onChange={(e) => setFormData({ ...formData, accountNumber: e.target.value })}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
if (/^\d{0,17}$/.test(value)) {
|
||||
setFormData({ ...formData, accountNumber: value });
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{(formData.accountNumber.length < 11 || formData.accountNumber.length > 17)
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
|
|
@ -538,9 +643,13 @@ const FundDrive = () => {
|
|||
placeholder="IFSC Code"
|
||||
className="form-field"
|
||||
value={formData.ifscCode}
|
||||
onChange={(e) => setFormData({ ...formData, ifscCode: e.target.value })}
|
||||
onChange={(e) => setFormData({ ...formData, ifscCode: e.target.value.toUpperCase() })}
|
||||
/>
|
||||
{!/^[A-Z]{4}0[A-Z0-9]{6}$/.test(formData.ifscCode) && formData.ifscCode !== '' && (
|
||||
<p className="error-message">Invalid IFSC Code format</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">Fundraising Amount</label>
|
||||
<input
|
||||
|
|
@ -550,9 +659,7 @@ const FundDrive = () => {
|
|||
value={formData.fundAmount}
|
||||
onChange={(e) => {
|
||||
const value = parseInt(e.target.value, 10);
|
||||
if (!isNaN(value) && value >= 0) {
|
||||
setFormData({ ...formData, fundAmount: value });
|
||||
}
|
||||
setFormData({ ...formData, fundAmount: isNaN(value) ? '' : value });
|
||||
}}
|
||||
min="1000"
|
||||
/>
|
||||
|
|
@ -560,11 +667,27 @@ const FundDrive = () => {
|
|||
<p className="error-message">Minimum amount should be ₹1000</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="button-group">
|
||||
<button type="button" className="form-button back-button" onClick={handleBack}>
|
||||
Back
|
||||
</button>
|
||||
<button type="button" className="form-button submit-button" onClick={handleSubmit}>
|
||||
<button
|
||||
type="button"
|
||||
className="form-button submit-button"
|
||||
onClick={handleSubmit}
|
||||
disabled={
|
||||
!formData.bankHolderName ||
|
||||
!formData.bankName ||
|
||||
!formData.accountNumber ||
|
||||
formData.accountNumber.length < 11 ||
|
||||
formData.accountNumber.length > 17 ||
|
||||
!formData.ifscCode ||
|
||||
!/^[A-Z]{4}0[A-Z0-9]{6}$/.test(formData.ifscCode) ||
|
||||
!formData.fundAmount ||
|
||||
formData.fundAmount < 1000
|
||||
}
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -572,6 +695,20 @@ const FundDrive = () => {
|
|||
)}
|
||||
|
||||
|
||||
{step === 4 && (
|
||||
<div className="form-container-box">
|
||||
<h4>Thank You!</h4>
|
||||
<p>Thanks for reaching out to VVET. We will review your submission and get back to you soon.</p>
|
||||
|
||||
<button className="form-button" onClick={() => window.location.reload()}>
|
||||
Start Over
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import './Homesection1.css'
|
|||
|
||||
const HomeSection1 = () => {
|
||||
return (
|
||||
<div class="home-section">
|
||||
<div className="home-section">
|
||||
<div>
|
||||
<h1 className='heading-border-bottom'>Welcome to Vertivel Educational Trust</h1>
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import Navbar from "./Navbar";
|
||||
import Footer from "./Footer";
|
||||
import Carousel from "./Carousel";
|
||||
import HomeSection1 from "./Home-Section-1";
|
||||
|
|
@ -12,7 +11,6 @@ import "./Home.css";
|
|||
|
||||
const Home = () => {
|
||||
const images = [
|
||||
"https://i.postimg.cc/4NtQrKtZ/Untitled1.jpg",
|
||||
"https://i.postimg.cc/MKkybWLL/Untitled2.jpg",
|
||||
"https://i.postimg.cc/15pDvkh3/Untitled3.jpg",
|
||||
"https://i.postimg.cc/6pcnXCQs/Untitled4.jpg",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import React from 'react';
|
||||
import { Button, Typography, Box, Grid, Icon } from '@mui/material';
|
||||
import { AccessAlarm, School, CheckCircle } from '@mui/icons-material';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
|
@ -28,7 +27,7 @@ const HomeMockSection = () => {
|
|||
|
||||
<Typography variant="body1" sx={{ marginBottom: '20px' }}>
|
||||
Prepare for NEET with high-quality mock tests designed to give you the best practice before the big exam.
|
||||
With Vidhai's mock tests, you can assess your performance and get feedback that helps you improve.
|
||||
With Vidhai's mock tests, you can assess your performance and get feedback that helps you improve.
|
||||
</Typography>
|
||||
|
||||
<Grid container spacing={2} sx={{ marginBottom: '20px' }}>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import React from 'react';
|
||||
import './Marquee.css'; // Import the CSS file for styling
|
||||
|
||||
const Marquee = () => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import "./Navbar.css";
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ function Navbar() {
|
|||
alt="College Logo"
|
||||
/>
|
||||
<div className="brand-section">
|
||||
<h4 className="college-name" onClick={() => navigate("/")}>
|
||||
<h4 className="college-name" onClick={() => navigate("/home")}>
|
||||
VETRIVEL EDUCATIONAL TRUST
|
||||
</h4>
|
||||
<p>A Legacy of Excellence in Education</p>
|
||||
|
|
@ -34,7 +34,7 @@ function Navbar() {
|
|||
</button>
|
||||
|
||||
{/* Links */}
|
||||
<div className={`links ${menuOpen ? "open" : ""}`}>
|
||||
<div className={`links ${menuOpen ? "open" : "/home"}`}>
|
||||
<Link to="/home">Home</Link>
|
||||
<Link to="/aboutUs">About Us</Link>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import React from 'react';
|
||||
import { Card, CardContent, Typography } from '@mui/material';
|
||||
import { Support, AttachMoney, Group } from '@mui/icons-material'; // Importing specific Material UI icons
|
||||
import { AttachMoney, Group } from '@mui/icons-material'; // Importing specific Material UI icons
|
||||
import PersonIcon from '@mui/icons-material/Person';
|
||||
import './StatsCard.css'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,354 +1,483 @@
|
|||
import { useState } from "react";
|
||||
import "./Supporter.css";
|
||||
import "./FundDrive.css";
|
||||
// Inside src/Components/FundDrive.jsx
|
||||
import axios from "axios";
|
||||
import './form-step2.css';
|
||||
|
||||
const Supporter = () => {
|
||||
|
||||
|
||||
const FundDrive = () => {
|
||||
const [step, setStep] = useState(1);
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const [formData, setFormData] = useState({
|
||||
name: "",
|
||||
email: "",
|
||||
phone: "",
|
||||
age: "",
|
||||
dob: "",
|
||||
aadharFront: null,
|
||||
aadharBack: null,
|
||||
paymentMethod: "",
|
||||
paymentScreenshot: null,
|
||||
category: "",
|
||||
customCategory: "",
|
||||
pan: "",
|
||||
images: [],
|
||||
bankHolderName: "",
|
||||
bankName: "",
|
||||
accountNumber: "",
|
||||
ifscCode: "",
|
||||
donation_Amount: "",
|
||||
payment: "",
|
||||
transactionScreenshot: null,
|
||||
feeDoc: null,
|
||||
});
|
||||
const [isPanVerified, setIsPanVerified] = useState(false); // To track PAN verification status
|
||||
const [verificationError, setVerificationError] = useState("");
|
||||
const [panImage, setPanImage] = useState(null); // Define panImage state
|
||||
|
||||
const [showPaymentScreenshot, setShowPaymentScreenshot] = useState(false);
|
||||
|
||||
const handleChange = (e) => {
|
||||
const { name, value, files } = e.target;
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
[name]: files ? files[0] : value,
|
||||
}));
|
||||
|
||||
const handleInputChange = (e) => {
|
||||
const { name, value } = e.target;
|
||||
setFormData({
|
||||
...formData,
|
||||
[name]: value,
|
||||
});
|
||||
};
|
||||
|
||||
const nextStep = () => {
|
||||
if (isValid()) setStep((prev) => prev + 1);
|
||||
|
||||
|
||||
const handleNext = () => {
|
||||
setStep(step + 1);
|
||||
};
|
||||
|
||||
const prevStep = () => setStep((prev) => prev - 1);
|
||||
const handleBack = () => {
|
||||
if (step > 1) setStep(step - 1);
|
||||
};
|
||||
|
||||
const isValid = () => {
|
||||
if (step === 1) {
|
||||
return formData.name && formData.email && formData.phone && formData.age && formData.dob;
|
||||
|
||||
const handlePanImageUpload = (e) => {
|
||||
const file = e.target.files[0];
|
||||
setPanImage(file); // Store PAN image in state
|
||||
};
|
||||
|
||||
|
||||
|
||||
const verifyPan = async () => {
|
||||
try {
|
||||
// Validate PAN format client-side first
|
||||
const panRegex = /^[A-Z]{5}[0-9]{4}[A-Z]{1}$/;
|
||||
if (!panRegex.test(formData.pan)) {
|
||||
setVerificationError("Invalid PAN format. It should be in the format ABCDE1234F.");
|
||||
setIsPanVerified(false);
|
||||
return false;
|
||||
}
|
||||
if (step === 2) {
|
||||
return formData.aadharFront && formData.aadharBack;
|
||||
|
||||
if (!panImage) {
|
||||
setVerificationError("Please upload a PAN card image.");
|
||||
setIsPanVerified(false);
|
||||
return false;
|
||||
}
|
||||
if (step === 3) {
|
||||
return formData.paymentMethod;
|
||||
}
|
||||
if (step === 4 && formData.paymentMethod === "UPI") {
|
||||
return formData.paymentScreenshot;
|
||||
|
||||
const formDataForPan = new FormData();
|
||||
formDataForPan.append("pan", formData.pan);
|
||||
formDataForPan.append("panImage", panImage);
|
||||
|
||||
// Show loading state if needed
|
||||
// setIsLoading(true);
|
||||
|
||||
const response = await axios.post(
|
||||
"http://localhost:5002/api/verify-pan",
|
||||
formDataForPan,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
|
||||
console.log("PAN verification response:", response.data);
|
||||
|
||||
if (response.data.verified) {
|
||||
setIsPanVerified(true);
|
||||
setVerificationError(""); // Clear any previous errors
|
||||
return true;
|
||||
} else {
|
||||
setIsPanVerified(false);
|
||||
setVerificationError(response.data.message || "PAN verification failed.");
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
// Hide loading state
|
||||
// setIsLoading(false);
|
||||
|
||||
console.error("Error verifying PAN:", error);
|
||||
|
||||
// Handle specific error cases
|
||||
if (error.response) {
|
||||
// The server responded with an error status
|
||||
setVerificationError(error.response.data.message || "PAN verification failed. Server returned an error.");
|
||||
} else if (error.request) {
|
||||
// The request was made but no response was received
|
||||
setVerificationError("Cannot connect to the verification service. Please try again later.");
|
||||
} else {
|
||||
// Something else caused the error
|
||||
setVerificationError("An error occurred during PAN verification.");
|
||||
}
|
||||
|
||||
setIsPanVerified(false);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const handleFileChange = (e) => {
|
||||
const { name, files } = e.target;
|
||||
setFormData((prev) => ({ ...prev, [name]: files[0] }));
|
||||
};
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
setIsSubmitting(true);
|
||||
|
||||
// Verify PAN first if not verified
|
||||
if (!isPanVerified) {
|
||||
const verified = await verifyPan();
|
||||
if (!verified) return;
|
||||
}
|
||||
|
||||
try {
|
||||
console.log("Submitting Form Data:", formData);
|
||||
setTimeout(() => {
|
||||
alert("Form Submitted Successfully!");
|
||||
setIsSubmitting(false);
|
||||
setFormData({
|
||||
name: "",
|
||||
email: "",
|
||||
phone: "",
|
||||
age: "",
|
||||
dob: "",
|
||||
aadharFront: null,
|
||||
aadharBack: null,
|
||||
paymentMethod: "",
|
||||
paymentScreenshot: null,
|
||||
});
|
||||
}, 2000);
|
||||
const formSubmissionData = new FormData();
|
||||
|
||||
// Append non-file fields
|
||||
for (const key in formData) {
|
||||
if (formData[key] && !(formData[key] instanceof File)) {
|
||||
formSubmissionData.append(key, formData[key]);
|
||||
}
|
||||
}
|
||||
|
||||
// Append donor-specific file fields
|
||||
if (panImage) {
|
||||
formSubmissionData.append("panImage", panImage);
|
||||
}
|
||||
if (formData.transactionScreenshot) {
|
||||
formSubmissionData.append("transactionScreenshot", formData.transactionScreenshot);
|
||||
}
|
||||
|
||||
const response = await axios.post(
|
||||
"http://localhost:5002/api/donor/submit",
|
||||
formSubmissionData,
|
||||
{ headers: { "Content-Type": "multipart/form-data" } }
|
||||
);
|
||||
|
||||
console.log("Donor form response:", response.data);
|
||||
setStep(4); // success step
|
||||
} catch (error) {
|
||||
console.error("Submission Error:", error);
|
||||
alert("Something went wrong. Please try again.");
|
||||
setIsSubmitting(false);
|
||||
console.error("Donor form submission error:", error);
|
||||
alert("Error submitting donor form. Please try again.");
|
||||
}
|
||||
};
|
||||
|
||||
const handleUPIPayment = () => {
|
||||
const upiUrl =
|
||||
"upi://pay?pa=157511100001246@UBIN0815756.ifsc.npci&pn=Ashoka%20Windows%20and%20Annex%20Apartment%20Owners%20Association&cu=INR&am=50&tn=113%20Dec%202021%20fine&tr=202112113fine&refUrl=https%3A%2F%2Fwww.ashokawindows.com";
|
||||
|
||||
// Open the UPI payment app
|
||||
window.location.href = upiUrl;
|
||||
|
||||
// Immediately show the upload screenshot field after clicking Pay via UPI
|
||||
setShowPaymentScreenshot(true);
|
||||
};
|
||||
|
||||
const handleNetBankingPayment = () => {
|
||||
// Placeholder for actual Net Banking redirection or API call
|
||||
alert("Redirecting to Net Banking Payment Gateway...");
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="supporter-container">
|
||||
<div className="step-box">
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="container">
|
||||
|
||||
<div className="container-box">
|
||||
<form>
|
||||
{step === 1 && (
|
||||
<div className="step1-box">
|
||||
<h4>Step 1:Personal Details</h4>
|
||||
<label>Name:</label>
|
||||
<div className="step-box">
|
||||
<h4>Step 1: Personal Details</h4>
|
||||
|
||||
<div className="form-grid">
|
||||
<div className="form-field">
|
||||
<label>Name</label>
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
value={formData.name}
|
||||
onChange={handleChange}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
className="input-small"
|
||||
placeholder="Enter your name"
|
||||
placeholder="Full Name"
|
||||
/>
|
||||
<label>Email:</label>
|
||||
</div>
|
||||
|
||||
<div className="form-field">
|
||||
<label>Email</label>
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
value={formData.email}
|
||||
onChange={handleChange}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
className="input-small"
|
||||
placeholder="Enter your email"
|
||||
placeholder="example@domain.com"
|
||||
/>
|
||||
<label>Phone Number:</label>
|
||||
<input
|
||||
type="tel"
|
||||
name="phone"
|
||||
value={formData.phone}
|
||||
onChange={handleChange}
|
||||
required
|
||||
className="input-small"
|
||||
placeholder="Enter phone number"
|
||||
/>
|
||||
<label>Age:</label>
|
||||
</div>
|
||||
<div className="form-field">
|
||||
<label>Age</label>
|
||||
<input
|
||||
type="number"
|
||||
name="age"
|
||||
value={formData.age}
|
||||
onChange={handleChange}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
className="input-small"
|
||||
placeholder="Enter your age"
|
||||
placeholder="e.g. 25"
|
||||
/>
|
||||
<label>Date of Birth:</label>
|
||||
</div>
|
||||
<div className="form-field">
|
||||
<label>Date of Birth</label>
|
||||
<input
|
||||
type="date"
|
||||
name="dob"
|
||||
value={formData.dob}
|
||||
onChange={handleChange}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
className="input-small"
|
||||
placeholder="e.g. 25"
|
||||
/>
|
||||
<br />
|
||||
<br />
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-field">
|
||||
<label>Phone Number</label>
|
||||
<input
|
||||
type="tel"
|
||||
name="phone"
|
||||
value={formData.phone}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
placeholder="10-digit number"
|
||||
/>
|
||||
</div>
|
||||
<div className="form-field">
|
||||
<label>PAN Number</label>
|
||||
<input
|
||||
type="text"
|
||||
name="pan"
|
||||
value={formData.pan}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
maxLength={10}
|
||||
placeholder="e.g. ABCDE1234F"
|
||||
className="input-small"
|
||||
pattern="[A-Z]{5}[0-9]{4}[A-Z]{1}"
|
||||
title="Enter valid 10-character PAN (e.g. ABCDE1234F)"
|
||||
/>
|
||||
</div>
|
||||
<div className="form-field">
|
||||
<label>Upload PAN Image</label>
|
||||
<input
|
||||
type="file"
|
||||
accept="image/*"
|
||||
onChange={handlePanImageUpload}
|
||||
required
|
||||
/>
|
||||
{panImage && <p>{panImage.name}</p>} {/* Display image file name */}
|
||||
</div>
|
||||
{verificationError && <p style={{ color: 'red' }}>{verificationError}</p>}
|
||||
<div className="form-field">
|
||||
<button
|
||||
type="button"
|
||||
onClick={nextStep}
|
||||
disabled={!isValid()}
|
||||
className="form-button verify-button"
|
||||
onClick={verifyPan}
|
||||
disabled={!formData.pan || !panImage}
|
||||
>
|
||||
Verify PAN
|
||||
</button>
|
||||
{isPanVerified && <p style={{ color: 'green' }}>PAN verified successfully!</p>}
|
||||
</div>
|
||||
<div className="button-group">
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleNext}
|
||||
className="form-button next-button"
|
||||
disabled={!formData.name || !formData.email || !formData.phone || !formData.age || !formData.dob || !formData.pan || !isPanVerified}
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
|
||||
{step === 2 && (
|
||||
<div className="step2-box">
|
||||
<h4>Step 2:Upload a Images</h4>
|
||||
<label>Aadhar Card Front:</label>
|
||||
<div className="bank-details-section-box">
|
||||
<h4>Step 2: Banking Details</h4>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">Bank Account Holder Name</label>
|
||||
<input
|
||||
type="file"
|
||||
name="aadharFront"
|
||||
onChange={handleChange}
|
||||
required
|
||||
className="input-small"
|
||||
type="text"
|
||||
placeholder="Bank Account Holder Name"
|
||||
className="form-field"
|
||||
value={formData.bankHolderName}
|
||||
onChange={(e) => setFormData({ ...formData, bankHolderName: e.target.value })}
|
||||
/>
|
||||
<label>Aadhar Card Back:</label>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">Bank Name</label>
|
||||
<input
|
||||
type="file"
|
||||
name="aadharBack"
|
||||
onChange={handleChange}
|
||||
required
|
||||
className="input-small"
|
||||
type="text"
|
||||
placeholder="Bank Name"
|
||||
className="form-field"
|
||||
value={formData.bankName}
|
||||
onChange={(e) => setFormData({ ...formData, bankName: e.target.value })}
|
||||
/>
|
||||
<br />
|
||||
<br />
|
||||
<button
|
||||
type="button"
|
||||
onClick={prevStep}
|
||||
className="form-button back-button"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">Bank Account Number</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Bank Account Number"
|
||||
className="form-field"
|
||||
value={formData.accountNumber}
|
||||
onChange={(e) => setFormData({ ...formData, accountNumber: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label className="form-label">IFSC Code</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="IFSC Code"
|
||||
className="form-field"
|
||||
value={formData.ifscCode}
|
||||
onChange={(e) => setFormData({ ...formData, ifscCode: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="form-label">Donating Amount</label>
|
||||
<input
|
||||
type="number"
|
||||
placeholder="Donating Amount"
|
||||
className="form-field"
|
||||
value={formData.donation_Amount}
|
||||
onChange={(e) => {
|
||||
const value = parseInt(e.target.value, 10);
|
||||
if (!isNaN(value) && value >= 0) {
|
||||
setFormData({ ...formData, donation_Amount: value });
|
||||
}
|
||||
}}
|
||||
min="1000"
|
||||
/>
|
||||
{formData.donation_Amount > 0 && formData.donation_Amount < 1000 && (
|
||||
<p className="error-message">Minimum amount should be ₹1000</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="button-group">
|
||||
<button type="button" className="form-button back-button" onClick={handleBack}>
|
||||
Back
|
||||
</button>
|
||||
<div style={{ marginTop: "10px" }}>
|
||||
{/* <button type="button" className="form-button submit-button" onClick={handleNext}>
|
||||
Next
|
||||
</button> */}
|
||||
<button
|
||||
type="button"
|
||||
onClick={nextStep}
|
||||
disabled={!isValid()}
|
||||
className="form-button next-button"
|
||||
className="form-button submit-button"
|
||||
onClick={handleNext}
|
||||
disabled={
|
||||
!formData.bankHolderName ||
|
||||
!formData.bankName ||
|
||||
!formData.accountNumber ||
|
||||
formData.accountNumber.length < 11 ||
|
||||
formData.accountNumber.length > 17 ||
|
||||
!formData.ifscCode ||
|
||||
!/^[A-Z]{4}0[A-Z0-9]{6}$/.test(formData.ifscCode) ||
|
||||
!formData.donation_Amount||
|
||||
formData.donation_Amount < 1000
|
||||
}
|
||||
>
|
||||
Next
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
)}
|
||||
{step === 3 && (
|
||||
<div className="step3-box">
|
||||
<h4>Step 3:Select Payment Method</h4>
|
||||
<label>Payment Method:</label>
|
||||
<div className="form-container-box">
|
||||
<h4>Step 3: Payment & Upload Transaction Screenshot</h4>
|
||||
|
||||
<label htmlFor="payment">Select Payment Method *</label>
|
||||
<select
|
||||
name="paymentMethod"
|
||||
|
||||
value={formData.paymentMethod}
|
||||
onChange={handleChange}
|
||||
name="payment"
|
||||
value={formData.payment || ""}
|
||||
onChange={handleInputChange}
|
||||
required
|
||||
className="input-small"
|
||||
|
||||
className="form-select"
|
||||
>
|
||||
|
||||
<option value="UPI">Pay by any UPI App</option>
|
||||
<option value="Net Banking">Net Banking</option>
|
||||
<option value="" disabled>Select Payment Mode</option>
|
||||
<option value="UPI">UPI</option>
|
||||
<option value="Bank Transfer">Bank Transfer</option>
|
||||
</select>
|
||||
<br />
|
||||
<br />
|
||||
<button
|
||||
type="button"
|
||||
onClick={prevStep}
|
||||
className="form-button back-button"
|
||||
>
|
||||
|
||||
{/* UPI QR Code */}
|
||||
{formData.payment === "UPI" && (
|
||||
<div className="upi-section">
|
||||
<p>Scan the UPI QR code to make the payment:</p>
|
||||
<img src="src/Components/upi.png" alt="UPI QR Code" className="upi-image" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Bank Transfer Details */}
|
||||
{formData.payment === "Bank Transfer" && (
|
||||
<div className="bank-details">
|
||||
<p><strong>Account No:</strong> 50200082832122</p>
|
||||
<p><strong>Bank:</strong> HDFC</p>
|
||||
<p><strong>Branch:</strong> DEVAKOTTAI</p>
|
||||
<p><strong>Account Name:</strong> DVK VETRIVEL EDU AND WEL PUB CHAR TRUST</p>
|
||||
<p><strong>Account Type:</strong> Current</p>
|
||||
<p><strong>RTGS/NEFT IFSC:</strong> HDFC0002576</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
{/* Screenshot Upload */}
|
||||
{formData.payment && (
|
||||
<>
|
||||
<label htmlFor="transactionScreenshot">Upload Transaction Screenshot *</label>
|
||||
<input
|
||||
type="file"
|
||||
name="transactionScreenshot"
|
||||
accept="image/*"
|
||||
onChange={handleFileChange}
|
||||
required
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className="button-group">
|
||||
<button type="button" className="form-button back-button" onClick={handleBack}>
|
||||
Back
|
||||
</button>
|
||||
<div style={{ marginTop: "10px" }}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={nextStep}
|
||||
disabled={!isValid()}
|
||||
className="form-button next-button"
|
||||
onClick={handleSubmit}
|
||||
disabled={!formData.payment || !formData.transactionScreenshot}
|
||||
>
|
||||
Next
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
|
||||
{step === 4 && formData.paymentMethod === "UPI" && (
|
||||
<div className="step4-box">
|
||||
<h4>Step 4:Pay via UPI</h4>
|
||||
<br></br>
|
||||
<br></br>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleUPIPayment}
|
||||
className="form-button upi-button"
|
||||
>
|
||||
Pay via UPI
|
||||
</button>
|
||||
{/* Upload screenshot field appears after Pay via UPI is clicked */}
|
||||
{showPaymentScreenshot && (
|
||||
<div className="payment-screenshot">
|
||||
<label>Upload Payment Screenshot:</label>
|
||||
<input
|
||||
type="file"
|
||||
name="paymentScreenshot"
|
||||
onChange={handleChange}
|
||||
required
|
||||
className="input-small"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<br />
|
||||
<br />
|
||||
<button
|
||||
type="button"
|
||||
onClick={prevStep}
|
||||
className="form-button back-button"
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
<div style={{ marginTop: "10px" }}>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isSubmitting || !formData.paymentScreenshot}
|
||||
className="form-button submit-button"
|
||||
>
|
||||
{isSubmitting ? "Submitting..." : "Submit"}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{step === 4 && (
|
||||
<div className="form-container-box">
|
||||
<h4>Thank You!</h4>
|
||||
<p>Thanks for reaching out to VVET. We will review your submission and get back to you soon.</p>
|
||||
|
||||
{step === 4 && formData.paymentMethod === "Net Banking" && (
|
||||
<div className="step4-box">
|
||||
<h4>Step 4:Pay via Net banking</h4>
|
||||
<br></br>
|
||||
<br></br>
|
||||
{/* Net Banking - Redirection or Process */}
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleNetBankingPayment}
|
||||
className="form-button net-banking-button"
|
||||
>
|
||||
Pay via Net Banking
|
||||
</button>
|
||||
{/* Upload screenshot field appears after Pay via Net Banking is clicked */}
|
||||
{showPaymentScreenshot && (
|
||||
<div className="payment-screenshot">
|
||||
<label>Upload Payment Screenshot:</label>
|
||||
<input
|
||||
type="file"
|
||||
name="paymentScreenshot"
|
||||
onChange={handleChange}
|
||||
required
|
||||
className="input-small"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<br />
|
||||
<br />
|
||||
<button
|
||||
type="button"
|
||||
onClick={prevStep}
|
||||
className="form-button back-button"
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
<div style={{ marginTop: "10px" }}>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isSubmitting || !formData.paymentScreenshot}
|
||||
className="form-button submit-button"
|
||||
>
|
||||
{isSubmitting ? "Submitting..." : "Submit"}
|
||||
<button className="form-button" onClick={() => window.location.reload()}>
|
||||
Start Over
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
|
||||
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
);
|
||||
};
|
||||
|
||||
export default Supporter;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export default FundDrive;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
.form-container-box {
|
||||
padding: 20px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 10px;
|
||||
background-color: #fff;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
color: #f3efef;
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 15px;
|
||||
font-size: 1.2rem;
|
||||
color: #a9a3a3;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 5px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="number"],
|
||||
input[type="tel"],
|
||||
input[type="file"],
|
||||
select,
|
||||
textarea {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
margin-bottom: 10px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
font-size: 1rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
select.dropdown-input {
|
||||
margin-top: 10px;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
textarea {
|
||||
min-height: 100px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.form-button {
|
||||
padding: 10px 20px;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.form-button:disabled {
|
||||
background-color: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.back-button {
|
||||
background-color: #6c757d;
|
||||
}
|
||||
|
||||
.custom-category-input {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
|
|
@ -3,7 +3,7 @@ import axios from 'axios';
|
|||
|
||||
export const submitVvvetForm = async (formData) => {
|
||||
try {
|
||||
const response = await axios.post('http://localhost:5002/api/vvet/add', formData);
|
||||
const response = await axios.post('http://localhost:5002/api/users/add', formData);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error('Error submitting form:', error);
|
||||
|
|
|
|||
Loading…
Reference in New Issue