From 7589e2d14c312d3e3e6050b13199c045a1b2c1fe Mon Sep 17 00:00:00 2001 From: Lanskikh Date: Wed, 25 Dec 2024 18:57:43 +0500 Subject: [PATCH] upd --- src/app/(admin)/login/layout.tsx | 4 +- src/app/(admin)/login/page.tsx | 1 - src/app/(main)/layout.tsx | 2 +- src/app/(main)/projects/page.tsx | 2 +- src/app/globals.css | 44 ++++++++- src/components/CompanyActions.tsx | 3 + src/components/Layout/Feedback.tsx | 18 ++-- src/components/Layout/ModalContainer.tsx | 2 +- src/components/Layout/NewFooter.tsx | 14 +-- src/components/Layout/NewHeader.tsx | 8 +- src/components/Layout/SelectPhoneCode.tsx | 12 +-- src/components/MediaUploader.tsx | 13 ++- src/components/modals/CompanyFormModal.tsx | 86 +++++++++++++++++ src/components/pages/MainPage/Clients.tsx | 3 +- .../IntreractivePresentation.tsx | 16 ++-- src/components/pages/MainPage/NewAwards.tsx | 4 +- .../pages/MainPage/NewCalculator.tsx | 40 ++++---- .../pages/MainPage/NewMotivation.tsx | 28 ++++-- src/components/pages/MainPage/NewProjects.tsx | 2 +- src/components/pages/MainPage/NewStats.tsx | 94 +++++++++++++------ src/components/pages/MainPage/Streaming.tsx | 26 ++--- .../pages/ProjectsPage/ProjectCard.tsx | 10 +- .../pages/ProjectsPage/ProjectsList.tsx | 29 +++--- .../pages/ProjectsPage/ProjectsPageHeader.tsx | 4 +- .../pages/ProjectsPage/ProjectsSection.tsx | 10 +- src/lib/Providers.tsx | 1 - src/lib/queryClient.ts | 2 +- src/types/ICityProjects.ts | 1 - src/ui/NewFigure.tsx | 8 +- src/ui/Title.tsx | 15 ++- tailwind.config.ts | 10 +- 31 files changed, 366 insertions(+), 146 deletions(-) create mode 100644 src/components/CompanyActions.tsx create mode 100644 src/components/modals/CompanyFormModal.tsx diff --git a/src/app/(admin)/login/layout.tsx b/src/app/(admin)/login/layout.tsx index 6451e903..59917b3d 100644 --- a/src/app/(admin)/login/layout.tsx +++ b/src/app/(admin)/login/layout.tsx @@ -10,7 +10,9 @@ export default function Layout({ children }: { children: React.ReactNode }) { const { data } = useQuery({ queryKey: ['checkAuth'], - queryFn: async () => await api.get('auth/check').json<{ auth: boolean }>(), + queryFn: async () => { + return await api.get('auth/check').json<{ auth: boolean }>(); + }, }); useEffect(() => { diff --git a/src/app/(admin)/login/page.tsx b/src/app/(admin)/login/page.tsx index d90737da..17d878f1 100644 --- a/src/app/(admin)/login/page.tsx +++ b/src/app/(admin)/login/page.tsx @@ -16,7 +16,6 @@ export default function LoginPage() { const queryClient = useQueryClient(); const { mutate: login } = useMutation({ - mutationKey: ['login'], mutationFn: async ({ username, password, diff --git a/src/app/(main)/layout.tsx b/src/app/(main)/layout.tsx index bdfd368f..960627c6 100644 --- a/src/app/(main)/layout.tsx +++ b/src/app/(main)/layout.tsx @@ -7,7 +7,7 @@ export default function MainLayout({ children }: PropsWithChildren) { return (
-
+
{children}
diff --git a/src/app/(main)/projects/page.tsx b/src/app/(main)/projects/page.tsx index 5bc84f9d..17f0e981 100644 --- a/src/app/(main)/projects/page.tsx +++ b/src/app/(main)/projects/page.tsx @@ -34,7 +34,7 @@ export default async function ProjectsPage({ return ( -
+
diff --git a/src/app/globals.css b/src/app/globals.css index fb5cd18a..8ba8b32a 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -121,9 +121,9 @@ body { @apply 2xl:text-[clamp(20px,20px+(100vw-1560px)/360*8,28px)] text-[clamp(16px,16px+(100vw-360px)/1240*4,20px)] leading-[clamp(17.6px,17.6px+(100vw-360px)/1240*6.4,24px)]; } - .accent { + /* .accent { @apply -tracking-[.02em] md:text-[clamp(28px,28px+(100vw-768px)/832*4,32px)] text-[clamp(20px,20px+(100vw-360px)/408*8,28px)] md:leading-[clamp(28px,28px+(100vw-768px)/832*7.2,35.2px)] leading-[clamp(20px,20px+(100vw-360px)/408*8,28px)]; - } + } */ .l-text { @apply 2xl:text-[clamp(20px,20px+(100vw-1560px)/360*4,24px)] text-[clamp(16px,16px+(100vw-360px)/1240*4,20px)] leading-[clamp(21.6px,21.6px+(100vw-360px)/1240*5.4,27px)]; @@ -199,4 +199,44 @@ body { .card-gradient-5 { @apply bg-[radial-gradient(circle_closest-side_at_center,#5545AC,transparent)] bg-[length:0px_0px] hover:bg-[length:100%_100%] bg-center bg-no-repeat transition-all duration-300 delay-100; } + /* */ + .line1 { + @apply min-[1440px]:text-[clamp(96px,96px+(100vw-1440px)/480*32,128px)] md:text-[clamp(92px,92px+(100vw-768px)/672*8,100px)] sm:text-[clamp(40px,40px+(100vw-360px)/408*16,56px)] text-[40px] leading-[85%]; + } + + .line2 { + @apply min-[1440px]:text-[clamp(64px,64px+(100vw-1440px)/480*24,88px)] md:text-[clamp(40px,40px+(100vw-768px)/672*24,64px)] sm:text-[clamp(32px,32px+(100vw-360px)/408*8,40px)] text-[32px] leading-[95%]; + } + + .heading1 { + @apply min-[1440px]:text-[clamp(24px,24px+(100vw-1440px)/480*4,28px)] text-2xl leading-[1.167]; + } + + .heading2 { + @apply min-[1440px]:text-[clamp(20px,20px+(100vw-1440px)/480*4,24px)] sm:text-[clamp(16px,16px+(100vw-360px)/1080*4,20px)] text-base min-[1440px]:leading-[1.2] leading-[1.125]; + } + + .accent { + @apply min-[1440px]:text-[clamp(32px,32px+(100vw-1440px)/480*8,40px)] text-2xl min-[1440px]:leading-[1.1] leading-none; + } + + .text1 { + @apply min-[1440px]:text-[clamp(14px,14px+(100vw-1440px)/480*4,18px)] text-sm leading-[1.35]; + } + + .text2 { + @apply min-[1440px]:text-[clamp(12px,12px+(100vw-1440px)/480*2,14px)] text-xs leading-[1.35]; + } + + .btnl { + @apply sm:text-[clamp(16px,16px+(100vw-360px)/1560*2,18px)] text-base leading-none; + } + + .btnm { + @apply sm:text-[clamp(14px,14px+(100vw-360px)/1560*2,16px)] text-sm leading-none; + } + + .btns { + @apply sm:text-[clamp(12px,12px+(100vw-360px)/1560*2,14px)] text-xs leading-none; + } } diff --git a/src/components/CompanyActions.tsx b/src/components/CompanyActions.tsx new file mode 100644 index 00000000..85596850 --- /dev/null +++ b/src/components/CompanyActions.tsx @@ -0,0 +1,3 @@ +export function CompanyActions() { + return
; +} diff --git a/src/components/Layout/Feedback.tsx b/src/components/Layout/Feedback.tsx index 525739a3..6b68fff7 100644 --- a/src/components/Layout/Feedback.tsx +++ b/src/components/Layout/Feedback.tsx @@ -14,13 +14,13 @@ import { SelectPhoneCode } from './SelectPhoneCode'; export function Feedback() { return (
-

+

Хотите увеличить конверсию?
Давайте обсудим детали.

-

Нам нужна

+

Нам нужна

@@ -84,7 +84,7 @@ export function FeedbackForm() { type="text" placeholder="Имя*" {...register('name')} - 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" + className="bg-transparent border-b border-[#3D425C] focus:border-white py-4 rounded-none outline-none transition-all w-full placeholder:btnl placeholder:font-medium placeholder:select-none" />
@@ -100,7 +100,7 @@ export function FeedbackForm() { mask={placeholder?.replace(/\d/g, '9') ?? ''} maskChar={null} placeholder={placeholder} - className="w-full transition-all bg-transparent rounded-none outline-none m-text placeholder:m-text placeholder:font-medium placeholder:select-none peer" + className="w-full transition-all bg-transparent rounded-none outline-none placeholder:btnl placeholder:font-medium placeholder:select-none peer" />
@@ -112,14 +112,14 @@ export function FeedbackForm() { type="text" placeholder="E-mail*" {...register('email')} - 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" + className="bg-transparent border-b border-[#3D425C] focus:border-white py-4 rounded-none outline-none transition-all w-full placeholder:btnl placeholder:font-medium placeholder:select-none" />
- - + *Нажимая кнопку отправить, вы принимаете {' '} @@ -150,11 +150,11 @@ export function ProductOption({ getValues('products').filter((product: string) => product !== text) ); } - }, [chosen]); + }, [chosen, getValues, setValue, text]); return (
setChosen(!chosen)} diff --git a/src/components/Layout/ModalContainer.tsx b/src/components/Layout/ModalContainer.tsx index 9d10b39a..0c86962c 100644 --- a/src/components/Layout/ModalContainer.tsx +++ b/src/components/Layout/ModalContainer.tsx @@ -19,7 +19,7 @@ export function ModalContainer() { modal && (
-

Позвонить

-
+

Позвонить

+
8 800 770 00 67 -

Написать

-
+

Написать

+
info@graff.tech Политика конфиденциальности и обработки персональных данных -

+

© 2024 GRAFF interactive. Все права защищены

graff.tech diff --git a/src/components/Layout/NewHeader.tsx b/src/components/Layout/NewHeader.tsx index a9650969..1ed7d06b 100644 --- a/src/components/Layout/NewHeader.tsx +++ b/src/components/Layout/NewHeader.tsx @@ -41,13 +41,17 @@ export function NewHeader() { {data?.auth && ( - )} @@ -64,7 +68,7 @@ export function HeaderLink({ href, text }: { href: string; text: string }) { return ( diff --git a/src/components/Layout/SelectPhoneCode.tsx b/src/components/Layout/SelectPhoneCode.tsx index 8fb78b04..19ecd1a0 100644 --- a/src/components/Layout/SelectPhoneCode.tsx +++ b/src/components/Layout/SelectPhoneCode.tsx @@ -26,7 +26,7 @@ export function SelectPhoneCode({ function handleExpand(e: SyntheticEvent) { e.preventDefault(); - setOpen(prev => !prev); + setOpen((prev) => !prev); } function pickPhoneCode(phoneCode: string, country: CountryCode) { @@ -43,11 +43,11 @@ export function SelectPhoneCode({ c.iso === currentCountry)?.flag || ''} + src={countries.find((c) => c.iso === currentCountry)?.flag || ''} className="!relative w-4 sm:w-6" alt={currentCountry} /> -

{currentPhoneCode}

+

{currentPhoneCode}

: } @@ -56,10 +56,10 @@ export function SelectPhoneCode({ {open && (
{getCountries() - .map(country => [`+${getCountryCallingCode(country)}`, country]) + .map((country) => [`+${getCountryCallingCode(country)}`, country]) .filter( ([phonecode, country]) => - phonecode !== currentPhoneCode || country !== currentCountry, + phonecode !== currentPhoneCode || country !== currentCountry ) .map(([phoneCode, country]) => (
pickPhoneCode(phoneCode, country as CountryCode)} > c.iso === country)?.flag || ''} + src={countries.find((c) => c.iso === country)?.flag || ''} alt={country} className="!relative w-4 sm:w-6" width={16} diff --git a/src/components/MediaUploader.tsx b/src/components/MediaUploader.tsx index 1a6e0f48..d933ee2d 100644 --- a/src/components/MediaUploader.tsx +++ b/src/components/MediaUploader.tsx @@ -9,12 +9,18 @@ export function MediaUploader({ fieldName, item, label, + className, + width = 300, + height = 300, }: { dest: string; setValue: UseFormSetValue; fieldName: Path; item: Record<'img', string> & Record<'id', string>; label: string; + className?: string; + width?: number; + height?: number; }) { const [file, setFile] = useState(); const [previewFile, setPreviewFile] = useState(''); @@ -52,7 +58,12 @@ export function MediaUploader({ }, [file, uploadFile]); return ( -
-

+

Клиент всегда видит актуальные данные об интересующем его лоте, включая статус и стоимость.

@@ -104,7 +104,7 @@ export function InteractivePresentation() {
-

+

Клиент всегда видит актуальные данные об интересующем его лоте, включая статус и стоимость.

@@ -150,10 +150,10 @@ export function DoubleCard() { 'Стоимость', 'Инсоляция', 'Особенности планировки', - ].map(tag => ( + ].map((tag) => (

{tag}

@@ -176,13 +176,15 @@ export function CardContainer({ }>) { return (
-

{title}

+

{title}

{children}
- {text &&

{text}

} + {text &&

{text}

}
); } diff --git a/src/components/pages/MainPage/NewAwards.tsx b/src/components/pages/MainPage/NewAwards.tsx index 86e2c3c4..3bce5bb3 100644 --- a/src/components/pages/MainPage/NewAwards.tsx +++ b/src/components/pages/MainPage/NewAwards.tsx @@ -63,8 +63,8 @@ export function AwardItem({ alt={title} />
-

{title}

-

{description}

+

{title}

+

{description}

); diff --git a/src/components/pages/MainPage/NewCalculator.tsx b/src/components/pages/MainPage/NewCalculator.tsx index 70dc240a..19627014 100644 --- a/src/components/pages/MainPage/NewCalculator.tsx +++ b/src/components/pages/MainPage/NewCalculator.tsx @@ -186,14 +186,16 @@ export function NewCalculator() {
-

Срок реализации объекта

-

- +

Срок реализации объекта

+

+ {calculated ? implementationPeriod : oldImplementationPeriod} {' '} - {calculated - ? implementationPeriodEnding - : oldImplementationPeriodEnding} + + {calculated + ? implementationPeriodEnding + : oldImplementationPeriodEnding} +

{calculated && ( @@ -205,7 +207,7 @@ export function NewCalculator() { y: 0, }} exit={{ opacity: 0, y: -10 }} - className="rounded-2xl px-3 py-[7px] font-medium text-xs absolute bottom-7 right-6 bg-[#FF4517] z-[2]" + className="rounded-2xl px-3 py-[7px] font-medium btns absolute bottom-7 right-6 bg-[#FF4517] z-[2]" > Продано @@ -236,12 +238,12 @@ export function NewCalculator() {
-

Ежемесячный доход

-

- +

Ежемесячный доход

+

+ {calculated ? monthlyIncome : oldMonthlyIncome} {' '} - млн руб. + млн руб.

@@ -327,13 +329,13 @@ export function NewRegionSelector({ return (
-

Регион

+

Регион

setOpened(!opened)} > -

{chosen.name}

+

{chosen.name}

{opened ? : }
{opened && ( @@ -381,7 +383,7 @@ export function ConsultationRange({ return (
-

Консультаций в месяц

+

Консультаций в месяц

-

{consultations}

+

{consultations}

-

+

из 350

@@ -428,8 +430,8 @@ export function StatsColumn({ return (
-

{value}

-

+

{value}

+

{percents}%

@@ -443,7 +445,7 @@ export function StatsColumn({ }} />
-

{title}

+

{title}

); } diff --git a/src/components/pages/MainPage/NewMotivation.tsx b/src/components/pages/MainPage/NewMotivation.tsx index 16d3fd22..19d434ad 100644 --- a/src/components/pages/MainPage/NewMotivation.tsx +++ b/src/components/pages/MainPage/NewMotivation.tsx @@ -13,7 +13,7 @@ export function NewMotivation() { const [scrolled, setScrolled] = useState(false); useEffect(() => { - scrollY.on('change', value => setScrolled(value > 250)); + scrollY.on('change', (value) => setScrolled(value > 250)); }, [scrollY]); return ( @@ -27,10 +27,16 @@ export function NewMotivation() { дороже
-

+

Интеграция в офисы продаж

@@ -58,9 +68,11 @@ export function NewMotivation() {
-

+

Удаленная демонстрация

diff --git a/src/components/pages/MainPage/NewProjects.tsx b/src/components/pages/MainPage/NewProjects.tsx index 4bb01909..279ed84e 100644 --- a/src/components/pages/MainPage/NewProjects.tsx +++ b/src/components/pages/MainPage/NewProjects.tsx @@ -49,7 +49,7 @@ export function NewProjects() { } return ( -
+
За 15 лет работы мы реализовали{' '} diff --git a/src/components/pages/MainPage/NewStats.tsx b/src/components/pages/MainPage/NewStats.tsx index bed57e87..1a9c0f5b 100644 --- a/src/components/pages/MainPage/NewStats.tsx +++ b/src/components/pages/MainPage/NewStats.tsx @@ -15,7 +15,15 @@ import { getCompaniesCount } from '@/utils/getCompaniesCount'; import { getProjectsGroupedByCities } from '@/utils/getProjectsGroupedByCities'; import { useQuery } from '@tanstack/react-query'; import Image from 'next/image'; -import { useEffect, useRef, useState } from 'react'; +import { + Dispatch, + SetStateAction, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; +import { useHover } from 'usehooks-ts'; export function NewStats() { const { data: projects } = useQuery({ @@ -49,7 +57,7 @@ export function NewStats() {
-

+

Время реализации проекта сокращается до

@@ -59,18 +67,16 @@ export function NewStats() {
-

+

Время на подготовку рекламных материалов сокращается до

@@ -115,6 +121,22 @@ export function Map({ projects: IProject[]; chooseCity: (_: ICityProjects) => void; }) { + const { cityPoint } = useCityPointStore(); + + const [currentHovered, setCurrentHovered] = useState(null); + + const groupedProjects = useMemo( + () => + Array.from( + getProjectsGroupedByCities( + projects.filter(({ city }) => + cities.some(({ title }) => title === city) + ) + ).entries() + ), + [projects] + ); + return (

- {Array.from( - getProjectsGroupedByCities( - projects.filter(({ city }) => city !== 'Dubai' && city !== 'Абу-Даби') - ).entries() - ).map(([city, projects]) => { + {Array.from(groupedProjects).map(([city, projects], index) => { const point = cities.find(({ title }) => title === city)!; return point ? ( 3 ? projects.length - 3 : 0} + {...{ setCurrentHovered, index }} /> ) : null; })} @@ -156,16 +178,30 @@ export function CityPoint({ x, y, chooseCity, -}: ICityProjects & { chooseCity: (_: ICityProjects) => void }) { + active, + setCurrentHovered, + index, +}: ICityProjects & { + chooseCity: (_: ICityProjects) => void; + active: boolean; + setCurrentHovered: Dispatch>; + index: number; +}) { const companiesWithMapIcon = companies.filter((company) => company.mapIcon); - const { cityPoint } = useCityPointStore(); + const ref = useRef(null); + + const hovered = useHover(ref); + + useEffect(() => { + setCurrentHovered(hovered ? index : null); + }, [hovered, index, setCurrentHovered]); return ( -
+
chooseCity({ title, x, y, companies })} > @@ -173,14 +209,14 @@ export function CityPoint({
-

{title}

+

{title}

{companiesWithMapIcon .slice(0, 3) @@ -199,6 +235,7 @@ export function CityPoint({ src={process.env.NEXT_PUBLIC_S3_BUCKET + '' + mapIcon} alt={title} className="!relative object-cover" + sizes="" fill /> )} @@ -259,7 +296,7 @@ export function ProjectsSlider({ title: name, company, description, - tags: devices, + tags, image, stage = 1, }) => ( @@ -277,19 +314,19 @@ export function ProjectsSlider({ className="w-2 h-2 rounded-full" style={{ backgroundColor: company.color }} /> -

{company.title}

+

{company.title}

)} -
+
{Math.round((100 / 6) * stage)}%
- {devices.map((device) => ( + {tags.map((tag) => (
- {device} + {tag}
))}
@@ -301,9 +338,10 @@ export function ProjectsSlider({ fill className="!relative rounded object-cover aspect-[290/301]" alt={name} + sizes="" />
-

{description}

+

{description}

) @@ -311,7 +349,7 @@ export function ProjectsSlider({
-

+

{current} из {count} в {city}

diff --git a/src/components/pages/MainPage/Streaming.tsx b/src/components/pages/MainPage/Streaming.tsx index 74a303d2..3925801b 100644 --- a/src/components/pages/MainPage/Streaming.tsx +++ b/src/components/pages/MainPage/Streaming.tsx @@ -32,11 +32,11 @@ export function Streaming() { ))}
-

+

Расскажем и покажем как это работает на созвоне