Anonymous
Проблема с маршрутизацией: при переходе к /category/smartphones/iphone открывается index.html вместо Category.html.
Сообщение
Anonymous » 01 янв 2026, 17:35
У меня есть веб-приложение, работающее на localhost:5000, использующее HTML-страницы (index.html и Category.html) с динамической загрузкой компонентов (например, header.html) с помощью функции loadComponent. Ссылки в меню (header.html) указывают на такие пути, как /category/smartphones/iphone, но когда я перехожу по этому URL-адресу, он открывает index.html с ошибками вместо отображения категории.html с продуктами из категории «смартфоны» и бренда «iPhone». Как настроить сервер и функцию loadComponent, чтобы при переходе к /category/smartphones/iphone правильно загружался файл Category.html и фильтровались продукты из Firestore по категориям и брендам?
Контекст:
Я использую Firestore для хранения данных о продуктах.
Функция loadComponent загружает header.html и footer.html в Category.html.
текущий код обрабатывает только параметры строки запроса (например, ?name=smartphones&brand=iphone), но не очищает пути.
Сервер работает на порту 5000, но неправильно перенаправляет пути.
Я могу предоставить необходимые коды (например, loadComponent.js, Category.html, header.html или конфигурацию сервера), если это поможет.
Код: Выделить всё
{
"hosting": {
"public": ".",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "/category/:category/:brand",
"destination": "/category.html?name=:category&brand=:brand"
},
{
"source": "**",
"destination": "/index.html"
}
]
}
}
Код: Выделить всё
Կատեգորիա | SOTKA MOBILE
:root {
--bg-color: #F8F9FA;
--card-bg-color: #FFFFFF;
--text-color: #1B1B1B;
--accent-color: #B58863;
--border-color: #DEE2E6;
--header-bg-color: #1c1f23;
--header-text-color: #FFFFFF;
--submenu-item-bg: #EAF2F0;
--dark-menu-bg: #2a2e33;
--dark-menu-border: #3b4047;
--dark-menu-text: #F8F9FA;
--dark-menu-sub-text: #a0a0a0;
--dark-menu-hover-bg: #3b4047;
}
/* Basic Reset and Body Styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
margin: 0;
font-family: 'Montserrat', sans-serif;
background-color: var(--bg-color);
color: var(--text-color);
}
/* Общие стили для страницы категории */
.category-page {
padding: 30px 5%;
}
.category-title {
font-size: 28px;
font-weight: 600;
margin-bottom: 25px;
text-align: center;
}
/* Панель сортировки */
.sort-bar {
display: flex;
justify-content: flex-end;
margin-bottom: 20px;
gap: 10px;
}
.sort-bar select {
padding: 8px 12px;
border-radius: 10px;
border: 1px solid #ddd;
font-size: 14px;
cursor: pointer;
}
/* Новые стили для фильтров */
#filter-bar {
display: flex;
flex-wrap: wrap;
gap: 15px;
margin-bottom: 20px;
}
#filter-bar select {
padding: 10px 15px;
border-radius: 10px;
border: 1px solid #ddd;
font-size: 14px;
cursor: pointer;
background-color: #fff;
color: #1c1f23;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
background-image: url('data:image/svg+xml;charset=UTF-8,');
background-repeat: no-repeat;
background-position: right 10px center;
background-size: 12px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}
#filter-bar select:hover,
#filter-bar select:focus {
border-color: #aaa;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
outline: none;
}
/* Сетка товаров */
.product-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
justify-items: center;
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
.product-card {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
max-width: 300px;
width: 100%;
height: 350px;
background-color: rgba(246, 245, 248, 0.5);
border: 1px solid rgba(255, 255, 255, 0.4);
border-radius: 15px;
text-align: center;
position: relative;
overflow: hidden;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15);
transition: transform 0.3s ease, box-shadow 0.3s ease;
backdrop-filter: blur(25px);
-webkit-backdrop-filter: blur(25px);
flex-shrink: 0;
margin-bottom: 20px;
}
.product-card:hover {
transform: translateY(-5px);
box-shadow: 0 12px 45px rgba(0, 0, 0, 0.2);
}
.product-card-link {
text-decoration: none;
color: inherit;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
height: 100%;
width: 100%;
padding: 10px;
box-sizing: border-box;
}
.product-title,
.current-price,
.old-price {
color: var(--text-color);
text-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
text-decoration: none;
}
.product-image-wrapper {
position: absolute;
top: -40px;
left: 50%;
transform: translateX(-50%);
width: 100%;
height: 250px;
display: flex;
justify-content: center;
align-items: center;
pointer-events: none;
overflow: hidden;
}
.product-image {
width: 450px;
height: 400px;
object-fit: contain;
display: block;
}
.product-details {
margin-top: auto;
width: 100%;
padding-top: 220px;
position: relative;
z-index: 2;
}
.product-title {
font-size: 18px;
font-weight: 700;
color: var(--text-color);
margin-bottom: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-decoration: none;
}
.product-prices {
margin-bottom: 15px;
display: flex;
justify-content: center;
align-items: baseline;
width: 100%;
}
.old-price {
font-size: 14px;
color: #888;
text-decoration: line-through;
}
.current-price {
font-size: 20px;
font-weight: 700;
color: var(--header-bg-color);
text-decoration: none;
}
.current-price .currency {
font-size: 14px;
margin-left: 4px;
font-weight: normal;
color: inherit;
}
.product-actions {
display: flex;
justify-content: center;
width: 100%;
}
.btn-order {
background-color: var(--header-bg-color);
color: var(--header-text-color);
border: none;
border-radius: 15px;
padding: 15px 30px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: background-color 0.3s ease, transform 0.2s ease, color 0.3s ease;
width: 100%;
max-width: 250px;
text-decoration: none;
}
.btn-order:hover {
background-color: var(--accent-color);
color: var(--header-bg-color);
transform: translateY(-2px);
}
.btn-add-to-cart {
display: none;
}
/* --- Featured Products Media Queries (ОБНОВЛЕНО) --- */
@media (max-width: 1200px) {
.product-grid {
grid-template-columns: repeat(3, 1fr);
max-width: 1200px;
gap: 15px;
}
.product-card {
height: 320px;
max-width: 100%;
}
}
@media (max-width: 992px) {
.product-grid {
grid-template-columns: repeat(2, 1fr);
max-width: 992px;
gap: 15px;
}
.product-card {
height: 300px;
}
}
@media (max-width: 768px) {
.product-grid {
grid-template-columns: repeat(2, 1fr);
padding: 0 10px;
gap: 10px;
}
.product-card {
max-width: 100%;
height: 250px;
margin-bottom: 15px;
}
.product-image {
width: 250px;
height: 230px;
}
.product-details {
padding-top: 130px;
}
.product-title {
font-size: 13px;
margin-bottom: 3px;
}
.current-price {
font-size: 15px;
}
.btn-order {
padding: 8px 12px;
font-size: 12px;
}
.product-image {
width: 320px;
height: 280px;
}
}
@media (max-width: 480px) {
.featured-products-section {
padding: 50px 0;
}
.featured-products-section .section-title {
font-size: 22px;
padding-bottom: 25px;
}
.product-grid {
grid-template-columns: repeat(2, 1fr);
padding: 0 5px;
gap: 10px;
}
.product-card {
width: 100%;
max-width: 100%;
box-sizing: border-box;
margin: 0;
height: 250px;
}
.product-image-wrapper {
top: 5px;
height: 120px;
}
.product-image {
width: 300px;
height: 250px;
}
.product-details {
padding-top: 100px;
padding-bottom: 10px;
}
.product-title {
font-size: 13px;
margin-bottom: 8px;
white-space: normal;
font-weight: 700;
color: var(--text-color);
}
.current-price {
font-size: 14px;
}
.btn-order {
padding: 5px 10px;
font-size: 10px;
width: 100%;
height: 30px;
}
}
@media (min-width: 993px) and (max-width: 1200px) {
.product-grid {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 20px;
padding: 0 20px;
}
.product-card {
flex: 0 0 calc(33.333% - 14px);
}
}
Կատեգորիա
Դասավորել ըստ
Գին ↑
Գին ↓
Անուն A-Z
Անուն Z-A
// Загрузка компонентов с использованием loadComponent
// Загрузка компонентов с использованием loadComponent
async function loadPartials() {
await loadComponent('header-container', 'header.html');
await loadComponent('footer-container', 'footer.html');
}
loadPartials();
// Получение параметров из URL
// Получение параметров из URL
const urlParts = window.location.pathname.split('/').filter(Boolean); // ['category', 'smartphones', 'iphone']
const categoryName = urlParts[1] ? urlParts[1].toLowerCase() : (urlParams.get('name') || 'laptops').toLowerCase();
const brandName = urlParts[2] ? urlParts[2].toLowerCase() : urlParams.get('brand') || null;
// Установка заголовка категории
document.getElementById('category-name').textContent = brandName ?
`${categoryName.charAt(0).toUpperCase() + categoryName.slice(1)} - ${brandName.charAt(0).toUpperCase() + brandName.slice(1)}` :
categoryName.charAt(0).toUpperCase() + categoryName.slice(1);
// Инициализация Firestore
import {
getFirestore
} from 'https://www.gstatic.com/firebasejs/10.12.2/firebase-firestore-compat.js';
const db = getFirestore();
const productsContainer = document.getElementById('category-products');
const sortSelect = document.getElementById('sort-by');
async function loadProducts(sort = 'default') {
let query = db.collection('products').where('category', 'in', [
categoryName,
categoryName.charAt(0).toUpperCase() + categoryName.slice(1)
]);
if (brandName) {
query = query.where('brand', 'in', [
brandName,
brandName.charAt(0).toUpperCase() + brandName.slice(1)
]);
}
const snapshot = await query.get();
let productCards = [];
snapshot.forEach(doc => {
const data = doc.data();
const imageUrl = data.image || (data.colorOptions?.[0]?.colorImageUrls?.[0] || 'https://via.placeholder.com/250?text=No+Image');
if (Array.isArray(data.memoryOptions) && data.memoryOptions.length > 0) {
data.memoryOptions.forEach((option, index) => {
const salePrice = option['Sale Price'] || '';
const memory = option.memory || '';
productCards.push({
id: `${doc.id}-${index}`,
name: `${data.name} ${memory}`,
image: imageUrl,
price: parseFloat(salePrice.replace(' AMD', '').replace(/\./g, '')) || 0,
priceText: salePrice || data['Price'] || 'N/A AMD'
});
});
} else {
const salePrice = data['Sale Price'] || data['Price'] || '';
productCards.push({
id: doc.id,
name: data.name,
image: imageUrl,
price: parseFloat(salePrice.replace(' AMD', '').replace(/\./g, '')) || 0,
priceText: salePrice || 'N/A AMD'
});
}
});
// Сортировка
if (sort === 'price-asc') productCards.sort((a, b) => a.price - b.price);
if (sort === 'price-desc') productCards.sort((a, b) => b.price - a.price);
if (sort === 'name-asc') productCards.sort((a, b) => a.name.localeCompare(b.name));
if (sort === 'name-desc') productCards.sort((a, b) => b.name.localeCompare(a.name));
// Рендер
productsContainer.innerHTML = '';
if (productCards.length === 0) {
productsContainer.innerHTML = `Ոչինչ չի գտնվել 🙁
`;
} else {
productCards.forEach(p => {
const card = `
[url=product-detail.html?id=${p.id}]
[img]${p.image}[/img]
${p.name}
${p.priceText}
Գնել
[/url]
`;
productsContainer.insertAdjacentHTML('beforeend', card);
});
}
}
sortSelect.addEventListener('change', () => {
loadProducts(sortSelect.value);
});
document.addEventListener('DOMContentLoaded', () => {
const targetElement = document.getElementById('header-container'); // Или другой контейнер
const categoryName = targetElement ? targetElement.getAttribute('data-category') : null;
const brandName = targetElement ? targetElement.getAttribute('data-brand') : null;
// Установка заголовка категории
const categoryTitle = document.getElementById('category-name');
if (categoryTitle) {
categoryTitle.textContent = brandName ?
`${categoryName.charAt(0).toUpperCase() + categoryName.slice(1)} - ${brandName.charAt(0).toUpperCase() + brandName.slice(1)}` :
categoryName.charAt(0).toUpperCase() + categoryName.slice(1) || 'Կատեգորիա';
}
// Загрузка продуктов
async function loadProducts(sort = 'default') {
let query = db.collection('products').where('category', 'in', [
categoryName || 'laptops',
(categoryName || 'laptops').charAt(0).toUpperCase() + (categoryName || 'laptops').slice(1)
]);
if (brandName) {
query = query.where('brand', 'in', [
brandName,
brandName.charAt(0).toUpperCase() + brandName.slice(1)
]);
}
}
loadProducts();
});
Подробнее здесь:
https://stackoverflow.com/questions/797 ... html-inste
1767278133
Anonymous
У меня есть веб-приложение, работающее на localhost:5000, использующее HTML-страницы (index.html и Category.html) с динамической загрузкой компонентов (например, header.html) с помощью функции loadComponent. Ссылки в меню (header.html) указывают на такие пути, как /category/smartphones/iphone, но когда я перехожу по этому URL-адресу, он открывает index.html с ошибками вместо отображения категории.html с продуктами из категории «смартфоны» и бренда «iPhone». Как настроить сервер и функцию loadComponent, чтобы при переходе к /category/smartphones/iphone правильно загружался файл Category.html и фильтровались продукты из Firestore по категориям и брендам? [b]Контекст:[/b] Я использую Firestore для хранения данных о продуктах. Функция loadComponent загружает header.html и footer.html в Category.html. текущий код обрабатывает только параметры строки запроса (например, ?name=smartphones&brand=iphone), но не очищает пути. Сервер работает на порту 5000, но неправильно перенаправляет пути. Я могу предоставить необходимые коды (например, loadComponent.js, Category.html, header.html или конфигурацию сервера), если это поможет. [code]{ "hosting": { "public": ".", "ignore": [ "firebase.json", "**/.*", "**/node_modules/**" ], "rewrites": [ { "source": "/category/:category/:brand", "destination": "/category.html?name=:category&brand=:brand" }, { "source": "**", "destination": "/index.html" } ] } } [/code] [code] Կատեգորիա | SOTKA MOBILE :root { --bg-color: #F8F9FA; --card-bg-color: #FFFFFF; --text-color: #1B1B1B; --accent-color: #B58863; --border-color: #DEE2E6; --header-bg-color: #1c1f23; --header-text-color: #FFFFFF; --submenu-item-bg: #EAF2F0; --dark-menu-bg: #2a2e33; --dark-menu-border: #3b4047; --dark-menu-text: #F8F9FA; --dark-menu-sub-text: #a0a0a0; --dark-menu-hover-bg: #3b4047; } /* Basic Reset and Body Styles */ * { margin: 0; padding: 0; box-sizing: border-box; } body { margin: 0; font-family: 'Montserrat', sans-serif; background-color: var(--bg-color); color: var(--text-color); } /* Общие стили для страницы категории */ .category-page { padding: 30px 5%; } .category-title { font-size: 28px; font-weight: 600; margin-bottom: 25px; text-align: center; } /* Панель сортировки */ .sort-bar { display: flex; justify-content: flex-end; margin-bottom: 20px; gap: 10px; } .sort-bar select { padding: 8px 12px; border-radius: 10px; border: 1px solid #ddd; font-size: 14px; cursor: pointer; } /* Новые стили для фильтров */ #filter-bar { display: flex; flex-wrap: wrap; gap: 15px; margin-bottom: 20px; } #filter-bar select { padding: 10px 15px; border-radius: 10px; border: 1px solid #ddd; font-size: 14px; cursor: pointer; background-color: #fff; color: #1c1f23; appearance: none; -webkit-appearance: none; -moz-appearance: none; background-image: url('data:image/svg+xml;charset=UTF-8,'); background-repeat: no-repeat; background-position: right 10px center; background-size: 12px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05); } #filter-bar select:hover, #filter-bar select:focus { border-color: #aaa; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); outline: none; } /* Сетка товаров */ .product-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; justify-items: center; max-width: 1200px; margin: 0 auto; padding: 0 20px; } .product-card { display: flex; flex-direction: column; align-items: center; justify-content: flex-end; max-width: 300px; width: 100%; height: 350px; background-color: rgba(246, 245, 248, 0.5); border: 1px solid rgba(255, 255, 255, 0.4); border-radius: 15px; text-align: center; position: relative; overflow: hidden; box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15); transition: transform 0.3s ease, box-shadow 0.3s ease; backdrop-filter: blur(25px); -webkit-backdrop-filter: blur(25px); flex-shrink: 0; margin-bottom: 20px; } .product-card:hover { transform: translateY(-5px); box-shadow: 0 12px 45px rgba(0, 0, 0, 0.2); } .product-card-link { text-decoration: none; color: inherit; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; width: 100%; padding: 10px; box-sizing: border-box; } .product-title, .current-price, .old-price { color: var(--text-color); text-shadow: 0 0 5px rgba(0, 0, 0, 0.1); text-decoration: none; } .product-image-wrapper { position: absolute; top: -40px; left: 50%; transform: translateX(-50%); width: 100%; height: 250px; display: flex; justify-content: center; align-items: center; pointer-events: none; overflow: hidden; } .product-image { width: 450px; height: 400px; object-fit: contain; display: block; } .product-details { margin-top: auto; width: 100%; padding-top: 220px; position: relative; z-index: 2; } .product-title { font-size: 18px; font-weight: 700; color: var(--text-color); margin-bottom: 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-decoration: none; } .product-prices { margin-bottom: 15px; display: flex; justify-content: center; align-items: baseline; width: 100%; } .old-price { font-size: 14px; color: #888; text-decoration: line-through; } .current-price { font-size: 20px; font-weight: 700; color: var(--header-bg-color); text-decoration: none; } .current-price .currency { font-size: 14px; margin-left: 4px; font-weight: normal; color: inherit; } .product-actions { display: flex; justify-content: center; width: 100%; } .btn-order { background-color: var(--header-bg-color); color: var(--header-text-color); border: none; border-radius: 15px; padding: 15px 30px; font-size: 16px; font-weight: 600; cursor: pointer; transition: background-color 0.3s ease, transform 0.2s ease, color 0.3s ease; width: 100%; max-width: 250px; text-decoration: none; } .btn-order:hover { background-color: var(--accent-color); color: var(--header-bg-color); transform: translateY(-2px); } .btn-add-to-cart { display: none; } /* --- Featured Products Media Queries (ОБНОВЛЕНО) --- */ @media (max-width: 1200px) { .product-grid { grid-template-columns: repeat(3, 1fr); max-width: 1200px; gap: 15px; } .product-card { height: 320px; max-width: 100%; } } @media (max-width: 992px) { .product-grid { grid-template-columns: repeat(2, 1fr); max-width: 992px; gap: 15px; } .product-card { height: 300px; } } @media (max-width: 768px) { .product-grid { grid-template-columns: repeat(2, 1fr); padding: 0 10px; gap: 10px; } .product-card { max-width: 100%; height: 250px; margin-bottom: 15px; } .product-image { width: 250px; height: 230px; } .product-details { padding-top: 130px; } .product-title { font-size: 13px; margin-bottom: 3px; } .current-price { font-size: 15px; } .btn-order { padding: 8px 12px; font-size: 12px; } .product-image { width: 320px; height: 280px; } } @media (max-width: 480px) { .featured-products-section { padding: 50px 0; } .featured-products-section .section-title { font-size: 22px; padding-bottom: 25px; } .product-grid { grid-template-columns: repeat(2, 1fr); padding: 0 5px; gap: 10px; } .product-card { width: 100%; max-width: 100%; box-sizing: border-box; margin: 0; height: 250px; } .product-image-wrapper { top: 5px; height: 120px; } .product-image { width: 300px; height: 250px; } .product-details { padding-top: 100px; padding-bottom: 10px; } .product-title { font-size: 13px; margin-bottom: 8px; white-space: normal; font-weight: 700; color: var(--text-color); } .current-price { font-size: 14px; } .btn-order { padding: 5px 10px; font-size: 10px; width: 100%; height: 30px; } } @media (min-width: 993px) and (max-width: 1200px) { .product-grid { display: flex; flex-wrap: wrap; justify-content: center; gap: 20px; padding: 0 20px; } .product-card { flex: 0 0 calc(33.333% - 14px); } } Կատեգորիա Դասավորել ըստ Գին ↑ Գին ↓ Անուն A-Z Անուն Z-A // Загрузка компонентов с использованием loadComponent // Загрузка компонентов с использованием loadComponent async function loadPartials() { await loadComponent('header-container', 'header.html'); await loadComponent('footer-container', 'footer.html'); } loadPartials(); // Получение параметров из URL // Получение параметров из URL const urlParts = window.location.pathname.split('/').filter(Boolean); // ['category', 'smartphones', 'iphone'] const categoryName = urlParts[1] ? urlParts[1].toLowerCase() : (urlParams.get('name') || 'laptops').toLowerCase(); const brandName = urlParts[2] ? urlParts[2].toLowerCase() : urlParams.get('brand') || null; // Установка заголовка категории document.getElementById('category-name').textContent = brandName ? `${categoryName.charAt(0).toUpperCase() + categoryName.slice(1)} - ${brandName.charAt(0).toUpperCase() + brandName.slice(1)}` : categoryName.charAt(0).toUpperCase() + categoryName.slice(1); // Инициализация Firestore import { getFirestore } from 'https://www.gstatic.com/firebasejs/10.12.2/firebase-firestore-compat.js'; const db = getFirestore(); const productsContainer = document.getElementById('category-products'); const sortSelect = document.getElementById('sort-by'); async function loadProducts(sort = 'default') { let query = db.collection('products').where('category', 'in', [ categoryName, categoryName.charAt(0).toUpperCase() + categoryName.slice(1) ]); if (brandName) { query = query.where('brand', 'in', [ brandName, brandName.charAt(0).toUpperCase() + brandName.slice(1) ]); } const snapshot = await query.get(); let productCards = []; snapshot.forEach(doc => { const data = doc.data(); const imageUrl = data.image || (data.colorOptions?.[0]?.colorImageUrls?.[0] || 'https://via.placeholder.com/250?text=No+Image'); if (Array.isArray(data.memoryOptions) && data.memoryOptions.length > 0) { data.memoryOptions.forEach((option, index) => { const salePrice = option['Sale Price'] || ''; const memory = option.memory || ''; productCards.push({ id: `${doc.id}-${index}`, name: `${data.name} ${memory}`, image: imageUrl, price: parseFloat(salePrice.replace(' AMD', '').replace(/\./g, '')) || 0, priceText: salePrice || data['Price'] || 'N/A AMD' }); }); } else { const salePrice = data['Sale Price'] || data['Price'] || ''; productCards.push({ id: doc.id, name: data.name, image: imageUrl, price: parseFloat(salePrice.replace(' AMD', '').replace(/\./g, '')) || 0, priceText: salePrice || 'N/A AMD' }); } }); // Сортировка if (sort === 'price-asc') productCards.sort((a, b) => a.price - b.price); if (sort === 'price-desc') productCards.sort((a, b) => b.price - a.price); if (sort === 'name-asc') productCards.sort((a, b) => a.name.localeCompare(b.name)); if (sort === 'name-desc') productCards.sort((a, b) => b.name.localeCompare(a.name)); // Рендер productsContainer.innerHTML = ''; if (productCards.length === 0) { productsContainer.innerHTML = `Ոչինչ չի գտնվել 🙁 `; } else { productCards.forEach(p => { const card = ` [url=product-detail.html?id=${p.id}] [img]${p.image}[/img] ${p.name} ${p.priceText} Գնել [/url] `; productsContainer.insertAdjacentHTML('beforeend', card); }); } } sortSelect.addEventListener('change', () => { loadProducts(sortSelect.value); }); document.addEventListener('DOMContentLoaded', () => { const targetElement = document.getElementById('header-container'); // Или другой контейнер const categoryName = targetElement ? targetElement.getAttribute('data-category') : null; const brandName = targetElement ? targetElement.getAttribute('data-brand') : null; // Установка заголовка категории const categoryTitle = document.getElementById('category-name'); if (categoryTitle) { categoryTitle.textContent = brandName ? `${categoryName.charAt(0).toUpperCase() + categoryName.slice(1)} - ${brandName.charAt(0).toUpperCase() + brandName.slice(1)}` : categoryName.charAt(0).toUpperCase() + categoryName.slice(1) || 'Կատեգորիա'; } // Загрузка продуктов async function loadProducts(sort = 'default') { let query = db.collection('products').where('category', 'in', [ categoryName || 'laptops', (categoryName || 'laptops').charAt(0).toUpperCase() + (categoryName || 'laptops').slice(1) ]); if (brandName) { query = query.where('brand', 'in', [ brandName, brandName.charAt(0).toUpperCase() + brandName.slice(1) ]); } } loadProducts(); }); [/code] Подробнее здесь: [url]https://stackoverflow.com/questions/79756645/routing-issue-transition-to-category-smartphones-iphone-opens-index-html-inste[/url]