const [formData, setFormData] = useState({
name: "",
email: "",
vote: "",
// Not uploaded to the Database. This is used for route.ts switch case
action: "Demo",
});
...
// Handles anything Input related on the Voting Demo Form
const handleChange = (e: any) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};
For the handleSubmit, this is where the main functionality takes place!
// When the Form is submitted
const handleSubmit = async (e: any) => {
e.preventDefault();
setMessage("");
// If the user did not vote a specific pokemon, error message is shown
if (!formData.vote) {
setMessage("Error: Please select a Pokémon to vote for.");
return;
}
// If all inputs are entered, perform a POST request in the route.ts where we head to the "Demo" switch statement
const res = await fetch("/api/vote", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name: formData.name,
email: formData.email,
vote: formData.vote,
action: "Demo", // Not uploaded to the Database. This is used for route.ts switch case
}),
});
const data = await res.json();
if (!res.ok) {
setMessage(data?.error || "Error: Form submission failed.");
} else {
setMessage("Vote submitted successfully!");
setFormData({
name: "",
email: "",
vote: "",
action: "Demo", // Not uploaded to the Database. This is used for route.ts switch case
});
}
};
When the user clicks "Submit", it checks to see if the user selected their vote. If not, it prompts the error to the user that they need to vote:
// If the user did not vote a specific pokemon, error message is shown
if (!formData.vote) {
setMessage("Error: Please select a Pokémon to vote for.");
return;
}
If the check is all good, it performs a POST request on /api/vote and sending it to the database. After that, the form clears out:
// If all inputs are entered, perform a POST request in the route.ts where we head to the "Demo" switch statement
const res = await fetch("/api/vote", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name: formData.name,
email: formData.email,
vote: formData.vote,
action: "Demo", // Not uploaded to the Database. This is used for route.ts switch case
}),
});
const data = await res.json();
if (!res.ok) {
setMessage(data?.error || "Error: Form submission failed.");
} else {
setMessage("Vote submitted successfully!");
setFormData({
name: "",
email: "",
vote: "",
action: "Demo", // Not uploaded to the Database. This is used for route.ts switch case
});
}
That's pretty much what's happening on the client side. You may also notice this part:
action: "Demo", // Not uploaded to the Database. This is used for route.ts switch case
In the api/vote folder, I have multiple PUT requests in where inside of the PUT request, there is a switch case. I won't be able to go into detail now, but one thing to note that it is used to identify which code to execute. In this case, it's "Demo":
case "Demo": {
const { name, email, vote } = body;
if (!name || !email || !vote) {
return NextResponse.json(
{ error: "Missing name, email, or vote" },
{ status: 400 }
);
}
// Insert the row that contains their name, email, and the vote they voted for
const { error } = await supabase
.from("VoteDemo")
.insert([
{
Name: name,
Email: email,
Vote: vote,
},
]);
if (error) {
console.log("Supabase insert error (VoteDemo):", error);
return NextResponse.json(
{ error: error.message },
{ status: 500 }
);
}
return NextResponse.json({
success: true,
message: "Vote saved successfully in VoteDemo",
});
}
Simply put, it does an insert statement to the "VoteDemo" table of the Name, Email, and Vote (yes @bingkahu, I saw your many votes. on that database).
That is pretty much it for that page. Next week, I will discuss more detail on how the Custom Polls work!
Official Website
If you would love to see the project yourself, feel free to check out the link here: https://easypollvote.vercel.app
I recommend to put a fake email and a fake name if you are using the app. Everything works as intended! Check it out and feedback is greatly appreciated!
Any questions/comments/feedback? I would love to hear from you!
Note: This post is monitored by the University and therefore the repository is currently private until the early Summer!