upd fixed

This commit is contained in:
2024-10-25 13:32:41 +05:00
parent 94efdfef72
commit 0fd6eb6fb3
38 changed files with 289 additions and 213 deletions
+6 -1
View File
@@ -1,6 +1,11 @@
'use client';
import dynamic from 'next/dynamic';
import { usePathname } from 'next/navigation';
export default function Layout({ children }: { children: React.ReactNode }) {
const pathname = usePathname();
const DynamicRelevantSlider = dynamic(
() =>
import('@/components/pages/BlogPage/RelevantSlider').then(
@@ -12,7 +17,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
return (
<section>
{children}
<DynamicRelevantSlider />
{!pathname.endsWith('edit') && <DynamicRelevantSlider />}
</section>
);
}
+1 -1
View File
@@ -44,7 +44,7 @@ export default function BlogPage() {
input: {
blocks: '[]',
cardImage: '',
createdAt: new Date().toISOString().split('T')[0],
createdAt: new Date().toISOString(),
description: '',
posterImage: '',
tags: [],
+28 -26
View File
@@ -34,32 +34,34 @@ export default function ProjectsPage() {
});
return (
<div className="lg:pt-20 pt-14">
<div className="flex justify-between items-start">
<Title className="lg:mb-14 sm:mb-8 mb-4">Проекты</Title>
{data?.checkAuth.__typename === 'CheckAuthResponse' &&
data.checkAuth.isAuth && (
<Button
onClick={() =>
setModal(
<ProjectFormModal
action={'create'}
onSubmit={(data: IAddProjectFormInput) => {
addProject({ variables: { input: data } });
setModal(null, '');
}}
/>,
'addProject',
)
}
>
Добавить проект
</Button>
)}
</div>
<div className="sm:pb-5 pb-4 gap-4 flex flex-wrap justify-between border-b border-[#3D425C] sm:grid grid-cols-12">
<ProjectsFilters />
<CitySelector />
<div className="lg:space-y-14 sm:space-y-8 space-y-4">
<div className="lg:space-y-10 space-y-5">
<div className="flex justify-between">
<Title>Проекты</Title>
{data?.checkAuth.__typename === 'CheckAuthResponse' &&
data.checkAuth.isAuth && (
<Button
onClick={() =>
setModal(
<ProjectFormModal
action={'create'}
onSubmit={(data: IAddProjectFormInput) => {
addProject({ variables: { input: data } });
setModal(null, '');
}}
/>,
'addProject',
)
}
>
Добавить проект
</Button>
)}
</div>
<div className="sm:pb-5 pb-4 gap-4 flex flex-wrap justify-between sm:grid grid-cols-12">
<ProjectsFilters />
<CitySelector />
</div>
</div>
<ProjectsList />
</div>
+1 -1
View File
@@ -125,7 +125,7 @@ body {
}
.s-text {
@apply text-base;
@apply text-base leading-[17.5px];
}
.l-caption {
+3 -3
View File
@@ -17,7 +17,7 @@ export function Feedback() {
return (
<div
id="contacts"
className="sm:grid lg:grid-cols-12 sm:grid-cols-2 lg:gap-x-4 sm:gap-x-14 lg:gap-y-[68px] pb-20 pt-[70px]"
className="sm:grid lg:grid-cols-12 sm:grid-cols-2 lg:gap-x-4 sm:gap-x-14 lg:gap-y-[68px] pb-20 pt-[200px]"
>
<h2 className="font-medium lg:col-span-7 sm:col-span-full h2 max-lg:mb-6">
Хотите увеличить конверсию? <br />
@@ -26,14 +26,14 @@ export function Feedback() {
<Button
color="primary"
icon={<SendIcon />}
className="self-end row-start-2 px-6 py-4 lg:col-span-3 sm:max-lg:mb-20 max-sm:mb-14"
className="self-end row-start-2 px-6 py-4 lg:col-span-3 sm:max-lg:mb-20 max-sm:mb-14 btn-text"
width="full"
onClick={() => setModal(<ModalWithForm />, 'form')}
>
Оставить заявку
</Button>
<div className="space-y-3 lg:col-start-9 lg:col-span-4 sm:col-span-1 sm:col-start-1 max-sm:mb-8">
<h4 className="mb-1 text-xl font-medium">Свяжитесь с нами</h4>
<h4 className="mb-1 h4 font-medium">Свяжитесь с нами</h4>
<Button
color="secondary"
className="py-4"
+2 -2
View File
@@ -25,7 +25,7 @@ export function Footer() {
<Contact type="email" text="info@graff.tech" />
<Contact type="phone" text="8 800 770 00 67" />
</div>
<div className="font-medium p-[14px] border border-[#3D425C] rounded-full m-text">
<div className="font-medium p-[14px] border border-[#3D425C] rounded-full text-sm">
RU
</div>
</div>
@@ -34,7 +34,7 @@ export function Footer() {
<Contact type="email" text="sam@graff.tech" />
<Contact type="phone" text="+971 58 506 0097" />
</div>
<div className="font-medium py-[14px] px-[10px] border border-[#3D425C] rounded-full m-text">
<div className="font-medium py-[14px] px-[10px] border border-[#3D425C] rounded-full text-sm">
UAE
</div>
</div>
+1 -1
View File
@@ -23,7 +23,7 @@ export function ModalContainer() {
(name === 'video' || name === 'form'
? ' bg-black bg-opacity-90 [backdrop-filter:blur(10px);]'
: '') +
(name === 'menu' ? ' lg:top-16 top-14' : ' top-0')
(name === 'menu' ? ' lg:top-16 top-12' : ' top-0')
}
>
{modal}
+2 -2
View File
@@ -40,7 +40,7 @@ export function SelectPhoneCode({
className="!relative w-4 sm:w-6"
alt={currentCountry}
/>
<p className="h4">{currentPhoneCode}</p>
<p className="m-text">{currentPhoneCode}</p>
<ClassNameWrapper
className="flex-1 max-sm:w-4 sm:max-lg:w-5"
element={open ? <ChevronUpIcon /> : <ChevronDownIcon />}
@@ -70,7 +70,7 @@ export function SelectPhoneCode({
width={16}
height={8}
/>
<p className="flex-1 py-1 cursor-pointer h4">{phoneCode}</p>
<p className="flex-1 py-1 cursor-pointer m-text">{phoneCode}</p>
</div>
))}
</div>
+1 -1
View File
@@ -82,7 +82,7 @@ export function MenuModal() {
</div>
</MenuLink>
<MenuLink href="/blog" title="Блог">
в аквапарке реально...
в аквапарке реально офигенно
</MenuLink>
<MenuLink href="/projects" title="Проекты">
<div className="flex relative self-end">
+8 -9
View File
@@ -104,10 +104,9 @@ export function ModalWithForm() {
<form onSubmit={handleSubmit}>
<div className="space-y-6">
<hr className="border-[#3D425C]" />
<div>
<label
className="m-text text-[#9299BD] select-none"
className="s-text text-[#9299BD] select-none"
htmlFor="name"
>
Имя
@@ -118,13 +117,13 @@ export function ModalWithForm() {
value={name}
onChange={e => setName(e.target.value)}
placeholder="Ваше имя"
className="bg-transparent border-b border-[#3D425C] focus:border-white py-4 rounded-none outline-none transition-all w-full placeholder:h4 placeholder:font-medium placeholder:select-none"
className="bg-transparent border-b border-[#3D425C] focus:border-white py-4 rounded-none outline-none transition-all w-full placeholder:m-text placeholder:font-medium placeholder:select-none"
/>
</div>
<div>
<label
className="m-text text-[#9299BD] select-none"
className="s-text text-[#9299BD] select-none"
htmlFor="tel"
>
Телефон
@@ -143,7 +142,7 @@ export function ModalWithForm() {
value={phone}
placeholder={placeholder}
onChange={e => setPhone(e.target.value.replace(/ /g, ''))}
className="w-full transition-all bg-transparent rounded-none outline-none h4 placeholder:h4 placeholder:font-medium placeholder:select-none peer"
className="w-full transition-all bg-transparent rounded-none outline-none m-text placeholder:m-text placeholder:font-medium placeholder:select-none peer"
/>
<div className="bottom-0 absolute w-full border-b border-[#3D425C] peer-focus:border-white -mb-2" />
</div>
@@ -151,7 +150,7 @@ export function ModalWithForm() {
<div>
<label
className="m-text text-[#9299BD] select-none"
className="s-text text-[#9299BD] select-none"
htmlFor="email"
>
Email*
@@ -163,13 +162,13 @@ export function ModalWithForm() {
value={email}
onChange={e => setEmail(e.target.value)}
placeholder="Ваш email"
className="bg-transparent border-b border-[#3D425C] focus:border-white py-4 rounded-none outline-none transition-all w-full placeholder:h4 placeholder:font-medium placeholder:select-none"
className="bg-transparent border-b border-[#3D425C] focus:border-white py-4 rounded-none outline-none transition-all w-full placeholder:m-text placeholder:font-medium placeholder:select-none"
/>
</div>
<div>
<label
className="m-text text-[#9299BD] select-none"
className="s-text text-[#9299BD] select-none"
htmlFor="description"
>
Задача
@@ -181,7 +180,7 @@ export function ModalWithForm() {
value={description}
rows={1}
onChange={e => setDescription(e.target.value)}
className="bg-transparent border-b py-4 focus:border-white max-h-[300px] h-auto rounded-none border-[#3D425C] resize-none outline-none transition-all w-full placeholder:h4 placeholder:font-medium placeholder:select-none"
className="bg-transparent border-b py-4 focus:border-white max-h-[300px] h-auto rounded-none border-[#3D425C] resize-none outline-none transition-all w-full placeholder:m-text placeholder:font-medium placeholder:select-none"
/>
</div>
</div>
@@ -17,7 +17,7 @@ export function ArticleCard({
}: IArticle & { draft?: boolean }) {
const { id, title, cardImage, createdAt, tags, description } = article;
const [year, month, date] = createdAt.split('-');
const [year, month, date] = createdAt.split('T')[0].split('-');
const params = useSearchParams();
@@ -1,7 +1,7 @@
'use client';
import { useGetArticlesQuery } from '@/queries/articles/getArticles';
import { Block } from '@/types/IArticl';
import { Block } from '@/types/IArticle';
import { useSearchParams } from 'next/navigation';
import { useEffect, useState } from 'react';
import { ArticleCard } from './ArticleCard';
@@ -38,8 +38,8 @@ export const AvailableItem = forwardRef<HTMLDivElement, IAvailable>(
transition={{ duration: 0.5 }}
className="absolute bottom-6 left-6 space-y-4"
>
<h3 className="h3 font-medium">{title}</h3>
<p className="m-text max-w-[49%]">{text}</p>
<h3 className="h4 font-medium">{title}</h3>
<p className="s-text max-w-[49%]">{text}</p>
</motion.div>
)}
</div>
@@ -168,7 +168,7 @@ export function Calculator() {
калькулятор эффективности продукта
</span>
</p>
<div className="sm:grid lg:grid-cols-12 sm:grid-cols-8 bg-[#14161F] -mx-6 px-6 col-span-full">
<div className="sm:grid lg:grid-cols-12 sm:grid-cols-8 bg-[#14161F] col-span-full">
<div className="lg:col-span-3 col-span-full lg:row-span-full sm:py-6 pt-6 lg:pr-6 border-y border-[#3D425C] flex max-sm:flex-col lg:flex-col gap-x-6 justify-between lg:bg-[url(/img/pages/home/calculator/highlight_desktop.png)] bg-cover bg-no-repeat bg-center">
<div className="space-y-4 w-full">
{selectedRegion && (
@@ -190,10 +190,12 @@ export function Calculator() {
)}
<div className="rounded-2xl border border-[#3D425C] p-4 relative">
<div className="space-y-2">
<p className="text-[#9299BD] font-medium m-caption">
<p className="text-[#9299BD] font-medium lg:m-caption l-caption">
Консультаций в месяц
</p>
<p className="font-medium">{consultations}</p>
<p className="font-medium lg:s-text btn-text">
{consultations}
</p>
</div>
</div>
<Slider
@@ -206,27 +208,29 @@ export function Calculator() {
className="bottom-4 max-w-[calc(100%-32px)] left-4"
/>
</div>
<div className="space-y-[25px] max-sm:pb-4 sm:max-lg:min-w-[45.31vw] max-sm:bg-[url(/img/pages/home/calculator/highlight.png)] bg-no-repeat bg-cover bg-center">
<div className="space-y-6 max-sm:pb-4 sm:max-lg:min-w-[45.31vw] max-sm:bg-[url(/img/pages/home/calculator/highlight.png)] bg-no-repeat bg-cover bg-center">
<div className="space-y-4">
<p className="font-medium">Усредненные параметры ЖК</p>
<p className="font-medium lg:s-text m-text">
Усредненные параметры ЖК
</p>
<hr className="border-[#3D425C]" />
<div className="grid grid-cols-[2fr_1fr] gap-y-2 gap-x-2">
<p className="font-medium text-[#9299BD] l-caption">
<p className="font-medium text-[#9299BD] lg:m-caption m-text">
Площадь жилья
</p>
<p className="font-medium l-caption">
<p className="font-medium lg:m-caption">
{selectedRegion?.areaInComplex || 1500} м<sup>2</sup>
</p>
<p className="font-medium text-[#9299BD] l-caption">
<p className="font-medium text-[#9299BD] lg:m-caption m-text">
Площадь квартиры
</p>
<p className="font-medium l-caption">
{selectedRegion?.areaApartment || 100} м<sup>2</sup>
</p>
<p className="font-medium text-[#9299BD] l-caption">
<p className="font-medium text-[#9299BD] lg:m-caption m-text">
Стоимость одного м<sup>2</sup>
</p>
<p className="font-medium l-caption">
<p className="font-medium lg:m-caption m-text">
{selectedRegion?.costPerSquare || 100} тыс. руб.
</p>
</div>
@@ -242,21 +246,21 @@ export function Calculator() {
<div className="max-sm:hidden col-start-4 lg:row-start-1 sm:col-span-2 lg:py-6 sm:pt-8 lg:pl-6 lg:space-y-4 sm:space-y-9 lg:border-y border-b lg:border-x sm:border-r border-[#3D425C]">
<p className="font-medium h4">Расчет</p>
<div>
<div className="pt-10 pb-[39px] space-y-[39px] border-t border-[#3D425C]">
<p className="text-[#9299BD] font-medium text-sm leading-[16.8px]">
<div className="py-10 space-y-10 border-t border-[#3D425C]">
<p className="text-[#9299BD] font-medium lg:s-text m-text">
Консультаций
</p>
<p className="text-[#9299BD] font-medium text-sm leading-[16.8px]">
<p className="text-[#9299BD] font-medium lg:s-text m-text">
Забронировано
</p>
<p className="text-[#9299BD] font-medium text-sm leading-[16.8px]">
<p className="text-[#9299BD] font-medium lg:s-text m-text">
Продано
</p>
</div>
<p className="text-[#9299BD] font-medium lg:py-[23px] sm:py-5 border-t border-[#3D425C] text-sm leading-[16.8px]">
<p className="text-[#9299BD] font-medium lg:py-6 sm:py-5 border-t border-[#3D425C] lg:s-text m-text">
Срок реализации
</p>
<p className="text-[#9299BD] font-medium py-[25px] border-t border-[#3D425C] text-sm leading-[16.8px]">
<p className="text-[#9299BD] font-medium lg:py-6 sm:py-5 border-t border-[#3D425C] lg:s-text m-text">
Месячный доход
</p>
</div>
@@ -271,7 +275,7 @@ export function Calculator() {
<div className="flex flex-wrap gap-x-1 gap-y-4 lg:hidden sm:pb-4 pb-6 border-b border-[#3D425C]">
<button
className={
'text-sm leading-none font-medium py-3 px-6 rounded-full border ' +
'btn-text font-medium py-3 px-6 rounded-full border ' +
(calculated
? 'bg-[#798FFF] border-[#798FFF]'
: 'border-[#3D425C]')
@@ -282,7 +286,7 @@ export function Calculator() {
</button>
<button
className={
'text-sm leading-none border font-medium py-4 px-6 rounded-full ' +
'btn-text border font-medium py-4 px-6 rounded-full ' +
(calculated
? 'border-[#3D425C]'
: 'bg-[#798FFF] border-[#798FFF]')
@@ -297,20 +301,28 @@ export function Calculator() {
Воронка продаж
</p>
<div className="bg-[#212431] rounded-full flex justify-center items-center relative">
<span className="absolute left-4 l-caption sm:hidden">
Консультаций
</span>
<p
className={
'px-5 py-[15.5px] rounded-full w-full text-center font-medium leading-[16.8px] text-sm ' +
'px-5 py-[15.5px] rounded-full w-full text-center font-medium lg:s-text sm:m-text l-caption ' +
(calculated ? 'bg-[#798FFF]' : 'bg-[#545186]')
}
>
{consultations}
</p>
<p className="absolute text-sm font-medium right-5">100%</p>
<p className="absolute lg:s-text sm:m-text l-caption font-medium right-5">
100%
</p>
</div>
<div className="bg-[#212431] rounded-full flex justify-center items-center relative">
<span className="absolute left-4 l-caption sm:hidden">
Бронь
</span>
<p
className={
'px-5 py-[15.5px] rounded-full font-medium text-sm leading-[16.8px] text-center ' +
'px-5 py-[15.5px] rounded-full font-medium lg:s-text sm:m-text l-caption text-center ' +
(calculated
? 'bg-[#798FFF] w-[60%]'
: 'bg-[#545186] w-[50%]')
@@ -318,14 +330,17 @@ export function Calculator() {
>
{calculated ? reservation : oldReservation}
</p>
<p className="absolute text-sm font-medium right-5">
<p className="absolute lg:s-text sm:m-text l-caption font-medium right-5">
{calculated ? '48%' : '30%'}
</p>
</div>
<div className="bg-[#212431] rounded-full flex justify-center items-center relative">
<span className="absolute left-4 l-caption sm:hidden">
Продажи
</span>
<p
className={
'px-5 py-[15.5px] rounded-full font-medium leading-[16.8px] text-sm text-center ' +
'px-5 py-[15.5px] rounded-full font-medium lg:s-text sm:m-text l-caption text-center ' +
(calculated
? 'bg-[#798FFF] w-[32%]'
: 'bg-[#545186] w-[22%]')
@@ -333,7 +348,7 @@ export function Calculator() {
>
{calculated ? sales : oldSales}
</p>
<p className="absolute text-sm font-medium right-5">
<p className="absolute lg:s-text sm:m-text l-caption font-medium right-5">
{calculated ? '42%' : '30%'}
</p>
</div>
@@ -348,10 +363,10 @@ export function Calculator() {
</div>
<div className="py-4 accent font-medium border-t border-[#3D425C]">
<p className="m-text font-medium text-[#9299BD] sm:hidden mb-1">
Срок реализации
Месячный доход
</p>
{calculated ? monthlyIncome : oldMonthlyIncome}{' '}
<span className="h4">млн. руб.</span>
{calculated ? monthlyIncome : oldMonthlyIncome}
<span className="h4"> млн. руб.</span>
</div>
</div>
</div>
@@ -362,22 +377,28 @@ export function Calculator() {
</p>
<div className="space-y-2">
<div className="bg-[#212431] rounded-full flex justify-center items-center relative">
<p className="px-5 py-[15.5px] bg-[#545186] rounded-full w-full text-sm leading-[16.8px] font-medium text-center">
<p className="px-5 py-[15.5px] bg-[#545186] rounded-full w-full lg:s-text sm:m-text l-caption font-medium text-center">
{consultations}
</p>
<p className="absolute text-sm font-medium right-5">100%</p>
<p className="absolute lg:s-text sm:m-text l-caption font-medium right-5">
100%
</p>
</div>
<div className="bg-[#212431] rounded-full flex justify-center items-center relative">
<p className="px-5 py-[15.5px] bg-[#545186] w-[50%] rounded-full text-center leading-[16.8px] text-sm font-medium">
<p className="px-5 py-[15.5px] bg-[#545186] w-[50%] rounded-full text-center lg:s-text sm:m-text l-caption font-medium">
{oldReservation}
</p>
<p className="absolute text-sm font-medium right-5">30%</p>
<p className="absolute lg:s-text sm:m-text l-caption font-medium right-5">
30%
</p>
</div>
<div className="bg-[#212431] rounded-full flex justify-center items-center relative">
<p className="px-5 py-[15.5px] bg-[#545186] rounded-full w-[22%] text-center leading-[16.8px] text-sm font-medium">
<p className="px-5 py-[15.5px] bg-[#545186] rounded-full w-[22%] text-center lg:s-text sm:m-text l-caption font-medium">
{oldSales}
</p>
<p className="absolute text-sm font-medium right-5">30%</p>
<p className="absolute lg:s-text sm:m-text l-caption font-medium right-5">
30%
</p>
</div>
</div>
<div>
@@ -42,7 +42,7 @@ export function RegionSelector({
>
<div className="relative h-full cursor-pointer">
<div className="flex flex-col justify-between h-full space-y-2">
<label className="opacity-50 font-medium leading-none cursor-pointer m-caption">
<label className="opacity-50 font-medium leading-none cursor-pointer lg:m-caption l-caption">
{label}
</label>
<input
@@ -63,7 +63,7 @@ export function RegionSelector({
{options.map((option, index) => (
<button
key={index}
className="2xl:pl-6 2xl:pr-8 2xl:py-3 pl-4 pr-6 py-2 m-text 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 lg:s-text btn-text hover:bg-white hover:bg-opacity-10 transition-colors w-full text-left flex justify-between"
onClick={() => handleClick(option)}
>
<span>{option}</span>
+22 -18
View File
@@ -1,25 +1,29 @@
import { clients } from '@/consts/clients';
import { Descriptor } from '@/ui/Descriptor';
export function Clients() {
return (
<div className="space-y-8">
<div className="flex items-center overflow-hidden w-screen lg:-mx-10 -mx-6 mt-10 min-h-[117px]">
<MarqueeHalf items={clients.slice(0, clients.length / 3)} />
<MarqueeHalf items={clients.slice(0, clients.length / 3)} />
</div>
<div className="flex items-center overflow-hidden w-screen lg:-mx-10 -mx-6 min-h-[117px]">
<MarqueeHalf
reversed
items={clients.slice(clients.length / 3, (2 * clients.length) / 3)}
/>
<MarqueeHalf
reversed
items={clients.slice(clients.length / 3, (2 * clients.length) / 3)}
/>
</div>
<div className="border-b border-[#3D425C] flex items-center overflow-hidden w-screen lg:-mx-10 -mx-6 min-h-[117px] pb-16">
<MarqueeHalf items={clients.slice(2 * (clients.length / 3))} />
<MarqueeHalf items={clients.slice(2 * (clients.length / 3))} />
<div className="space-y-6 pb-20 mt-10">
<Descriptor title="партнеры" />
<div className="space-y-8">
<div className="flex items-center overflow-hidden w-screen lg:-mx-10 -mx-6 mt-10 min-h-[117px]">
<MarqueeHalf items={clients.slice(0, clients.length / 3)} />
<MarqueeHalf items={clients.slice(0, clients.length / 3)} />
</div>
<div className="flex items-center overflow-hidden w-screen lg:-mx-10 -mx-6 min-h-[117px]">
<MarqueeHalf
reversed
items={clients.slice(clients.length / 3, (2 * clients.length) / 3)}
/>
<MarqueeHalf
reversed
items={clients.slice(clients.length / 3, (2 * clients.length) / 3)}
/>
</div>
<div className="border-b border-[#3D425C] flex items-center overflow-hidden w-screen lg:-mx-10 -mx-6 min-h-[117px] pb-16">
<MarqueeHalf items={clients.slice(2 * (clients.length / 3))} />
<MarqueeHalf items={clients.slice(2 * (clients.length / 3))} />
</div>
</div>
</div>
);
+4 -4
View File
@@ -24,14 +24,14 @@ export function Datamining() {
</Title>
<div className="grid lg:grid-cols-4 border-y border-[#3D425C] relative">
<div className="lg:col-span-1 col-span-full max-lg:border-b border-[#3D425C] lg:border-r">
<p className="xl:pt-10 sm:py-8 py-6 pr-4 text-left accent font-medium sm:max-lg:w-3/4">
<p className="xl:pt-10 sm:py-8 py-6 pr-4 text-left sm:h3 h4 font-medium sm:max-lg:w-3/4">
Graff.estate легко встраивается в&nbsp;существующую цепочку продаж
</p>
</div>
<div className="grid lg:grid-cols-3 sm:grid-cols-2 lg:col-span-3 col-s gap-x-4 lg:pl-4">
<div
ref={ref1}
className="sm:aspect-square max-sm:space-y-10 p-6 my-4 w-full bg-[url(/img/pages/home/projectmanagment/Ellipse.png)] flex flex-col justify-between gap-x-4 sm:max-lg:col-start-1 col-span-1 qspace-y-[140px]"
className="sm:aspect-squareq max-sm:space-y-10 p-6 my-4 w-full bg-[url(/img/pages/home/projectmanagment/Ellipse.png)] flex flex-col gap-y-5 justify-between sm:max-lg:col-start-1 col-span-1"
>
<div className="flex max-w-16 relative">
<Image
@@ -64,7 +64,7 @@ export function Datamining() {
<p className="font-medium sm:max-lg:h3 h4">
Актуальная информация о&nbsp;квартирах
</p>
<p className="lg:m-text sm:l-text m-text">
<p className="sm-max-lg:l-text m-text">
Клиент всегда видит актуальные данные об&nbsp;интересующем его
лоте, включая статус и стоимость
</p>
@@ -72,7 +72,7 @@ export function Datamining() {
</div>
<div
ref={ref2}
className="sm:aspect-square max-sm:space-y-10 p-6 sm:my-4 max-sm:mb-4 w-full bg-[url(/img/pages/home/projectmanagment/Ellipse.png)] flex flex-col justify-between sm:max-lg:col-start-2 col-span-1 qspace-y-[140px]"
className="sm:aspect-squareq max-sm:space-y-10 p-6 my-4 w-full bg-[url(/img/pages/home/projectmanagment/Ellipse.png)] flex flex-col justify-between sm:max-lg:col-start-2 col-span-1"
>
<div className="flex max-h-16 relative">
<Image
@@ -38,7 +38,7 @@ export const IntegrationItem = forwardRef<
<h4 className="h4 font-medium">{title}</h4>
<h4 className="h4 font-medium">{year}</h4>
</div>
<p className="m-caption font-medium text-[#737AA1]">{company}</p>
<p className="l-caption font-medium text-[#737AA1]">{company}</p>
</div>
</div>
);
+4 -3
View File
@@ -1,21 +1,22 @@
import { SkolkovoIcon } from '@/components/icons/SkolkovoIcon';
import { ClassNameWrapper } from '@/hocs/ClassNameWrapper';
import { Title } from '@/ui/Title';
export function Motivation() {
return (
<div className="lg:pb-20 sm:pb-61 pb-6 max-sm:space-y-8">
<div className="flex justify-between mb-12 gap-x-4">
<h1 className="h1 font-medium">
<Title headerLevel={1}>
Интерактивный инструмент
<br className="max-lg:hidden" /> продаж
<span className="text-gradient"> для&nbsp;застройщиков</span>
</h1>
</Title>
<div className="max-sm:hidden">
<ClassNameWrapper className="mt-4 mr-2" element={<SkolkovoIcon />} />
</div>
</div>
<div className="flex justify-between">
<h3 className="h3 font-medium min-w-[50vw]">
<h3 className="h4 font-medium min-w-[50vw]">
Помогаем девелоперам эффективно демонстрировать свой объект.
<br />
Продавать больше и быстрее.
+4 -4
View File
@@ -59,11 +59,11 @@ export function Projects() {
}, [getProjects]);
return (
<div>
<>
<div className="border-y border-[#3D425C] py-6 grid lg:grid-cols-4 sm:gap-y-8 gap-y-6">
<div className="sm:space-y-6 space-y-3 col-start-1 lg:col-span-2">
<Descriptor title="Проекты" />
<p className="accent font-medium">
<p className="lg:h3 sm:accent h4 font-medium">
За <span className="text-gradient">13 лет</span> работы мы
реализовали{' '}
<span className="text-gradient">
@@ -97,7 +97,7 @@ export function Projects() {
)}
<Link
href={'/projects'}
className="lg:col-start-4 self-end w-full bg-[#14161F] btn-text flex justify-between items-center rounded-full border border-[#3D425C] py-5 px-6"
className="lg:col-start-4 self-end w-full bg-[#14161F] btn-text flex justify-between items-center rounded-full font-medium border border-[#3D425C] py-5 px-6"
>
Все проекты
<ClassNameWrapper
@@ -121,6 +121,6 @@ export function Projects() {
))}
</>
)}
</div>
</>
);
}
+1 -1
View File
@@ -102,7 +102,7 @@ function ReviewContent({
<div className="h-full flex justify-center items-center">
<div className="space-y-6 max-w-[33%] absolute left-10 top-10 max-lg:hidden">
<Descriptor title="отзывы клиентов" className="mb-2" />
<div className="font-medium accent">{text}</div>
<div className="font-medium sm:accent h4">{text}</div>
<div className="m-caption max-w-[50%] font-medium">{author}</div>
</div>
<button
+1 -1
View File
@@ -22,7 +22,7 @@ export function Showreel() {
className="w-full lg:aspect-[1552/616] object-cover self-stretch"
/>
<button
className="absolute z-[9] p-8 rounded-full border group-hover:block hidden bg-[#14161F33]"
className="absolute z-[8] p-8 rounded-full border group-hover:block hidden bg-[#14161F33]"
onClick={() => {
setModal(
<VideoModal
+17 -14
View File
@@ -39,7 +39,7 @@ export function Statistics() {
<span className="text-gradient"> дороже</span>
</Title>
<div className="grid lg:grid-cols-12 grid-cols-2 border-t border-[#3D425C]">
<div className="lg:col-span-3 col-span-2 lg:pt-10 sm:py-8 py-4 lg:border-r border-b border-[#3D425C] accent font-medium pr-4">
<div className="lg:col-span-3 col-span-2 lg:pt-10 sm:py-8 py-4 lg:border-r border-b border-[#3D425C] h3 font-medium pr-4">
Мы собрали статистику за&nbsp;13&nbsp;лет работы c&nbsp;застройщиками,
реализовав {getProjectsCount(projects.length)}
</div>
@@ -54,25 +54,27 @@ export function Statistics() {
</div>
<div className="lg:col-span-3 md:col-span-1 col-span-full lg:py-10 sm:max-lg:pt-8 pt-6 pr-4 lg:flex flex-col justify-between sm:max-lg:space-y-5 max-sm:space-y-3 lg:border-b lg:border-r border-[#3D425C]">
<Descriptor title="экономическая эффективность" />
<p className="l-text">
<p className="m-text">
Экономьте на стоимости проектного финансирования сократив время
реализации проекта c помощью интерактивной презентации
</p>
</div>
<div className="lg:col-span-9 sm:col-start-1 col-span-2 xl:py-4 lg:py-3 py-6 sm:py-8 xl:pl-4 lg:pl-3 sm:gap-4 gap-3 border-b border-[#3D425C] flex flex-wrap">
<div className="lg:col-span-9 sm:col-start-1 col-span-2 xl:py-4 lg:py-3 py-6 sm:py-8 xl:pl-4 lg:pl-3 sm:gap-4 gap-3 border-b border-[#3D425C] grid xl:grid-cols-3 sm:grid-cols-2">
<Figure
figures={[30, 48]}
percent={18}
title={'Конверсия из консультации в бронирование увеличивается на'}
title={`Конверсия из консультации\nв бронирование увеличивается на`}
/>
<Figure
figures={[30, 42]}
percent={12}
title={'Конверсия из консультации в бронирование увеличивается на'}
title={`Конверсия из бронирования\nв продажу увеличивается на`}
/>
<div className="p-6 xl:w-[376px] sm:w-[350px] w-full sm:h-[250px] [background:center/cover_url(/img/pages/home/stats/highlight.svg)_no-repeat,#14161F] overflow-hidden flex flex-col">
<p className="l-text font-medium">
Время реализации проекта сокращается до
<div className="p-6 container [background:center/cover_url(/img/pages/home/stats/highlight.svg)_no-repeat,#14161F] overflow-hidden flex flex-col">
<p className="m-text font-medium">
Время реализации проекта
<br />
сокращается до
</p>
<div className="relative aspect-[328/158] flex items-end flex-1">
<Image
@@ -94,10 +96,11 @@ export function Statistics() {
</p>
</div>
</div>
<div className="p-6 xl:w-[376px] sm:w-[350px] w-full sm:h-[250px] [background:center/cover_url(/img/pages/home/stats/highlight.svg)_no-repeat,left_bottom/65%_65%_url(/img/pages/home/stats/adv.png)_no-repeat,#14161F] flex flex-col">
<p className="l-text font-medium">
Время на подготовку рекламных материалов сокращается до
<div className="p-6 container [background:center/cover_url(/img/pages/home/stats/highlight.svg)_no-repeat,left_bottom/65%_url(/img/pages/home/stats/adv.png)_no-repeat,#14161F] flex flex-col">
<p className="m-text font-medium">
Время на подготовку рекламных
<br />
материалов сокращается до
</p>
<div className="aspect-[328/158] relative flex-1">
<p className="h1 font-medium absolute bottom-0 right-0">
@@ -160,9 +163,9 @@ function Figure({
return (
<motion.div
ref={root}
className="p-6 xl:w-[376px] lg:h-[250px] sm:w-[350px] w-full [background:center/cover_url(/img/pages/home/stats/highlight.svg)_no-repeat,#14161F] flex flex-col"
className="p-6 container [background:center/cover_url(/img/pages/home/stats/highlight.svg)_no-repeat,#14161F] flex flex-col"
>
<p className="l-text font-medium">{title}</p>
<p className="m-text font-medium whitespace-break-spaces">{title}</p>
<div className="aspect-[328/158] relative flex-1 flex">
<Image
src={'/img/pages/home/stats/increasing.svg'}
+3 -3
View File
@@ -17,11 +17,11 @@ export function Streaming() {
</Title>
<div className="grid lg:grid-cols-12 sm:grid-cols-2 max-lg:border-t border-[#3D425C]">
<div className="lg:pt-10 lg:pb-6 lg:pr-6 sm:pt-8 pt-6 lg:flex flex-col justify-between col-start-1 lg:col-span-3 sm:max-lg:space-y-4 max-sm:space-y-3 sm:col-span-1 lg:border-t lg:border-r border-[#3D425C]">
<p className="font-medium accent">
<p className="font-medium h3">
<span className="text-gradient">Graff.estate stream</span> доступен
на&nbsp;любых устройствах
</p>
<p className="sm:m-text leading-[17.5px]">
<p className="sm:m-text s-text">
Высокий уровень графики и полное погружение покупателя в процесс
выбора квартиры
</p>
@@ -37,7 +37,7 @@ export function Streaming() {
</div>
<div className="lg:pt-10 lg:pb-8 lg:pr-8 sm:max-lg:py-8 max-sm:py-6 lg:flex flex-col justify-between lg:row-start-2 lg:col-span-3 sm:col-span-1 lg:border-y sm:max-lg:space-y-5 max-sm:space-y-3 max-sm:border-t lg:border-r border-[#3D425C]">
<Descriptor title="Демоверсии" />
<p className="l-text">
<p className="lg:l-text m-text">
Местоположение и устройство не имеют значения. Нужен только интернет
</p>
</div>
+3 -6
View File
@@ -1,8 +1,5 @@
import { ArrowMoreIcon } from '@/components/icons/ArrowMoreIcon';
import { ClassNameWrapper } from '@/hocs/ClassNameWrapper';
import { Title } from '@/ui/Title';
import Image from 'next/image';
import Link from 'next/link';
export function Winners() {
return (
@@ -22,13 +19,13 @@ export function Winners() {
alt={'BuildUP 2023'}
sizes="100%"
/>
<p className="accent font-medium mb-2 lg:col-start-2 sm:col-start-2 lg:col-span-2 sm:col-span-6">
<p className="sm:h3 h4 font-medium mb-2 lg:col-start-2 sm:col-start-2 lg:col-span-2 sm:col-span-6">
В 2023 году наш продукт для застройщиков GRAFF.estate был признан лучшим
в&nbsp;категории IT на&nbsp;Акселераторе технологических стартапов
от&nbsp;лидеров в&nbsp;строительстве и&nbsp;девелопменте Build UP
от&nbsp;Фонда «Сколково»
</p>
<Link
{/* <Link
href={'/'}
className="flex gap-x-1 py-2 w-fit sm:col-start-2 sm:col-span-2"
>
@@ -39,7 +36,7 @@ export function Winners() {
className="text-[#9299BD]"
element={<ArrowMoreIcon />}
/>
</Link>
</Link> */}
</div>
);
}
@@ -35,9 +35,9 @@ export function ProjectCard(project: IProject) {
/>
<div className="absolute top-0 left-0 w-full h-full bg-gradient-card" />
<div className="relative flex flex-col gap-4">
<div>
<p className="h3 font-medium">{name}</p>
<p className="m-text">
<div className="space-y-1">
<p className="lg:h4 h3 font-medium">{name}</p>
<p className="l-caption">
{company !== '-' && `${company},`} {city}
</p>
</div>
@@ -45,9 +45,7 @@ export function ProjectCard(project: IProject) {
<div className="flex flex-wrap gap-2">
{stage! < 6 && (
<div className="bg-[#14161F] px-3 py-2 rounded-full w-fit flex items-center gap-1">
<p className="leading-none btn-text font-semibold">
{stagePercentage}%
</p>
<p className="l-caption font-semibold">{stagePercentage}%</p>
<ProgressPie value={stagePercentage} />
</div>
)}
@@ -43,7 +43,7 @@ export function ProjectsList() {
}, [getProjects]);
return (
<div>
<div className="border-[#3D425C] border-t">
{sortedProjects && sortedProjects.size > 0 ? (
Array.from(sortedProjects.entries()).map(([year, projects]) => (
<ProjectsSection key={year} year={year} projects={projects} />
@@ -28,7 +28,7 @@ export function ProjectsSection({
return (
filteredProjects.length !== 0 && (
<div className="grid xl:grid-cols-[repeat(4,calc(25vw-24px))] md:grid-cols-3 sm:grid-cols-2 gap-4 pt-8 border-b border-[#3D425C] py-10">
<div className="font-semibold text-xl aspect-square">{year}</div>
<div className="font-medium lg:h4 h3 sm:aspect-square">{year}</div>
{filteredProjects.map(project => (
<ProjectCard key={project.id} {...project} />
))}
@@ -42,11 +42,11 @@ export function ProjectsSection({
ease: [0.58, 0.12, 0.27, 0.98],
delay: 0.2,
}}
className="border border-[#3D425C] p-4 flex sm:flex-col sm:justify-end items-end gap-2 sm:rounded-none rounded-full sm:aspect-square hover:border-[#3D425C] active:border-[#3d425cc4] active:text-[#ffffffc4] duration-150 ease-in-out transition-all"
className="border border-[#3D425C] p-4 flex sm:flex-col sm:justify-end btn-text font-medium items-end gap-2 sm:rounded-none rounded-full sm:aspect-square hover:border-[#3D425C] active:border-[#3d425cc4] active:text-[#ffffffc4] duration-150 ease-in-out transition-all"
onClick={onClick}
>
<div className="flex gap-2 items-center justify-between sm:justify-end w-full">
<p className="font-medium leading-none">Показать еще</p>
Показать еще
<ClassNameWrapper
className="max-sm:hidden"
element={<ArrowMoreIcon />}
-51
View File
@@ -1,51 +0,0 @@
import { IArticle } from '@/types/IArticl';
export const Posts: IArticle[] = [
{
id: '1',
image: '/img/pages/blog/post1/cover.jpg',
title:
'Graff interactive забрал 2 места в «Битве стартапов-победителей Build UP 2023»',
description:
'Решения SIPUNI, GRAFF interactive и ГК «СТЕНА» стали победителями нашей «Битвы стартапов-победителей Build UP 2023»',
tags: ['награды', 'недвижимость', 'новое'],
mainImage: '/img/pages/blog/post1/main.jpg',
createdAt: '12 ФЕВРАЛЯ 2024',
extraDesc:
'Среди девелоперов, представители которых приняли участие в выборе победителей эфира: Группа «Самолет», ГК «А101», Холдинг Setl Group, ГК ТОЧНО, ДОНСТРОЙ, Федеральный девелопер «Неометрия», «Ак Барс Дом», PIONEER, ГК «Первый Трест» и Capital Group.',
video: '/img/pages/blog/post1/video.jpg',
slides: [
'/img/pages/blog/post1/slides/1.jpg',
'/img/pages/blog/post1/slides/2.jpg',
'/img/pages/blog/post1/video.jpg',
],
review: {
author: {
name: 'Егор Бобров',
position: 'Коммерческий директор авторского квартала «Машаров»',
avatar: '/img/pages/blog/post1/avatar.jpg',
},
text: 'Конверсия из показа в сделку выросла в 1,5 раза. Эффективность инструмента была подтверждена буквально в первый день после его внедрения. Например, один из клиентов, посетив офис и увидев свою будущую квартиру с помощью интерактивной панели, сразу решил купить недвижимость в этом проекте, отказавшись от других вариантов.',
},
extraVideo: '/img/pages/blog/post1/extra_video.jpg',
},
{
id: '2',
image: '/img/pages/blog/post2/cover.jpg',
title:
'Graff interactive на международном фестивале маркетинга и креатива в недвижимости WOW FEST 2023',
description:
'В начале сентября приняли участие в международном фестивале маркетинга и креатива в недвижимости WOW FEST 2023. В рамках программы фестиваля мы познакомили участников и гостей форума с нашим интерактивным инструментом продаж.',
tags: ['выставки', 'недвижимость'],
createdAt: '15 СЕНТЯБРЯ 2023',
},
{
id: '3',
image: '/img/pages/blog/post3/cover.jpg',
title: 'Транспортное и специальное тренажеростроение — 2023',
description:
'27 апреля 2023 года в Москве — состоялась XV Международная конференция «Транспортное и специальное тренажеростроение — 2023». Директор GRAFF interactive принял участие и выступил с докладом',
tags: ['лекция', 'тренажеры'],
createdAt: '27 АПРЕЛЯ 2023',
},
];
+28
View File
@@ -0,0 +1,28 @@
// async function AddAllProjects() {
// for (const project of Data) {
// try {
// const image = await oldApi.get('upload/' + project.image).blob();
// const formData = new FormData();
// formData.append('files', image);
// formData.append('dest', 'projects');
// const { files } = await api
// .post('upload', { body: formData })
// .json<{ files: string[] }>();
// addProject({
// variables: {
// input: {
// city: project.city,
// company: project.company,
// devices: project.devices,
// image: files[0],
// name: project.name,
// releaseDate: project.releaseDate.split('T')[0],
// stage: project.stage!,
// },
// },
// });
// } catch (error) {
// console.log((error as Error).message);
// }
// }
// }
+1
View File
@@ -104,6 +104,7 @@ export type Mutation = {
__typename?: 'Mutation';
createArticle: ArticleResult;
createProject: ProjectResult;
deleteAllProjects: ProjectsResult;
deleteArticle: ArticleResult;
deleteProject: ProjectResult;
login: AuthResult;
@@ -0,0 +1,56 @@
import * as Types from '../../../generated/graphql';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type DeleteAllProjectsMutationVariables = Types.Exact<{ [key: string]: never; }>;
export type DeleteAllProjectsMutation = { __typename?: 'Mutation', deleteAllProjects: { __typename?: 'Error', message: string } | { __typename?: 'Projects', projects: Array<{ __typename?: 'Project', id: number, name: string, company: string, image: string, stage: number, releaseDate: any, devices: Array<string> }> } };
export const DeleteAllProjectsDocument = gql`
mutation DeleteAllProjects {
deleteAllProjects {
... on Error {
message
}
... on Projects {
projects {
id
name
company
image
stage
releaseDate
devices
}
}
}
}
`;
export type DeleteAllProjectsMutationFn = Apollo.MutationFunction<DeleteAllProjectsMutation, DeleteAllProjectsMutationVariables>;
/**
* __useDeleteAllProjectsMutation__
*
* To run a mutation, you first call `useDeleteAllProjectsMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useDeleteAllProjectsMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [deleteAllProjectsMutation, { data, loading, error }] = useDeleteAllProjectsMutation({
* variables: {
* },
* });
*/
export function useDeleteAllProjectsMutation(baseOptions?: Apollo.MutationHookOptions<DeleteAllProjectsMutation, DeleteAllProjectsMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<DeleteAllProjectsMutation, DeleteAllProjectsMutationVariables>(DeleteAllProjectsDocument, options);
}
export type DeleteAllProjectsMutationHookResult = ReturnType<typeof useDeleteAllProjectsMutation>;
export type DeleteAllProjectsMutationResult = Apollo.MutationResult<DeleteAllProjectsMutation>;
export type DeleteAllProjectsMutationOptions = Apollo.BaseMutationOptions<DeleteAllProjectsMutation, DeleteAllProjectsMutationVariables>;
@@ -0,0 +1,18 @@
mutation DeleteAllProjects {
deleteAllProjects {
... on Error {
message
}
... on Projects {
projects {
id
name
company
image
stage
releaseDate
devices
}
}
}
}
@@ -0,0 +1 @@
export * from './deleteAllProjects.generated';
+1 -1
View File
@@ -10,7 +10,7 @@ export function Descriptor({
return (
<div className={'opacity-60 flex gap-1 items-center ' + className}>
<CubeIcon />
<h6 className="descriptor uppercase font-medium">{title}</h6>
<h6 className="lg:s-text m-text uppercase font-medium">{title}</h6>
</div>
);
}
+2 -2
View File
@@ -7,7 +7,7 @@ export function DeviceBadge({
badgeType: Device;
active?: boolean;
}) {
return badgeType === 'stream' ? (
return badgeType === 'Stream' ? (
<div
className={
'px-3 py-2 rounded-full w-fit flex items-center gap-2 ' +
@@ -31,7 +31,7 @@ export function DeviceBadge({
) : (
<div
className={
'px-3 py-2 rounded-[32px] btn-text font-semibold flex items-center ' +
'px-3 py-[7px] rounded-[32px] l-caption font-medium flex items-center ' +
(badgeType.length === 2 ? 'uppercase' : 'capitalize') +
(active ? ' bg-[#798FFF]' : ' bg-[#14161F]')
}
+1 -1
View File
@@ -1,4 +1,4 @@
import { IArticle } from '@/types/IArticl';
import { IArticle } from '@/types/IArticle';
export function getPostsTags(posts: IArticle[]) {
const tags: string[] = [];
-7
View File
@@ -40,9 +40,6 @@ const config: Config = {
},
},
},
// corePlugins: {
// preflight: true,
// },
plugins: [
function ({ addBase }: { addBase: any }) {
const preflightStyles = postcss.parse(
@@ -52,10 +49,6 @@ const config: Config = {
),
);
preflightStyles.walkRules(rule => {
// rule.selector = rule.selector
// .split(',')
// .map(selector => `tailwind-preflight ${selector}`)
// .join(',');
rule.selector = '.no-tailwind-base ' + rule.selector;
});
addBase(preflightStyles.nodes);