Skip to content

Commit

Permalink
Adds nextjs-start (#242)
Browse files Browse the repository at this point in the history
* Adds nextjs-start

* Include an initial config to get started quicker
  • Loading branch information
umaar authored Jul 27, 2023
1 parent c8f3a26 commit c43de97
Show file tree
Hide file tree
Showing 43 changed files with 1,991 additions and 0 deletions.
1 change: 1 addition & 0 deletions nextjs-start/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.next/
165 changes: 165 additions & 0 deletions nextjs-start/components/Filters.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// The filters shown on the restaurant listings page

import Tag from "@/components/Tag.jsx";

function FilterSelect({ label, options, value, onChange, name, icon }) {
return (
<div>
<img src={icon} alt={label} />
<label>
{label}
<select value={value} onChange={onChange} name={name}>
{options.map((option, index) => (
<option value={option} key={index}>
{option === "" ? "All" : option}
</option>
))}
</select>
</label>
</div>
);
}

export default function Filters({ filters, setFilters }) {
const handleSelectionChange = (event, name) => {
setFilters(prevFilters => ({
...prevFilters,
[name]: event.target.value,
}));
};

const updateField = (type, value) => {
setFilters({ ...filters, [type]: value });
};

return (
<section className="filter">
<details className="filter-menu">
<summary>
<img src="/filter.svg" alt="filter" />
<div>
<p>Restaurants</p>
<p>Sorted by {filters.sort || "Rating"}</p>
</div>
</summary>

<form
method="GET"
onSubmit={event => {
event.preventDefault();
event.target.parentNode.removeAttribute("open");
}}
>
<FilterSelect
label="Category"
options={[
"",
"Italian",
"Chinese",
"Japanese",
"Mexican",
"Indian",
"Mediterranean",
"Caribbean",
"Cajun",
"German",
"Russian",
"Cuban",
"Organic",
"Tapas",
]}
value={filters.category}
onChange={event =>
handleSelectionChange(event, "category")
}
name="category"
icon="/food.svg"
/>

<FilterSelect
label="City"
options={[
"",
"New York",
"Los Angeles",
"London",
"Paris",
"Tokyo",
"Mumbai",
"Dubai",
"Amsterdam",
"Seoul",
"Singapore",
"Istanbul",
]}
value={filters.city}
onChange={event => handleSelectionChange(event, "city")}
name="city"
icon="/location.svg"
/>

<FilterSelect
label="Price"
options={["", "$", "$$", "$$$", "$$$$"]}
value={filters.price}
onChange={event =>
handleSelectionChange(event, "price")
}
name="price"
icon="/price.svg"
/>

<FilterSelect
label="Sort"
options={["Rating", "Review"]}
value={filters.sort}
onChange={event => handleSelectionChange(event, "sort")}
name="sort"
icon="/sortBy.svg"
/>

<footer>
<menu>
<button
className="button--cancel"
type="reset"
onClick={() => {
setFilters({
city: "",
category: "",
price: "",
sort: "",
});
}}
>
Reset
</button>
<button type="submit" className="button--confirm">
Submit
</button>
</menu>
</footer>
</form>
</details>

<div className="tags">
{Object.entries(filters).map(([type, value]) => {
// The main filter bar already specifies what
// sorting is being used. So skip showing the
// sorting as a 'tag'
if (type == "sort" || value == "") {
return null;
}
return (
<Tag
key={value}
type={type}
value={value}
updateField={updateField}
/>
);
})}
</div>
</section>
);
}
73 changes: 73 additions & 0 deletions nextjs-start/components/Header.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"use client";

import React, { useState, useEffect } from "react";
import Link from "next/link";
import {
signInWithGoogle,
signOut,
onAuthStateChanged,
} from "@/lib/firebase/auth.js";
import { addFakeRestaurantsAndReviews } from "@/lib/firebase/firestore.js";

async function handleUserSession() {}

function useUserSession() {}

export default function Header({ initialUser }) {
const user = useUserSession(initialUser);

const handleSignOut = event => {
event.preventDefault();
signOut();
};

const handleSignIn = event => {
event.preventDefault();
signInWithGoogle();
};

return (
<header>
<Link href="/" className="logo">
<img src="/friendly-eats.svg" alt="FriendlyEats" />
Friendly Eats
</Link>
{user ? (
<>
<div className="profile">
<p>
<img src="/profile.svg" alt={user.email} />
{user.displayName}
</p>

<div className="menu">
...
<ul>
<li>{user.displayName}</li>

<li>
<a
href="#"
onClick={addFakeRestaurantsAndReviews}
>
Add sample restaurants
</a>
</li>

<li>
<a href="#" onClick={handleSignOut}>
Sign Out
</a>
</li>
</ul>
</div>
</div>
</>
) : (
<a href="#" onClick={handleSignIn}>
Sign In with Google
</a>
)}
</header>
);
}
66 changes: 66 additions & 0 deletions nextjs-start/components/RatingPicker.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React from "react";

// A HTML and CSS only rating picker thanks to: https://codepen.io/chris22smith/pen/MJzLJN

const RatingPicker = () => {
return (
<p className="rating-picker">
<input
className="radio-input"
type="radio"
id="star5"
name="rating"
value="5"
/>
<label className="radio-label" htmlFor="star5" title="5 stars">
5 stars
</label>

<input
className="radio-input"
type="radio"
id="star4"
name="rating"
value="4"
/>
<label className="radio-label" htmlFor="star4" title="4 stars">
4 stars
</label>

<input
className="radio-input"
type="radio"
id="star3"
name="rating"
value="3"
/>
<label className="radio-label" htmlFor="star3" title="3 stars">
3 stars
</label>

<input
className="radio-input"
type="radio"
id="star2"
name="rating"
value="2"
/>
<label className="radio-label" htmlFor="star2" title="2 stars">
2 stars
</label>

<input
className="radio-input"
type="radio"
id="star1"
name="rating"
value="1"
/>
<label className="radio-label" htmlFor="star1" title="1 star">
1 star
</label>
</p>
);
};

export default RatingPicker;
Loading

0 comments on commit c43de97

Please sign in to comment.