Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Реализованы страницы ресторанов и отдельного ресторана, конфиг с моковыми данными и базовый роутинг #6

Merged
merged 5 commits into from
Feb 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion build.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#!/bin/bash
mkdir -p public/build
handlebars -m public/src/pages/restaurantDetail.hbs -f public/build/restaurantDetail.js
handlebars -m public/src/pages/restaurantPage.hbs -f public/build/restaurantPage.js
handlebars -m public/src/pages/restaurantList.hbs -f public/build/restaurantList.js
handlebars -m public/src/components/header.hbs -f public/build/header.js
handlebars -m public/src/components/restaurantCard.hbs -f public/build/restaurantCard.js
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"main": "index.js",
"scripts": {
"build": "build.sh",
"devStart": "npm run build && nodemon server/server.js"
"start": "npm run build && nodemon server/server.js"
},
"repository": {
"type": "git",
Expand Down
1 change: 1 addition & 0 deletions public/build/header.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions public/build/restaurantCard.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion public/build/restaurantList.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions public/build/restaurantPage.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 6 additions & 5 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
<head>
<meta charset="utf-8">
<title>Handlebars test</title>
<script src="/handlebars/handlebars.runtime.js"></script>

</head>
<body>
<div id="root">
</div>
<script type="module" src="index.js"></script>
<div id="root"></div>
<noscript>
Please enable JavaScript in order to use this app.
</noscript>
</body>
<script src="/handlebars/handlebars.runtime.js"></script>
<script type="module" src="index.js"></script>
</html>
80 changes: 68 additions & 12 deletions public/index.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,79 @@
import "./build/restaurantList.js";
import "./build/restaurantDetail.js";
import "./build/restaurantPage.js";
import "./build/header.js";
import "./build/restaurantCard.js"
import * as requests from "./src/modules/requests.js"

const rootElement = document.getElementById('root');
const pageElement = document.createElement('main');
const rootElement = document.getElementById("root");
const pageElement = document.createElement("main");

rootElement.appendChild(pageElement);

const restaurants = [
{ name: "Restaurant A" },
{ name: "Restaurant B" },
{ name: "Restaurant C" }
];
Handlebars.registerPartial("restaurantCard", Handlebars.templates["restaurantCard.hbs"]);

function renderHeader() {
const template = Handlebars.templates["header.hbs"];
rootElement.insertAdjacentHTML("afterbegin", template());

function renderRestaurantList() {
const template = Handlebars.templates['restaurantList.hbs'];
pageElement.innerHTML = template({ restaurantList: restaurants });
document.getElementsByClassName("logo")[0].addEventListener("click", () => {
renderRestaurantList();
history.pushState({}, "", "/");
})
}

renderRestaurantList()
async function renderRestaurantList() {
try {
let restaurantList = await requests.getRestaurantList();
if (!restaurantList) throw new Error("Empty restaurant list");
const template = Handlebars.templates["restaurantList.hbs"];
pageElement.innerHTML = template({ restaurantList });

document.querySelectorAll(".restaurant-card").forEach(card => {
card.addEventListener("click", () => {
const restaurantId = card.dataset.id;
renderRestaurantPage(restaurantId);
history.pushState({ id: restaurantId }, "", `/restaurants/${restaurantId}`);
});
});

} catch (error) {
console.error("Error rendering restaurant list:", error);
}
}

async function renderRestaurantPage(id) {
pageElement.innerHTML = '';
try {
let restaurantDetail = await requests.getRestaurantById(id);
if (!restaurantDetail) throw new Error("Empty restaurant list");
const currentTime = new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
let openStatus;
if (restaurantDetail.workingHours.open < currentTime && restaurantDetail.workingHours.closed > currentTime)
openStatus = "Open"
else
openStatus = "Closed"
const template = Handlebars.templates["restaurantPage.hbs"];
pageElement.innerHTML = template({ restaurantDetail, openStatus });
} catch (error) {
console.error("Error rendering restaurant list:", error);
}
}

window.addEventListener('popstate', (event) => {
const restaurantId = event.state ? event.state.id : null;
if (restaurantId) {
renderRestaurantPage(restaurantId);
} else {
renderRestaurantList();
}
});

const currentPath = window.location.pathname;
if (currentPath.startsWith("/restaurants/")) {
const restaurantId = currentPath.split("/")[2];
renderRestaurantPage(restaurantId);
} else {
renderRestaurantList();
}

renderHeader();
Empty file.
13 changes: 13 additions & 0 deletions public/src/components/header.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<header class="header">
<div class="logo">
Delivery
</div>
<div class="search-form">
<form action="">
<input class="search-form-input" placeholder="Поиск по ресторанам" type="text">
<button class="search-form-button">Найти</button>
</form>
</div>
<button class="address-button">Выберите адрес доставки</button>
<button class="login-button">Войти</button>
</header>
Empty file.
12 changes: 12 additions & 0 deletions public/src/components/restaurantCard.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<div class="restaurant-card" data-id="{{id}}">
<img src="{{image}}" alt="{{name}}" class="card-image">
<div class="restaurant-card-content">
<h2 class="restaurant-card-title">{{name}}</h2>
<div class="restaurant-card-info">
<div class="restaurant-rating"> {{rating}} ⭐</div>
<div class="restaurant-distance"> {{distance}}</div>
<div class="restaurant-time"> {{time}}</div>
</div>
<div class="restaurant-additional-info">{{additionalInfo}}</div>
</div>
</div>
25 changes: 25 additions & 0 deletions public/src/modules/requests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export async function getRestaurantList() {
const url = "http://localhost:3000/restaurants";
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Response status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error(error.message);
}
}

export async function getRestaurantById(id) {
const url = `http://localhost:3000/restaurants/${id}`;
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Response status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error(error.message);
}
}
3 changes: 0 additions & 3 deletions public/src/pages/restaurantDetail.hbs

This file was deleted.

2 changes: 1 addition & 1 deletion public/src/pages/restaurantList.hbs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{{#each restaurantList}}
<li>{{this.name}}</li>
{{> restaurantCard this}}
{{/each}}
15 changes: 15 additions & 0 deletions public/src/pages/restaurantPage.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<div class="restaurant-page" data-id="{{restaurantDetail.id}}">
<img src="{{restaurantDetail.image}}" alt="{{restaurantDetail.name}}" class="card-image">
<div class="restaurant-content">
<h1 class="restaurant-title">{{restaurantDetail.name}}</h1>
<div class="restaurant-additional-info">{{restaurantDetail.additionalInfo}}</div>
<h2>Ratings and Reviews</h2>
<div class="restaurant-details">
<div class="restaurant-rating">{{restaurantDetail.rating}} ⭐</div>
<div class="restaurant-hours-address">
<div class="restaurant-hours">{{openStatus}}</div>
<div class="restaurant-address">{{restaurantDetail.address}}</div>
</div>
</div>
</div>
</div>
129 changes: 129 additions & 0 deletions server/mocks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
export const restaurantList = [
{
id: 1,
name: "Italiano Pizza",
image: "images/italiano_pizza.jpg",
rating: 4.8,
distance: "1.2 km",
time: "25-30 min",
additionalInfo: "Authentic Italian pizza with fresh ingredients.",
address: "123 Pizza Street, Downtown",
workingHours: {
Monday: { open: "10:00", close: "22:00" },
Tuesday: { open: "10:00", close: "22:00" },
Wednesday: { open: "10:00", close: "22:00" },
Thursday: { open: "10:00", close: "22:00" },
Friday: { open: "10:00", close: "23:00" },
Saturday: { open: "11:00", close: "23:00" },
Sunday: { open: "11:00", close: "21:00" }
}
},
{
id: 2,
name: "Sushi Master",
image: "images/sushi_master.jpg",
rating: 4.6,
distance: "2.5 km",
time: "30-40 min",
additionalInfo: "Traditional Japanese sushi and rolls.",
address: "456 Sushi Avenue, Uptown",
workingHours: {
Monday: { open: "12:00", close: "22:00" },
Tuesday: { open: "12:00", close: "22:00" },
Wednesday: { open: "12:00", close: "22:00" },
Thursday: { open: "12:00", close: "22:00" },
Friday: { open: "12:00", close: "23:00" },
Saturday: { open: "13:00", close: "23:00" },
Sunday: { open: "13:00", close: "21:00" }
}
},
{
id: 3,
name: "Burger House",
image: "images/burger_house.jpg",
rating: 4.5,
distance: "800 m",
time: "15-20 min",
additionalInfo: "Juicy burgers with premium beef and homemade sauces.",
address: "789 Burger Lane, Midtown",
workingHours: {
Monday: { open: "09:00", close: "23:00" },
Tuesday: { open: "09:00", close: "23:00" },
Wednesday: { open: "09:00", close: "23:00" },
Thursday: { open: "09:00", close: "23:00" },
Friday: { open: "09:00", close: "24:00" },
Saturday: { open: "10:00", close: "24:00" },
Sunday: { open: "10:00", close: "22:00" }
}
},
{
id: 4,
name: "Vegan Delight",
image: "images/vegan_delight.jpg",
rating: 4.7,
distance: "3 km",
time: "20-25 min",
additionalInfo: "Healthy and delicious vegan meals.",
address: "101 Vegan Blvd, Green District",
workingHours: {
Monday: { open: "11:00", close: "21:00" },
Tuesday: { open: "11:00", close: "21:00" },
Wednesday: { open: "11:00", close: "21:00" },
Thursday: { open: "11:00", close: "21:00" },
Friday: { open: "11:00", close: "22:00" },
Saturday: { open: "12:00", close: "22:00" },
Sunday: { open: "12:00", close: "20:00" }
}
},
{
id: 5,
name: "Steak & Grill",
image: "images/steak_grill.jpg",
rating: 4.9,
distance: "5 km",
time: "40-50 min",
additionalInfo: "High-quality steaks and grilled dishes.",
address: "202 Grill Road, West End",
workingHours: {
Monday: { open: "12:00", close: "23:00" },
Tuesday: { open: "12:00", close: "23:00" },
Wednesday: { open: "12:00", close: "23:00" },
Thursday: { open: "12:00", close: "23:00" },
Friday: { open: "12:00", close: "24:00" },
Saturday: { open: "13:00", close: "24:00" },
Sunday: { open: "13:00", close: "22:00" }
}
}
];


export const menuItems = {
"Pizza": [
{ id: 101, name: "Margherita", price: 8.99, description: "Classic Margherita with fresh tomatoes, mozzarella, and basil." },
{ id: 102, name: "Pepperoni", price: 9.99, description: "Pepperoni pizza with spicy salami and cheese." }
],
"Sushi": [
{ id: 201, name: "California Roll", price: 6.99, description: "Crab, avocado, cucumber, and rice wrapped in nori." },
{ id: 202, name: "Salmon Nigiri", price: 7.99, description: "Fresh salmon slice over seasoned rice." }
],
"Burgers": [
{ id: 301, name: "Classic Cheeseburger", price: 10.99, description: "Beef patty, cheddar cheese, lettuce, and tomato." },
{ id: 302, name: "BBQ Bacon Burger", price: 12.99, description: "Beef patty with crispy bacon and BBQ sauce." }
],
"Vegan": [
{ id: 401, name: "Vegan Buddha Bowl", price: 9.49, description: "Quinoa, chickpeas, avocado, and fresh veggies." },
{ id: 402, name: "Tofu Stir Fry", price: 8.99, description: "Tofu sautéed with vegetables and soy sauce." }
],
"Steak": [
{ id: 501, name: "Ribeye Steak", price: 19.99, description: "Grilled ribeye steak with garlic butter." },
{ id: 502, name: "T-Bone Steak", price: 22.99, description: "Juicy T-bone steak cooked to perfection." }
]
};

export const restaurantMenu = {
1: [101, 102],
2: [201, 202],
3: [301, 302],
4: [401, 402],
5: [501, 502]
};
Loading