feat: add contacts page and content

This commit is contained in:
2025-07-11 14:00:53 +03:00
parent 8fe566e1c9
commit e4f898961c
20 changed files with 598 additions and 3 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

View File

@@ -1,3 +1,5 @@
import { Contacts } from '@/views';
export default function ContactsPage() {
return <div>Contacts</div>;
return <Contacts />;
}

View File

@@ -0,0 +1,2 @@
export * from './licence-slider';
export * from './yandex-map';

View File

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

View File

@@ -0,0 +1,15 @@
.Slider {
display: block;
padding: 0 20px;
.Slide {
display: flex;
justify-content: center;
align-items: center;
.Image {
width: 200px;
height: auto;
}
}
}

View File

@@ -0,0 +1,61 @@
'use client';
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/grid';
import 'swiper/css/autoplay';
import s from './styles.module.scss';
import Image, { StaticImageData } from 'next/image';
import { Swiper, SwiperSlide } from 'swiper/react';
import { Autoplay, Grid } from 'swiper/modules';
type LicenseSliderProps = {
slidesData: {
id: string;
name: string;
image: StaticImageData;
}[];
};
const swiperBreakpoints = {
360: {
slidesPerView: 1,
spaceBetween: 10,
},
768: {
slidesPerView: 3,
spaceBetween: 30,
},
1024: {
slidesPerView: 4,
spaceBetween: 30,
},
1440: {
slidesPerView: 5,
spaceBetween: 30,
},
};
function LicenceSlider({ slidesData }: LicenseSliderProps) {
return (
<Swiper
className={s.Slider}
modules={[Grid, Autoplay]}
breakpoints={swiperBreakpoints}
autoplay={{
delay: 2000,
disableOnInteraction: false,
}}
loop={true}
>
{slidesData.map(({ id, name, image }) => (
<SwiperSlide key={id} className={s.Slide}>
<Image className={s.Image} src={image} alt={name} quality={75} />
</SwiperSlide>
))}
</Swiper>
);
}
export { LicenceSlider };

View File

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

View File

@@ -0,0 +1,85 @@
.Map {
position: relative;
iframe {
border-radius: rem(28px);
width: 100%;
height: rem(600px);
padding-bottom: rem(200px);
@include iftablet {
height: rem(360px);
padding-bottom: unset;
}
@include iflaptop {
height: rem(400px);
}
@include ifdesktop {
height: rem(450px);
}
}
.FlowBlock{
position: absolute;
z-index: 2;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
background: $color-white;
bottom: 0;
border-radius: rem(28px);
width: 100%;
height: fit-content;
padding: rem(40px) rem(35px) rem(20px);
@include iftablet {
top: rem(30px);
right: rem(50px);
border-radius: rem(28px);
width: rem(300px);
padding: rem(20px) rem(20px) rem(10px);
}
@include iflaptop {
top: rem(20px);
right: rem(150px);
border-radius: rem(28px);
width: rem(300px);
padding: rem(40px) rem(20px) rem(20px);
}
@include ifdesktop {
top: rem(40px);
right: rem(300px);
border-radius: rem(28px);
width: rem(340px);
padding: rem(40px) rem(35px) rem(40px);
}
.Header {
font-family: $font-roboto;
font-weight: 400;
font-size: 32px;
line-height: 130%;
color: $color-text;
margin-top: 10px;
&:first-child {
margin-top: 0;
}
}
.Text {
font-family: $font-roboto;
font-weight: 400;
font-size: 16px;
line-height: 130%;
color: $color-text;
margin-bottom: 10px;
}
}
}

View File

@@ -0,0 +1,25 @@
import s from './styles.module.scss';
function YandexMap() {
return (
<div className={s.Map}>
<iframe
src='https://yandex.ru/map-widget/v1/?um=constructor%3A7f1285c4f3e470bc9affa220323655ac72edd1be376c2579d421ca359ac46a7d&amp;source=constructor'
// width='100%'
// height='620'
frameBorder='0'
></iframe>
<div className={s.FlowBlock}>
<h3 className={s.Header}>Сочи</h3>
<p className={s.Text}>ул. Навагинская д. 9Д, офис 35</p>
<h3 className={s.Header}>Время работы:</h3>
<p className={s.Text}>Понедельник - Пятница</p>
<p className={s.Text}>с 09:00 до 17:00</p>
<h3 className={s.Header}>Телефон:</h3>
<p className={s.Text}>+7 (900) 241-34-34</p>
</div>
</div>
);
}
export { YandexMap };

View File

@@ -180,7 +180,7 @@ const BtnPhone = (props: SVGIcon) => (
);
//HealthiconsHomeOutline
const Home = (props: SVGProps<SVGSVGElement>) => (
const Home = (props: SVGIcon) => (
<svg
xmlns='http://www.w3.org/2000/svg'
width={200}
@@ -199,6 +199,89 @@ const Home = (props: SVGProps<SVGSVGElement>) => (
</svg>
);
// PhPhoneCall
const ContactCall = (props: SVGIcon) => (
<svg
xmlns='http://www.w3.org/2000/svg'
width={96}
height={96}
viewBox='0 0 256 256'
{...props}
>
<path
fill='currentColor'
d='M144.27 45.93a8 8 0 0 1 9.8-5.66a86.22 86.22 0 0 1 61.66 61.66a8 8 0 0 1-5.66 9.8a8.2 8.2 0 0 1-2.07.27a8 8 0 0 1-7.73-5.94a70.35 70.35 0 0 0-50.33-50.33a8 8 0 0 1-5.67-9.8m-2.33 41.8c13.79 3.68 22.65 12.54 26.33 26.33A8 8 0 0 0 176 120a8.2 8.2 0 0 0 2.07-.27a8 8 0 0 0 5.66-9.8c-5.12-19.16-18.5-32.54-37.66-37.66a8 8 0 1 0-4.13 15.46m81.94 95.35A56.26 56.26 0 0 1 168 232C88.6 232 24 167.4 24 88a56.26 56.26 0 0 1 48.92-55.88a16 16 0 0 1 16.62 9.52l21.12 47.15v.12a16 16 0 0 1-1.27 15.09c-.18.27-.37.52-.57.77L88 129.45c7.49 15.22 23.41 31 38.83 38.51l24.34-20.71a8 8 0 0 1 .75-.56a16 16 0 0 1 15.17-1.4l.13.06l47.11 21.11a16 16 0 0 1 9.55 16.62m-15.88-2h-.11l-47-21.05l-24.35 20.71a8 8 0 0 1-.74.56a16 16 0 0 1-15.75 1.14c-18.73-9.05-37.4-27.58-46.46-46.11a16 16 0 0 1 1-15.7a6 6 0 0 1 .57-.77L96 95.15l-21-47a.6.6 0 0 1 0-.12A40.2 40.2 0 0 0 40 88a128.14 128.14 0 0 0 128 128a40.21 40.21 0 0 0 40-34.93Z'
></path>
</svg>
);
//StreamlineFastforwardClock
const ContactTimer = (props: SVGIcon) => (
<svg
xmlns='http://www.w3.org/2000/svg'
width={96}
height={96}
viewBox='0 0 14 14'
{...props}
>
<g fill='none' stroke='currentColor' strokeLinecap='round' strokeWidth={1}>
<path strokeLinejoin='round' d='M7 3.5v4l2.6 1.3'></path>
<path d='M13.326 8.5a6.5 6.5 0 1 1-.558-4.5'></path>
<path strokeLinejoin='round' d='M13.5 2v2.5H11'></path>
</g>
</svg>
);
//RiWhatsappLine
const ContactWhatsapp = (props: SVGIcon) => {
return (
<svg
xmlns='http://www.w3.org/2000/svg'
width={96}
height={96}
viewBox='0 0 24 24'
{...props}
>
<path
fill='currentColor'
d='m7.254 18.494l.724.423A7.95 7.95 0 0 0 12.001 20a8 8 0 1 0-8-8a7.95 7.95 0 0 0 1.084 4.024l.422.724l-.653 2.401zM2.005 22l1.352-4.968A9.95 9.95 0 0 1 2.001 12c0-5.523 4.477-10 10-10s10 4.477 10 10s-4.477 10-10 10a9.95 9.95 0 0 1-5.03-1.355zM8.392 7.308q.202-.014.403-.004q.081.006.162.016c.159.018.334.115.393.249q.447 1.015.868 2.04c.062.152.025.347-.093.537c-.06.097-.154.233-.263.372c-.113.145-.356.411-.356.411s-.099.118-.061.265c.014.056.06.137.102.205l.059.095c.256.427.6.86 1.02 1.268c.12.116.237.235.363.346c.468.413.998.75 1.57 1l.005.002c.085.037.128.057.252.11q.093.039.191.066q.036.01.073.011a.35.35 0 0 0 .295-.142c.723-.876.79-.933.795-.933v.002a.48.48 0 0 1 .378-.127q.092.004.177.04c.531.243 1.4.622 1.4.622l.582.261c.098.047.187.158.19.265c.004.067.01.175-.013.373c-.032.259-.11.57-.188.733a1.2 1.2 0 0 1-.21.302a2.4 2.4 0 0 1-.33.288q-.124.092-.125.09a5 5 0 0 1-.383.22a2 2 0 0 1-.833.23c-.185.01-.37.024-.556.014c-.008 0-.568-.087-.568-.087a9.45 9.45 0 0 1-3.84-2.046c-.226-.199-.436-.413-.65-.626c-.888-.885-1.561-1.84-1.97-2.742a3.5 3.5 0 0 1-.33-1.413a2.73 2.73 0 0 1 .565-1.68c.073-.094.142-.192.261-.305c.126-.12.207-.184.294-.228a1 1 0 0 1 .371-.1'
></path>
</svg>
);
};
//Fa6BrandsCloudscale
const CloudScale = (props: SVGIcon) => (
<svg
xmlns='http://www.w3.org/2000/svg'
width={84}
height={96}
viewBox='0 0 448 512'
{...props}
>
<path
fill='currentColor'
d='m318.1 154l-9.4 7.6c-22.5-19.3-51.5-33.6-83.3-33.6C153.8 128 96 188.8 96 260.3c0 6.6.4 13.1 1.4 19.4c-2-56 41.8-97.4 92.6-97.4c24.2 0 46.2 9.4 62.6 24.7l-25.2 20.4c-8.3-.9-16.8 1.8-23.1 8.1c-11.1 11-11.1 28.9 0 40c11.1 11 28.9 11 40 0c6.3-6.3 9-14.9 8.1-23.1l75.2-88.8c6.3-6.5-3.3-15.9-9.5-9.6m-83.8 111.5c-5.6 5.5-14.6 5.5-20.2 0c-5.6-5.6-5.6-14.6 0-20.2s14.6-5.6 20.2 0s5.6 14.7 0 20.2M224 32C100.5 32 0 132.5 0 256s100.5 224 224 224s224-100.5 224-224S347.5 32 224 32m0 384c-88.2 0-160-71.8-160-160S135.8 96 224 96s160 71.8 160 160s-71.8 160-160 160'
></path>
</svg>
);
//FaSolidMailBulk
const MailBulk = (props: SVGIcon) => (
<svg
xmlns='http://www.w3.org/2000/svg'
width={108}
height={96}
viewBox='0 0 576 512'
{...props}
>
<path
fill='currentColor'
d='M160 448c-25.6 0-51.2-22.4-64-32c-64-44.8-83.2-60.8-96-70.4V480c0 17.67 14.33 32 32 32h256c17.67 0 32-14.33 32-32V345.6c-12.8 9.6-32 25.6-96 70.4c-12.8 9.6-38.4 32-64 32m128-192H32c-17.67 0-32 14.33-32 32v16c25.6 19.2 22.4 19.2 115.2 86.4c9.6 6.4 28.8 25.6 44.8 25.6s35.2-19.2 44.8-22.4c92.8-67.2 89.6-67.2 115.2-86.4V288c0-17.67-14.33-32-32-32m256-96H224c-17.67 0-32 14.33-32 32v32h96c33.21 0 60.59 25.42 63.71 57.82l.29-.22V416h192c17.67 0 32-14.33 32-32V192c0-17.67-14.33-32-32-32m-32 128h-64v-64h64zm-352-96c0-35.29 28.71-64 64-64h224V32c0-17.67-14.33-32-32-32H96C78.33 0 64 14.33 64 32v192h96z'
></path>
</svg>
);
const Icons = Object.assign(
{},
{
@@ -212,6 +295,11 @@ const Icons = Object.assign(
MenuArrow,
BtnPhone,
Home,
ContactCall,
ContactTimer,
ContactWhatsapp,
CloudScale,
MailBulk,
},
);

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: '',
},
{
name: PAGE_NAME,
path: '',
},
];

View File

@@ -0,0 +1,33 @@
import lic0 from '@public/images/licence/dtr-strahovka.png';
import lic1 from '@public/images/licence/dtr-eac-0.png';
import lic2 from '@public/images/licence/dtr-eac-1.png';
import lic3 from '@public/images/licence/dtr-eac-2.png';
import lic4 from '@public/images/licence/dtr-eac-3.png';
export const slidesData = [
{
id: '0',
name: '',
image: lic0,
},
{
id: '1',
name: '',
image: lic1,
},
{
id: '2',
name: '',
image: lic2,
},
{
id: '3',
name: '',
image: lic3,
},
{
id: '4',
name: '',
image: lic4,
},
];

View File

@@ -0,0 +1,162 @@
.Information {
margin: 0 auto;
max-width: rem(1540px);
display: grid;
grid-template-columns: auto;
gap: 10px;
padding: 10px;
@include iftablet {
grid-template-columns: repeat(2, 1fr);
justify-items: center;
gap: 20px;
padding: 20px;
}
@include iflaptop {
padding: 28px;
}
@include ifdesktop {
padding: 40px;
gap: 40px;
}
.Contact {
h3 {
@extend %title;
width: 100%;
@include iftablet {
max-width: 420px;
}
}
.Row {
display: grid;
grid-template-columns: 1fr 1fr;
justify-items: center;
align-items: center;
margin-bottom: 20px;
.Info {
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
.Text {
font-family: $font-roboto;
font-weight: 400;
font-size: 16px;
line-height: 100%;
color: $color-text;
a {
color: $color-green;
&:hover {
color: $color-green-hover;
text-decoration: underline;
}
}
}
}
}
}
.Details {
h3 {
@extend %title;
}
p {
font-family: $font-roboto;
font-weight: 400;
font-size: 16px;
line-height: 150%;
color: $color-text-light;
margin-bottom: 20px;
}
}
}
.LicenceSlider {
margin: 0 auto 40px;
max-width: rem(1200px);
.Title {
@extend %title;
}
}
.WorkTime {
display: grid;
grid-template-columns: auto;
gap: 0;
width: 100%;
background-color: transparent;
background-image: linear-gradient(300deg, #009283 16%, #58c644 37%);
@include iftablet {
grid-template-columns: auto auto;
}
.Block {
position: relative;
padding: 20px 0 20px 100px;
@include iftablet {
background-color: #009283;
}
&_grad {
@include iftablet {
background-color: transparent;
background-image: linear-gradient(300deg, #009283 16%, #58c644 37%);
}
}
.Icon {
position: absolute;
top: 16px;
left: 16px;
@include iftablet {
top: 18px;
left: 30px;
}
}
.Title {
font-family: $font-roboto;
font-weight: 500;
font-size: 24px;
line-height: 130%;
color: $color-white;
margin-bottom: 4px;
}
.Text {
font-family: $font-roboto;
font-weight: 500;
font-size: 16px;
line-height: 130%;
color: $color-white;
margin-bottom: 4px;
}
}
}
%title {
font-family: $font-roboto;
font-weight: 500;
font-size: 32px;
line-height: 130%;
color: $color-text;
text-align: center;
height: 80px;
margin-bottom: 20px;
}

View File

@@ -1,7 +1,111 @@
import s from './styles.module.scss';
import { Breadcrumbs } from '@/widgets';
import { Partners } from '@/feature/article';
import { LicenceSlider, YandexMap } from '@/feature/contacts';
import { breadcrumbData } from './model/breadcrums';
import { Icons } from '@shared/ui/icon';
import { slidesData } from './model/slides';
import clsx from 'clsx';
function Contacts() {
return <></>;
return (
<>
<Breadcrumbs breadcrumbs={breadcrumbData} />
<section>
<YandexMap />
</section>
<section className={s.Information}>
<div className={s.Contact}>
<h3>Обращайтесь к нам, любым удобным способом</h3>
<div className={s.Row}>
<Icons.ContactCall width={96} height={96} color={'#19bb3f'} />
<div className={s.Info}>
<p className={s.Text}>Звоните</p>
<p className={s.Text}>
<a href={`tel:+79002413434`}>+7 (900) 241-34-34</a>
</p>
</div>
</div>
<div className={s.Row}>
<Icons.ContactTimer width={84} height={84} color={'#19bb3f'} />
<div className={s.Info}>
<p className={s.Text}>Ежедневно</p>
<p className={s.Text}>с 09:00 до 17:00</p>
</div>
</div>
<div className={s.Row}>
<Icons.Envelope width={96} height={96} color={'#19bb3f'} />
<div className={s.Info}>
<p className={s.Text}>E-mail:</p>
<p className={s.Text}>
<a href={`mailto:spo-71@yandex.ru`}>spo-71@yandex.ru</a>
</p>
</div>
</div>
<div className={s.Row}>
<Icons.ContactWhatsapp width={96} height={96} color={'#19bb3f'} />
<div className={s.Info}>
<p className={s.Text}>Whatsapp, Telegram:</p>
<p className={s.Text}>+7 (900) 241-34-34</p>
</div>
</div>
</div>
<div className={s.Details}>
<h3>Реквизиты</h3>
<p> Название: ООО ДИ ТРАСО </p>
<p>
{' '}
Юр.адрес: 354000, Краснодарский край, г.Сочи, ул.Труда, д.15, кв.
64{' '}
</p>
<p />
<p>
ИНН: 2320219187 <br />
КПП: 232001001 <br />
ОГРН: 1142366003010
</p>
<p>
Банк: Юго-Западный Банк ПАО Сбербанк г. Ростов-на-Дону <br />
БИК: 046015602
<br />
Р/с: 40702810230060002355
<br />
К/с: 30101810600000000602 <br />
</p>
<p>Директор: Ельчищев Иван Борисович </p>
</div>
</section>
<section className={s.LicenceSlider}>
<h3 className={s.Title}>Лицензии и сертификаты</h3>
<LicenceSlider slidesData={slidesData} />
</section>
<section className={s.WorkTime}>
<div className={clsx(s.Block, s.Block_grad)}>
<Icons.CloudScale
className={s.Icon}
width={64}
height={64}
color={'#FFFFFF'}
/>
<h3 className={s.Title}>Режим работы:</h3>
<p className={s.Text}>Будние дни: с 9.00 до 17.00</p>
<p className={s.Text}>Выходные: суббота, воскресенье</p>
</div>
<div className={s.Block}>
<Icons.MailBulk
className={s.Icon}
width={64}
height={64}
color={'#FFFFFF'}
/>
<h3 className={s.Title}>Контакты для связи</h3>
<p className={s.Text}>Тел.: +7 (900) 241-34-34</p>
<p className={s.Text}>E-mail: spo-71@yandex.ru</p>
</div>
</section>
<Partners />
</>
);
}
export { Contacts };

View File

@@ -1,4 +1,5 @@
export * from './home';
export * from './contacts';
//Expertise
export * from './expertise/category';