upd
@@ -14,9 +14,11 @@
|
||||
"framer-motion": "^10.16.5",
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "^18.2.0",
|
||||
"react-circular-progressbar": "^2.1.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-rangeslider": "^2.2.0",
|
||||
"react-router-dom": "^6.18.0",
|
||||
"react-swipeable": "^7.0.1",
|
||||
"usehooks-ts": "^2.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
|
After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 135 KiB |
|
After Width: | Height: | Size: 104 KiB |
|
After Width: | Height: | Size: 115 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 107 KiB |
|
After Width: | Height: | Size: 103 KiB |
|
After Width: | Height: | Size: 135 KiB |
|
After Width: | Height: | Size: 107 KiB |
|
After Width: | Height: | Size: 126 KiB |
|
After Width: | Height: | Size: 134 KiB |
|
After Width: | Height: | Size: 142 KiB |
|
After Width: | Height: | Size: 145 KiB |
|
After Width: | Height: | Size: 135 KiB |
|
After Width: | Height: | Size: 168 KiB |
|
After Width: | Height: | Size: 144 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 131 KiB |
|
After Width: | Height: | Size: 102 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 91 KiB |
|
After Width: | Height: | Size: 74 KiB |
@@ -3,7 +3,7 @@ import "./App.css";
|
||||
import LogoIcon from "./components/icons/LogoIcon";
|
||||
import BlendingHeader from "./components/blendings/BlendingHeader";
|
||||
import FeatureItem from "./components/FeatureItem";
|
||||
import BlendVR from "./components/blendings/BlendVR";
|
||||
// import BlendVR from "./components/blendings/BlendVR";
|
||||
import BlendStream from "./components/blendings/BlendStream";
|
||||
import StreamButton from "./components/StreamButton";
|
||||
import "react-rangeslider/lib/index.css";
|
||||
@@ -18,15 +18,17 @@ import Calc from "./components/Calc";
|
||||
import BlendingCalc from "./components/blendings/BlendingCalc";
|
||||
import BlendingClients from "./components/blendings/BlendingClients";
|
||||
import Heading2 from "./components/Headings/Heading2";
|
||||
import PlayIcon from "./components/icons/PlayIcon";
|
||||
// import PlayIcon from "./components/icons/PlayIcon";
|
||||
import VideoSliderMobile from "./components/VideoSliderMobile";
|
||||
|
||||
function App() {
|
||||
const [selectedVideo, setSelectedVideo] = useState<string>(
|
||||
"https://graff.estate/videos/features/virtual_tour.mp4"
|
||||
);
|
||||
const [isShowProjects, setIsShowProjects] = useState<boolean>(false);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen text-white 2xl:px-10 xl:px-8 sm:px-6 px-4">
|
||||
<div className="min-h-screen text-white 2xl:px-10 xl:px-8 sm:px-6 px-4 overflow-x-clip">
|
||||
<div className="relative conatiner mx-auto 2xl:max-w-screen-2xl">
|
||||
<div className="flex justify-between py-6 2xl:mb-28 xl:mb-[88px] sm:mb-12 mb-14">
|
||||
<div>
|
||||
@@ -190,22 +192,22 @@ function App() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4 2xl:mb-40 sm:mb-[120px] mb-20">
|
||||
<div className="xl:grid flex flex-col grid-cols-2 xl:gap-4 sm:gap-10 gap-8 2xl:mb-40 sm:mb-[120px] mb-20">
|
||||
<div className="flex flex-col gap-20">
|
||||
<div className="flex flex-col gap-8">
|
||||
<div className="xl:flex flex-col grid sm:grid-cols-2 xl:gap-8 gap-3">
|
||||
<Heading2>
|
||||
Функциональные
|
||||
<br />
|
||||
<span style={{ WebkitTextFillColor: "#fff" }}>возможности</span>
|
||||
</Heading2>
|
||||
<p className="w-2/3">
|
||||
<p className="xl:w-2/3 xl:text-base text-sm">
|
||||
Интерактивная презентация увлекает покупателей и предоставляет
|
||||
актуальную информацию о жилом комплексе, отвечая на все вопросы
|
||||
и показывая важные особенности и преимущества объекта
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="pr-6">
|
||||
<div className="pr-6 xl:block hidden">
|
||||
<FeatureItem
|
||||
title="Виртуальный тур по жилому комплексу"
|
||||
desc="Клиент лично оценит угол инсоляции, малые архитектурные формы и ландшафт, перемещаясь по комплексу с помощью тапа."
|
||||
@@ -238,7 +240,7 @@ function App() {
|
||||
/>
|
||||
<FeatureItem
|
||||
title="Формирование вишлиста"
|
||||
desc="Фильтр позволит отметить конкретные преимущества, определить количество комнат, желаемый этаж, цену, и получить выборку подходящих вариантов."
|
||||
desc="Клиент может добавить варианты квартир в избранное, сравнить их между собой по основным параметрам и выбрать свою будущую квартиру."
|
||||
video="https://graff.estate/videos/features/wish.mp4"
|
||||
handleHoverStart={(video) => setSelectedVideo(video)}
|
||||
/>
|
||||
@@ -266,67 +268,43 @@ function App() {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="aspect-video sticky top-[25%]">
|
||||
<div className="aspect-video sticky top-[25%] xl:block hidden">
|
||||
<FeatureVideoViewBox video={selectedVideo} />
|
||||
</div>
|
||||
|
||||
<VideoSliderMobile />
|
||||
</div>
|
||||
|
||||
<div className="relative grid grid-cols-4 gap-4 2xl:mb-40 sm:mb-[120px] mb-20">
|
||||
<div className="col-span-2 flex flex-col gap-16">
|
||||
<h2 className="font-gilroy text-[64px] leading-none max-w-[780px] font-medium text-gradient">
|
||||
Экскурсия{" "}
|
||||
<div className="relative grid grid-cols-2 gap-4 2xl:mb-40 sm:mb-[120px] mb-20">
|
||||
<div className="flex flex-col gap-8">
|
||||
<Heading2>
|
||||
Экскурсия
|
||||
<br />
|
||||
<span style={{ WebkitTextFillColor: "#fff" }}>
|
||||
в виртуальной реальности
|
||||
</span>
|
||||
</h2>
|
||||
</Heading2>
|
||||
|
||||
<Button>Записаться в шоу-рум</Button>
|
||||
</div>
|
||||
|
||||
<p className="">
|
||||
Клиенту достаточно надеть шлем виртуальной реальности, чтобы
|
||||
прогуляться, оценить и ощутить пространство{" "}
|
||||
</p>
|
||||
<div className="flex flex-col gap-4">
|
||||
<p>
|
||||
Он полностью погружается в воссозданную реальность, чувствует
|
||||
удобство и уровень комфорта
|
||||
<p className="2xl:text-base text-sm">
|
||||
Клиенту достаточно надеть шлем виртуальной реальности, чтобы
|
||||
прогуляться, оценить и ощутить пространство{" "}
|
||||
</p>
|
||||
<div className="relative flex justify-center items-center">
|
||||
<video
|
||||
src="https://graff.estate/videos/vr.mp4"
|
||||
muted
|
||||
// autoPlay
|
||||
loop
|
||||
playsInline
|
||||
preload="metadata"
|
||||
className=""
|
||||
/>
|
||||
<button className="group absolute border border-[#3D425C] bg-[#14161F] bg-opacity-20 p-4 rounded-full">
|
||||
<span className="block group-hover:scale-125 transition-transform">
|
||||
<PlayIcon />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-span-4 flex justify-center mb-16">
|
||||
<img src="/images/VRHeadset.png" alt="" className="w-4/5" />
|
||||
</div>
|
||||
<div className="absolute top-[50%] left-[50%] -translate-x-[50%] -translate-y-[50%] blur-[22px] -z-10">
|
||||
<BlendVR />
|
||||
|
||||
<Button className="sm:block hidden">Записаться в шоу-рум</Button>
|
||||
</div>
|
||||
<div className=""></div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4 2xl:mb-40 sm:mb-[120px] mb-20">
|
||||
<div>
|
||||
<div className="flex flex-col gap-8 mb-[204px]">
|
||||
<h2 className="font-gilroy text-[64px] text-gradient leading-none font-medium">
|
||||
<Heading2>
|
||||
Анализируем
|
||||
<br />
|
||||
<span style={{ WebkitTextFillColor: "#fff" }}>
|
||||
поведение пользователей
|
||||
</span>
|
||||
</h2>
|
||||
</Heading2>
|
||||
<p className="w-2/3">
|
||||
Система внутренней аналитики программы собирает информацию о
|
||||
поведении пользователя и эффективности работы менеджеров для
|
||||
@@ -345,7 +323,7 @@ function App() {
|
||||
|
||||
<div className="relative grid grid-cols-4 gap-4 mb-16">
|
||||
<div className="col-span-2 flex flex-col justify-between">
|
||||
<h2 className="font-gilroy text-[64px] text-gradient leading-none font-medium">
|
||||
<Heading2>
|
||||
Graff.estate stream —
|
||||
<br />
|
||||
<span style={{ WebkitTextFillColor: "#fff" }}>
|
||||
@@ -353,7 +331,7 @@ function App() {
|
||||
<br />
|
||||
жилого комплекса
|
||||
</span>
|
||||
</h2>
|
||||
</Heading2>
|
||||
<Button>Узнать больше</Button>
|
||||
</div>
|
||||
<div className="flex flex-col gap-12">
|
||||
@@ -400,13 +378,13 @@ function App() {
|
||||
|
||||
<div className="relative flex flex-col gap-16 2xl:mb-40 sm:mb-[120px] mb-20">
|
||||
<div className="flex flex-col gap-8">
|
||||
<h2 className="font-gilroy text-[64px] text-gradient leading-none font-medium">
|
||||
<Heading2>
|
||||
Оцените эффективность интерактивного
|
||||
<br />
|
||||
<span style={{ WebkitTextFillColor: "#fff" }}>
|
||||
инструмента продаж
|
||||
</span>
|
||||
</h2>
|
||||
</Heading2>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<p className="w-2/3">
|
||||
Мы изучили отраслевую аналитику на рынке продаж новых квартир и
|
||||
@@ -428,71 +406,165 @@ function App() {
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-16 2xl:mb-40 sm:mb-[120px] mb-20">
|
||||
<h2 className="font-gilroy text-[64px] text-gradient leading-none font-medium w-fit">
|
||||
Проекты
|
||||
</h2>
|
||||
<div className="grid grid-cols-3 gap-8">
|
||||
<Heading2>Проекты</Heading2>
|
||||
<div className="grid xl:grid-cols-3 sm:grid-cols-2 2xl:gap-8 xl:gap-6 gap-3">
|
||||
<ProjectCard
|
||||
title="ЖК «Голос в сердце города»"
|
||||
company="Голос Девелопмент, Челябинск"
|
||||
image="/images/projects/photo01.jpg"
|
||||
stream
|
||||
stage={1}
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="ЖК «Кама»"
|
||||
company="ГК Альфа, Пермь"
|
||||
image="/images/projects/photo02.jpg"
|
||||
stage={2}
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="ЖК «Август»"
|
||||
company="Родина Девелопмент, Тюмень"
|
||||
image="/images/ViewBox.jpg"
|
||||
releaseDate="23.11.2023"
|
||||
image="/images/projects/photo03.jpg"
|
||||
stage={4}
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="ЖК «DNS Сити»"
|
||||
company="НКС Девелопмент, Владивосток"
|
||||
image="/images/projects/photo04.jpg"
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="ЖК «Upside Towers»"
|
||||
company="Upside Development, Москва"
|
||||
image="/images/ViewBox.jpg"
|
||||
releaseDate="22.11.2023"
|
||||
image="/images/projects/photo05.jpg"
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="ЖК «Scala City»"
|
||||
company="Рисан, Пенза"
|
||||
image="/images/projects/photo06.jpg"
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="ЖК «Мираполис»"
|
||||
company="ГК Основа, Москва"
|
||||
image="/images/ViewBox.jpg"
|
||||
releaseDate="21.11.2023"
|
||||
/>
|
||||
<ProjectCard
|
||||
title="ЖК «Life Резиденция»"
|
||||
company="Paritet Pro Development, Тюмень"
|
||||
image="/images/ViewBox.jpg"
|
||||
releaseDate="20.11.2023"
|
||||
/>
|
||||
<ProjectCard
|
||||
title="МФК «Re:volution towers»"
|
||||
company="НКС Девелопмент, Екатеринбург"
|
||||
image="/images/ViewBox.jpg"
|
||||
releaseDate="15.11.2023"
|
||||
stream
|
||||
/>
|
||||
<ProjectCard
|
||||
title="ЖК «Новатор»"
|
||||
company="ГК СБК, Тюмень"
|
||||
image="/images/ViewBox.jpg"
|
||||
releaseDate="15.11.2023"
|
||||
/>
|
||||
<ProjectCard
|
||||
title="ЖК «Айвазовский City»"
|
||||
company="ГК ЭНКО, Тюмень"
|
||||
image="/images/ViewBox.jpg"
|
||||
releaseDate="15.11.2023"
|
||||
stream
|
||||
image="/images/projects/photo07.jpg"
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="ЖК «Ориент»"
|
||||
company="СК+, Хабаровск"
|
||||
image="/images/ViewBox.jpg"
|
||||
releaseDate="15.11.2023"
|
||||
stream
|
||||
image="/images/projects/photo08.jpg"
|
||||
/>
|
||||
<MoreProjectButton />
|
||||
|
||||
{!isShowProjects ? (
|
||||
<MoreProjectButton handleClick={() => setIsShowProjects(true)} />
|
||||
) : (
|
||||
<>
|
||||
<ProjectCard
|
||||
title="ЖК «Новатор»"
|
||||
company="СБК, Тюмень"
|
||||
image="/images/projects/photo09.jpg"
|
||||
stream
|
||||
stage={1}
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="ЖК «Фотограф»"
|
||||
company="Мавис, Санкт-Петербург"
|
||||
image="/images/projects/photo10.jpg"
|
||||
stage={2}
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="ЖК «Life Резиденция»"
|
||||
company="Паритет Девелопмент, Тюмень"
|
||||
image="/images/projects/photo11.jpg"
|
||||
stage={3}
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="МФК «Re:volution towers»"
|
||||
company="НКС Девелопмент, Екатеринбург"
|
||||
image="/images/projects/photo12.jpg"
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="ЖК «Айвазовский»"
|
||||
company="ЭНКО, Тюмень"
|
||||
image="/images/projects/photo13.jpg"
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="ЖК «Авторский квартал Машаров»"
|
||||
company="Сибинтел Девелопмент, Тюмень"
|
||||
image="/images/projects/photo14.jpg"
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="ЖК «Уральский»"
|
||||
company="Эфес, Екатеринбург"
|
||||
image="/images/projects/photo15.jpg"
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="Iskan Abu Dhabi"
|
||||
company="ОАЭ, Абу-Даби"
|
||||
image="/images/projects/photo16.jpg"
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="ЖК «Графика»"
|
||||
company="Мавис, Санкт-Петербург"
|
||||
image="/images/projects/photo17.jpg"
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="ЖК «4you»"
|
||||
company="Атлас Девелопмент, Екатеринбург"
|
||||
image="/images/projects/photo18.jpg"
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="ЖК «Новая Атмосфера»"
|
||||
company="Застройщик Атмосфера, Брянск"
|
||||
image="/images/projects/photo19.jpg"
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="ЖК «Тринити»"
|
||||
company="НКС-девелопмент, Екатеринбург"
|
||||
image="/images/projects/photo20.jpg"
|
||||
/>
|
||||
|
||||
<ProjectCard
|
||||
title="ЖК «Дом на Опалихинской»"
|
||||
company="Корпорация «Маяк», Екатеринбург"
|
||||
image="/images/projects/photo21.jpg"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative flex flex-col gap-16 2xl:mb-40 sm:mb-[120px] mb-20">
|
||||
<h2 className="font-gilroy text-[64px] text-gradient leading-none font-medium">
|
||||
<Heading2>
|
||||
Наши клиенты{" "}
|
||||
<span style={{ WebkitTextFillColor: "#fff" }}>в девелопменте</span>
|
||||
</h2>
|
||||
<img src="/images/ClientsLogos.png" alt="" />
|
||||
</Heading2>
|
||||
<img
|
||||
src="/images/clients-logos.png"
|
||||
alt=""
|
||||
className="sm:block hidden"
|
||||
/>
|
||||
<img
|
||||
src="/images/clients-logos-mobile.png"
|
||||
alt=""
|
||||
className="sm:hidden block"
|
||||
/>
|
||||
<div className="absolute top-0 right-0 blur-[34px]">
|
||||
<BlendingClients />
|
||||
</div>
|
||||
|
||||
@@ -158,8 +158,8 @@ function Calc() {
|
||||
|
||||
return (
|
||||
<div className="relative flex flex-col gap-16">
|
||||
<div className="grid grid-cols-4">
|
||||
<div>
|
||||
<div className="grid xl:grid-cols-4 sm:grid-cols-3">
|
||||
<div className="xl:col-auto sm:col-span-full xl:block sm:grid grid-cols-2">
|
||||
<CalcSelect
|
||||
label="Регион"
|
||||
placeholder="Выберите регион"
|
||||
@@ -175,7 +175,7 @@ function Calc() {
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<div className="border border-t-0 border-[#3D425C] p-6">
|
||||
<div className="border xl:border-t-0 xl:border-l sm:border-l-0 border-[#3D425C] 2xl:p-6 p-4">
|
||||
<p className="text-[#52587A] text-xs leading-[120%]">
|
||||
Установлены усредненные показатели по региону.
|
||||
<br />
|
||||
@@ -190,33 +190,33 @@ function Calc() {
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-8 py-6 flex flex-col justify-between border border-l-0 border-[#3D425C]">
|
||||
<div className="2xl:px-8 2xl:py-6 px-6 py-4 flex flex-col justify-between gap-6 border xl:border-l-0 xl:border-t border-t-0 border-[#3D425C]">
|
||||
<p className="text-sm">
|
||||
Средняя площадь
|
||||
<br />
|
||||
жилья в комплексе, м2
|
||||
</p>
|
||||
<p className="text-5xl font-gilroy font-medium leading-none">
|
||||
<p className="2xl:text-5xl text-[32px] font-gilroy font-medium leading-none">
|
||||
{(selectedRegion?.areaInComplex || 1500).toLocaleString()}
|
||||
</p>
|
||||
</div>
|
||||
<div className="px-8 py-6 flex flex-col justify-between border border-l-0 border-[#3D425C]">
|
||||
<div className="2xl:px-8 2xl:py-6 px-6 py-4 flex flex-col justify-between border border-l-0 xl:border-t border-t-0 border-[#3D425C]">
|
||||
<p className="text-sm">
|
||||
Средняя площадь
|
||||
<br />
|
||||
квартиры, м2
|
||||
</p>
|
||||
<p className="text-5xl font-gilroy font-medium leading-none">
|
||||
<p className="2xl:text-5xl text-[32px] font-gilroy font-medium leading-none">
|
||||
{(selectedRegion?.areaApartment || 100).toLocaleString()}
|
||||
</p>
|
||||
</div>
|
||||
<div className="px-8 py-6 flex flex-col justify-between border border-l-0 border-[#3D425C]">
|
||||
<div className="2xl:px-8 2xl:py-6 px-6 py-4 flex flex-col justify-between border border-l-0 xl:border-t border-t-0 border-[#3D425C]">
|
||||
<p className="text-sm">
|
||||
Средняя стоимость
|
||||
<br />
|
||||
одного м2, тыс. руб.
|
||||
</p>
|
||||
<p className="text-5xl font-gilroy font-medium leading-none">
|
||||
<p className="2xl:text-5xl text-[32px] font-gilroy font-medium leading-none">
|
||||
{(selectedRegion?.costPerSquare || 100).toLocaleString()}
|
||||
</p>
|
||||
</div>
|
||||
@@ -225,10 +225,10 @@ function Calc() {
|
||||
<div className="grid grid-cols-4">
|
||||
<div className="flex flex-col gap-6 mr-8 border-b border-[#3D425C]">
|
||||
<div className="flex justify-between">
|
||||
<p className="font-gilroy font-medium">
|
||||
<p className="font-gilroy font-medium 2xl:text-base text-sm">
|
||||
Очных консультаций в месяц
|
||||
</p>
|
||||
<p className="font-gilroy font-medium text-[#798FFF]">
|
||||
<p className="font-gilroy font-medium text-[#798FFF] 2xl:text-base text-sm">
|
||||
{consultations}
|
||||
</p>
|
||||
</div>
|
||||
@@ -255,20 +255,20 @@ function Calc() {
|
||||
|
||||
<div className="col-span-3 grid grid-cols-2">
|
||||
<div>
|
||||
<div className="px-8 py-6 border border-[#3D425C] flex flex-col gap-4">
|
||||
<div className="2xl:px-8 2xl:py-6 px-6 py-4 border border-[#3D425C] flex flex-col gap-4">
|
||||
<p className="text-sm">Срок реализации</p>
|
||||
<div className="grid grid-cols-2">
|
||||
<p
|
||||
className={`text-5xl font-gilroy font-medium flex items-end gap-1.5 w-fit ${
|
||||
className={`2xl:text-5xl text-[32px] font-gilroy font-medium flex items-end gap-1.5 w-fit ${
|
||||
isToolEnabled && "text-gradient"
|
||||
}`}
|
||||
>
|
||||
<span>
|
||||
<span className="leading-none">
|
||||
{isToolEnabled
|
||||
? implementationPeriod
|
||||
: oldImplementationPeriod}
|
||||
</span>
|
||||
<span className="text-2xl">
|
||||
<span className="2xl:text-2xl text-xl leading-none">
|
||||
{isToolEnabled
|
||||
? implementationPeriodEnding
|
||||
: oldImplementationPeriodEnding}
|
||||
@@ -291,19 +291,21 @@ function Calc() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="px-8 py-6 border border-t-0 border-[#3D425C] flex flex-col gap-4">
|
||||
<div className="2xl:px-8 2xl:py-6 px-6 py-4 border border-t-0 border-[#3D425C] flex flex-col gap-4">
|
||||
<p className="text-sm">Месячный доход</p>
|
||||
<div className="grid grid-cols-2">
|
||||
<p
|
||||
className={`text-5xl font-gilroy font-medium flex items-end gap-1.5 w-fit ${
|
||||
className={`2xl:text-5xl text-[32px] font-gilroy font-medium flex items-end gap-1.5 w-fit ${
|
||||
isToolEnabled && "text-gradient"
|
||||
}`}
|
||||
>
|
||||
<span>
|
||||
<span className="leading-none">
|
||||
{isToolEnabled ? monthlyIncome : oldMonthlyIncome}
|
||||
</span>
|
||||
<span
|
||||
className={`${isToolEnabled && "text-gradient"} text-2xl`}
|
||||
className={`${
|
||||
isToolEnabled && "text-gradient"
|
||||
} 2xl:text-2xl text-xl leading-none`}
|
||||
>
|
||||
млн руб.
|
||||
</span>
|
||||
@@ -322,24 +324,28 @@ function Calc() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-8 py-6 border border-l-0 border-[#3D425C] flex flex-col gap-4">
|
||||
<div className="2xl:px-8 2xl:py-6 px-6 py-4 border border-l-0 border-[#3D425C] flex flex-col gap-4">
|
||||
<p className="text-sm">Статистика продаж</p>
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="flex items-center gap-4">
|
||||
<p className="w-[36px] text-sm">100%</p>
|
||||
<div className="w-[284px] bg-[#212431] rounded-full flex justify-center">
|
||||
<div className="p-3.5 bg-gradient rounded-full w-full">
|
||||
<div className="flex flex-col 2xl:gap-3 gap-1.5">
|
||||
{/* <div className="grid grid-cols-3 items-center gap-4">
|
||||
<p className="w-fit 2xl:text-sm text-xs">100%</p>
|
||||
<div className=" bg-[#212431] rounded-full flex justify-center">
|
||||
<div className="2xl:p-3.5 p-2 bg-gradient rounded-full w-full">
|
||||
<p className="text-center">{consultations}</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm text-[#8088A7]">Консультаций в офисе</p>
|
||||
<p className="2xl:text-sm text-xs text-[#8088A7] whitespace-nowrap">
|
||||
Консультаций в офисе
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-4">
|
||||
<p className="w-[36px] text-sm">{isToolEnabled ? 48 : 30}%</p>
|
||||
<p className="w-[36px] 2xl:text-sm text-xs">
|
||||
{isToolEnabled ? 48 : 30}%
|
||||
</p>
|
||||
<div className="w-[284px] bg-[#212431] rounded-full flex justify-center">
|
||||
<div
|
||||
className={`p-3.5 bg-gradient rounded-full transition-all w-[50%] ${
|
||||
className={`2xl:p-3.5 p-2 bg-gradient rounded-full transition-all w-[50%] ${
|
||||
isToolEnabled ? "w-[60%]" : "w-[50%]"
|
||||
}`}
|
||||
>
|
||||
@@ -348,14 +354,18 @@ function Calc() {
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm text-[#8088A7]">Бронь квартиры</p>
|
||||
<p className="2xl:text-sm text-xs text-[#8088A7] whitespace-nowrap">
|
||||
Бронь квартиры
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-4">
|
||||
<p className="w-[36px] text-sm">{isToolEnabled ? 42 : 30}%</p>
|
||||
<p className="w-[36px] 2xl:text-sm text-xs">
|
||||
{isToolEnabled ? 42 : 30}%
|
||||
</p>
|
||||
<div className="w-[284px] bg-[#212431] rounded-full flex justify-center">
|
||||
<div
|
||||
className={`p-3.5 bg-gradient rounded-full transition-all ${
|
||||
className={`2xl:p-3.5 p-2 bg-gradient rounded-full transition-all ${
|
||||
isToolEnabled ? "w-[32%]" : "w-[22%]"
|
||||
}`}
|
||||
>
|
||||
@@ -364,7 +374,59 @@ function Calc() {
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm text-[#8088A7]">Продажа</p>
|
||||
<p className="2xl:text-sm text-xs text-[#8088A7]">Продажа</p>
|
||||
</div> */}
|
||||
|
||||
<div className="flex gap-4">
|
||||
<div className="flex flex-col 2xl:gap-3 gap-1.5 justify-around">
|
||||
<p className="2xl:text-sm text-xs">100%</p>
|
||||
<p className="2xl:text-sm text-xs">
|
||||
{isToolEnabled ? 48 : 30}%
|
||||
</p>
|
||||
<p className="2xl:text-sm text-xs">
|
||||
{isToolEnabled ? 42 : 30}%
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-full flex flex-col 2xl:gap-3 gap-1.5 justify-around">
|
||||
<div className="bg-[#212431] rounded-full flex justify-center">
|
||||
<div className="bg-gradient 2xl:py-3.5 py-2 rounded-full w-full">
|
||||
<p className="text-center">{consultations}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-[#212431] rounded-full flex justify-center">
|
||||
<div
|
||||
className={`bg-gradient 2xl:py-3.5 py-2 rounded-full ${
|
||||
isToolEnabled ? "w-[60%]" : "w-[50%]"
|
||||
}`}
|
||||
>
|
||||
<p className="text-center">
|
||||
{isToolEnabled ? reservation : oldReservation}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-[#212431] rounded-full flex justify-center">
|
||||
<div
|
||||
className={`bg-gradient 2xl:py-3.5 py-2 rounded-full ${
|
||||
isToolEnabled ? "w-[32%]" : "w-[22%]"
|
||||
}`}
|
||||
>
|
||||
<p className="text-center">
|
||||
{isToolEnabled ? sales : oldSales}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col 2xl:gap-3 gap-1.5 justify-around">
|
||||
<p className="2xl:text-sm text-xs text-[#8088A7] whitespace-nowrap">
|
||||
Консультаций в офисе
|
||||
</p>
|
||||
<p className="2xl:text-sm text-xs text-[#8088A7] whitespace-nowrap">
|
||||
Бронь квартиры
|
||||
</p>
|
||||
<p className="2xl:text-sm text-xs text-[#8088A7] whitespace-nowrap">
|
||||
Продажа
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -34,19 +34,19 @@ function CalcSelect({
|
||||
<div
|
||||
className={`border ${
|
||||
isShow ? "border-[#798FFF]" : "border-[#3D425C]"
|
||||
} p-6 pr-8 flex flex-col justify-center h-24 cursor-pointer transition-colors`}
|
||||
} 2xl:p-6 2xl:pr-8 p-4 pr-6 flex flex-col justify-center h-24 cursor-pointer transition-colors`}
|
||||
onClick={() => setIsShow((prev) => !prev)}
|
||||
>
|
||||
<div className="relative h-full cursor-pointer">
|
||||
<div className="flex flex-col justify-between h-full ">
|
||||
<label className="opacity-50 font-gilroy font-medium leading-none cursor-pointer">
|
||||
<label className="2xl:text-base text-sm opacity-50 font-gilroy font-medium leading-none cursor-pointer">
|
||||
{label}
|
||||
</label>
|
||||
<input
|
||||
readOnly
|
||||
type="text"
|
||||
placeholder={placeholder}
|
||||
className="w-full bg-transparent outline-none cursor-pointer"
|
||||
className="2xl:text-base text-sm w-full bg-transparent outline-none cursor-pointer"
|
||||
value={selectedOption}
|
||||
/>
|
||||
</div>
|
||||
@@ -60,7 +60,7 @@ function CalcSelect({
|
||||
{options.map((option, index) => (
|
||||
<button
|
||||
key={index}
|
||||
className="px-6 py-3 pr-8 hover:bg-white hover:bg-opacity-10 transition-colors w-full text-left flex justify-between"
|
||||
className="2xl:pl-6 2xl:pr-8 2xl:py-3 pl-4 pr-6 py-2 2xl:text-base text-sm hover:bg-white hover:bg-opacity-10 transition-colors w-full text-left flex justify-between"
|
||||
onClick={() => handleClick(option)}
|
||||
>
|
||||
<span>{option}</span>
|
||||
|
||||
@@ -12,7 +12,7 @@ function ExampleCard({ title, company, image }: ExampleCardProps) {
|
||||
<motion.div
|
||||
initial={{ opacity: 0, translateY: 64 }}
|
||||
whileInView={{ opacity: 1, translateY: 0 }}
|
||||
viewport={{ once: true, margin: "-200px" }}
|
||||
viewport={{ once: true, margin: "-10%" }}
|
||||
transition={{ duration: 1, ease: [0.58, 0.12, 0.27, 0.98] }}
|
||||
className="aspect-video bg-cover bg-center bg-no-repeat"
|
||||
style={{ backgroundImage: `url('${image}')` }}
|
||||
@@ -20,7 +20,7 @@ function ExampleCard({ title, company, image }: ExampleCardProps) {
|
||||
<motion.div
|
||||
initial={{ opacity: 0, translateY: 64 }}
|
||||
whileInView={{ opacity: 1, translateY: 0 }}
|
||||
viewport={{ once: true, margin: "-100px" }}
|
||||
viewport={{ once: true, margin: "-10%" }}
|
||||
transition={{ duration: 1, ease: [0.58, 0.12, 0.27, 0.98], delay: 0.2 }}
|
||||
className="flex flex-col gap-1"
|
||||
>
|
||||
|
||||
@@ -18,8 +18,8 @@ function FeatureVideoViewBox({ video }: FeatureVideoViewBoxProps) {
|
||||
videoEl.loop = true;
|
||||
videoEl.playsInline = true;
|
||||
videoEl.preload = "metadata";
|
||||
videoEl.onloadeddata = () => console.log("onloadeddata");
|
||||
videoEl.classList.add("absolute", "h-fit");
|
||||
// videoEl.onloadeddata = () => console.log("onloadeddata");
|
||||
|
||||
videoContainerRef.current.appendChild(videoEl);
|
||||
|
||||
@@ -30,22 +30,7 @@ function FeatureVideoViewBox({ video }: FeatureVideoViewBoxProps) {
|
||||
}
|
||||
}, [video]);
|
||||
|
||||
return (
|
||||
<div ref={videoContainerRef} className="relative h-fit">
|
||||
{/* {videos.map((videoSrc, index) => (
|
||||
<video
|
||||
key={index}
|
||||
src={videoSrc}
|
||||
muted
|
||||
autoPlay
|
||||
playsInline
|
||||
loop
|
||||
onLoadedData={handleLoadedData}
|
||||
className="absolute"
|
||||
/>
|
||||
))} */}
|
||||
</div>
|
||||
);
|
||||
return <div ref={videoContainerRef} className="relative h-fit"></div>;
|
||||
}
|
||||
|
||||
export default FeatureVideoViewBox;
|
||||
|
||||
@@ -8,7 +8,7 @@ interface Heading2Props {
|
||||
function Heading2({ children, className }: Heading2Props) {
|
||||
return (
|
||||
<h2
|
||||
className={`2xl:text-[64px] xl:text-5xl text-[40px] text-gradient font-gilroy font-medium leading-none ${className}`}
|
||||
className={`2xl:text-[64px] xl:text-5xl text-[40px] text-gradient font-gilroy font-medium leading-none w-fit ${className}`}
|
||||
>
|
||||
{children}
|
||||
</h2>
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
import { motion } from "framer-motion";
|
||||
import PlusIcon from "./icons/PlusIcon";
|
||||
|
||||
function MoreProjectButton() {
|
||||
interface MoreProjectButtonProps {
|
||||
handleClick?: () => void;
|
||||
}
|
||||
|
||||
function MoreProjectButton({ handleClick }: MoreProjectButtonProps) {
|
||||
return (
|
||||
<motion.button
|
||||
initial={{ opacity: 0 }}
|
||||
whileInView={{ opacity: 1 }}
|
||||
viewport={{ once: true, margin: "-100px" }}
|
||||
transition={{ duration: 1, ease: [0.58, 0.12, 0.27, 0.98], delay: 0.2 }}
|
||||
className="aspect-[4/3] border border-[#3D425C] rounded-[48px] flex flex-col justify-center items-center gap-2"
|
||||
className="sm:aspect-[4/3] border border-[#3D425C] rounded-[48px] px-6 py-4 flex sm:flex-col sm:justify-center justify-between items-center gap-2"
|
||||
onClick={handleClick}
|
||||
>
|
||||
<PlusIcon />
|
||||
<p className="font-gilroy font-medium leading-none">Показать еще</p>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { CircularProgressbar, buildStyles } from "react-circular-progressbar";
|
||||
|
||||
interface ProgressPieProps {
|
||||
value: number;
|
||||
}
|
||||
|
||||
function ProgressPie({ value }: ProgressPieProps) {
|
||||
return (
|
||||
<CircularProgressbar
|
||||
value={value}
|
||||
strokeWidth={50}
|
||||
styles={buildStyles({
|
||||
trailColor: "#3D425C",
|
||||
pathColor: "#798FFF",
|
||||
strokeLinecap: "butt",
|
||||
})}
|
||||
className="w-5 h-5"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default ProgressPie;
|
||||
@@ -1,53 +1,62 @@
|
||||
import { isAfter, parse } from "date-fns";
|
||||
import { motion } from "framer-motion";
|
||||
import ProgressPie from "./ProgressPie";
|
||||
|
||||
interface ProjectCardProps {
|
||||
title: string;
|
||||
company: string;
|
||||
image: string;
|
||||
releaseDate: string;
|
||||
stream?: boolean;
|
||||
stage?: number;
|
||||
}
|
||||
|
||||
function ProjectCard({
|
||||
title,
|
||||
company,
|
||||
image,
|
||||
releaseDate,
|
||||
stage = 6,
|
||||
stream,
|
||||
}: ProjectCardProps) {
|
||||
const stagePercentage = Math.round((100 / 6) * stage);
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
whileInView={{ opacity: 1 }}
|
||||
viewport={{ once: true, margin: "-100px" }}
|
||||
transition={{ duration: 1, ease: [0.58, 0.12, 0.27, 0.98], delay: 0.2 }}
|
||||
className="aspect-[4/3] p-6 bg-cover bg-center bg-no-repeat flex items-end"
|
||||
style={{
|
||||
background: `linear-gradient(180deg, rgba(20, 22, 31, 0.00) 0%, rgba(20, 22, 31, 0.60) 100%), url('${image}'), lightgray 50% / cover no-repeat`,
|
||||
}}
|
||||
className="group relative aspect-[4/3] p-4 flex items-end overflow-hidden"
|
||||
>
|
||||
<div className="flex flex-col gap-4">
|
||||
<div
|
||||
className="group-hover:scale-110 transition-transform duration-500 absolute top-0 left-0 w-full h-full bg-cover bg-center bg-no-repeat"
|
||||
style={{
|
||||
backgroundImage: `url(${image})`,
|
||||
}}
|
||||
></div>
|
||||
<div className="absolute top-0 left-0 w-full h-full bg-gradient-card"></div>
|
||||
<div className="relative flex flex-col gap-4">
|
||||
<div>
|
||||
<p className="text-2xl font-gilroy font-medium">{title}</p>
|
||||
<p className="text-sm">{company}</p>
|
||||
<p className="2xl:text-2xl text-xl font-gilroy font-medium">
|
||||
{title}
|
||||
</p>
|
||||
<p className="2xl:text-sm text-xs">{company}</p>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2">
|
||||
{isAfter(parse(releaseDate, "dd.MM.yyyy", new Date()), new Date()) ? (
|
||||
<div className="bg-[#14161F] px-4 py-2.5 rounded-full w-fit">
|
||||
<div className="flex gap-1">
|
||||
{stage < 6 ? (
|
||||
<div className="bg-[#14161F] px-3 py-2 rounded-full w-fit flex items-center gap-1">
|
||||
<p className="font-gilroy font-medium leading-none">
|
||||
Релиз {releaseDate}
|
||||
{stagePercentage}%
|
||||
</p>
|
||||
<ProgressPie value={stagePercentage} />
|
||||
</div>
|
||||
) : (
|
||||
<div className="bg-gradient px-4 py-2.5 rounded-full w-fit">
|
||||
<div className="bg-gradient px-3 py-2 rounded-full w-fit">
|
||||
<p className="font-gilroy font-medium leading-none">Сдан</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{stream && (
|
||||
<div className="bg-[#14161F] px-4 py-2.5 rounded-full w-fit flex items-center gap-2">
|
||||
<div className="bg-[#14161F] px-3 py-2 rounded-full w-fit flex items-center gap-2">
|
||||
<div className="w-2 h-2 bg-gradient rounded-full"></div>
|
||||
<p className="font-gilroy font-semibold leading-none text-gradient">
|
||||
Stream
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
/* eslint-disable react-hooks/rules-of-hooks */
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { motion } from "framer-motion";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import ArrowLeftIcon from "./icons/ArrowLeftIcon";
|
||||
import ArrowRightIcon from "./icons/ArrowRightIcon";
|
||||
import { useSwipeable } from "react-swipeable";
|
||||
|
||||
function VideoSliderMobile() {
|
||||
const [items] = useState<any[]>([
|
||||
{
|
||||
title: "Виртуальный тур по жилому комплексу",
|
||||
desc: "Клиент лично оценит угол инсоляции, малые архитектурные формы и ландшафт, перемещаясь по комплексу с помощью тапа.",
|
||||
video: "https://graff.estate/videos/features/virtual_tour.mp4",
|
||||
},
|
||||
{
|
||||
title: "Вся инфрастуктура на одном экране",
|
||||
desc: "Возможность оценить инфраструктуру района покажет важные для клиента точки интереса и время, за которое он сможет до них дойти.",
|
||||
video: "https://graff.estate/videos/features/nks_infra.mp4",
|
||||
},
|
||||
{
|
||||
title: "Конфигуратор интерьера",
|
||||
desc: "Клиент может свободно выбирать мебель и дизайн с помощью конфигуратора интерьера. Возможно выбрать стиль всей квартиры или изменить отдельные детали.",
|
||||
video: "https://graff.estate/videos/features/uralsky.mp4",
|
||||
},
|
||||
{
|
||||
title: "Параметрический поиск квартир",
|
||||
desc: "Фильтр позволит отметить конкретные преимущества, определить количество комнат, желаемый этаж, цену, и получить выборку подходящих вариантов.",
|
||||
video: "https://graff.estate/videos/features/parametric.mp4",
|
||||
},
|
||||
{
|
||||
title: "Любой рендер за несколько секунд",
|
||||
desc: "Когда для рекламы вам понадобится любой объект с любого ракурса, просто сделайте фотографию внутри презентации.",
|
||||
video: "https://graff.estate/videos/features/render.mp4",
|
||||
},
|
||||
{
|
||||
title: "Формирование вишлиста",
|
||||
desc: "Клиент может добавить варианты квартир в избранное, сравнить их между собой по основным параметрам и выбрать свою будущую квартиру.",
|
||||
video: "https://graff.estate/videos/features/wish.mp4",
|
||||
},
|
||||
{
|
||||
title: "Интеграция с CRM-системой",
|
||||
desc: "Приложение передает информацию о клиенте в CRM-систему застройщика и получает актуальную информацию по ценам и статусам квартир.",
|
||||
video: "https://graff.estate/videos/features/integra_crm.mp4",
|
||||
},
|
||||
{
|
||||
title: "Отправка коммерческого предложения",
|
||||
desc: "Коммерческое предложение с выбранными квартирами может быть отправлено клиенту на почту или распечатано и отдано лично в руки.",
|
||||
video: "https://graff.estate/videos/features/send.mp4",
|
||||
},
|
||||
{
|
||||
title: "Интерактивная инсоляция",
|
||||
desc: "Функция позволяет в режиме реального времени увидеть уровень освещенности выбранной квартиры, а если вы изучаете экстерьер жилого комплекса – функция покажет архитектурную подсветку.",
|
||||
video: "",
|
||||
},
|
||||
{
|
||||
title: "Подбор квартир на генплане",
|
||||
desc: "Сделать генплан удобным инструментом выбора квартиры поможет подсветка выбранных квартир прямо на фасаде Жилого комплекса.",
|
||||
video: "",
|
||||
},
|
||||
]);
|
||||
|
||||
const [activeIndex, setActiveIndex] = useState<number>(0);
|
||||
const videoRefs = items.map(() => useRef<HTMLVideoElement>(null));
|
||||
const handlers = useSwipeable({
|
||||
onSwiped: (e) => {
|
||||
if (e.dir === "Left") {
|
||||
handleClickNext();
|
||||
}
|
||||
|
||||
if (e.dir === "Right") {
|
||||
handleClickPrev();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
function handleClickPrev() {
|
||||
if (activeIndex === 0) {
|
||||
setActiveIndex(items.length - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
setActiveIndex((prev) => prev - 1);
|
||||
}
|
||||
|
||||
function handleClickNext() {
|
||||
if (activeIndex === items.length - 1) {
|
||||
setActiveIndex(0);
|
||||
return;
|
||||
}
|
||||
|
||||
setActiveIndex((prev) => prev + 1);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
items.forEach((_, index) => {
|
||||
if (activeIndex === index) {
|
||||
videoRefs[index].current?.play();
|
||||
} else {
|
||||
videoRefs[index].current?.pause();
|
||||
}
|
||||
});
|
||||
}, [activeIndex]);
|
||||
|
||||
return (
|
||||
<div {...handlers} className="xl:hidden flex flex-col sm:gap-6 gap-4 border-b border-[#3D425C] pb-5">
|
||||
<div
|
||||
// ref={videosContainerRef}
|
||||
className={`relative flex sm:gap-[88px] items-start transition-all duration-500`}
|
||||
style={{ left: `-${activeIndex * 100}%` }}
|
||||
>
|
||||
{items.map((item, index) => (
|
||||
<motion.video
|
||||
ref={videoRefs[index]}
|
||||
key={index}
|
||||
src={item.video}
|
||||
muted
|
||||
loop
|
||||
playsInline
|
||||
preload="metadata"
|
||||
className={`relative aspect-video transition-all duration-500 sm:w-[calc(100%-88px)] ${
|
||||
index === activeIndex
|
||||
? ""
|
||||
: "sm:scale-[70%] scale-[80%] sm:-translate-y-[15%] -translate-y-[10%] sm:-translate-x-[calc(15%+88px-12px)] -translate-x-[calc(10%-8px)]"
|
||||
}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between sm:gap-[30px] gap-3 sm:h-auto h-[168px]">
|
||||
<div className="flex flex-col gap-3">
|
||||
<p className="text-xl font-gilroy font-medium">
|
||||
{items[activeIndex].title}
|
||||
</p>
|
||||
<p className="text-sm">{items[activeIndex].desc}</p>
|
||||
</div>
|
||||
<div className="relative flex flex-col items-center gap-4">
|
||||
<div className="sm:absolute -top-[64px]">
|
||||
<p className="sm:text-2xl text-xl font-gilroy font-medium">
|
||||
{activeIndex + 1}/{items.length}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2 self-end">
|
||||
<button
|
||||
onClick={handleClickNext}
|
||||
className="sm:p-4 p-2 border border-[#3D425C] rounded-full outline-none"
|
||||
>
|
||||
<ArrowRightIcon />
|
||||
</button>
|
||||
<button
|
||||
onClick={handleClickPrev}
|
||||
className="sm:p-4 p-2 border border-[#3D425C] rounded-full outline-none"
|
||||
>
|
||||
<ArrowLeftIcon />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default VideoSliderMobile;
|
||||
@@ -0,0 +1,25 @@
|
||||
interface IconProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
function ArrowLeftIcon({ className }: IconProps) {
|
||||
return (
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={className}
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M19 12C19 11.4477 18.5523 11 18 11L8.5183 11L13.0496 6.72759C13.4515 6.34871 13.4701 5.71582 13.0912 5.31398C12.7124 4.91215 12.0795 4.89353 11.6776 5.27241L5.31399 11.2724C5.11359 11.4613 5 11.7246 5 12C5 12.2754 5.11359 12.5386 5.31399 12.7276L11.6776 18.7276C12.0795 19.1065 12.7124 19.0878 13.0912 18.686C13.4701 18.2842 13.4515 17.6513 13.0496 17.2724L8.5183 13L18 13C18.5523 13 19 12.5523 19 12Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default ArrowLeftIcon;
|
||||
@@ -1,17 +1,22 @@
|
||||
function ArrowRightIcon() {
|
||||
interface IconProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
function ArrowRightIcon({ className }: IconProps) {
|
||||
return (
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 32 32"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={className}
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M6.66667 16.0003C6.66667 16.7367 7.26363 17.3337 8 17.3337L20.6423 17.3337L14.6005 23.0302C14.0647 23.5354 14.0399 24.3792 14.545 24.915C15.0502 25.4508 15.8941 25.4756 16.4298 24.9704L24.9147 16.9705C25.1819 16.7185 25.3333 16.3676 25.3333 16.0003C25.3333 15.6331 25.1819 15.2821 24.9147 15.0302L16.4298 7.03021C15.8941 6.52504 15.0502 6.54986 14.545 7.08565C14.0399 7.62143 14.0647 8.46528 14.6005 8.97045L20.6423 14.667L8 14.667C7.26363 14.667 6.66667 15.264 6.66667 16.0003Z"
|
||||
fill="white"
|
||||
d="M5 12C5 12.5523 5.44771 13 6 13L15.4817 13L10.9504 17.2724C10.5485 17.6513 10.5299 18.2842 10.9088 18.686C11.2876 19.0879 11.9205 19.1065 12.3224 18.7276L18.686 12.7276C18.8864 12.5387 19 12.2754 19 12C19 11.7246 18.8864 11.4614 18.686 11.2724L12.3224 5.27241C11.9205 4.89354 11.2876 4.91215 10.9088 5.31399C10.5299 5.71583 10.5485 6.34872 10.9504 6.72759L15.4817 11L6 11C5.44772 11 5 11.4477 5 12Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -70,3 +70,17 @@ body {
|
||||
height: 6px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.bg-gradient-card {
|
||||
content: "";
|
||||
/* position: absolute; */
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(20, 22, 31, 0) 0%,
|
||||
rgba(20, 22, 31, 0.6) 100%
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1404,6 +1404,11 @@ queue-microtask@^1.2.2:
|
||||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
||||
|
||||
react-circular-progressbar@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/react-circular-progressbar/-/react-circular-progressbar-2.1.0.tgz#99e5ae499c21de82223b498289e96f66adb8fa3a"
|
||||
integrity sha512-xp4THTrod4aLpGy68FX/k1Q3nzrfHUjUe5v6FsdwXBl3YVMwgeXYQKDrku7n/D6qsJA9CuunarAboC2xCiKs1g==
|
||||
|
||||
react-dom@^18.2.0:
|
||||
version "18.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
|
||||
@@ -1440,6 +1445,11 @@ react-router@6.18.0:
|
||||
dependencies:
|
||||
"@remix-run/router" "1.11.0"
|
||||
|
||||
react-swipeable@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/react-swipeable/-/react-swipeable-7.0.1.tgz#cd299f5986c5e4a7ee979839658c228f660e1e0c"
|
||||
integrity sha512-RKB17JdQzvECfnVj9yDZsiYn3vH0eyva/ZbrCZXZR0qp66PBRhtg4F9yJcJTWYT5Adadi+x4NoG53BxKHwIYLQ==
|
||||
|
||||
react@^18.2.0:
|
||||
version "18.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
|
||||
|
||||