upd
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 10 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 8.8 KiB |
@@ -1,12 +0,0 @@
|
||||
<svg width="1464" height="512" viewBox="0 0 1464 512" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_f_4447_20946)">
|
||||
<ellipse cx="804" cy="656" rx="356" ry="504" transform="rotate(90 804 656)" fill="#5545AC"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_f_4447_20946" x="0" y="0" width="1608" height="1312" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="150" result="effect1_foregroundBlur_4447_20946"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 631 B |
Binary file not shown.
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 38 KiB |
Binary file not shown.
@@ -2,14 +2,14 @@ import { Metadata, ResolvingMetadata } from 'next';
|
||||
|
||||
export async function generateMetadata(
|
||||
{},
|
||||
_: ResolvingMetadata,
|
||||
_: ResolvingMetadata
|
||||
): Promise<Metadata> {
|
||||
return {
|
||||
title: 'Продукты - 360',
|
||||
title: 'Продукты - Walk',
|
||||
};
|
||||
}
|
||||
|
||||
export default function SpheresLayout({
|
||||
export default function WalkLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
@@ -1,5 +1,5 @@
|
||||
import { InProcess } from '@/components/pages/InProcess';
|
||||
|
||||
export default function SpheresPage() {
|
||||
export default function WalkPage() {
|
||||
return <InProcess />;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
import { ClassNameWrapper } from '@/hocs/ClassNameWrapper';
|
||||
import { useCheckAuthQuery } from '@/queries/checkAuth';
|
||||
import { useModalStore } from '@/stores/useModalStore';
|
||||
import { Button } from '@/ui/Button';
|
||||
import { PropsWithChildren, ReactNode } from 'react';
|
||||
import { PlusIcon } from './icons/PlusIcon';
|
||||
|
||||
export function AddItemButton({
|
||||
modal,
|
||||
modalName,
|
||||
children,
|
||||
className,
|
||||
color,
|
||||
}: PropsWithChildren<{
|
||||
modal: ReactNode;
|
||||
modalName: string;
|
||||
className?: string;
|
||||
color: 'secondary' | 'primary';
|
||||
}>) {
|
||||
const { data: auth } = useCheckAuthQuery();
|
||||
|
||||
const { setModal } = useModalStore();
|
||||
|
||||
return (
|
||||
auth && (
|
||||
<Button
|
||||
color={color}
|
||||
className={className}
|
||||
onClick={() => setModal(modal, modalName)}
|
||||
icon={<ClassNameWrapper element={<PlusIcon />} className="w-4 h-4" />}
|
||||
>
|
||||
{children}
|
||||
</Button>
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -181,6 +181,7 @@ export function Header() {
|
||||
{productsOpened && (isMd || isLg) && (
|
||||
<>
|
||||
<motion.div
|
||||
onClick={() => setProductsOpened(false)}
|
||||
ref={productsRef}
|
||||
animate={{
|
||||
width: isLg
|
||||
|
||||
@@ -14,7 +14,7 @@ export function Links({ text }: { text: string }) {
|
||||
<div className="absolute bottom-0 left-[calc(77/460*100%)]">
|
||||
<div className="relative lg:max-w-[calc(306/460*100%)] sm:max-w-[calc(186/273.33*100%)] max-w-[calc(270/340*100%)]">
|
||||
<Image
|
||||
className="!relative"
|
||||
className="!relative w-full h-full"
|
||||
src={'/img/components/products/stream.png'}
|
||||
alt="stream"
|
||||
fill
|
||||
|
||||
@@ -23,26 +23,31 @@ export function Products() {
|
||||
))} */}
|
||||
<ProductItem
|
||||
key={1}
|
||||
href={`/${products[0].title.toLowerCase()}`}
|
||||
{...products[0]}
|
||||
className={`md:aspect-[361.5/263] md:col-start-1 md:row-span-3`}
|
||||
/>
|
||||
<ProductItem
|
||||
key={2}
|
||||
href={`/${products[1].title.toLowerCase()}`}
|
||||
{...products[1]}
|
||||
className={`md:aspect-[361.5/263] md:col-start-1 md:row-span-3`}
|
||||
/>
|
||||
<ProductItem
|
||||
key={3}
|
||||
href={`/${products[2].title.toLowerCase()}`}
|
||||
{...products[2]}
|
||||
className={`max-md:aspect-[100/114] md:col-start-2 md:row-start-1 md:row-end-3`}
|
||||
/>
|
||||
<ProductItem
|
||||
key={4}
|
||||
href={`/${products[3].title.toLowerCase()}`}
|
||||
{...products[3]}
|
||||
className={`max-md:aspect-[100/114] md:col-start-2 md:row-start-3 md:row-end-5`}
|
||||
/>
|
||||
<ProductItem
|
||||
key={5}
|
||||
href={`/${products[4].title.toLowerCase()}`}
|
||||
{...products[4]}
|
||||
className={`col-span-2 md:col-span-1 md:col-start-2 md:row-start-5 md:row-end-7`}
|
||||
/>
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
export function PanDotsIcon() {
|
||||
return (
|
||||
<svg
|
||||
width={24}
|
||||
height={24}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M6 5C6 3.89543 6.89543 3 8 3C9.10457 3 10 3.89543 10 5C10 6.10457 9.10457 7 8 7C6.89543 7 6 6.10457 6 5Z"
|
||||
fill="currentColor"
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
export function PlusIcon() {
|
||||
return (
|
||||
<svg
|
||||
width={40}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M12.0001 11.9998H18.0001M12.0001 11.9998L12.0001 6M12.0001 11.9998L12.0001 18M12.0001 11.9998H6"
|
||||
stroke="white"
|
||||
|
||||
@@ -20,7 +20,7 @@ export function ArticleCard({
|
||||
href={`/blog/${id}`}
|
||||
className={`relative space-y-3${
|
||||
className ? ' ' + className : ''
|
||||
} hover:bg-[#7A7A7A] hover:backdrop-blur-[500]`}
|
||||
} hover:backdrop-blur-[500px] hover:bg-[radial-gradient(ellipse_at_bottom,#7A7A7A,transparent)] bg-cover rounded-2xl relative`}
|
||||
>
|
||||
<Image
|
||||
src={process.env.NEXT_PUBLIC_S3_BUCKET + cardImage}
|
||||
|
||||
@@ -12,17 +12,21 @@ export function ArticlesList({ tags }: { tags: string[] }) {
|
||||
<TagsFilters type="article" tags={tags} />
|
||||
<div className="mt-12">
|
||||
{articles && articles.length > 0 ? (
|
||||
<div className="col-start-2 flex flex-wrap gap-x-3 gap-y-6">
|
||||
<div className="gap-x-3 gap-y-6 flex flex-wrap col-start-2">
|
||||
{articles?.map((article, index) => (
|
||||
<ArticleCard
|
||||
key={article.id}
|
||||
{...article}
|
||||
className={index % 5 < 4 && index % 5 > 0 ? 'w-1/3' : 'w-1/2'}
|
||||
className={
|
||||
index % 5 < 4 && index % 5 > 0
|
||||
? 'lg:w-1/3 sm:w-1/2'
|
||||
: 'sm:w-1/2'
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-center heading1 font-medium">Статьи не найдены</p>
|
||||
<p className="heading1 font-medium text-center">Статьи не найдены</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { AddItemButton } from '@/components/AddItemButton';
|
||||
import { AddItemWrapper } from '@/hocs/AddItemButton';
|
||||
import { useCheckAuthQuery } from '@/queries/checkAuth';
|
||||
import { Title } from '@/ui/Title';
|
||||
|
||||
@@ -14,14 +14,14 @@ export function ArticlesPageHeader() {
|
||||
<span className="text-[#7A7A7A]"> новости, статьи и видео</span>
|
||||
</Title>
|
||||
{auth && (
|
||||
<AddItemButton
|
||||
<AddItemWrapper
|
||||
color="primary"
|
||||
modalName="addArticle"
|
||||
className="sticky top-0"
|
||||
modal={<></>}
|
||||
>
|
||||
Добавить статью
|
||||
</AddItemButton>
|
||||
</AddItemWrapper>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Title } from '@/ui/Title';
|
||||
import Image from 'next/image';
|
||||
import { VanyaBoom } from '@/ui/VanyaBoom';
|
||||
import { Links } from '../Layout/Links';
|
||||
|
||||
export function InProcess() {
|
||||
@@ -7,24 +7,11 @@ export function InProcess() {
|
||||
<div className="lg:space-y-16 sm:space-y-12 space-y-10">
|
||||
<div className="sm:max-lg:space-y-6 max-sm:space-y-8">
|
||||
<Title headerLevel={1} className="col-span-full text-center">
|
||||
Мы работаем{' '}
|
||||
<Image
|
||||
src={'/img/pages/about/vanya_workaet.png'}
|
||||
alt="vanya workaet"
|
||||
className="inline-block max-lg:hidden"
|
||||
width={128}
|
||||
height={62}
|
||||
/>
|
||||
Мы работаем <VanyaBoom className="inline-block max-lg:hidden" />
|
||||
<br />
|
||||
над этим разделом
|
||||
</Title>
|
||||
<Image
|
||||
className="lg:hidden m-auto mt-6 mb-12"
|
||||
src={'/img/pages/about/vanya_workaet.png'}
|
||||
alt="vanya workaet"
|
||||
width={128}
|
||||
height={62}
|
||||
/>
|
||||
<VanyaBoom className="lg:hidden m-auto mt-6 mb-1" />
|
||||
</div>
|
||||
<Links text="А над этими мы уже поработали" />
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
'use client';
|
||||
|
||||
import { oldApi } from '@/api';
|
||||
import { LogoIcon } from '@/components/icons/LogoIcon';
|
||||
import regionsData from '@/consts/regionsData.json';
|
||||
import { ClassNameWrapper } from '@/hocs/ClassNameWrapper';
|
||||
import { GradientButton } from '@/ui/GradientButton';
|
||||
import { Title } from '@/ui/Title';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import Image from 'next/image';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { CalculatorSwitch } from './CalculatorSwitch';
|
||||
import { ConsultationRange } from './ConsultationsRange';
|
||||
import { Region, RegionSelector } from './RegionSelector';
|
||||
import { StatsColumn } from './StatColumn';
|
||||
@@ -143,12 +145,20 @@ export function Calculator() {
|
||||
)}
|
||||
<ConsultationRange
|
||||
consultations={consultations!}
|
||||
setConsulatations={setConsultations}
|
||||
/>
|
||||
<CalculatorSwitch
|
||||
enabled={calculated}
|
||||
onToggle={() => setCalculated(!calculated)}
|
||||
setConsultations={setConsultations}
|
||||
/>
|
||||
<GradientButton
|
||||
onClick={() => setCalculated(!calculated)}
|
||||
className="flex gap-x-3 items-center max-md:absolute top-0 max-md:-mt-7 left-[calc(50%-24px)]"
|
||||
>
|
||||
<ClassNameWrapper
|
||||
element={<LogoIcon />}
|
||||
className={
|
||||
'lg:w-7 lg:h-7 w-5 h-5 ' +
|
||||
(!calculated ? 'opacity-50' : 'opacity-100')
|
||||
}
|
||||
/>
|
||||
</GradientButton>
|
||||
</div>
|
||||
<div className="space-y-10 lg:max-w-[1040px] w-full max-lg:order-1">
|
||||
<div className="h-80 flex items-end justify-center w-full">
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
import { LogoIcon } from '@/components/icons/LogoIcon';
|
||||
import { ClassNameWrapper } from '@/hocs/ClassNameWrapper';
|
||||
|
||||
export function CalculatorSwitch({
|
||||
onToggle,
|
||||
enabled,
|
||||
}: {
|
||||
onToggle: () => void;
|
||||
enabled: boolean;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex gap-x-3 items-center max-md:absolute top-0 max-md:-mt-7 left-[calc(50%-24px)]">
|
||||
<div
|
||||
className={
|
||||
'p-px rounded-full cursor-pointer transition-colors ' +
|
||||
(enabled ? 'bg-gradient' : 'bg-[#37393B99]')
|
||||
}
|
||||
onClick={onToggle}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'rounded-full lg:border-[7px] border-[4px] border-black p-[14px] transition-colors ' +
|
||||
(enabled ? 'bg-gradient' : 'bg-[#37393B99]')
|
||||
}
|
||||
>
|
||||
<ClassNameWrapper
|
||||
element={<LogoIcon />}
|
||||
className={
|
||||
'lg:w-7 lg:h-7 w-5 h-5 ' +
|
||||
(!enabled ? 'opacity-50' : 'opacity-100')
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p className="btnl font-medium text-[#7A7A7A] select-none max-md:hidden">
|
||||
Инструмент
|
||||
<br />
|
||||
{enabled ? 'включен' : 'выключен'}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,27 +1,55 @@
|
||||
import { PanDotsIcon } from '@/components/icons/PanDotsIcon';
|
||||
import { ClassNameWrapper } from '@/hocs/ClassNameWrapper';
|
||||
import { DragEvent, useRef } from 'react';
|
||||
import { MouseEvent, useRef, useState } from 'react';
|
||||
|
||||
export function ConsultationRange({
|
||||
consultations,
|
||||
setConsulatations,
|
||||
setConsultations,
|
||||
}: {
|
||||
consultations: number;
|
||||
setConsulatations: (consultations: number) => void;
|
||||
setConsultations: (consultations: number) => void;
|
||||
}) {
|
||||
const root = useRef<HTMLDivElement>(null);
|
||||
const barRef = useRef<HTMLDivElement>(null);
|
||||
const panRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
function handleDrag(e: DragEvent<HTMLDivElement>) {
|
||||
const width = Math.max(
|
||||
root.current!.clientWidth / 35,
|
||||
Math.min(
|
||||
e.clientX - panRef.current!.getBoundingClientRect().left,
|
||||
root.current!.clientWidth
|
||||
const [offset, setOffset] = useState(0);
|
||||
const [start, setStart] = useState(0);
|
||||
const [isMouseDown, setIsMouseDown] = useState(false);
|
||||
|
||||
function handleMouseDown(e: MouseEvent) {
|
||||
console.log(e.clientX - root.current!.getBoundingClientRect().x);
|
||||
setIsMouseDown(true);
|
||||
setStart(
|
||||
Math.max(
|
||||
Math.min(
|
||||
e.clientX - root.current!.getBoundingClientRect().x - offset,
|
||||
root.current!.clientWidth
|
||||
),
|
||||
root.current!.clientWidth / 35
|
||||
)
|
||||
);
|
||||
setConsulatations(Math.round((width / root.current!.clientWidth) * 350));
|
||||
panRef.current!.style.width = `${width}px`;
|
||||
}
|
||||
|
||||
function handleMouseMove(e: MouseEvent) {
|
||||
const el = panRef.current;
|
||||
if (!el || !isMouseDown) return;
|
||||
const dx = Math.max(
|
||||
Math.min(
|
||||
e.clientX - root.current!.getBoundingClientRect().x - start,
|
||||
root.current!.clientWidth - 48
|
||||
),
|
||||
(root.current!.clientWidth - 48) / 35
|
||||
);
|
||||
el.style.left = `${dx}px`;
|
||||
setOffset(dx);
|
||||
setConsultations(Math.round((dx / (root.current!.clientWidth - 48)) * 350));
|
||||
barRef.current!.style.width = `${dx + 48}px`;
|
||||
}
|
||||
|
||||
function handleMouseUp(e: MouseEvent) {
|
||||
if (!isMouseDown) return;
|
||||
setIsMouseDown(false);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -32,23 +60,20 @@ export function ConsultationRange({
|
||||
ref={root}
|
||||
>
|
||||
<div
|
||||
className="absolute left-0 top-0 rounded-2xl h-full bg-[#37393B99] backdrop-blur-2xl flex items-center pr-6 z-[2]"
|
||||
ref={panRef}
|
||||
ref={barRef}
|
||||
className="absolute left-0 top-0 rounded-2xl h-full bg-[#37393B99] backdrop-blur-2xl flex items-center z-[2] pr-12"
|
||||
>
|
||||
<p className="btnl pl-8 font-medium select-none">{consultations}</p>
|
||||
<div
|
||||
className="self-center select-none absolute [user-drag:none] cursor-grab active:cursor-move [:.grabbing_*_&]:!cursor-grabbing focus:cursor-move"
|
||||
onMouseDown={() => false}
|
||||
style={{
|
||||
left: Math.max((panRef.current?.clientWidth ?? 50) - 25, 0),
|
||||
}}
|
||||
draggable
|
||||
onDrag={handleDrag}
|
||||
onDragStart={() => false}
|
||||
onDragEnd={handleDrag}
|
||||
ref={panRef}
|
||||
className="active:cursor-move right-6 absolute flex items-center self-center h-full pr-6 cursor-pointer select-none"
|
||||
onMouseDown={handleMouseDown}
|
||||
onMouseMove={handleMouseMove}
|
||||
onMouseLeave={handleMouseUp}
|
||||
onMouseUp={handleMouseUp}
|
||||
>
|
||||
<ClassNameWrapper
|
||||
className="text-[#7A7A7A] select-none [user-drag:none] [-webkit-user-drag:none]"
|
||||
className="text-[#7A7A7A] select-none w-6 h-6"
|
||||
element={<PanDotsIcon />}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
'use client';
|
||||
|
||||
import { PlusIcon } from '@/components/icons/PlusIcon';
|
||||
import { ItemActions } from '@/components/ItemActions';
|
||||
import { CompanyFormModal } from '@/components/modals/CompanyFormModal';
|
||||
import { AddItemWrapper } from '@/hocs/AddItemButton';
|
||||
import { ClassNameWrapper } from '@/hocs/ClassNameWrapper';
|
||||
import { useGetCompaniesQuery } from '@/queries/getCompanies';
|
||||
import { GradientButton } from '@/ui/GradientButton';
|
||||
import { Title } from '@/ui/Title';
|
||||
import { getCompaniesCount } from '@/utils/getCompaniesCount';
|
||||
import Image from 'next/image';
|
||||
@@ -42,14 +47,16 @@ export function Clients() {
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
{/* <AddItemButton
|
||||
color="secondary"
|
||||
<AddItemWrapper
|
||||
modal={<CompanyFormModal action="create" />}
|
||||
modalName="addCompany"
|
||||
className="aspect-square flex justify-center items-center bg-[#232425] rounded-xl opacity-60 hover:opacity-100 transition-opacity p-5"
|
||||
className="aspect-square flex flex-col items-center justify-center gap-3"
|
||||
>
|
||||
<PlusIcon />
|
||||
</AddItemButton> */}
|
||||
<GradientButton>
|
||||
<ClassNameWrapper element={<PlusIcon />} className="w-7 h-7" />
|
||||
</GradientButton>
|
||||
<p className="btnl font-medium">Добавить</p>
|
||||
</AddItemWrapper>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Title } from '@/ui/Title';
|
||||
import Image from 'next/image';
|
||||
import { VanyaBoom } from '@/ui/VanyaBoom';
|
||||
import { Links } from '../Layout/Links';
|
||||
|
||||
export function NotFoundPage() {
|
||||
@@ -7,24 +7,11 @@ export function NotFoundPage() {
|
||||
<div className="lg:space-y-16 sm:space-y-12 space-y-10">
|
||||
<div className="sm:max-lg:space-y-6 max-sm:space-y-8">
|
||||
<Title headerLevel={1} className="col-span-full text-center">
|
||||
Ошибка 404{' '}
|
||||
<Image
|
||||
src={'/img/pages/about/vanya_workaet.png'}
|
||||
alt="vanya workaet"
|
||||
className="inline-block max-lg:hidden"
|
||||
width={128}
|
||||
height={62}
|
||||
/>
|
||||
Ошибка 404 <VanyaBoom className="inline-block max-lg:hidden" />
|
||||
<br />
|
||||
такой страницы нет
|
||||
</Title>
|
||||
<Image
|
||||
className="lg:hidden m-auto mt-6 mb-12"
|
||||
src={'/img/pages/about/vanya_workaet.png'}
|
||||
alt="vanya workaet"
|
||||
width={128}
|
||||
height={62}
|
||||
/>
|
||||
<VanyaBoom className="lg:hidden m-auto mt-6 mb-1" />
|
||||
</div>
|
||||
<Links text={'Зато есть много других интересных'} />
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
'use client';
|
||||
|
||||
import { AddItemButton } from '@/components/AddItemButton';
|
||||
import { PlusIcon } from '@/components/icons/PlusIcon';
|
||||
import { ProjectFormModal } from '@/components/modals/ProjectFormModal';
|
||||
import { AddItemWrapper } from '@/hocs/AddItemButton';
|
||||
import { ClassNameWrapper } from '@/hocs/ClassNameWrapper';
|
||||
import { useCheckAuthQuery } from '@/queries/checkAuth';
|
||||
import { useGetProjectsCountQuery } from '@/queries/getProjectsCount';
|
||||
import { Button } from '@/ui/Button';
|
||||
import { Title } from '@/ui/Title';
|
||||
import { getProjectsCount } from '@/utils/getProjectsCount';
|
||||
|
||||
@@ -13,21 +16,28 @@ export function ProjectsPageHeader() {
|
||||
const auth = useCheckAuthQuery();
|
||||
|
||||
return (
|
||||
<div className="lg:space-y-14 sm:space-y-8 space-y-10 relative">
|
||||
<div className="lg:space-y-14 sm:space-y-8 relative space-y-10">
|
||||
<Title className="text-center" headerLevel={2}>
|
||||
За 15 лет работы мы реализовали
|
||||
<br />
|
||||
{getProjectsCount(count ?? 0)} для застройщиков
|
||||
</Title>
|
||||
{auth && (
|
||||
<AddItemButton
|
||||
color="primary"
|
||||
<AddItemWrapper
|
||||
modalName="addProject"
|
||||
modal={<ProjectFormModal action={'create'} />}
|
||||
className="sticky top-0 btns"
|
||||
className="btns sticky top-0"
|
||||
>
|
||||
Добавить проект
|
||||
</AddItemButton>
|
||||
<Button
|
||||
color="primary"
|
||||
className="btns rounded-xl gap-2 py-2"
|
||||
icon={
|
||||
<ClassNameWrapper className="w-4 h-4" element={<PlusIcon />} />
|
||||
}
|
||||
>
|
||||
Добавить проект
|
||||
</Button>
|
||||
</AddItemWrapper>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { useCheckAuthQuery } from '@/queries/checkAuth';
|
||||
import { useModalStore } from '@/stores/useModalStore';
|
||||
import { PropsWithChildren, ReactNode, useEffect, useRef } from 'react';
|
||||
|
||||
export function AddItemWrapper({
|
||||
modal,
|
||||
modalName,
|
||||
children,
|
||||
className,
|
||||
}: PropsWithChildren<{
|
||||
modal: ReactNode;
|
||||
modalName: string;
|
||||
className?: string;
|
||||
}>) {
|
||||
const { data: auth } = useCheckAuthQuery();
|
||||
|
||||
const { setModal } = useModalStore();
|
||||
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (auth) {
|
||||
ref.current?.children.item(0)!.addEventListener('click', () => {
|
||||
console.log('asd');
|
||||
setModal(modal, modalName);
|
||||
});
|
||||
|
||||
return () => {
|
||||
ref.current?.children.item(0)!.removeEventListener('click', () => {
|
||||
setModal(modal, modalName);
|
||||
});
|
||||
};
|
||||
}
|
||||
}, [auth]);
|
||||
|
||||
return (
|
||||
auth && (
|
||||
<div ref={ref} className={className}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { PropsWithChildren } from 'react';
|
||||
|
||||
export function GradientButton({
|
||||
children,
|
||||
onClick,
|
||||
className,
|
||||
}: PropsWithChildren<{ onClick?: () => void; className?: string }>) {
|
||||
return (
|
||||
<button
|
||||
onClick={onClick}
|
||||
className={`bg-gradient-to-bl p-px rounded-full from-[#BE69F5] to-[#798FFF00]${
|
||||
className ? ' ' + className : ''
|
||||
}`}
|
||||
>
|
||||
<div className="p-2 bg-black rounded-full">
|
||||
<div className="p-[14px] rounded-full bg-[#37393B99] active:bg-gradient-to-r from-[#6078F2] to-[#C868F5]">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useMediaQueries } from '@/hooks/useMediaQueries';
|
||||
import { motion } from 'framer-motion';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
|
||||
export interface IProduct {
|
||||
id: number;
|
||||
@@ -14,11 +15,13 @@ export function ProductItem({
|
||||
title,
|
||||
text,
|
||||
className,
|
||||
}: IProduct & { className?: string }) {
|
||||
href,
|
||||
}: IProduct & { className?: string; href: string }) {
|
||||
const { isLg, isMd } = useMediaQueries();
|
||||
|
||||
return (
|
||||
<div
|
||||
<Link
|
||||
href={href}
|
||||
className={`md:p-5 p-2 flex flex-col justify-between relative max-md:items-start max-lg:bg-[#37393B99] rounded-2xl${
|
||||
className ? ' ' + className : ''
|
||||
}`}
|
||||
@@ -78,6 +81,6 @@ export function ProductItem({
|
||||
</div>
|
||||
</motion.div>
|
||||
<p className="opacity-60 btns font-medium md:hidden">{text}</p>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import Image from 'next/image';
|
||||
|
||||
export function VanyaBoom({ className }: { className?: string }) {
|
||||
return (
|
||||
<div
|
||||
className={`relative max-w-32 max-h-[78px]${
|
||||
className ? ' ' + className : ''
|
||||
}`}
|
||||
>
|
||||
<video
|
||||
src="/videos/pages/inProcess/impla.mp4"
|
||||
className="aspect-[128/62] absolute rounded-3xl"
|
||||
muted
|
||||
autoPlay
|
||||
loop
|
||||
playsInline
|
||||
/>
|
||||
<Image
|
||||
src={'/img/pages/about/vanya_workaet.png'}
|
||||
alt="vanya workaet"
|
||||
className="relative mix-blend-lighten"
|
||||
width={128}
|
||||
height={62}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user