added fetch card from server, style changes, i18
@@ -3,14 +3,21 @@ import "./App.css"
|
||||
import { Route, Switch } from "react-router-dom";
|
||||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useAppDispatch, useAppSelector } from "./hooks/redux";
|
||||
import cookies from "js-cookie";
|
||||
|
||||
import AOS from "aos";
|
||||
import "aos/dist/aos.css";
|
||||
import { Main } from "./components/main/main";
|
||||
import { Header } from "./components/header/header";
|
||||
import { Footer } from "./components/footer/footer";
|
||||
import { Demostration } from "./components/demonstration/demonstartion";
|
||||
import useQuery from "./hooks/useQuery";
|
||||
import textRU from "./utils/textRU"
|
||||
import textEN from "./utils/textEN";
|
||||
import { languageSlice } from "./store/reducers/languageSlice";
|
||||
import { fetchCards } from "./store/reducers/ActionCreator";
|
||||
|
||||
|
||||
|
||||
export type TObjct = {
|
||||
calendar: boolean;
|
||||
@@ -28,51 +35,52 @@ export const App: React.FC = () => {
|
||||
const savedLanguage = localStorage.getItem('savedLang')
|
||||
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const { handleChangeLanguage } = languageSlice.actions;
|
||||
const { cards, currentCard, error } = useAppSelector((state) => state.cardReducer);
|
||||
const { currentLang } = useAppSelector((state) => state.languageReducer);
|
||||
|
||||
const query = useQuery()
|
||||
|
||||
const langQuery = query.get('lang')
|
||||
|
||||
const langArray = ['en', 'ru']
|
||||
|
||||
const browserLanguage = window.navigator.language
|
||||
|
||||
const handleBrowserLanguage = () => {
|
||||
return langArray.includes(browserLanguage)
|
||||
}
|
||||
|
||||
const handleCookiesLanguage = () => {
|
||||
const language = cookies.get("i18next")
|
||||
return language
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (savedLanguage !== null) {
|
||||
setSavedLanguage()
|
||||
} else {
|
||||
setInitialLanguage()
|
||||
if (langArray.includes(langQuery as string)) {
|
||||
dispatch(handleChangeLanguage(langQuery as string));
|
||||
return
|
||||
}
|
||||
}, []);
|
||||
|
||||
function setSavedLanguage() {
|
||||
if (savedLanguage === 'RU') {
|
||||
setLanguage('RU')
|
||||
localStorage.setItem("lang", 'RU')
|
||||
setText(textRU)
|
||||
} else if (savedLanguage === 'EN') {
|
||||
setLanguage('EN')
|
||||
localStorage.setItem("lang", 'EN')
|
||||
setText(textEN)
|
||||
else if (handleCookiesLanguage()) {
|
||||
const languageCookies = handleCookiesLanguage()
|
||||
console.log(languageCookies)
|
||||
dispatch(handleChangeLanguage(languageCookies as string))
|
||||
return
|
||||
}
|
||||
}
|
||||
let isSupported = handleBrowserLanguage()
|
||||
dispatch(handleChangeLanguage(isSupported ? browserLanguage : 'en'));
|
||||
}, [])
|
||||
|
||||
function setInitialLanguage() {
|
||||
if (window.navigator.language === 'ru') {
|
||||
setLanguage('RU')
|
||||
localStorage.setItem("lang", 'RU')
|
||||
setText(textRU)
|
||||
|
||||
} else {
|
||||
setLanguage('EN')
|
||||
setText(textEN)
|
||||
useEffect(() => {
|
||||
if (currentLang) {
|
||||
dispatch(fetchCards(currentLang))
|
||||
}
|
||||
}
|
||||
}, [currentLang])
|
||||
|
||||
|
||||
|
||||
function changeLanguage(language: string) {
|
||||
if (language === 'RU') {
|
||||
setLanguage(language);
|
||||
setText(textRU)
|
||||
localStorage.setItem('savedLang', 'RU');
|
||||
localStorage.setItem("lang", 'RU')
|
||||
} else {
|
||||
setLanguage('EN')
|
||||
localStorage.setItem("lang", 'EN')
|
||||
localStorage.setItem("savedLang", 'EN')
|
||||
setText(textEN)
|
||||
}
|
||||
}
|
||||
|
||||
AOS.init({
|
||||
mirror: true,
|
||||
@@ -81,8 +89,8 @@ export const App: React.FC = () => {
|
||||
<Switch>
|
||||
<Route path="/" exact>
|
||||
<div className='App'>
|
||||
<Header text={text.footer} language={language} changeLanguage={changeLanguage}></Header>
|
||||
<Main locale={language} text={text}></Main>
|
||||
<Header></Header>
|
||||
<Main cards={cards} locale={language} text={text}></Main>
|
||||
<Footer language={language} text={text.footer}></Footer>
|
||||
</div>
|
||||
</Route>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
background: #141414;
|
||||
background: #1C1D21;
|
||||
border-radius: 16px;
|
||||
padding: 32px;
|
||||
font-style: normal;
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
/* Landing/White */
|
||||
|
||||
color: #EBEBEB;
|
||||
color: #F2F2F2;
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
align-items: flex-start;
|
||||
gap: 20px;
|
||||
padding: 24px;
|
||||
background: #141414;
|
||||
background: #1C1D21;
|
||||
border-radius: 16px;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
@@ -95,7 +95,7 @@
|
||||
font-weight: 400;
|
||||
font-size: 18px;
|
||||
line-height: 140%;
|
||||
color: #EBEBEB;
|
||||
color: #F2F2F2;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
font-weight: 400;
|
||||
font-size: 18px;
|
||||
line-height: 140%;
|
||||
color: #EBEBEB;
|
||||
color: #F2F2F2;
|
||||
}
|
||||
|
||||
.graph__row_item_l {
|
||||
|
||||
@@ -4,21 +4,23 @@ import "../multiplayer/multiplayer.css";
|
||||
import { PieChartComp } from "../piechart/piechart";
|
||||
import { Button } from "../buttonDemo/buttonDemo"
|
||||
import { Content } from "../content/content";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
|
||||
|
||||
|
||||
export const Analytics: React.FC<any> = ({ text }) => {
|
||||
const { cardLarge, cardLarge1, cardLarge2, cardSmall, cardSmall1, cardSmall2, cardSmall3 } = text;
|
||||
const {t} = useTranslation()
|
||||
return (
|
||||
<div className="analytics__container">
|
||||
<Content text={text}></Content>
|
||||
<div data-aos="fade-up" data-aos-delay="100" className="graph__container">
|
||||
<div className="graph__row_1">
|
||||
<div className="graph__row_item">
|
||||
<span className="graph__title title_1">{cardLarge.title}</span>
|
||||
<span className="graph__title title_1">{t('cardLarge-title')}</span>
|
||||
<div className="graph__bar_row">
|
||||
<p className="graph__caption">{cardLarge.row}</p>
|
||||
<p className="graph__caption">{t('cardLarge-row')}</p>
|
||||
<div className="bar__container">
|
||||
<div className="graph__bar_width_container">
|
||||
<div className="graph__bar_1"></div>
|
||||
@@ -27,7 +29,7 @@ export const Analytics: React.FC<any> = ({ text }) => {
|
||||
<p className="graph__procentage">45%</p>
|
||||
</div>
|
||||
<div className="graph__bar_row">
|
||||
<p className="graph__caption">{cardLarge.row1}</p>
|
||||
<p className="graph__caption">{t('cardLarge-row1')}</p>
|
||||
<div className="bar__container">
|
||||
<div className="graph__bar_width_container">
|
||||
<div className="graph__bar_2"></div>
|
||||
@@ -37,7 +39,7 @@ export const Analytics: React.FC<any> = ({ text }) => {
|
||||
|
||||
</div>
|
||||
<div className="graph__bar_row">
|
||||
<p className="graph__caption">{cardLarge.row2}</p>
|
||||
<p className="graph__caption">{t('cardLarge-row2')}</p>
|
||||
<div className="bar__container">
|
||||
<div className="graph__bar_width_container">
|
||||
<div className="graph__bar_3"></div>
|
||||
@@ -47,7 +49,7 @@ export const Analytics: React.FC<any> = ({ text }) => {
|
||||
|
||||
</div>
|
||||
<div className="graph__bar_row">
|
||||
<p className="graph__caption">{cardLarge.row3}</p>
|
||||
<p className="graph__caption">{t('cardLarge-row3')}</p>
|
||||
<div className="bar__container">
|
||||
<div className="graph__bar_width_container">
|
||||
<div className="graph__bar_4"></div>
|
||||
@@ -58,57 +60,57 @@ export const Analytics: React.FC<any> = ({ text }) => {
|
||||
</div>
|
||||
</div>
|
||||
<div className="graph__row_item">
|
||||
<span className="graph__title title_2">{cardLarge1.title}</span>
|
||||
<span className="graph__title title_2">{t('cardLarge1-title')}</span>
|
||||
<div className="chart__container">
|
||||
<PieChartComp />
|
||||
<div className="legend__container">
|
||||
<div className="legend__row">
|
||||
<div className="legend__point color"></div>
|
||||
<p className="legend__caption">{cardLarge1.row}</p>
|
||||
<p className="legend__caption">{t('cardLarge1-row')}</p>
|
||||
</div>
|
||||
<div className="legend__row">
|
||||
<div className="legend__point color1"></div>
|
||||
<p className="legend__caption">{cardLarge1.row1}</p>
|
||||
<p className="legend__caption">{t('cardLarge1-row1')}</p>
|
||||
</div>
|
||||
<div className="legend__row">
|
||||
<div className="legend__point color2"></div>
|
||||
<p className="legend__caption">{cardLarge1.row2}</p>
|
||||
<p className="legend__caption">{t('cardLarge1-row2')}</p>
|
||||
</div>
|
||||
<div className="legend__row">
|
||||
<div className="legend__point color3"></div>
|
||||
<p className="legend__caption">{cardLarge1.row3}</p>
|
||||
<p className="legend__caption">{t('cardLarge1-row3')}</p>
|
||||
</div>
|
||||
<div className="legend__row">
|
||||
<div className="legend__point color4"></div>
|
||||
<p className="legend__caption">{cardLarge1.row4}</p>
|
||||
<p className="legend__caption">{t('cardLarge1-row4')}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="graph__row_item">
|
||||
<span className="graph__title">{cardLarge2.title}</span>
|
||||
<span className="graph__title">{t('cardLarge2-title')}</span>
|
||||
<div className="sales__container">
|
||||
<div className="sales__row">
|
||||
<div className="background__row">
|
||||
<div className="sales__bar">{cardLarge2.row}</div>
|
||||
<div className="sales__bar">{t('cardLarge2-row')}</div>
|
||||
</div>
|
||||
<div className="sales__procentage"></div>
|
||||
</div>
|
||||
<div className="sales__row">
|
||||
<div className="background__row">
|
||||
<div className="sales__bar sales_bar_width">{cardLarge2.row1}</div>
|
||||
<div className="sales__bar sales_bar_width">{t('cardLarge2-row1')}</div>
|
||||
</div>
|
||||
<div className="sales__procentage">93,47%</div>
|
||||
</div>
|
||||
<div className="sales__row">
|
||||
<div className="background__row">
|
||||
<div className="sales__bar sales_bar_width1">{cardLarge2.row2}</div>
|
||||
<div className="sales__bar sales_bar_width1">{t('cardLarge2-row2')}</div>
|
||||
</div>
|
||||
<div className="sales__procentage">45,68%</div>
|
||||
</div>
|
||||
<div className="sales__row">
|
||||
<div className="background__row">
|
||||
<div className="sales__bar sales_bar_width3">{cardLarge2.row3}</div>
|
||||
<div className="sales__bar sales_bar_width3">{t('cardLarge2-row3')}</div>
|
||||
</div>
|
||||
<div className="sales__procentage">29,13%</div>
|
||||
</div>
|
||||
@@ -118,38 +120,38 @@ export const Analytics: React.FC<any> = ({ text }) => {
|
||||
</div>
|
||||
<div className="graph__row_2">
|
||||
<div className=" graph__row_item_s">
|
||||
<span className="graph__title_s">{cardSmall.title}</span>
|
||||
<span className="graph__title_s">{t('cardSmall-title')}</span>
|
||||
<div className="graph__color_elem">
|
||||
12:45
|
||||
</div>
|
||||
</div>
|
||||
<div className="graph__row_item_s">
|
||||
<span className="graph__title_s">{cardSmall1.title}</span>
|
||||
<span className="graph__title_s">{t('cardSmall1-title')}</span>
|
||||
<div className="graph__color_elem">
|
||||
856
|
||||
</div>
|
||||
</div>
|
||||
<div className=" graph__row_item_s">
|
||||
<span className="graph__title_s">{cardSmall2.title}</span>
|
||||
<span className="graph__title_s">{t('cardSmall2-title')}</span>
|
||||
<div className="graph__color_elem">
|
||||
12,44
|
||||
</div>
|
||||
</div>
|
||||
<div className="graph__row_item_s">
|
||||
<span className="graph__title_s">{cardSmall3.title}</span>
|
||||
<span className="graph__title_s">{t('cardSmall3-title')}</span>
|
||||
<div className="graph__color_elem">
|
||||
134,5
|
||||
</div>
|
||||
</div>
|
||||
<div className=" graph__row_mobile graph__row_item_l">
|
||||
<div className="graph__text">{text.mainBlockSubblock}</div>
|
||||
<div className="graph__text">{t(`${text}-mainBlockSubblock`)}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="main-block_subblock">
|
||||
<div className="graph__text_mobile">{text.mainBlockSubblock}</div>
|
||||
<Button text={text}></Button>
|
||||
<div className="graph__text_mobile">{t(`${text}-mainBlockSubblock`)}</div>
|
||||
<Button></Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -3,8 +3,11 @@ import "./animationComponent.css"
|
||||
import "../../styles/styles.css"
|
||||
import "./mapblock.css"
|
||||
import { Button } from "../buttonDemo/buttonDemo"
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const AnimationComponent: React.FC<any> = () => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
export const AnimationComponent: React.FC<any> = ({ text }) => {
|
||||
return (
|
||||
<div>
|
||||
<div className="animation-container">
|
||||
@@ -18,9 +21,9 @@ export const AnimationComponent: React.FC<any> = ({ text }) => {
|
||||
|
||||
</div>
|
||||
<span className="title__caption">
|
||||
{text.titleCaption}
|
||||
{t('main-titleCaption')}
|
||||
</span>
|
||||
<Button text={text}></Button>
|
||||
<Button></Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,16 +1,26 @@
|
||||
import { Link } from "react-router-dom";
|
||||
import iconButton from '../../styles/iconButton.svg'
|
||||
import '../../styles/styles.css'
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAppSelector, useAppDispatch } from "../../hooks/redux";
|
||||
|
||||
|
||||
|
||||
export const Button: React.FC<any> = () => {
|
||||
const { currentLang } = useAppSelector((state) => state.languageReducer);
|
||||
|
||||
const { t } = useTranslation()
|
||||
|
||||
|
||||
return (
|
||||
<a href={`https://stream.graff.tech/?lang=${currentLang}`} className="link">
|
||||
<button className="main-block__button">
|
||||
{t('main-button')}
|
||||
<div className="main-block__icon_container">
|
||||
<img alt="icon" src={iconButton} className="main-block__icon"></img>
|
||||
</div>
|
||||
</button>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
export const Button: React.FC<any> = ({text}) => {
|
||||
return (
|
||||
<a href="https://stream.graff.tech/" className="link">
|
||||
<button className="main-block__button">
|
||||
{text.button}
|
||||
<div className="main-block__icon_container">
|
||||
<img alt="icon" src={iconButton} className="main-block__icon"></img>
|
||||
</div>
|
||||
</button>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
@@ -5,8 +5,9 @@ import point0 from "./Ellipse0.svg";
|
||||
import point1 from "./Ellipse1.svg";
|
||||
import { TProps } from "../calendarDesktop/calendarDesktop";
|
||||
import { useSwiper } from 'swiper/react';
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export const Calendar: React.FC<TProps> = ({ open, setOpen, time, onUpdate, isMobile, locale, text }) => {
|
||||
export const Calendar: React.FC<TProps> = ({ open, setOpen, time, onUpdate, isMobile, locale }) => {
|
||||
const swiper = useSwiper();
|
||||
const [calendar, setCalendar] = useState<any[]>([]);
|
||||
const [value, setValue] = useState(time);
|
||||
@@ -25,8 +26,8 @@ export const Calendar: React.FC<TProps> = ({ open, setOpen, time, onUpdate, isMo
|
||||
|
||||
useEffect(() => {
|
||||
setValue(time.locale(locale as string))
|
||||
}, [locale])
|
||||
|
||||
}, [locale])
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const day = startDay.clone().subtract("1", "day");
|
||||
@@ -86,11 +87,13 @@ export const Calendar: React.FC<TProps> = ({ open, setOpen, time, onUpdate, isMo
|
||||
}
|
||||
|
||||
|
||||
return (<div data-aos="fade-up" className='calendar'>
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (<div data-aos="fade-up" className='calendar'>
|
||||
<div className={open.calendar ? 'opacity_active' : 'opacity'}>
|
||||
<div className="calendar__header">
|
||||
<span className="calendar__caption calendar__caption_calendar">
|
||||
{text.calendarCaption}
|
||||
{t('calendarCaption')}
|
||||
</span>
|
||||
<div className="line"></div>
|
||||
</div>
|
||||
@@ -134,11 +137,11 @@ export const Calendar: React.FC<TProps> = ({ open, setOpen, time, onUpdate, isMo
|
||||
<div className="appointment__block">
|
||||
<div>
|
||||
<img alt="point" className="point" src={point1}></img>
|
||||
<span className="appointment__caption_active">{text.appointmentTrue}</span>
|
||||
<span className="appointment__caption_active">{t('appointmentTrue')}</span>
|
||||
</div>
|
||||
<div>
|
||||
<img alt="point" className="point" src={point0}></img>
|
||||
<span className="appointment__caption" >{text.appointmentFalse}</span>
|
||||
<span className="appointment__caption" >{t('appointmentFalse')}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>)
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M23 12H1M1 12L8.2 5M1 12L8.2 19" stroke="#EBEBEB" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 211 B |
@@ -3,35 +3,7 @@
|
||||
}
|
||||
|
||||
|
||||
.button__arrow_l {
|
||||
cursor: pointer;
|
||||
background-image: url(./Arrow_Left.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
height: 14px;
|
||||
width: 22px;
|
||||
}
|
||||
|
||||
.button__arrow_r {
|
||||
-webkit-transform: matrix(-1, 0, 0, 1, 0, 0);
|
||||
-ms-transform: matrix(-1, 0, 0, 1, 0, 0);
|
||||
transform: matrix(-1, 0, 0, 1, 0, 0);
|
||||
|
||||
cursor: pointer;
|
||||
background-image: url(./Arrow_Left.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
height: 14px;
|
||||
width: 22px;
|
||||
}
|
||||
|
||||
.button__arrow_r:hover {
|
||||
background-image: url(../calendar/arrow_active1.png);
|
||||
}
|
||||
|
||||
.button__arrow_l:hover {
|
||||
background-image: url(../calendar/arrow_active1.png);
|
||||
}
|
||||
|
||||
.button__arrow_back {
|
||||
cursor: pointer;
|
||||
@@ -139,11 +111,11 @@
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
|
||||
color: #ebebeb;
|
||||
color: #F2F2F2;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
width: 385px;
|
||||
background: #141414;
|
||||
background: #1C1D21;
|
||||
border-radius: 16px;
|
||||
padding: 24px 32px;
|
||||
box-sizing: border-box;
|
||||
|
||||
@@ -9,6 +9,7 @@ import "../../styles/styles.css";
|
||||
import { Confirm } from "../confirm/confirm";
|
||||
import { Calendar } from "../calendar/calendar";
|
||||
import { Content } from '../content/content'
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
|
||||
export type TProps = {
|
||||
@@ -36,14 +37,13 @@ export const CalendarDesktop: React.FC<TProps> = ({
|
||||
text,
|
||||
locale
|
||||
}) => {
|
||||
console.log(text, 'here2')
|
||||
|
||||
const {t} = useTranslation()
|
||||
return (
|
||||
<div className="calendar__container">
|
||||
<Content text={text}></Content>
|
||||
<Content isColorCaption={true} text={text}></Content>
|
||||
<div className="wrapper">
|
||||
<Calendar
|
||||
text={text}
|
||||
setDisplayForm={setDisplayForm}
|
||||
displayForm={displayForm}
|
||||
open={open}
|
||||
@@ -56,7 +56,6 @@ export const CalendarDesktop: React.FC<TProps> = ({
|
||||
|
||||
/>
|
||||
<Timepicker
|
||||
text={text}
|
||||
setDisplayForm={setDisplayForm}
|
||||
displayForm={displayForm}
|
||||
open={open}
|
||||
@@ -68,7 +67,6 @@ export const CalendarDesktop: React.FC<TProps> = ({
|
||||
|
||||
></Timepicker>
|
||||
<Form
|
||||
text={text}
|
||||
setDisplayForm={setDisplayForm}
|
||||
displayForm={displayForm}
|
||||
open={open}
|
||||
@@ -80,7 +78,6 @@ export const CalendarDesktop: React.FC<TProps> = ({
|
||||
|
||||
></Form>
|
||||
<Confirm
|
||||
text={text}
|
||||
setDisplayForm={setDisplayForm}
|
||||
displayForm={displayForm}
|
||||
open={open}
|
||||
@@ -93,7 +90,7 @@ export const CalendarDesktop: React.FC<TProps> = ({
|
||||
</div>
|
||||
<div className="main-block__subblock-container">
|
||||
<div className="main-block_subblock">
|
||||
{text.mainBlockSubblock}
|
||||
{t('calendar-mainBlockSubblock')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,6 +11,7 @@ import "swiper/css/pagination";
|
||||
import "swiper/css/navigation";
|
||||
import "./calendarMobile.css"
|
||||
import { Content } from "../content/content";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
|
||||
|
||||
@@ -18,11 +19,12 @@ import { Content } from "../content/content";
|
||||
export const CalendarMobile: React.FC<TProps> = ({ setDisplayForm, displayForm, open, setOpen, onUpdate, time, onExit, isMobile, text, locale }) => {
|
||||
|
||||
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<div className="calendar__mobile">
|
||||
<div className="calendar__container">
|
||||
<div className="slider">
|
||||
<Content text={text}></Content>
|
||||
<Content isColorCaption={true} text={text}></Content>
|
||||
</div>
|
||||
<Swiper
|
||||
rewind={true}
|
||||
@@ -87,7 +89,7 @@ export const CalendarMobile: React.FC<TProps> = ({ setDisplayForm, displayForm,
|
||||
</Swiper>
|
||||
<div className="main-block__subblock-container calendar__padding">
|
||||
<div className="main-block_subblock">
|
||||
{text.mainBlockSubblock}
|
||||
{t('calendar-mainBlockSubblock')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
|
||||
.block__container {
|
||||
overflow: hidden;
|
||||
background: #141414;
|
||||
border-radius: 32px;
|
||||
background: #1C1D21; border-radius: 32px;
|
||||
padding: 74px 80px;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import './cloudSolution.css'
|
||||
import "../../styles/styles.css";
|
||||
import serverFrame from './serverFrame.png'
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
|
||||
export const CloudSolution: React.FC<any> = ({ text }) => {
|
||||
const {t} = useTranslation()
|
||||
return (
|
||||
<div data-aos="zoom-in" data-aos-duration="500" className="cloud__container">
|
||||
<div className='block__container'>
|
||||
@@ -17,11 +19,11 @@ export const CloudSolution: React.FC<any> = ({ text }) => {
|
||||
Graff.estate stream –
|
||||
</p>
|
||||
<p className=" main-block__title_gardient_small width cloud__title">
|
||||
{text.title}
|
||||
{t('cloudSolution-title')}
|
||||
</p>
|
||||
</div>
|
||||
<p className="main-block__caption cloud__caption">
|
||||
{text.mainBlockCaption}
|
||||
{t('cloudSolution=mainBlockCaption')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import '../form/form.css'
|
||||
import { TProps } from "../calendarDesktop/calendarDesktop";
|
||||
import { useSwiper } from 'swiper/react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
|
||||
|
||||
|
||||
export const Confirm: React.FC<TProps> = ({ open, onExit, setOpen, isMobile, text }) => {
|
||||
export const Confirm: React.FC<TProps> = ({ open, onExit, setOpen, isMobile }) => {
|
||||
const swiper = useSwiper();
|
||||
|
||||
const {t} = useTranslation()
|
||||
|
||||
function exit() {
|
||||
if (isMobile) {
|
||||
swiper.slideNext()
|
||||
@@ -20,14 +23,14 @@ export const Confirm: React.FC<TProps> = ({ open, onExit, setOpen, isMobile, tex
|
||||
return (<div className={open.confirm ? "confirm" : "confirm__none"}>
|
||||
<div className="confirm__container">
|
||||
<h2 className="confirm__title">
|
||||
{text.confirm.title}
|
||||
{t("confirm-title")}
|
||||
</h2>
|
||||
<p className="confirm__caption">
|
||||
{text.confirm.caption}
|
||||
{t("confirm-caption")}
|
||||
</p>
|
||||
</div>
|
||||
<button onClick={exit} className="button__submit">
|
||||
{text.buttons.next}
|
||||
{t("buttons-next")}
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import "../../styles/styles.css";
|
||||
|
||||
export const Content: React.FC<any> = ({ text, captionSmall }) => {
|
||||
export const Content: React.FC<any> = ({ text, captionSmall, isColorCaption }) => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<div data-aos="fade-up"
|
||||
data-aos-delay="400"
|
||||
className="main-block__container">
|
||||
<p className="main-block__title_small">
|
||||
Graff.estate stream{" "}
|
||||
<p className="main-block__title_gardient_small">{text.title}</p>
|
||||
<p className="main-block__title_gardient_small">{t(`${text}-title`)}</p>
|
||||
</p>
|
||||
{text.mainBlockCaptionColor ? <p className=" main-block__caption_color">
|
||||
{text.mainBlockCaptionColor}
|
||||
</p>
|
||||
: <></>}
|
||||
{isColorCaption ? <p className=" main-block__caption_color">
|
||||
{t(`${text}-mainBlockCaptionColor`)}
|
||||
</p> : <></>}
|
||||
<p className={captionSmall ? "main-block__caption main-block__caption_small" : "main-block__caption"}>
|
||||
{text.mainBlockCaption}
|
||||
{t(`${text}-mainBlockCaption`)}
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
}
|
||||
|
||||
.demos_container {
|
||||
background: #141414;
|
||||
background: #1C1D21;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
}
|
||||
|
||||
.demo_image {
|
||||
object-fit: cover;
|
||||
background: -webkit-gradient(linear, left bottom, left top, from(rgba(0, 0, 0, 0.3)), to(rgba(0, 0, 0, 0.3)));
|
||||
background: -o-linear-gradient(bottom, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3));
|
||||
background: linear-gradient(0deg, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3));
|
||||
@@ -88,7 +89,7 @@
|
||||
|
||||
/* Landing/White */
|
||||
|
||||
color: #EBEBEB;
|
||||
color: #F2F2F2;
|
||||
}
|
||||
|
||||
.caption {
|
||||
@@ -102,7 +103,7 @@
|
||||
|
||||
/* Landing/White */
|
||||
|
||||
color: #EBEBEB;
|
||||
color: #F2F2F2;
|
||||
|
||||
opacity: 0.5;
|
||||
|
||||
@@ -120,7 +121,7 @@
|
||||
|
||||
/* Landing/White */
|
||||
|
||||
color: #EBEBEB;
|
||||
color: #F2F2F2;
|
||||
}
|
||||
|
||||
.caption2 {
|
||||
@@ -135,7 +136,7 @@
|
||||
|
||||
/* Landing/White */
|
||||
|
||||
color: #EBEBEB;
|
||||
color: #F2F2F2;
|
||||
|
||||
opacity: 0.5;
|
||||
}
|
||||
@@ -232,8 +233,6 @@
|
||||
|
||||
.demo_image {
|
||||
height: auto;
|
||||
-o-object-fit: cover;
|
||||
object-fit: cover;
|
||||
width: 240px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,56 +3,41 @@ import "../../styles/styles.css";
|
||||
import building1 from './building1.png'
|
||||
import building2 from './building2.png'
|
||||
|
||||
import { useAppDispatch, useAppSelector } from "../../hooks/redux";
|
||||
|
||||
import iconButton from "./iconButton.svg"
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
|
||||
export const Demos: React.FC<any> = ({ text }) => {
|
||||
const { card, card1 } = text;
|
||||
console.log(text)
|
||||
export const Demos: React.FC<any> = ({ cards }) => {
|
||||
const { currentLang } = useAppSelector((state) => state.languageReducer);
|
||||
const {t} = useTranslation()
|
||||
|
||||
return (<div className=" demo__container_mobile main-block__container width demo__container">
|
||||
<h3 className='demos__tittle'>
|
||||
{text.title}
|
||||
{t('demo-title')}
|
||||
</h3>
|
||||
<a href='https://stream.graff.tech/' target='_blank' rel="noreferrer" data-aos="fade-up"
|
||||
data-aos-delay="100" className='demos_container'>
|
||||
<div className="main-block__icon_container demo__icon">
|
||||
<img alt='icon' src={iconButton} className="main-block__icon"></img>
|
||||
</div>
|
||||
<div className='demo'>
|
||||
<img alt='buildingImg' src={building1} className='demo_image'></img>
|
||||
<div className='demo_info'>
|
||||
<div className='title__block'>
|
||||
<h4 className='title__demo'>{card.title}</h4>
|
||||
<p className='caption'>{card.subTitle}</p>
|
||||
</div>
|
||||
<div className='body__block'>
|
||||
<p className='caption1'>{card.caption}</p>
|
||||
<p className='caption2'>{card.caption1}</p>
|
||||
{cards.map((i: any) => (
|
||||
<a href={`https://stream.graff.tech/?lang=${currentLang}`} target='_blank' rel="noreferrer" data-aos="fade-up"
|
||||
data-aos-delay="100" className='demos_container'>
|
||||
<div className="main-block__icon_container demo__icon">
|
||||
<img alt='icon' src={iconButton} className="main-block__icon"></img>
|
||||
</div>
|
||||
<div className='demo'>
|
||||
<img alt='buildingImg' src={i.preview} className='demo_image'></img>
|
||||
<div className='demo_info'>
|
||||
<div className='title__block'>
|
||||
<h4 className='title__demo'>{i.title}</h4>
|
||||
<p className='caption'>{i.location}</p>
|
||||
</div>
|
||||
<div className='body__block'>
|
||||
<p className='caption1'>{i.description}</p>
|
||||
{i.feature_description ? <p className='caption2'>{i.feature_description}</p> : <p></p>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<a href='https://stream.graff.tech/' target='_blank' rel="noreferrer" data-aos="fade-up"
|
||||
data-aos-delay="150" className='demos_container'>
|
||||
<div className="main-block__icon_container demo__icon">
|
||||
<img alt='icon' src={iconButton} className="main-block__icon"></img>
|
||||
</div>
|
||||
<div className='demo'>
|
||||
<img alt='buildingImg' src={building2} className='demo_image'></img>
|
||||
<div className='demo_info'>
|
||||
<div className='title__block'>
|
||||
<h4 className='title__demo'>{card1.title}</h4>
|
||||
<p className='caption'>{card1.subTitle}</p>
|
||||
</div>
|
||||
<div className='body__block'>
|
||||
<p className='caption1'>{card1.caption}</p>
|
||||
<p className='caption2'>{card1.caption1}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
|
||||
)
|
||||
|
||||
|
After Width: | Height: | Size: 382 KiB |
@@ -34,8 +34,7 @@
|
||||
flex-direction: column;
|
||||
height: 380px;
|
||||
padding: 32px;
|
||||
background: #141414;
|
||||
border-radius: 16px;
|
||||
background: #1C1D21; border-radius: 16px;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
@@ -67,7 +66,7 @@
|
||||
|
||||
/* Landing/White */
|
||||
|
||||
color: #ebebeb;
|
||||
color: #C5C7CE;
|
||||
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 639 KiB After Width: | Height: | Size: 669 KiB |
|
Before Width: | Height: | Size: 433 KiB After Width: | Height: | Size: 437 KiB |
@@ -9,7 +9,7 @@
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
background-color: transparent;
|
||||
background: #141414;
|
||||
background: #1C1D21;
|
||||
border-radius: 32px 32px 0px 0px;
|
||||
color: #EBEBEB;
|
||||
display: -webkit-box;
|
||||
@@ -30,7 +30,7 @@
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
padding: 120px 120px;
|
||||
padding: 0 120px;
|
||||
gap: 186px;
|
||||
-webkit-box-pack: justify;
|
||||
-ms-flex-pack: justify;
|
||||
@@ -173,7 +173,7 @@
|
||||
}
|
||||
|
||||
.footer__card_l {
|
||||
background: #1E1E1E;
|
||||
background: #2E3038;
|
||||
border-radius: 16px;
|
||||
padding: 32px;
|
||||
margin-bottom: 30px;
|
||||
@@ -190,6 +190,7 @@
|
||||
}
|
||||
|
||||
.footer__card_2 {
|
||||
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
@@ -205,8 +206,8 @@
|
||||
|
||||
/* Gray */
|
||||
|
||||
color: #E3DDE5;
|
||||
border: 1px solid #454545;
|
||||
color: #FFFFFF;
|
||||
border: 1px solid #73788C;
|
||||
border-radius: 16px;
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ export const Footer: React.FC<any> = ({ text, language }) => {
|
||||
<p className='contacts__title'>{text.social}</p>
|
||||
<div className='footer__container_social'>
|
||||
<a href='https://www.facebook.com/GRAFFinteractive' target='_blank' rel="noreferrer" className='footer__social'>Facebook</a>
|
||||
<a href='https://www.instagram.com/graffinteractive/' target='_blank' rel="noreferrer" className='footer__social'>Instagram</a>
|
||||
<a href='https://www.youtube.com/channel/UCveYBNLVeGxgsDsfhrVxNoA' target='_blank' rel="noreferrer" className='footer__social'>YouTube</a>
|
||||
<a href='https://vk.com/graffinteractive' target='_blank' rel="noreferrer" className='footer__social'>VK</a>
|
||||
</div>
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 17 KiB |
@@ -1,6 +1,5 @@
|
||||
.form__container {
|
||||
width: 385px;
|
||||
color: #ebebeb;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
@@ -11,7 +10,8 @@
|
||||
padding: 24px 32px;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
background: #141414;
|
||||
background: #1C1D21;
|
||||
color: #F2F2F2;
|
||||
border-radius: 16px;
|
||||
-webkit-box-pack: justify;
|
||||
-ms-flex-pack: justify;
|
||||
|
||||
@@ -3,9 +3,10 @@ import "../timepicker/timepicker.css"
|
||||
import "../../index.css"
|
||||
import { TProps } from "../calendarDesktop/calendarDesktop";
|
||||
import { useSwiper } from 'swiper/react';
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
|
||||
export const Form: React.FC<TProps> = ({ time, open, setOpen, displayForm, setDisplayForm, isMobile, text }) => {
|
||||
export const Form: React.FC<TProps> = ({ time, open, setOpen, displayForm, setDisplayForm, isMobile }) => {
|
||||
const swiper = useSwiper();
|
||||
|
||||
|
||||
@@ -37,7 +38,7 @@ export const Form: React.FC<TProps> = ({ time, open, setOpen, displayForm, setDi
|
||||
form: false,
|
||||
confirm: true
|
||||
})
|
||||
swiper.slideNext()
|
||||
swiper.slideNext()
|
||||
} else {
|
||||
setDisplayForm(false)
|
||||
setOpen({
|
||||
@@ -45,11 +46,12 @@ export const Form: React.FC<TProps> = ({ time, open, setOpen, displayForm, setDi
|
||||
timePicker: false,
|
||||
form: false,
|
||||
confirm: true
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const { t } = useTranslation()
|
||||
|
||||
|
||||
return (
|
||||
@@ -58,7 +60,7 @@ export const Form: React.FC<TProps> = ({ time, open, setOpen, displayForm, setDi
|
||||
<div className="timepicker__header">
|
||||
<div className="caption__container">
|
||||
<div onClick={goBack} className="button__arrow_back"></div>
|
||||
<span className="calendar__caption">{text.formCaption}</span>
|
||||
<span className="calendar__caption">{t('formCaption')}</span>
|
||||
</div>
|
||||
<div className="line line_time"></div>
|
||||
<div className="date date_time">{!open.form ? '' : time.format("DD MMM, HH:mm")}</div>
|
||||
@@ -70,26 +72,26 @@ export const Form: React.FC<TProps> = ({ time, open, setOpen, displayForm, setDi
|
||||
name="tel"
|
||||
className="form__input"
|
||||
type="text"
|
||||
placeholder={text.placeholders.name}
|
||||
placeholder={t('placeholders-phoneNumber') as string}
|
||||
></input>
|
||||
<input
|
||||
name="email"
|
||||
className="form__input"
|
||||
type="number"
|
||||
placeholder={text.placeholders.phoneNumber}
|
||||
placeholder={t('placeholders-email') as string}
|
||||
></input>
|
||||
<input
|
||||
name="name"
|
||||
className="form__input"
|
||||
type="email"
|
||||
placeholder={text.placeholders.email}
|
||||
placeholder={t('placeholders-name') as string}
|
||||
></input>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button onClick={handleConfirm} disabled={!open.form} type="submit" className={open.form ? 'button__submit' : 'button__submit button__submit_disabled'}>
|
||||
{text.buttons.plan}
|
||||
{t('buttons-plan')}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<svg width="20" height="13" viewBox="0 0 20 13" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1 13C0.447716 13 0 12.5523 0 12V1C0 0.447715 0.447715 0 1 0H6.82201C7.28827 0 7.66624 0.377978 7.66624 0.844238V0.844238C7.66624 1.3105 7.28827 1.68848 6.82201 1.68848H2.34491C2.06877 1.68848 1.84491 1.91233 1.84491 2.18848V5.14941C1.84491 5.42556 2.06877 5.64941 2.34491 5.64941H6.42515C6.88966 5.64941 7.26621 6.02597 7.26621 6.49048V6.49048C7.26621 6.95499 6.88966 7.33154 6.42515 7.33154H2.34491C2.06877 7.33154 1.84491 7.5554 1.84491 7.83154V10.8115C1.84491 11.0877 2.06877 11.3115 2.34491 11.3115H6.89365C7.35991 11.3115 7.73789 11.6895 7.73789 12.1558V12.1558C7.73789 12.622 7.35991 13 6.89365 13H1Z" fill="#F2F2F2"/>
|
||||
<path d="M19.0865 0C19.591 0 20 0.408988 20 0.913501V12C20 12.5523 19.5523 13 19 13H18.8462C18.5082 13 18.193 12.8293 18.0085 12.5461L12.1107 3.49922C12.0972 3.47838 12.074 3.46582 12.0491 3.46582V3.46582C12.0085 3.46582 11.9755 3.49876 11.9755 3.5394V12.0775C11.9755 12.587 11.5625 13 11.0531 13V13C10.5436 13 10.1306 12.587 10.1306 12.0775V1C10.1306 0.447715 10.5783 0 11.1306 0H11.2963C11.6343 0 11.9495 0.170802 12.1341 0.454032L18.0378 9.51347C18.0514 9.53431 18.0746 9.54687 18.0994 9.54687V9.54687C18.1401 9.54687 18.173 9.51394 18.173 9.4733V0.913501C18.173 0.408988 18.582 0 19.0865 0V0Z" fill="#F2F2F2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg width="20" height="13" viewBox="0 0 20 13" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.897734 12.7877C0.401929 12.7877 0 12.3858 0 11.89V0.999999C0 0.447714 0.447715 0 1 0H4.24172C5.16366 0 5.92872 0.170669 6.5369 0.512008C7.14894 0.853346 7.60604 1.32581 7.90819 1.92939C8.21034 2.52882 8.36142 3.2219 8.36142 4.00865C8.36142 4.79123 8.20841 5.48015 7.90238 6.07541C7.60023 6.66651 7.14313 7.12648 6.53109 7.45533C5.92291 7.78418 5.15785 7.94861 4.23591 7.94861H1.85311C1.39447 7.94861 1.02266 7.5768 1.02266 7.11816C1.02266 6.65951 1.39447 6.2877 1.85311 6.2877H4.07321C4.65427 6.2877 5.12686 6.19821 5.49099 6.01921C5.859 5.84022 6.12822 5.58005 6.29866 5.23871C6.46911 4.89737 6.55433 4.48735 6.55433 4.00865C6.55433 3.52578 6.46717 3.10743 6.29285 2.7536C6.12241 2.39978 5.85319 2.1292 5.48518 1.94188C5.12105 1.7504 4.64265 1.65466 4.04997 1.65466H2.29547C2.01933 1.65466 1.79547 1.87852 1.79547 2.15466V11.89C1.79547 12.3858 1.39354 12.7877 0.897734 12.7877ZM5.32848 7.01825C5.66354 7.01825 5.97028 7.20621 6.12241 7.50474L8.14113 11.4661C8.44931 12.0708 8.01003 12.7877 7.3313 12.7877C6.9869 12.7877 6.67209 12.5931 6.51818 12.285L4.53132 8.30754C4.23536 7.71508 4.66621 7.01825 5.32848 7.01825Z" fill="#F2F2F2"/>
|
||||
<path d="M18.1987 0.900639C18.1987 0.403229 18.602 0 19.0994 0C19.5968 0 20 0.40323 20 0.900639V8.41066C20 9.30564 19.8044 10.0986 19.4131 10.7896C19.0219 11.4765 18.4718 12.0176 17.7629 12.4131C17.054 12.8044 16.2231 13 15.2702 13C14.3211 13 13.4922 12.8044 12.7833 12.4131C12.0744 12.0176 11.5243 11.4765 11.1331 10.7896C10.7418 10.0986 10.5462 9.30564 10.5462 8.41066V0.897733C10.5462 0.401929 10.9481 0 11.4439 0C11.9397 0 12.3417 0.401929 12.3417 0.897734V8.25456C12.3417 8.83317 12.4598 9.34726 12.6961 9.79683C12.9363 10.2464 13.2752 10.6002 13.713 10.8583C14.1507 11.1122 14.6698 11.2392 15.2702 11.2392C15.8745 11.2392 16.3955 11.1122 16.8332 10.8583C17.2748 10.6002 17.6119 10.2464 17.8443 9.79683C18.0806 9.34726 18.1987 8.83317 18.1987 8.25456V0.900639Z" fill="#F2F2F2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
@@ -1,32 +1,53 @@
|
||||
/*
|
||||
* Prefixed by https://autoprefixer.github.io
|
||||
* PostCSS: v8.4.14,
|
||||
* Autoprefixer: v10.4.7
|
||||
* Browsers: last 4 version
|
||||
*/
|
||||
|
||||
.header-container {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
.header {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
padding: 30px 40px;
|
||||
color: #ffffff;
|
||||
-webkit-box-pack: justify;
|
||||
-ms-flex-pack: justify;
|
||||
justify-content: space-between;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.header-popup {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.header-button-container {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
}
|
||||
|
||||
|
||||
.button-lang {
|
||||
background: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
padding: 10px 14px;
|
||||
}
|
||||
|
||||
|
||||
.button-lang:hover {
|
||||
background: #23242A;
|
||||
}
|
||||
|
||||
.button-lang-active {
|
||||
cursor: pointer;
|
||||
pointer-events: none;
|
||||
background: #2E3038;
|
||||
|
||||
}
|
||||
|
||||
.header__buttons_wrapper {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@@ -35,73 +56,48 @@
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
width: 31px;
|
||||
height: 50px;
|
||||
width: 104px;
|
||||
height: 40px;
|
||||
|
||||
}
|
||||
|
||||
.header-buttons {
|
||||
margin-right: 96px;
|
||||
}
|
||||
|
||||
.header-button {
|
||||
font-family: "GilroyWebRegular";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
line-height: 125%;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
color: #ffffff;
|
||||
cursor: pointer;
|
||||
padding: 0px;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.header-lang-button-text:hover {
|
||||
background: rgba(235, 235, 235, 0.2);
|
||||
|
||||
}
|
||||
|
||||
.wrapper__button {
|
||||
margin: 0;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.header-lang-button {
|
||||
position: absolute;
|
||||
right: 40px;
|
||||
top: 40px;
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
width: 58px;
|
||||
padding: 5px 12px;
|
||||
-webkit-box-sizing: border-box;
|
||||
width: 55px;
|
||||
padding: 6px 8px 5px 12px;
|
||||
box-sizing: border-box;
|
||||
height: 31px;
|
||||
-webkit-box-pack: justify;
|
||||
-ms-flex-pack: justify;
|
||||
height: 29px;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
line-height: 13px;
|
||||
background-color: transparent;
|
||||
border: 1.2px solid #ebebeb;
|
||||
border: 2px solid #ebebeb;
|
||||
border-radius: 12px;
|
||||
-webkit-transition: height ease-in 0.3s;
|
||||
-o-transition: height ease-in 0.3s;
|
||||
transition: height ease-in 0.3s;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 15px;
|
||||
line-height: 130%;
|
||||
transition: height ease-in 0.5s;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.header-lang-button_disabled {
|
||||
@@ -109,7 +105,7 @@
|
||||
}
|
||||
|
||||
.header-lang-button_active {
|
||||
height: 53px;
|
||||
height: 51px;
|
||||
}
|
||||
|
||||
.header-lang-button_active {
|
||||
@@ -117,8 +113,8 @@
|
||||
}
|
||||
|
||||
.header-lang-button-text {
|
||||
|
||||
width: 100%;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
background-color: transparent;
|
||||
color: #ebebeb;
|
||||
@@ -126,54 +122,29 @@
|
||||
text-align: left;
|
||||
margin: 0;
|
||||
border: none;
|
||||
height: 15px;
|
||||
height: 13px;
|
||||
-webkit-appearance: none;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 15px;
|
||||
line-height: 130%;
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.header-lang-button-picked {
|
||||
width: 100%;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
background-color: transparent;
|
||||
color: #ebebeb;
|
||||
padding: 0;
|
||||
text-align: left;
|
||||
margin: 0;
|
||||
border: none;
|
||||
height: 100%;
|
||||
-webkit-appearance: none;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 15px;
|
||||
line-height: 130%;
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.header-select__icon {
|
||||
top: 6px;
|
||||
height: 16px;
|
||||
height: 13px;
|
||||
right: 5px;
|
||||
position: absolute;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.select {
|
||||
background-color: transparent;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-ms-flex-item-align: center;
|
||||
-ms-grid-row-align: center;
|
||||
align-self: center;
|
||||
gap: 11px;
|
||||
position: relative;
|
||||
@@ -187,9 +158,10 @@
|
||||
.option {
|
||||
/* or 16px */
|
||||
|
||||
|
||||
/* Landing/White */
|
||||
|
||||
color: #ebebeb;
|
||||
color: #EBEBEB;
|
||||
}
|
||||
|
||||
.burger__button {
|
||||
@@ -197,34 +169,31 @@
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
display: none;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
|
||||
}
|
||||
|
||||
.line__burger {
|
||||
background-color: #ffffff;
|
||||
background-color: #FFFFFF;
|
||||
width: 14px;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1600px) {
|
||||
.header-container {
|
||||
.header {
|
||||
padding: 35px 48px;
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
width: 46px;
|
||||
height: 74px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.header-button {
|
||||
font-size: 20px;
|
||||
|
||||
}
|
||||
|
||||
.header-lang-button_active {
|
||||
height: auto;
|
||||
|
||||
}
|
||||
|
||||
.header-buttons {
|
||||
@@ -232,45 +201,58 @@
|
||||
}
|
||||
|
||||
.header-lang-button {
|
||||
width: 70px;
|
||||
padding: 7px 15px;
|
||||
top: 57px;
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 1279px) {
|
||||
.header-container {
|
||||
.header {
|
||||
padding: 30px 12px;
|
||||
}
|
||||
|
||||
.header-lang-button {
|
||||
top: 40px;
|
||||
right: 12px;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1024px) {
|
||||
.header-container {
|
||||
.header {
|
||||
padding: 15px 12px;
|
||||
}
|
||||
|
||||
.header-lang-button {
|
||||
right: 12px;
|
||||
top: 26px;
|
||||
top: 25%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 639px) {
|
||||
.header-container {
|
||||
|
||||
.header-logo {
|
||||
width: 94px;
|
||||
height: 36px;
|
||||
|
||||
}
|
||||
|
||||
.header-popup {
|
||||
position: static;
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: 8px 10px;
|
||||
}
|
||||
|
||||
.header-buttons {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.burger__button {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,106 +1,39 @@
|
||||
import React, { CSSProperties, useState } from "react";
|
||||
import "./Header.css";
|
||||
|
||||
import logo from "./logoIcon.svg";
|
||||
import chevron from "./chevronIcon.svg";
|
||||
import "./header.css";
|
||||
import "../../styles/styles.css";
|
||||
import iconClose from './closeIcon1.svg'
|
||||
import { Nav } from "../Navigaton/navigation";
|
||||
import { useLocation, useHistory } from "react-router-dom";
|
||||
import ru from './RU.svg'
|
||||
import en from './EN.svg'
|
||||
|
||||
import { useAppSelector, useAppDispatch } from "../../hooks/redux";
|
||||
import { languageSlice } from "../../store/reducers/languageSlice";
|
||||
|
||||
import { useLocation } from "react-router-dom";
|
||||
|
||||
|
||||
export type THeader = {
|
||||
language: string;
|
||||
changeLanguage: (language: string) => void;
|
||||
text?: any;
|
||||
};
|
||||
|
||||
export const Header: React.FC<THeader> =
|
||||
({ changeLanguage, language, text }) => {
|
||||
const [open, setOpen] = useState<boolean>(false)
|
||||
const [menuOpen, setMenuOpen] = useState(false)
|
||||
const [opacity, setOpacity] = useState(false)
|
||||
const userLanguage = language === 'RU';
|
||||
export const Header: React.FC = ({ }) => {
|
||||
const buttons = [{
|
||||
icon: ru, value: "ru"
|
||||
}, { icon: en, value: "en" }]
|
||||
const location = useLocation();
|
||||
|
||||
const location = useLocation()
|
||||
const history = useHistory()
|
||||
console.log(location, 'loc')
|
||||
|
||||
function handleUpdateLanguage(value: string) {
|
||||
changeLanguage(value)
|
||||
setOpen(prev => !prev)
|
||||
}
|
||||
|
||||
function handleOpen() {
|
||||
setOpen(prev => !prev)
|
||||
}
|
||||
|
||||
function handleOpacity() {
|
||||
setOpacity(true)
|
||||
}
|
||||
|
||||
const style = {
|
||||
background: 'rgba(235, 235, 235, 0.2'
|
||||
};
|
||||
|
||||
const iconTransform = {
|
||||
transform: 'rotate(-90deg)'
|
||||
} as CSSProperties
|
||||
|
||||
const setBackground = opacity && !open as boolean;
|
||||
|
||||
function setOpacityAndMenu() {
|
||||
setMenuOpen(true)
|
||||
const targetElement = document.querySelector('body') as HTMLElement
|
||||
targetElement.style.overflow = 'hidden'
|
||||
}
|
||||
const { handleChangeLanguage } = languageSlice.actions;
|
||||
const { currentLang } = useAppSelector((state) => state.languageReducer);
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
|
||||
function openMenu() {
|
||||
setMenuOpen(false)
|
||||
const targetElement = document.querySelector('body') as HTMLElement
|
||||
targetElement.style.overflow = 'visible'
|
||||
|
||||
}
|
||||
|
||||
function goBack() {
|
||||
if (location.pathname === '/demos') {
|
||||
history.goBack()
|
||||
} else {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="header">
|
||||
<div className="header-container">
|
||||
<img onClick={goBack} className="header-logo" alt="company-logo" src={logo} />
|
||||
<div className="header-buttons">
|
||||
<div className="header__buttons_wrapper">
|
||||
<a target='_blank' rel="noreferrer" href={userLanguage ? 'https://graff.tech/contacts/' : 'http://en.graff.tech/contactseng' } className="header-button">{text.captionContact}</a>
|
||||
<a target='_blank' rel="noreferrer" href={userLanguage ? 'https://graff.tech/' : 'http://en.graff.tech/' } className="header-button">{text.captionCompain}</a>
|
||||
</div>
|
||||
<div className={open ? "header-lang-button header-lang-button_active" : 'header-lang-button header-lang-button_disabled'} style={setBackground ? style : { background: 'transparent' }}>
|
||||
<img alt="img" src={chevron} className="header-select__icon" style={open ? iconTransform : {
|
||||
transform: 'rotate(0deg)'
|
||||
}}></img>
|
||||
<div className="wrapper__button">
|
||||
<button onMouseEnter={handleOpacity} onMouseLeave={() => setOpacity(false)} onClick={handleOpen} className=" header-lang-button-picked">{language}</button>
|
||||
</div>
|
||||
{language === 'RU' ? (<button value={'EN'} onClick={(e: any) => handleUpdateLanguage(e.target.value)} className="header-lang-button-text">EN</button>
|
||||
) : (<button onClick={(e: any) => handleUpdateLanguage(e.target.value)} value={'RU'} className="header-lang-button-text">RU</button>)}
|
||||
</div>
|
||||
</div>
|
||||
{menuOpen ? <img alt="iconClose" src={iconClose} onClick={openMenu} className='nav__close'></img>
|
||||
:
|
||||
<button onClick={setOpacityAndMenu} className="burger__button">
|
||||
<span className="line__burger"></span>
|
||||
<span className="line__burger"></span>
|
||||
<span className="line__burger"></span>
|
||||
</button>}
|
||||
</div>
|
||||
<Nav text={text} setOpacity={setOpacity} language={language} menuOpen={menuOpen} setOpen={setMenuOpen} changeLanguage={changeLanguage}></Nav>
|
||||
return (
|
||||
<header className={location.pathname === '/' ? 'header' : 'header header-popup'}>
|
||||
<a className="header-logo" target='_blank' href="https://estate.graff.tech/" style={{ cursor: "pointer" }}><img alt="company-logo" src={logo} />
|
||||
</a>
|
||||
<div className="header-button-container">
|
||||
{buttons.map((item, index) => (<button key={index} onClick={() => dispatch(handleChangeLanguage(item.value))} value={item.value} className={currentLang === item.value ? 'button-lang button-lang-active' : "button-lang"}><img src={item.icon}></img></button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
</header>
|
||||
);
|
||||
};
|
||||
@@ -12,6 +12,7 @@ import { Demos } from "../demos/demos";
|
||||
import { PhotoComponent } from "../photoComponent/photoComponent";
|
||||
import { CalendarMobile } from "../calendarMobile/calendarMobile";
|
||||
import moment, { Moment } from "moment";
|
||||
|
||||
import useScreenSize from 'use-screen-size'
|
||||
|
||||
|
||||
@@ -28,7 +29,7 @@ export type TText = {
|
||||
text: object,
|
||||
}
|
||||
|
||||
export const Main: React.FC<any> = ({ text, locale }) => {
|
||||
export const Main: React.FC<any> = ({ locale, cards }) => {
|
||||
|
||||
const { width } = useScreenSize()
|
||||
const [displayForm, setDisplayForm] = useState(true);
|
||||
@@ -78,14 +79,15 @@ export const Main: React.FC<any> = ({ text, locale }) => {
|
||||
})
|
||||
setDisplayForm(true)
|
||||
}
|
||||
|
||||
return (
|
||||
<main className="main">
|
||||
<AnimationComponent text={text.title} />
|
||||
<SliderComponent text={text.slider} />
|
||||
<AnimationComponent />
|
||||
<SliderComponent />
|
||||
<div className="calendar__mobile">
|
||||
<CalendarMobile
|
||||
locale={locale}
|
||||
text={text.calendar}
|
||||
text={'calendar'}
|
||||
setDisplayForm={setDisplayForm}
|
||||
displayForm={displayForm}
|
||||
setOpen={navigationHandler}
|
||||
@@ -99,7 +101,7 @@ export const Main: React.FC<any> = ({ text, locale }) => {
|
||||
<div className="calendar__desktop">
|
||||
<CalendarDesktop
|
||||
locale={locale}
|
||||
text={text.calendar}
|
||||
text={'calendar'}
|
||||
setDisplayForm={setDisplayForm}
|
||||
displayForm={displayForm}
|
||||
setOpen={navigationHandler}
|
||||
@@ -110,13 +112,13 @@ export const Main: React.FC<any> = ({ text, locale }) => {
|
||||
isMobile={isMobile}
|
||||
></CalendarDesktop>
|
||||
</div>
|
||||
<Multiplayer text={text.multiplayer} />
|
||||
<Devices text={text.devices} />
|
||||
<PhotoComponent text={text.photoComponent} />
|
||||
<Player text={text.player} />
|
||||
<Analytics text={text.analytics} />
|
||||
<CloudSolution text={text.cloudSolution} />
|
||||
<Demos text={text.demos} />
|
||||
<Multiplayer text={'multiplayer'} />
|
||||
<Devices text={'devices'} />
|
||||
<PhotoComponent text={'photoComponent'} />
|
||||
<Player text={'player'} />
|
||||
<Analytics text={'analytics'} />
|
||||
<CloudSolution text={'analytics'} />
|
||||
<Demos cards={cards} />
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
.multiplayer__container {
|
||||
background: #141414;
|
||||
background: #1C1D21;
|
||||
border-radius: 32px;
|
||||
padding: 120px 32px 80px;
|
||||
margin-bottom: 160px;
|
||||
|
||||
@@ -7,16 +7,18 @@ import photo3 from "./Photo3.png";
|
||||
import { Button } from "../buttonDemo/buttonDemo"
|
||||
import { Content } from "../content/content";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export const Multiplayer: React.FC<any> = ({text}) => {
|
||||
const [captionSmall, setCaptionSmall] = useState(true);
|
||||
const {t} = useTranslation()
|
||||
return (
|
||||
<div
|
||||
data-aos="zoom-in"
|
||||
data-aos-duration="400"
|
||||
className="multiplayer__container"
|
||||
>
|
||||
<Content captionSmall={captionSmall} text={text}></Content>
|
||||
<Content isColor={false} captionSmall={captionSmall} text={text}></Content>
|
||||
<div className="multiplayer__photo-container">
|
||||
<img alt="device" src={photo1} className="multiplayer__image" />
|
||||
<img alt="device" src={photo} className="multiplayer__image" />
|
||||
@@ -25,7 +27,7 @@ export const Multiplayer: React.FC<any> = ({text}) => {
|
||||
</div>
|
||||
<div className="main-block__subblock-container">
|
||||
<div className={captionSmall ? " main-block__caption_small main-block_subblock " : 'main-block_subblock'}>
|
||||
{text.mainBlockSubblock}
|
||||
{t(`${text}-mainBlockSubblock`)}
|
||||
<Button text={text}></Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
*/
|
||||
|
||||
.player__container {
|
||||
background: #141414;
|
||||
border-radius: 32px;
|
||||
background: #1C1D21; border-radius: 32px;
|
||||
padding: 120px 32px 80px;
|
||||
margin-bottom: 80px;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
|
||||
background: #141414;
|
||||
background: #1C1D21;
|
||||
border-radius: 32px;
|
||||
padding-top: 120px;
|
||||
padding-bottom: 85px;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import React from "react";
|
||||
import "./sliderComponent.css";
|
||||
import "../../styles/styles.css"
|
||||
import Swiper from "../swiper/swiper";
|
||||
import Swiper from "../swiper/swiper"
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const SliderComponent: React.FC<any> = React.memo(({ text }) => {
|
||||
export const SliderComponent: React.FC<any> = () => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<div data-aos="zoom-in" data-aos-duration="500" className="slider-container">
|
||||
<div className="slider">
|
||||
@@ -15,14 +17,13 @@ export const SliderComponent: React.FC<any> = React.memo(({ text }) => {
|
||||
<p className="main-block__title_gardient title__gardient_pos">stream</p>
|
||||
</div>
|
||||
<p className=" main-block__caption_color main-block__caption_color_slider">
|
||||
{text.mainBlockCaptionColor}
|
||||
{t('slider-mainBlockCaptionColor')}
|
||||
</p>
|
||||
<p className="main-block__caption_l">{text.mainBlockCaption}</p>
|
||||
<p className="main-block__caption_l">{t('slider-mainBlockCaption')}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Swiper
|
||||
text={text}
|
||||
slidesPerView={'2'}
|
||||
centeredSlides={false}
|
||||
spaceBetween={0}
|
||||
@@ -34,4 +35,4 @@ export const SliderComponent: React.FC<any> = React.memo(({ text }) => {
|
||||
></Swiper>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M23 12H1M1 12L8.2 5M1 12L8.2 19" stroke="#F2F2F2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 228 B |
|
Before Width: | Height: | Size: 215 B After Width: | Height: | Size: 215 B |
@@ -10,6 +10,29 @@
|
||||
width: 536px;
|
||||
}
|
||||
|
||||
.button__arrow_l {
|
||||
cursor: pointer;
|
||||
background-image: url(./Arrow_Left.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
height: 14px;
|
||||
width: 22px;
|
||||
}
|
||||
|
||||
.button__arrow_r {
|
||||
-webkit-transform: matrix(-1, 0, 0, 1, 0, 0);
|
||||
-ms-transform: matrix(-1, 0, 0, 1, 0, 0);
|
||||
transform: matrix(-1, 0, 0, 1, 0, 0);
|
||||
|
||||
cursor: pointer;
|
||||
background-image: url(./Arrow_Left.svg);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
height: 14px;
|
||||
width: 22px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -81,7 +104,7 @@
|
||||
color: #ebebeb;
|
||||
|
||||
display: flex;
|
||||
color: #ebebeb !important;
|
||||
color: #F2F2F2 !important;
|
||||
}
|
||||
|
||||
.swiper__caption {
|
||||
|
||||
@@ -15,6 +15,7 @@ import "swiper/css";
|
||||
import "swiper/css/pagination";
|
||||
import "swiper/css/navigation";
|
||||
import "../calendar/calendar";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
type propsTypes = {
|
||||
slidesPerView: string;
|
||||
@@ -24,17 +25,18 @@ type propsTypes = {
|
||||
className: string;
|
||||
children: React.ReactNode;
|
||||
rewind: boolean;
|
||||
text: any;
|
||||
slideToClickedSlide: boolean,
|
||||
};
|
||||
|
||||
export default function SwiperCentred(props: propsTypes) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const size = useScreenSize();
|
||||
const [caption, setCaption] = useState<any>();
|
||||
|
||||
useEffect(() => {
|
||||
setCaption(props.text.subtitle1);
|
||||
}, [props.text]);
|
||||
setCaption(t('slider-subtitle1'));
|
||||
}, [t]);
|
||||
|
||||
function updateCaption() {
|
||||
const slide = document
|
||||
@@ -82,8 +84,8 @@ export default function SwiperCentred(props: propsTypes) {
|
||||
<SwiperSlide style={swiperWidth()}>
|
||||
{({ isActive }) => (
|
||||
<img
|
||||
data-caption={props.text.subtitle}
|
||||
className={isActive ? "image__slider_active" : "image__slider"}
|
||||
data-caption={t('slider-subtitle')}
|
||||
className={isActive ? "image__slider_active" : "image__slider"}
|
||||
src={img1}
|
||||
alt="slide"
|
||||
/>
|
||||
@@ -92,7 +94,7 @@ export default function SwiperCentred(props: propsTypes) {
|
||||
<SwiperSlide style={swiperWidth()}>
|
||||
{({ isActive }) => (
|
||||
<img
|
||||
data-caption={props.text.subtitle1}
|
||||
data-caption={t('slider-subtitle1')}
|
||||
className={isActive ? "image__slider_active" : "image__slider"}
|
||||
src={img}
|
||||
alt="slide"
|
||||
@@ -102,8 +104,8 @@ export default function SwiperCentred(props: propsTypes) {
|
||||
<SwiperSlide style={swiperWidth()}>
|
||||
{({ isActive }) => (
|
||||
<img
|
||||
data-caption={props.text.subtitle2}
|
||||
className={isActive ? "image__slider_active" : "image__slider"}
|
||||
data-caption={t('slider-subtitle2')}
|
||||
className={isActive ? "image__slider_active" : "image__slider"}
|
||||
src={img2}
|
||||
alt="slide"
|
||||
/>
|
||||
@@ -112,8 +114,8 @@ export default function SwiperCentred(props: propsTypes) {
|
||||
<SwiperSlide style={swiperWidth()}>
|
||||
{({ isActive }) => (
|
||||
<img
|
||||
data-caption={props.text.subtitle3}
|
||||
className={isActive ? "image__slider_active" : "image__slider"}
|
||||
data-caption={t('slider-subtitle3')}
|
||||
className={isActive ? "image__slider_active" : "image__slider"}
|
||||
src={img3}
|
||||
alt="slide"
|
||||
/>
|
||||
|
||||
@@ -7,6 +7,7 @@ import point0 from "../calendar/Ellipse0.svg";
|
||||
import point1 from "../calendar/Ellipse1.svg";
|
||||
import { TProps } from "../calendarDesktop/calendarDesktop";
|
||||
import { useSwiper } from 'swiper/react';
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +17,6 @@ export const Timepicker: React.FC<TProps> = ({
|
||||
open,
|
||||
setOpen,
|
||||
isMobile,
|
||||
text
|
||||
}) => {
|
||||
|
||||
|
||||
@@ -84,16 +84,18 @@ export const Timepicker: React.FC<TProps> = ({
|
||||
}
|
||||
}
|
||||
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div data-aos="fade-up" className={open.timePicker ? " calendar aos-init aos-animate" : "calendar aos-init aos-animate"}>
|
||||
<div className={open.timePicker ? 'opacity_active' : 'opacity'}>
|
||||
<div className="timepicker__header">
|
||||
<div className="caption__container">
|
||||
<div onClick={() => goBack()} className="button__arrow_back" ></div>
|
||||
<span className="calendar__caption">{text.timepickerCaption}</span>
|
||||
<span className="calendar__caption">{t('timepickerCaption')}</span>
|
||||
</div>
|
||||
<div className="line line_time"></div>
|
||||
<div className="date date_time">{!open.calendar ? time.format("DD MMMM") : '' }</div>
|
||||
<div className="date date_time">{!open.calendar ? time.format("DD MMMM") : ''}</div>
|
||||
</div>
|
||||
<div className="form__block">
|
||||
{timePicker.map((date, i) => (
|
||||
@@ -114,11 +116,11 @@ export const Timepicker: React.FC<TProps> = ({
|
||||
<div className="appointment__block appointment__block_time">
|
||||
<div>
|
||||
<img alt="point" className="point" src={point1}></img>
|
||||
<span className="appointment__caption_active">{text.appointmentTrue}</span>
|
||||
<span className="appointment__caption_active">{t('appointmentTrue')}</span>
|
||||
</div>
|
||||
<div>
|
||||
<img alt="point" className="point" src={point0}></img>
|
||||
<span>{text.appointmentFalse}</span>
|
||||
<span>{t('appointmentFalse')}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import { useDispatch, useSelector, TypedUseSelectorHook } from "react-redux";
|
||||
import { AppDispatch, RootState } from "../store/store";
|
||||
|
||||
export const useAppDispatch = () => useDispatch<AppDispatch>();
|
||||
|
||||
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
|
||||
@@ -0,0 +1,5 @@
|
||||
import { useLocation } from "react-router";
|
||||
|
||||
const useQuery = () => new URLSearchParams(useLocation().search);
|
||||
|
||||
export default useQuery
|
||||
@@ -5,7 +5,7 @@
|
||||
@import url(./components/cloudSolution/cloudSolution.css);
|
||||
@import url(./components/devices/devices.css);
|
||||
@import url(./components/form/form.css);
|
||||
@import url(./components/header/header.css);
|
||||
@import url(./components/header/Header.css);
|
||||
@import url(./components/multiplayer/multiplayer.css);
|
||||
@import url(./components/player/player.css);
|
||||
@import url(./components/sliderComponent/sliderComponent.css);
|
||||
@@ -28,7 +28,7 @@ body {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
background: #0e0e0e;
|
||||
background: #151619;
|
||||
width: 100%;
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,34 @@ import './index.css';
|
||||
import App from './App';
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import { Provider } from "react-redux";
|
||||
import { setupStore } from "./store/store";
|
||||
import i18next from "i18next";
|
||||
import { initReactI18next } from "react-i18next";
|
||||
import HttpApi from "i18next-http-backend";
|
||||
import LanguageDetector from "i18next-browser-languagedetector";
|
||||
|
||||
|
||||
const store = setupStore();
|
||||
|
||||
i18next
|
||||
.use(HttpApi)
|
||||
.use(LanguageDetector)
|
||||
.use(initReactI18next)
|
||||
.init({
|
||||
supportedLngs: ["en", "ru"],
|
||||
fallbackLng: "en",
|
||||
debug: false,
|
||||
// Options for language detector
|
||||
detection: {
|
||||
order: ["cookie", "navigator"],
|
||||
caches: ["cookie"],
|
||||
},
|
||||
// react: { useSuspense: false },
|
||||
backend: {
|
||||
loadPath: "/assets/locales/{{lng}}/translation.json",
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
const root = ReactDOM.createRoot(
|
||||
@@ -10,8 +38,10 @@ const root = ReactDOM.createRoot(
|
||||
|
||||
);
|
||||
root.render(
|
||||
<BrowserRouter basename='/streaming-landing'>
|
||||
<App />
|
||||
<BrowserRouter>
|
||||
<Provider store={store}>
|
||||
<App />
|
||||
</Provider>
|
||||
</BrowserRouter>
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
export interface ICards {
|
||||
app_title: string;
|
||||
title: string;
|
||||
language: string;
|
||||
location: string;
|
||||
feature_description: string;
|
||||
icon: string;
|
||||
logo: string;
|
||||
preview: string;
|
||||
_id: string;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface IData {
|
||||
link: string;
|
||||
connection_code: string;
|
||||
msg: string,
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||
import axios from 'axios';
|
||||
|
||||
const instance = axios.create({
|
||||
baseURL: 'https://a1.coord.graff.tech',
|
||||
});
|
||||
|
||||
instance.defaults.headers.post['Content-Type'] = 'application/json';
|
||||
|
||||
|
||||
|
||||
export const fetchCards = createAsyncThunk(
|
||||
"cards/FetchAll",
|
||||
async (language: string, thunkApi) => {
|
||||
try {
|
||||
const { data } = await instance.get('/title/get_for_language/', { params: { start: 0, count: 100, language: language } });
|
||||
return data;
|
||||
} catch (e: any) {
|
||||
const { response } = e
|
||||
if (!response) {
|
||||
return thunkApi.rejectWithValue('Произошла ошибка, попробуйте позже');
|
||||
|
||||
} else {
|
||||
return thunkApi.rejectWithValue(response.data.message);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
export const createSession = createAsyncThunk(
|
||||
"session/Create",
|
||||
async (title: string, thunkApi) => {
|
||||
try {
|
||||
const { data } = await instance.post('/session/create', { title });
|
||||
return data;
|
||||
} catch (e: any) {
|
||||
const { response } = e
|
||||
if (!response) {
|
||||
return thunkApi.rejectWithValue('Произошла ошибка, попробуйте позже');
|
||||
|
||||
} else {
|
||||
return thunkApi.rejectWithValue(response.data.message);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export const connectSession = createAsyncThunk(
|
||||
"session/Connect",
|
||||
async (code: string, thunkApi) => {
|
||||
try {
|
||||
const { data } = await instance.get('/session/connect', { params: { session_id: code } });
|
||||
return data;
|
||||
} catch (e: any) {
|
||||
const { response } = e
|
||||
if (!response) {
|
||||
return thunkApi.rejectWithValue('Произошла ошибка, попробуйте позже');
|
||||
|
||||
} else {
|
||||
return thunkApi.rejectWithValue(response.data.message);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,45 @@
|
||||
import { ICards } from "../../models/ICards";
|
||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||
import { fetchCards } from "./ActionCreator";
|
||||
|
||||
interface CardState {
|
||||
cards: ICards[];
|
||||
isLoading: boolean;
|
||||
error: any;
|
||||
currentCard: ICards | null;
|
||||
}
|
||||
const initialState: CardState = {
|
||||
cards: [],
|
||||
isLoading: false,
|
||||
error: "",
|
||||
currentCard: null,
|
||||
};
|
||||
|
||||
export const cardSlice = createSlice({
|
||||
name: "cards",
|
||||
initialState,
|
||||
reducers: {
|
||||
handleCurrentCard(state, action: PayloadAction<ICards>) {
|
||||
state.currentCard = action.payload;
|
||||
},
|
||||
},
|
||||
extraReducers: {
|
||||
|
||||
[fetchCards.fulfilled.type]: (state, action: PayloadAction<ICards[]>) => {
|
||||
state.isLoading = false;
|
||||
state.error = "";
|
||||
state.cards = action.payload;
|
||||
},
|
||||
[fetchCards.pending.type]: (state) => {
|
||||
state.isLoading = true;
|
||||
},
|
||||
[fetchCards.rejected.type]: (state, action: PayloadAction<any>) => {
|
||||
console.log(action.payload)
|
||||
state.isLoading = false;
|
||||
state.error = action.payload;
|
||||
},
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
export default cardSlice.reducer;
|
||||
@@ -0,0 +1,50 @@
|
||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||
import i18next from "i18next";
|
||||
import { initReactI18next } from "react-i18next";
|
||||
import HttpApi from "i18next-http-backend";
|
||||
import cookies from "js-cookie";
|
||||
import LanguageDetector from "i18next-browser-languagedetector";
|
||||
|
||||
i18next
|
||||
.use(HttpApi)
|
||||
.use(LanguageDetector)
|
||||
.use(initReactI18next)
|
||||
.init({
|
||||
supportedLngs: ["en", "ru"],
|
||||
fallbackLng: "en",
|
||||
debug: false,
|
||||
// Options for language detector
|
||||
detection: {
|
||||
order: ["cookie", "navigator"],
|
||||
caches: ["cookie"],
|
||||
},
|
||||
// react: { useSuspense: false },
|
||||
backend: {
|
||||
loadPath: "/assets/locales/{{lng}}/translation.json",
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
||||
interface LanguageState {
|
||||
currentLang: string;
|
||||
}
|
||||
|
||||
const initialState: LanguageState = {
|
||||
currentLang: '',
|
||||
};
|
||||
|
||||
export const languageSlice = createSlice({
|
||||
name: "language",
|
||||
initialState,
|
||||
reducers: {
|
||||
handleChangeLanguage(state, action: PayloadAction<string>) {
|
||||
i18next.changeLanguage(action.payload)
|
||||
state.currentLang = action.payload
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
export default languageSlice.reducer;
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
import { IData } from "../../models/IData";
|
||||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||
import { createSession, connectSession } from "./ActionCreator";
|
||||
|
||||
export interface sessionState {
|
||||
isLoading: boolean;
|
||||
error: any;
|
||||
url: string;
|
||||
id: string;
|
||||
playerCount: any
|
||||
}
|
||||
|
||||
interface ConnectSessionResponseInterface {
|
||||
websocket_url: string;
|
||||
}
|
||||
|
||||
interface CreateSessionResponseInterface {
|
||||
session_id: string;
|
||||
}
|
||||
|
||||
const initialState: sessionState = {
|
||||
isLoading: false,
|
||||
error: null,
|
||||
url: "",
|
||||
id: "",
|
||||
playerCount: [],
|
||||
};
|
||||
|
||||
export const sessionSlice = createSlice({
|
||||
name: "data",
|
||||
initialState,
|
||||
reducers: {
|
||||
cleanErrors(state) {
|
||||
state = initialState
|
||||
},
|
||||
|
||||
setUserCount(state, action) {
|
||||
console.log(action.payload)
|
||||
const newArr = new Array(action.payload).fill('user')
|
||||
state.playerCount = newArr
|
||||
}
|
||||
},
|
||||
extraReducers: {
|
||||
[createSession.fulfilled.type]: (
|
||||
state,
|
||||
action: PayloadAction<CreateSessionResponseInterface>
|
||||
) => {
|
||||
state.isLoading = false;
|
||||
state.id = action.payload.session_id;
|
||||
},
|
||||
[createSession.rejected.type]: (state, action: PayloadAction<any>) => {
|
||||
state.isLoading = false;
|
||||
state.error = action.payload;
|
||||
},
|
||||
[createSession.pending.type]: (state) => {
|
||||
state.isLoading = true;
|
||||
},
|
||||
[connectSession.fulfilled.type]: (
|
||||
state,
|
||||
action: PayloadAction<ConnectSessionResponseInterface>
|
||||
) => {
|
||||
state.isLoading = false;
|
||||
const url = action.payload.websocket_url;
|
||||
state.url = url;
|
||||
},
|
||||
[connectSession.rejected.type]: (state, action: PayloadAction<any>) => {
|
||||
state.isLoading = false;
|
||||
state.error = action.payload;
|
||||
},
|
||||
[connectSession.pending.type]: (state, action) => {
|
||||
state.isLoading = true;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default sessionSlice.reducer;
|
||||
@@ -0,0 +1,25 @@
|
||||
import { combineReducers, configureStore } from "@reduxjs/toolkit";
|
||||
|
||||
import cardReducer from "./reducers/cardSlice";
|
||||
import sessionReducer from "./reducers/sessionSlice";
|
||||
import languageReducer from "./reducers/languageSlice";
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
cardReducer,
|
||||
sessionReducer,
|
||||
languageReducer,
|
||||
});
|
||||
|
||||
export const setupStore = () => {
|
||||
return configureStore({
|
||||
reducer: rootReducer,
|
||||
middleware: (getDefaultMiddleware) =>
|
||||
getDefaultMiddleware({ serializableCheck: false }),
|
||||
});
|
||||
};
|
||||
|
||||
export type RootState = ReturnType<typeof rootReducer>;
|
||||
|
||||
export type AppStore = ReturnType<typeof setupStore>;
|
||||
|
||||
export type AppDispatch = AppStore["dispatch"];
|
||||
@@ -38,7 +38,7 @@
|
||||
font-size: 18px;
|
||||
line-height: 140%;
|
||||
margin: 0;
|
||||
color: #ebebeb;
|
||||
color: #F2F2F2;
|
||||
}
|
||||
|
||||
.main-block__subblock-container {
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
/* Landing/White */
|
||||
|
||||
color: #ebebeb;
|
||||
color: #F2F2F2;
|
||||
}
|
||||
|
||||
.main-block__title {
|
||||
@@ -84,7 +84,7 @@
|
||||
font-weight: 400;
|
||||
font-size: 64px;
|
||||
line-height: 100%;
|
||||
color: #ebebeb;
|
||||
color: #F2F2F2;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 100%;
|
||||
color: #ebebeb;
|
||||
color: #F2F2F2;
|
||||
margin: 0;
|
||||
font-size: 40px;
|
||||
}
|
||||
@@ -133,7 +133,7 @@
|
||||
font-size: 18px;
|
||||
line-height: 140%;
|
||||
margin: 20px 0 0 0;
|
||||
color: #ebebeb;
|
||||
color: #F2F2F2;
|
||||
}
|
||||
|
||||
.main-block__caption_color {
|
||||
@@ -191,7 +191,7 @@
|
||||
border: 1px solid #454545;
|
||||
border-radius: 32px;
|
||||
background-color: transparent;
|
||||
color: #ebebeb;
|
||||
color: #F2F2F2;
|
||||
cursor: pointer;
|
||||
}
|
||||
.main-block__icon {
|
||||
|
||||