This commit is contained in:
2025-07-23 10:24:19 +05:00
parent ade6679ecd
commit 92175de0c1
162 changed files with 4092 additions and 1785 deletions
+1
View File
@@ -0,0 +1 @@
<svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M43.315 7.25a7 7 0 0 1 6.999 7.164l-.591 25.262-9.871 6.787H23.148v6.787H11v-6.787h12.148l-9.11-6.787.598-25.59a7 7 0 0 1 6.999-6.836zM52 46.463v6.787H39.852v-6.787zM22.333 35.667a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5m20 0a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5M21.5 12.333v10.834C21.5 29.15 26.35 34 32.333 34s10.834-4.85 10.834-10.833V12.333z" fill="#232425"/></svg>

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

+7 -3
View File
@@ -67,6 +67,10 @@
"summer": "Summer",
"autumn": "Autumn",
"winter": "Winter"
},
"light": {
"night": "Night",
"day": "Day"
}
},
"engine": {
@@ -149,7 +153,6 @@
"Москва": "Moscow",
"Владивосток": "Vladivostok",
"watch": "Watch"
},
"calculator": {
"title": "Estimate the effectiveness",
@@ -210,8 +213,9 @@
"Выставки": "Exhibitions",
"name": "Name*",
"submit": "Submit request",
"policy": "*By clicking the submit button, you accept",
"policy_link": "terms of use and privacy policy",
"remark": "*By clicking the submit button, you accept",
"terms_conditions_links": "terms of use",
"policy_link": "privacy policy",
"filters": "Filters",
"apply": "Apply"
},
+26 -25
View File
@@ -207,33 +207,34 @@
"Виртуальный тур по 360 сферам": "Виртуальный тур по 360 сферам",
"name": "Имя*",
"submit": "Оставить заявку",
"policy": "*Нажимая кнопку отправить, вы принимаете",
"policy_link": "условия использования и политику конфиденциальности",
"remark": "*Нажимая кнопку отправить, вы принимаете",
"terms_conditions_links": "условия использования",
"policy_link": "и политику конфиденциальности",
"filters": "Фильтры",
"apply": "Применить"
},
"footer": {
"call": "Позвонить",
"write": "Написать",
"privacy": "Политика конфиденциальности и обработки персональных данных",
"copyright": "© 2025 GRAFF interactive. Все права защищены"
},
"in_process": {
"title": "Мы работаем",
"title1": "над этим разделом",
"description": "А над этими мы уже поработали"
},
"not_found": {
"title": "Ошибка 404",
"description": "такой страницы нет",
"link": "Зато есть много других интересных"
},
"blog": {
"title": "Все о работе компании:",
"description": "статьи, видео и публикации"
},
"popup": {
"text": " Новости разработки интерактивных решений для девелоперов в нашем телеграм канале",
"link": "Перейти"
}
"call": "Позвонить",
"write": "Написать",
"privacy": "Политика конфиденциальности и обработки персональных данных",
"copyright": "© 2025 GRAFF interactive. Все права защищены"
},
"in_process": {
"title": "Мы работаем",
"title1": "над этим разделом",
"description": "А над этими мы уже поработали"
},
"not_found": {
"title": "Ошибка 404",
"description": "такой страницы нет",
"link": "Зато есть много других интересных"
},
"blog": {
"title": "Все о работе компании:",
"description": "статьи, видео и публикации"
},
"popup": {
"text": " Новости разработки интерактивных решений для девелоперов в нашем телеграм канале",
"link": "Перейти"
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+7 -10
View File
@@ -1,11 +1,8 @@
import { api } from '@/api';
import { RelevantArticlesPreview } from '@/components/pages/ArticlePage/RelevantArticlesPreview';
import { IArticle } from '@/types/IArticle';
import { QueryClient } from '@tanstack/react-query';
import { Metadata } from 'next';
import Link from 'next/link';
import CloseIcon from '../../../../../public/icons/close.svg';
import NotFound from '@/app/not-found';
import { api } from "@/api";
import { IArticle } from "@/types/IArticle";
import { QueryClient } from "@tanstack/react-query";
import { Metadata } from "next";
import NotFound from "@/app/not-found";
export async function generateMetadata({
params,
@@ -17,7 +14,7 @@ export async function generateMetadata({
const queryClient = new QueryClient();
const { cardImage, tags, title } = await queryClient.fetchQuery<IArticle>({
queryKey: ['articles', slug],
queryKey: ["articles", slug],
queryFn: async () => await api.get(`articles/${slug}`).json<IArticle>(),
});
@@ -30,7 +27,7 @@ export async function generateMetadata({
images: {
url: process.env.NEXT_PUBLIC_S3_BUCKET + cardImage,
},
siteName: 'graff.estate',
siteName: "graff.estate",
},
};
}
+1 -1
View File
@@ -14,7 +14,7 @@ export default function MainLayout({ children }: PropsWithChildren) {
<Header />
<main className="flex-1 md:max-lg:pt-[120px] pt-25 md:max-lg:px-4 lg:px-[1.389vw] px-[10px] overflow-clip relative">
{children}
{/* <Feedback /> */}
<Feedback />
</main>
<Footer />
</div>
+28 -28
View File
@@ -1,30 +1,30 @@
import { api } from '@/api';
import { Awards } from '@/components/pages/MainPage/Awards';
import { Calculator } from '@/components/pages/MainPage/Calculator/Calculator';
import { Clients } from '@/components/pages/MainPage/Clients/Clients';
import { Map } from '@/components/pages/MainPage/Map/Map';
import { Motivation } from '@/components/pages/MainPage/Motivation';
import { Presentation } from '@/components/pages/MainPage/Presentation/Presentation';
import { Projects } from '@/components/pages/MainPage/Projects';
import { Reviews } from '@/components/pages/MainPage/Reviews/Reviews';
import { Statistics } from '@/components/pages/MainPage/Statistics';
import { Streaming } from '@/components/pages/MainPage/Streaming/Streaming';
import { ICompany } from '@/types/ICompany';
import { IProject } from '@/types/IProject';
import { api } from "@/api";
import { Awards } from "@/components/pages/MainPage/Awards";
import { Calculator } from "@/components/pages/MainPage/Calculator/Calculator";
import { Clients } from "@/components/pages/MainPage/Clients/Clients";
import { Map } from "@/components/pages/MainPage/Map/Map";
import { Motivation } from "@/components/pages/MainPage/Motivation";
import { Presentation } from "@/components/pages/MainPage/Presentation/Presentation";
import { Projects } from "@/components/pages/MainPage/Projects";
import { Reviews } from "@/components/pages/MainPage/Reviews/Reviews";
import { Statistics } from "@/components/pages/MainPage/Statistics";
import { Streaming } from "@/components/pages/MainPage/Streaming/Streaming";
import { ICompany } from "@/types/ICompany";
import { IProject } from "@/types/IProject";
import {
dehydrate,
HydrationBoundary,
QueryClient,
queryOptions,
} from '@tanstack/react-query';
import { Integrations } from '@/components/pages/MainPage/Integrations/Integrations';
} from "@tanstack/react-query";
import { Integrations } from "@/components/pages/MainPage/Integrations/Integrations";
// import { Suspense } from 'react';
import dynamic from 'next/dynamic';
import { queryProjectsOptions } from '@/queries/getProjects';
import { queryCompaniesOptions } from '@/queries/getCompanies';
import { queryCompaniesCountOptions } from '@/queries/getCompaniesCount';
import NewStreaming from '@/components/pages/MainPage/NewStreaming';
import NewMap from '@/components/pages/MainPage/Map/NewMap';
import dynamic from "next/dynamic";
import { queryProjectsOptions } from "@/queries/getProjects";
import { queryCompaniesOptions } from "@/queries/getCompanies";
import { queryCompaniesCountOptions } from "@/queries/getCompaniesCount";
import NewStreaming from "@/components/pages/MainPage/NewStreaming";
import NewMap from "@/components/pages/MainPage/Map/NewMap";
export default async function HomePage() {
const queryClient = new QueryClient();
@@ -32,8 +32,8 @@ export default async function HomePage() {
await queryClient.prefetchQuery(queryProjectsOptions);
await queryClient.prefetchQuery({
queryKey: ['projects', 'count'],
queryFn: () => api.get('projects/count').json<number>(),
queryKey: ["projects", "count"],
queryFn: () => api.get("projects/count").json<number>(),
});
await queryClient.prefetchQuery(queryCompaniesOptions);
@@ -41,27 +41,27 @@ export default async function HomePage() {
await queryClient.prefetchQuery(queryCompaniesCountOptions);
await queryClient.prefetchQuery({
queryKey: ['projects', 'Удаленная демонстрация'],
queryKey: ["projects", "Удаленная демонстрация"],
queryFn: () =>
api.get('projects?tags=Удаленная демонстрация').json<IProject[]>(),
api.get("projects?tags=Удаленная демонстрация").json<IProject[]>(),
});
const Presentation = dynamic(
() =>
import('@/components/pages/MainPage/Presentation/Presentation').then(
import("@/components/pages/MainPage/Presentation/Presentation").then(
(mod) => mod.Presentation
),
{ ssr: false }
);
const Map = dynamic(
() => import('@/components/pages/MainPage/Map/Map').then((mod) => mod.Map),
() => import("@/components/pages/MainPage/Map/Map").then((mod) => mod.Map),
{ ssr: false }
);
const Clients = dynamic(
() =>
import('@/components/pages/MainPage/Clients/Clients').then(
import("@/components/pages/MainPage/Clients/Clients").then(
(mod) => mod.Clients
),
{ ssr: false }
-13
View File
@@ -1,13 +0,0 @@
import { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Политика конфиденциальности',
};
export default function PolicyLayout({
children,
}: {
children: React.ReactNode;
}) {
return <section>{children}</section>;
}
-75
View File
@@ -1,75 +0,0 @@
import { policy } from '@/consts/policy';
export default function PolicyPage() {
return (
<div className="grid grid-cols-12 gap-y-20">
<p className="col-span-8 heading1 font-medium">
Политика конфиденциальности
</p>
<ol className="col-span-full grid grid-cols-4 gap-x-4">
{policy.map(({ content, title }, index) => (
<PolicyItem
content={content}
index={index}
title={title}
key={index}
/>
))}
</ol>
</div>
);
}
function PolicyItem({
content,
title,
index,
}: {
title: string;
index: number;
content: (
| string
| { title: string; content: string[]; enumeration?: boolean }
)[];
}) {
return (
<li className="col-span-full grid grid-cols-4 py-6 border-t border-[#3D425C] last:border-b">
<p className="heading2 font-medium col-span-1 pr-5">
{index + 1}. {title}
</p>
<div className="space-y-4 col-start-2 col-span-2 text2">
{content.map((item, index1) =>
typeof item !== 'string' ? (
<div className="space-y-2" key={index1}>
<p className="flex gap-x-1">
<span>
{index + 1}.{index1 + 1}.
</span>
{item.title}
</p>
{item.content.map((contentItem, index2) => (
<p className="flex gap-x-1 ml-[44px]" key={index2}>
{item.enumeration ? (
<span>
{index + 1}.{index1 + 1}.{index2 + 1}
</span>
) : (
<span></span>
)}
{contentItem}
</p>
))}
</div>
) : (
<p key={index} className="flex gap-x-1">
<span>
{index + 1}.{index1 + 1}
</span>
{item}
</p>
)
)}
</div>
</li>
);
}
+39
View File
@@ -0,0 +1,39 @@
"use client";
import CloseIcon from "@/components/icons/CloseIcon";
function PrivacyPolicyLayout({ children }: { children: React.ReactNode }) {
function handleClose() {
try {
window.close();
} catch {
// Если не удалось закрыть, пытаемся вернуться назад в истории
if (window.history.length > 1) {
window.history.back();
} else {
// Если и это не работает, перенаправляем на главную страницу
window.location.href = "/";
}
}
}
return (
<section className="fixed inset-0 bg-[#0F101199] [backdrop-filter:blur(16px)] z-[14]">
<button
className="fixed inset-0 cursor-pointer"
onClick={handleClose}
></button>
{children}
<button
onClick={handleClose}
className="fixed lg:right-[1.389vw] lg:top-[1.389vw] right-5 top-5 lg:rounded-[1.111vw] rounded-2xl bg-[#37393B99] lg:p-[1.111vw] p-4 cursor-pointer backdrop-blur-2xl"
>
<div className="text-white lg:size-[1.111vw] size-4">
<CloseIcon />
</div>
</button>
</section>
);
}
export default PrivacyPolicyLayout;
+320
View File
@@ -0,0 +1,320 @@
"use client";
import { useLenis } from "@/hooks/useLenis";
import ArrowUpIcon from "@/components/icons/ArrowUpIcon";
import ReactLenis from "lenis/react";
function PrivacyPolicyPage() {
const lenis = useLenis();
return (
<div className="absolute left-1/2 -translate-x-1/2 lg:w-[66.25vw] w-full overflow-y-auto max-h-dvh h-full alg:h-[calc(100vh-40px)]">
<ReactLenis ref={lenis} className="overflow-y-scroll h-full">
<div className="bg-gradient lg:px-[5.208vw] md:max-lg:px-4 px-2.5 lg:pt-[14.514vw] md:max-lg:pt-[157px] pt-[169px] lg:pb-[1.667vw] md:max-lg:pb-6 pb-4 lg:rounded-t-[1.944vw]">
<h1 className="heading1 font-medium">Privacy Policy</h1>
</div>
<div className="bg-[#232425] lg:px-[5.208vw] md:max-lg:px-4 px-2.5 lg:pt-[2.778vw] md:max-lg:pt-10 pt-8">
<div className="lg:max-w-[38.889vw] md:max-lg:max-w-[66.667vw] lg:space-y-[2.778vw] md:max-lg:space-y-10 space-y-8">
<div className="lg:space-y-[0.833vw] space-y-3 text2">
<p>
This Privacy Policy together with any other policies or notices
made available to you when we collect Personal Information from
you and our Terms of Service apply to your use of our Services.
</p>
<p>
When we refer to Personal Information, we mean any information
about an individual from which that person can be identified. It
does not include data where the identity has been removed, which
is referred to as anonymous data.
</p>
<p>
Our Services are not intended for children and we do not
knowingly collect Personal Information relating to children.
</p>
<p>
In the event of any inconsistency or conflict between our Terms
of Service and this Privacy Policy, this Privacy Policy shall
prevail.
</p>
<p>Personal Information that we collect and why we collect it</p>
</div>
<div className="lg:space-y-[0.833vw] space-y-3 text2">
<p>
<span className="font-bold">
We use different methods to collect Personal Information from
and about you including through:
</span>
<ul className="list-disc list-inside">
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
direct interactions with you, such as during the
registration process for Future ID;
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
automated technologies or interactions website;
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
third parties or publicly available sources.
</li>
</ul>
</p>
<p>
We may collect, store, process, use and transfer different kinds
of Personal Information about you which we have grouped together
as follows:
</p>
</div>
<div className="lg:space-y-[0.833vw] space-y-3 text2 grid grid-cols-[1fr_2fr] lg:gap-[0.833vw] gap-3">
<p className="font-bold">Сategory of data</p>
<p className="font-bold">
Includes the following types of Personal Information
</p>
<p>Identity Data</p>
<p>
Name, username or similar identifier, title, date of birth,
profile picture, nationality, location, gender, role/job title,
education history, personal biography description, tagline and
descriptive tags.
</p>
<p>Contact Data</p>
<p>
Delivery addresses, email addresses, social networking
profile(s), telephone numbers and contact information.
</p>
<p>Technical and Location Data</p>
<p>
Internet protocol (IP) address, device type, your login data,
browser type and version, time zone setting, browser plug-in
types and versions, operating system and platform and other
technology on the devices you use to access this Website, unique
device identification numbers, broad geographic location (e.g.
country or city-level location) and other technical information
from your device. Some services or functions of our Services may
make use of location-based information pursuant to which we may
collect information about the Wi-Fi routers closest to you and
the cell IDs of the towers closest to you.
</p>
<p>Usage Data</p>
<p>Information about how you use our Services.</p>
<p>Marketing and Communications Data</p>
<p>
Your preferences in receiving marketing from us and our third
parties and your communication preferences.
</p>
</div>
<div className="lg:space-y-[1.667vw] md:max-lg:space-y-6 space-y-3">
<p className="text2">
Some of this information may be collected using cookies and
similar tracking technology, as explained further under the
section titled Cookies.
</p>
<p className="text2">
<span className="font-bold">
We use Personal Information collected:
</span>
<ul className="list-disc list-inside">
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
to contact you, including providing you with communications
in relation to any applications to our Services and to
inform you of any relevant upcoming Services, opportunities
and offers;
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
to send related updates, if applicable;
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
to provide you goods, documentation or other materials in
the course of providing our Services;
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
to provide you with promotional/informative content based on
your preferences;
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
to respond to any questions and/or concerns that you submit
to us;
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
to allow other users of our Services to search and find any
public profile you may maintain when using our Services;
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
to compile relevant statistics and to monitor the
performance of our Services;
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
to identify and better understand the users of our Services,
where they come from, and what part of our Services
interests them, for internal analytics and statistical
purposes and to improve the relevance of content on our
Services;
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
to refine and develop our systems and analytics and to
increase quality assurance and standards for our Services.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
for such other uses you authorise and/or consent to from
time to time.
</li>
</ul>
</p>
<p className="text2">
Where we need to collect personal data by law, or under the
terms of a contract we have with you, and you fail to provide
that data when requested, we may have to suspend or terminate
your access to part or all of our Services.
</p>
<p className="text2">
If you share any personal data of a third party with us, please
ensure that you have the express consent from that third party
which permits you to share their personal data with us (and we
will assume that you have such consent prior to sharing their
personal data with us). We strongly advise you to keep a record
of their consent and provide them with a copy of, or link to,
this Privacy Policy. You acknowledge and agree that you shall
remain fully responsible and liable for obtaining the relevant
consent from that third party and for sharing their personal
data with us.
</p>
</div>
<div className="lg:space-y-[1.667vw] md:max-lg:space-y-6 space-y-3">
<h2 className="heading2 font-medium">Security</h2>
<p className="text2">
The security of your Personal Information is important to us. We
follow generally accepted industry standards to protect the
Personal Information formation submitted to us, both during
transmission and once we receive it. Our Services use
appropriate technical and organisational security measures to
protect your Personal Information. The measures used are
designed to provide a level of security appropriate to the risk
of unauthorised or unlawful processing of your Personal
Information.
</p>
<p className="text2">
Unfortunately, the transmission of Personal Information via the
internet is not completely secure. Although we will do our best
to protect your Personal Information, we cannot guarantee the
security of your Personal Information transmitted to us through
our Services.  Any transmission is at your own risk.  Once we
have received your Personal Information, we will use strict
procedures and security features to try to prevent unauthorised
access.  Please note that no website or online service can ever
be guaranteed as 100% secure and you should take reasonable
precautions to protect your Personal Information (for example,
by sharing Personal Information only with operators of websites
and other digital platforms that you trust, by keeping any login
details secure and confidential and by using antivirus software
on your devices).
</p>
<p className="text2">
We will retain your Personal Information for as long as we deem
necessary or appropriate, including to comply with our legal
obligations, resolve disputes and enforce our agreements. If you
wish to request that we no longer use your Personal Information,
please contact us via our Reach Us page.
</p>
</div>
<div className="lg:space-y-[1.667vw] md:max-lg:space-y-6 space-y-3">
<h2 className="heading2 font-medium">
International data transfers
</h2>
<p className="text2">
Personal Information submitted through our Services may be
hosted, transferred to, and processed in, countries other than
the country in which you are resident.  These countries may have
data protection laws that are different to the laws of your
country. However, we have taken appropriate safeguards to
require that your Personal Information will remain protected in
accordance with this Privacy Policy.
</p>
</div>
<div className="lg:space-y-[1.667vw] md:max-lg:space-y-6 space-y-3">
<h2 className="heading2 font-medium">Third Party Links</h2>
<p className="text2">
Our Services may include links to third-party websites, digital
platforms, plug-ins and applications. Clicking on those links or
enabling those connections may allow third parties to collect or
share information about you. We do not control these third-party
websites or digital platforms and we are not responsible for
their privacy statements. When you transition to other digital
platforms, whether directly or redirected from our own, we
encourage you to read the privacy policy and terms and
conditions of use/service for such digital platforms.
</p>
</div>
<div className="lg:space-y-[1.667vw] md:max-lg:space-y-6 space-y-3">
<h2 className="heading2 font-medium">
Correcting and Updating Your Personal Information
</h2>
<p className="text2">
To review or update your Personal Information to ensure it is
accurate, please contact us via our Reach Us page.
</p>
<p className="text2">
You may review, update or delete Personal Information from your
Future ID profile, or delete your Future ID, at any time through
the settings page that is accessible when logged in to your
Future ID.
</p>
<p className="text2">
When we have no ongoing legitimate business need to process your
Personal Information, we will either delete or anonymise it or,
if this is not possible (for example, because your Personal
Information has been stored in backup archives), then we will
securely store your Personal Information and isolate it from any
further processing until deletion is possible.
</p>
</div>
<div className="lg:space-y-[1.667vw] md:max-lg:space-y-6 space-y-3">
<h2 className="heading2 font-medium">
Notification of Privacy Policy Changes
</h2>
<p className="text2">
We may update this Privacy Policy to reflect changes to our
information practices or any relevant statute, regulations
and/or policy. We encourage you to periodically review this page
for the latest information on our privacy practices.
</p>
</div>
<div className="lg:space-y-[1.667vw] md:max-lg:space-y-6 space-y-3">
<h2 className="heading2 font-medium">Contact</h2>
<p className="text2">
You can contact us about this Privacy Policy or in order to
exercise your data protection rights via our Reach Us page.  We
will respond to all requests we receive from individuals wishing
to exercise their data protection rights in accordance with
applicable data protection laws.
</p>
</div>
</div>
</div>
<div className="lg:pl-[5.208vw] md:max-lg:pl-4 px-2.5 lg:py-[2.778vw] md:max-lg:py-10 py-8 w-full bg-[#232425] lg:rounded-b-[1.944vw]">
<button
onClick={() => lenis.current?.lenis?.scrollTo(0)}
className="lg:max-w-[38.889vw] md:max-lg:max-w-[66.667vw] w-full cursor-pointer flex items-center justify-center lg:gap-[0.556vw] gap-2 lg:py-[1.111vw] py-4 lg:rounded-[1.111vw] rounded-2xl bg-[#37393B99]"
>
<p className="btnm font-medium">Top</p>
<div className="text-white lg:size-[1.111vw] size-4">
<ArrowUpIcon />
</div>
</button>
</div>
</ReactLenis>
</div>
);
}
export default PrivacyPolicyPage;
@@ -0,0 +1,41 @@
"use client";
import CloseIcon from "@/components/icons/CloseIcon";
export default function TermConditionsLayout({
children,
}: {
children: React.ReactNode;
}) {
function handleClose() {
try {
window.close();
} catch {
// Если не удалось закрыть, пытаемся вернуться назад в истории
if (window.history.length > 1) {
window.history.back();
} else {
// Если и это не работает, перенаправляем на главную страницу
window.location.href = "/";
}
}
}
return (
<section className="fixed inset-0 bg-[#0F101199] [backdrop-filter:blur(16px)] z-[14]">
<button
className="fixed inset-0 cursor-pointer"
onClick={handleClose}
></button>
{children}
<button
onClick={handleClose}
className="fixed lg:right-[1.389vw] lg:top-[1.389vw] right-5 top-5 lg:rounded-[1.111vw] rounded-2xl bg-[#37393B99] lg:p-[1.111vw] p-4 cursor-pointer backdrop-blur-2xl"
>
<div className="text-white lg:size-[1.111vw] size-4">
<CloseIcon />
</div>
</button>
</section>
);
}
+539
View File
@@ -0,0 +1,539 @@
"use client";
import { useLenis } from "@/hooks/useLenis";
import ReactLenis from "lenis/react";
import ArrowUpIcon from "@/components/icons/ArrowUpIcon";
function TermsConditionsPage() {
const lenis = useLenis();
return (
<div className="absolute left-1/2 -translate-x-1/2 lg:w-[66.25vw] w-full overflow-y-auto max-h-dvh h-full alg:h-[calc(100vh-40px)]">
<ReactLenis ref={lenis} className="overflow-y-scroll h-full">
<div className="bg-gradient lg:px-[5.208vw] md:max-lg:px-4 px-2.5 lg:pt-[14.514vw] md:max-lg:pt-[157px] pt-[169px] lg:pb-[1.667vw] md:max-lg:pb-6 pb-4 lg:rounded-t-[1.944vw]">
<h1 className="heading1 font-medium">Terms & Conditions</h1>
</div>
<div className="bg-[#232425] lg:px-[5.208vw] md:max-lg:px-4 px-2.5 lg:pt-[2.778vw] md:max-lg:pt-10 pt-8">
<div className="lg:max-w-[38.889vw] md:max-lg:max-w-[66.667vw] lg:space-y-[1.667vw] md:max-lg:space-y-6 space-y-3">
<h2 className="heading2 font-medium">
Please read these Terms & Conditions carefully. These are the
general Terms & Conditions governing your access and use of this
website (Site).
</h2>
<h2 className="heading2 font-medium">
Acceptance of the Terms and Conditions
</h2>
<div className="lg:space-y-[0.833vw] md:max-lg:space-y-6 space-y-3">
<p className="text2">
This website is owned and operated by GRAFF interactive FZCO
(which term includes all subsidiaries of GRAFF interactive)
(GRAFF interactive Company, we or us). The following
terms and conditions entered into with the Company in respect of
which this website is used together with any documents they
expressly incorporate by reference (collectively, these Terms
and Conditions), govern your access to and use of
https://graffestate.ae/ (the “Website”), including any content,
functionality and services offered on or through the Website
whether as a guest or a registered user
</p>
<p className="text2">
Please read the Terms and Conditions carefully before you start
to use the Website. By using the Website or, where applicable,
by clicking to accept or agree to the Terms and Conditions when
this option is made available to you, you accept and agree to be
bound and abide by these Terms and Conditions and our Privacy
Policy, found at https://graffestate.ae/privacypolicy/,
incorporated herein by reference. If you do not want to agree to
these Terms and Conditions or the Privacy Policy, you must not
access or use the Website.
</p>
</div>
</div>
<div className="lg:max-w-[38.889vw] md:max-lg:max-w-[66.667vw] lg:space-y-[1.667vw] md:max-lg:space-y-6 space-y-3 lg:pt-[2.778vw] md:max-lg:pt-10 pt-8">
<h2 className="heading2 font-medium">
Changes to the Terms and Conditions
</h2>
<div className="lg:space-y-[0.833vw] md:max-lg:space-y-6 space-y-3">
<p className="text2">
We may revise and update these Terms and Conditions from time to
time in our sole discretion. All changes are effective
immediately when we post them, and apply to all access to and
use of the Website thereafter.
</p>
<p className="text2">
Your continued use of the Website following the posting of
revised Terms and Conditions means that you accept and agree to
the changes. You are expected to check this page from time to
time so you are aware of any changes, as they are binding on
you.
</p>
</div>
</div>
<div className="lg:max-w-[38.889vw] md:max-lg:max-w-[66.667vw] lg:space-y-[1.667vw] md:max-lg:space-y-6 space-y-3 lg:pt-[2.778vw] md:max-lg:pt-10 pt-8">
<h2 className="heading2 font-medium">
Accessing the Website and Account Security
</h2>
<div className="lg:space-y-[0.833vw] md:max-lg:space-y-6 space-y-3">
<p className="text2">
We reserve the right to withdraw or amend the Website, and any
service or material we provide on the Website, in our sole
discretion without notice. We will not be liable if for any
reason all or any part of the Website is unavailable at any time
or for any period. From time to time, we may restrict access to
some parts of the Website, or the entire Website, to any user,
including registered users.
</p>
<p className="text2 whitespace-pre-line">
{`You are responsible for:
Making all arrangements necessary for you to have access to the Website.
Ensuring that all persons who access the Website through your internet connection are aware of these Terms and Conditions and comply with them.`}
</p>
</div>
</div>
<div className="lg:max-w-[38.889vw] md:max-lg:max-w-[66.667vw] lg:space-y-[1.667vw] md:max-lg:space-y-6 space-y-3 lg:pt-[2.778vw] md:max-lg:pt-10 pt-8">
<h2 className="heading2 font-medium">
Intellectual Property Rights
</h2>
<div className="lg:space-y-[0.833vw] md:max-lg:space-y-6 space-y-3">
<p className="text2">
The Website and its entire contents, features and functionality
(including but not limited to all information, software, text,
displays, images, video and audio, and the design, selection and
arrangement thereof), are owned by the Company, its licensors or
other providers of such material and are protected by
international copyright, trademark, patent, trade secret and
other intellectual property or proprietary rights laws.
</p>
<p className="text2 whitespace-pre-line">
Your computer may temporarily store copies of such materials in
RAM incidental to your accessing and viewing those materials.
</p>
<p className="text2 whitespace-pre-line">
You may store files that are automatically cached by your Web
browser for display enhancement purposes.
</p>
<p className="text2 whitespace-pre-line">
You may print or download one copy of a reasonable number of
pages of the Website for your own personal, non-commercial use
and not for further reproduction, publication or distribution.
</p>
<p className="text2 whitespace-pre-line">
If we provide desktop, mobile or other applications for
download, you may download a single copy to your computer or
mobile device solely for your own personal, non-commercial use,
provided you agree to be bound by our end user license agreement
for such applications.
</p>
<p className="text2">
If we provide social media features with certain content, you
may take such actions as are enabled by such features.
</p>
<p className="text2">
<span className="font-bold">You must not:</span>
<ul className="list-disc list-inside">
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
Modify copies of any materials from this site.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
Republish any part of the Website on another website, in any
other medium (print, electronic or otherwise) or as part of
any commercial service.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
Use any illustrations, photographs, video or audio sequences
or any graphics separately from the accompanying text.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
Delete or alter any copyright, trademark or other
proprietary rights notices from copies of materials from
this site.
</li>
</ul>
</p>
<p className="text2">
No right, title or interest in or to the Website or any content
on the site is transferred to you, and all rights not expressly
granted are reserved by the Company. Any use of the Website not
expressly permitted by these Terms and Conditions is a breach of
these Terms and Conditions and may violate copyright, trademark
and other laws.
</p>
</div>
</div>
<div className="lg:max-w-[38.889vw] md:max-lg:max-w-[66.667vw] lg:space-y-[1.667vw] md:max-lg:space-y-6 space-y-3 lg:pt-[2.778vw] md:max-lg:pt-10 pt-8 lg:pb-[3.056vw] md:max-lg:pb-12 pb-6">
<h2 className="heading2 font-medium">Trademarks </h2>
<div className="">
<p className="text2">
The Companys names, brand names, the Companys logos and all
related names, logos, product and service names, designs and
slogans are trademarks of the Company or its affiliates or
licensors. You must not use such marks without the prior written
permission of the Company. All other names, logos, product and
service names, designs and slogans on this Website are the
trademarks of their respective owners.
</p>
</div>
</div>
<div className="lg:max-w-[38.889vw] md:max-lg:max-w-[66.667vw] lg:space-y-[1.667vw] md:max-lg:space-y-6 space-y-3 lg:pt-[2.778vw] md:max-lg:pt-10 pt-8">
<h2 className="heading2 font-medium">Prohibited Uses</h2>
<div className="lg:space-y-[0.833vw] md:max-lg:space-y-6 space-y-3">
<p className="text2">
You may use the Website only for lawful purposes and in
accordance with these Terms and Conditions.
</p>
<p className="text2 whitespace-pre-line">
<span className="font-bold">
You agree not to use the Website:
</span>
<ul className="list-disc list-inside text-left">
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
In any way that violates any applicable federal, local or
international law or regulation.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
To transmit, or procure the sending of, any advertising or
promotional material, including any junk mail, chain
letter or spam or any other similar solicitation.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
To impersonate or attempt to impersonate the Company, a
Company employee, another user or any other person or entity
(including, without limitation, by using e-mail addresses or
screen names associated with any of the foregoing).
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
To engage in any other conduct that restricts or inhibits
anyones use or enjoyment of the Website, or which, as
determined by us, may harm the Company or users of the
Website or expose them to liability.
</li>
</ul>
</p>
<p className="text2 whitespace-pre-line">
<span className="font-bold">
Additionally, you agree not to:
</span>
<ul className="list-disc list-inside text-left">
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
Use the Website in any manner that could disable,
overburden, damage, or impair the Website or interfere with
any other partys use of the Website, including their
ability to engage in real time activities through the
Website.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
Use any robot, spider or other automatic device, process or
means to access the Website for any purpose, including
monitoring or copying any of the material on the Website.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
Use any manual process to monitor or copy any of the
material on the Website or for any other unauthorized
purpose without our prior written consent.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
Use any device, software or routine that interferes with the
proper working of the Website.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
Introduce any viruses, trojan horses, worms, logic bombs or
other material which is malicious or technologically
harmful.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
Attempt to gain unauthorized access to, interfere with,
damage or disrupt any parts of the Website, the server on
which the Website is stored, or any server, computer or
database connected to the Website.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
Attack the Website via a denial-of-service attack or a
distributed denial-of-service attack.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
Otherwise attempt to interfere with the proper working of
the Website.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
Reliance on Information Posted
</li>
</ul>
</p>
<p className="text2">
The information presented on or through the Website is made
available solely for general information purposes. We do not
warrant the accuracy, completeness or usefulness of this
information. Any reliance you place on such information is
strictly at your own risk. We disclaim all liability and
responsibility arising from any reliance placed on such
materials by you or any other visitor to the Website, or by
anyone who may be informed of any of its contents.
</p>
<p className="text2">
GRAFF interactive reserves the absolute right, without any
liability whatsoever, to amend vary or extend at any time the
information mentioned on or through the Website.
</p>
<p className="text2">
<span className="font-bold">Update of the Website</span>
<br />
<br />
We may update the content on the Website from time to time, but
its content is not necessarily complete or up-to-date. Any of
the material on the Website may be out of date at any given
time, and we are under no obligation to update such material.
</p>
<p className="text2">
<span className="font-bold">
Information About You and Your Visits to the Website
</span>
<br />
<br />
All information we collect on this Website is subject to our
Privacy Policy. By using the Website, you consent to all actions
taken by us with respect to your information in compliance with
the Privacy Policy.
</p>
<p className="text2">
<span className="font-bold">
Online Purchases and Other Terms and Conditions
</span>
<br />
<br />
All purchases through our site or other transactions for the
sale of services formed through the Website or as a result of
visits made by you are governed by these Terms and Conditions.
</p>
<p className="text2">
Additional terms and conditions may also apply to specific
portions, services or features of the Website. All such
additional terms and conditions are hereby incorporated by this
reference into these Terms and Conditions.
</p>
<p className="text2">
<span className="font-bold">
Linking to the Website and Social Media Features
</span>
<br />
<br />
You may link to any page, provided you do so in a way that is
fair and legal and does not damage our reputation or take
advantage of it, but you must not establish a link in such a way
as to suggest any form of association, approval or endorsement
on our part.
</p>
<p className="text2 whitespace-pre-line">
<span className="font-bold">
This Website may provide certain social media features that
enable you to:
</span>
<ul className="list-disc list-inside text-left">
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
Link from your own or certain third-party websites to
certain content on this Website.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
Send e-mails or other communications with certain content,
or links to certain content, on this Website.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
Cause limited portions of content on this Website to be
displayed or appear to be displayed on your own or certain
third-party websites.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
You may use these features solely as they are provided by
us, solely with respect to the content they are displayed
with and otherwise in accordance with any additional terms
and conditions we provide with respect to such features.
</li>
</ul>
</p>
<p className="text2 whitespace-pre-line">
<span className="font-bold">
Subject to the foregoing, you must not:
</span>
<ul className="list-disc list-inside text-left">
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
Establish a link from any website that is not owned by you.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
Otherwise take any action with respect to the materials on
this Website that is inconsistent with any other provision
of these Terms and Conditions.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
You agree to cooperate with us in causing any unauthorized
framing or linking immediately to cease. We reserve the
right to withdraw linking permission without notice.
</li>
<br />
<li className="lg:pl-10 lg:-indent-7 md:max-lg:pl-5 md:max-lg:-indent-4.5 pl-4 -indent-4">
We may disable all or any social media features and any
links at any time without notice in our discretion.
</li>
</ul>
</p>
<p className="text2">
<span className="font-bold">Links From the Website</span>
<br />
<br />
If the Website contains links to other sites and resources
provided by third parties, these links are provided for your
convenience only. We have no control over the contents of those
sites or resources, and accept no responsibility for them or for
any loss or damage that may arise from your use of them. If you
decide to access any of the third party websites linked to this
Website, you do so entirely at your own risk and subject to the
terms and conditions of use for such websites.
</p>
<p className="text2">
<span className="font-bold">Disclaimer of Warranties</span>
<br />
<br />
You understand that we cannot and do not guarantee or warrant
that the Website will be free of viruses or other destructive
code. You are responsible for implementing sufficient procedures
and checkpoints to satisfy your particular requirements for
anti-virus protection and accuracy of data input and output, and
for maintaining a means external to our Website for any
reconstruction of any lost data.
</p>
<p className="text2">
We will not be liable for any loss or damage caused by a
distributed denial-of-service attack, viruses or other
technologically harmful material that may infect your computer
equipment, computer programs, data or other proprietary material
due to your use of the website or any services or items obtained
through the website or to your downloading of any material
posted on it, or on any website linked to it.
</p>
<p className="text2">
Your use of the website, its content and any services or items
obtained through the website is at your own risk. The website,
its content and any services or items obtained through the
website are provided on an as is and as available basis,
without any warranties of any kind, either express or implied.
Neither the company nor any person associated with the company
makes any warranty or representation with respect to the
completeness, security, reliability, quality, accuracy or
availability of the website. Without limiting the foregoing,
neither the company nor anyone associated with the company
represents or warrants that the website, its content or any
services or items obtained through the website will be accurate,
reliable, error-free or uninterrupted, that defects will be
corrected, that our site or the server that makes it available
are free of viruses or other harmful components or that the
website or any services will otherwise meet your needs or
expectations.
</p>
<p className="text2">
The company hereby disclaims all warranties of any kind, whether
express or implied, statutory or otherwise, including but not
limited to any warranties of non-infringement.
</p>
<p className="text2">
The foregoing does not affect any warranties which cannot be
excluded or limited under applicable law.
</p>
<p className="text2">
<span className="font-bold">Indemnification</span>
<br />
<br />
You agree to defend, indemnify and hold harmless the Company,
its affiliates, licensors and service providers, and its and
their respective officers, directors, employees, contractors,
agents, licensors, suppliers, successors and assigns from and
against any claims, liabilities, damages, judgments, awards,
losses, costs, expenses or fees (including reasonable attorneys
fees) arising out of or relating to your violation of these
Terms and Conditions or your use of the Website and, any use of
the Websites content, services and products other than as
expressly authorized in these Terms and Conditions or your use
of any information obtained from the Website.
</p>
<p className="text2 whitespace-pre-line">
<span className="font-bold">Waiver and Severability</span>
<br />
<br />
{`No waiver of by the Company of any term or condition set forth in these Terms and Conditions shall be deemed a further or continuing waiver of such term or condition or a waiver of any other term or condition, and any failure of the Company to assert a right or provision under these Terms and Conditions shall not constitute a waiver of such right or provision.
If any provision of these Terms and Conditions is held by a court or other tribunal of competent jurisdiction to be invalid, illegal or unenforceable for any reason, such provision shall be eliminated or limited to the minimum extent such that the remaining provisions of the Terms and Conditions will continue in full force and effect.`}
</p>
<p className="text2 whitespace-pre-line">
<span className="font-bold">Entire Agreement</span>
<br />
<br />
The Terms and Conditions, our Privacy Policy constitute the sole
and entire agreement between you and the Company with respect to
the Website and supersede all prior and contemporaneous
understandings, agreements, representations and warranties, both
written and oral, with respect to the Website.
</p>
<p className="text2 whitespace-pre-line">
<span className="font-bold">Your Comments and Concerns</span>
<br />
<br />
This website is operated and owned by the Company. In respect of
requests for technical support and other communications relating
to the Website, you can contact us by using our website contact
form, or by emailing us at info@graff.tech For feedback or
suggestions, please contact us through the Get in Touch form on
the Website.
</p>
<p className="text2">
You understand and accept that by using this Website in
updating, changing or altering your personal information,
address(es) or contact details, you are accepting that the
Company or any of its affiliates may, at their discretion, use
such information as an alternative information to send legal
notices under these Terms and Conditions. It is your obligation
to immediately inform the Company of any changes to such
information.
</p>
</div>
</div>
</div>
<div className="lg:pl-[5.208vw] md:max-lg:pl-4 px-2.5 lg:py-[2.778vw] md:max-lg:py-10 py-8 w-full bg-[#232425] lg:rounded-b-[1.944vw]">
<button
onClick={() => lenis.current?.lenis?.scrollTo(0)}
className="lg:max-w-[38.889vw] md:max-lg:max-w-[66.667vw] w-full cursor-pointer flex items-center justify-center lg:gap-[0.556vw] gap-2 lg:py-[1.111vw] py-4 lg:rounded-[1.111vw] rounded-2xl bg-[#37393B99]"
>
<p className="btnm font-medium">Top</p>
<div className="text-white lg:size-[1.111vw] size-4">
<ArrowUpIcon />
</div>
</button>
</div>
</ReactLenis>
</div>
);
}
export default TermsConditionsPage;
+27 -27
View File
@@ -1,36 +1,36 @@
import { ModalContainer } from '@/components/Layout/ModalContainer';
import type { Metadata } from 'next';
import Script from 'next/script';
import './globals.css';
import { QueryProvider } from '@/lib/QueryProvider';
import { LenisProvider } from '@/lib/LenisProvider';
import PopupModal from '@/components/modals/PopupModal';
import LocaleLayout from './[locale]/layout';
import { ModalContainer } from "@/components/Layout/ModalContainer";
import type { Metadata } from "next";
import Script from "next/script";
import "./globals.css";
import { QueryProvider } from "@/lib/QueryProvider";
import { LenisProvider } from "@/lib/LenisProvider";
import PopupModal from "@/components/modals/PopupModal";
import LocaleLayout from "./[locale]/layout";
export const metadata: Metadata = {
title: 'Interactive Solutions for Developers',
title: "Interactive Solutions for Developers",
description:
'We help developers effectively showcase their properties. Sell more and faster.',
"We help developers effectively showcase their properties. Sell more and faster.",
keywords: [
'real estate',
'developers',
'property developers',
'integration',
'sales offices',
'presentation',
'interactive tool',
'interactive presentation',
"real estate",
"developers",
"property developers",
"integration",
"sales offices",
"presentation",
"interactive tool",
"interactive presentation",
],
openGraph: {
title: 'Interactive Solutions for Property Developers',
title: "Interactive Solutions for Property Developers",
description:
'We help developers effectively showcase their properties. Sell more and faster.',
type: 'website',
siteName: 'Interactive Solutions for Developers',
url: 'https://graff.estate',
"We help developers effectively showcase their properties. Sell more and faster.",
type: "website",
siteName: "Interactive Solutions for Developers",
url: "https://graff.estate",
images: [
{
url: 'https://graff.estate/icon.svg',
url: "https://graff.estate/icon.svg",
width: 300,
height: 200,
},
@@ -45,17 +45,17 @@ export default function RootLayout({
}>) {
return (
<html>
<body className='min-h-screen flex flex-col justify-between'>
<body className="min-h-screen flex flex-col justify-between">
<QueryProvider>
<LenisProvider>
<LocaleLayout>
{/* <PopupModal /> */}
<PopupModal />
{children}
<ModalContainer />
</LocaleLayout>
</LenisProvider>
</QueryProvider>
<Script id='metrika-counter' strategy='afterInteractive'>
<Script id="metrika-counter" strategy="afterInteractive">
{`(function (m, e, t, r, i, k, a) {
m[i] =
m[i] ||
+15 -11
View File
@@ -1,15 +1,15 @@
import { useFieldArrayFormContext } from '@/lib/FieldArrayFormProvider';
import { RefObject, SyntheticEvent } from 'react';
import { FieldArrayWithId } from 'react-hook-form';
import AddIcon from '../../public/icons/add.svg';
import EditIcon from '../../public/icons/edit.svg';
import TrashIcon from '../../public/icons/trash.svg';
import { IArticleInput } from './modals/ArticleFormModal';
import { useFieldArrayFormContext } from "@/lib/FieldArrayFormProvider";
import { RefObject, SyntheticEvent } from "react";
import { FieldArrayWithId } from "react-hook-form";
import AddIcon from "@/components/icons/AddIcon";
import EditIcon from "@/components/icons/EditIcon";
import TrashIcon from "@/components/icons/TrashIcon";
import { IArticleInput } from "./modals/ArticleFormModal";
interface IBlockActionsProps {
index: number;
btnref: RefObject<HTMLButtonElement>;
item: FieldArrayWithId<IArticleInput, 'blocks', 'id'>;
item: FieldArrayWithId<IArticleInput, "blocks", "id">;
}
export function BlockActions({
@@ -40,13 +40,17 @@ export function BlockActions({
return (
<div className="flex gap-x-4">
<button ref={btnref} onClick={handleEditBlock} className="cursor-pointer">
<EditIcon className="text-white lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4" />
<div className="text-white lg:size-[1.111vw] size-4">
<EditIcon />
</div>
</button>
<button onClick={handleDublicateBlock} className="cursor-pointer">
<AddIcon className="text-white lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4" />
<AddIcon />
</button>
<button onClick={handleRemoveBlock} className="cursor-pointer">
<TrashIcon className="text-white lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4" />
<div className="text-white lg:size-[1.111vw] size-4">
<TrashIcon />
</div>
</button>
</div>
);
+18 -16
View File
@@ -1,7 +1,7 @@
import { useDeleteMutation } from '@/hooks/useDeleteMutation';
import { useModalStore } from '@/stores/useModalStore';
import { Button } from '@/ui/Button';
import CloseIcon from '../../public/icons/close.svg';
import { useDeleteMutation } from "@/hooks/useDeleteMutation";
import { useModalStore } from "@/stores/useModalStore";
import { Button } from "@/ui/Button";
import CloseIcon from "@/components/icons/CloseIcon";
export function DeleteItemModal({
title,
@@ -9,7 +9,7 @@ export function DeleteItemModal({
id,
}: {
title: string;
entity: 'projects' | 'companies' | 'articles' | 'stories' | 'map';
entity: "projects" | "companies" | "articles" | "stories" | "map";
id: string;
}) {
const { setModal } = useModalStore();
@@ -25,23 +25,25 @@ export function DeleteItemModal({
className="hover:bg-white
hover:bg-opacity-10 p-2 transition-colors rounded-full cursor-pointer group"
>
<CloseIcon className="lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4 text-white group-hover:text-black" />
<div className="text-white lg:size-[1.111vw] size-4 group-hover:text-black">
<CloseIcon />
</div>
</button>
</div>
<Button
onClick={remove}
className="self-end text-white outline-none rounded-2xl btns cursor-pointer"
>
Удалить{' '}
{entity === 'projects'
? 'проект'
: entity === 'companies'
? 'компанию'
: entity === 'articles'
? 'статью'
: entity === 'stories'
? 'историю'
: 'проект на карте'}
Удалить{" "}
{entity === "projects"
? "проект"
: entity === "companies"
? "компанию"
: entity === "articles"
? "статью"
: entity === "stories"
? "историю"
: "проект на карте"}
</Button>
</div>
);
+32 -24
View File
@@ -1,23 +1,23 @@
import { api } from '@/api';
import { Button } from '@/ui/Button';
import { ChangeEvent, useCallback, useEffect, useState } from 'react';
import Dropzone from 'react-dropzone';
import { api } from "@/api";
import { Button } from "@/ui/Button";
import { ChangeEvent, useCallback, useEffect, useState } from "react";
import Dropzone from "react-dropzone";
import {
FieldValues,
Path,
PathValue,
useFormContext,
useWatch,
} from 'react-hook-form';
import AddIcon from '../../public/icons/add.svg';
import RestartIcon from '../../public/icons/restart.svg';
import TrashIcon from '../../public/icons/trash.svg';
} from "react-hook-form";
import AddIcon from "@/components/icons/AddIcon";
import RestartIcon from "@/components/icons/RestartIcon";
import TrashIcon from "@/components/icons/TrashIcon";
export function ImageUploader<T extends FieldValues>({
dest,
name,
label = 'Выберите или перетащите изображение',
className = '',
label = "Выберите или перетащите изображение",
className = "",
required = false,
}: {
dest: string;
@@ -27,7 +27,7 @@ export function ImageUploader<T extends FieldValues>({
className?: string;
}) {
const [file, setFile] = useState<File>();
const [previewFile, setPreviewFile] = useState('');
const [previewFile, setPreviewFile] = useState("");
const { register, setValue, control } = useFormContext();
@@ -44,12 +44,12 @@ export function ImageUploader<T extends FieldValues>({
if (!file) return;
const formData = new FormData();
formData.append('dest', dest);
formData.append('files', file);
formData.append("dest", dest);
formData.append("files", file);
try {
const filePaths = await api
.post('upload', { body: formData })
.post("upload", { body: formData })
.json<PathValue<T, Path<T>>[]>();
setValue(name, filePaths[0]!);
} catch (error) {
@@ -71,19 +71,19 @@ export function ImageUploader<T extends FieldValues>({
setFile(file);
setPreviewFile(URL.createObjectURL(file));
}}
accept={{ 'image/*': ['*'] }}
accept={{ "image/*": ["*"] }}
noClick
>
{({ getRootProps, getInputProps, inputRef }) => (
<div
{...getRootProps()}
className={`relative border border-[#37393B] px-3 py-2 rounded-lg flex flex-col justify-center items-center gap-2${
className ? ' ' + className : ''
className ? " " + className : ""
}`}
>
<input
type="file"
accept={'image/*'}
accept={"image/*"}
required={required}
{...{ ...register(name, { required }), ref: inputRef }}
onChange={handleChangeFile}
@@ -93,7 +93,7 @@ export function ImageUploader<T extends FieldValues>({
<>
<div
className={`relative${
name === 'image' ? ' max-w-[calc(292/824*100%)]' : ''
name === "image" ? " max-w-[calc(292/824*100%)]" : ""
}`}
>
<img
@@ -101,9 +101,9 @@ export function ImageUploader<T extends FieldValues>({
previewFile ||
process.env.NEXT_PUBLIC_S3_BUCKET + currentImg
}
alt={''}
alt={""}
className={`pointer-events-none aspect-square object-${
name === 'image' ? 'cover rounded-2xl' : 'contain'
name === "image" ? "cover rounded-2xl" : "contain"
} !relative`}
sizes="100%"
/>
@@ -115,7 +115,9 @@ export function ImageUploader<T extends FieldValues>({
className="px-3 py-2 bg-[#37393B99] btns"
rounded="xl"
icon={
<RestartIcon className="lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4 text-white" />
<div className="text-white lg:size-[1.111vw] size-4">
<RestartIcon />
</div>
}
>
Заменить
@@ -125,11 +127,13 @@ export function ImageUploader<T extends FieldValues>({
e.preventDefault();
setFile(undefined!);
setValue(name, undefined!);
setPreviewFile('');
setPreviewFile("");
}}
className="bg-[#37393B99] px-3 py-2 rounded-xl cursor-pointer"
>
<TrashIcon className="lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4 text-white" />
<div className="text-white lg:size-[1.111vw] size-4">
<TrashIcon />
</div>
</button>
</div>
</>
@@ -142,7 +146,11 @@ export function ImageUploader<T extends FieldValues>({
onClick={() => inputRef.current?.click()}
color="secondary"
className="bg-[#37393B99] rounded-xl px-3 py-[9px] btnm"
icon={<AddIcon className="w-4 h-4 text-white" />}
icon={
<div className="text-white lg:size-[1.111vw] size-4">
<AddIcon />
</div>
}
>
Выбрать
</Button>
+40 -36
View File
@@ -1,25 +1,25 @@
'use client';
"use client";
import { useCheckAuthQuery } from '@/queries/checkAuth';
import { useModalStore } from '@/stores/useModalStore';
import { IArticle } from '@/types/IArticle';
import { ICompany } from '@/types/ICompany';
import { IProject } from '@/types/IProject';
import { IStory } from '@/types/IStory';
import { isArticle } from '@/utils/isArticle';
import { isCompany } from '@/utils/isCompany';
import { isProject } from '@/utils/isProject';
import { isStory } from '@/utils/isStory';
import { SyntheticEvent } from 'react';
import EditIcon from '../../public/icons/edit.svg';
import TrashIcon from '../../public/icons/trash.svg';
import { DeleteItemModal } from './DeleteItemModal';
import { ArticleContentFormModal } from './modals/ArticleContentFormModal';
import { CompanyFormModal } from './modals/CompanyFormModal';
import { MapPointProjectFormModal } from './modals/MapPointFormModal';
import { ProjectFormModal } from './modals/ProjectFormModal';
import { StoryFormModal } from './modals/StoryFormModal';
import { IMapProject } from '@/types/IMapProject';
import { useCheckAuthQuery } from "@/queries/checkAuth";
import { useModalStore } from "@/stores/useModalStore";
import { IArticle } from "@/types/IArticle";
import { ICompany } from "@/types/ICompany";
import { IProject } from "@/types/IProject";
import { IStory } from "@/types/IStory";
import { isArticle } from "@/utils/isArticle";
import { isCompany } from "@/utils/isCompany";
import { isProject } from "@/utils/isProject";
import { isStory } from "@/utils/isStory";
import { SyntheticEvent } from "react";
import EditIcon from "@/components/icons/EditIcon";
import TrashIcon from "@/components/icons/TrashIcon";
import { DeleteItemModal } from "./DeleteItemModal";
import { ArticleContentFormModal } from "./modals/ArticleContentFormModal";
import { CompanyFormModal } from "./modals/CompanyFormModal";
import { MapPointProjectFormModal } from "./modals/MapPointFormModal";
import { ProjectFormModal } from "./modals/ProjectFormModal";
import { StoryFormModal } from "./modals/StoryFormModal";
import { IMapProject } from "@/types/IMapProject";
export function ItemActions({
item,
@@ -42,10 +42,10 @@ export function ItemActions({
setModal(<CompanyFormModal action="edit" defaultValues={company} />);
} else if (isArticle(item)) setModal(<ArticleContentFormModal {...item} />);
else if (isStory(item))
setModal(<StoryFormModal action={'edit'} defaultValues={item} />);
setModal(<StoryFormModal action={"edit"} defaultValues={item} />);
else
setModal(
<MapPointProjectFormModal action={'edit'} defaultValues={item} />
<MapPointProjectFormModal action={"edit"} defaultValues={item} />
);
}
@@ -55,27 +55,27 @@ export function ItemActions({
<DeleteItemModal
id={item.id}
title={
'Удаление ' +
"Удаление " +
(isProject(item)
? 'проекта'
? "проекта"
: isCompany(item)
? 'компании'
? "компании"
: isArticle(item)
? 'статьи'
? "статьи"
: isStory(item)
? 'истории'
: 'проекта на карте')
? "истории"
: "проекта на карте")
}
entity={
isProject(item)
? 'projects'
? "projects"
: isCompany(item)
? 'companies'
? "companies"
: isArticle(item)
? 'articles'
? "articles"
: isStory(item)
? 'stories'
: 'map'
? "stories"
: "map"
}
/>
);
@@ -87,13 +87,17 @@ export function ItemActions({
onClick={handleEdit}
className="relative lg:px-[0.833vw] lg:py-[0.556vw] px-3 py-2 bg-[#37393B99] backdrop-blur-sm rounded-full outline-none cursor-pointer"
>
<EditIcon className="lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4 text-white" />
<div className="text-white lg:size-[1.111vw] size-4">
<EditIcon />
</div>
</button>
<button
onClick={handleDelete}
className="relative lg:px-[0.833vw] lg:py-[0.556vw] px-3 py-2 bg-[#37393B99] backdrop-blur-sm rounded-full outline-none cursor-pointer"
>
<TrashIcon className="lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4 text-white" />
<div className="text-white lg:size-[1.111vw] size-4">
<TrashIcon />
</div>
</button>
</div>
);
+101 -78
View File
@@ -1,35 +1,36 @@
'use client';
"use client";
import { api } from "@/api";
import { projectsTags } from "@/consts/projectsTags";
import { Product } from "@/types/Product";
import { Button } from "@/ui/Button";
import { CheckboxesGroup } from "@/ui/CheckboxesGroup";
import { getExampleNumber } from "libphonenumber-js";
import examples from "libphonenumber-js/mobile/examples";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useEffect, useMemo, useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
import ReactInputMask from "react-input-mask";
import { Country } from "react-phone-number-input";
import CheckIcon from "@/components/icons/CheckIcon";
import { useTranslations } from "next-intl";
import { api } from '@/api';
import { projectsTags } from '@/consts/projectsTags';
import { Product } from '@/types/Product';
import { Button } from '@/ui/Button';
import { CheckboxesGroup } from '@/ui/CheckboxesGroup';
import { getExampleNumber } from 'libphonenumber-js';
import examples from 'libphonenumber-js/mobile/examples';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { useEffect, useMemo, useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import ReactInputMask from 'react-input-mask';
import { Country } from 'react-phone-number-input';
import CheckIcon from '../../../public/icons/check.svg';
import { useTranslations } from 'next-intl';
export function Feedback() {
const pathname = usePathname();
const t = useTranslations('feedback');
const t = useTranslations("feedback");
return (
<div
id='contacts'
id="contacts"
className={`lg:mb-20 md:mb-12 lg:flex lg:gap-[0.833vw] max-lg:space-y-12 justify-between lg:mt-[14.07vh]${
!pathname.startsWith('/form') ? ' mt-25' : ''
} mb-10${pathname.startsWith('/prime') ? ' max-lg:hidden' : ''}`}
!pathname.startsWith("/form") ? " mt-25" : ""
} mb-10${pathname.startsWith("/prime") ? " max-lg:hidden" : ""}`}
>
<h2 className='line2 font-medium max-lg:mb-6 lg:max-w-[45%]'>
<span className='text-[#7A7A7A]'>{t('title')}</span>
<h2 className="line2 font-medium max-lg:mb-6 lg:max-w-[45%]">
<span className="text-[#7A7A7A]">{t("title")}</span>
<br />
{t('description')}
{t("description")}
</h2>
<FeedbackForm />
</div>
@@ -46,7 +47,7 @@ interface IInput {
export function FeedbackForm() {
const [[phoneCode, country], setPhoneCodeAndCountry] = useState<
[string, Country]
>(['+971', 'AE']);
>(["+971", "AE"]);
const placeholder = useMemo(
() => getExampleNumber(country, examples),
@@ -54,7 +55,7 @@ export function FeedbackForm() {
);
const form = useForm<IInput>({
defaultValues: { products: [] },
defaultValues: { products: ["Интерактивная презентация"] },
});
const { register, handleSubmit, formState } = form;
@@ -62,92 +63,114 @@ export function FeedbackForm() {
const handlePhoneChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
// Remove all spaces and ensure we have the correct country code
const cleanValue = value.replaceAll(/ /g, '');
if (!cleanValue.startsWith('+971')) {
const cleanValue = value.replaceAll(/ /g, "");
if (!cleanValue.startsWith("+971")) {
// If the value doesn't start with +971, force it
form.setValue('phone', '+971' + cleanValue.replace('+', ''));
form.setValue("phone", "+971" + cleanValue.replace("+", ""));
} else {
form.setValue('phone', cleanValue);
form.setValue("phone", cleanValue);
}
};
async function onSubmit(data: IInput) {
await api.post('mail', { json: data }).json();
await api.post("mail", { json: data }).json();
}
const t = useTranslations('feedback');
const t = useTranslations("feedback");
return (
<div className='flex-1 space-y-4 lg:max-w-[47.431vw]'>
<div className='space-y-10'>
<div className="flex-1 space-y-4 lg:max-w-[47.431vw]">
<div className="space-y-10">
{!formState.isSubmitted ? (
<FormProvider {...form}>
<form
className='lg:space-y-[1.944vw] md:max-lg:space-y-7 space-y-3'
className="lg:space-y-[1.944vw] md:max-lg:space-y-7 space-y-3"
onSubmit={handleSubmit(onSubmit)}
>
<div className='lg:space-y-[1.111vw] space-y-4'>
<p className='heading2 font-medium'>{t('products')}</p>
<CheckboxesGroup name='products' options={projectsTags} />
<div className="lg:space-y-[1.111vw] space-y-4">
<p className="heading2 font-medium">{t("products")}</p>
<CheckboxesGroup name="products" options={projectsTags} />
</div>
<input
id='name'
autoComplete='none'
type='text'
id="name"
autoComplete="none"
type="text"
required
placeholder={t('name')}
{...register('fullname')}
className='bg-transparent border-b border-[#37393B] focus:border-white py-4 rounded-none outline-none transition-all w-full placeholder:btnl btnl placeholder:font-medium placeholder:select-none'
placeholder={t("name")}
{...register("fullname")}
className="bg-transparent border-b border-[#37393B] focus:border-white py-4 rounded-none outline-none transition-all w-full placeholder:btnl btnl placeholder:font-medium placeholder:select-none"
/>
<input
autoComplete='none'
required
id='email'
type='email'
placeholder='Email*'
{...register('email')}
className='bg-transparent border-b border-[#37393B] focus:border-white py-4 rounded-none btnl outline-none transition-all w-full placeholder:btnl placeholder:font-medium placeholder:select-none'
/>
<div className='flex gap-x-3 py-2 border-[#3D425C] relative'>
{/* <div className="flex gap-x-3 py-2 border-[#3D425C] relative">
<ReactInputMask
type='tel'
autoComplete='none'
required
type="tel"
autoComplete="none"
onChange={handlePhoneChange}
id={'tel'}
id={"tel"}
maskChar={null}
mask={'+971 59 999 9999'}
placeholder={'+971 5 X XXX XXXX'}
value={form.watch('phone')}
className='placeholder:btnl placeholder:font-medium placeholder:select-none peer btnl w-full h-full transition-all bg-transparent rounded-none outline-none'
mask={"+971 59 999 9999"}
placeholder={"+971 5 X XXX XXXX"}
value={form.watch("phone")}
className="placeholder:btnl placeholder:font-medium placeholder:select-none peer btnl w-full h-full transition-all bg-transparent rounded-none outline-none"
/>
<div className='bottom-0 absolute w-full border-b border-[#37393B] peer-focus:border-white -mb-2' />
</div>
<div className='md:flex items-stretch lg:gap-[0.833vw] gap-3'>
<div className="bottom-0 absolute w-full border-b border-[#37393B] peer-focus:border-white -mb-2" />
</div> */}
<input
required
autoComplete="none"
id="phone"
type="tel"
placeholder={"Phone*"}
{...register("phone")}
className="bg-transparent border-b border-[#37393B] focus:border-white py-4 rounded-none btnl outline-none transition-all w-full placeholder:btnl placeholder:font-medium placeholder:select-none"
/>
<input
autoComplete="none"
id="email"
type="email"
placeholder="Email"
{...register("email")}
className="bg-transparent border-b border-[#37393B] focus:border-white py-4 rounded-none btnl outline-none transition-all w-full placeholder:btnl placeholder:font-medium placeholder:select-none"
/>
<div className="md:flex items-stretch lg:gap-[0.833vw] gap-3">
<Button
type='submit'
className='btnl max-md:mb-3 max-md:w-full lg:px-[2.222vw] lg:py-[1.389vw] px-8 py-5 cursor-pointer lg:rounded-[1.111vw] rounded-2xl'
type="submit"
className="btnl max-md:mb-3 max-md:w-full lg:px-[2.222vw] lg:py-[1.389vw] px-8 py-5 cursor-pointer lg:rounded-[1.111vw] rounded-2xl"
>
{t('submit')}
{t("submit")}
</Button>
<Link
href={'/policy'}
className='text2 xl:max-w-[60%] md:max-lg:max-w-[40%] md:max-lg:py-1'
>
<div className="text2 xl:max-w-[60%] md:max-lg:max-w-[45%] md:max-lg:py-1">
<p>
<span className='text-[#7A7A7A]'>{t('policy')}</span>{' '}
{t('policy_link')}
<span className="text-[#7A7A7A]">{t("remark")}</span>{" "}
<a
href={"/terms-conditions"}
target="_blank"
className="underline"
>
{t("terms_conditions_links")}
</a>{" "}
<span className="text-[#7A7A7A]">and </span>
<a
href={"/privacypolicy"}
target="_blank"
className="underline"
>
{t("policy_link")}
</a>
</p>
</Link>
</div>
</div>
</form>
</FormProvider>
) : (
<div className='bg-[#37393B99] aspect-[643/480] w-full rounded-2xl flex justify-center items-center'>
<div className='flex items-center justify-center gap-3'>
<div className='bg-gradient p-3 rounded-full'>
<CheckIcon className='text-white lg:w-[1.667vw] lg:h-[1.667vw] w-6 h-6' />
<div className="bg-[#37393B99] aspect-[643/480] w-full rounded-2xl flex justify-center items-center">
<div className="flex items-center justify-center gap-3">
<div className="bg-gradient p-3 rounded-full">
<div className="text-white lg:size-[1.667vw] size-6">
<CheckIcon />
</div>
</div>
<p className='heading2 font-medium'>
<p className="heading2 font-medium">
We received your request
<br />
and will contact you soon!
+16 -19
View File
@@ -2,13 +2,9 @@
import Link from "next/link";
import { PropsWithChildren } from "react";
import ArrowMoreIcon from "../../../public/icons/arrow_more.svg";
import RutubeIcon from "../../../public/icons/rutube.svg";
import TelegramIcon from "../../../public/icons/tg.svg";
import VkIcon from "../../../public/icons/vk.svg";
import YoutubeIcon from "../../../public/icons/youtube.svg";
import ArrowMoreIcon from "@/components/icons/ArrowMoreIcon";
import YoutubeIcon from "@/components/icons/YoutubeIcon";
import { useTranslations } from "next-intl";
import { useLocale } from "next-intl";
export function Footer() {
const t = useTranslations("footer");
@@ -26,7 +22,9 @@ export function Footer() {
<p className="text-[#7A7A7A] text1 font-medium">{t("call")}</p>
<div className="lg:line2 md:max-lg:heading1 line2 flex items-center font-medium">
+971 58 506 0097
<ArrowMoreIcon className="text-white lg:w-[5.556vw] lg:h-[5.556vw] md:max-lg:w-[4.167vw] md:max-lg:h-[4.167vw] w-[10vw] h-[10vw]" />
<div className="text-white lg:size-[5.556vw] md:max-lg:size-[4.167vw] size-[10vw]">
<ArrowMoreIcon />
</div>
</div>
</Link>
<Link
@@ -36,7 +34,9 @@ export function Footer() {
<p className="text-[#7A7A7A] text1 font-medium">{t("write")}</p>
<div className="lg:line2 md:max-lg:heading1 line2 flex items-center font-medium">
sam@graff.tech
<ArrowMoreIcon className="text-white lg:w-[5.556vw] lg:h-[5.556vw] md:max-lg:w-[4.167vw] md:max-lg:h-[4.167vw] w-[10vw] h-[10vw]" />
<div className="text-white lg:size-[5.556vw] md:max-lg:size-[4.167vw] size-[10vw]">
<ArrowMoreIcon />
</div>
</div>
</Link>
<div className="gap-y-2 justify-between md:gap-x-[1.042vw] gap-x-[1.111vw] md:flex-col flex">
@@ -50,26 +50,23 @@ export function Footer() {
<VkIcon className="lg:w-[1.389vw] lg:h-[1.389vw] md:max-lg:w-[2.083vw] md:max-lg:h-[2.083vw] w-[5.556vw] h-[5.556vw] text-white group-hover:text-black" />
</ContactLink> */}
<ContactLink href="https://www.youtube.com/@GRAFFinteractive">
<YoutubeIcon className="lg:w-[1.389vw] lg:h-[1.389vw] md:max-lg:w-[2.083vw] md:max-lg:h-[2.083vw] w-[5.556vw] h-[5.556vw] text-white group-hover:text-black" />
<div className="text-white lg:size-[1.389vw] md:max-lg:size-[2.083vw] size-[5.556vw] group-hover:text-black">
<YoutubeIcon />
</div>
</ContactLink>
</div>
</div>
<div className="lg:gap-x-[1.667vw] gap-y-2 lg:flex grid">
<Link
href={"/policy"}
<a
target="_blank"
href={"/privacypolicy"}
className="text-[#37393B] text1 font-medium leading-[18.9px] w-fit"
>
{t("privacy")}
</Link>
</a>
<p className="text-[#37393B] text1 font-medium leading-[18.9px] col-start-1">
{t("copyright")}
</p>
<Link
href={"https://graff.tech"}
className="text-[#37393B] text1 font-medium leading-[18.9px] lg:w-fit md:col-start-2 md:text-right w-full"
>
graff.tech
</Link>
</div>
</footer>
);
@@ -83,7 +80,7 @@ export function ContactLink({
return (
<Link
href={href}
className={`lg:rounded-[1.111vw] rounded-2xl bg-[#37393B99] lg:p-[1.25vw] p-[18px] hover:bg-white transition-all hover:text-black flex justify-center w-full group ${className}`}
className={`lg:rounded-[1.111vw] rounded-2xl bg-[#37393B99] lg:p-[1.25vw] p-[18px] hover:bg-white transition-all hover:text-black flex justify-center w-fit group ${className}`}
>
{children}
</Link>
+14 -18
View File
@@ -6,26 +6,20 @@ import { useMediaQueries } from "@/hooks/useMediaQueries";
import { useScroll } from "@/hooks/useScroll";
import { useCheckAuthQuery } from "@/queries/checkAuth";
import { HeaderLink } from "@/ui/HeaderLink";
import {
QueryClient,
useMutation,
useQueryClient,
} from "@tanstack/react-query";
import { useMutation } from "@tanstack/react-query";
import { AnimatePresence, motion } from "framer-motion";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useRef, useState } from "react";
import { useOnClickOutside } from "usehooks-ts";
import BurgerIcon from "../../../public/icons/burger.svg";
import CloseIcon from "../../../public/icons/close.svg";
import GraffIcon from "../../../public/icons/graff.svg";
import LogoIcon from "../../../public/icons/logo_hor.svg";
import SkolkovoIcon from "../../../public/icons/skolkovo.svg";
import BurgerIcon from "@/components/icons/BurgerIcon";
import CloseIcon from "@/components/icons/CloseIcon";
import GraffIcon from "@/components/icons/GraffIcon";
import { LogoIcon } from "@/components/icons/LogoIcon";
import { Products } from "./Products";
import { useAuthStore } from "@/stores/useAuthStore";
import { getQueryClient } from "@/lib/queryClient";
import { useTranslations } from "next-intl";
import { useLocale } from "next-intl";
export function Header() {
const t = useTranslations("header");
@@ -75,7 +69,9 @@ export function Header() {
ref={logoRef}
className="max-lg:hidden cursor-pointer outline-none"
>
<LogoIcon className="w-[13.333vw] aspect-[4/1]" />
<div className="w-[13.333vw] aspect-[4/1]">
<LogoIcon />
</div>
</Link>
<div className="relative flex justify-center flex-1 m-auto">
<AnimatePresence>
@@ -91,7 +87,9 @@ export function Header() {
href={"/"}
className="aspect-square lg:p-[1.111vw] p-3 hover:bg-[#232425] group active:bg-white lg:rounded-[1.111vw] rounded-2xl content-center m-auto"
>
<GraffIcon className="text-white group-active:text-black lg:w-[1.111vw] md:max-lg:w-[2.083vw] w-4 lg:h-[1.111vw] md:max-lg:h-[2.083vw] h-4" />
<div className="text-white group-active:text-black lg:size-[1.111vw] md:max-lg:size-[2.083vw] size-4">
<GraffIcon />
</div>
</Link>
)}
<div
@@ -138,11 +136,9 @@ export function Header() {
className="!border-none p-[18px] hover:bg-[#232425] rounded-2xl active:opacity-50 outline-none cursor-pointer"
onClick={() => setBurgerOpened((prev) => !prev)}
>
{burgerOpened ? (
<CloseIcon className="lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4" />
) : (
<BurgerIcon className="lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4" />
)}
<div className="text-white lg:size-[1.111vw] size-4">
{burgerOpened ? <CloseIcon /> : <BurgerIcon />}
</div>
</button>
</div>
{auth && (
+11 -13
View File
@@ -1,14 +1,14 @@
/* eslint-disable @next/next/no-img-element */
import countries from 'countries-phone-masks';
import countries from "countries-phone-masks";
import {
CountryCode,
getCountries,
getCountryCallingCode,
} from 'libphonenumber-js';
import { SyntheticEvent, useRef, useState } from 'react';
import { useOnClickOutside } from 'usehooks-ts';
import ChevronDownIcon from '../../../public/icons/chevron_down.svg';
import ChevronUpIcon from '../../../public/icons/chevron_up.svg';
} from "libphonenumber-js";
import { SyntheticEvent, useRef, useState } from "react";
import { useOnClickOutside } from "usehooks-ts";
import ChevronDownIcon from "@/components/icons/ChevronDownIcon";
import ChevronUpIcon from "@/components/icons/ChevronUpIcon";
export function SelectPhoneCode({
currentPhoneCodeAndCountry: [currentPhoneCode, currentCountry],
@@ -42,16 +42,14 @@ export function SelectPhoneCode({
<img
width={16}
height={8}
src={countries.find((c) => c.iso === currentCountry)?.flag || ''}
src={countries.find((c) => c.iso === currentCountry)?.flag || ""}
className="!relative w-4 sm:w-6"
alt={currentCountry}
/>
<p className="btnl font-medium">{currentPhoneCode}</p>
{open ? (
<ChevronUpIcon className="max-sm:w-4 sm:max-lg:w-5 text-white" />
) : (
<ChevronDownIcon className="max-sm:w-4 sm:max-lg:w-5 text-white" />
)}
<div className="text-white lg:size-[1.111vw] size-4">
{open ? <ChevronUpIcon /> : <ChevronDownIcon />}
</div>
</button>
{open && (
<div className="space-y-1 absolute z-10 bg-[#14161F] top-[100%] -left-1 border border-t-0 rounded-b-lg border-[#37393B] max-h-[300px] overflow-y-auto overflow-x-hidden">
@@ -68,7 +66,7 @@ export function SelectPhoneCode({
onClick={() => pickPhoneCode(phoneCode, country as CountryCode)}
>
<img
src={countries.find((c) => c.iso === country)?.flag || ''}
src={countries.find((c) => c.iso === country)?.flag || ""}
alt={country}
className="!relative w-4 sm:w-6"
width={16}
+26 -18
View File
@@ -1,11 +1,11 @@
import { api } from '@/api';
import { Button } from '@/ui/Button';
import { ChangeEvent, useCallback, useEffect, useState } from 'react';
import Dropzone from 'react-dropzone';
import { useFormContext, useWatch } from 'react-hook-form';
import AddIcon from '../../public/icons/add.svg';
import RestartIcon from '../../public/icons/restart.svg';
import TrashIcon from '../../public/icons/trash.svg';
import { api } from "@/api";
import { Button } from "@/ui/Button";
import { ChangeEvent, useCallback, useEffect, useState } from "react";
import Dropzone from "react-dropzone";
import { useFormContext, useWatch } from "react-hook-form";
import AddIcon from "@/components/icons/AddIcon";
import RestartIcon from "@/components/icons/RestartIcon";
import TrashIcon from "@/components/icons/TrashIcon";
export function VideoUploader({
name,
@@ -19,7 +19,7 @@ export function VideoUploader({
const { register, control, setValue } = useFormContext();
const [file, setFile] = useState<File>();
const [previewFile, setPreviewFile] = useState('');
const [previewFile, setPreviewFile] = useState("");
const currentVideo = useWatch({ control, name });
@@ -36,14 +36,14 @@ export function VideoUploader({
if (!file) return;
const formData = new FormData();
formData.append('dest', dest);
formData.append('files', file);
formData.append("dest", dest);
formData.append("files", file);
console.log(formData.getAll('files'));
console.log(formData.getAll("files"));
try {
const filePaths = await api
.post('upload', { body: formData })
.post("upload", { body: formData })
.json<string[]>();
setValue(name, filePaths[0]!);
} catch (error) {
@@ -65,7 +65,7 @@ export function VideoUploader({
setPreviewFile(URL.createObjectURL(file));
}}
accept={{
'video/*': ['*'],
"video/*": ["*"],
}}
noClick
>
@@ -104,7 +104,9 @@ export function VideoUploader({
className="px-3 py-2 bg-[#37393B99] btns"
rounded="xl"
icon={
<RestartIcon className="lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4 text-white" />
<div className="text-white lg:size-[1.111vw] size-4">
<RestartIcon />
</div>
}
>
Заменить
@@ -114,11 +116,13 @@ export function VideoUploader({
e.preventDefault();
setFile(undefined!);
setValue(name, undefined!);
setPreviewFile('');
setPreviewFile("");
}}
className="bg-[#37393B99] px-3 py-2 rounded-xl cursor-pointer"
>
<TrashIcon className="lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4 text-white" />
<div className="text-white lg:size-[1.111vw] size-4">
<TrashIcon />
</div>
</button>
</div>
</>
@@ -131,7 +135,11 @@ export function VideoUploader({
onClick={() => inputRef.current?.click()}
color="secondary"
className="bg-[#37393B99] rounded-xl px-3 py-[9px] btnm"
icon={<AddIcon className="w-4 h-4 text-white" />}
icon={
<div className="text-white lg:size-[1.111vw] size-4">
<AddIcon />
</div>
}
>
Выбрать
</Button>
@@ -1,12 +1,12 @@
import { useFieldArrayFormContext } from '@/lib/FieldArrayFormProvider';
import { IButtonLink } from '@/types/IArticle';
import { TextInput } from '@/ui/TextInput';
import { Reorder } from 'framer-motion';
import Link from 'next/link';
import { useEffect, useState } from 'react';
import ArrowMoreIcon from '../../../public/icons/arrow_more.svg';
import CloseIcon from '../../../public/icons/close.svg';
import { IArticleInput } from '../modals/ArticleFormModal';
import { useFieldArrayFormContext } from "@/lib/FieldArrayFormProvider";
import { IButtonLink } from "@/types/IArticle";
import { TextInput } from "@/ui/TextInput";
import { Reorder } from "framer-motion";
import Link from "next/link";
import { useEffect, useState } from "react";
import ArrowMoreIcon from "@/components/icons/ArrowMoreIcon";
import CloseIcon from "@/components/icons/CloseIcon";
import { IArticleInput } from "../modals/ArticleFormModal";
interface IArticleButtonLinkInputProps {
index: number;
@@ -19,15 +19,15 @@ export function ArticleButtonLinkInput({
}: IArticleButtonLinkInputProps) {
const { remove, watch } = useFieldArrayFormContext<IArticleInput>();
const [title, setTitle] = useState('');
const [link, setLink] = useState('');
const [title, setTitle] = useState("");
const [link, setLink] = useState("");
useEffect(() => {
const { unsubscribe } = watch(({ blocks }) => {
if (!blocks || !blocks.length || blocks[index]?.type !== 'ButtonLink')
if (!blocks || !blocks.length || blocks[index]?.type !== "ButtonLink")
return;
setTitle(blocks[index]?.title ?? '');
setLink(blocks[index]?.link ?? '');
setTitle(blocks[index]?.title ?? "");
setLink(blocks[index]?.link ?? "");
});
return unsubscribe;
@@ -44,8 +44,10 @@ export function ArticleButtonLinkInput({
href={link}
className="rounded-2xl bg-gradient px-6 py-4 flex gap-2 items-center btnm font-medium w-fit"
>
{title ?? 'Название кнопки'}
<ArrowMoreIcon className="lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4 text-white" />
{title ?? "Название кнопки"}
<div className="text-white lg:size-[1.111vw] size-4">
<ArrowMoreIcon />
</div>
</Link>
)}
<div className="flex gap-4 justify-stretch">
@@ -59,7 +61,9 @@ export function ArticleButtonLinkInput({
className="p-1 absolute top-2 right-2 cursor-pointer"
onClick={() => remove(index)}
>
<CloseIcon className="lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4 text-white" />
<div className="text-white lg:size-[1.111vw] size-4">
<CloseIcon />
</div>
</button>
</Reorder.Item>
);
@@ -1,9 +1,9 @@
import { useFieldArrayFormContext } from '@/lib/FieldArrayFormProvider';
import { IImage } from '@/types/IArticle';
import { Reorder } from 'framer-motion';
import CloseIcon from '../../../public/icons/close.svg';
import { ImageUploader } from '../ImageUploader';
import { IArticleInput } from '../modals/ArticleFormModal';
import { useFieldArrayFormContext } from "@/lib/FieldArrayFormProvider";
import { IImage } from "@/types/IArticle";
import { Reorder } from "framer-motion";
import CloseIcon from "@/components/icons/CloseIcon";
import { ImageUploader } from "../ImageUploader";
import { IArticleInput } from "../modals/ArticleFormModal";
export function ArticleImageInput({
item,
@@ -14,7 +14,7 @@ export function ArticleImageInput({
}) {
const { remove } = useFieldArrayFormContext<IArticleInput>();
return (
<Reorder.Item value={item} as="div" style={{ display: 'relative' }}>
<Reorder.Item value={item} as="div" style={{ display: "relative" }}>
<div className="relative">
<ImageUploader
dest="articles"
@@ -25,7 +25,9 @@ export function ArticleImageInput({
className="cursor-pointer absolute top-5 right-5 z-10"
onClick={() => remove(index)}
>
<CloseIcon className="text-white lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4" />
<div className="text-white lg:size-[1.111vw] size-4">
<CloseIcon />
</div>
</button>
</div>
</Reorder.Item>
@@ -1,11 +1,11 @@
import { useFieldArrayFormContext } from '@/lib/FieldArrayFormProvider';
import { IQuote } from '@/types/IArticle';
import { TextInput } from '@/ui/TextInput';
import { Reorder } from 'framer-motion';
import { useWatch } from 'react-hook-form';
import CloseIcon from '../../../public/icons/close.svg';
import { ImageUploader } from '../ImageUploader';
import { IArticleInput } from '../modals/ArticleFormModal';
import { useFieldArrayFormContext } from "@/lib/FieldArrayFormProvider";
import { IQuote } from "@/types/IArticle";
import { TextInput } from "@/ui/TextInput";
import { Reorder } from "framer-motion";
import { useWatch } from "react-hook-form";
import CloseIcon from "@/components/icons/CloseIcon";
import { ImageUploader } from "../ImageUploader";
import { IArticleInput } from "../modals/ArticleFormModal";
export function ArticleQuoteInput({
index,
@@ -41,8 +41,8 @@ export function ArticleQuoteInput({
</div>
</div>
<TextInput
label={''}
placeholder={'Текст'}
label={""}
placeholder={"Текст"}
name={`blocks.${index}.text`}
textareaValue={text}
/>
@@ -50,7 +50,9 @@ export function ArticleQuoteInput({
onClick={() => remove(index)}
className="absolute top-5 right-5 cursor-pointer"
>
<CloseIcon className="text-white lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4" />
<div className="text-white lg:size-[1.111vw] size-4">
<CloseIcon />
</div>
</button>
</Reorder.Item>
);
@@ -1,12 +1,12 @@
import { Reorder } from 'framer-motion';
import { SyntheticEvent } from 'react';
import { UseFieldArrayRemove } from 'react-hook-form';
import CloseIcon from '../../../public/icons/close.svg';
import { ImageUploader } from '../ImageUploader';
import { Reorder } from "framer-motion";
import { SyntheticEvent } from "react";
import { UseFieldArrayRemove } from "react-hook-form";
import CloseIcon from "@/components/icons/CloseIcon";
import { ImageUploader } from "../ImageUploader";
interface IArticleSliderImageInputProps {
remove: UseFieldArrayRemove;
item: Record<'img', string> & Record<'id', string>;
item: Record<"img", string> & Record<"id", string>;
index: number;
imgIndex: number;
}
@@ -33,7 +33,9 @@ export function ArticleSliderImageInput({
className="self-start z-[1] cursor-pointer"
onClick={handleClickClose}
>
<CloseIcon className="text-white lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4" />
<div className="text-white lg:size-[1.111vw] size-4">
<CloseIcon />
</div>
</button>
</Reorder.Item>
);
@@ -1,16 +1,16 @@
import { useFieldArrayFormContext } from '@/lib/FieldArrayFormProvider';
import { ISlider } from '@/types/IArticle';
import { reorderFields } from '@/utils/reorderFields';
import { Reorder } from 'framer-motion';
import { SyntheticEvent } from 'react';
import { useFieldArray } from 'react-hook-form';
import AddIcon from '../../../public/icons/add.svg';
import TrashIcon from '../../../public/icons/trash.svg';
import { IArticleInput } from '../modals/ArticleFormModal';
import { ArticleSliderImageInput } from './ArticleSliderImageInput';
import { useFieldArrayFormContext } from "@/lib/FieldArrayFormProvider";
import { ISlider } from "@/types/IArticle";
import { reorderFields } from "@/utils/reorderFields";
import { Reorder } from "framer-motion";
import { SyntheticEvent } from "react";
import { useFieldArray } from "react-hook-form";
import AddIcon from "@/components/icons/AddIcon";
import TrashIcon from "@/components/icons/TrashIcon";
import { IArticleInput } from "../modals/ArticleFormModal";
import { ArticleSliderImageInput } from "./ArticleSliderImageInput";
interface IArticleSliderInputProps {
item: ISlider & Record<'id', string>;
item: ISlider & Record<"id", string>;
index: number;
}
@@ -25,7 +25,7 @@ export function ArticleSliderInput({ index, item }: IArticleSliderInputProps) {
function handleAddSlide(e: SyntheticEvent) {
e.preventDefault();
append({ img: '', type: 'Image' });
append({ img: "", type: "Image" });
}
function handleRemoveSlider(e: SyntheticEvent) {
@@ -41,10 +41,14 @@ export function ArticleSliderInput({ index, item }: IArticleSliderInputProps) {
>
<div className="flex gap-x-4 justify-center">
<button onClick={handleAddSlide} className="cursor-pointer">
<AddIcon className="text-white lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4" />
<div className="text-white lg:size-[1.111vw] size-4">
<AddIcon />
</div>
</button>
<button onClick={handleRemoveSlider} className="cursor-pointer">
<TrashIcon className="text-white lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4" />
<div className="text-white lg:size-[1.111vw] size-4">
<TrashIcon />
</div>
</button>
</div>
<Reorder.Group
@@ -1,8 +1,8 @@
import { useFieldArrayFormContext } from '@/lib/FieldArrayFormProvider';
import { IVideo } from '@/types/IArticle';
import { Reorder } from 'framer-motion';
import TrashIcon from '../../../public/icons/trash.svg';
import { VideoUploader } from '../VideoUploader';
import { useFieldArrayFormContext } from "@/lib/FieldArrayFormProvider";
import { IVideo } from "@/types/IArticle";
import { Reorder } from "framer-motion";
import TrashIcon from "@/components/icons/TrashIcon";
import { VideoUploader } from "../VideoUploader";
export function ArticleVideoUploader({
item,
@@ -21,7 +21,9 @@ export function ArticleVideoUploader({
>
<VideoUploader name={`blocks.${index}.src`} dest="articles" />
<button onClick={() => remove(index)} className="cursor-pointer">
<TrashIcon className="text-white lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4" />
<div className="text-white lg:size-[1.111vw] size-4">
<TrashIcon />
</div>
</button>
</Reorder.Item>
);
+14
View File
@@ -0,0 +1,14 @@
function AddIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M3 11h8V3h2v8h8v2h-8v8h-2v-8H3z"
fill="currentColor"
/>
</svg>
);
}
export default AddIcon;
+14
View File
@@ -0,0 +1,14 @@
function ArrowDownIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M10.96 16.05V4l2.08 2.08v9.97l5.504-5.505 1.471 1.47L12 20.031l-8.016-8.016 1.471-1.47z"
fill="currentColor"
/>
</svg>
);
}
export default ArrowDownIcon;
+14
View File
@@ -0,0 +1,14 @@
function ArrowLeftIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M7.966 13.025h12.05l-2.08-2.08h-9.97l5.505-5.505-1.47-1.47-8.016 8.015L12 20l1.471-1.47z"
fill="currentColor"
/>
</svg>
);
}
export default ArrowLeftIcon;
+14
View File
@@ -0,0 +1,14 @@
function ArrowMoreIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="m15.588 9.59-8.52 8.52v-2.94l7.049-7.05H6.332V6.04h11.336v11.336h-2.08z"
fill="currentColor"
/>
</svg>
);
}
export default ArrowMoreIcon;
+14
View File
@@ -0,0 +1,14 @@
function ArrowRightIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M16.034 10.975H3.984l2.08 2.08h9.97l-5.505 5.505 1.47 1.47 8.016-8.015L12 4l-1.471 1.47z"
fill="currentColor"
/>
</svg>
);
}
export default ArrowRightIcon;
+14
View File
@@ -0,0 +1,14 @@
function ArrowUpIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M10.96 7.95V20l2.08-2.08V7.95l5.504 5.505 1.471-1.47L12 3.969l-8.016 8.016 1.471 1.47z"
fill="#fff"
/>
</svg>
);
}
export default ArrowUpIcon;
+12
View File
@@ -0,0 +1,12 @@
function BurgerIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M21 6.667H3V4h15.429zm-18 4h18v2.666H3zm0 6.666h18V20H5.571z"
fill="currentColor"
/>
</svg>
);
}
export default BurgerIcon;
+14
View File
@@ -0,0 +1,14 @@
function CheckIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="m9.707 18 9.707-9.707L18 6.879l-8.293 8.293-4.293-4.293L4 12.293z"
fill="currentColor"
/>
</svg>
);
}
export default CheckIcon;
+14
View File
@@ -0,0 +1,14 @@
function ChevronDownIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M12 17.707 19.707 10l-1.414-1.414L12 14.879 5.707 8.586 4.293 10z"
fill="currentColor"
/>
</svg>
);
}
export default ChevronDownIcon;
+14
View File
@@ -0,0 +1,14 @@
function ChevronLeftIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M7 11.707 14.707 4l1.414 1.414-6.293 6.293L16.121 18l-1.414 1.414z"
fill="currentColor"
/>
</svg>
);
}
export default ChevronLeftIcon;
+14
View File
@@ -0,0 +1,14 @@
function ChevronRightIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M17.121 11.707 9.414 4 8 5.414l6.293 6.293L8 18l1.414 1.414z"
fill="currentColor"
/>
</svg>
);
}
export default ChevronRightIcon;
+14
View File
@@ -0,0 +1,14 @@
function ChevronUpIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="m12 6.586 7.707 7.707-1.414 1.414L12 9.414l-6.293 6.293-1.414-1.414z"
fill="currentColor"
/>
</svg>
);
}
export default ChevronUpIcon;
+14
View File
@@ -0,0 +1,14 @@
function CloseIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M6.343 4.929 12 10.586l5.657-5.657 1.414 1.414L13.414 12l5.657 5.657-1.414 1.414L12 13.414l-5.657 5.657-1.414-1.414L10.586 12 4.929 6.343z"
fill="currentColor"
/>
</svg>
);
}
export default CloseIcon;
File diff suppressed because one or more lines are too long
+34
View File
@@ -0,0 +1,34 @@
function EditIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clipPath="url(#a)">
<mask
id="b"
style={{
maskType: "alpha",
}}
maskUnits="userSpaceOnUse"
x={0}
y={0}
width={24}
height={24}
>
<path fill="currentColor" d="M0 0h24v24H0z" />
</mask>
<g mask="url(#b)">
<path
d="M3 21v-4.25L16.2 3.575q.3-.275.663-.425.362-.15.762-.15t.775.15.65.45L20.425 5q.3.275.438.65a2.17 2.17 0 0 1 0 1.512 1.9 1.9 0 0 1-.438.663L7.25 21zM17.6 7.8 19 6.4 17.6 5l-1.4 1.4z"
fill="currentColor"
/>
</g>
</g>
<defs>
<clipPath id="a">
<path fill="currentColor" d="M0 0h24v24H0z" />
</clipPath>
</defs>
</svg>
);
}
export default EditIcon;
+14
View File
@@ -0,0 +1,14 @@
function EduIcon() {
return (
<svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="m11.456 23.112-6.73-3.41a1.14 1.14 0 0 1 0-2.032l18.845-9.547a1.14 1.14 0 0 1 1.033.002l18.673 9.547a1.14 1.14 0 0 1 0 2.029l-.674.345v8.104a1.9 1.9 0 0 1 1.14 1.742v3.038a1.9 1.9 0 1 1-3.799 0v-3.038a1.9 1.9 0 0 1 1.14-1.741v-7.328l-4.558 2.33-11.922 6.095a1.14 1.14 0 0 1-1.033.002m-.859 1.694L11.456 25.24v6.93h.005c.18 3.793 5.72 6.837 12.53 6.837s12.35-3.044 12.53-6.837h.005v-6.885l-11.057 5.653a3.04 3.04 0 0 1-2.757.005"
fill="currentColor"
/>
</svg>
);
}
export default EduIcon;
+14
View File
@@ -0,0 +1,14 @@
function FiltersIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M6.5 14.389a2.139 2.139 0 1 0 0 4.278 2.139 2.139 0 0 0 0-4.278M2.634 15.61a3.974 3.974 0 0 1 7.732 0H23v1.833H10.366a3.974 3.974 0 0 1-7.732 0H1V15.61zM17.5 5.833a2.139 2.139 0 1 1 0 4.278 2.139 2.139 0 0 1 0-4.278m3.866 1.223a3.974 3.974 0 0 0-7.732 0H1v1.833h12.634a3.974 3.974 0 0 0 7.732 0H23V7.056z"
fill="currentColor"
/>
</svg>
);
}
export default FiltersIcon;
+12
View File
@@ -0,0 +1,12 @@
function FingerPrintIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M6.997 12.102a11.8 11.8 0 0 1-1.24 5.292.7.7 0 1 1-1.253-.623 10.4 10.4 0 0 0 1.093-4.669A6.28 6.28 0 0 1 7.96 7.183a.7.7 0 0 1 .875 1.094 4.88 4.88 0 0 0-1.838 3.825m4.901-.7a.7.7 0 0 0-.7.7c0 2.728-.693 5.411-2.013 7.798a.7.7 0 0 0 1.225.68 17.5 17.5 0 0 0 2.188-8.478.7.7 0 0 0-.7-.7m0-2.8a3.5 3.5 0 0 0-3.5 3.5.7.7 0 1 0 1.4 0 2.1 2.1 0 0 1 4.2 0 18.7 18.7 0 0 1-1.795 8.052.702.702 0 0 0 1.27.598 20.1 20.1 0 0 0 1.926-8.65 3.5 3.5 0 0 0-3.501-3.5m0-5.602a9.11 9.11 0 0 0-9.102 9.102 7.7 7.7 0 0 1-.438 2.567.7.7 0 0 0 1.321.466c.344-.974.518-2 .517-3.033a7.702 7.702 0 0 1 15.404 0c0 1.6-.155 3.196-.463 4.765a.7.7 0 0 0 1.373.272c.326-1.66.49-3.346.49-5.037A9.11 9.11 0 0 0 11.898 3m-2.94 11.217a.7.7 0 0 0-.823.547 13.2 13.2 0 0 1-1.507 3.977.7.7 0 1 0 1.213.7 14.6 14.6 0 0 0 1.663-4.397.7.7 0 0 0-.547-.827m2.94-8.416q-.395 0-.788.049a.7.7 0 0 0 .175 1.389 4.908 4.908 0 0 1 5.514 4.863q0 1.362-.168 2.713a.7.7 0 0 0 .693.793.7.7 0 0 0 .693-.613q.177-1.438.175-2.888a6.31 6.31 0 0 0-6.294-6.306m5.07 11.224a.7.7 0 0 0-.853.503c-.128.498-.276.998-.438 1.488a.7.7 0 0 0 1.07.791.7.7 0 0 0 .254-.345c.175-.519.332-1.05.468-1.58a.7.7 0 0 0-.5-.856z"
fill="currentColor"
/>
</svg>
);
}
export default FingerPrintIcon;
+29
View File
@@ -0,0 +1,29 @@
function FolderBack() {
return (
<svg viewBox="0 0 222 190" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M205.568 190H16.96C8.058 190 .84 182.784.84 173.882V16.118C.841 7.216 8.058 0 16.96 0h81.578c5.904 0 10.689 4.786 10.689 10.69a5.345 5.345 0 0 0 5.345 5.344h90.996c8.902 0 16.119 7.216 16.119 16.118v141.73c0 8.902-7.217 16.118-16.119 16.118"
fill="currentColor"
/>
<path
d="M205.568 190H16.96C8.058 190 .84 182.784.84 173.882V16.118C.841 7.216 8.058 0 16.96 0h81.578c5.904 0 10.689 4.786 10.689 10.69a5.345 5.345 0 0 0 5.345 5.344h90.996c8.902 0 16.119 7.216 16.119 16.118v141.73c0 8.902-7.217 16.118-16.119 16.118"
fill="url(#a)"
/>
<defs>
<linearGradient
id="a"
x1={111.264}
y1={0}
x2={111.264}
y2={190}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="currentColor" stopOpacity={0.4} />
<stop offset={1} stopColor="currentColor" stopOpacity={0} />
</linearGradient>
</defs>
</svg>
);
}
export default FolderBack;
+29
View File
@@ -0,0 +1,29 @@
function FolderFront() {
return (
<svg viewBox="0 0 248 155" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M219.693 154.998H26.543c-8.315 0-15.266-6.326-16.047-14.605L.686 36.404c-.9-9.548 6.685-17.765 16.275-17.63l48.918.687c4.656.066 9.27-.878 13.527-2.767l33.305-14.777a16.1 16.1 0 0 1 6.537-1.385h112.033c9.503 0 16.944 8.18 16.047 17.64L235.74 140.4c-.785 8.275-7.734 14.597-16.047 14.597"
fill="currentColor"
/>
<path
d="M219.693 154.998H26.543c-8.315 0-15.266-6.326-16.047-14.605L.686 36.404c-.9-9.548 6.685-17.765 16.275-17.63l48.918.687c4.656.066 9.27-.878 13.527-2.767l33.305-14.777a16.1 16.1 0 0 1 6.537-1.385h112.033c9.503 0 16.944 8.18 16.047 17.64L235.74 140.4c-.785 8.275-7.734 14.597-16.047 14.597"
fill="url(#a)"
/>
<defs>
<linearGradient
id="a"
x1={124}
y1={0.532}
x2={124}
y2={154.998}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="currentColor" stopOpacity={0} />
<stop offset={1} stopColor="currentColor" stopOpacity={0.4} />
</linearGradient>
</defs>
</svg>
);
}
export default FolderFront;
+12
View File
@@ -0,0 +1,12 @@
function FullscreenIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="m5.414 20 4.293-4.293-1.414-1.414L4 18.586v-4.293l-2 2V22h5.707l2-2zM20 5.414v4.293l2-2V2h-5.707l-2 2h4.293l-4.293 4.293 1.414 1.414z"
fill="currentColor"
/>
</svg>
);
}
export default FullscreenIcon;
+16
View File
@@ -0,0 +1,16 @@
function GraffIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M17.8603 2H21.8523V5.98661L19.6278 8.05375H15.7837V4.21479L17.8603 2Z"
fill="currentColor"
/>
<path
d="M22.0001 12.0133C22.0001 11.3659 21.9384 10.733 21.8206 10.1199C21.8183 10.0933 21.8159 10.0667 21.8134 10.0402L15.7635 10.0401V13.9999L15.7642 13.9999L17.7129 13.9999C16.8908 16.3524 14.6495 18.0402 12.0135 18.0402C11.9874 18.0402 11.9614 18.0401 11.9355 18.0397C8.63872 17.9977 5.97921 15.3157 5.97921 12.0133C5.97921 8.86571 8.39537 6.28166 11.4765 6.01002C11.6349 5.99605 11.7951 5.98819 11.9568 5.98668C11.9757 5.98651 11.9946 5.98642 12.0135 5.98642L12.0142 5.98642V2.02665H12C6.47717 2.02665 2 6.49784 2 12.0133C2 17.5288 6.47717 22 12 22C17.5229 22 22.0001 17.5288 22.0001 12.0133Z"
fill="currentColor"
/>
</svg>
);
}
export default GraffIcon;
+12
View File
@@ -0,0 +1,12 @@
function HearthIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M20.525 4.572c-1.968-2.096-5.157-2.096-7.124 0L12 6.064l-1.4-1.492c-1.968-2.096-5.157-2.096-7.125 0s-1.967 5.492 0 7.588L12 22l8.525-9.84c1.967-2.096 1.967-5.493 0-7.588"
fill="currentColor"
/>
</svg>
);
}
export default HearthIcon;
+14
View File
@@ -0,0 +1,14 @@
function KidsIcon() {
return (
<svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M42.301 3.805a2 2 0 1 0-2.58 3.057c1.525 1.286 2.027 3.03 1.783 4.663-2.769-1.39-5.946-2.192-9.44-2.192-11.64 0-20.272 10.178-21.091 21.213-6.424 2.59-5.382 10.892 1.278 12.234h1.278c3.65 6.939 9.933 11.954 17.896 11.886 8.543-.073 15.338-4.159 19.173-11.886 7.888 0 8.989-8.993 2.557-12.234 0-6.412-3.005-12.704-8.094-16.748 1.157-3.298.554-7.198-2.76-9.993m2.76 9.993a20.5 20.5 0 0 0-3.557-2.274c-.48 3.21-3.84 5.987-7.972 4.006a2 2 0 0 0-1.73 3.607c6.19 2.967 11.579-.552 13.259-5.34M24.394 31.12q.032.02.058.047a.3.3 0 0 1-.058.047.3.3 0 0 1-.057-.047.3.3 0 0 1 .057-.047m0-3.884c-1.187 0-2.222.468-2.938 1.28-.683.774-.98 1.747-.98 2.652.001.905.299 1.877.981 2.65.716.812 1.75 1.281 2.937 1.281s2.222-.469 2.938-1.28c.682-.774.98-1.746.98-2.65 0-.906-.297-1.879-.98-2.653-.716-.811-1.75-1.28-2.938-1.28m16.617 3.884q.032.02.058.047a.3.3 0 0 1-.058.047.3.3 0 0 1-.057-.047.3.3 0 0 1 .057-.047m0-3.884c-1.187 0-2.222.468-2.938 1.28a4 4 0 0 0-.979 2.652c0 .905.298 1.877.98 2.65.716.812 1.75 1.281 2.937 1.281 1.188 0 2.222-.469 2.938-1.28.682-.774.98-1.746.98-2.65 0-.906-.297-1.879-.98-2.653-.716-.811-1.75-1.28-2.938-1.28m-.338 14.817a2 2 0 1 0-3.158-2.454c-1.76 2.264-3.692 3.115-5.422 3.09-1.758-.026-3.732-.965-5.515-3.134a2 2 0 1 0-3.09 2.541c2.333 2.835 5.332 4.545 8.546 4.592 3.243.048 6.283-1.602 8.64-4.635"
fill="currentColor"
/>
</svg>
);
}
export default KidsIcon;
+40
View File
@@ -0,0 +1,40 @@
function LoaderIcon() {
return (
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g
clipPath="url(#paint0_angular_10_1208_clip_path)"
data-figma-skip-parse="true"
>
<g transform="matrix(0.0056 0.0056 -0.0056 0.0056 8 8)">
<foreignObject
x={-1607.14}
y={-1607.14}
width={3214.29}
height={3214.29}
>
<div
style={{
background:
"conic-gradient(from 90deg,rgba(255, 255, 255, 0.0195) 0deg,rgba(255, 255, 255, 1) 314.826deg,rgba(255, 255, 255, 0) 353.741deg,rgba(255, 255, 255, 0.0195) 360deg)",
height: "100%",
width: "100%",
opacity: 1,
}}
/>
</foreignObject>
</g>
</g>
<path
d="M14.9999 8C15.5523 8 16.0064 7.5505 15.9376 7.00248C15.745 5.46994 15.1116 4.01808 14.1039 2.82871C12.8797 1.38372 11.1826 0.419892 9.31444 0.108723C7.44632 -0.202447 5.52839 0.159221 3.90189 1.12938C2.27539 2.09953 1.04582 3.61525 0.431936 5.40685C-0.181945 7.19846 -0.140318 9.14975 0.549411 10.9135C1.23914 12.6773 2.53224 14.1392 4.19863 15.0391C5.86502 15.9391 7.79663 16.2186 9.64978 15.828C11.1751 15.5066 12.5658 14.7483 13.6578 13.6559C14.0483 13.2653 13.9652 12.6317 13.529 12.2929C13.0927 11.9542 12.4693 12.0409 12.0629 12.4149C11.2735 13.1413 10.2989 13.6472 9.2373 13.8709C7.84748 14.1638 6.39881 13.9541 5.14904 13.2792C3.89928 12.6043 2.92948 11.5079 2.4122 10.1851C1.89491 8.86229 1.86369 7.39886 2.32409 6.05519C2.78449 4.71152 3.70665 3.57476 4.92649 2.84716C6.14634 2.11956 7.58475 1.84832 8.9858 2.08169C10.3869 2.31506 11.6597 3.03791 12.5778 4.12163C13.2791 4.94938 13.7387 5.94667 13.9167 7.00451C14.0083 7.54918 14.4476 8 14.9999 8Z"
data-figma-gradient-fill="{&#34;type&#34;:&#34;GRADIENT_ANGULAR&#34;,&#34;stops&#34;:[{&#34;color&#34;:{&#34;r&#34;:1.0,&#34;g&#34;:1.0,&#34;b&#34;:1.0,&#34;a&#34;:1.0},&#34;position&#34;:0.87451690435409546},{&#34;color&#34;:{&#34;r&#34;:1.0,&#34;g&#34;:1.0,&#34;b&#34;:1.0,&#34;a&#34;:0.0},&#34;position&#34;:0.98261332511901855}],&#34;stopsVar&#34;:[],&#34;transform&#34;:{&#34;m00&#34;:11.199999809265137,&#34;m01&#34;:-11.199999809265137,&#34;m02&#34;:8.0,&#34;m10&#34;:11.199999809265137,&#34;m11&#34;:11.199999809265137,&#34;m12&#34;:-3.1999998092651367},&#34;opacity&#34;:1.0,&#34;blendMode&#34;:&#34;NORMAL&#34;,&#34;visible&#34;:true}"
/>
<defs>
<clipPath id="paint0_angular_10_1208_clip_path">
<path d="M14.9999 8C15.5523 8 16.0064 7.5505 15.9376 7.00248C15.745 5.46994 15.1116 4.01808 14.1039 2.82871C12.8797 1.38372 11.1826 0.419892 9.31444 0.108723C7.44632 -0.202447 5.52839 0.159221 3.90189 1.12938C2.27539 2.09953 1.04582 3.61525 0.431936 5.40685C-0.181945 7.19846 -0.140318 9.14975 0.549411 10.9135C1.23914 12.6773 2.53224 14.1392 4.19863 15.0391C5.86502 15.9391 7.79663 16.2186 9.64978 15.828C11.1751 15.5066 12.5658 14.7483 13.6578 13.6559C14.0483 13.2653 13.9652 12.6317 13.529 12.2929C13.0927 11.9542 12.4693 12.0409 12.0629 12.4149C11.2735 13.1413 10.2989 13.6472 9.2373 13.8709C7.84748 14.1638 6.39881 13.9541 5.14904 13.2792C3.89928 12.6043 2.92948 11.5079 2.4122 10.1851C1.89491 8.86229 1.86369 7.39886 2.32409 6.05519C2.78449 4.71152 3.70665 3.57476 4.92649 2.84716C6.14634 2.11956 7.58475 1.84832 8.9858 2.08169C10.3869 2.31506 11.6597 3.03791 12.5778 4.12163C13.2791 4.94938 13.7387 5.94667 13.9167 7.00451C14.0083 7.54918 14.4476 8 14.9999 8Z" />
</clipPath>
</defs>
</svg>
);
}
export default LoaderIcon;
+14
View File
@@ -0,0 +1,14 @@
function LocationIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M6.49 4.548a8.364 8.364 0 0 1 12.02 0c3.32 3.397 3.32 8.904 0 12.301L12.5 23l-6.01-6.15c-3.32-3.398-3.32-8.905 0-12.302m6.01 8.636c1.341 0 2.429-1.113 2.429-2.485 0-1.373-1.088-2.486-2.429-2.486s-2.429 1.113-2.429 2.486c0 1.372 1.088 2.485 2.429 2.485"
fill="currentColor"
/>
</svg>
);
}
export default LocationIcon;
+221
View File
@@ -0,0 +1,221 @@
function LogoHorIcon() {
return (
<svg viewBox="0 0 192 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clipPath="url(#a)">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M24.214 48c13.38 0 24.215-10.738 24.215-24 0-1.618-.166-3.21-.47-4.745H33.332v9.518h4.718c-1.992 5.65-7.416 9.71-13.795 9.71-8.067 0-14.612-6.488-14.612-14.483S16.19 9.518 24.256 9.518V0h-.042C10.848 0 0 10.752 0 24c0 13.262 10.848 24 24.214 24"
fill="#798FFF"
/>
<path
d="M22.996.027C12.591 1.618 4.635 10.52 4.635 21.257c0 11.863 9.727 21.49 21.724 21.49s21.723-9.613 21.723-21.49c0-.686-.027-1.358-.097-2.03H33.318v9.504h4.719c-1.993 5.65-7.417 9.696-13.81 9.696-8.08 0-14.625-6.473-14.625-14.468 0-7.557 5.853-13.756 13.325-14.4.429-.041.858-.055 1.3-.055V0H24.2c-.401 0-.802.014-1.204.027"
fill="#D375FF"
/>
<path
opacity={0.3}
d="M21.406 9.806a16 16 0 0 1 2.823-.26V0H24.2c-1.95 0-3.846.22-5.659.645z"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="M8.635 5.43 7.126 26.977l2.159-2.016c-.014-.247-.014-.494-.014-.755 0-7.981 6.517-14.468 14.598-14.564l-9.686-7.543a24 24 0 0 0-5.548 3.333"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="m0 24.274 11.028 5.856a14.2 14.2 0 0 1-1.356-6.075c0-2.167.484-4.238 1.37-6.076L7.666 6.651C2.947 11.012 0 17.198 0 24.055z"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="m0 23.315 14.64 21.6 15.98.287-6.24-6.76h-.193c-8.053 0-14.584-6.433-14.584-14.36 0-.329.014-.644.027-.96H0z"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="m10.627 43.79 9.312-6.02c-6.032-1.838-10.391-7.242-10.391-13.633 0-.823.07-1.632.208-2.413l-6.2 15.099a24.3 24.3 0 0 0 7.071 6.967"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="M32.048 46.738A25.6 25.6 0 0 1 24.133 48c-5.12 0-9.866-1.509-13.81-4.087l9.327-6.061c1.425.438 2.933.672 4.51.672h.18z"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="M29.556 47.41c-1.744.384-3.556.59-5.424.59-.803 0-1.605-.041-2.394-.11L19.58 37.837c.29.096.58.179.885.247z"
fill="#000"
fillOpacity={0.4}
/>
<path
opacity={0.3}
d="m33.47 23.122 14.598-3.4-.083-.453H33.47z"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="m36.517 28.731 11.567-9.449v-.013L33.846 28.73z"
fill="#000"
fillOpacity={0.4}
/>
<path
opacity={0.3}
d="m43.295 19.269-10.53 26.976a24.23 24.23 0 0 0 10.447-7.612l1.66-19.378h-1.577z"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="M47.958 19.269 32.765 46.245c9.146-3.415 15.663-12.11 15.663-22.314 0-1.59-.166-3.154-.47-4.662"
fill="#000"
fillOpacity={0.4}
/>
<path
d="M38.467 0h9.603v9.463h-9.603zm9.601 9.463h-9.603l-4.995 4.91h9.243z"
fill="#798FFF"
/>
<path d="M38.465 9.463V0L33.47 5.253v9.106z" fill="#798FFF" />
<path
opacity={0.3}
d="M48.068 8.146v1.317l-5.286 4.896h-1.12V8.05zM33.47 14.359V5.116l6.711-.563 2.2.576z"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="M37.746 1.056 33.47 5.389v8.983h5.7z"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="m33.72 4.896-.25.275v9.202l5.369-5.074 2.504-.096 5.66.932-.54-.795-6.78-7.228z"
fill="#D375FF"
/>
<path
opacity={0.3}
d="M38.812 0h-.346L37.04 1.495l1.688.96zm7.487 11.273-3.334 3.086h-.582l.512-6.171 2.588-.48z"
fill="#000"
fillOpacity={0.6}
/>
<path d="M38.451 9.463h9.617V0H38.45z" fill="url(#b)" />
<path
d="M122.76 9.463h-7.223v4.882h6.642v3.62h-6.642v7.708h-4.621V5.815h11.859v3.648z"
fill="url(#c)"
/>
<path
d="M76.24 24.343a15 15 0 0 1-7.459 1.659 11.3 11.3 0 0 1-4.178-.59 10.5 10.5 0 0 1-3.584-2.07 10 10 0 0 1-2.255-3.374 9.3 9.3 0 0 1-.637-3.923 9.8 9.8 0 0 1 .72-4.114 10.5 10.5 0 0 1 2.393-3.524 11 11 0 0 1 3.806-2.277 11.8 11.8 0 0 1 4.483-.672c1.965-.041 3.916.26 5.77.878v4.183a11.94 11.94 0 0 0-5.77-1.33 6.4 6.4 0 0 0-2.546.424 6.1 6.1 0 0 0-2.117 1.372c-1.26 1.33-1.91 3.058-1.813 4.827-.11 1.715.457 3.388 1.619 4.732a5.7 5.7 0 0 0 1.965 1.275c.747.288 1.55.425 2.366.398.9.027 1.813-.124 2.643-.453v-3.84H67.55v-3.58h8.648z"
fill="url(#d)"
/>
<path
d="m104.275 17.829-2.2-6.652a9 9 0 0 1-.346-1.783h-.11a7.4 7.4 0 0 1-.346 1.728l-2.242 6.734zm7.542 7.844h-5.009l-1.439-4.416h-7.293l-1.438 4.416h-5.023l7.472-19.858h5.479z"
fill="url(#e)"
/>
<path
d="M82.094 9.161v5.527h1.992c.443.014.885-.041 1.287-.192.415-.137.788-.37 1.107-.645.29-.274.525-.603.691-.96.153-.356.236-.74.222-1.124 0-1.742-1.066-2.66-3.21-2.66zm12.591 16.512h-5.3l-3.196-5.101c-.249-.384-.484-.727-.692-1.043a4.5 4.5 0 0 0-.664-.782 2.9 2.9 0 0 0-.706-.507 1.9 1.9 0 0 0-.774-.164h-1.26v7.597h-4.607V5.815h7.306c4.995 0 7.471 1.81 7.471 5.403a5.1 5.1 0 0 1-.332 1.92 5.3 5.3 0 0 1-.927 1.591c-.401.466-.9.878-1.439 1.207a7 7 0 0 1-1.895.796c.318.096.608.246.885.438.305.22.581.467.83.727.277.288.526.576.761.892.25.315.457.644.665.946z"
fill="url(#f)"
/>
<path
d="M135.6 9.463h-7.223v4.882h6.642v3.62h-6.642v7.708h-4.635V5.815H135.6z"
fill="url(#g)"
/>
<path
d="M62.942 40.784q-1.494 0-2.59-.662-1.086-.662-1.691-1.862t-.605-2.816q0-1.672.596-2.892.594-1.218 1.672-1.88 1.087-.662 2.561-.662 1.512 0 2.58.7 1.067.69 1.616 1.984.548 1.295.5 3.09h-1.417v-.49q-.038-1.986-.86-2.997-.812-1.01-2.381-1.01-1.644 0-2.523 1.067-.87 1.068-.87 3.043 0 1.928.87 2.996.879 1.058 2.485 1.058 1.096 0 1.909-.5.822-.512 1.295-1.465l1.294.5q-.604 1.334-1.786 2.07-1.17.727-2.655.727m-3.903-5v-1.162h7.796v1.163zm13.881 4.99q-1.796 0-2.958-.775-1.152-.775-1.417-2.155l1.417-.236q.228.87 1.03 1.39.813.51 2.004.51 1.162 0 1.833-.482.671-.492.671-1.333 0-.472-.217-.765-.208-.302-.86-.558-.653-.255-1.947-.604-1.389-.379-2.173-.756-.785-.378-1.115-.87-.331-.5-.331-1.219 0-.87.491-1.521.492-.661 1.361-1.02.87-.37 2.022-.37 1.154 0 2.06.378.917.37 1.475 1.04.557.67.661 1.56l-1.417.254a2.04 2.04 0 0 0-.898-1.417q-.747-.53-1.9-.548-1.086-.029-1.767.416-.68.435-.68 1.162 0 .406.245.7.246.282.889.538.651.255 1.852.557 1.409.36 2.211.757.804.396 1.144.935.34.538.34 1.333 0 1.444-1.077 2.277-1.068.822-2.949.822m11.111-.274q-.86.18-1.7.142a3.8 3.8 0 0 1-1.494-.36 2.15 2.15 0 0 1-.992-1.001 2.95 2.95 0 0 1-.302-1.144q-.02-.585-.02-1.332V27.46h1.38v9.29q0 .642.01 1.077.02.424.198.756.34.633 1.078.756.746.122 1.842-.057zm-6.69-9.015v-1.191h6.69v1.19zm11.054 9.298q-1.152 0-1.937-.415-.775-.416-1.162-1.106a3 3 0 0 1-.388-1.503q0-.83.33-1.417.341-.595.918-.973.585-.379 1.35-.577a20 20 0 0 1 1.711-.33q.945-.151 1.843-.256a59 59 0 0 0 1.588-.217l-.492.302q.03-1.512-.586-2.24-.614-.727-2.135-.727-1.05 0-1.777.473-.719.471-1.011 1.493l-1.351-.397q.35-1.371 1.408-2.127t2.75-.756q1.398 0 2.372.53.983.519 1.389 1.512.19.444.245.992.057.548.057 1.115V40.5H92.28v-2.56l.36.15q-.52 1.314-1.617 2.004-1.095.69-2.627.69m.16-1.2q.975 0 1.702-.35a3.1 3.1 0 0 0 1.172-.954q.444-.615.576-1.38a5 5 0 0 0 .123-1.077q.01-.596.01-.888l.529.274q-.71.094-1.54.189-.823.095-1.626.217-.794.123-1.437.293-.435.123-.84.35-.407.217-.672.586-.255.368-.255.916 0 .445.218.86.226.417.718.69.501.274 1.323.274m12.412.917q-.86.18-1.701.142a3.8 3.8 0 0 1-1.493-.36 2.15 2.15 0 0 1-.992-1.001 2.9 2.9 0 0 1-.303-1.144q-.018-.585-.019-1.332V27.46h1.38v9.29q0 .642.01 1.077.018.424.198.756.34.633 1.077.756.747.122 1.843-.057zm-6.69-9.015v-1.191h6.69v1.19zm12.083 9.298q-1.493 0-2.589-.661-1.087-.662-1.692-1.862t-.605-2.816q0-1.672.596-2.892.595-1.218 1.672-1.88 1.088-.662 2.561-.662 1.512 0 2.58.7 1.068.69 1.616 1.984.549 1.295.501 3.09h-1.417v-.49q-.038-1.986-.86-2.997-.813-1.01-2.382-1.01-1.644 0-2.523 1.067-.87 1.068-.869 3.043 0 1.928.869 2.996.879 1.058 2.485 1.058 1.097 0 1.909-.5.822-.512 1.295-1.465l1.295.5q-.606 1.334-1.786 2.07-1.173.727-2.656.727m-3.903-4.998v-1.163h7.797v1.163z"
fill="url(#h)"
/>
</g>
<defs>
<linearGradient
id="b"
x1={43.264}
y1={0}
x2={43.264}
y2={9.46}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#D375FF" />
<stop offset={1} stopColor="#798FFF" />
</linearGradient>
<linearGradient
id="c"
x1={116.828}
y1={5.445}
x2={116.828}
y2={26.017}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#D375FF" />
<stop offset={1} stopColor="#798FFF" />
</linearGradient>
<linearGradient
id="d"
x1={67.176}
y1={5.445}
x2={67.176}
y2={26.016}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#D375FF" />
<stop offset={1} stopColor="#798FFF" />
</linearGradient>
<linearGradient
id="e"
x1={101.711}
y1={5.445}
x2={101.711}
y2={26.017}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#D375FF" />
<stop offset={1} stopColor="#798FFF" />
</linearGradient>
<linearGradient
id="f"
x1={86.08}
y1={5.445}
x2={86.08}
y2={26.017}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#D375FF" />
<stop offset={1} stopColor="#798FFF" />
</linearGradient>
<linearGradient
id="g"
x1={129.675}
y1={5.445}
x2={129.675}
y2={26.017}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#D375FF" />
<stop offset={1} stopColor="#798FFF" />
</linearGradient>
<linearGradient
id="h"
x1={88.71}
y1={20.1}
x2={88.71}
y2={46.5}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#D375FF" />
<stop offset={1} stopColor="#798FFF" />
</linearGradient>
<clipPath id="a">
<path fill="#fff" d="M0 0h192v48H0z" />
</clipPath>
</defs>
</svg>
);
}
export default LogoHorIcon;
+214 -15
View File
@@ -1,20 +1,219 @@
export function LogoIcon() {
return (
<svg
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M17.8603 2H21.8523V5.98661L19.6278 8.05375H15.7837V4.21479L17.8603 2Z"
fill="currentColor"
/>
<path
d="M22.0001 12.0133C22.0001 11.3659 21.9384 10.733 21.8206 10.1199C21.8183 10.0933 21.8159 10.0667 21.8134 10.0402L15.7635 10.0401V13.9999L15.7642 13.9999L17.7129 13.9999C16.8908 16.3524 14.6495 18.0402 12.0135 18.0402C11.9874 18.0402 11.9614 18.0401 11.9355 18.0397C8.63872 17.9977 5.97921 15.3157 5.97921 12.0133C5.97921 8.86571 8.39537 6.28166 11.4765 6.01002C11.6349 5.99605 11.7951 5.98819 11.9568 5.98668C11.9757 5.98651 11.9946 5.98642 12.0135 5.98642L12.0142 5.98642V2.02665H12C6.47717 2.02665 2 6.49784 2 12.0133C2 17.5288 6.47717 22 12 22C17.5229 22 22.0001 17.5288 22.0001 12.0133Z"
fill="currentColor"
/>
<svg viewBox="0 0 192 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clipPath="url(#a)">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M24.214 48c13.38 0 24.215-10.738 24.215-24 0-1.618-.166-3.21-.47-4.745H33.332v9.518h4.718c-1.992 5.65-7.416 9.71-13.795 9.71-8.067 0-14.612-6.488-14.612-14.483S16.19 9.518 24.256 9.518V0h-.042C10.848 0 0 10.752 0 24c0 13.262 10.848 24 24.214 24"
fill="#798FFF"
/>
<path
d="M22.996.027C12.591 1.618 4.635 10.52 4.635 21.257c0 11.863 9.727 21.49 21.724 21.49s21.723-9.613 21.723-21.49c0-.686-.027-1.358-.097-2.03H33.318v9.504h4.719c-1.993 5.65-7.417 9.696-13.81 9.696-8.08 0-14.625-6.473-14.625-14.468 0-7.557 5.853-13.756 13.325-14.4.429-.041.858-.055 1.3-.055V0H24.2c-.401 0-.802.014-1.204.027"
fill="#D375FF"
/>
<path
opacity={0.3}
d="M21.406 9.806a16 16 0 0 1 2.823-.26V0H24.2c-1.95 0-3.846.22-5.659.645z"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="M8.635 5.43 7.126 26.977l2.159-2.016c-.014-.247-.014-.494-.014-.755 0-7.981 6.517-14.468 14.598-14.564l-9.686-7.543a24 24 0 0 0-5.548 3.333"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="m0 24.274 11.028 5.856a14.2 14.2 0 0 1-1.356-6.075c0-2.167.484-4.238 1.37-6.076L7.666 6.651C2.947 11.012 0 17.198 0 24.055z"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="m0 23.315 14.64 21.6 15.98.287-6.24-6.76h-.193c-8.053 0-14.584-6.433-14.584-14.36 0-.329.014-.644.027-.96H0z"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="m10.627 43.79 9.312-6.02c-6.032-1.838-10.391-7.242-10.391-13.633 0-.823.07-1.632.208-2.413l-6.2 15.099a24.3 24.3 0 0 0 7.071 6.967"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="M32.048 46.738A25.6 25.6 0 0 1 24.133 48c-5.12 0-9.866-1.509-13.81-4.087l9.327-6.061c1.425.438 2.933.672 4.51.672h.18z"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="M29.556 47.41c-1.744.384-3.556.59-5.424.59-.803 0-1.605-.041-2.394-.11L19.58 37.837c.29.096.58.179.885.247z"
fill="#000"
fillOpacity={0.4}
/>
<path
opacity={0.3}
d="m33.47 23.122 14.598-3.4-.083-.453H33.47z"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="m36.517 28.731 11.567-9.449v-.013L33.846 28.73z"
fill="#000"
fillOpacity={0.4}
/>
<path
opacity={0.3}
d="m43.295 19.269-10.53 26.976a24.23 24.23 0 0 0 10.447-7.612l1.66-19.378h-1.577z"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="M47.958 19.269 32.765 46.245c9.146-3.415 15.663-12.11 15.663-22.314 0-1.59-.166-3.154-.47-4.662"
fill="#000"
fillOpacity={0.4}
/>
<path
d="M38.467 0h9.603v9.463h-9.603zm9.601 9.463h-9.603l-4.995 4.91h9.243z"
fill="#798FFF"
/>
<path d="M38.465 9.463V0L33.47 5.253v9.106z" fill="#798FFF" />
<path
opacity={0.3}
d="M48.068 8.146v1.317l-5.286 4.896h-1.12V8.05zM33.47 14.359V5.116l6.711-.563 2.2.576z"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="M37.746 1.056 33.47 5.389v8.983h5.7z"
fill="#000"
fillOpacity={0.6}
/>
<path
opacity={0.3}
d="m33.72 4.896-.25.275v9.202l5.369-5.074 2.504-.096 5.66.932-.54-.795-6.78-7.228z"
fill="#D375FF"
/>
<path
opacity={0.3}
d="M38.812 0h-.346L37.04 1.495l1.688.96zm7.487 11.273-3.334 3.086h-.582l.512-6.171 2.588-.48z"
fill="#000"
fillOpacity={0.6}
/>
<path d="M38.451 9.463h9.617V0H38.45z" fill="url(#b)" />
<path
d="M122.76 9.463h-7.223v4.882h6.642v3.62h-6.642v7.708h-4.621V5.815h11.859v3.648z"
fill="url(#c)"
/>
<path
d="M76.24 24.343a15 15 0 0 1-7.459 1.659 11.3 11.3 0 0 1-4.178-.59 10.5 10.5 0 0 1-3.584-2.07 10 10 0 0 1-2.255-3.374 9.3 9.3 0 0 1-.637-3.923 9.8 9.8 0 0 1 .72-4.114 10.5 10.5 0 0 1 2.393-3.524 11 11 0 0 1 3.806-2.277 11.8 11.8 0 0 1 4.483-.672c1.965-.041 3.916.26 5.77.878v4.183a11.94 11.94 0 0 0-5.77-1.33 6.4 6.4 0 0 0-2.546.424 6.1 6.1 0 0 0-2.117 1.372c-1.26 1.33-1.91 3.058-1.813 4.827-.11 1.715.457 3.388 1.619 4.732a5.7 5.7 0 0 0 1.965 1.275c.747.288 1.55.425 2.366.398.9.027 1.813-.124 2.643-.453v-3.84H67.55v-3.58h8.648z"
fill="url(#d)"
/>
<path
d="m104.275 17.829-2.2-6.652a9 9 0 0 1-.346-1.783h-.11a7.4 7.4 0 0 1-.346 1.728l-2.242 6.734zm7.542 7.844h-5.009l-1.439-4.416h-7.293l-1.438 4.416h-5.023l7.472-19.858h5.479z"
fill="url(#e)"
/>
<path
d="M82.094 9.161v5.527h1.992c.443.014.885-.041 1.287-.192.415-.137.788-.37 1.107-.645.29-.274.525-.603.691-.96.153-.356.236-.74.222-1.124 0-1.742-1.066-2.66-3.21-2.66zm12.591 16.512h-5.3l-3.196-5.101c-.249-.384-.484-.727-.692-1.043a4.5 4.5 0 0 0-.664-.782 2.9 2.9 0 0 0-.706-.507 1.9 1.9 0 0 0-.774-.164h-1.26v7.597h-4.607V5.815h7.306c4.995 0 7.471 1.81 7.471 5.403a5.1 5.1 0 0 1-.332 1.92 5.3 5.3 0 0 1-.927 1.591c-.401.466-.9.878-1.439 1.207a7 7 0 0 1-1.895.796c.318.096.608.246.885.438.305.22.581.467.83.727.277.288.526.576.761.892.25.315.457.644.665.946z"
fill="url(#f)"
/>
<path
d="M135.6 9.463h-7.223v4.882h6.642v3.62h-6.642v7.708h-4.635V5.815H135.6z"
fill="url(#g)"
/>
<path
d="M62.942 40.784q-1.494 0-2.59-.662-1.086-.662-1.691-1.862t-.605-2.816q0-1.672.596-2.892.594-1.218 1.672-1.88 1.087-.662 2.561-.662 1.512 0 2.58.7 1.067.69 1.616 1.984.548 1.295.5 3.09h-1.417v-.49q-.038-1.986-.86-2.997-.812-1.01-2.381-1.01-1.644 0-2.523 1.067-.87 1.068-.87 3.043 0 1.928.87 2.996.879 1.058 2.485 1.058 1.096 0 1.909-.5.822-.512 1.295-1.465l1.294.5q-.604 1.334-1.786 2.07-1.17.727-2.655.727m-3.903-5v-1.162h7.796v1.163zm13.881 4.99q-1.796 0-2.958-.775-1.152-.775-1.417-2.155l1.417-.236q.228.87 1.03 1.39.813.51 2.004.51 1.162 0 1.833-.482.671-.492.671-1.333 0-.472-.217-.765-.208-.302-.86-.558-.653-.255-1.947-.604-1.389-.379-2.173-.756-.785-.378-1.115-.87-.331-.5-.331-1.219 0-.87.491-1.521.492-.661 1.361-1.02.87-.37 2.022-.37 1.154 0 2.06.378.917.37 1.475 1.04.557.67.661 1.56l-1.417.254a2.04 2.04 0 0 0-.898-1.417q-.747-.53-1.9-.548-1.086-.029-1.767.416-.68.435-.68 1.162 0 .406.245.7.246.282.889.538.651.255 1.852.557 1.409.36 2.211.757.804.396 1.144.935.34.538.34 1.333 0 1.444-1.077 2.277-1.068.822-2.949.822m11.111-.274q-.86.18-1.7.142a3.8 3.8 0 0 1-1.494-.36 2.15 2.15 0 0 1-.992-1.001 2.95 2.95 0 0 1-.302-1.144q-.02-.585-.02-1.332V27.46h1.38v9.29q0 .642.01 1.077.02.424.198.756.34.633 1.078.756.746.122 1.842-.057zm-6.69-9.015v-1.191h6.69v1.19zm11.054 9.298q-1.152 0-1.937-.415-.775-.416-1.162-1.106a3 3 0 0 1-.388-1.503q0-.83.33-1.417.341-.595.918-.973.585-.379 1.35-.577a20 20 0 0 1 1.711-.33q.945-.151 1.843-.256a59 59 0 0 0 1.588-.217l-.492.302q.03-1.512-.586-2.24-.614-.727-2.135-.727-1.05 0-1.777.473-.719.471-1.011 1.493l-1.351-.397q.35-1.371 1.408-2.127t2.75-.756q1.398 0 2.372.53.983.519 1.389 1.512.19.444.245.992.057.548.057 1.115V40.5H92.28v-2.56l.36.15q-.52 1.314-1.617 2.004-1.095.69-2.627.69m.16-1.2q.975 0 1.702-.35a3.1 3.1 0 0 0 1.172-.954q.444-.615.576-1.38a5 5 0 0 0 .123-1.077q.01-.596.01-.888l.529.274q-.71.094-1.54.189-.823.095-1.626.217-.794.123-1.437.293-.435.123-.84.35-.407.217-.672.586-.255.368-.255.916 0 .445.218.86.226.417.718.69.501.274 1.323.274m12.412.917q-.86.18-1.701.142a3.8 3.8 0 0 1-1.493-.36 2.15 2.15 0 0 1-.992-1.001 2.9 2.9 0 0 1-.303-1.144q-.018-.585-.019-1.332V27.46h1.38v9.29q0 .642.01 1.077.018.424.198.756.34.633 1.077.756.747.122 1.843-.057zm-6.69-9.015v-1.191h6.69v1.19zm12.083 9.298q-1.493 0-2.589-.661-1.087-.662-1.692-1.862t-.605-2.816q0-1.672.596-2.892.595-1.218 1.672-1.88 1.088-.662 2.561-.662 1.512 0 2.58.7 1.068.69 1.616 1.984.549 1.295.501 3.09h-1.417v-.49q-.038-1.986-.86-2.997-.813-1.01-2.382-1.01-1.644 0-2.523 1.067-.87 1.068-.869 3.043 0 1.928.869 2.996.879 1.058 2.485 1.058 1.097 0 1.909-.5.822-.512 1.295-1.465l1.295.5q-.606 1.334-1.786 2.07-1.173.727-2.656.727m-3.903-4.998v-1.163h7.797v1.163z"
fill="url(#h)"
/>
</g>
<defs>
<linearGradient
id="b"
x1={43.264}
y1={0}
x2={43.264}
y2={9.46}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#D375FF" />
<stop offset={1} stopColor="#798FFF" />
</linearGradient>
<linearGradient
id="c"
x1={116.828}
y1={5.445}
x2={116.828}
y2={26.017}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#D375FF" />
<stop offset={1} stopColor="#798FFF" />
</linearGradient>
<linearGradient
id="d"
x1={67.176}
y1={5.445}
x2={67.176}
y2={26.016}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#D375FF" />
<stop offset={1} stopColor="#798FFF" />
</linearGradient>
<linearGradient
id="e"
x1={101.711}
y1={5.445}
x2={101.711}
y2={26.017}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#D375FF" />
<stop offset={1} stopColor="#798FFF" />
</linearGradient>
<linearGradient
id="f"
x1={86.08}
y1={5.445}
x2={86.08}
y2={26.017}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#D375FF" />
<stop offset={1} stopColor="#798FFF" />
</linearGradient>
<linearGradient
id="g"
x1={129.675}
y1={5.445}
x2={129.675}
y2={26.017}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#D375FF" />
<stop offset={1} stopColor="#798FFF" />
</linearGradient>
<linearGradient
id="h"
x1={88.71}
y1={20.1}
x2={88.71}
y2={46.5}
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#D375FF" />
<stop offset={1} stopColor="#798FFF" />
</linearGradient>
<clipPath id="a">
<path fill="#fff" d="M0 0h192v48H0z" />
</clipPath>
</defs>
</svg>
);
}
+15
View File
@@ -0,0 +1,15 @@
function MailIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M2 20h18l2-2V4H4L2 6zM6.303 6 12 9.798 17.697 6zM4 6.869V18h16V6.869l-8 5.333z"
fill="currentColor"
/>
<path d="M19 18h1v-1z" fill="currentColor" />
</svg>
);
}
export default MailIcon;
+12
View File
@@ -0,0 +1,12 @@
function MetroIcon() {
return (
<svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M56.147 44.265 43.066 11 32 30.446 20.98 11 7.852 44.265H4v5.041h19.802v-5.041h-2.957l2.867-8.282L32 49.667l8.288-13.684 2.867 8.282h-2.957v5.041H60v-5.041z"
fill="currentColor"
/>
</svg>
);
}
export default MetroIcon;
+14
View File
@@ -0,0 +1,14 @@
function MinusIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M3 11h18v2H3z"
fill="currentColor"
/>
</svg>
);
}
export default MinusIcon;
+12
View File
@@ -0,0 +1,12 @@
function MuteIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M5.74 3.993a1 1 0 1 0-1.48 1.345l2.116 2.328h-2.71A1.667 1.667 0 0 0 2 9.333v5.333a1.667 1.667 0 0 0 1.667 1.667h3.656l5.73 4.456A1 1 0 0 0 14.667 20v-3.214l2.926 3.22a1 1 0 0 0 1.48-1.345zM4 9.666h2.667v4.667H4zm8.667 8.289-4-3.111v-4.658l4 4.397zM10.083 6.788a1 1 0 0 1 .176-1.404l2.793-2.173A1 1 0 0 1 14.667 4v5.245a1 1 0 0 1-2 0v-3.2l-1.18.917a1 1 0 0 1-1.404-.175zM16.25 10.9a1 1 0 0 1 1.5-1.32 3.67 3.67 0 0 1 .462 4.184 1 1 0 0 1-1.75-.963 1.67 1.67 0 0 0-.212-1.903zM22 12a7 7 0 0 1-1.593 4.446 1.002 1.002 0 0 1-1.663-.16 1 1 0 0 1 .12-1.111 5 5 0 0 0-.137-6.509 1.001 1.001 0 1 1 1.49-1.333A7 7 0 0 1 22 11.999"
fill="currentColor"
/>
</svg>
);
}
export default MuteIcon;
+14
View File
@@ -0,0 +1,14 @@
function NatureIcon() {
return (
<svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M42.85 16.596c0-14.177-20.553-15.834-20.553 0-14.426 2.36-9.914 21.492 2.74 21.493h5.535v15.726h-8.275a2 2 0 0 0 0 4h20.552a2 2 0 1 0 0-4h-8.277V38.089h5.536c11.491 0 15.311-18.682 2.741-21.493m-8.278 21.493v-7.277l6.485-3.496a2 2 0 1 0-1.899-3.52l-4.586 2.472v-4.935a2 2 0 0 0-4 0V38.09z"
fill="currentColor"
/>
</svg>
);
}
export default NatureIcon;
+12
View File
@@ -0,0 +1,12 @@
function PanDotsIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M6 5a2 2 0 1 1 4 0 2 2 0 0 1-4 0m7 0a2 2 0 1 1 4 0 2 2 0 0 1-4 0m-7 7a2 2 0 1 1 4 0 2 2 0 0 1-4 0m7 0a2 2 0 1 1 4 0 2 2 0 0 1-4 0m-7 7a2 2 0 1 1 4 0 2 2 0 0 1-4 0m7 0a2 2 0 1 1 4 0 2 2 0 0 1-4 0"
fill="currentColor"
/>
</svg>
);
}
export default PanDotsIcon;
+12
View File
@@ -0,0 +1,12 @@
function PauseIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M10 3H7L5 5v16h3l2-2zm9 0h-3l-2 2v16h3l2-2z"
fill="currentColor"
/>
</svg>
);
}
export default PauseIcon;
+12
View File
@@ -0,0 +1,12 @@
function PhoneIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M18.97 21.092 3.414 5.536v2.828l12.728 12.728zM9.07 9.778 11.9 6.95 8.363 3.414H5.535L4.121 4.828zm5.656 5.657 4.95 4.95 1.414-1.415v-2.828l-3.535-3.536z"
fill="currentColor"
/>
</svg>
);
}
export default PhoneIcon;
+9
View File
@@ -0,0 +1,9 @@
function PlayIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M21 12 6 21V3z" fill="currentColor" />
</svg>
);
}
export default PlayIcon;
+15
View File
@@ -0,0 +1,15 @@
function PlusIcon() {
return (
<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="currentColor"
stroke-width="2"
stroke-linecap="square"
stroke-linejoin="round"
/>
</svg>
);
}
export default PlusIcon;
+21
View File
@@ -0,0 +1,21 @@
function QuestionIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M12 4C10.9494 4 9.90914 4.20693 8.93853 4.60896C7.96793 5.011 7.08602 5.60028 6.34315 6.34315C5.60028 7.08601 5.011 7.96793 4.60896 8.93853C4.20693 9.90914 4 10.9494 4 12C4 13.0506 4.20693 14.0909 4.60896 15.0615C5.011 16.0321 5.60028 16.914 6.34315 17.6569C7.08601 18.3997 7.96793 18.989 8.93853 19.391C9.90914 19.7931 10.9494 20 12 20C13.0506 20 14.0909 19.7931 15.0615 19.391C16.0321 18.989 16.914 18.3997 17.6569 17.6569C18.3997 16.914 18.989 16.0321 19.391 15.0615C19.7931 14.0909 20 13.0506 20 12C20 10.9494 19.7931 9.90914 19.391 8.93853C18.989 7.96793 18.3997 7.08602 17.6569 6.34315C16.914 5.60028 16.0321 5.011 15.0615 4.60896C14.0909 4.20693 13.0506 4 12 4ZM8.17317 2.7612C9.38642 2.25866 10.6868 2 12 2C13.3132 2 14.6136 2.25866 15.8268 2.76121C17.0401 3.26375 18.1425 4.00035 19.0711 4.92893C19.9997 5.85752 20.7362 6.95991 21.2388 8.17317C21.7413 9.38642 22 10.6868 22 12C22 13.3132 21.7413 14.6136 21.2388 15.8268C20.7362 17.0401 19.9997 18.1425 19.0711 19.0711C18.1425 19.9997 17.0401 20.7362 15.8268 21.2388C14.6136 21.7413 13.3132 22 12 22C10.6868 22 9.38642 21.7413 8.17317 21.2388C6.95991 20.7362 5.85752 19.9997 4.92893 19.0711C4.00035 18.1425 3.26375 17.0401 2.7612 15.8268C2.25866 14.6136 2 13.3132 2 12C2 10.6868 2.25866 9.38642 2.76121 8.17316C3.26375 6.95991 4.00035 5.85752 4.92893 4.92893C5.85752 4.00035 6.95991 3.26375 8.17317 2.7612Z"
fill="currentColor"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M12 8C10.9294 8 10 8.91059 10 10.1111V11.1111H8V10.1111C8 7.8752 9.75689 6 12 6C14.2431 6 16 7.8752 16 10.1111C16 11.3591 15.2208 12.3058 14.5607 12.9629C14.272 13.2503 13.9593 13.5261 13.682 13.7706C13.6305 13.816 13.5802 13.8603 13.5315 13.9035C13.2029 14.1946 12.9463 14.4318 12.7604 14.6495L12.1109 15.4099L10.5901 14.1109L11.2396 13.3505C11.5273 13.0137 11.8825 12.6924 12.2052 12.4065C12.2609 12.3572 12.3159 12.3086 12.3702 12.2607C12.648 12.0156 12.9077 11.7864 13.1497 11.5455C13.7528 10.9452 14 10.5019 14 10.1111C14 8.91059 13.0706 8 12 8Z"
fill="currentColor"
/>
<rect x="11" y="16" width="2" height="2" fill="currentColor" />
</svg>
);
}
export default QuestionIcon;
+14
View File
@@ -0,0 +1,14 @@
function RestartIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
fillRule="evenodd"
clipRule="evenodd"
d="m14.505 3.509 1.96-1.172-.824-1.379-4.67 2.792 2.825 4.37 1.349-.871-1.475-2.281c3.822.748 6.724 4.17 6.724 8.301 0 4.682-3.728 8.454-8.298 8.454s-8.298-3.772-8.298-8.454a8.5 8.5 0 0 1 2.714-6.253L5.42 5.84a10.1 10.1 0 0 0-3.228 7.43c0 5.543 4.422 10.06 9.904 10.06S22 18.812 22 13.27c0-4.702-3.183-8.667-7.495-9.76"
fill="currentColor"
/>
</svg>
);
}
export default RestartIcon;

Some files were not shown because too many files have changed in this diff Show More