updated main page

This commit is contained in:
2024-08-02 20:02:12 +05:00
parent ed374337cc
commit b759a42e6c
24 changed files with 338 additions and 175 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

+12
View File
@@ -0,0 +1,12 @@
<svg width="376" height="250" viewBox="0 0 376 250" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_3520_13373)">
<ellipse cx="376.59" cy="238.207" rx="174.425" ry="113.415" transform="rotate(-6.77723 376.59 238.207)" fill="#5545AC"/>
</g>
<defs>
<filter id="filter0_f_3520_13373" x="-297.141" y="-376.301" width="1347.46" height="1229.02" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="250" result="effect1_foregroundBlur_3520_13373"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 677 B

+9
View File
@@ -0,0 +1,9 @@
<svg width="180" height="127" viewBox="0 0 180 127" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.4" d="M2 125C103.5 125 178 53.5 178 2.50439" stroke="url(#paint0_linear_3520_13370)" stroke-width="4" stroke-linecap="round"/>
<defs>
<linearGradient id="paint0_linear_3520_13370" x1="188" y1="-1.49999" x2="-19.6824" y2="106.334" gradientUnits="userSpaceOnUse">
<stop stop-color="#798FFF"/>
<stop offset="1" stop-color="#798FFF" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.
+5 -3
View File
@@ -1,12 +1,14 @@
import { Motivation } from '@/components/Main/Motivation';
import Projects from '@/components/Main/Projects';
import StatsMap from '@/components/Main/StatsMap';
import { Projects } from '@/components/Main/Projects';
import { Showreel } from '@/components/Main/Showreel';
import { Statistics } from '@/components/Main/Statistics';
export default function Home() {
return (
<div>
<Motivation />
<StatsMap />
<Showreel />
<Statistics />
<Projects />
</div>
);
+4 -8
View File
@@ -1,7 +1,5 @@
'use client';
import { BurgerIcon } from '@/components/icons/BurgerIcon';
import { CloseIcon } from '@/components/icons/CloseIcon';
import { LogoIcon } from '@/components/icons/LogoIcon';
import { LogoWithTextIcon } from '@/components/icons/LogoWithTextIcon';
import { ModalWithForm } from '@/components/Layout/ModalWithForm';
@@ -9,8 +7,6 @@ import { useWindowWidth } from '@/hooks/useWindowWidth';
import { useModalStore } from '@/stores/useModalStore';
import { BurgerLink } from '@/ui/BurgerLink';
import { Button } from '@/ui/Button';
import { ChooseLang } from '@/ui/ChooseLang';
import { LangToggler } from '@/ui/LangToggler';
import { NavLink } from '@/ui/NavLink';
import { motion } from 'framer-motion';
import Link from 'next/link';
@@ -55,14 +51,14 @@ export function Header() {
>
Оставить заявку
</Button>
<LangToggler />
{/* <LangToggler />
<button
ref={menuBtnRef}
onClick={() => setMenuOpen(prev => !prev)}
className="px-6 py-5 xl:hidden border-[#3D425C] max-sm:border-l"
>
{!menuOpen ? <BurgerIcon /> : <CloseIcon />}
</button>
</button> */}
</div>
</nav>
{menuOpen && (
@@ -95,8 +91,8 @@ export function Header() {
>
Оставить заявку
</Button>
<ChooseLang currentLang="RU" />
<ChooseLang currentLang="EN" />
{/* <ChooseLang currentLang="RU" />
<ChooseLang currentLang="EN" /> */}
</div>
</motion.div>
)}
-2
View File
@@ -4,7 +4,6 @@ import { Products } from '@/consts/Products';
import Link from 'next/link';
import { useRef, useState } from 'react';
import { useOnClickOutside } from 'usehooks-ts';
import { ArrowDownIcon } from '../icons/ArrowDown';
export function ProductsList() {
const [isOpen, setIsOpen] = useState(false);
@@ -21,7 +20,6 @@ export function ProductsList() {
onClick={() => setIsOpen(prev => !prev)}
>
Продукты
<ArrowDownIcon className="max-xl:hidden" />
</button>
<div className="grid grid-cols-2 gap-y-3 xl:hidden bg-[#14161F] pl-10 pb-6">
{Products.map(product => (
+23 -24
View File
@@ -1,33 +1,32 @@
import Image from 'next/image';
import { Title } from '../../ui/Title';
import { ArrowDownIcon } from '../icons/ArrowDownIcon';
import { SkolkovoIcon } from '../icons/SkolkovoIcon';
export function Motivation() {
return (
<div className="lg:pt-20 lg:px-6 lg:pb-40 pb-20 flex flex-col gap-[64px]">
<div className="flex justify-between">
<div>
<Title className="mb-10">
Интерактивный инструмент
<br />
продаж
<span className="text-gradient"> для застройщиков</span>
</Title>
<h3 className="h3 font-semibold">
Помогаем девелоперам эффективно демонстрировать свой объект.
<br />
Продавать больше и быстрее.
</h3>
</div>
<SkolkovoIcon className="mt-4" />
<div className="lg:pt-40 lg:px-6 lg:pb-24 pb-20">
<div className="flex justify-between mb-12">
<Title>
Интерактивный инструмент
<br />
продаж
<span className="text-gradient"> для застройщиков</span>
</Title>
<SkolkovoIcon className="mt-4 mr-2" />
</div>
<div className="flex justify-between">
<h3 className="h3 font-medium min-w-[50vw]">
Помогаем девелоперам эффективно демонстрировать свой объект.
<br />
Продавать больше и быстрее.
</h3>
<div className="flex gap-x-2 max-h-6 self-end">
<p className="m-text">Используйте скролл</p>
<div className="p-[7px] rounded-full bg-white w-6 h-6 flex mb-0">
<ArrowDownIcon />
</div>
</div>
</div>
<Image
src="/img/home-page/1.jpg"
alt=""
width={1160}
height={679}
priority
/>
</div>
);
}
+2 -4
View File
@@ -1,6 +1,6 @@
import Image from 'next/image';
const Projects = () => {
export function Projects() {
return (
<section className="grid grid-cols-12 px-6">
<p className="text-[32px] text-white col-span-6 col-start-4">
@@ -89,6 +89,4 @@ const Projects = () => {
</div>
</section>
);
};
export default Projects;
}
+99
View File
@@ -0,0 +1,99 @@
'use client';
import { useCallback, useEffect, useRef, useState } from 'react';
import { LoadingIcon } from '../icons/LoadingIcon';
import { PauseIcon } from '../icons/PauseIcon';
import { PlayIcon } from '../icons/PlayIcon';
export function Showreel() {
const [isPlaying, setIsPlaying] = useState(false);
const [hovered, setHovered] = useState(false);
const [isBuffering, setIsBuffering] = useState(false);
function handleOnPlaying() {
setIsBuffering(false);
}
function handleOnWaiting() {
setIsBuffering(true);
}
const ref = useRef<HTMLDivElement>(null);
const videoRef = useRef<HTMLVideoElement>(null);
const addMouseOut = useCallback(
() =>
ref.current?.addEventListener('mouseout', () => setHovered(isPlaying)),
[isPlaying],
);
const removeMouseOut = useCallback(
() =>
ref.current?.removeEventListener('mouseout', () => setHovered(isPlaying)),
[isPlaying],
);
useEffect(() => {
const video = ref.current;
video?.addEventListener('mouseover', () => setHovered(true));
addMouseOut();
return () => {
video?.removeEventListener('mouseover', () => setHovered(true));
removeMouseOut();
};
}, [isPlaying, addMouseOut, removeMouseOut]);
return (
<div className="lg:mb-[200px] lg:px-6">
<div ref={ref} className="relative flex justify-center items-center">
<video
ref={videoRef}
src="/videos/showreel_1080p_4000k_h264.mp4"
muted
loop
className={
'w-full object-cover ' +
(hovered ? 'aspect-video' : 'aspect-[1552/616]')
}
onPlaying={handleOnPlaying}
onWaiting={handleOnWaiting}
/>
{hovered && (
<button
onClick={() => {
if (!isPlaying) {
videoRef.current?.play();
setIsPlaying(true);
} else {
videoRef.current?.pause();
setIsPlaying(false);
}
}}
className="absolute z-30 mx-auto p-8 rounded-full border"
>
{isPlaying ? (
<PauseIcon className="w-10 h-10" />
) : (
<PlayIcon className="w-10 h-10" />
)}
</button>
)}
<div
className={
'absolute aspect-video w-full h-full flex justify-center items-center bg-black bg-opacity-50 transition-opacity ' +
(isBuffering ? 'opacity-100' : 'opacity-0')
}
>
<div className="flex gap-4 items-center">
<span>
<LoadingIcon className="animate-spin h-5 w-5" />
</span>
<span className="">Загружаем шоурил...</span>
</div>
</div>
</div>
</div>
);
}
+117
View File
@@ -0,0 +1,117 @@
import { LineThrow } from '@/ui/LineThrow';
import { Title } from '@/ui/Title';
import { Manrope } from 'next/font/google';
import Image from 'next/image';
import { CubeIcon } from '../icons/CubeIcon';
const manrope = Manrope({ subsets: ['latin'] });
export function Statistics() {
return (
<section className="lg:px-6">
<Title className="mb-20">
Продавайте недвижимость <br />
<span className="text-gradient">проще и </span>
<LineThrow>быстрее</LineThrow>
<span className="text-gradient"> дороже</span>
</Title>
<div className="grid grid-cols-4 border-t border-[#3D425C]">
<div className="col-span-1 pt-10 border-r border-b border-[#3D425C] accent font-medium">
Мы собрали статистику за 13 лет работы с застройщиками, реализовав 40
проектов
</div>
<div className="col-start-2 col-span-full py-10 pl-4 flex items-center justify-center border-b border-[#3D425C]">
<Image
src={'/img/home-page/map.png'}
alt={''}
fill
className="!static object-cover"
/>
</div>
<div className="col-span-1 pt-10 flex gap-1 items-center opacity-60 h-fit">
<CubeIcon />
<p className="descriptor uppercase font-medium">
экономическая эффективность
</p>
</div>
<div className="flex flex-wrap col-span-3 py-4 pl-4 gap-4">
<div className="p-6 w-[376px] h-[250px] flex flex-col bg-[url(/img/home-page/highlight.svg)] bg-no-repeat">
<p className="m-text">
Конверсия из консультации в бронирование <br /> увеличивается на
</p>
<div className="flex flex-1 relative">
<p
className="font-bold absolute -bottom-[5px] text-[#52587A]"
style={{ fontFamily: manrope.style.fontFamily }}
>
30%
</p>
<p
className="font-bold absolute top-[7px] left-[202px] text-[#798FFF]"
style={{ fontFamily: manrope.style.fontFamily }}
>
48%
</p>
<Image
src={'/img/home-page/increasing.svg'}
width="176"
height="122"
alt={''}
className="bottom-1 left-10 max-h-[122px] absolute"
/>
<p className="h1 self-end absolute right-0">
18<span className="h3 font-medium">%</span>
</p>
</div>
</div>
<div className="p-6 flex flex-col w-[376px] h-[250px] bg-[url(/img/home-page/highlight.svg)] bg-no-repeat">
<p className="m-text">
Конверсия из консультации в бронирование <br /> увеличивается на
</p>
<div className="flex flex-1 relative">
<p
className="font-bold absolute -bottom-[5px] text-[#52587A]"
style={{ fontFamily: manrope.style.fontFamily }}
>
30%
</p>
<p
className="font-bold absolute top-[7px] left-[202px] text-[#798FFF]"
style={{ fontFamily: manrope.style.fontFamily }}
>
42%
</p>
<Image
src={'/img/home-page/increasing.svg'}
width="176"
height="122"
alt={''}
className="bottom-1 left-10 max-h-[122px] absolute"
/>
<p className="h1 self-end absolute right-0">
12<span className="h3 font-medium">%</span>
</p>
</div>
</div>
<div className="flex flex-col p-6 w-[376px] h-[250px] bg-[url(/img/home-page/building.png),url(/img/home-page/highlight.png),url(/img/home-page/highlight.svg)]g">
<p className="m-text">
Время реализации проекта <br /> сокращается до
</p>
<p className="absolute bottom-6 right-6 text-[#fff] text-[96px] tracking-[-2%] leading-[24px]">
2<span className="text-[24px] font-semibold">раз</span>
</p>
</div>
<div className="flex flex-col border-l border-t border-[#3D425C] p-6 relative col-start-3 row-start-2">
<p>
Время на подготовку рекламных <br /> материалов сокращается до
</p>
<p className="absolute bottom-6 right-6 text-[#fff] text-[96px] tracking-[-2%] leading-[24px]">
4<span className="text-[24px] font-semibold">раз</span>
</p>
</div>
</div>
</div>
</section>
);
}
-96
View File
@@ -1,96 +0,0 @@
import { LineThrow } from '@/ui/LineThrow';
import { Title } from '@/ui/Title';
import Image from 'next/image';
import EconomicEfficiencyIcon from '../icons/EconomicEfficiencyIcon';
const StatsMap = () => {
return (
<section className="lg:px-6">
<Title>
Продавайте недвижимость <br />
<span className="text-gradient">проще и </span>
<LineThrow>быстрее</LineThrow>
<span className="text-gradient"> дороже</span>
</Title>
<div className="grid grid-cols-4 grid-rows-4 my-16 border border-[#3D425C]">
<div className="col-span-1 row-span-2 text-white bg-[#3D425C] p-6">
<p className="text-[32px]">
Мы собрали статистику за 13 лет работы с застройщиками,
реализовав 40 проектов
</p>
</div>
<div className="col-start-2 col-span-full row-span-2 px-[124px] py-10 flex items-center justify-center border-b border-[#3D425C]">
<Image
src={'/img/home-page/map.png'}
alt={''}
width={936}
height={490}
/>
</div>
<div className="col-span-1 p-6 row-span-2">
<div className="flex gap-1 items-center text-[#a1a2a5]">
<EconomicEfficiencyIcon />
<p className="text-sm ">экономическая эффективность</p>
</div>
</div>
<div className="col-start-2 col-span-full row-span-2 grid grid-cols-3 grid-rows-2">
<div className="flex flex-col border-x border-b border-[#3D425C] p-6 relative">
<p>
Конверсия из консультации в бронирование <br /> увеличивается на
</p>
<Image
src={'/img/home-page/2.png'}
alt={''}
className="w-full h-full"
width={346}
height={179}
/>
<p className="absolute bottom-6 right-6 text-[#fff] text-[96px] tracking-[-2%] leading-[24px]">
18<span className="text-[24px] font-semibold">%</span>
</p>
</div>
<div className="flex flex-col border-r border-b border-[#3D425C] p-6 relative">
<p>
Конверсия из бронирования в продажу <br /> увеличивается на
</p>
<Image
src={'/img/home-page/3.png'}
alt={''}
className="w-full h-full"
width={346}
height={179}
/>
<p className="absolute bottom-6 right-6 text-[#fff] text-[96px] tracking-[-2%] leading-[24px]">
12<span className="text-[24px] font-semibold">%</span>
</p>
</div>
<div className="flex flex-col border-x border-[#3D425C] p-6 relative col-start-1 row-start-2">
<p>
Время реализации проекта <br /> сокращается до
</p>
{/* <Image
src={'/img/home-page/3.png'}
alt={''}
className="w-full h-full"
width={346}
height={179}
/> */}
<p className="absolute bottom-6 right-6 text-[#fff] text-[96px] tracking-[-2%] leading-[24px]">
2<span className="text-[24px] font-semibold">раз</span>
</p>
</div>
<div className="flex flex-col border-l border-t border-[#3D425C] p-6 relative col-start-3 row-start-2">
<p>
Время на подготовку рекламных <br /> материалов сокращается до
</p>
<p className="absolute bottom-6 right-6 text-[#fff] text-[96px] tracking-[-2%] leading-[24px]">
4<span className="text-[24px] font-semibold">раз</span>
</p>
</div>
</div>
</div>
</section>
);
};
export default StatsMap;
+1 -1
View File
@@ -1,7 +1,7 @@
import { useSearchParams } from 'next/navigation';
import { useState } from 'react';
import { YearFilterItem } from './YearFilterItem';
import { ArrowDownIcon } from './icons/ArrowDown';
import { ArrowDownIcon } from './icons/ArrowDownIcon';
export function YearFilterDropdown({ years }: { years: string[] }) {
const [isOpen, setIsOpen] = useState(false);
-22
View File
@@ -1,22 +0,0 @@
export function ArrowDownIcon({ className = '' }: { className?: string }) {
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
className={className}
color="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<g opacity="0.8">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M11.2929 16.7071C11.6834 17.0976 12.3166 17.0976 12.7071 16.7071L19.7071 9.70713C20.0976 9.31661 20.0976 8.68344 19.7071 8.29292C19.3165 7.90239 18.6834 7.90239 18.2928 8.29292L12 14.5858L5.70711 8.29292C5.31658 7.90239 4.68342 7.90239 4.29289 8.29292C3.90237 8.68344 3.90237 9.31661 4.29289 9.70713L11.2929 16.7071Z"
fill="white"
/>
</g>
</svg>
);
}
+14
View File
@@ -0,0 +1,14 @@
export function ArrowDownIcon({ className = '' }: { className?: string }) {
return (
<svg
width="12"
height="12"
viewBox="0 0 12 12"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<path d="M6 10V0M6 10L11 5M6 10L1 5" stroke="#14161F" strokeWidth="1.5" />
</svg>
);
}
@@ -1,4 +1,8 @@
const EconomicEfficiencyIcon = () => {
export function EconomicEfficiencyIcon({
className = '',
}: {
className?: string;
}) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
@@ -6,6 +10,7 @@ const EconomicEfficiencyIcon = () => {
height="16"
fill="none"
viewBox="0 0 16 16"
className={className}
>
<path
fill="currentColor"
@@ -13,6 +18,6 @@ const EconomicEfficiencyIcon = () => {
></path>
</svg>
);
};
}
export default EconomicEfficiencyIcon;
+24
View File
@@ -0,0 +1,24 @@
export function LoadingIcon({ className = '' }: { className?: string }) {
return (
<svg
className={className}
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
></circle>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
);
}
+15
View File
@@ -0,0 +1,15 @@
export function PauseIcon({ className = '' }: { className?: string }) {
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<rect x="5" y="3" width="5" height="18" rx="1" fill="white" />
<rect x="14" y="3" width="5" height="18" rx="1" fill="white" />
</svg>
);
}
+4 -5
View File
@@ -1,16 +1,15 @@
export function PlayIcon({ className = '' }: { className?: string }) {
return (
<svg
width="27"
height="31"
viewBox="0 0 27 31"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
color="currentColor"
>
<path
d="M24.9373 12.6581C27.1501 13.9356 27.1501 17.1295 24.9373 18.407L5.0224 29.9049C2.80963 31.1824 0.043673 29.5855 0.0436731 27.0304L0.0436741 4.0347C0.0436742 1.47962 2.80963 -0.117308 5.0224 1.16023L24.9373 12.6581Z"
d="M19.5708 11.1425C20.2182 11.5309 20.2182 12.4691 19.5708 12.8575L7.5145 20.0913C6.84797 20.4912 6 20.0111 6 19.2338L6 4.76619C6 3.9889 6.84797 3.50878 7.5145 3.9087L19.5708 11.1425Z"
fill="white"
/>
</svg>
+1 -1
View File
@@ -1,6 +1,6 @@
'use client';
import { ArrowDownIcon } from '@/components/icons/ArrowDown';
import { ArrowDownIcon } from '@/components/icons/ArrowDownIcon';
import { useLanguageStore } from '@/stores/useLanguageStore';
import { motion } from 'framer-motion';
import { useRef, useState } from 'react';
-6
View File
@@ -11,11 +11,5 @@ export function LineThrow({
{' '}
{children}
</span>
// <span
// className={`'text-[#52587A] relative before:content-[""] before:absolute before:top-[calc(50%+3px)] before:left-0 before:w-full before:h-[6px] before:bg-[#fff] before:block' + ${className}`}
// >
// {' '}
// {children}
// </span>
);
}
+1 -1
View File
@@ -4,5 +4,5 @@ export function Title({
className = '',
children,
}: PropsWithChildren<{ className?: string }>) {
return <h1 className={'font-medium h1 ' + className}>{children}</h1>;
return <h1 className={'font-medium h2 ' + className}>{children}</h1>;
}