feat: add sitemap #7

Merged
redrockjs merged 1 commits from dev into main 2025-12-14 11:46:44 +00:00
21 changed files with 588 additions and 39 deletions

85
.idea/workspace.xml generated
View File

@@ -5,12 +5,19 @@
</component>
<component name="ChangeListManager">
<list default="true" id="2a96f817-9dc2-4f3c-893a-c4974c750774" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/src/shared/const/tracking-service.ts" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/widgets/yandex-metrika/index.ts" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/widgets/yandex-metrika/ui.tsx" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/app/sitemap/page.tsx" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/views/sitemap/index.ts" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/views/sitemap/model/breadcrums.ts" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/views/sitemap/model/links.ts" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/views/sitemap/styles.module.scss" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/views/sitemap/ui.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/app/layout.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/layout.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/widgets/index.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/widgets/index.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/app/ekspertiza/ocenochnaja/page.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/ekspertiza/ocenochnaja/page.tsx" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/shared/api/api.service.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/api/api.service.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/shared/config/routes.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/config/api-routes.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/shared/const/menu.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/const/menu.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/views/index.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/views/index.ts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/widgets/footer/ui.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/widgets/footer/ui.tsx" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -18,15 +25,15 @@
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="DarkyenusTimeTracker">
<option name="totalTimeSeconds" value="247180" />
<option name="totalTimeSeconds" value="251068" />
<option name="gitIntegration" value="true" />
<option name="naggedAbout" value="1" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="SCSS File" />
<option value="TypeScript JSX File" />
<option value="SCSS File" />
<option value="TypeScript File" />
</list>
</option>
@@ -46,36 +53,42 @@
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;ModuleVcsDetector.initialDetectionPerformed&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252&quot;: &quot;true&quot;,
&quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
&quot;RunOnceActivity.typescript.service.memoryLimit.init&quot;: &quot;true&quot;,
&quot;SHARE_PROJECT_CONFIGURATION_FILES&quot;: &quot;true&quot;,
&quot;com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1&quot;: &quot;true&quot;,
&quot;git-widget-placeholder&quot;: &quot;dev&quot;,
&quot;ignore.virus.scanning.warn.message&quot;: &quot;true&quot;,
&quot;javascript.preferred.runtime.type.id&quot;: &quot;node&quot;,
&quot;js.debugger.nextJs.config.created.client&quot;: &quot;true&quot;,
&quot;js.debugger.nextJs.config.created.server&quot;: &quot;true&quot;,
&quot;junie.onboarding.icon.badge.shown&quot;: &quot;true&quot;,
&quot;list.type.of.created.stylesheet&quot;: &quot;SCSS&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;npm.Next.js: server-side.executor&quot;: &quot;Run&quot;,
&quot;prettierjs.PrettierConfiguration.Package&quot;: &quot;C:\\dev-projects\\ocenka-web\\node_modules\\prettier&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;terminal&quot;,
&quot;to.speed.mode.migration.done&quot;: &quot;true&quot;,
&quot;ts.external.directory.path&quot;: &quot;C:\\dev-projects\\ocenka-web\\node_modules\\typescript\\lib&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"ModuleVcsDetector.initialDetectionPerformed": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
"RunOnceActivity.git.unshallow": "true",
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
"com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1": "true",
"git-widget-placeholder": "dev",
"ignore.virus.scanning.warn.message": "true",
"javascript.preferred.runtime.type.id": "node",
"js.debugger.nextJs.config.created.client": "true",
"js.debugger.nextJs.config.created.server": "true",
"junie.onboarding.icon.badge.shown": "true",
"last_opened_file_path": "C:/dev-projects/ocenka-web/src/views/sitemap/model",
"list.type.of.created.stylesheet": "SCSS",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"npm.Next.js: server-side.executor": "Run",
"prettierjs.PrettierConfiguration.Package": "C:\\dev-projects\\ocenka-web\\node_modules\\prettier",
"settings.editor.selected.configurable": "terminal",
"to.speed.mode.migration.done": "true",
"ts.external.directory.path": "C:\\dev-projects\\ocenka-web\\node_modules\\typescript\\lib",
"vue.rearranger.settings.migration": "true"
}
}</component>
}]]></component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="C:\dev-projects\ocenka-web\src\views\sitemap\model" />
<recent name="C:\dev-projects\ocenka-web\src\views\expertise\ocenka" />
<recent name="C:\dev-projects\ocenka-web\src\views\expertise\ocenka\model" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="C:\dev-personal\ocenka-web" />
<recent name="C:\dev-personal\ocenka-web\public\images" />
@@ -127,6 +140,8 @@
<workItem from="1765367128544" duration="6526000" />
<workItem from="1765705116766" duration="506000" />
<workItem from="1765705636949" duration="904000" />
<workItem from="1765708416527" duration="881000" />
<workItem from="1765709337833" duration="2887000" />
</task>
<servers />
</component>

View File

@@ -1,5 +1,33 @@
// TODO Проверить что это за страница
import { Ocenochnaya } from '@/views';
import type { Metadata } from 'next';
import { headers } from 'next/headers';
import { metaInfo, phoneBeautify } from '@shared/lib';
import { TMetainfo } from '@shared/types/metainfo';
import { CONTACTS } from '@shared/const/contacts';
const metainfo: TMetainfo = {
title: 'Оценочная экспертиза',
description: `Проведение оценочной экспертизы. Лицензированные эксперты. Экспертиза принимается судом. Тел.: ${phoneBeautify(CONTACTS.PHONE)}. Предварительный анализ - бесплатно!`,
companyName: CONTACTS.COMPANY_FULL,
phone: phoneBeautify(CONTACTS.PHONE),
ogImageUrl: '/images/opengraph/expertise/ocenka.png',
};
export async function generateMetadata(): Promise<Metadata> {
const h = await headers();
const referer = h.get('referer') ?? '';
const host = h.get('host') ?? '';
const proto = h.get('x-forwarded-proto') ?? '';
const path = referer ? new URL(referer).pathname : '';
const metainfoExtended = Object.assign({}, metainfo, {
host: `${proto}://${host}`,
path: path,
});
return metaInfo(metainfoExtended);
}
export default function Page() {
return <div>Page</div>;
return <Ocenochnaya />;
}

33
src/app/sitemap/page.tsx Normal file
View File

@@ -0,0 +1,33 @@
import { Sitemap } from '@/views';
import type { Metadata } from 'next';
import { headers } from 'next/headers';
import { metaInfo, phoneBeautify } from '@shared/lib';
import { TMetainfo } from '@shared/types/metainfo';
import { CONTACTS } from '@shared/const/contacts';
const metainfo: TMetainfo = {
title: 'Карта сайта',
description: `Услуги оценки имущества и проведение судебных экспертиз Тел.: ${phoneBeautify(CONTACTS.PHONE)}. Предварительный анализ - бесплатно!`,
companyName: CONTACTS.COMPANY_FULL,
phone: phoneBeautify(CONTACTS.PHONE),
ogImageUrl: '/images/opengraph/main.png',
};
export async function generateMetadata(): Promise<Metadata> {
const h = await headers();
const referer = h.get('referer') ?? '';
const host = h.get('host') ?? '';
const proto = h.get('x-forwarded-proto') ?? '';
const path = referer ? new URL(referer).pathname : '';
const metainfoExtended = Object.assign({}, metainfo, {
host: `${proto}://${host}`,
path: path,
});
return metaInfo(metainfoExtended);
}
export default function Page() {
return <Sitemap />;
}

View File

@@ -1,4 +1,4 @@
import { API_ROUTES } from '@shared/config/routes';
import { API_ROUTES } from '@shared/config/api-routes';
import { TBaseForm } from '@shared/api/api.types';
import { CORE } from '@shared/config/core';

View File

@@ -1,4 +1,5 @@
export const API_ROUTES = {
SEND_FORM: '/sendform',
HEARTBEAT: '/heartbeat',
OPENGRAPH_IMAGE: '/og',
} as const;

View File

@@ -19,6 +19,10 @@ export const baseMenu: TMenuItem[] = [
title: 'Трасологическая',
link: ROUTES.EXPERTIZA_TRASOLOGIA,
},
{
title: 'Оценочная',
link: ROUTES.EXPERTIZA_OCENKI,
},
{
title: 'Пожарно-техническая',
link: ROUTES.EXPERTIZA_POZHAR,

View File

@@ -0,0 +1 @@
export * from './ui';

View File

@@ -0,0 +1,27 @@
const documentsData = {
title: 'Цели экспертизы:',
description:
'Оценка рыночной, восстановительной или ликвидационной стоимости:',
docs: [
'движимого имущества: транспорт, оборудование, машины, техника и тд.;',
'недвижимого имущества, в виде объектов коммерческой и жилой недвижимости, земельных участков различного назначения;',
'отдельных материальных ценностей, вещей;',
'бизнеса, пакетов акций, ценных бумаг, финансовых вложений организаций;',
'интеллектуальной собственности, услуг, видов работ, информации, имеющих материальную ценность;',
'прав требования, кредиторской и дебиторской задолженности.',
],
};
const howToData = {
title: 'Заказать экспертизу очень просто',
description:
'Экспертное заключение, полученный от компании «ДИ ТРАСО», будет являться официальным документом, подтверждающим результат работы эксперта. В нем будет содержаться вся полная информация.',
};
const connectData = {
title: 'Как провести кадастровую экспертизу',
description:
'Для того, чтобы заказать выполнение оценочной экспертизы, вы можете воспользоваться любым удобным способом.',
};
export { documentsData, howToData, connectData };

View File

@@ -0,0 +1,14 @@
import { ROUTES } from '@shared/const/route';
export const PAGE_NAME = 'Оценочная экспертиза';
export const breadcrumbData = [
{
name: 'Экспертиза',
path: ROUTES.EXPERTIZA,
},
{
name: PAGE_NAME,
path: '',
},
];

View File

@@ -0,0 +1,8 @@
import { TExpert } from '@shared/types/expert';
import expertPhoto from '@public/images/photo/polinov-andrey.jpg';
export const expertData: TExpert = {
name: 'Полинов Андрей',
position: 'Эксперт, оценщик',
photo: expertPhoto,
};

View File

@@ -0,0 +1,29 @@
import { TRelatedArticles } from '@shared/types/relatedArticles';
import { ROUTES } from '@shared/const/route';
export const relatedArticlesData: TRelatedArticles[] = [
{
title: 'Автотехническая экспертиза',
description:
'При возникновении ситуаций, возникающих в результате ДТП (дорожно-транспортных происшествий), для решения наиболее сложных проблем, требуется проведение специальной автоэкспертизы, позволяющей реализовать право водителя на получение страховки …',
link: ROUTES.EXPERTIZA_AUTOTECH,
},
{
title: 'Документарная экспертиза',
description:
'Если возникают сомнения в подлинности документа, например, завещания или долговой расписки, если Вы не уверены в достоверности реквизитов или подписи на договоре, то Вы вправе обратиться за технической экспертизой документа…',
link: ROUTES.EXPERTIZA_DOCUMENT,
},
{
title: 'Товароведческая экспертиза',
description:
'Судебная экспертиза товаров должна проводиться только специалистом, получившим узкопрофильную квалификацию. Если Вам необходима товароведческая экспертиза и для суда, мы готовы подробно исследовать любой товар. Результат работы…',
link: ROUTES.EXPERTIZA_TOVAR,
},
{
title: 'Рецензия (Проверка) экспертизы',
description:
'Необходимость в составлении рецензии на судебную экспертизу появляется в ситуациях, когда выводы заключения являются не обоснованными, а квалификация и опыт эксперта не вызывают доверия. В ходе рецензирования экспертное заключение проверяется…',
link: ROUTES.EXPERTIZA_RECENZII,
},
];

View File

@@ -0,0 +1,35 @@
import { TSidebar } from '@/shared/types/sidebar';
import { ROUTES } from '@shared/const/route';
const sidebarData: TSidebar = {
estimate: '3',
offer:
'Наш эксперт свяжется с вами для уточнения обстоятельств дела и определения точной стоимости.',
relatedTitle: 'Сопутствующие экспертизы',
related: [
{
title: 'Автотехническая',
link: ROUTES.EXPERTIZA_AUTOTECH,
},
{
title: 'Документарная',
link: ROUTES.EXPERTIZA_DOCUMENT,
},
{
title: 'Товароведческая',
link: ROUTES.EXPERTIZA_TOVAR,
},
{
title: 'Рецензирование (проверка)',
link: ROUTES.EXPERTIZA_RECENZII,
},
],
warrantiesTitle: 'Наши гарантии',
warranties: [
'Эксперты компании являются членами Саморегулируемой организации судебных экспертов',
'Деятельность компании застрахована на 60 000 000 рублей',
'Экспертизы выполняются в соответствии с Федеральными Законодательными Актами',
],
};
export { sidebarData };

View File

@@ -0,0 +1,71 @@
.Container {
margin: 0 auto;
max-width: rem(1540px);
display: grid;
grid-template-columns: auto;
gap: 0;
padding: 0 rem(10px);
@include iftablet {
grid-template-columns: auto;
padding: 0 rem(20px);
}
@include iflaptop {
padding: 0 rem(28px);
gap: rem(40px);
grid-template-columns: auto rem(300px);
}
@include ifdesktop {
grid-template-columns: auto rem(360px);
gap: rem(160px);
padding: 0 rem(40px);
}
}
.Article {
display: flex;
flex-direction: column;
padding: rem(40px) 0;
.Section {
display: block;
}
.Text {
font-family: $font-roboto;
font-weight: 400;
font-size: rem(16px);
line-height: 130%;
color: $color-text;
margin-bottom: rem(16px);
}
.List {
display: flex;
flex-direction: column;
list-style-type: disc;
margin-left: rem(16px);
margin-bottom: rem(16px);
}
.ListItem {
font-family: $font-roboto;
font-weight: 300;
font-size: rem(16px);
line-height: 130%;
color: $color-text;
list-style: unset;
}
.Header {
font-family: $font-roboto;
font-weight: 300;
font-size: rem(32px);
line-height: 130%;
color: $color-text;
margin-bottom: rem(16px);
}
}

View File

@@ -0,0 +1,46 @@
import s from './styles.module.scss';
import { CallbackForm, Connect, OrderSchema } from '@/entities';
import {
Consultation,
Documents,
Partners,
RelatedArticles,
Sidebar,
} from '@/feature/article';
import { Breadcrumbs } from '@/widgets';
import { sidebarData } from './model/sidebar';
import { relatedArticlesData } from './model/related';
import { expertData } from './model/expert';
import { breadcrumbData, PAGE_NAME } from './model/breadcrums';
import { connectData, documentsData, howToData } from './model/article';
function Ocenochnaya() {
return (
<>
<Breadcrumbs breadcrumbs={breadcrumbData} />
<article className={s.Container}>
<div className={s.Article}>
<section className={s.Section}>
<p className={s.Text}>
Судебная оценочная (стоимостная) экспертиза представляет собой вид
экспертизы, главной задачей которой является определение рыночной
стоимости различных объектов оценки. Объектами оценки принято
считать любые объекты, которые имеют материальную ценность.
</p>
</section>
<CallbackForm pageName={PAGE_NAME} />
<Documents {...documentsData} />
<OrderSchema {...howToData} />
<Connect {...connectData} />
</div>
<Sidebar {...sidebarData} pageName={PAGE_NAME} />
</article>
<Consultation {...expertData} pageName={PAGE_NAME} />
<RelatedArticles related={relatedArticlesData} pageName={PAGE_NAME} />
<Partners />
</>
);
}
export { Ocenochnaya };

View File

@@ -1,8 +1,10 @@
// Common
export * from './home';
export * from './contacts';
export * from './privacy-policy';
export * from './cookie';
export * from './user-agreement';
export * from './sitemap';
//Expertise
export * from './expertise/category';
@@ -12,6 +14,7 @@ export * from './expertise/computer';
export * from './expertise/document';
export * from './expertise/finans';
export * from './expertise/kadastr';
export * from './expertise/ocenochnaya';
export * from './expertise/pocherk';
export * from './expertise/pozhar';
export * from './expertise/recenzii';

View File

@@ -0,0 +1 @@
export * from './ui';

View File

@@ -0,0 +1,14 @@
import { ROUTES } from '@shared/const/route';
export const PAGE_NAME = 'Карта сайта';
export const breadcrumbData = [
{
name: 'Карта сайта',
path: ROUTES.SITEMAP,
},
{
name: 'Карта сайта',
path: '',
},
];

View File

@@ -0,0 +1,39 @@
import { ROUTES } from '@shared/const/route';
export const commonLinksData = [
{
title: 'Меню',
block: [
{ name: 'Главная', link: ROUTES.HOME },
{ name: 'Экспертиза', link: ROUTES.EXPERTIZA },
{ name: 'Оценка', link: ROUTES.OCENKA },
{ name: 'Юрист', link: ROUTES.JURIST },
{ name: 'Эксперты', link: ROUTES.EXPERTS },
{ name: 'Контакты', link: ROUTES.CONTACTS },
],
},
];
export const expertsLinksData = [
{
title: 'Эксперты',
block: [
{ name: 'Ельчищев Иван Борисович', link: ROUTES.EXPERTS },
{ name: 'Янцен Яна Николаевна', link: ROUTES.EXPERTS_YANCEN },
{ name: 'Каминский Дмитрий Олегович', link: ROUTES.EXPERTS_KAMINSKIY },
{ name: 'Колодий Александр Сергеевич', link: ROUTES.EXPERTS_KOLODIY },
{ name: 'Микова Инна Георгиевна', link: ROUTES.EXPERTS_MIKOVA },
{ name: 'Полинов Андрей Владимирович', link: ROUTES.EXPERTS_POLINOV },
{ name: 'Митяев Алексей Александрович', link: ROUTES.EXPERTS_MITYAEV },
{ name: 'Бородин Виталий Петрович', link: ROUTES.EXPERTS_BORODIN },
{
name: 'Волкова-Гончарова Татьяна Анатольевна',
link: ROUTES.EXPERTS_VOLKOVA_GONCHAROVA,
},
{
name: 'Гюльмамедов Явар Фирмамед-оглы',
link: ROUTES.EXPERTS_GULMAMEDOV,
},
],
},
];

View File

@@ -0,0 +1,78 @@
.Container {
margin: 0 auto;
max-width: rem(1540px);
display: flex;
flex-direction: column;
gap: 0;
padding: rem(10px);
@include iftablet {
padding: rem(20px);
}
@include iflaptop {
padding: rem(28px);
}
@include ifdesktop {
padding: rem(40px);
}
}
.Header {
font-family: $font-roboto;
font-weight: 500;
font-size: rem(32px);
line-height: 130%;
color: $color-text;
margin: rem(20px) 0;
}
.Grid {
display: grid;
grid-template-columns: auto;
gap: rem(40px) 0;
@include iftablet {
grid-template-columns: repeat(3, 1fr);
}
}
.Block {
display: block;
.Title {
font-family: $font-roboto;
font-weight: 500;
font-size: rem(24px);
line-height: 130%;
color: $color-text;
margin-bottom: rem(20px);
}
.List {
display: flex;
flex-direction: column;
gap: rem(10px);
list-style-type: disc;
margin-left: rem(16px);
}
.ListItem {
font-family: $font-roboto;
font-weight: 400;
font-size: rem(16px);
line-height: 130%;
color: $color-text;
list-style: unset;
a {
color: $color-green;
}
a:hover {
color: $color-green-hover;
text-decoration: underline;
}
}
}

102
src/views/sitemap/ui.tsx Normal file
View File

@@ -0,0 +1,102 @@
import s from './styles.module.scss';
import { linksData as expertiseLinksData } from '@views/expertise/category/model/links';
import { linksData as ocenkaLinksData } from '@views/ocenka/category/model/links';
import { linksData as juristLinksData } from '@views/jurist/category/model/links';
import { expertsLinksData } from '@views/sitemap/model/links';
import { commonLinksData } from '@views/sitemap/model/links';
import Link from 'next/link';
import { Partners } from '@/feature/article';
import { breadcrumbData } from './model/breadcrums';
import { Breadcrumbs } from '@/widgets';
function Sitemap() {
return (
<>
<Breadcrumbs breadcrumbs={breadcrumbData} />
<section className={s.Container}>
<h2 className={s.Header}>Страницы сайта</h2>
<div className={s.Grid}>
{commonLinksData.map(({ block }, index) => (
<div key={index} className={s.Block}>
<ul className={s.List}>
{block.map(({ name, link }, idx) => (
<li key={idx} className={s.ListItem}>
{link ? <Link href={link}>{name}</Link> : name}
</li>
))}
</ul>
</div>
))}
</div>
</section>
<section className={s.Container}>
<h2 className={s.Header}>Судебная экспертиза</h2>
<div className={s.Grid}>
{expertiseLinksData.map(({ block }, index) => (
<div key={index} className={s.Block}>
<ul className={s.List}>
{block.map(({ name, link }, idx) => (
<li key={idx} className={s.ListItem}>
{link ? <Link href={link}>{name}</Link> : name}
</li>
))}
</ul>
</div>
))}
</div>
</section>
<section className={s.Container}>
<h2 className={s.Header}>Услуги оценки имущества и бизнеса</h2>
<div className={s.Grid}>
{ocenkaLinksData.map(({ title, block }, index) => (
<div key={index} className={s.Block}>
<h3 className={s.Title}>{title}</h3>
<ul className={s.List}>
{block.map(({ name, link }, idx) => (
<li key={idx} className={s.ListItem}>
{link ? <Link href={link}>{name}</Link> : name}
</li>
))}
</ul>
</div>
))}
</div>
</section>
<section className={s.Container}>
<h2 className={s.Header}>Юридические услуги</h2>
<div className={s.Grid}>
{juristLinksData.map(({ block }, index) => (
<div key={index} className={s.Block}>
<ul className={s.List}>
{block.map(({ name, link }, idx) => (
<li key={idx} className={s.ListItem}>
{link ? <Link href={link}>{name}</Link> : name}
</li>
))}
</ul>
</div>
))}
</div>
</section>
<section className={s.Container}>
<h2 className={s.Header}>Эксперты и оценщики</h2>
<div className={s.Grid}>
{expertsLinksData.map(({ block }, index) => (
<div key={index} className={s.Block}>
<ul className={s.List}>
{block.map(({ name, link }, idx) => (
<li key={idx} className={s.ListItem}>
{link ? <Link href={link}>{name}</Link> : name}
</li>
))}
</ul>
</div>
))}
</div>
</section>
<Partners />
</>
);
}
export { Sitemap };

View File

@@ -181,7 +181,7 @@ function Footer() {
</Link>
</li>
<li className={s.ListItem}>
<Link href={ROUTES.EMPTY}>Карта сайта</Link>
<Link href={ROUTES.SITEMAP}>Карта сайта</Link>
</li>
</ul>
</div>