Skip to content

Commit

Permalink
Merge pull request #6 from frontend-park-mail-ru/ad-3-add-first-pages…
Browse files Browse the repository at this point in the history
…-mocks-base-routing

Реализованы страницы ресторанов и отдельного ресторана, конфиг с моковыми данными и базовый роутинг
  • Loading branch information
YarikMix authored Feb 23, 2025
2 parents 5dad40a + 28ea662 commit f1613a2
Show file tree
Hide file tree
Showing 18 changed files with 307 additions and 26 deletions.
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

0 comments on commit f1613a2

Please sign in to comment.