From a71f101b1079183630a7972d1837850a7d8d9a4b Mon Sep 17 00:00:00 2001
From: Maaz
Date: Sun, 15 Jun 2025 14:17:14 -0500
Subject: [PATCH] feat: add ReviewsSection component with review fetching and
submission functionality
---
src/App.tsx | 23 +++++-
src/ReviewsSection.tsx | 165 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 185 insertions(+), 3 deletions(-)
diff --git a/src/App.tsx b/src/App.tsx
index 48934cb..b7f71ee 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,4 +1,5 @@
import { useState, useEffect } from "react";
+import ReviewsSection from "./ReviewsSection";
import {
ChevronDown,
Trophy,
@@ -542,7 +543,10 @@ const App = () => {
Striker Competition
- Engineered a realistic operating room prototype showcased at the Stryker Competition, demonstrating advanced surgical workflow design and innovation.
+ Engineered a realistic operating room prototype showcased at
+ the Stryker Competition, demonstrating advanced surgical
+ workflow design and innovation.
+
@@ -675,7 +679,10 @@ const App = () => {
-
+
Entrepreneurial Spirit
@@ -689,7 +696,10 @@ const App = () => {
-
+
Growth Mindset
@@ -703,6 +713,13 @@ const App = () => {
+ {/* Reviews Section */}
+
+
{/* Footer */}
{
+ const [reviews, setReviews] = useState([]);
+ const [name, setName] = useState("");
+ const [message, setMessage] = useState("");
+ const [loading, setLoading] = useState(false);
+ const [error, setError] = useState("");
+ const [success, setSuccess] = useState("");
+ const [isModalOpen, setIsModalOpen] = useState(false);
+
+ useEffect(() => {
+ fetchReviews().then(setReviews);
+ }, []);
+ const handleSubmit = async (e: React.FormEvent) => {
+ e.preventDefault();
+ setLoading(true);
+ setError("");
+ setSuccess("");
+ try {
+ await addReview({ name, message });
+ setSuccess("Review submitted!");
+ setName("");
+ setMessage("");
+ setReviews(await fetchReviews());
+ // Close modal immediately after successful submission
+ setIsModalOpen(false);
+ } catch (err) {
+ setError("Failed to submit review.");
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const openModal = () => {
+ setIsModalOpen(true);
+ setError("");
+ setSuccess("");
+ };
+
+ return (
+
+
+
+ Reviews
+
+
+
+
+ Add Your Review
+
+
+
+ {/* Review Modal */}
+ {isModalOpen && (
+
+
+
setIsModalOpen(false)}
+ className="absolute top-4 right-4 text-gray-400 hover:text-gray-600"
+ >
+
+
+
+
+
+
+
+ Share Your Review
+
+
+
+
+
+ )}
+
+
+ {reviews.length === 0 && (
+
+ No reviews yet. Be the first!
+
+ )}
+ {reviews.map((review) => (
+
+
+
+ {review.name}
+
+
+ {review.createdAt?.toDate?.().toLocaleString?.() || ""}
+
+
+
{review.message}
+
+ ))}
+
+
+
+ );
+};
+
+export default ReviewsSection;