Обновлены страницы с мета-тегами: заменены статические мета-теги на компонент MetaTags, который динамически получает данные через getMetaByPath. Добавлены новые страницы с мета-тегами, включая карточку товара, страницы оплаты и профиля, а также обновлены существующие страницы для улучшения SEO.
This commit is contained in:
@ -61,14 +61,7 @@ export const metaConfig: Record<string, MetaConfig> = {
|
||||
ogDescription: 'Компания Protek - надежный поставщик автозапчастей с многолетним опытом.'
|
||||
},
|
||||
|
||||
// Новости
|
||||
'/news': {
|
||||
title: 'Новости и акции - Protek',
|
||||
description: 'Актуальные новости компании Protek, специальные предложения и акции на автозапчасти.',
|
||||
keywords: 'новости protek, акции, специальные предложения, скидки на запчасти',
|
||||
ogTitle: 'Новости и акции - Protek',
|
||||
ogDescription: 'Актуальные новости компании Protek, специальные предложения и акции.'
|
||||
},
|
||||
|
||||
|
||||
// Оптовые продажи
|
||||
'/wholesale': {
|
||||
@ -79,14 +72,7 @@ export const metaConfig: Record<string, MetaConfig> = {
|
||||
ogDescription: 'Оптовые продажи автозапчастей для автосервисов и дилеров. Специальные цены.'
|
||||
},
|
||||
|
||||
// Способы оплаты
|
||||
'/payments-method': {
|
||||
title: 'Способы оплаты - Protek',
|
||||
description: 'Удобные способы оплаты автозапчастей: наличными, картой, банковским переводом, онлайн-платежи.',
|
||||
keywords: 'способы оплаты, оплата запчастей, банковская карта, наличные, онлайн-платеж',
|
||||
ogTitle: 'Способы оплаты - Protek',
|
||||
ogDescription: 'Удобные способы оплаты автозапчастей: наличными, картой, банковским переводом.'
|
||||
},
|
||||
|
||||
|
||||
// Корзина
|
||||
'/cart': {
|
||||
@ -97,6 +83,149 @@ export const metaConfig: Record<string, MetaConfig> = {
|
||||
ogDescription: 'Корзина покупок. Оформите заказ на выбранные автозапчасти.'
|
||||
},
|
||||
|
||||
// Новости
|
||||
'/news': {
|
||||
title: 'Новости - Protek',
|
||||
description: 'Актуальные новости компании Protek, события автомобильной индустрии и мира автозапчастей.',
|
||||
keywords: 'новости protek, автомобильные новости, события автоиндустрии',
|
||||
ogTitle: 'Новости - Protek',
|
||||
ogDescription: 'Актуальные новости компании Protek и автомобильной индустрии.'
|
||||
},
|
||||
|
||||
// Карточка товара
|
||||
'/card': {
|
||||
title: 'Карточка товара - Protek',
|
||||
description: 'Подробная информация о товаре: характеристики, цены, наличие, отзывы.',
|
||||
keywords: 'карточка товара, характеристики запчасти, цена, наличие',
|
||||
ogTitle: 'Карточка товара - Protek',
|
||||
ogDescription: 'Подробная информация о товаре: характеристики, цены, наличие.'
|
||||
},
|
||||
|
||||
// Поиск автомобилей по артикулу
|
||||
'/vehicles-by-part': {
|
||||
title: 'Автомобили по артикулу - Protek',
|
||||
description: 'Поиск автомобилей, в которых используется деталь с указанным артикулом.',
|
||||
keywords: 'автомобили по артикулу, применимость детали, где используется',
|
||||
ogTitle: 'Автомобили по артикулу - Protek',
|
||||
ogDescription: 'Поиск автомобилей, в которых используется деталь с указанным артикулом.'
|
||||
},
|
||||
|
||||
// Страницы оплаты
|
||||
'/payment/success': {
|
||||
title: 'Оплата прошла успешно - Protek',
|
||||
description: 'Ваш платеж успешно обработан. Спасибо за покупку! Мы приступим к обработке заказа.',
|
||||
keywords: 'оплата успешна, платеж прошел, заказ оплачен',
|
||||
ogTitle: 'Оплата прошла успешно - Protek',
|
||||
ogDescription: 'Ваш платеж успешно обработан. Спасибо за покупку!'
|
||||
},
|
||||
|
||||
'/payment/cancelled': {
|
||||
title: 'Оплата отменена - Protek',
|
||||
description: 'Платеж был отменен. Вы можете попробовать оплатить заказ повторно.',
|
||||
keywords: 'оплата отменена, платеж отклонен, повторная оплата',
|
||||
ogTitle: 'Оплата отменена - Protek',
|
||||
ogDescription: 'Платеж был отменен. Вы можете попробовать оплатить заказ повторно.'
|
||||
},
|
||||
|
||||
'/payment/failed': {
|
||||
title: 'Ошибка оплаты - Protek',
|
||||
description: 'Произошла ошибка при обработке платежа. Попробуйте еще раз или выберите другой способ оплаты.',
|
||||
keywords: 'ошибка оплаты, платеж не прошел, проблема с оплатой',
|
||||
ogTitle: 'Ошибка оплаты - Protek',
|
||||
ogDescription: 'Произошла ошибка при обработке платежа. Попробуйте еще раз.'
|
||||
},
|
||||
|
||||
'/payment/invoice': {
|
||||
title: 'Счёт на оплату - Protek',
|
||||
description: 'Счёт на оплату заказа. Вы можете оплатить удобным для вас способом.',
|
||||
keywords: 'счет на оплату, инвойс, оплата заказа',
|
||||
ogTitle: 'Счёт на оплату - Protek',
|
||||
ogDescription: 'Счёт на оплату заказа. Вы можете оплатить удобным для вас способом.'
|
||||
},
|
||||
|
||||
// Дополнительные страницы профиля
|
||||
'/profile-req': {
|
||||
title: 'Реквизиты - Личный кабинет Protek',
|
||||
description: 'Управление реквизитами организации в личном кабинете.',
|
||||
keywords: 'реквизиты организации, личный кабинет, данные компании',
|
||||
ogTitle: 'Реквизиты - Protek',
|
||||
ogDescription: 'Управление реквизитами организации в личном кабинете.'
|
||||
},
|
||||
|
||||
'/profile-acts': {
|
||||
title: 'Акты сверки - Личный кабинет Protek',
|
||||
description: 'Акты сверки взаиморасчетов в личном кабинете.',
|
||||
keywords: 'акты сверки, взаиморасчеты, личный кабинет',
|
||||
ogTitle: 'Акты сверки - Protek',
|
||||
ogDescription: 'Акты сверки взаиморасчетов в личном кабинете.'
|
||||
},
|
||||
|
||||
'/profile-balance': {
|
||||
title: 'Баланс - Личный кабинет Protek',
|
||||
description: 'Информация о балансе и финансовых операциях в личном кабинете.',
|
||||
keywords: 'баланс счета, финансы, личный кабинет',
|
||||
ogTitle: 'Баланс - Protek',
|
||||
ogDescription: 'Информация о балансе и финансовых операциях.'
|
||||
},
|
||||
|
||||
// Процесс заказа
|
||||
'/order-confirmation': {
|
||||
title: 'Подтверждение заказа - Protek',
|
||||
description: 'Подтверждение оформленного заказа. Проверьте данные перед финальным подтверждением.',
|
||||
keywords: 'подтверждение заказа, проверка заказа, финальный шаг',
|
||||
ogTitle: 'Подтверждение заказа - Protek',
|
||||
ogDescription: 'Подтверждение оформленного заказа. Проверьте данные.'
|
||||
},
|
||||
|
||||
'/cart-step-2': {
|
||||
title: 'Оформление заказа - Шаг 2 - Protek',
|
||||
description: 'Второй шаг оформления заказа. Выберите способ доставки и оплаты.',
|
||||
keywords: 'оформление заказа шаг 2, доставка, способ оплаты',
|
||||
ogTitle: 'Оформление заказа - Шаг 2',
|
||||
ogDescription: 'Второй шаг оформления заказа. Выберите способ доставки и оплаты.'
|
||||
},
|
||||
|
||||
'/payments-method': {
|
||||
title: 'Способы оплаты - Protek',
|
||||
description: 'Выберите удобный способ оплаты: наличными, картой, банковским переводом.',
|
||||
keywords: 'способы оплаты, оплата картой, наличные, банковский перевод',
|
||||
ogTitle: 'Способы оплаты - Protek',
|
||||
ogDescription: 'Выберите удобный способ оплаты: наличными, картой, банковским переводом.'
|
||||
},
|
||||
|
||||
'/checkout': {
|
||||
title: 'Оформление заказа - Protek',
|
||||
description: 'Оформление заказа автозапчастей. Быстро и безопасно.',
|
||||
keywords: 'оформление заказа, checkout, заказать запчасти',
|
||||
ogTitle: 'Оформление заказа - Protek',
|
||||
ogDescription: 'Оформление заказа автозапчастей. Быстро и безопасно.'
|
||||
},
|
||||
|
||||
// Детальные страницы
|
||||
'/detail_category': {
|
||||
title: 'Категория товаров - Protek',
|
||||
description: 'Просмотр товаров в выбранной категории автозапчастей.',
|
||||
keywords: 'категория товаров, группа запчастей, каталог',
|
||||
ogTitle: 'Категория товаров - Protek',
|
||||
ogDescription: 'Просмотр товаров в выбранной категории автозапчастей.'
|
||||
},
|
||||
|
||||
'/detail_product': {
|
||||
title: 'Детальная информация о товаре - Protek',
|
||||
description: 'Подробная информация о товаре: технические характеристики, совместимость, цены.',
|
||||
keywords: 'детальная информация, технические характеристики, совместимость',
|
||||
ogTitle: 'Детальная информация о товаре - Protek',
|
||||
ogDescription: 'Подробная информация о товаре: технические характеристики, совместимость.'
|
||||
},
|
||||
|
||||
'/detail_sku': {
|
||||
title: 'Информация о SKU - Protek',
|
||||
description: 'Детальная информация о конкретном артикуле товара.',
|
||||
keywords: 'информация SKU, артикул товара, детали товара',
|
||||
ogTitle: 'Информация о SKU - Protek',
|
||||
ogDescription: 'Детальная информация о конкретном артикуле товара.'
|
||||
},
|
||||
|
||||
// Избранное
|
||||
'/favorite': {
|
||||
title: 'Избранные товары - Protek',
|
||||
@ -106,15 +235,6 @@ export const metaConfig: Record<string, MetaConfig> = {
|
||||
ogDescription: 'Ваши избранные автозапчасти. Сохраните интересующие товары.'
|
||||
},
|
||||
|
||||
// Профиль
|
||||
'/profile-orders': {
|
||||
title: 'Мои заказы - Личный кабинет Protek',
|
||||
description: 'Личный кабинет клиента Protek. Управляйте своими заказами, отслеживайте статус доставки.',
|
||||
keywords: 'личный кабинет, мои заказы, статус заказа, история покупок',
|
||||
ogTitle: 'Мои заказы - Личный кабинет Protek',
|
||||
ogDescription: 'Личный кабинет клиента Protek. Управляйте своими заказами.'
|
||||
},
|
||||
|
||||
// Страница благодарности
|
||||
'/thankyoupage': {
|
||||
title: 'Спасибо за заказ - Protek',
|
||||
@ -122,7 +242,99 @@ export const metaConfig: Record<string, MetaConfig> = {
|
||||
keywords: 'заказ оформлен, спасибо за заказ, подтверждение заказа',
|
||||
ogTitle: 'Спасибо за заказ - Protek',
|
||||
ogDescription: 'Ваш заказ успешно оформлен. Мы свяжемся с вами в ближайшее время.'
|
||||
}
|
||||
},
|
||||
|
||||
// Новости - открытая статья
|
||||
'/news-open': {
|
||||
title: 'Новости - Protek',
|
||||
description: 'Читайте актуальные новости и статьи от компании Protek о мире автозапчастей.',
|
||||
keywords: 'новости protek, статьи, автозапчасти новости',
|
||||
ogTitle: 'Новости - Protek',
|
||||
ogDescription: 'Читайте актуальные новости и статьи от компании Protek.'
|
||||
},
|
||||
|
||||
// Главная страница (новая версия)
|
||||
'/home-new': {
|
||||
title: 'Protek - Автозапчасти и аксессуары (новая версия)',
|
||||
description: 'Новый дизайн сайта Protek с улучшенным интерфейсом для поиска автозапчастей и аксессуаров.',
|
||||
keywords: 'автозапчасти, новый дизайн, улучшенный интерфейс, protek',
|
||||
ogTitle: 'Protek - Новая версия сайта',
|
||||
ogDescription: 'Новый дизайн сайта Protek с улучшенным интерфейсом.'
|
||||
},
|
||||
|
||||
// Поиск
|
||||
'/search': {
|
||||
title: 'Поиск запчастей - Protek',
|
||||
description: 'Универсальный поиск автозапчастей по артикулу, VIN коду или модели автомобиля.',
|
||||
keywords: 'поиск запчастей, поиск по артикулу, поиск по VIN, универсальный поиск',
|
||||
ogTitle: 'Поиск запчастей - Protek',
|
||||
ogDescription: 'Универсальный поиск автозапчастей по артикулу, VIN коду или модели автомобиля.'
|
||||
},
|
||||
|
||||
// Поиск по артикулу
|
||||
'/article-search': {
|
||||
title: 'Поиск деталей по артикулу - Protek',
|
||||
description: 'Найдите автозапчасти по артикулу или номеру детали. Быстрый и точный поиск в каталоге.',
|
||||
keywords: 'поиск по артикулу, номер детали, поиск запчастей по номеру',
|
||||
ogTitle: 'Поиск деталей по артикулу - Protek',
|
||||
ogDescription: 'Найдите автозапчасти по артикулу или номеру детали.'
|
||||
},
|
||||
|
||||
// Профиль - заказы
|
||||
'/profile-orders': {
|
||||
title: 'Мои заказы - Личный кабинет Protek',
|
||||
description: 'Управляйте своими заказами в личном кабинете. Отслеживайте статус и историю заказов.',
|
||||
keywords: 'мои заказы, личный кабинет, история заказов, статус заказа',
|
||||
ogTitle: 'Мои заказы - Protek',
|
||||
ogDescription: 'Управляйте своими заказами в личном кабинете.'
|
||||
},
|
||||
|
||||
// Профиль - настройки
|
||||
'/profile-set': {
|
||||
title: 'Настройки профиля - Личный кабинет Protek',
|
||||
description: 'Настройки личного кабинета. Управляйте персональными данными и настройками аккаунта.',
|
||||
keywords: 'настройки профиля, личные данные, настройки аккаунта',
|
||||
ogTitle: 'Настройки профиля - Protek',
|
||||
ogDescription: 'Настройки личного кабинета и персональных данных.'
|
||||
},
|
||||
|
||||
// Профиль - адреса
|
||||
'/profile-addresses': {
|
||||
title: 'Мои адреса - Личный кабинет Protek',
|
||||
description: 'Управляйте адресами доставки в личном кабинете. Добавляйте и редактируйте адреса.',
|
||||
keywords: 'адреса доставки, мои адреса, личный кабинет',
|
||||
ogTitle: 'Мои адреса - Protek',
|
||||
ogDescription: 'Управляйте адресами доставки в личном кабинете.'
|
||||
},
|
||||
|
||||
// Профиль - гараж
|
||||
'/profile-gar': {
|
||||
title: 'Мой гараж - Личный кабинет Protek',
|
||||
description: 'Мой гараж - сохраняйте информацию о ваших автомобилях для быстрого подбора запчастей.',
|
||||
keywords: 'мой гараж, мои автомобили, сохраненные авто',
|
||||
ogTitle: 'Мой гараж - Protek',
|
||||
ogDescription: 'Сохраняйте информацию о ваших автомобилях для быстрого подбора запчастей.'
|
||||
},
|
||||
|
||||
// Профиль - история
|
||||
'/profile-history': {
|
||||
title: 'История просмотров - Личный кабинет Protek',
|
||||
description: 'История просмотренных товаров и запчастей. Быстро найдите ранее просмотренные товары.',
|
||||
keywords: 'история просмотров, просмотренные товары, личный кабинет',
|
||||
ogTitle: 'История просмотров - Protek',
|
||||
ogDescription: 'История просмотренных товаров и запчастей.'
|
||||
},
|
||||
|
||||
// VIN поиск (шаг 2)
|
||||
'/vin-step-2': {
|
||||
title: 'Поиск запчастей по VIN - Шаг 2 - Protek',
|
||||
description: 'Второй шаг поиска запчастей по VIN коду. Выберите нужные детали для вашего автомобиля.',
|
||||
keywords: 'VIN поиск шаг 2, выбор деталей, поиск по VIN',
|
||||
ogTitle: 'Поиск запчастей по VIN - Шаг 2',
|
||||
ogDescription: 'Второй шаг поиска запчастей по VIN коду.'
|
||||
},
|
||||
|
||||
|
||||
};
|
||||
|
||||
// Функция для получения meta-тегов по пути
|
||||
|
@ -8,18 +8,15 @@ import AboutIntro from "@/components/about/AboutIntro";
|
||||
import AboutOffers from "@/components/about/AboutOffers";
|
||||
import AboutProtekInfo from "@/components/about/AboutProtekInfo";
|
||||
import AboutHelp from "@/components/about/AboutHelp";
|
||||
import MetaTags from "@/components/MetaTags";
|
||||
import { getMetaByPath } from "@/lib/meta-config";
|
||||
|
||||
export default function About() {
|
||||
const metaData = getMetaByPath('/about');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>About</title>
|
||||
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect" />
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags {...metaData} />
|
||||
<CatalogInfoHeader
|
||||
title="О компании"
|
||||
breadcrumbs={[
|
||||
|
@ -7,6 +7,8 @@ import Footer from "@/components/Footer";
|
||||
import MobileMenuBottomSection from "@/components/MobileMenuBottomSection";
|
||||
import { DOC_FIND_OEM } from "@/lib/graphql";
|
||||
import { LaximoDocFindOEMResult } from "@/types/laximo";
|
||||
import MetaTags from "@/components/MetaTags";
|
||||
import { getMetaByPath } from "@/lib/meta-config";
|
||||
|
||||
const InfoArticleSearch = () => (
|
||||
<section className="section-info">
|
||||
@ -57,14 +59,11 @@ const ArticleSearchPage = () => {
|
||||
const result: LaximoDocFindOEMResult | null = data?.laximoDocFindOEM || null;
|
||||
const hasResults = result && result.details && result.details.length > 0;
|
||||
|
||||
const metaData = getMetaByPath('/article-search');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Поиск деталей по артикулу {searchQuery} - Protek</title>
|
||||
<meta name="description" content={`Результаты поиска деталей по артикулу ${searchQuery}`} />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags {...metaData} />
|
||||
<InfoArticleSearch />
|
||||
<div className="page-wrapper bg-[#F5F8FB] min-h-screen">
|
||||
<div className="flex flex-col px-32 pt-10 pb-16 max-md:px-5">
|
||||
|
@ -1,4 +1,5 @@
|
||||
import Head from "next/head";
|
||||
import MetaTags from "../components/MetaTags";
|
||||
import { getMetaByPath, createProductMeta } from "../lib/meta-config";
|
||||
import { useRouter } from "next/router";
|
||||
import { useEffect, useState, useMemo } from "react";
|
||||
import { useQuery, useLazyQuery } from "@apollo/client";
|
||||
@ -190,14 +191,21 @@ export default function CardPage() {
|
||||
setVisibleOffersCount(INITIAL_OFFERS_COUNT); // Сбрасываем к начальному количеству
|
||||
};
|
||||
|
||||
// Создаем meta-теги
|
||||
const metaConfig = result ? createProductMeta({
|
||||
name: result.name,
|
||||
brand: result.brand,
|
||||
articleNumber: result.articleNumber,
|
||||
price: allOffers.length > 0 ? Math.min(...allOffers.map(offer => offer.sortPrice)) : undefined
|
||||
}) : getMetaByPath('/card');
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Загрузка товара - Protek</title>
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags
|
||||
title="Загрузка товара - Protek"
|
||||
description="Загрузка информации о товаре..."
|
||||
/>
|
||||
<main className="min-h-screen bg-gray-50 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<div className="animate-spin rounded-full h-32 w-32 border-b-2 border-red-600 mx-auto"></div>
|
||||
@ -211,14 +219,13 @@ export default function CardPage() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{result ? `${result.brand} ${result.articleNumber} - ${result.name}` : `Карточка товара`} - Protek</title>
|
||||
<meta name="description" content={`Подробная информация о товаре ${result?.name}`} />
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect" />
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
|
||||
<link href="/images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="/images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags
|
||||
title={metaConfig.title}
|
||||
description={metaConfig.description}
|
||||
keywords={metaConfig.keywords}
|
||||
ogTitle={metaConfig.ogTitle}
|
||||
ogDescription={metaConfig.ogDescription}
|
||||
/>
|
||||
<InfoCard
|
||||
brand={result ? result.brand : brandQuery}
|
||||
articleNumber={result ? result.articleNumber : searchQuery}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React from "react";
|
||||
import Head from "next/head";
|
||||
import MetaTags from "../components/MetaTags";
|
||||
import { getMetaByPath } from "../lib/meta-config";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import CatalogSubscribe from "@/components/CatalogSubscribe";
|
||||
@ -10,15 +11,17 @@ import CartSummary2 from "../components/CartSummary2";
|
||||
import MobileMenuBottomSection from "../components/MobileMenuBottomSection";
|
||||
|
||||
export default function CartStep2() {
|
||||
const metaConfig = getMetaByPath('/cart-step-2');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Cart Step 2</title>
|
||||
<meta name="description" content="Cart Step 2" />
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags
|
||||
title={metaConfig.title}
|
||||
description={metaConfig.description}
|
||||
keywords={metaConfig.keywords}
|
||||
ogTitle={metaConfig.ogTitle}
|
||||
ogDescription={metaConfig.ogDescription}
|
||||
/>
|
||||
|
||||
<CartInfo />
|
||||
<section className="main">
|
||||
|
@ -8,19 +8,16 @@ import CartRecommended from "../components/CartRecommended";
|
||||
import CatalogSubscribe from "@/components/CatalogSubscribe";
|
||||
import MobileMenuBottomSection from "@/components/MobileMenuBottomSection";
|
||||
import React, { useState } from "react";
|
||||
import MetaTags from "@/components/MetaTags";
|
||||
import { getMetaByPath } from "@/lib/meta-config";
|
||||
|
||||
export default function CartPage() {
|
||||
const [step, setStep] = useState(1);
|
||||
const metaData = getMetaByPath('/cart');
|
||||
|
||||
return (
|
||||
<><Head>
|
||||
<title>Cart</title>
|
||||
<meta name="description" content="Cart" />
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect" />
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<>
|
||||
<MetaTags {...metaData} />
|
||||
|
||||
<CartInfo />
|
||||
|
||||
|
@ -1,14 +1,20 @@
|
||||
import Head from "next/head";
|
||||
import MetaTags from "../components/MetaTags";
|
||||
import { getMetaByPath } from "../lib/meta-config";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
|
||||
export default function Checkout() {
|
||||
const metaConfig = getMetaByPath('/checkout');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Checkout</title>
|
||||
<meta name="description" content="Checkout" />
|
||||
</Head>
|
||||
<MetaTags
|
||||
title={metaConfig.title}
|
||||
description={metaConfig.description}
|
||||
keywords={metaConfig.keywords}
|
||||
ogTitle={metaConfig.ogTitle}
|
||||
ogDescription={metaConfig.ogDescription}
|
||||
/>
|
||||
<Header />
|
||||
{/* Вставь сюда содержимое <body> из checkout.html, преобразовав в JSX. Все пути к картинкам и svg поменяй на /images/... */}
|
||||
{/* Пример: <img src="/images/logo.svg" ... /> */}
|
||||
|
@ -1,14 +1,20 @@
|
||||
import Head from "next/head";
|
||||
import MetaTags from "../components/MetaTags";
|
||||
import { getMetaByPath } from "../lib/meta-config";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
|
||||
export default function DetailCategory() {
|
||||
const metaConfig = getMetaByPath('/detail_category');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Detail Category</title>
|
||||
<meta name="description" content="Detail Category" />
|
||||
</Head>
|
||||
<MetaTags
|
||||
title={metaConfig.title}
|
||||
description={metaConfig.description}
|
||||
keywords={metaConfig.keywords}
|
||||
ogTitle={metaConfig.ogTitle}
|
||||
ogDescription={metaConfig.ogDescription}
|
||||
/>
|
||||
<Header />
|
||||
{/* Вставь сюда содержимое <body> из detail_category.html, преобразовав в JSX. Все пути к картинкам и svg поменяй на /images/... */}
|
||||
{/* Пример: <img src="/images/logo.svg" ... /> */}
|
||||
|
@ -1,14 +1,20 @@
|
||||
import Head from "next/head";
|
||||
import MetaTags from "../components/MetaTags";
|
||||
import { getMetaByPath } from "../lib/meta-config";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
|
||||
export default function DetailProduct() {
|
||||
const metaConfig = getMetaByPath('/detail_product');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Detail Product</title>
|
||||
<meta name="description" content="Detail Product" />
|
||||
</Head>
|
||||
<MetaTags
|
||||
title={metaConfig.title}
|
||||
description={metaConfig.description}
|
||||
keywords={metaConfig.keywords}
|
||||
ogTitle={metaConfig.ogTitle}
|
||||
ogDescription={metaConfig.ogDescription}
|
||||
/>
|
||||
<Header />
|
||||
{/* Вставь сюда содержимое <body> из detail_product.html, преобразовав в JSX. Все пути к картинкам и svg поменяй на /images/... */}
|
||||
{/* Пример: <img src="/images/logo.svg" ... /> */}
|
||||
|
@ -1,14 +1,20 @@
|
||||
import Head from "next/head";
|
||||
import MetaTags from "../components/MetaTags";
|
||||
import { getMetaByPath } from "../lib/meta-config";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
|
||||
export default function DetailSku() {
|
||||
const metaConfig = getMetaByPath('/detail_sku');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Detail SKU</title>
|
||||
<meta name="description" content="Detail SKU" />
|
||||
</Head>
|
||||
<MetaTags
|
||||
title={metaConfig.title}
|
||||
description={metaConfig.description}
|
||||
keywords={metaConfig.keywords}
|
||||
ogTitle={metaConfig.ogTitle}
|
||||
ogDescription={metaConfig.ogDescription}
|
||||
/>
|
||||
<Header />
|
||||
{/* Вставь сюда содержимое <body> из detail_sku.html, преобразовав в JSX. Все пути к картинкам и svg поменяй на /images/... */}
|
||||
{/* Пример: <img src="/images/logo.svg" ... /> */}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import Head from "next/head";
|
||||
import MetaTags from "../components/MetaTags";
|
||||
import { getMetaByPath } from "../lib/meta-config";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import CatalogSubscribe from "@/components/CatalogSubscribe";
|
||||
@ -19,6 +20,8 @@ export default function Favorite() {
|
||||
const [sortBy, setSortBy] = useState<'name' | 'brand' | 'date'>('date');
|
||||
const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc');
|
||||
|
||||
const metaConfig = getMetaByPath('/favorite');
|
||||
|
||||
// Создаем динамические фильтры на основе данных избранного
|
||||
const dynamicFilters: FilterConfig[] = useMemo(() => {
|
||||
const filters: FilterConfig[] = [];
|
||||
@ -96,13 +99,13 @@ export default function Favorite() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Избранное - Protek Auto</title>
|
||||
<meta name="description" content="Ваши избранные товары" />
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags
|
||||
title={metaConfig.title}
|
||||
description={metaConfig.description}
|
||||
keywords={metaConfig.keywords}
|
||||
ogTitle={metaConfig.ogTitle}
|
||||
ogDescription={metaConfig.ogDescription}
|
||||
/>
|
||||
<FavoriteInfo />
|
||||
<section className="main">
|
||||
|
||||
|
@ -13,17 +13,15 @@ import TopSalesSection from "@/components/index/TopSalesSection";
|
||||
import PromoImagesSection from "@/components/index/PromoImagesSection";
|
||||
import NewArrivalsSection from '@/components/index/NewArrivalsSection';
|
||||
import SupportVinSection from '@/components/index/SupportVinSection';
|
||||
import MetaTags from "@/components/MetaTags";
|
||||
import { getMetaByPath } from "@/lib/meta-config";
|
||||
|
||||
export default function HomeNew () {
|
||||
const metaData = getMetaByPath('/home-new');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Home New</title>
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect" />
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags {...metaData} />
|
||||
<IndexTopMenuNav />
|
||||
<ProductOfDaySection />
|
||||
<CategoryNavSection />
|
||||
|
@ -6,23 +6,19 @@ import MobileMenuBottomSection from "@/components/MobileMenuBottomSection";
|
||||
import InfoNewsOpen from "@/components/news-open/InfoNewsOpen";
|
||||
import ContentNews from "@/components/news-open/ContentNews";
|
||||
import NewsCard from "@/components/news/NewsCard";
|
||||
import MetaTags from "@/components/MetaTags";
|
||||
import { getMetaByPath } from "@/lib/meta-config";
|
||||
|
||||
export default function NewsOpen() {
|
||||
const metaData = getMetaByPath('/news-open');
|
||||
|
||||
return (
|
||||
<>
|
||||
<MetaTags {...metaData} />
|
||||
<Head>
|
||||
<title>news open</title>
|
||||
<meta content="news open" property="og:title" />
|
||||
<meta content="news open" property="twitter:title" />
|
||||
<meta content="width=device-width, initial-scale=1" name="viewport" />
|
||||
<meta content="Webflow" name="generator" />
|
||||
<link href="/css/normalize.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/css/webflow.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/css/protekproject.webflow.css" rel="stylesheet" type="text/css" />
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect" />
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<InfoNewsOpen />
|
||||
<section className="main">
|
||||
|
@ -1,4 +1,5 @@
|
||||
import Head from "next/head";
|
||||
import MetaTags from "../components/MetaTags";
|
||||
import { getMetaByPath } from "../lib/meta-config";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import CatalogSubscribe from "@/components/CatalogSubscribe";
|
||||
@ -8,16 +9,17 @@ import NewsCard from "@/components/news/NewsCard";
|
||||
import MobileMenuBottomSection from "@/components/MobileMenuBottomSection";
|
||||
|
||||
export default function News() {
|
||||
const metaConfig = getMetaByPath('/news');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>News</title>
|
||||
<meta name="description" content="News" />
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect" />
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags
|
||||
title={metaConfig.title}
|
||||
description={metaConfig.description}
|
||||
keywords={metaConfig.keywords}
|
||||
ogTitle={metaConfig.ogTitle}
|
||||
ogDescription={metaConfig.ogDescription}
|
||||
/>
|
||||
<InfoNews />
|
||||
<section className="main">
|
||||
<div className="w-layout-blockcontainer container w-container">
|
||||
|
@ -1,14 +1,20 @@
|
||||
import Head from "next/head";
|
||||
import MetaTags from "../components/MetaTags";
|
||||
import { getMetaByPath } from "../lib/meta-config";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
|
||||
export default function OrderConfirmation() {
|
||||
const metaConfig = getMetaByPath('/order-confirmation');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Order Confirmation</title>
|
||||
<meta name="description" content="Order Confirmation" />
|
||||
</Head>
|
||||
<MetaTags
|
||||
title={metaConfig.title}
|
||||
description={metaConfig.description}
|
||||
keywords={metaConfig.keywords}
|
||||
ogTitle={metaConfig.ogTitle}
|
||||
ogDescription={metaConfig.ogDescription}
|
||||
/>
|
||||
<Header />
|
||||
{/* Вставь сюда содержимое <body> из order-confirmation.html, преобразовав в JSX. Все пути к картинкам и svg поменяй на /images/... */}
|
||||
{/* Пример: <img src="/images/logo.svg" ... /> */}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Head from "next/head";
|
||||
import MetaTags from "../../components/MetaTags";
|
||||
import { getMetaByPath } from "../../lib/meta-config";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import { useRouter } from "next/router";
|
||||
@ -30,16 +31,17 @@ export default function PaymentCancelled() {
|
||||
router.push('/catalog');
|
||||
};
|
||||
|
||||
const metaConfig = getMetaByPath('/payment/cancelled');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Оплата отменена - Protekauto</title>
|
||||
<meta name="description" content="Оплата заказа была отменена" />
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect" />
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
|
||||
<link href="/images/favicon.ico" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="/images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags
|
||||
title={metaConfig.title}
|
||||
description={metaConfig.description}
|
||||
keywords={metaConfig.keywords}
|
||||
ogTitle={metaConfig.ogTitle}
|
||||
ogDescription={metaConfig.ogDescription}
|
||||
/>
|
||||
|
||||
<Header />
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Head from "next/head";
|
||||
import MetaTags from "../../components/MetaTags";
|
||||
import { getMetaByPath } from "../../lib/meta-config";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import { useRouter } from "next/router";
|
||||
@ -40,16 +41,17 @@ export default function PaymentFailed() {
|
||||
router.push('/catalog');
|
||||
};
|
||||
|
||||
const metaConfig = getMetaByPath('/payment/failed');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Ошибка оплаты - Protekauto</title>
|
||||
<meta name="description" content="Произошла ошибка при оплате заказа" />
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect" />
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
|
||||
<link href="/images/favicon.ico" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="/images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags
|
||||
title={metaConfig.title}
|
||||
description={metaConfig.description}
|
||||
keywords={metaConfig.keywords}
|
||||
ogTitle={metaConfig.ogTitle}
|
||||
ogDescription={metaConfig.ogDescription}
|
||||
/>
|
||||
|
||||
<Header />
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import Head from 'next/head';
|
||||
import MetaTags from "../../components/MetaTags";
|
||||
import { getMetaByPath } from "../../lib/meta-config";
|
||||
|
||||
const InvoicePage: React.FC = () => {
|
||||
const router = useRouter();
|
||||
@ -20,12 +21,17 @@ const InvoicePage: React.FC = () => {
|
||||
router.push('/profile/orders');
|
||||
};
|
||||
|
||||
const metaConfig = getMetaByPath('/payment/invoice');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Счёт на оплату - Протек Авто</title>
|
||||
<meta name="description" content="Счёт на оплату заказа" />
|
||||
</Head>
|
||||
<MetaTags
|
||||
title={metaConfig.title}
|
||||
description={metaConfig.description}
|
||||
keywords={metaConfig.keywords}
|
||||
ogTitle={metaConfig.ogTitle}
|
||||
ogDescription={metaConfig.ogDescription}
|
||||
/>
|
||||
|
||||
<div className="w-layout-vflex" style={{
|
||||
minHeight: '100vh',
|
||||
|
@ -1,11 +1,12 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Head from "next/head";
|
||||
import Footer from "@/components/Footer";
|
||||
import { useRouter } from "next/router";
|
||||
import { useMutation, ApolloProvider } from "@apollo/client";
|
||||
import { gql } from "@apollo/client";
|
||||
import { apolloClient } from "@/lib/apollo";
|
||||
import toast from "react-hot-toast";
|
||||
import MetaTags from "../../components/MetaTags";
|
||||
import { getMetaByPath } from "../../lib/meta-config";
|
||||
|
||||
const CONFIRM_PAYMENT = gql`
|
||||
mutation ConfirmPayment($orderId: ID!) {
|
||||
@ -74,17 +75,6 @@ function PaymentSuccessContent() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Оплата прошла успешно - Protekauto</title>
|
||||
<meta name="description" content="Ваш заказ успешно оплачен" />
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect" />
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
|
||||
<link href="/images/favicon.ico" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="/images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
|
||||
|
||||
|
||||
<div className="w-layout-blockcontainer container info w-container">
|
||||
<div className="w-layout-vflex flex-block-9">
|
||||
<div className="w-layout-hflex flex-block-7">
|
||||
@ -211,9 +201,20 @@ function PaymentSuccessContent() {
|
||||
}
|
||||
|
||||
export default function PaymentSuccess() {
|
||||
const metaConfig = getMetaByPath('/payment/success');
|
||||
|
||||
return (
|
||||
<ApolloProvider client={apolloClient}>
|
||||
<PaymentSuccessContent />
|
||||
</ApolloProvider>
|
||||
<>
|
||||
<MetaTags
|
||||
title={metaConfig.title}
|
||||
description={metaConfig.description}
|
||||
keywords={metaConfig.keywords}
|
||||
ogTitle={metaConfig.ogTitle}
|
||||
ogDescription={metaConfig.ogDescription}
|
||||
/>
|
||||
<ApolloProvider client={apolloClient}>
|
||||
<PaymentSuccessContent />
|
||||
</ApolloProvider>
|
||||
</>
|
||||
);
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import Head from "next/head";
|
||||
import MetaTags from "../components/MetaTags";
|
||||
import { getMetaByPath } from "../lib/meta-config";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
import CatalogSubscribe from "@/components/CatalogSubscribe";
|
||||
@ -10,12 +11,17 @@ import DeliveryInfo from "@/components/payments/DeliveryInfo";
|
||||
import PaymentsCompony from "@/components/payments/PaymentsCompony";
|
||||
|
||||
export default function PaymentsMethod() {
|
||||
const metaConfig = getMetaByPath('/payments-method');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Payments Method</title>
|
||||
<meta name="description" content="Payments Method" />
|
||||
</Head>
|
||||
<MetaTags
|
||||
title={metaConfig.title}
|
||||
description={metaConfig.description}
|
||||
keywords={metaConfig.keywords}
|
||||
ogTitle={metaConfig.ogTitle}
|
||||
ogDescription={metaConfig.ogDescription}
|
||||
/>
|
||||
<InfoPayments />
|
||||
|
||||
<section className="main">
|
||||
|
@ -12,7 +12,8 @@ import LKMenu from '@/components/LKMenu';
|
||||
import ProfileActsMain from '@/components/profile/ProfileActsMain';
|
||||
import ProfileInfo from '@/components/profile/ProfileInfo';
|
||||
import NotificationMane from "@/components/profile/NotificationMane";
|
||||
import Head from "next/head";
|
||||
import MetaTags from "../components/MetaTags";
|
||||
import { getMetaByPath } from "../lib/meta-config";
|
||||
|
||||
const ProfileActsPage = () => {
|
||||
const router = useRouter();
|
||||
@ -59,13 +60,13 @@ const ProfileActsPage = () => {
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>ProfileActs</title>
|
||||
<meta content="ProfileActs" property="og:title" />
|
||||
<meta content="ProfileActs" property="twitter:title" />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags
|
||||
title={getMetaByPath('/profile-acts').title}
|
||||
description={getMetaByPath('/profile-acts').description}
|
||||
keywords={getMetaByPath('/profile-acts').keywords}
|
||||
ogTitle={getMetaByPath('/profile-acts').ogTitle}
|
||||
ogDescription={getMetaByPath('/profile-acts').ogDescription}
|
||||
/>
|
||||
<ProfileInfo />
|
||||
<div className="flex flex-col pt-10 pb-16 max-md:px-5">
|
||||
<div className="flex relative gap-8 items-start self-stretch max-md:gap-5 max-sm:flex-col max-sm:gap-4 justify-center mx-auto max-w-[1580px] w-full h-full">
|
||||
|
@ -7,19 +7,17 @@ import LKMenu from '@/components/LKMenu';
|
||||
import ProfileAddressesMain from '@/components/profile/ProfileAddressesMain';
|
||||
import ProfileInfo from '@/components/profile/ProfileInfo';
|
||||
import Head from "next/head";
|
||||
import MetaTags from "@/components/MetaTags";
|
||||
import { getMetaByPath } from "@/lib/meta-config";
|
||||
|
||||
|
||||
|
||||
const ProfileAddressesPage = () => {
|
||||
const metaData = getMetaByPath('/profile-addresses');
|
||||
|
||||
return (
|
||||
<div className="page-wrapper">
|
||||
<Head>
|
||||
<title>ProfileAddresses</title>
|
||||
<meta content="ProfileAddresses" property="og:title" />
|
||||
<meta content="ProfileAddresses" property="twitter:title" />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags {...metaData} />
|
||||
<ProfileInfo />
|
||||
<div className="flex flex-col pt-10 pb-16 max-md:px-5">
|
||||
|
||||
|
@ -10,7 +10,8 @@ import MobileMenuBottomSection from "@/components/MobileMenuBottomSection";
|
||||
import LKMenu from '@/components/LKMenu';
|
||||
import ProfileBalanceMain from '@/components/profile/ProfileBalanceMain';
|
||||
import ProfileInfo from '@/components/profile/ProfileInfo';
|
||||
import Head from "next/head";
|
||||
import MetaTags from "../components/MetaTags";
|
||||
import { getMetaByPath } from "../lib/meta-config";
|
||||
|
||||
const ProfileBalancePage = () => {
|
||||
const router = useRouter();
|
||||
@ -56,15 +57,17 @@ const ProfileBalancePage = () => {
|
||||
);
|
||||
}
|
||||
|
||||
const metaConfig = getMetaByPath('/profile-balance');
|
||||
|
||||
return (
|
||||
<div className="page-wrapper">
|
||||
<Head>
|
||||
<title>ProfileBalance</title>
|
||||
<meta content="ProfileBalance" property="og:title" />
|
||||
<meta content="ProfileBalance" property="twitter:title" />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags
|
||||
title={metaConfig.title}
|
||||
description={metaConfig.description}
|
||||
keywords={metaConfig.keywords}
|
||||
ogTitle={metaConfig.ogTitle}
|
||||
ogDescription={metaConfig.ogDescription}
|
||||
/>
|
||||
<ProfileInfo />
|
||||
<div className="flex flex-col pt-10 pb-16 max-md:px-5">
|
||||
<div className="flex relative gap-8 items-start self-stretch max-md:gap-5 max-sm:flex-col max-sm:gap-4 justify-center mx-auto max-w-[1580px] w-full h-full">
|
||||
|
@ -7,19 +7,17 @@ import LKMenu from '@/components/LKMenu';
|
||||
import ProfileGarageMain from '@/components/profile/ProfileGarageMain';
|
||||
import ProfileInfo from '@/components/profile/ProfileInfo';
|
||||
import Head from "next/head";
|
||||
import MetaTags from "@/components/MetaTags";
|
||||
import { getMetaByPath } from "@/lib/meta-config";
|
||||
|
||||
|
||||
|
||||
const ProfileGaragePage = () => {
|
||||
const metaData = getMetaByPath('/profile-gar');
|
||||
|
||||
return (
|
||||
<div className="page-wrapper">
|
||||
<Head>
|
||||
<title>ProfileGarage</title>
|
||||
<meta content="ProfileGarage" property="og:title" />
|
||||
<meta content="ProfileGarage" property="twitter:title" />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags {...metaData} />
|
||||
<ProfileInfo />
|
||||
<div className="flex flex-col pt-10 pb-16 max-md:px-5">
|
||||
|
||||
|
@ -7,6 +7,8 @@ import LKMenu from '@/components/LKMenu';
|
||||
import ProfileHistoryMain from '@/components/profile/ProfileHistoryMain';
|
||||
import ProfileInfo from '@/components/profile/ProfileInfo';
|
||||
import Head from "next/head";
|
||||
import MetaTags from "@/components/MetaTags";
|
||||
import { getMetaByPath } from "@/lib/meta-config";
|
||||
|
||||
|
||||
|
||||
@ -29,15 +31,11 @@ const ProfileHistoryPage = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
const metaData = getMetaByPath('/profile-history');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>ProfileHistory</title>
|
||||
<meta content="ProfileHistory" property="og:title" />
|
||||
<meta content="ProfileHistory" property="twitter:title" />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags {...metaData} />
|
||||
<div className="page-wrapper h-full flex flex-col flex-1">
|
||||
<ProfileInfo />
|
||||
<div className="flex flex-col pt-10 pb-16 max-md:px-5 h-full flex-1">
|
||||
|
@ -8,20 +8,18 @@ import LKMenu from '@/components/LKMenu';
|
||||
import ProfileOrdersMain from '@/components/profile/ProfileOrdersMain';
|
||||
import ProfileInfo from '@/components/profile/ProfileInfo';
|
||||
import Head from "next/head";
|
||||
import MetaTags from "@/components/MetaTags";
|
||||
import { getMetaByPath } from "@/lib/meta-config";
|
||||
|
||||
|
||||
|
||||
|
||||
const ProfileOrdersPage = () => {
|
||||
const metaData = getMetaByPath('/profile-orders');
|
||||
|
||||
return (
|
||||
<div className="page-wrapper">
|
||||
<Head>
|
||||
<title>ProfileOrders</title>
|
||||
<meta content="ProfileOrders" property="og:title" />
|
||||
<meta content="ProfileOrders" property="twitter:title" />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags {...metaData} />
|
||||
<ProfileInfo />
|
||||
<div className="flex flex-col pt-10 pb-16 max-md:px-5">
|
||||
|
||||
|
@ -10,7 +10,8 @@ import MobileMenuBottomSection from "@/components/MobileMenuBottomSection";
|
||||
import LKMenu from '@/components/LKMenu';
|
||||
import ProfileRequisitiesMain from '@/components/profile/ProfileRequisitiesMain';
|
||||
import ProfileInfo from '@/components/profile/ProfileInfo';
|
||||
import Head from "next/head";
|
||||
import MetaTags from "../components/MetaTags";
|
||||
import { getMetaByPath } from "../lib/meta-config";
|
||||
|
||||
const ProfileRequisitiesPage = () => {
|
||||
const router = useRouter();
|
||||
@ -55,15 +56,18 @@ const ProfileRequisitiesPage = () => {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const metaConfig = getMetaByPath('/profile-req');
|
||||
|
||||
return (
|
||||
<div className="page-wrapper">
|
||||
<Head>
|
||||
<title>ProfileRequisities</title>
|
||||
<meta content="ProfileRequisities" property="og:title" />
|
||||
<meta content="ProfileRequisities" property="twitter:title" />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags
|
||||
title={metaConfig.title}
|
||||
description={metaConfig.description}
|
||||
keywords={metaConfig.keywords}
|
||||
ogTitle={metaConfig.ogTitle}
|
||||
ogDescription={metaConfig.ogDescription}
|
||||
/>
|
||||
<ProfileInfo />
|
||||
<div className="flex flex-col pt-10 pb-16 max-md:px-5">
|
||||
|
||||
|
@ -7,19 +7,17 @@ import LKMenu from '@/components/LKMenu';
|
||||
import ProfileSettingsMain from '@/components/profile/ProfileSettingsMain';
|
||||
import ProfileInfo from '@/components/profile/ProfileInfo';
|
||||
import Head from "next/head";
|
||||
import MetaTags from "@/components/MetaTags";
|
||||
import { getMetaByPath } from "@/lib/meta-config";
|
||||
|
||||
|
||||
|
||||
const ProfileSettingsPage = () => {
|
||||
const metaData = getMetaByPath('/profile-set');
|
||||
|
||||
return (
|
||||
<div className="page-wrapper h-full flex flex-col flex-1">
|
||||
<Head>
|
||||
<title>ProfileHistory</title>
|
||||
<meta content="ProfileSettings" property="og:title" />
|
||||
<meta content="ProfileSettings" property="twitter:title" />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags {...metaData} />
|
||||
<ProfileInfo />
|
||||
<div className="flex flex-col pt-10 pb-16 max-md:px-5">
|
||||
|
||||
|
@ -7,6 +7,8 @@ import Footer from '@/components/Footer';
|
||||
import MobileMenuBottomSection from '@/components/MobileMenuBottomSection';
|
||||
import { DOC_FIND_OEM, FIND_LAXIMO_VEHICLES_BY_PART_NUMBER } from '@/lib/graphql';
|
||||
import { LaximoDocFindOEMResult, LaximoVehiclesByPartResult, LaximoVehicleSearchResult } from '@/types/laximo';
|
||||
import MetaTags from '@/components/MetaTags';
|
||||
import { getMetaByPath } from '@/lib/meta-config';
|
||||
|
||||
type SearchMode = 'parts' | 'vehicles';
|
||||
|
||||
@ -98,14 +100,11 @@ const SearchPage = () => {
|
||||
const hasPartsResults = partsResult && partsResult.details && partsResult.details.length > 0;
|
||||
const hasVehiclesResults = vehiclesResult && vehiclesResult.totalVehicles > 0;
|
||||
|
||||
const metaData = getMetaByPath('/search');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Поиск по артикулу {searchQuery} - Protek</title>
|
||||
<meta name="description" content={`Результаты поиска по артикулу ${searchQuery}`} />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags {...metaData} />
|
||||
<InfoSearch />
|
||||
<div className="page-wrapper bg-[#F5F8FB] min-h-screen">
|
||||
<div className="flex flex-col pt-10 pb-16 max-md:px-5">
|
||||
|
@ -7,6 +7,8 @@ import Footer from '@/components/Footer';
|
||||
import VehicleSearchSection from '../../components/VehicleSearchSection';
|
||||
import { GET_LAXIMO_CATALOG_INFO } from '@/lib/graphql';
|
||||
import { LaximoCatalogInfo } from '@/types/laximo';
|
||||
import MetaTags from '@/components/MetaTags';
|
||||
import { getMetaByPath } from '@/lib/meta-config';
|
||||
|
||||
const VehicleSearchPage = () => {
|
||||
const router = useRouter();
|
||||
@ -69,12 +71,11 @@ const VehicleSearchPage = () => {
|
||||
|
||||
const catalogInfo = catalogData.laximoCatalogInfo;
|
||||
|
||||
const metaData = getMetaByPath('/vehicle-search');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Поиск автомобиля - {catalogInfo.name}</title>
|
||||
<meta name="description" content={`Поиск автомобилей ${catalogInfo.name} для подбора запчастей`} />
|
||||
</Head>
|
||||
<MetaTags {...metaData} />
|
||||
<Header />
|
||||
|
||||
<main className="min-h-screen bg-gray-50">
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useQuery } from '@apollo/client';
|
||||
import Head from 'next/head';
|
||||
|
||||
import Footer from '@/components/Footer';
|
||||
import Layout from '@/components/Layout';
|
||||
import VehiclePartsSearchSection from '@/components/VehiclePartsSearchSection';
|
||||
@ -212,9 +212,10 @@ const VehicleDetailsPage = () => {
|
||||
if (vehicleLoading) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Загрузка автомобиля...</title>
|
||||
</Head>
|
||||
<MetaTags
|
||||
title="Загрузка автомобиля..."
|
||||
description="Загружаем информацию об автомобиле..."
|
||||
/>
|
||||
<div style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#f9fafb' }}>
|
||||
<div className="text-center">
|
||||
<div className="animate-spin rounded-full h-32 w-32 border-b-2 border-red-600 mx-auto"></div>
|
||||
@ -229,9 +230,10 @@ const VehicleDetailsPage = () => {
|
||||
if (!catalogData?.laximoCatalogInfo) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Каталог не найден</title>
|
||||
</Head>
|
||||
<MetaTags
|
||||
title="Каталог не найден"
|
||||
description="Информация о каталоге недоступна"
|
||||
/>
|
||||
<main className="min-h-screen bg-gray-50 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<h1 className="text-2xl font-bold text-gray-900 mb-4">Каталог не найден</h1>
|
||||
|
@ -6,6 +6,8 @@ import Header from '@/components/Header';
|
||||
import Footer from '@/components/Footer';
|
||||
import { GET_LAXIMO_CATALOG_INFO, SEARCH_LAXIMO_OEM } from '@/lib/graphql';
|
||||
import { LaximoCatalogInfo, LaximoOEMResult } from '@/types/laximo';
|
||||
import MetaTags from '@/components/MetaTags';
|
||||
import { getMetaByPath } from '@/lib/meta-config';
|
||||
|
||||
const InfoPartDetail = ({ brandName, oemNumber }: { brandName: string; oemNumber: string }) => (
|
||||
<section className="section-info">
|
||||
@ -121,12 +123,11 @@ const PartDetailPage = () => {
|
||||
const totalDetails = oemResult?.categories.reduce((total, cat) =>
|
||||
total + cat.units.reduce((unitTotal, unit) => unitTotal + unit.details.length, 0), 0) || 0;
|
||||
|
||||
const metaData = getMetaByPath('/vehicle-search');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Деталь {oemNumber} - {catalogInfo?.name || 'Каталог запчастей'}</title>
|
||||
<meta name="description" content={`Подробная информация о детали ${oemNumber} в каталоге ${catalogInfo?.name}`} />
|
||||
</Head>
|
||||
<MetaTags {...metaData} />
|
||||
<Header />
|
||||
<div className="bg-[#F5F8FB] min-h-screen w-full">
|
||||
<InfoPartDetail brandName={catalogInfo?.name || String(brand)} oemNumber={String(oemNumber)} />
|
||||
|
@ -7,6 +7,8 @@ import Footer from '@/components/Footer';
|
||||
import MobileMenuBottomSection from '@/components/MobileMenuBottomSection';
|
||||
import { GET_BRANDS_BY_CODE, GET_LAXIMO_CATALOG_INFO } from '@/lib/graphql';
|
||||
import { LaximoCatalogInfo } from '@/types/laximo';
|
||||
import MetaTags from '@/components/MetaTags';
|
||||
import { getMetaByPath } from '@/lib/meta-config';
|
||||
|
||||
const InfoBrandSelection = ({
|
||||
brandName,
|
||||
@ -115,14 +117,11 @@ const BrandSelectionPage = () => {
|
||||
router.back();
|
||||
};
|
||||
|
||||
return (
|
||||
const metaData = getMetaByPath('/vehicle-search');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Выбор производителя для {oemNumber} - {catalogInfo?.name || 'Каталог запчастей'}</title>
|
||||
<meta name="description" content={`Выберите производителя для детали ${oemNumber} в каталоге ${catalogInfo?.name}`} />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<MetaTags {...metaData} />
|
||||
<InfoBrandSelection
|
||||
brandName={catalogInfo?.name || String(brand)}
|
||||
oemNumber={String(oemNumber)}
|
||||
|
@ -6,6 +6,8 @@ import Header from '@/components/Header';
|
||||
import Footer from '@/components/Footer';
|
||||
import { FIND_LAXIMO_VEHICLES_BY_PART_NUMBER } from '@/lib/graphql';
|
||||
import { LaximoVehiclesByPartResult, LaximoVehicleSearchResult } from '@/types/laximo';
|
||||
import MetaTags from "../components/MetaTags";
|
||||
import { getMetaByPath } from "../lib/meta-config";
|
||||
|
||||
const VehiclesByPartPage = () => {
|
||||
const router = useRouter();
|
||||
@ -46,12 +48,15 @@ const VehiclesByPartPage = () => {
|
||||
router.back();
|
||||
};
|
||||
|
||||
const metaConfig = getMetaByPath('/vehicles-by-part');
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Поиск автомобилей по артикулу {cleanPartNumber} - Protek</title>
|
||||
</Head>
|
||||
<MetaTags
|
||||
title="Поиск автомобилей по артикулу - Protek"
|
||||
description="Поиск автомобилей, в которых используется деталь..."
|
||||
/>
|
||||
<main className="min-h-screen bg-gray-50 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<div className="animate-spin rounded-full h-32 w-32 border-b-2 border-red-600 mx-auto"></div>
|
||||
@ -66,9 +71,10 @@ const VehiclesByPartPage = () => {
|
||||
if (error || !data?.laximoFindVehiclesByPartNumber) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Ошибка поиска - Protek</title>
|
||||
</Head>
|
||||
<MetaTags
|
||||
title="Ошибка поиска - Protek"
|
||||
description="Произошла ошибка при поиске автомобилей по артикулу"
|
||||
/>
|
||||
<main className="min-h-screen bg-gray-50 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<div className="text-red-500 mb-4">
|
||||
@ -100,10 +106,13 @@ const VehiclesByPartPage = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Автомобили по артикулу {cleanPartNumber} - Protek</title>
|
||||
<meta name="description" content={`Найдено ${result.totalVehicles} автомобилей по артикулу ${cleanPartNumber} в ${result.catalogs.length} каталогах`} />
|
||||
</Head>
|
||||
<MetaTags
|
||||
title={cleanPartNumber ? `Автомобили по артикулу ${cleanPartNumber} - Protek` : metaConfig.title}
|
||||
description={cleanPartNumber ? `Поиск автомобилей, в которых используется деталь с артикулом ${cleanPartNumber}` : metaConfig.description}
|
||||
keywords={metaConfig.keywords}
|
||||
ogTitle={metaConfig.ogTitle}
|
||||
ogDescription={metaConfig.ogDescription}
|
||||
/>
|
||||
<Header />
|
||||
|
||||
<main className="min-h-screen bg-gray-50">
|
||||
|
@ -10,6 +10,8 @@ import VinKnot from "@/components/vin/VinKnot";
|
||||
import KnotParts from "@/components/vin/KnotParts";
|
||||
import React, { useState } from "react";
|
||||
import KnotIn from "@/components/vin/KnotIn";
|
||||
import MetaTags from "@/components/MetaTags";
|
||||
import { getMetaByPath } from "@/lib/meta-config";
|
||||
|
||||
|
||||
export default function Vin() {
|
||||
@ -34,21 +36,15 @@ export default function Vin() {
|
||||
return () => document.removeEventListener("click", handler);
|
||||
}, []);
|
||||
|
||||
const metaData = getMetaByPath('/vin-step-2');
|
||||
|
||||
return (
|
||||
<>
|
||||
<MetaTags {...metaData} />
|
||||
<Head>
|
||||
<title>VIN</title>
|
||||
<meta content="vin" property="og:title" />
|
||||
<meta content="vin" property="twitter:title" />
|
||||
<meta content="width=device-width, initial-scale=1" name="viewport" />
|
||||
<meta content="Webflow" name="generator" />
|
||||
<link href="/css/normalize.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/css/webflow.css" rel="stylesheet" type="text/css" />
|
||||
<link href="/css/protekproject.webflow.css" rel="stylesheet" type="text/css" />
|
||||
<link href="https://fonts.googleapis.com" rel="preconnect" />
|
||||
<link href="https://fonts.gstatic.com" rel="preconnect" crossOrigin="anonymous" />
|
||||
<link href="images/favicon.png" rel="shortcut icon" type="image/x-icon" />
|
||||
<link href="images/webclip.png" rel="apple-touch-icon" />
|
||||
</Head>
|
||||
<InfoVin />
|
||||
<section className="main">
|
||||
|
Reference in New Issue
Block a user