Skip to content

Commit

Permalink
Merge pull request #8 from 392-f24/frontend-improvement
Browse files Browse the repository at this point in the history
Frontend improvement
  • Loading branch information
angelp03 authored Nov 8, 2024
2 parents 885898c + cd0b602 commit 6fa49fc
Show file tree
Hide file tree
Showing 17 changed files with 787 additions and 322 deletions.
4 changes: 2 additions & 2 deletions database.rules.json
Original file line number Diff line number Diff line change
@@ -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
}
}
204 changes: 15 additions & 189 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,194 +1,20 @@
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";
import ReviewsPage from "./pages/ReviewsPage";
import CafePage from "./pages/CafePage";

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/> }/>
<Route path="/cafes" element={ <ReviewsPage/> }/>
<Route path="/cafe/:place_id" element={<CafePage/>}/>
</Routes>
</Router>
)
}

export default App;
46 changes: 39 additions & 7 deletions src/components/Banner.css
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -16,7 +16,7 @@
}

.logo-div {
height:100%;
height: 100%;
display: flex;
align-items: center;
margin-right: 3rem;
Expand All @@ -31,11 +31,14 @@
.logo-search-div form {
display: flex;
align-items: center;
position: relative; /* Allow positioning of the autocomplete dropdown */
}

.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;
Expand All @@ -46,18 +49,21 @@
}

.search-btn {
height: 2.6rem;
height: 2.3rem;
width: 3rem;
background-color: #8A3323;
border: none;
cursor: pointer;
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.25rem;
}

.banner-buttons {
Expand All @@ -68,7 +74,7 @@

.banner-btn {
text-align: center;
height:2.45rem;
height: 2.45rem;
width: 8rem;
background-color: #8A3323;
color: white;
Expand All @@ -83,4 +89,30 @@

.banner-btn:hover {
background-color: #a85c43;
}
}

/* 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;
}
Loading

0 comments on commit 6fa49fc

Please sign in to comment.