From 5b8b6a209dbab0011692ec2d1dfd688078838cbf Mon Sep 17 00:00:00 2001
From: angelp03 <angelpimentel2025@u.northwestern.edu>
Date: Fri, 8 Nov 2024 10:24:55 -0600
Subject: [PATCH 1/7] refactor existing frontend code

---
 src/App.jsx                  | 200 ++---------------------------------
 src/components/Banner.css    |  13 ++-
 src/components/Banner.jsx    |   7 +-
 src/pages/LandingPage.jsx    |  25 +++++
 src/pages/ReviewPostPage.jsx | 157 +++++++++++++++++++++++++++
 src/utilities/firebase.js    |  46 ++++----
 6 files changed, 234 insertions(+), 214 deletions(-)
 create mode 100644 src/pages/LandingPage.jsx
 create mode 100644 src/pages/ReviewPostPage.jsx

diff --git a/src/App.jsx b/src/App.jsx
index f300761..1dc6065 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,194 +1,16 @@
-import React, { useState, useEffect } from 'react';
-import './App.css';
-import { useAuthState, signInWithGoogle, firebaseSignOut } from './utilities/firebase'; 
-import { findCafes } from './utilities/findCafes';
-import MapComponent from "./MapComponent";
-
-function App() {
-  const [reviews, setReviews] = useState([]);
-  const [availability, setAvailability] = useState({});
-  const [newReview, setNewReview] = useState('');
-  const [selectedReview, setSelectedReview] = useState(null);
-  const [replyText, setReplyText] = useState('');
-  const [cafeStatus, setCafeStatus] = useState({ seating: '', outlets: '' });
-  const [address, setAddress] = useState('');
-  const [dist, setDist] = useState('');
-  const [cafes, setCafes] = useState([]); 
-
-  const [user] = useAuthState();
-
-  const handleSignIn = async () => {
-    try {
-      await signInWithGoogle();
-    } catch (error) {
-      console.error('Error signing in:', error);
-    }
-  };
-
-  const handleLogout = () => firebaseSignOut();
-
-  useEffect(() => {}, []);
-
-  const findCafesWrapper = () => {
-    findCafes(dist, address, setCafes);
-  };
-
-  const handleReviewSubmit = () => {
-    if (newReview.trim()) {
-      const review = { id: Date.now(), text: newReview, replies: [] };
-      setReviews((prevReviews) => [...prevReviews, review]);
-      setNewReview('');
-    }
-  };
-
-  const handleReplySubmit = (reviewId) => {
-    if (replyText.trim()) {
-      setReviews((prevReviews) =>
-        prevReviews.map((review) =>
-          review.id === reviewId
-            ? { ...review, replies: [...review.replies, replyText] }
-            : review
-        )
-      );
-      setReplyText('');
-      setSelectedReview(null);
-    }
-  };
-
-  const handleAvailabilityUpdate = (cafeId) => {
-    const timestamp = new Date().toLocaleString();
-    const newUpdate = { timestamp, seating: cafeStatus.seating, outlets: cafeStatus.outlets };
-
-    setAvailability((prevAvailability) => ({
-      ...prevAvailability,
-      [cafeId]: {
-        history: [...(prevAvailability[cafeId]?.history || []), newUpdate],
-      },
-    }));
-    setCafeStatus({ seating: '', outlets: '' });
-  };
-
-  const cafesMap = [
-    { name: "Cafe Blue", lat: 42.046, lng: -87.688 },
-    { name: "Green Bean Cafe", lat: 42.048, lng: -87.684 },
-    { name: "Java Lounge", lat: 42.044, lng: -87.690 },
-  ];
+import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
+import LandingPage from './pages/LandingPage';
+import ReviewPostPage from "./pages/ReviewPostPage";
 
+const App = () => {
   return (
-    <div className="App">
-      <header className="App-header">
-        <h1>CafeWay</h1>
-        {user ? (
-          <>
-            <button className="my-post-button" onClick={handleLogout}>Sign Out</button>
-            <p>Welcome, {user.email}</p>
-          </>
-        ) : (
-          <button className="my-post-button" onClick={handleSignIn}>Sign In</button>
-        )}
-      </header>
-
-      <div className="listings-container">
-        <div className="listings-column">
-          <h2>Share a Review</h2>
-          <input
-            type="text"
-            placeholder="Share a quick review..."
-            value={newReview}
-            onChange={(e) => setNewReview(e.target.value)}
-          />
-          <button onClick={handleReviewSubmit}>Submit</button>
-
-          <ul className="review-list">
-            {reviews.map((review) => (
-              <li key={review.id} className="review-item">
-                <p onClick={() => setSelectedReview(review)}>{review.text}</p>
-                <ul className="reply-list">
-                  {review.replies.map((reply, index) => (
-                    <li key={index} className="reply-item">
-                      <span className="reply-label">Reply:</span> {reply}
-                    </li>
-                  ))}
-                </ul>
-                {selectedReview && selectedReview.id === review.id && (
-                  <div className="reply-input">
-                    <input
-                      type="text"
-                      placeholder="Write a reply..."
-                      value={replyText}
-                      onChange={(e) => setReplyText(e.target.value)}
-                    />
-                    <button onClick={() => handleReplySubmit(review.id)}>Send</button>
-                  </div>
-                )}
-              </li>
-            ))}
-          </ul>
-
-          <h2>Update Cafe Availability</h2>
-          <input
-            type="text"
-            placeholder="Seating status (e.g., Few seats left)"
-            value={cafeStatus.seating}
-            onChange={(e) => setCafeStatus({ ...cafeStatus, seating: e.target.value })}
-          />
-          <input
-            type="text"
-            placeholder="Outlet status (e.g., All taken)"
-            value={cafeStatus.outlets}
-            onChange={(e) => setCafeStatus({ ...cafeStatus, outlets: e.target.value })}
-          />
-          <button onClick={() => handleAvailabilityUpdate('cafe-123')}>Update Availability</button>
-
-          <h2>Availability History</h2>
-          {availability['cafe-123']?.history?.map((update, index) => (
-            <div key={index} className="availability-item">
-              <p>
-                <strong>{update.timestamp}:</strong> Seating: {update.seating}, Outlets: {update.outlets}
-              </p>
-            </div>
-          ))}
-        </div>
-
-        <div className="map-column">
-          <h2>Cafes Near Me</h2>
-          <input
-            type="text"
-            placeholder="Enter zip code"
-            value={address}
-            onChange={(e) => setAddress(e.target.value)}
-          />
-          <input
-            type="number"
-            placeholder="Enter radius (in miles)"
-            value={dist}
-            onChange={(e) => setDist(e.target.value)}
-          />
-          <button onClick={findCafesWrapper}>Search</button>
-          <h2>Cafes Near Me</h2>
-          <ul>
-            {cafes.map((cafe, index) => (
-              <li className="cafe-card" key={index}>{cafe}</li>
-            ))}
-          </ul>
-            
-
-          <ul className="cafe-list">
-            {cafes.map((cafesMap, index) => (
-              <li key={index} className="cafe-item">
-                {cafe.name} (Lat: {cafe.lat}, Lng: {cafe.lng})
-              </li>
-            ))}
-          </ul>
-
-          {/* Integrate MapComponent with hardcoded data */}
-          <div style={{ height: '400px', width: '100%', marginTop: '20px' }}>
-            <MapComponent cafes={cafesMap} />
-          </div>
-        </div>
-      </div>
-    </div>
-  );
+    <Router>
+      <Routes>
+        <Route path="/" element={ <LandingPage/> }/>
+        <Route path="/post" element={ <ReviewPostPage/> }/>
+      </Routes>
+    </Router>
+  )
 }
 
 export default App;
diff --git a/src/components/Banner.css b/src/components/Banner.css
index 89c1df9..f3016a4 100644
--- a/src/components/Banner.css
+++ b/src/components/Banner.css
@@ -7,7 +7,7 @@
     font-family: 'Hind Vadodara', sans-serif;
     font-weight: bolder;
     color: #8A3323;
-    border-bottom: 1px solid #8A3323;
+    border-bottom: 2px solid #8A3323;
 }
 
 .logo-search-div {
@@ -35,7 +35,9 @@
 
 .text-input {
     width: 22rem;
-    height: 1.5rem;
+    height: 2rem;
+    border-top: none;
+    border-left: none;
     border-bottom: 1px solid black;
     border-radius: 0;
     padding-left: 0.5rem;
@@ -46,7 +48,7 @@
 }
 
 .search-btn {
-    height: 2.6rem;
+    height: 2.3rem;
     width: 3rem;
     background-color: #8A3323;
     border: none;
@@ -54,10 +56,13 @@
     display: flex;
     justify-content: center;
     align-items: center;
-    margin-bottom: 0.65rem;
+    border-top: none;
+    border-left:none;
+    border-right:none;
     border-top-left-radius: 0;
     border-bottom-left-radius: 0;
     border-bottom: 1px solid black;
+    border-top-right-radius: 0.25;
 }
 
 .banner-buttons {
diff --git a/src/components/Banner.jsx b/src/components/Banner.jsx
index 2642603..1633ca0 100644
--- a/src/components/Banner.jsx
+++ b/src/components/Banner.jsx
@@ -1,8 +1,9 @@
 import './Banner.css';
 import Icon from '../Icon.svg';
 import Search from '../Search.svg';
+import { handleSignIn } from '../utilities/firebase';
 
-const Banner = () => {
+export const Banner = () => {
     // const navigate = useNavigate();
     // const navigateToReviews = () => {
     //     navigate('/reviews')
@@ -27,7 +28,7 @@ const Banner = () => {
                 <button className="banner-btn">
                     Review
                 </button>
-                <button className="banner-btn">
+                <button className="banner-btn" onClick={handleSignIn}>
                     Login
                 </button>
             </div>
@@ -35,4 +36,4 @@ const Banner = () => {
     )
 }
 
-export default Banner
\ No newline at end of file
+export default Banner;
\ No newline at end of file
diff --git a/src/pages/LandingPage.jsx b/src/pages/LandingPage.jsx
new file mode 100644
index 0000000..a198607
--- /dev/null
+++ b/src/pages/LandingPage.jsx
@@ -0,0 +1,25 @@
+import React from 'react';
+import '../App.css';
+import MapComponent from "../MapComponent";
+import Banner from '../components/Banner';
+
+const LandingPage = () => {
+
+    const cafesMap = [
+        { name: "Cafe Blue", lat: 42.046, lng: -87.688 },
+        { name: "Green Bean Cafe", lat: 42.048, lng: -87.684 },
+        { name: "Java Lounge", lat: 42.044, lng: -87.690 },
+    ];
+
+    return (
+        <div className="App">
+            <Banner />
+            {/* Integrate MapComponent with hardcoded data */}
+            <div style={{ height: '600px', width: '100%'}}>
+                <MapComponent cafes={cafesMap} />
+            </div>
+        </div>
+    );
+}
+
+export default LandingPage;
\ No newline at end of file
diff --git a/src/pages/ReviewPostPage.jsx b/src/pages/ReviewPostPage.jsx
new file mode 100644
index 0000000..861853d
--- /dev/null
+++ b/src/pages/ReviewPostPage.jsx
@@ -0,0 +1,157 @@
+import React, { useState, useEffect } from 'react';
+import '../App.css';
+import { useAuthState } from '../utilities/firebase';
+import { findCafes } from '../utilities/findCafes';
+
+const ReviewPostPage = () => {
+    const [reviews, setReviews] = useState([]);
+    const [availability, setAvailability] = useState({});
+    const [newReview, setNewReview] = useState('');
+    const [selectedReview, setSelectedReview] = useState(null);
+    const [replyText, setReplyText] = useState('');
+    const [cafeStatus, setCafeStatus] = useState({ seating: '', outlets: '' });
+    const [address, setAddress] = useState('');
+    const [dist, setDist] = useState('');
+    const [cafes, setCafes] = useState([]);
+    useEffect(() => { }, []);
+
+    const findCafesWrapper = () => {
+        findCafes(dist, address, setCafes);
+    };
+
+    const handleReviewSubmit = () => {
+        if (newReview.trim()) {
+            const review = { id: Date.now(), text: newReview, replies: [] };
+            setReviews((prevReviews) => [...prevReviews, review]);
+            setNewReview('');
+        }
+    };
+
+    const handleReplySubmit = (reviewId) => {
+        if (replyText.trim()) {
+            setReviews((prevReviews) =>
+                prevReviews.map((review) =>
+                    review.id === reviewId
+                        ? { ...review, replies: [...review.replies, replyText] }
+                        : review
+                )
+            );
+            setReplyText('');
+            setSelectedReview(null);
+        }
+    };
+
+    const handleAvailabilityUpdate = (cafeId) => {
+        const timestamp = new Date().toLocaleString();
+        const newUpdate = { timestamp, seating: cafeStatus.seating, outlets: cafeStatus.outlets };
+
+        setAvailability((prevAvailability) => ({
+            ...prevAvailability,
+            [cafeId]: {
+                history: [...(prevAvailability[cafeId]?.history || []), newUpdate],
+            },
+        }));
+        setCafeStatus({ seating: '', outlets: '' });
+    };
+    return (
+        <div>
+            <div className="listings-container">
+                <div className="listings-column">
+                    <h2>Share a Review</h2>
+                    <input
+                        type="text"
+                        placeholder="Share a quick review..."
+                        value={newReview}
+                        onChange={(e) => setNewReview(e.target.value)}
+                    />
+                    <button onClick={handleReviewSubmit}>Submit</button>
+
+                    <ul className="review-list">
+                        {reviews.map((review) => (
+                            <li key={review.id} className="review-item">
+                                <p onClick={() => setSelectedReview(review)}>{review.text}</p>
+                                <ul className="reply-list">
+                                    {review.replies.map((reply, index) => (
+                                        <li key={index} className="reply-item">
+                                            <span className="reply-label">Reply:</span> {reply}
+                                        </li>
+                                    ))}
+                                </ul>
+                                {selectedReview && selectedReview.id === review.id && (
+                                    <div className="reply-input">
+                                        <input
+                                            type="text"
+                                            placeholder="Write a reply..."
+                                            value={replyText}
+                                            onChange={(e) => setReplyText(e.target.value)}
+                                        />
+                                        <button onClick={() => handleReplySubmit(review.id)}>Send</button>
+                                    </div>
+                                )}
+                            </li>
+                        ))}
+                    </ul>
+
+                    <h2>Update Cafe Availability</h2>
+                    <input
+                        type="text"
+                        placeholder="Seating status (e.g., Few seats left)"
+                        value={cafeStatus.seating}
+                        onChange={(e) => setCafeStatus({ ...cafeStatus, seating: e.target.value })}
+                    />
+                    <input
+                        type="text"
+                        placeholder="Outlet status (e.g., All taken)"
+                        value={cafeStatus.outlets}
+                        onChange={(e) => setCafeStatus({ ...cafeStatus, outlets: e.target.value })}
+                    />
+                    <button onClick={() => handleAvailabilityUpdate('cafe-123')}>Update Availability</button>
+
+                    <h2>Availability History</h2>
+                    {availability['cafe-123']?.history?.map((update, index) => (
+                        <div key={index} className="availability-item">
+                            <p>
+                                <strong>{update.timestamp}:</strong> Seating: {update.seating}, Outlets: {update.outlets}
+                            </p>
+                        </div>
+                    ))}
+                </div>
+
+                <div className="map-column">
+                    <h2>Cafes Near Me</h2>
+                    <input
+                        type="text"
+                        placeholder="Enter zip code"
+                        value={address}
+                        onChange={(e) => setAddress(e.target.value)}
+                    />
+                    <input
+                        type="number"
+                        placeholder="Enter radius (in miles)"
+                        value={dist}
+                        onChange={(e) => setDist(e.target.value)}
+                    />
+                    <button onClick={findCafesWrapper}>Search</button>
+                    <h2>Cafes Near Me</h2>
+                    <ul>
+                        {cafes.map((cafe, index) => (
+                            <li className="cafe-card" key={index}>{cafe}</li>
+                        ))}
+                    </ul>
+
+
+                    <ul className="cafe-list">
+                        {cafes.map((cafesMap, index) => (
+                            <li key={index} className="cafe-item">
+                                {cafe.name} (Lat: {cafe.lat}, Lng: {cafe.lng})
+                            </li>
+                        ))}
+                    </ul>
+
+                </div>
+            </div>
+        </div>
+    )
+}
+
+export default ReviewPostPage;
\ No newline at end of file
diff --git a/src/utilities/firebase.js b/src/utilities/firebase.js
index 4390349..ea1d27d 100644
--- a/src/utilities/firebase.js
+++ b/src/utilities/firebase.js
@@ -27,16 +27,16 @@ const database = getDatabase(app);
 
 export const signInWithGoogle = () => {
     signInWithPopup(auth, provider)
-      .then(async (result) => {
-        console.log('User signed in:', result.user);
-        var zipcode = await findZipcode(result.user.email);
-        console.log("Zipcode: ", zipcode);
-      })
-      .catch((error) => {
-        console.error('Error signing in with Google:', error);
-      });
-  };
-  
+        .then(async (result) => {
+            console.log('User signed in:', result.user);
+            var zipcode = await findZipcode(result.user.email);
+            console.log("Zipcode: ", zipcode);
+        })
+        .catch((error) => {
+            console.error('Error signing in with Google:', error);
+        });
+};
+
 export const firebaseSignOut = () => signOut(auth);
 
 export const useAuthState = () => {
@@ -53,13 +53,13 @@ export const useAuthState = () => {
 export const useDbData = (path) => {
     const [data, setData] = useState();
     const [error, setError] = useState(null);
-  
+
     useEffect(() => {
         const dbRef = ref(database, path);
         const unsubscribe = onValue(
-        dbRef,
-        (snapshot) => setData(snapshot.val()),
-        (error) => setError(error)
+            dbRef,
+            (snapshot) => setData(snapshot.val()),
+            (error) => setError(error)
         );
         return () => unsubscribe();
     }, [path]);
@@ -72,9 +72,9 @@ export const useDbUpdate = (path) => {
 
     const updateData = useCallback(
         (value) => {
-        update(ref(database, path), value)
-            .then(() => setResult({ message: "Update successful", timestamp: Date.now() }))
-            .catch((error) => setResult({ error, message: error.message }));
+            update(ref(database, path), value)
+                .then(() => setResult({ message: "Update successful", timestamp: Date.now() }))
+                .catch((error) => setResult({ error, message: error.message }));
         },
         [path]
     );
@@ -82,4 +82,14 @@ export const useDbUpdate = (path) => {
     return [updateData, result];
 };
 
-export {database};
\ No newline at end of file
+export const handleSignIn = async () => {
+    try {
+        await signInWithGoogle();
+    } catch (error) {
+        console.error('Error signing in:', error);
+    }
+};
+
+export const handleLogout = () => firebaseSignOut();
+
+export { database };
\ No newline at end of file

From 06eb086a235c427e7e0eb1010009eed17df65f91 Mon Sep 17 00:00:00 2001
From: angelp03 <angelpimentel2025@u.northwestern.edu>
Date: Fri, 8 Nov 2024 12:40:47 -0600
Subject: [PATCH 2/7] populate cafes with cafes near authenticated email

---
 src/App.jsx                 |  2 ++
 src/components/Banner.jsx   | 11 ++++----
 src/components/CafeList.css |  5 +++-
 src/components/CafeList.jsx | 52 ++++---------------------------------
 src/pages/LandingPage.jsx   |  4 ++-
 src/pages/ReviewsPage.jsx   | 42 ++++++++++++++++++++++++++----
 src/utilities/findCafes.jsx |  6 ++++-
 7 files changed, 62 insertions(+), 60 deletions(-)

diff --git a/src/App.jsx b/src/App.jsx
index 1dc6065..05dee09 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,6 +1,7 @@
 import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
 import LandingPage from './pages/LandingPage';
 import ReviewPostPage from "./pages/ReviewPostPage";
+import ReviewsPage from "./pages/ReviewsPage";
 
 const App = () => {
   return (
@@ -8,6 +9,7 @@ const App = () => {
       <Routes>
         <Route path="/" element={ <LandingPage/> }/>
         <Route path="/post" element={ <ReviewPostPage/> }/>
+        <Route path="/cafes" element={ <ReviewsPage/> }/>
       </Routes>
     </Router>
   )
diff --git a/src/components/Banner.jsx b/src/components/Banner.jsx
index 1633ca0..308290c 100644
--- a/src/components/Banner.jsx
+++ b/src/components/Banner.jsx
@@ -2,12 +2,13 @@ import './Banner.css';
 import Icon from '../Icon.svg';
 import Search from '../Search.svg';
 import { handleSignIn } from '../utilities/firebase';
+import { useNavigate } from 'react-router-dom';
 
 export const Banner = () => {
-    // const navigate = useNavigate();
-    // const navigateToReviews = () => {
-    //     navigate('/reviews')
-    // }
+    const navigate = useNavigate();
+    const navigateToReviews = () => {
+        navigate('/cafes')
+    }
     return (
         <div className='banner-div'>
             <div className="logo-search-div">
@@ -19,7 +20,7 @@ export const Banner = () => {
                 </div>
                 <form>
                     <input className="text-input" type="text" placeholder="Search for cafes near you" />
-                    <button className="search-btn"> 
+                    <button className="search-btn" onClick={navigateToReviews}> 
                         <img src={Search}/>
                     </button>
                 </form>
diff --git a/src/components/CafeList.css b/src/components/CafeList.css
index 18ba163..661a09d 100644
--- a/src/components/CafeList.css
+++ b/src/components/CafeList.css
@@ -1,6 +1,8 @@
 .cafe-list-container {
     display: flex;
     gap: 2rem;
+    width: 100vw;
+    height: 100vh;
 }
 
 .filter {
@@ -9,6 +11,7 @@
     background-color: #f5f5f5;
     border-radius: 5px;
     box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
+    height: 100%;
 }
 
 .cafe-list {
@@ -17,7 +20,7 @@
 }
 
 .cafe-card {
-    width: 100%;
+    width: 95%;
     margin-bottom: 1rem;
     padding: 1rem;
     border: 1px solid #ccc;
diff --git a/src/components/CafeList.jsx b/src/components/CafeList.jsx
index e29411c..8a7d1bc 100644
--- a/src/components/CafeList.jsx
+++ b/src/components/CafeList.jsx
@@ -1,43 +1,10 @@
 import './CafeList.css';
 
-const reviews = [
-    {
-        id: 1,
-        author: 'John Doe',
-        rating: 4,
-        content: 'Currently busy.',
-        location: 'Starbucks',
-    },
-    {
-        id: 2,
-        author: 'Jane Smith',
-        rating: 5,
-        content: 'Somewhat busy, some seats remain.',
-        location: 'Colectivo',
-    },
-    {
-        id: 3,
-        author: 'Alice Johnson',
-        rating: 3,
-        content: 'Very empty, plenty of seats.',
-        location: "Phil's",
-    },
-    {
-        id: 4,
-        author: 'Bob Brown',
-        rating: 5,
-        content: 'Very quiet and great coffee!',
-        location: 'Coffee Lab',
-    },
-];
-
-const CafeList = () => {
+const CafeList = ({ cafes }) => {
     return (
         <div className="cafe-list-container">
-            {/* Filter section */}
             <div className="filter">
                 <h4>Filter Options</h4>
-                {/* Example filter options */}
                 <label>
                     Rating:
                     <select>
@@ -53,21 +20,12 @@ const CafeList = () => {
                     Location:
                     <input type="text" placeholder="Search by location" />
                 </label>
-                {/* Add more filters here as needed */}
             </div>
-
-            {/* Review cards */}
             <div className="cafe-list">
-                {reviews.map((review) => (
-                    <div key={review.id} className="cafe-card">
-                        <h3>{review.author}</h3>
-                        <p>{review.location}</p>
-                        <div>
-                            {Array.from({ length: review.rating }).map((_, index) => (
-                                <span key={index}>&#9733;</span>
-                            ))}
-                        </div>
-                        <p>{review.content}</p>
+                {cafes.map((cafe, index) => (
+                    <div key={index} className="cafe-card">
+                        <h3>{cafe.name}</h3>
+                        <p>{cafe.vicinity}</p>
                     </div>
                 ))}
             </div>
diff --git a/src/pages/LandingPage.jsx b/src/pages/LandingPage.jsx
index a198607..b38d666 100644
--- a/src/pages/LandingPage.jsx
+++ b/src/pages/LandingPage.jsx
@@ -2,9 +2,11 @@ import React from 'react';
 import '../App.css';
 import MapComponent from "../MapComponent";
 import Banner from '../components/Banner';
+import { useAuthState } from '../utilities/firebase';
 
 const LandingPage = () => {
-
+    const [user] = useAuthState();
+    console.log(user)
     const cafesMap = [
         { name: "Cafe Blue", lat: 42.046, lng: -87.688 },
         { name: "Green Bean Cafe", lat: 42.048, lng: -87.684 },
diff --git a/src/pages/ReviewsPage.jsx b/src/pages/ReviewsPage.jsx
index c79993c..6fbc6fa 100644
--- a/src/pages/ReviewsPage.jsx
+++ b/src/pages/ReviewsPage.jsx
@@ -1,13 +1,45 @@
+import { useAuthState } from "../utilities/firebase";
+import { useState, useEffect } from "react";
+import { findZipcode } from "../utilities/findZipcode";
+import { findCafes } from "../utilities/findCafes";
 import Banner from "../components/Banner";
 import CafeList from "../components/CafeList";
 
 const ReviewsPage = () => {
+    const [user] = useAuthState();
+    const [zipcode, setZipcode] = useState(null);
+    const [cafes, setCafes] = useState([]);
+
+    useEffect(() => {
+        const fetchData = async () => {
+            if (user && user.email) {
+                try {
+                    const userZipcode = await findZipcode(user.email);
+                    setZipcode(userZipcode);
+
+                    if (userZipcode) {
+                        await findCafes(2, userZipcode, setCafes);
+                    }
+                } catch (error) {
+                    console.error("Error fetching zipcode or cafes:", error);
+                    setZipcode(null);
+                    setCafes([]);
+                }
+            }
+        };
+        fetchData();
+    }, [user]);
+
+    useEffect(() => {
+        console.log(cafes);
+    }, [cafes]);
+
     return (
         <div>
-            <Banner/>
-            <CafeList/>
+            <Banner />
+            <CafeList cafes={cafes} />
         </div>
-    )
-}
+    );
+};
 
-export default ReviewsPage;
\ No newline at end of file
+export default ReviewsPage;
diff --git a/src/utilities/findCafes.jsx b/src/utilities/findCafes.jsx
index 98dea2a..7160390 100644
--- a/src/utilities/findCafes.jsx
+++ b/src/utilities/findCafes.jsx
@@ -15,7 +15,11 @@ export const findCafes = (dist, address, setCafes) => {
           },
           (results, status) => {
             if (status === window.google.maps.places.PlacesServiceStatus.OK) {
-              setCafes(results.map((place) => place.name));
+              setCafes(results.map((place) => ({
+                name: place.name,
+                placeId: place.place_id,
+                vicinity: place.vicinity
+              })));
             } else {
               alert("No cafes found within the specified radius.");
               setCafes([]); 

From 244bed195cd2e3351eeb3a718feece3b0d8c44bd Mon Sep 17 00:00:00 2001
From: angelp03 <angelpimentel2025@u.northwestern.edu>
Date: Fri, 8 Nov 2024 13:08:22 -0600
Subject: [PATCH 3/7] navigation to cafe pages based on place id

---
 src/App.jsx                 |  2 +
 src/components/Banner.css   | 39 +++++++++++++++---
 src/components/Banner.jsx   | 82 +++++++++++++++++++++++++++++++------
 src/components/CafeList.jsx | 14 ++++++-
 src/pages/CafePage.jsx      | 62 ++++++++++++++++++++++++++++
 src/pages/LandingPage.jsx   | 33 ++++++++++++++-
 src/pages/ReviewsPage.jsx   |  2 +-
 7 files changed, 211 insertions(+), 23 deletions(-)
 create mode 100644 src/pages/CafePage.jsx

diff --git a/src/App.jsx b/src/App.jsx
index 05dee09..49e5fbc 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -2,6 +2,7 @@ import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
 import LandingPage from './pages/LandingPage';
 import ReviewPostPage from "./pages/ReviewPostPage";
 import ReviewsPage from "./pages/ReviewsPage";
+import CafePage from "./pages/CafePage";
 
 const App = () => {
   return (
@@ -10,6 +11,7 @@ const App = () => {
         <Route path="/" element={ <LandingPage/> }/>
         <Route path="/post" element={ <ReviewPostPage/> }/>
         <Route path="/cafes" element={ <ReviewsPage/> }/>
+        <Route path="/cafe/:place_id" element={<CafePage/>}/>
       </Routes>
     </Router>
   )
diff --git a/src/components/Banner.css b/src/components/Banner.css
index f3016a4..670039d 100644
--- a/src/components/Banner.css
+++ b/src/components/Banner.css
@@ -16,7 +16,7 @@
 }
 
 .logo-div {
-    height:100%;
+    height: 100%;
     display: flex;
     align-items: center;
     margin-right: 3rem;
@@ -31,6 +31,7 @@
 .logo-search-div form {
     display: flex;
     align-items: center;
+    position: relative;  /* Allow positioning of the autocomplete dropdown */
 }
 
 .text-input {
@@ -57,12 +58,12 @@
     justify-content: center;
     align-items: center;
     border-top: none;
-    border-left:none;
-    border-right:none;
+    border-left: none;
+    border-right: none;
     border-top-left-radius: 0;
     border-bottom-left-radius: 0;
     border-bottom: 1px solid black;
-    border-top-right-radius: 0.25;
+    border-top-right-radius: 0.25rem;
 }
 
 .banner-buttons {
@@ -73,7 +74,7 @@
 
 .banner-btn {
     text-align: center;
-    height:2.45rem;
+    height: 2.45rem;
     width: 8rem;
     background-color: #8A3323;
     color: white;
@@ -88,4 +89,30 @@
 
 .banner-btn:hover {
     background-color: #a85c43;
-}
\ No newline at end of file
+}
+
+/* Autocomplete Dropdown */
+.autocomplete-dropdown {
+    position: absolute;
+    top: 100%;  /* Align directly below the input field */
+    left: 0;
+    right: 0;
+    background-color: white;
+    border: 1px solid #ddd;
+    border-radius: 0.25rem;
+    max-height: 200px;
+    overflow-y: auto;
+    z-index: 10;
+    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+    width: 22rem;  /* Match the width of the input field */
+}
+
+.autocomplete-item {
+    padding: 10px;
+    cursor: pointer;
+    font-family: 'Hind Vadodara', sans-serif;
+}
+
+.autocomplete-item:hover {
+    background-color: #f0f0f0;
+}
diff --git a/src/components/Banner.jsx b/src/components/Banner.jsx
index 308290c..99609df 100644
--- a/src/components/Banner.jsx
+++ b/src/components/Banner.jsx
@@ -3,26 +3,84 @@ import Icon from '../Icon.svg';
 import Search from '../Search.svg';
 import { handleSignIn } from '../utilities/firebase';
 import { useNavigate } from 'react-router-dom';
+import { useState } from 'react';
 
-export const Banner = () => {
+export const Banner = ({ cafes }) => {
     const navigate = useNavigate();
-    const navigateToReviews = () => {
-        navigate('/cafes')
-    }
+    const [searchText, setSearchText] = useState('');
+    const [filteredCafes, setFilteredCafes] = useState([]);
+    const handleInputChange = (e) => {
+        const text = e.target.value;
+        setSearchText(text);
+
+        if (text) {
+            const matches = cafes.filter(cafe => 
+                cafe.name.toLowerCase().includes(text.toLowerCase())
+            );
+            setFilteredCafes(matches);
+        } else {
+            setFilteredCafes([]);
+        }
+    };
+
+    const handleSelectCafe = (cafe) => {
+        setSearchText(cafe.name);
+        setFilteredCafes([]);
+        navigate(`/cafe/${cafe.placeId}`);
+    };
+
+
+    const handleSearch = (e) => {
+        e.preventDefault();
+
+        if (searchText.trim() === '') {
+            navigate('/cafes');
+        } else {
+            const selectedCafe = cafes.find(cafe =>
+                cafe.name.toLowerCase() === searchText.toLowerCase()
+            );
+
+            if (selectedCafe) {
+                navigate(`/cafe/${selectedCafe.placeId}`);
+            } else {
+                alert('Cafe not found.');
+            }
+        }
+    };
+
     return (
         <div className='banner-div'>
             <div className="logo-search-div">
                 <div className='logo-div'>
-                    <img src={Icon}/>
+                    <img src={Icon} alt="CafeWay Logo" />
                     <h1>
                         CafeWay
                     </h1>
                 </div>
-                <form>
-                    <input className="text-input" type="text" placeholder="Search for cafes near you" />
-                    <button className="search-btn" onClick={navigateToReviews}> 
-                        <img src={Search}/>
+                <form onSubmit={handleSearch}>
+                    <input
+                        className="text-input"
+                        type="text"
+                        placeholder="Search for cafes near you"
+                        value={searchText}
+                        onChange={handleInputChange}
+                    />
+                    <button className="search-btn" type="submit"> 
+                        <img src={Search} alt="Search Icon" />
                     </button>
+                    {filteredCafes.length > 0 && (
+                        <ul className="autocomplete-dropdown">
+                            {filteredCafes.map((cafe) => (
+                                <li
+                                    key={cafe.placeId}
+                                    onClick={() => handleSelectCafe(cafe)}
+                                    className="autocomplete-item"
+                                >
+                                    {cafe.name} - {cafe.vicinity}
+                                </li>
+                            ))}
+                        </ul>
+                    )}
                 </form>
             </div>
             <div className="banner-buttons">
@@ -34,7 +92,7 @@ export const Banner = () => {
                 </button>
             </div>
         </div>
-    )
-}
+    );
+};
 
-export default Banner;
\ No newline at end of file
+export default Banner;
diff --git a/src/components/CafeList.jsx b/src/components/CafeList.jsx
index 8a7d1bc..c0c16e0 100644
--- a/src/components/CafeList.jsx
+++ b/src/components/CafeList.jsx
@@ -1,6 +1,12 @@
 import './CafeList.css';
+import { useNavigate } from 'react-router-dom';
 
 const CafeList = ({ cafes }) => {
+    const navigate = useNavigate();
+    const handleClick = (placeId) => {
+        navigate(`/cafe/${placeId}`);
+    };
+
     return (
         <div className="cafe-list-container">
             <div className="filter">
@@ -22,8 +28,12 @@ const CafeList = ({ cafes }) => {
                 </label>
             </div>
             <div className="cafe-list">
-                {cafes.map((cafe, index) => (
-                    <div key={index} className="cafe-card">
+                {cafes.map((cafe) => (
+                    <div 
+                        key={cafe.placeId} 
+                        className="cafe-card" 
+                        onClick={() => handleClick(cafe.placeId)}
+                    >
                         <h3>{cafe.name}</h3>
                         <p>{cafe.vicinity}</p>
                     </div>
diff --git a/src/pages/CafePage.jsx b/src/pages/CafePage.jsx
new file mode 100644
index 0000000..c29b1c2
--- /dev/null
+++ b/src/pages/CafePage.jsx
@@ -0,0 +1,62 @@
+import { useParams } from 'react-router-dom';
+import { useState, useEffect } from 'react';
+import { findZipcode } from '../utilities/findZipcode';
+import { findCafes } from '../utilities/findCafes';
+import { useAuthState } from '../utilities/firebase';
+
+const CafePage = () => {
+    const { place_id } = useParams();
+    const [user] = useAuthState();
+    const [zipcode, setZipcode] = useState(null);
+    const [cafes, setCafes] = useState([]);
+    const [cafe, setCafe] = useState(null);
+
+    useEffect(() => {
+        if (user && user.email) {
+            const fetchZipCode = async () => {
+                const userZipcode = await findZipcode(user.email);
+                setZipcode(userZipcode);
+            };
+            fetchZipCode();
+        }
+    }, [user]);
+
+    useEffect(() => {
+        if (zipcode) {
+            const fetchCafes = async () => {
+                try {
+                    await findCafes(5, zipcode, setCafes);
+                } catch (error) {
+                    console.error('Error fetching cafes:', error);
+                    setCafes([]);
+                }
+            };
+            fetchCafes();
+        }
+    }, [zipcode]);
+
+    useEffect(() => {
+        if (cafes.length > 0) {
+            const foundCafe = cafes.find((cafe) => cafe.placeId === place_id);
+            setCafe(foundCafe);
+        }
+    }, [cafes, place_id]);
+
+    if (!cafe) {
+        return (
+            <div>
+                <h1>Cafe not found</h1>
+                <p>Sorry, we couldn't find a cafe with the specified ID.</p>
+            </div>
+        );
+    }
+
+    return (
+        <div>
+            <h1>{cafe.name}</h1>
+            <p><strong>Location:</strong> {cafe.vicinity}</p>
+        </div>
+    );
+}
+
+export default CafePage;
diff --git a/src/pages/LandingPage.jsx b/src/pages/LandingPage.jsx
index b38d666..0ed5ef1 100644
--- a/src/pages/LandingPage.jsx
+++ b/src/pages/LandingPage.jsx
@@ -3,10 +3,39 @@ import '../App.css';
 import MapComponent from "../MapComponent";
 import Banner from '../components/Banner';
 import { useAuthState } from '../utilities/firebase';
+import { useState, useEffect } from "react";
+import { findZipcode } from "../utilities/findZipcode";
+import { findCafes } from "../utilities/findCafes";
 
 const LandingPage = () => {
     const [user] = useAuthState();
-    console.log(user)
+    const [zipcode, setZipcode] = useState(null);
+    const [cafes, setCafes] = useState([]);
+
+    useEffect(() => {
+        const fetchData = async () => {
+            if (user && user.email) {
+                try {
+                    const userZipcode = await findZipcode(user.email);
+                    setZipcode(userZipcode);
+
+                    if (userZipcode) {
+                        await findCafes(2, userZipcode, setCafes);
+                    }
+                } catch (error) {
+                    console.error("Error fetching zipcode or cafes:", error);
+                    setZipcode(null);
+                    setCafes([]);
+                }
+            }
+        };
+        fetchData();
+    }, [user]);
+
+    useEffect(() => {
+        console.log(cafes);
+    }, [cafes]);
+
     const cafesMap = [
         { name: "Cafe Blue", lat: 42.046, lng: -87.688 },
         { name: "Green Bean Cafe", lat: 42.048, lng: -87.684 },
@@ -15,7 +44,7 @@ const LandingPage = () => {
 
     return (
         <div className="App">
-            <Banner />
+            <Banner cafes={cafes} />
             {/* Integrate MapComponent with hardcoded data */}
             <div style={{ height: '600px', width: '100%'}}>
                 <MapComponent cafes={cafesMap} />
diff --git a/src/pages/ReviewsPage.jsx b/src/pages/ReviewsPage.jsx
index 6fbc6fa..f7c8750 100644
--- a/src/pages/ReviewsPage.jsx
+++ b/src/pages/ReviewsPage.jsx
@@ -36,7 +36,7 @@ const ReviewsPage = () => {
 
     return (
         <div>
-            <Banner />
+            <Banner cafes={cafes}/>
             <CafeList cafes={cafes} />
         </div>
     );

From fac5ddcd02a64fdfc09e2913fde9524bd6a21db8 Mon Sep 17 00:00:00 2001
From: angelp03 <angelpimentel2025@u.northwestern.edu>
Date: Fri, 8 Nov 2024 13:30:16 -0600
Subject: [PATCH 4/7] populate cafe page with posts and responses

---
 database.rules.json                   |  4 +--
 src/dummy.json                        | 31 +++++++++++++++++
 src/pages/CafePage.jsx                | 50 +++++++++++++++++++++++++++
 src/utilities/{posts.js => posts.jsx} |  3 +-
 4 files changed, 84 insertions(+), 4 deletions(-)
 create mode 100644 src/dummy.json
 rename src/utilities/{posts.js => posts.jsx} (94%)

diff --git a/database.rules.json b/database.rules.json
index f54493d..f122d7b 100644
--- a/database.rules.json
+++ b/database.rules.json
@@ -1,7 +1,7 @@
 {
   /* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */
   "rules": {
-    ".read": false,
-    ".write": false
+    ".read": true,
+    ".write": true
   }
 }
\ No newline at end of file
diff --git a/src/dummy.json b/src/dummy.json
new file mode 100644
index 0000000..bd2b4d8
--- /dev/null
+++ b/src/dummy.json
@@ -0,0 +1,31 @@
+{
+    "test_id": {
+        "cafeId": "ChIJ60vPsg_QD4gRE61MVG65nSs",
+        "content": "Great place for coffee and work!",
+        "category": "Review",
+        "date": "2024-11-07T14:30:00Z",
+        "replies": {
+            "replyId_1": "I agree, the coffee is fantastic!",
+            "replyId_2": "The WiFi is also great for working!"
+        },
+        "uid": "user_1"
+    },
+    "test_id_2": {
+        "cafeId": "ChIJ60vPsg_QD4gRE61MVG65nSs",
+        "content": "Could use more seating during peak hours.",
+        "category": "Suggestion",
+        "date": "2024-11-08T09:00:00Z",
+        "replies": {},
+        "uid": "user_2"
+    },
+    "test_id_3": {
+        "cafeId": "ChIJ60vPsg_QD4gRE61MVG65nSs",
+        "content": "Is the cafe open late on weekends?",
+        "category": "Question",
+        "date": "2024-11-09T11:45:00Z",
+        "replies": {
+            "replyId_1": "Yes, they stay open until 10 PM on Saturdays and Sundays!"
+        },
+        "uid": "user_3"
+    }
+}
\ No newline at end of file
diff --git a/src/pages/CafePage.jsx b/src/pages/CafePage.jsx
index c29b1c2..e5f722e 100644
--- a/src/pages/CafePage.jsx
+++ b/src/pages/CafePage.jsx
@@ -3,6 +3,7 @@ import { useState, useEffect } from 'react';
 import { findZipcode } from '../utilities/findZipcode';
 import { findCafes } from '../utilities/findCafes';
 import { useAuthState } from '../utilities/firebase';
+import { findCafePosts } from '../utilities/posts'; // Import the hook
 
 const CafePage = () => {
     const { place_id } = useParams();
@@ -42,6 +43,10 @@ const CafePage = () => {
         }
     }, [cafes, place_id]);
 
+    // Use the findCafePosts hook correctly here
+    const [posts, postError] = findCafePosts(cafe?.placeId); // Using the hook directly
+    console.log(posts);  // Check the format of posts
+
     if (!cafe) {
         return (
             <div>
@@ -51,10 +56,55 @@ const CafePage = () => {
         );
     }
 
+    // Assuming posts are in the form of an object with keys like test_id
+    const postItems = posts ? Object.values(posts) : []; // Convert the object into an array if needed
+
     return (
         <div>
             <h1>{cafe.name}</h1>
             <p><strong>Location:</strong> {cafe.vicinity}</p>
+
+            {/* Render posts if they exist */}
+            {postItems && postItems.length > 0 ? (
+                <div>
+                    <h2>Posts</h2>
+                    <ul>
+                        {postItems.map((post, index) => (
+                            <li key={index}>
+                                <p><strong>Category:</strong> {post.category}</p>
+                                <p><strong>Content:</strong> {post.content}</p>
+                                <small>{new Date(post.date).toLocaleString()}</small>
+                                
+                                {/* Render replies if they exist */}
+                                {post.replies && Object.entries(post.replies).length > 0 ? (
+                                    <div style={{ marginLeft: '20px', marginTop: '10px' }}>
+                                        <h3>Replies:</h3>
+                                        <ul>
+                                            {Object.entries(post.replies).map(([replyId, message], replyIndex) => (
+                                                <li key={replyIndex}>
+                                                    <p>{message}</p>
+                                                </li>
+                                            ))}
+                                        </ul>
+                                    </div>
+                                ) : (
+                                    <p>No replies for this post.</p>
+                                )}
+                            </li>
+                        ))}
+                    </ul>
+                </div>
+            ) : (
+                <p>No posts available for this cafe.</p>
+            )}
+
+            {/* Handle errors in fetching posts */}
+            {postError && (
+                <div>
+                    <h3>Error loading posts</h3>
+                    <p>{postError.message}</p>
+                </div>
+            )}
         </div>
     );
 }
diff --git a/src/utilities/posts.js b/src/utilities/posts.jsx
similarity index 94%
rename from src/utilities/posts.js
rename to src/utilities/posts.jsx
index d1f47f1..050ff36 100644
--- a/src/utilities/posts.js
+++ b/src/utilities/posts.jsx
@@ -11,11 +11,11 @@ export const findCafePosts = (cafeId) => {
 
         const postsRef = ref(database, `/posts`);
         const postsQuery = query(postsRef, orderByChild('cafeId'), equalTo(cafeId));
-
         const unsubscribe = onValue(
             postsQuery,
             (snapshot) => {
                 if (snapshot.exists()) {
+                    console.log(snapshot.val());
                     setData(snapshot.val());
                 } else {
                     setData([]);
@@ -28,6 +28,5 @@ export const findCafePosts = (cafeId) => {
 
         return () => unsubscribe();
     }, [cafeId]);
-
     return [data, error];
 };
\ No newline at end of file

From 0db40fdbab72ab97907cd43b66e9278a9b3dbdc4 Mon Sep 17 00:00:00 2001
From: angelp03 <angelpimentel2025@u.northwestern.edu>
Date: Fri, 8 Nov 2024 13:36:10 -0600
Subject: [PATCH 5/7] improve frontend of cafe page

---
 src/pages/CafePage.css |  90 ++++++++++++++++++++++++++++++++++++
 src/pages/CafePage.jsx | 102 +++++++++++++++++++++--------------------
 2 files changed, 143 insertions(+), 49 deletions(-)
 create mode 100644 src/pages/CafePage.css

diff --git a/src/pages/CafePage.css b/src/pages/CafePage.css
new file mode 100644
index 0000000..5aa8304
--- /dev/null
+++ b/src/pages/CafePage.css
@@ -0,0 +1,90 @@
+.cafe-page-container {
+    padding: 2rem;
+    font-family: 'Hind Vadodara', sans-serif;
+}
+
+.cafe-header {
+    margin-bottom: 2rem;
+    border-bottom: 1px solid #ddd;
+    padding-bottom: 1rem;
+    text-align: center;
+}
+
+.cafe-header h1 {
+    font-size: 2.5rem;
+    color: #8A3323;
+    margin-bottom: 0.5rem;
+}
+
+.cafe-header p {
+    font-size: 1.2rem;
+}
+
+.posts-section {
+    margin-top: 2rem;
+}
+
+.posts-section h2 {
+    font-size: 1.8rem;
+    margin-bottom: 1rem;
+    color: #8A3323;
+}
+.posts-list {
+    list-style-type: none;
+    padding: 0;
+}
+
+.post-item {
+    padding: 1rem;
+    margin-bottom: 1rem;
+    border: 1px solid #ddd;
+    border-radius: 8px;
+    background-color: #fafafa;
+}
+
+.post-header {
+    margin-bottom: 1rem;
+    font-size: 1rem;
+    color: #555;
+}
+
+.post-header strong {
+    color: #8A3323;
+}
+
+.post-content p {
+    font-size: 1.2rem;
+    color: #333;
+}
+
+.replies-section {
+    margin-top: 1rem;
+    padding-left: 20px;
+    background-color: #f9f9f9;
+    border-left: 3px solid #8A3323;
+}
+
+.replies-section h3 {
+    font-size: 1.5rem;
+    margin-bottom: 1rem;
+}
+
+.reply-item {
+    margin-bottom: 0.8rem;
+    font-size: 1.1rem;
+    color: #333;
+}
+
+.error-message {
+    text-align: center;
+    padding: 2rem;
+    background-color: #ffebee;
+    border: 1px solid #f44336;
+    border-radius: 8px;
+    color: #d32f2f;
+}
+
+.error-message h1,
+.error-message h3 {
+    color: #d32f2f;
+}
diff --git a/src/pages/CafePage.jsx b/src/pages/CafePage.jsx
index e5f722e..939e376 100644
--- a/src/pages/CafePage.jsx
+++ b/src/pages/CafePage.jsx
@@ -1,9 +1,11 @@
+import './CafePage.css';
 import { useParams } from 'react-router-dom';
 import { useState, useEffect } from 'react';
 import { findZipcode } from '../utilities/findZipcode';
 import { findCafes } from '../utilities/findCafes';
 import { useAuthState } from '../utilities/firebase';
-import { findCafePosts } from '../utilities/posts'; // Import the hook
+import { findCafePosts } from '../utilities/posts';
+import Banner from '../components/Banner';
 
 const CafePage = () => {
     const { place_id } = useParams();
@@ -43,68 +45,70 @@ const CafePage = () => {
         }
     }, [cafes, place_id]);
 
-    // Use the findCafePosts hook correctly here
-    const [posts, postError] = findCafePosts(cafe?.placeId); // Using the hook directly
-    console.log(posts);  // Check the format of posts
+    const [posts, postError] = findCafePosts(cafe?.placeId);
+    console.log(posts);
 
     if (!cafe) {
         return (
-            <div>
+            <div className="error-message">
                 <h1>Cafe not found</h1>
                 <p>Sorry, we couldn't find a cafe with the specified ID.</p>
             </div>
         );
     }
 
-    // Assuming posts are in the form of an object with keys like test_id
-    const postItems = posts ? Object.values(posts) : []; // Convert the object into an array if needed
+    const postItems = posts ? Object.values(posts) : []; 
 
     return (
         <div>
-            <h1>{cafe.name}</h1>
-            <p><strong>Location:</strong> {cafe.vicinity}</p>
-
-            {/* Render posts if they exist */}
-            {postItems && postItems.length > 0 ? (
-                <div>
-                    <h2>Posts</h2>
-                    <ul>
-                        {postItems.map((post, index) => (
-                            <li key={index}>
-                                <p><strong>Category:</strong> {post.category}</p>
-                                <p><strong>Content:</strong> {post.content}</p>
-                                <small>{new Date(post.date).toLocaleString()}</small>
-                                
-                                {/* Render replies if they exist */}
-                                {post.replies && Object.entries(post.replies).length > 0 ? (
-                                    <div style={{ marginLeft: '20px', marginTop: '10px' }}>
-                                        <h3>Replies:</h3>
-                                        <ul>
-                                            {Object.entries(post.replies).map(([replyId, message], replyIndex) => (
-                                                <li key={replyIndex}>
-                                                    <p>{message}</p>
-                                                </li>
-                                            ))}
-                                        </ul>
-                                    </div>
-                                ) : (
-                                    <p>No replies for this post.</p>
-                                )}
-                            </li>
-                        ))}
-                    </ul>
+            <Banner cafes={cafes}/>
+            <div className="cafe-page-container">
+                <div className="cafe-header">
+                    <h1>{cafe.name}</h1>
+                    <p><strong>Location:</strong> {cafe.vicinity}</p>
                 </div>
-            ) : (
-                <p>No posts available for this cafe.</p>
-            )}
 
-            {/* Handle errors in fetching posts */}
-            {postError && (
-                <div>
-                    <h3>Error loading posts</h3>
-                    <p>{postError.message}</p>
-                </div>
-            )}
+                {postItems && postItems.length > 0 ? (
+                    <div className="posts-section">
+                        <h2>Posts</h2>
+                        <ul className="posts-list">
+                            {postItems.map((post, index) => (
+                                <li key={index} className="post-item">
+                                    <div className="post-header">
+                                        <p><strong>Category:</strong> {post.category}</p>
+                                        <small>{new Date(post.date).toLocaleString()}</small>
+                                    </div>
+                                    <div className="post-content">
+                                        <p>{post.content}</p>
+                                    </div>
+                                    {post.replies && Object.entries(post.replies).length > 0 ? (
+                                        <div className="replies-section">
+                                            <h3>Replies:</h3>
+                                            <ul>
+                                                {Object.entries(post.replies).map(([replyId, message], replyIndex) => (
+                                                    <li key={replyIndex} className="reply-item">
+                                                        <p>{message}</p>
+                                                    </li>
+                                                ))}
+                                            </ul>
+                                        </div>
+                                    ) : (
+                                        <p>No replies for this post.</p>
+                                    )}
+                                </li>
+                            ))}
+                        </ul>
+                    </div>
+                ) : (
+                    <p>No posts available for this cafe.</p>
+                )}
+                {postError && (
+                    <div className="error-message">
+                        <h3>Error loading posts</h3>
+                        <p>{postError.message}</p>
+                    </div>
+                )}
+            </div>
         </div>
     );
 }

From 13f6919cb23b3ab8d03bf8fa508125575c4e4fef Mon Sep 17 00:00:00 2001
From: angelp03 <angelpimentel2025@u.northwestern.edu>
Date: Fri, 8 Nov 2024 13:41:07 -0600
Subject: [PATCH 6/7] update login/logout button based on auth state

---
 src/components/Banner.jsx | 23 +++++++++++++++--------
 src/pages/CafePage.jsx    | 10 ++++++----
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/src/components/Banner.jsx b/src/components/Banner.jsx
index 99609df..b5a7a2f 100644
--- a/src/components/Banner.jsx
+++ b/src/components/Banner.jsx
@@ -1,14 +1,17 @@
 import './Banner.css';
 import Icon from '../Icon.svg';
 import Search from '../Search.svg';
-import { handleSignIn } from '../utilities/firebase';
 import { useNavigate } from 'react-router-dom';
 import { useState } from 'react';
+import { handleSignIn, handleLogout, useAuthState } from '../utilities/firebase';
 
 export const Banner = ({ cafes }) => {
     const navigate = useNavigate();
     const [searchText, setSearchText] = useState('');
     const [filteredCafes, setFilteredCafes] = useState([]);
+    
+    const [user] = useAuthState(); 
+
     const handleInputChange = (e) => {
         const text = e.target.value;
         setSearchText(text);
@@ -29,7 +32,6 @@ export const Banner = ({ cafes }) => {
         navigate(`/cafe/${cafe.placeId}`);
     };
 
-
     const handleSearch = (e) => {
         e.preventDefault();
 
@@ -53,9 +55,7 @@ export const Banner = ({ cafes }) => {
             <div className="logo-search-div">
                 <div className='logo-div'>
                     <img src={Icon} alt="CafeWay Logo" />
-                    <h1>
-                        CafeWay
-                    </h1>
+                    <h1>CafeWay</h1>
                 </div>
                 <form onSubmit={handleSearch}>
                     <input
@@ -83,13 +83,20 @@ export const Banner = ({ cafes }) => {
                     )}
                 </form>
             </div>
+
             <div className="banner-buttons">
                 <button className="banner-btn">
                     Review
                 </button>
-                <button className="banner-btn" onClick={handleSignIn}>
-                    Login
-                </button>
+                {user ? (
+                    <button className="banner-btn" onClick={handleLogout}>
+                        Logout
+                    </button>
+                ) : (
+                    <button className="banner-btn" onClick={handleSignIn}>
+                        Login
+                    </button>
+                )}
             </div>
         </div>
     );
diff --git a/src/pages/CafePage.jsx b/src/pages/CafePage.jsx
index 939e376..08b1485 100644
--- a/src/pages/CafePage.jsx
+++ b/src/pages/CafePage.jsx
@@ -57,22 +57,24 @@ const CafePage = () => {
         );
     }
 
-    const postItems = posts ? Object.values(posts) : []; 
+    const postItems = posts ? Object.values(posts) : [];
+
+    const sortedPosts = postItems.sort((a, b) => new Date(b.date) - new Date(a.date));
 
     return (
         <div>
-            <Banner cafes={cafes}/>
+            <Banner cafes={cafes} />
             <div className="cafe-page-container">
                 <div className="cafe-header">
                     <h1>{cafe.name}</h1>
                     <p><strong>Location:</strong> {cafe.vicinity}</p>
                 </div>
 
-                {postItems && postItems.length > 0 ? (
+                {sortedPosts && sortedPosts.length > 0 ? (
                     <div className="posts-section">
                         <h2>Posts</h2>
                         <ul className="posts-list">
-                            {postItems.map((post, index) => (
+                            {sortedPosts.map((post, index) => (
                                 <li key={index} className="post-item">
                                     <div className="post-header">
                                         <p><strong>Category:</strong> {post.category}</p>

From cd0b6028a785ca830035694228220fb4587e8880 Mon Sep 17 00:00:00 2001
From: angelp03 <angelpimentel2025@u.northwestern.edu>
Date: Fri, 8 Nov 2024 14:00:50 -0600
Subject: [PATCH 7/7] allow replies and fix zipcode lookup

---
 src/pages/CafePage.jsx        | 52 +++++++++++++++++++++++++++++++----
 src/pages/ReviewsPage.jsx     |  1 +
 src/utilities/findZipcode.jsx |  3 +-
 src/utilities/posts.jsx       | 34 +++++++++++++++++++++--
 4 files changed, 81 insertions(+), 9 deletions(-)

diff --git a/src/pages/CafePage.jsx b/src/pages/CafePage.jsx
index 08b1485..8a2fd53 100644
--- a/src/pages/CafePage.jsx
+++ b/src/pages/CafePage.jsx
@@ -4,7 +4,7 @@ import { useState, useEffect } from 'react';
 import { findZipcode } from '../utilities/findZipcode';
 import { findCafes } from '../utilities/findCafes';
 import { useAuthState } from '../utilities/firebase';
-import { findCafePosts } from '../utilities/posts';
+import { findCafePosts, addReplyToPost } from '../utilities/posts';
 import Banner from '../components/Banner';
 
 const CafePage = () => {
@@ -13,6 +13,7 @@ const CafePage = () => {
     const [zipcode, setZipcode] = useState(null);
     const [cafes, setCafes] = useState([]);
     const [cafe, setCafe] = useState(null);
+    const [replyMessages, setReplyMessages] = useState({});
 
     useEffect(() => {
         if (user && user.email) {
@@ -46,7 +47,6 @@ const CafePage = () => {
     }, [cafes, place_id]);
 
     const [posts, postError] = findCafePosts(cafe?.placeId);
-    console.log(posts);
 
     if (!cafe) {
         return (
@@ -57,9 +57,30 @@ const CafePage = () => {
         );
     }
 
-    const postItems = posts ? Object.values(posts) : [];
+    const postItems = posts ? Object.entries(posts) : [];
+    const sortedPosts = postItems.sort((a, b) => new Date(b[1].date) - new Date(a[1].date));
 
-    const sortedPosts = postItems.sort((a, b) => new Date(b.date) - new Date(a.date));
+    const handleReplyChange = (e, postId) => {
+        setReplyMessages((prev) => ({
+            ...prev,
+            [postId]: e.target.value,
+        }));
+    };
+
+    const handleAddReply = async (postId) => {
+        const replyMessage = replyMessages[postId];
+        if (replyMessage && replyMessage.trim()) {
+            const error = await addReplyToPost(postId, user?.uid, replyMessage);
+            if (error) {
+                console.error('Error adding reply:', error);
+            } else {
+                setReplyMessages((prev) => ({
+                    ...prev,
+                    [postId]: '',
+                }));
+            }
+        }
+    };
 
     return (
         <div>
@@ -74,7 +95,7 @@ const CafePage = () => {
                     <div className="posts-section">
                         <h2>Posts</h2>
                         <ul className="posts-list">
-                            {sortedPosts.map((post, index) => (
+                            {sortedPosts.map(([postKey, post], index) => (
                                 <li key={index} className="post-item">
                                     <div className="post-header">
                                         <p><strong>Category:</strong> {post.category}</p>
@@ -83,6 +104,7 @@ const CafePage = () => {
                                     <div className="post-content">
                                         <p>{post.content}</p>
                                     </div>
+
                                     {post.replies && Object.entries(post.replies).length > 0 ? (
                                         <div className="replies-section">
                                             <h3>Replies:</h3>
@@ -97,6 +119,24 @@ const CafePage = () => {
                                     ) : (
                                         <p>No replies for this post.</p>
                                     )}
+
+                                    {user ? (
+                                        <div className="reply-section">
+                                            <textarea
+                                                value={replyMessages[postKey] || ''} 
+                                                onChange={(e) => handleReplyChange(e, postKey)}
+                                                placeholder="Write your reply..."
+                                            />
+                                            <button 
+                                                onClick={() => handleAddReply(postKey)}
+                                                className="reply-btn"
+                                            >
+                                                Reply
+                                            </button>
+                                        </div>
+                                    ) : (
+                                        <p>Please log in to reply.</p>
+                                    )}
                                 </li>
                             ))}
                         </ul>
@@ -113,6 +153,6 @@ const CafePage = () => {
             </div>
         </div>
     );
-}
+};
 
 export default CafePage;
diff --git a/src/pages/ReviewsPage.jsx b/src/pages/ReviewsPage.jsx
index f7c8750..f184840 100644
--- a/src/pages/ReviewsPage.jsx
+++ b/src/pages/ReviewsPage.jsx
@@ -9,6 +9,7 @@ const ReviewsPage = () => {
     const [user] = useAuthState();
     const [zipcode, setZipcode] = useState(null);
     const [cafes, setCafes] = useState([]);
+    console.log(user);
 
     useEffect(() => {
         const fetchData = async () => {
diff --git a/src/utilities/findZipcode.jsx b/src/utilities/findZipcode.jsx
index 740ced2..f16b393 100644
--- a/src/utilities/findZipcode.jsx
+++ b/src/utilities/findZipcode.jsx
@@ -41,7 +41,8 @@ const getZipCode = async (placeId) => {
 
 const getUniversity = (email) => {
   const domain = email.split('@')[1];
-  const university = domain.split('.')[0];
+  console.log(domain);
+  const university = domain.split('.')[1];
   return university;
 }
 
diff --git a/src/utilities/posts.jsx b/src/utilities/posts.jsx
index 050ff36..8bd36fe 100644
--- a/src/utilities/posts.jsx
+++ b/src/utilities/posts.jsx
@@ -1,5 +1,5 @@
 import { useState, useEffect } from 'react';
-import { onValue, query, orderByChild, equalTo, ref } from 'firebase/database';
+import { onValue, query, orderByChild, equalTo, ref, get, update } from 'firebase/database';
 import { database } from './firebase';
 
 export const findCafePosts = (cafeId) => {
@@ -29,4 +29,34 @@ export const findCafePosts = (cafeId) => {
         return () => unsubscribe();
     }, [cafeId]);
     return [data, error];
-};
\ No newline at end of file
+};
+
+export const addReplyToPost = async (postId, userId, replyMessage) => {
+    try {
+        const postRef = ref(database, `/posts/${postId}`);
+        const postSnapshot = await get(postRef);
+        if (!postSnapshot.exists()) {
+            return 'Post not found';
+        }
+
+        const postData = postSnapshot.val();
+        const replies = postData.replies || {};
+        const replyId = `replyId_${Object.keys(replies).length + 1}`;
+
+        const newReply = {
+            [replyId]: replyMessage
+        };
+
+        await update(postRef, {
+            replies: {
+                ...replies,
+                ...newReply
+            }
+        });
+
+        return null;
+    } catch (error) {
+        console.error('Error adding reply:', error);
+        return error.message || 'Error adding reply';
+    }
+};