updated clients, fixed slider, etc
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1021 B |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -31,7 +31,7 @@ export function Header() {
|
||||
|
||||
return (
|
||||
<header className="w-full">
|
||||
<nav className="flex items-stretch justify-between border-b border-[#3D425C] lg:pl-10 pl-4 lg:min-h-[72px] min-h-16">
|
||||
<nav className="flex justify-between border-b border-[#3D425C] lg:pl-10 pl-4 lg:max-h-[72px] min-h-16">
|
||||
<Link to={'/'} className="flex items-center outline-none">
|
||||
<LogoIcon className="lg:hidden" />
|
||||
{width >= 1024 && <LogoWithTextIcon />}
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
import { clients } from '../../consts/clients';
|
||||
import { IClient } from '../../types/Client';
|
||||
import { IClient } from '../../types/IClient';
|
||||
|
||||
export function Clients() {
|
||||
return (
|
||||
<div
|
||||
itemScope
|
||||
itemType="http://schema.org/сlients"
|
||||
className="space-y-8 select-none"
|
||||
itemType="http://schema.org/Clients"
|
||||
className="select-none grid grid-rows-[repeat(3,124px)] gap-y-[clamp(20px,2vw,32px)] pb-16 border-b border-[#3D425C] lg:-mx-10 sm:-mx-6 -mx-4"
|
||||
>
|
||||
<div className="flex items-center overflow-hidden w-screen lg:-mx-10 -mx-6 mt-10 min-h-[117px]">
|
||||
<div className="flex w-screen overflow-hidden">
|
||||
<MarqueeHalf items={clients.slice(0, clients.length / 3)} />
|
||||
<MarqueeHalf items={clients.slice(0, clients.length / 3)} />
|
||||
<MarqueeHalf items={clients.slice(0, clients.length / 3)} />
|
||||
</div>
|
||||
<div className="flex items-center overflow-hidden w-screen lg:-mx-10 -mx-6 min-h-[117px]">
|
||||
<div className="flex w-screen overflow-hidden">
|
||||
<MarqueeHalf
|
||||
reversed
|
||||
items={clients.slice(clients.length / 3, (2 * clients.length) / 3)}
|
||||
/>
|
||||
<MarqueeHalf
|
||||
reversed
|
||||
items={clients.slice(clients.length / 3, (2 * clients.length) / 3)}
|
||||
@@ -22,7 +27,8 @@ export function Clients() {
|
||||
items={clients.slice(clients.length / 3, (2 * clients.length) / 3)}
|
||||
/>
|
||||
</div>
|
||||
<div className="border-b border-[#3D425C] flex items-center overflow-hidden w-screen lg:-mx-10 -mx-6 min-h-[117px] pb-16">
|
||||
<div className="flex w-screen overflow-hidden">
|
||||
<MarqueeHalf items={clients.slice(2 * (clients.length / 3))} />
|
||||
<MarqueeHalf items={clients.slice(2 * (clients.length / 3))} />
|
||||
<MarqueeHalf items={clients.slice(2 * (clients.length / 3))} />
|
||||
</div>
|
||||
@@ -42,7 +48,7 @@ function MarqueeHalf({
|
||||
className={
|
||||
'flex flex-nowrap ' +
|
||||
(reversed
|
||||
? '[animation:infinite-scroll_45s_linear_infinite_reverse]'
|
||||
? '[animation:infinite-scroll_10s_linear_infinite_reverse]'
|
||||
: 'animate-infinite-scroll')
|
||||
}
|
||||
>
|
||||
@@ -50,9 +56,13 @@ function MarqueeHalf({
|
||||
<div
|
||||
itemProp={client.title}
|
||||
key={client.src}
|
||||
className="border-l border-[#3D425C] w-[312px] h-[124px] flex justify-center items-center relative"
|
||||
className="border-l border-[#3D425C] w-[clamp(200px,19.5vw,312px)] flex justify-center items-center px-5a"
|
||||
>
|
||||
<img src={client.src} alt={client.title} className="!relative" />
|
||||
<img
|
||||
src={client.src}
|
||||
alt={client.title}
|
||||
className="scale-50 pointer-events-none select-none"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -38,7 +38,7 @@ export function Ellipse() {
|
||||
<div
|
||||
ref={ref}
|
||||
style={{ top: mousePos[1], left: mousePos[0] }}
|
||||
className="absolute -z-10 bg-[url('src/assets/Ellipse.png')] bg-cover bg-no-repeat bg-center -translate-y-[75%] -translate-x-[50%] aspect-[348.75/262.77] w-[21.75vw]"
|
||||
className="absolute -z-[9] bg-[url('src/assets/Ellipse.png')] bg-cover bg-no-repeat bg-center -translate-y-[75%] -translate-x-[50%] aspect-[348.75/262.77] w-[21.75vw]"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
import { FormEvent, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import {
|
||||
FormEvent,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import ReactInputMask from 'react-input-mask';
|
||||
import { ArrowRightIcon } from '../icons/ArrowRightIcon';
|
||||
import { CloseIcon } from '../icons/CloseIcon';
|
||||
@@ -75,15 +82,19 @@ export function ModalWithForm() {
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const listener = (e: KeyboardEvent) => {
|
||||
const listener = useCallback(
|
||||
(e: KeyboardEvent) => {
|
||||
if (e.key === 'Escape') {
|
||||
setModal(false);
|
||||
}
|
||||
};
|
||||
},
|
||||
[setModal],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
document.addEventListener('keydown', listener);
|
||||
return () => document.removeEventListener('keydown', listener);
|
||||
}, [setModal]);
|
||||
}, [listener, setModal]);
|
||||
|
||||
return (
|
||||
<div className="fixed flex flex-col gap-4 top-0 right-0 h-full sm:w-[408px] w-full bg-[#14161F] overflow-y-auto sm:p-8 p-6">
|
||||
@@ -188,7 +199,7 @@ export function ModalWithForm() {
|
||||
<Button
|
||||
width="full"
|
||||
disabled={isLoading}
|
||||
className="py-5 px-6 mt-[213px]"
|
||||
className="px-6 py-5 mt-12"
|
||||
icon={
|
||||
isLoading ? (
|
||||
<LoaderIcon className="relative w-6 h-6 animate-spin" />
|
||||
@@ -230,258 +241,3 @@ export function ModalWithForm() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// function SelectPhoneCode({
|
||||
// currentPhoneCode,
|
||||
// onClick,
|
||||
// }: {
|
||||
// currentPhoneCode: PhoneCode;
|
||||
// onClick: (phoneCode: PhoneCode) => void;
|
||||
// }) {
|
||||
// const [open, setOpen] = useState(false);
|
||||
|
||||
// return (
|
||||
// <div className="relative flex flex-col">
|
||||
// <button
|
||||
// className="relative flex items-center gap-x-4"
|
||||
// onClick={e => {
|
||||
// e.preventDefault();
|
||||
// setOpen(prev => !prev);
|
||||
// }}
|
||||
// >
|
||||
// <p className="h4">{currentPhoneCode}</p>
|
||||
// {open ? <ChevronUpIcon /> : <ChevronDownIcon />}
|
||||
// </button>
|
||||
// {open && (
|
||||
// <div className="absolute z-10 bg-[#14161F] top-[100%] w-[calc(100%+4px)] -left-1 border border-t-0 p-1 rounded-b-lg border-[#3D425C]">
|
||||
// {phoneCodes
|
||||
// .filter(phonecode => phonecode !== currentPhoneCode)
|
||||
// .map(phoneCode => (
|
||||
// <p
|
||||
// key={phoneCode}
|
||||
// className="h4 cursor-pointer hover:bg-[#3D425C] py-1"
|
||||
// onClick={() => {
|
||||
// onClick(phoneCode);
|
||||
// setOpen(false);
|
||||
// }}
|
||||
// >
|
||||
// {phoneCode}
|
||||
// </p>
|
||||
// ))}
|
||||
// </div>
|
||||
// )}
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
// import ReactInputMask from 'react-input-mask';
|
||||
// import { SelectPhoneCode } from './SelectPhoneCode';
|
||||
// import { ClassNameWrapper } from '../../hocs/ClassNameWrapper';
|
||||
// import { LoaderIcon } from '../icons/LoaderIcon';
|
||||
// import { Button } from '../../ui/Button';
|
||||
// import { ArrowRightIcon } from '../icons/ArrowRightIcon';
|
||||
// import { FormEvent, useEffect, useMemo, useRef, useState } from 'react';
|
||||
// import { Country } from 'react-phone-number-input';
|
||||
// import { api } from '../../api/contactsFormInstance';
|
||||
// import { getExampleNumber } from 'libphonenumber-js';
|
||||
// import examples from 'libphonenumber-js/mobile/examples';
|
||||
|
||||
// export function ModalWithForm({
|
||||
// inModal = true,
|
||||
// send = () => {},
|
||||
// }: {
|
||||
// inModal?: boolean;
|
||||
// send?: () => void;
|
||||
// }) {
|
||||
// const [name, setName] = useState('');
|
||||
// const [[phoneCode, country], setPhoneCodeAndCountry] = useState<
|
||||
// [string, Country]
|
||||
// >(['+7', 'RU']);
|
||||
// const [phone, setPhone] = useState('');
|
||||
// const [email, setEmail] = useState('');
|
||||
// const [description, setDescription] = useState('');
|
||||
// const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
// const textAreaRef = useRef<HTMLTextAreaElement>(null);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (textAreaRef.current) {
|
||||
// textAreaRef.current.style.height = 'auto';
|
||||
// textAreaRef.current.style.height =
|
||||
// textAreaRef.current.scrollHeight + 'px';
|
||||
// }
|
||||
// }, [textAreaRef, description]);
|
||||
|
||||
// function handleSubmit(e: FormEvent<HTMLFormElement>) {
|
||||
// e.preventDefault();
|
||||
// sendMail();
|
||||
// }
|
||||
|
||||
// async function sendMail() {
|
||||
// setIsLoading(true);
|
||||
|
||||
// try {
|
||||
// await api
|
||||
// .post('mail', {
|
||||
// json: {
|
||||
// fullname: name,
|
||||
// phone: phoneCode + phone,
|
||||
// email,
|
||||
// request: description,
|
||||
// },
|
||||
// })
|
||||
// .json();
|
||||
|
||||
// setIsLoading(false);
|
||||
// send?.();
|
||||
// } catch (error) {
|
||||
// setIsLoading(false);
|
||||
// if (error instanceof Error) {
|
||||
// alert(error.message);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// const placeholder = useMemo(
|
||||
// () =>
|
||||
// getExampleNumber(country, examples)
|
||||
// ?.formatInternational()
|
||||
// .split(' ')
|
||||
// .slice(1)
|
||||
// .join(' '),
|
||||
// [country],
|
||||
// );
|
||||
|
||||
// return (
|
||||
// <form
|
||||
// onSubmit={handleSubmit}
|
||||
// className={
|
||||
// inModal
|
||||
// ? 'space-y-6'
|
||||
// : 'lg:space-y-12 sm:space-y-36 space-y-8 lg:max-w-[66vw] sm:max-w-[calc(369/720*100%)]'
|
||||
// }
|
||||
// >
|
||||
// <div className="space-y-6">
|
||||
// <div
|
||||
// className={
|
||||
// 'grid gap-x-4 items-start ' +
|
||||
// (inModal ? 'gap-y-6' : 'lg:grid-cols-3 max-lg:gap-y-4')
|
||||
// }
|
||||
// >
|
||||
// <div className="w-full">
|
||||
// <label
|
||||
// className="m-text text-[#9299BD] select-none"
|
||||
// htmlFor={'name' + +inModal}
|
||||
// >
|
||||
// Имя
|
||||
// </label>
|
||||
// <input
|
||||
// required
|
||||
// id={'name' + +inModal}
|
||||
// type="text"
|
||||
// value={name}
|
||||
// onChange={e => setName(e.target.value)}
|
||||
// placeholder="Ваше имя"
|
||||
// className="bg-transparent border-b border-[#3D425C] focus:border-white py-4 rounded-none outline-none transition-all w-full placeholder:h4 placeholder:font-medium placeholder:select-none"
|
||||
// />
|
||||
// </div>
|
||||
|
||||
// <div className="w-full">
|
||||
// <label
|
||||
// className="m-text text-[#9299BD] select-none"
|
||||
// htmlFor={'email' + +inModal}
|
||||
// >
|
||||
// Email*
|
||||
// </label>
|
||||
// <input
|
||||
// required
|
||||
// id={'email' + +inModal}
|
||||
// type="text"
|
||||
// value={email}
|
||||
// onChange={e => setEmail(e.target.value)}
|
||||
// placeholder="Ваш email"
|
||||
// className="bg-transparent border-b border-[#3D425C] focus:border-white py-4 rounded-none outline-none transition-all w-full placeholder:h4 placeholder:font-medium placeholder:select-none"
|
||||
// />
|
||||
// </div>
|
||||
|
||||
// <div className="w-full">
|
||||
// <label
|
||||
// className="m-text text-[#9299BD] select-none"
|
||||
// htmlFor={'tel' + +inModal}
|
||||
// >
|
||||
// Телефон
|
||||
// </label>
|
||||
// <div className="flex gap-x-3 py-4 border-[#3D425C] relative">
|
||||
// <SelectPhoneCode
|
||||
// currentPhoneCodeAndCountry={[phoneCode, country]}
|
||||
// onClick={setPhoneCodeAndCountry}
|
||||
// />
|
||||
// <div className="border-l border-[#3D425C]" />
|
||||
// <ReactInputMask
|
||||
// required
|
||||
// type="tel"
|
||||
// id={'tel' + +inModal}
|
||||
// mask={placeholder?.replace(/\d/g, '9') ?? ''}
|
||||
// maskChar={null}
|
||||
// value={phone}
|
||||
// placeholder={placeholder}
|
||||
// onChange={e => setPhone(e.target.value.replace(/ /g, ''))}
|
||||
// className="w-full transition-all bg-transparent rounded-none outline-none h4 placeholder:h4 placeholder:font-medium placeholder:select-none peer"
|
||||
// />
|
||||
// <div className="bottom-0 absolute w-full border-b border-[#3D425C] peer-focus:border-white -mb-px" />
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
|
||||
// <div>
|
||||
// <label
|
||||
// className="m-text text-[#9299BD] select-none"
|
||||
// htmlFor={'description' + +inModal}
|
||||
// >
|
||||
// Задача
|
||||
// </label>
|
||||
// <textarea
|
||||
// ref={textAreaRef}
|
||||
// id={'description' + +inModal}
|
||||
// placeholder="Опишите вашу задачу"
|
||||
// value={description}
|
||||
// rows={1}
|
||||
// onChange={e => setDescription(e.target.value)}
|
||||
// className="bg-transparent border-b py-4 focus:border-white max-h-[300px] h-auto rounded-none border-[#3D425C] resize-none outline-none transition-all w-full placeholder:h4 placeholder:font-medium placeholder:select-none focus:overflow-y-scroll overflow-hidden"
|
||||
// />
|
||||
// </div>
|
||||
// </div>
|
||||
|
||||
// <div className="space-y-4 lg:max-w-[25vw] sm:max-lg:mt-36">
|
||||
// <Button
|
||||
// width="full"
|
||||
// disabled={isLoading}
|
||||
// className="p-2 pl-8"
|
||||
// icon={
|
||||
// isLoading ? (
|
||||
// <ClassNameWrapper
|
||||
// element={<LoaderIcon />}
|
||||
// className="relative w-5 h-5 animate-spin"
|
||||
// />
|
||||
// ) : (
|
||||
// <div className="p-2 bg-white rounded-full">
|
||||
// <ClassNameWrapper
|
||||
// element={<ArrowRightIcon />}
|
||||
// className="w-5 h-5 text-black"
|
||||
// />
|
||||
// </div>
|
||||
// )
|
||||
// }
|
||||
// >
|
||||
// Отправить
|
||||
// </Button>
|
||||
// <p className="m-text text-[#52587A]">
|
||||
// *нажимая кнопку отправить, вы принимаете
|
||||
// <span className="text-gradient">
|
||||
// {' '}
|
||||
// условия использования и политику конфиденциальности
|
||||
// </span>
|
||||
// </p>
|
||||
// </div>
|
||||
// </form>
|
||||
// );
|
||||
// }
|
||||
|
||||
@@ -10,7 +10,7 @@ export const ForTeachingTab = forwardRef<HTMLDivElement>((_, ref) => {
|
||||
itemScope
|
||||
itemType="https://schema.org/TrainingsForEducation"
|
||||
ref={ref}
|
||||
className="lg:ml-[129px] lg:min-h-[calc(100vh-276px)] lg:min-w-[calc(100vw-129px)] sm:min-h-[calc(100vh-176px)] min-h-[calc(100vh)] min-w-[100vw] sm:sticky z-50 lg:top-[276px] sm:top-[176px] top-0 lg:px-10 lg:pt-10 sm:px-6 sm:pt-6 px-4 pt-4 lg:border-l bg-[#14161F] border-t border-[#3D425C]"
|
||||
className="lg:ml-[129px] lg:min-h-[calc(100vh-276px)] lg:min-w-[calc(100vw-129px)] sm:min-h-[calc(100vh-176px)] min-h-[calc(100vh)] min-w-[100vw] sm:sticky -z-10 lg:top-[276px] sm:top-[176px] top-0 lg:px-10 lg:pt-10 sm:px-6 sm:pt-6 px-4 pt-4 lg:border-l bg-[#14161F] border-t border-[#3D425C]"
|
||||
>
|
||||
<div className="flex justify-between ">
|
||||
<h2 className="font-medium h2">
|
||||
|
||||
@@ -44,7 +44,7 @@ export const IndustrialTab = forwardRef<HTMLDivElement, { sticked: boolean }>(
|
||||
itemScope
|
||||
itemType="https://schema.org/IndustrialTrainings"
|
||||
ref={ref}
|
||||
className="sm:sticky top-0 min-h-[100svh] min-w-[100vw] overflow-hiddens lg:px-10 lg:pt-10 sm:px-6 sm:pt-6 px-4 pt-4 border-t border-[#3D425C] bg-[#14161F] max-sm:flex flex-col items-center gap-y-4"
|
||||
className="sm:sticky top-0 min-h-[100svh] min-w-[100vw] overflow-hiddens lg:px-10 lg:pt-10 sm:px-6 sm:pt-6 px-4 pt-4 border-t border-[#3D425C] bg-[#14161F] -z-30 max-sm:flex flex-col items-center gap-y-4"
|
||||
>
|
||||
<div className="space-y-6 lg:space-y-14 sm:space-y-10">
|
||||
<div
|
||||
|
||||
@@ -16,7 +16,7 @@ export const SimulatorsTab = forwardRef<HTMLDivElement, { sticked: boolean }>(
|
||||
itemProp="simulators"
|
||||
itemType="http://schema.org/Simulators"
|
||||
ref={ref}
|
||||
className="lg:ml-[65px] lg:min-h-[calc(100svh-138px)] lg:min-w-[calc(100vw-65px)] sm:min-h-[calc(100svh-88px)] min-w-[100vw] min-h-[calc(100svh)] sm:sticky z-30 lg:top-[138px] sm:top-[88px] top-0 bg-[#14161F] lg:px-10 lg:pt-10 sm:px-6 sm:pt-6 px-4 pt-4 lg:space-y-12 sm:space-y-10 space-y-6 lg:border-l border-t border-[#3D425C]"
|
||||
className="lg:ml-[65px] lg:min-h-[calc(100svh-138px)] lg:min-w-[calc(100vw-65px)] sm:min-h-[calc(100svh-88px)] min-w-[100vw] min-h-[calc(100svh)] sm:sticky -z-20 lg:top-[138px] sm:top-[88px] top-0 bg-[#14161F] lg:px-10 lg:pt-10 sm:px-6 sm:pt-6 px-4 pt-4 lg:space-y-12 sm:space-y-10 space-y-6 lg:border-l border-t border-[#3D425C]"
|
||||
>
|
||||
<div
|
||||
className={
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { forwardRef, useState } from 'react';
|
||||
import { IProject, Media } from '../../types/Project';
|
||||
import { IProject, Media } from '../../types/IProject';
|
||||
|
||||
export const Project = forwardRef<HTMLDivElement, IProject<Media>>(
|
||||
({ src, title, tags, media, year }, ref) => {
|
||||
|
||||
@@ -23,7 +23,7 @@ export function Projects() {
|
||||
SlideElement={Project}
|
||||
slideSizes={
|
||||
width >= 1024
|
||||
? ['31.69vw', '31.56vw', '48vw', '48vw']
|
||||
? ['31.69vw', '31.56vw', '40vw', '40vw']
|
||||
: width >= 640
|
||||
? ['66.01vw', '66vw', '93.75vw', '93.75vw']
|
||||
: ['91.11vw', '91.11vw', '91.11vw', '91.11vw']
|
||||
|
||||
@@ -2,6 +2,7 @@ import { forwardRef, useImperativeHandle, useRef } from 'react';
|
||||
import { ArrowLeftIcon } from '../icons/ArrowLeftIcon';
|
||||
import { ArrowRightIcon } from '../icons/ArrowRightIcon';
|
||||
import { delay } from 'framer-motion';
|
||||
// import { delay } from 'framer-motion';
|
||||
|
||||
export const SliderControls = forwardRef<
|
||||
{ left: () => void; right: () => void },
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
export function CubeIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="13"
|
||||
height="13"
|
||||
viewBox="0 0 13 13"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="fill-none"
|
||||
>
|
||||
<g opacity="0.8">
|
||||
<path
|
||||
d="M18.1371 6H10.1532L6 10.4296V18.1075H13.6882L18.1371 13.9732V6Z"
|
||||
fill="white"
|
||||
/>
|
||||
</g>
|
||||
<path d="M4.15322 0H12.1371V7.9732H4.15322V0Z" fill="white" />
|
||||
<path
|
||||
d="M12.1371 7.9732H4.15322L0 12.1075H7.68817L12.1371 7.9732Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M4.15322 7.9732V0L0 4.42956V12.1075L4.15322 7.9732Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,43 +1,40 @@
|
||||
import { IClient } from '../types/Client';
|
||||
import { IClient } from '../types/IClient';
|
||||
|
||||
export const clients: IClient[] = [
|
||||
{ src: '/src/assets/clients/sezar_group.png', title: 'Sezar Group' },
|
||||
{ src: '/src/assets/clients/legenda.png', title: 'Legenda' },
|
||||
{ src: '/src/assets/clients/osnova.png', title: 'Основа' },
|
||||
{ src: '/src/assets/clients/upside.png', title: 'Upside' },
|
||||
{ src: '/src/assets/clients/brusnika.png', title: 'Брусника' },
|
||||
{ src: '/src/assets/clients/capital_group.png', title: 'Capital Group' },
|
||||
{ src: '/src/assets/clients/a101.png', title: 'А101' },
|
||||
{ src: '/src/assets/clients/forum.png', title: 'Forum' },
|
||||
{ src: '/src/assets/clients/leto.png', title: 'Лето' },
|
||||
{ src: '/src/assets/clients/center.png', title: 'Center' },
|
||||
{ src: '/src/assets/clients/center-invest.png', title: 'ЦЕНТР-ИНВЕСТ' },
|
||||
{ src: '/src/assets/clients/rodina.png', title: 'Rodina' },
|
||||
{ src: '/src/assets/clients/acons.png', title: 'Acons group' },
|
||||
{ src: '/src/assets/clients/alfa.png', title: 'Alfa' },
|
||||
{ src: '/src/assets/clients/sk+.png', title: 'СК+' },
|
||||
{ src: '/src/assets/clients/delom.png', title: 'Delom' },
|
||||
{ src: '/src/assets/clients/kama.png', title: 'КамаСтройИнвест' },
|
||||
{ src: '/src/assets/clients/risan.png', title: 'Рисан' },
|
||||
{ src: '/src/assets/clients/golos.png', title: 'Голос' },
|
||||
{ src: '/src/assets/clients/dns.png', title: 'DNS' },
|
||||
{ src: '/src/assets/clients/sibintel.png', title: 'Сибинтел' },
|
||||
{ src: '/src/assets/clients/kortros.png', title: 'Кортрос' },
|
||||
{ src: '/src/assets/clients/mayak.png', title: 'Корпорация Маяк' },
|
||||
{ src: '/src/assets/clients/sbk.png', title: 'СБК' },
|
||||
{ src: '/src/assets/clients/nks.png', title: 'НКС' },
|
||||
{ src: '/src/assets/clients/atom.png', title: 'Атлас' },
|
||||
{ src: '/src/assets/clients/yit.png', title: 'YIT' },
|
||||
{ src: '/src/assets/clients/sinara.png', title: 'Синара' },
|
||||
{ src: '/src/assets/clients/pik.png', title: 'Пик' },
|
||||
{ src: '/src/assets/clients/as.png', title: 'AS' },
|
||||
{ src: '/src/assets/clients/efes.png', title: 'Эфес' },
|
||||
{ src: '/src/assets/clients/atmosfera.png', title: 'Атмосфера' },
|
||||
{ src: '/src/assets/clients/abudhabi.png', title: 'Абу-Даби' },
|
||||
{ src: '/src/assets/clients/mavis.png', title: 'Mavis' },
|
||||
{ src: '/src/assets/clients/enko.png', title: 'Энко' },
|
||||
{ src: '/src/assets/clients/paritet.png', title: 'Паритет' },
|
||||
{ src: '/src/assets/clients/fortis.png', title: 'Fortis' },
|
||||
{
|
||||
src: '/src/assets/clients/aircraft_industries.png',
|
||||
title: 'Aircraft Industries',
|
||||
},
|
||||
{
|
||||
src: '/src/assets/clients/mintrans.png',
|
||||
title: 'Министерство транспорта Российской Федерации',
|
||||
},
|
||||
{
|
||||
src: '/src/assets/clients/moscow_government.png',
|
||||
title: 'Правительство Москвы',
|
||||
},
|
||||
{ src: '/src/assets/clients/npoa.png', title: 'НПО Автоматики' },
|
||||
{ src: '/src/assets/clients/elem.png', title: 'Elem' },
|
||||
{
|
||||
src: '/src/assets/clients/RussianRailways.png',
|
||||
title: 'Российские железные дороги',
|
||||
},
|
||||
{ src: '/src/assets/clients/uralvagonzavod.png', title: 'Уралвагонзавод' },
|
||||
{
|
||||
src: '/src/assets/clients/electro_him_pribor.png',
|
||||
title: 'комбинат Электрозимприбор',
|
||||
},
|
||||
{ src: '/src/assets/clients/rosatom.png', title: 'Росатом' },
|
||||
{ src: '/src/assets/clients/croc.png', title: 'Croc' },
|
||||
{ src: '/src/assets/clients/uralhimmash.png', title: 'Уралхиммаш' },
|
||||
{
|
||||
src: '/src/assets/clients/urfu.png',
|
||||
title: 'Уральский федеральный университет',
|
||||
},
|
||||
{
|
||||
src: '/src/assets/clients/uztm.png',
|
||||
title: 'Уральский завод тяжелого машиностроения',
|
||||
},
|
||||
{ src: '/src/assets/clients/dubai_police.png', title: 'Dubai Police' },
|
||||
{ src: '/src/assets/clients/ugmk.png', title: 'УГМК' },
|
||||
{ src: '/src/assets/clients/atlas.png', title: 'Атом' },
|
||||
];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { IProject, Media } from '../types/Project';
|
||||
import { IProject, Media } from '../types/IProject';
|
||||
|
||||
export const projects: IProject<Media>[] = [
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ export function AnchorLink({
|
||||
return (
|
||||
<Link
|
||||
className={
|
||||
'btn-text font-semibold border-l last:border-r border-[#3D425C] hidden py-[30px] px-10 xl:block hover:bg-[#3D425C] active:bg-[#14161F] outline-none ' +
|
||||
'btn-text font-semibold border-l last:border-r border-[#3D425C] hidden py-[30px] px-10 xl:flex items-center hover:bg-[#3D425C] active:bg-[#14161F] outline-none ' +
|
||||
className
|
||||
}
|
||||
to={route}
|
||||
|
||||
@@ -10,7 +10,7 @@ export function MiniTitle({
|
||||
return (
|
||||
<h2
|
||||
className={
|
||||
'flex gap-1 items-start self-start uppercase opacity-60 font-medium link xl:w-full ' +
|
||||
'flex gap-1 items-center self-start uppercase opacity-60 font-medium link xl:w-full ' +
|
||||
className
|
||||
}
|
||||
>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useWindowWidth } from '../hooks/useWindowWidth';
|
||||
import { motion } from 'framer-motion';
|
||||
import { delay, motion } from 'framer-motion';
|
||||
import { ReactNode, useEffect, useReducer, useRef, useState } from 'react';
|
||||
import { useSwipeable } from 'react-swipeable';
|
||||
import { SliderControls } from '../components/Main/SliderControls';
|
||||
@@ -77,6 +77,12 @@ export function SliderWithScaling<T extends { title: string }>({
|
||||
setSliderOffset(baseoffset);
|
||||
}, [baseoffset, order, slide]);
|
||||
|
||||
useEffect(() => {
|
||||
delay(() => {
|
||||
controlsRef.current.right();
|
||||
}, 2000);
|
||||
}, [slide]);
|
||||
|
||||
const handlers = useSwipeable({
|
||||
onSwipedLeft: controlsRef.current.right,
|
||||
onSwipedRight: controlsRef.current.left,
|
||||
@@ -110,9 +116,10 @@ export function SliderWithScaling<T extends { title: string }>({
|
||||
initial={
|
||||
currentSliding === 'next' && index === 0
|
||||
? { minWidth: minWidthScaled, minHeight: minHeightScaled }
|
||||
: index === 3
|
||||
? { minWidth, minHeight }
|
||||
: {}
|
||||
: { minWidth, minHeight }
|
||||
// index === 3
|
||||
// ?
|
||||
// : {}
|
||||
}
|
||||
transition={{ duration: 1, type: 'just' }}
|
||||
animate={
|
||||
@@ -124,7 +131,7 @@ export function SliderWithScaling<T extends { title: string }>({
|
||||
: {
|
||||
minWidth,
|
||||
minHeight,
|
||||
transition: { duration: index === 3 ? 0.0001 : 1 },
|
||||
// transition: { duration: index === 3 ? 0.0001 : 1 },
|
||||
}
|
||||
}
|
||||
className={'pointer-events-none ' + childClassName}
|
||||
@@ -147,7 +154,7 @@ export function SliderWithScaling<T extends { title: string }>({
|
||||
'absolute ' +
|
||||
(controlsPosition === 'top'
|
||||
? 'top-[75px]'
|
||||
: 'lg:bottom-32 bottom-0 sm:self-end self-center')
|
||||
: 'lg:bottom-20 -bottom-10 sm:self-end self-center')
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,7 @@ export default {
|
||||
'2xl': '1600px',
|
||||
},
|
||||
animation: {
|
||||
'infinite-scroll': 'infinite-scroll 30s linear infinite',
|
||||
'infinite-scroll': 'infinite-scroll 10s linear infinite',
|
||||
},
|
||||
keyframes: {
|
||||
'infinite-scroll': {
|
||||
|
||||