first commit
@@ -0,0 +1,5 @@
|
||||
.analytics__container {
|
||||
background: #141414;
|
||||
border-radius: 32px;
|
||||
padding: 120px 32px 80px;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import "../../styles/styles.css";
|
||||
import "../multiplayer/multiplayer.css";
|
||||
import "./analytics.css"
|
||||
|
||||
export const Analytics: React.FC = ({}) => {
|
||||
return (
|
||||
<div className="analytics__container">
|
||||
<div className="main-block__container">
|
||||
<div>
|
||||
<p className="main-block__title main-block__title_small">
|
||||
Graff.estate stream{" "}
|
||||
</p>
|
||||
<p className="main-block__title_gardient main-block__title_gardient_small">
|
||||
передать на устройство пользователя впечатляющий уровень графики.{" "}
|
||||
</p>
|
||||
</div>
|
||||
<p className="main-block__caption multiplayer__caption">
|
||||
Для работы с интерактивной презентацией покупателю достаточно
|
||||
смартфона и мобильного интернета.
|
||||
</p>
|
||||
</div>
|
||||
</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="#EBEBEB" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 211 B |
@@ -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="M1 12H23M23 12L15.8 5M23 12L15.8 19" stroke="#EBEBEB" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 215 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="4" cy="4" r="4" fill="#EBEBEB"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 144 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="4" cy="4" r="4" fill="#567ECE"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 144 B |
@@ -0,0 +1,232 @@
|
||||
.title_small {
|
||||
font-size: 40px;
|
||||
}
|
||||
.button__arrow_back {
|
||||
cursor: pointer;
|
||||
}
|
||||
.point {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.caption {
|
||||
font-size: 14px;
|
||||
}
|
||||
.appointment__block {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 24px;
|
||||
margin-top: 16px;
|
||||
font-family: "Gilroy";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 12px;
|
||||
line-height: 130%;
|
||||
|
||||
}
|
||||
.calendar__container {
|
||||
padding-top: 160px;
|
||||
margin-bottom: 160px;
|
||||
}
|
||||
|
||||
.appointment__caption_active {
|
||||
color: #567ECE;
|
||||
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
background-color: #454545;
|
||||
height: 1px;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 21px;
|
||||
}
|
||||
|
||||
.calendar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
color: #ebebeb;
|
||||
box-sizing: border-box;
|
||||
width: 385px;
|
||||
background: #141414;
|
||||
border-radius: 16px;
|
||||
padding: 24px 32px;
|
||||
box-sizing: border-box;
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
transition: opacity ease-in 0.5s;
|
||||
}
|
||||
|
||||
.calendar_active {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: #ebebeb;
|
||||
box-sizing: border-box;
|
||||
width: 385px;
|
||||
background: #141414;
|
||||
border-radius: 16px;
|
||||
padding: 24px 32px;
|
||||
box-sizing: border-box;
|
||||
opacity: 1;
|
||||
transition: opacity ease-in 0.5s;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1152px) {
|
||||
.calendar {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.caption__container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 17px;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 25px;
|
||||
margin-bottom: 80px;
|
||||
}
|
||||
|
||||
.calendar__header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.calendar__caption {
|
||||
font-family: "Gilroy";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 18px;
|
||||
line-height: 140%;
|
||||
/* or 25px */
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
.calendar__caption {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.date__container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 27px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.date {
|
||||
font-family: "Gilroy";
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
line-height: 110%;
|
||||
/* or 14px */
|
||||
}
|
||||
|
||||
.date_time {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
.date {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.calendar__table {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
margin-bottom: 4px;
|
||||
justify-content: center;
|
||||
border-radius: 4px;
|
||||
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.calendar__table:nth-child(even) {
|
||||
background: rgba(86, 126, 206, 0.1);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1152px) {
|
||||
.calendar__table {
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 832px) {
|
||||
.calendar__table {
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
.calendar__table {
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.calendar__cell {
|
||||
font-family: "Gilroy";
|
||||
font-style: normal;
|
||||
padding: 3px 5px;
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 12px;
|
||||
line-height: 130%;
|
||||
cursor: pointer;
|
||||
height: 30px;
|
||||
transition: all 0.3s ease;
|
||||
/* identical to box height, or 29px */
|
||||
}
|
||||
|
||||
.calendar__cell_none {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
.calendar__cell {
|
||||
font-size: 14px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.calendar__cell_active {
|
||||
color: #567ece;
|
||||
}
|
||||
|
||||
.calendar__cell_nopoint {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.weekday__cell {
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-family: "Gilroy";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 12px;
|
||||
line-height: 130%;
|
||||
height: 30px;
|
||||
color: #ebebeb;
|
||||
/* identical to box height, or 29px */
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
.weekday__cell {
|
||||
font-size: 14px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.calendar_none {
|
||||
display: none;
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
import React from "react";
|
||||
import "../sliderComponent/sliderComponent.css";
|
||||
import "../calendar/calendar.css";
|
||||
import moment, { Moment } from "moment";
|
||||
import "moment/locale/ru";
|
||||
import { useEffect, useState } from "react";
|
||||
import left from "./Arrow_Left.svg";
|
||||
import right from "./Arrow_Right.svg";
|
||||
import point0 from "./Ellipse0.svg";
|
||||
import point1 from "./Ellipse1.svg";
|
||||
import Timepicker from "../timepicker/timepicker";
|
||||
import Form from "../form/form";
|
||||
import { TObjct } from "../../App";
|
||||
import "../../styles/styles.css";
|
||||
|
||||
export type TProps = {
|
||||
time: Moment;
|
||||
onUpdate: (value: Moment) => void;
|
||||
setOpen: (value: TObjct) => void;
|
||||
open: TObjct;
|
||||
};
|
||||
|
||||
export const Calendar: React.FC<TProps> = ({
|
||||
time,
|
||||
onUpdate,
|
||||
setOpen,
|
||||
open,
|
||||
}) => {
|
||||
const [calendar, setCalendar] = useState<any[]>([]);
|
||||
const [value, setValue] = useState(time);
|
||||
const currDate = moment();
|
||||
const startDay = value.clone().startOf("month").startOf("week");
|
||||
const endDay = value.clone().endOf("month").endOf("week");
|
||||
const weekDays = ["пн", "вт", "ср", "чт", "пт", "сб", "вс"];
|
||||
|
||||
useEffect(() => {
|
||||
const day = startDay.clone().subtract("1", "day");
|
||||
const a: any = [];
|
||||
while (day.isBefore(endDay, "day")) {
|
||||
a.push(
|
||||
Array(7)
|
||||
.fill(0)
|
||||
.map(() => day.add(1, "day").clone())
|
||||
);
|
||||
}
|
||||
setCalendar(a);
|
||||
}, [value]);
|
||||
console.log(value);
|
||||
|
||||
function hide(day: object) {
|
||||
if (value.isSame(day, "month")) {
|
||||
if (currDate.isSame(day, "day")) {
|
||||
const cellClass = "calendar__cell_active calendar__cell";
|
||||
return cellClass;
|
||||
}
|
||||
return "calendar__cell";
|
||||
} else {
|
||||
return "calendar__cell_none";
|
||||
}
|
||||
}
|
||||
|
||||
function prevMonth() {
|
||||
return value.clone().subtract(1, "month");
|
||||
}
|
||||
|
||||
function nextMonth() {
|
||||
return value.clone().add(1, "month").startOf("month");
|
||||
}
|
||||
|
||||
function thisMonth() {
|
||||
return value.isSame(new Date(), "month");
|
||||
}
|
||||
|
||||
function updateDay(day: Moment) {
|
||||
const temp = currDate.clone().subtract(1, "day");
|
||||
if (day.isBefore(temp)) {
|
||||
return;
|
||||
} else {
|
||||
onUpdate(day);
|
||||
setOpen({
|
||||
calendar: false,
|
||||
timePicker: true,
|
||||
form: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="calendar__container">
|
||||
<div className="main-block__container">
|
||||
<div>
|
||||
<p className="main-block__title main-block__title_small">
|
||||
Graff.estate stream{" "}
|
||||
</p>
|
||||
<p className="main-block__title_gardient main-block__title_gardient_small">
|
||||
легко встраивается в существующую цепочку продаж.
|
||||
</p>
|
||||
</div>
|
||||
<p className=" main-block__caption_color">
|
||||
Проведение виртуальных экскурсий сотрудниками офиса продаж.
|
||||
</p>
|
||||
<p className="main-block__caption">
|
||||
Покупателю доступна возможность самостоятельно записаться на просмотр
|
||||
в удобное для него время, а менеджер отдела продаж удаленно поможет
|
||||
выбрать планировку и забронировать квартиру.
|
||||
</p>
|
||||
</div>
|
||||
<div className="wrapper">
|
||||
<div className={open.calendar ? "calendar_active" : "calendar"}>
|
||||
<div className="calendar__header">
|
||||
<span className="calendar__caption calendar__caption_calendar">
|
||||
Выбор даты
|
||||
</span>
|
||||
<div className="line"></div>
|
||||
</div>
|
||||
<div className="form__block">
|
||||
<div className="date__container">
|
||||
<img
|
||||
alt="back"
|
||||
src={left}
|
||||
className="button__arrow"
|
||||
onClick={() => !thisMonth() && setValue(prevMonth())}
|
||||
></img>
|
||||
<span className="date">
|
||||
{value.format("MMMM")}, {value.format("YYYY")}
|
||||
</span>
|
||||
<img
|
||||
alt="next"
|
||||
src={right}
|
||||
className="button__arrow"
|
||||
onClick={() => setValue(nextMonth())}
|
||||
></img>
|
||||
</div>
|
||||
<div className="calendar__table">
|
||||
{weekDays.map((day, i) => (
|
||||
<div key={i} className="weekday__cell">
|
||||
{day}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{calendar.map((week, i) => (
|
||||
<div key={i} className="calendar__table">
|
||||
{week.map((day: any, i: number) => (
|
||||
<div
|
||||
key={i}
|
||||
onClick={() => updateDay(day)}
|
||||
className={hide(day)}
|
||||
>
|
||||
{day.format("D")}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="appointment__block">
|
||||
<div>
|
||||
<img className="point" src={point1}></img>
|
||||
<span className="appointment__caption_active">Запись есть</span>
|
||||
</div>
|
||||
<div>
|
||||
<img className="point" src={point0}></img>
|
||||
<span className="appointment__caption" >Записи нет</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Timepicker
|
||||
open={open}
|
||||
setOpen={setOpen}
|
||||
onUpdate={onUpdate}
|
||||
time={time}
|
||||
></Timepicker>
|
||||
<Form
|
||||
open={open}
|
||||
setOpen={setOpen}
|
||||
onUpdate={onUpdate}
|
||||
time={time}
|
||||
></Form>
|
||||
</div>
|
||||
<div className="main-block__subblock-container">
|
||||
<div className="main-block_subblock">
|
||||
Процесс записи может быть встроен на сайт жилого комплекса, на который
|
||||
была настроена реклама.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
After Width: | Height: | Size: 90 KiB |
@@ -0,0 +1,55 @@
|
||||
.devices__contaner {
|
||||
margin-bottom: 160px;
|
||||
}
|
||||
|
||||
.card__container {
|
||||
display: flex;
|
||||
gap: 30px;
|
||||
margin-bottom: 80px;
|
||||
}
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 32px;
|
||||
background: #141414;
|
||||
border-radius: 16px;
|
||||
height: 388px;
|
||||
width: 380px;
|
||||
}
|
||||
|
||||
.card__name {
|
||||
font-family: "Gilroy";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 24px;
|
||||
line-height: 100%;
|
||||
/* identical to box height, or 24px */
|
||||
|
||||
/* Landing/White */
|
||||
|
||||
color: #ebebeb;
|
||||
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.card__image {
|
||||
width: 292px;
|
||||
height: 271px;
|
||||
}
|
||||
|
||||
.card__image_type {
|
||||
position: relative;
|
||||
width: 211px;
|
||||
top: 72px;
|
||||
left: -17px;
|
||||
|
||||
}
|
||||
|
||||
.card__image_type1 {
|
||||
position: absolute;
|
||||
top: 111px;
|
||||
right: 35px;
|
||||
width: 192px;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import "../../styles/styles.css";
|
||||
import "./devices.css";
|
||||
import "../multiplayer/multiplayer.css";
|
||||
import touchscreen from "./image.png";
|
||||
import imac from "./image1.png";
|
||||
import iphone from "./iPhone.png";
|
||||
import ipad from "./iPad.png";
|
||||
|
||||
export const Devices: React.FC = ({}) => {
|
||||
return (
|
||||
<div className="devices__contaner">
|
||||
<div className="main-block__container">
|
||||
<div>
|
||||
<p className="main-block__title main-block__title_small">
|
||||
Graff.estate stream{" "}
|
||||
</p>
|
||||
<p className="main-block__title_gardient main-block__title_gardient_small">
|
||||
доступен на любых устройствах.{" "}
|
||||
</p>
|
||||
</div>
|
||||
<p className="main-block__caption multiplayer__caption">
|
||||
Приложение легко адаптируется под экран любого размера и одинаково
|
||||
хорошо выглядит на мобильном телефоне или на большом сенсорном экране
|
||||
в отделе продаж застройщика.{" "}
|
||||
</p>
|
||||
</div>
|
||||
<div className="card__container">
|
||||
<div className="card">
|
||||
<p className="card__name">Interactive display</p>
|
||||
<img src={touchscreen} className="card__image"></img>
|
||||
</div>
|
||||
<div className="card">
|
||||
<p className="card__name">Desktop</p>
|
||||
<img src={imac} className="card__image"></img>
|
||||
</div>
|
||||
<div className="card">
|
||||
<p className="card__name">Mobile</p>
|
||||
<img src={iphone} className="card__image_type"></img>
|
||||
<img src={ipad} className="card__image_type1"></img>
|
||||
</div>
|
||||
</div>
|
||||
<div className="main-block__subblock-container">
|
||||
<div className="main-block_subblock">
|
||||
<button className="main-block__button">
|
||||
Демоверсия
|
||||
<div className="main-block__icon"></div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,239 @@
|
||||
.form__container {
|
||||
width: 385px;
|
||||
color: #ebebeb;
|
||||
display: grid;
|
||||
margin: 0 auto;
|
||||
grid-template-rows: auto 1fr;
|
||||
padding: 24px 32px;
|
||||
box-sizing: border-box;
|
||||
background: #141414;
|
||||
border-radius: 16px;
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
transition: opacity ease-in 0.5s;
|
||||
|
||||
}
|
||||
|
||||
.form__container_active {
|
||||
width: 385px;
|
||||
color: #ebebeb;
|
||||
display: grid;
|
||||
margin: 0 auto;
|
||||
grid-template-rows: auto 1fr;
|
||||
padding: 24px 32px;
|
||||
box-sizing: border-box;
|
||||
background: #141414;
|
||||
border-radius: 16px;
|
||||
opacity: 1;
|
||||
transition: opacity ease-in 0.5s;
|
||||
|
||||
}
|
||||
|
||||
.form__block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1152px) {
|
||||
.form__block {
|
||||
padding: 0 20px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 832px) {
|
||||
.form__block {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
.form__block {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1152px) {
|
||||
.form__container {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.form__container_none {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.form {
|
||||
margin-top: 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
outline: none;
|
||||
border-color: none;
|
||||
}
|
||||
|
||||
.form__input {
|
||||
padding: 16px 16px 12px;
|
||||
gap: 8px;
|
||||
color: #ebebeb;
|
||||
width: 321px;
|
||||
height: 44px;
|
||||
border: none;
|
||||
background: rgba(86, 126, 206, 0.1);
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.button__submit {
|
||||
font-family: "Gilroy";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
line-height: 125%;
|
||||
background: #567ece;
|
||||
border-radius: 8px;
|
||||
color: #EBEBEB;
|
||||
padding: 2px 0px 0px;
|
||||
cursor: pointer;
|
||||
height: 48px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form__input_error:focus {
|
||||
height: 60px;
|
||||
background: #e9e9e9;
|
||||
outline: none;
|
||||
border: none;
|
||||
width: 100%;
|
||||
padding: 20px 20px 19px;
|
||||
box-sizing: border-box;
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 17px;
|
||||
line-height: 21px;
|
||||
border: 1px solid #eb5757;
|
||||
color: #eb5757;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 832px) {
|
||||
.form__input :last-of-type {
|
||||
margin-bottom: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
.confirm {
|
||||
padding: 15px 20px 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.form__header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1152px) {
|
||||
.form__header {
|
||||
margin: 30px 12px 43px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 832px) {
|
||||
.form__header {
|
||||
margin: 40px 12px 43px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
.form__header {
|
||||
margin: 20px 10px 19px;
|
||||
}
|
||||
}
|
||||
|
||||
.confirm {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
padding: 150px 40px 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1152px) {
|
||||
.confirm {
|
||||
padding: 140px 20px 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
.confirm {
|
||||
padding: 80px 10px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.confirm__none {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.confirm__title {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-size: 40px;
|
||||
line-height: 110%;
|
||||
color: #333333;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.confirm__caption {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 18px;
|
||||
line-height: 130%;
|
||||
margin: 25px 0 40px;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
.confirm__caption {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.confirm__button {
|
||||
width: 380px;
|
||||
height: 59px;
|
||||
color: #ffffff;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
background: #333333;
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-size: 17px;
|
||||
line-height: 21px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
.confirm__button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.warning {
|
||||
margin-left: 20px;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
line-height: 15px;
|
||||
color: #eb5757;
|
||||
height: 30px;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.warning_on {
|
||||
visibility: visible;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import left from "../calendar/Arrow_Left.svg";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import moment from "moment";
|
||||
import "./form.css";
|
||||
import { TProps } from "../calendar/calendar";
|
||||
|
||||
export const Form: React.FC<TProps> = ({ time, open, setOpen }) => {
|
||||
function goBack() {
|
||||
setOpen({
|
||||
calendar: false,
|
||||
timePicker: true,
|
||||
form: false,
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={open.form ? "form__container_active" : "form__container"}>
|
||||
<div className="timepicker__header">
|
||||
<div className="caption__container">
|
||||
<img onClick={() => goBack()} className="button__arrow_back" alt="left" src={left}></img>
|
||||
<span className="calendar__caption">Выбор времени</span>
|
||||
</div>
|
||||
<div className="line line_time"></div>
|
||||
<div className="date">{time.format("DD MMM, LT")}</div>
|
||||
</div>
|
||||
<div className="form__block">
|
||||
<div>
|
||||
<form className="form">
|
||||
<input
|
||||
name="tel"
|
||||
className="form__input"
|
||||
type="text"
|
||||
placeholder="Номер телефона"
|
||||
></input>
|
||||
<input
|
||||
name="email"
|
||||
className="form__input"
|
||||
type="text"
|
||||
placeholder="E-mail"
|
||||
></input>
|
||||
<input
|
||||
name="name"
|
||||
className="form__input"
|
||||
type="text"
|
||||
placeholder="Ваше имя"
|
||||
></input>
|
||||
</form>
|
||||
</div>
|
||||
<button type="submit" className="button__submit">
|
||||
Запланировать
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Form;
|
||||
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.0001 12.6666L10.6667 8L6.0001 3.33334" stroke="white" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 218 B |
@@ -0,0 +1,55 @@
|
||||
.header-container {
|
||||
display: flex;
|
||||
padding: 35px 40px;
|
||||
box-sizing: border-box;
|
||||
color: #FFFFFF;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
width: 31px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.header-buttons {
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
}
|
||||
|
||||
.header-button {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
line-height: 125%;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.header-lang-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 6px 12px;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
font-weight: 400;
|
||||
font-size: 11px;
|
||||
line-height: 13px;
|
||||
color: #EBEBEB;
|
||||
background-color: transparent;
|
||||
border-radius: 50px;
|
||||
border: 2px solid #EBEBEB;
|
||||
}
|
||||
|
||||
.header-lang-button-text {
|
||||
display: flex;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.header-lang-button-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background: url('chevronIcon.svg') 50% 50% no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import React from "react";
|
||||
import logo from './logoIcon.svg';
|
||||
import './header.css';
|
||||
|
||||
export const Header:React.FC = React.memo(() => {
|
||||
return <div className="header-container">
|
||||
<img className="header-logo" alt="company-logo" src={logo} />
|
||||
<div className="header-buttons">
|
||||
<button className="header-button">Контакты</button>
|
||||
<button className="header-button">О компании</button>
|
||||
<button className="header-lang-button">
|
||||
<span className="header-lang-button-text">RU</span>
|
||||
<span className="header-lang-button-icon"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
})
|
||||
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 217 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 6L18 12L12 18" stroke="#EBEBEB" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M7 6L13 12L7 18" stroke="#EBEBEB" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 289 B |
@@ -0,0 +1,77 @@
|
||||
.mapblock__container {
|
||||
color: #ebebeb;
|
||||
background-image: url(./Map.svg);
|
||||
background-repeat: no-repeat;
|
||||
height: 780px;
|
||||
background-position: 300px;
|
||||
margin-bottom: 160px;
|
||||
}
|
||||
|
||||
.title__container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 30px;
|
||||
padding-top: 175px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-family: "Gilroy";
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-size: 96px;
|
||||
line-height: 80%;
|
||||
margin: 0;
|
||||
color: #ebebeb;
|
||||
}
|
||||
|
||||
.title__gardient {
|
||||
font-family: "Gilroy";
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-size: 96px;
|
||||
line-height: 80%;
|
||||
margin: 0;
|
||||
background-image: linear-gradient(#d375ff, #798fff);
|
||||
background-size: 100%;
|
||||
background-repeat: repeat;
|
||||
background-color: transparent;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
-moz-background-clip: text;
|
||||
-moz-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.button__demo {
|
||||
box-sizing: border-box;
|
||||
|
||||
background-color: transparent;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 14px 14px 12px 20px;
|
||||
gap: 4px;
|
||||
border: 1px solid #454545;
|
||||
border-radius: 32px;
|
||||
color: #ebebeb;
|
||||
width: 156px;
|
||||
margin-top: 31px;
|
||||
}
|
||||
|
||||
.title__caption {
|
||||
font-family: "Gilroy";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
line-height: 150%;
|
||||
/* or 21px */
|
||||
|
||||
letter-spacing: 0.02em;
|
||||
text-transform: uppercase;
|
||||
|
||||
/* Landing/White */
|
||||
|
||||
color: #ebebeb;
|
||||
|
||||
opacity: 0.8;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import React from "react";
|
||||
import "./mapblock.css";
|
||||
import chevron from "./chevron.svg";
|
||||
import { Swiper, SwiperSlide } from "swiper/react";
|
||||
|
||||
|
||||
export const Mapblock: React.FC = React.memo(() => {
|
||||
return (
|
||||
<div className="mapblock__container">
|
||||
<div className="title__container">
|
||||
<div>
|
||||
<p className="title">Graff.estate </p>
|
||||
<p className="title__gardient">stream</p>
|
||||
</div>
|
||||
<span className="title__caption">
|
||||
Технология удаленной демонстрации жилого комплекса.
|
||||
</span>
|
||||
<button className="button__demo">
|
||||
Демоверсия
|
||||
<img src={chevron}></img>
|
||||
</button>
|
||||
</div>
|
||||
<div className="swiper__container">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
After Width: | Height: | Size: 350 KiB |
|
After Width: | Height: | Size: 424 KiB |
|
After Width: | Height: | Size: 362 KiB |
|
After Width: | Height: | Size: 316 KiB |
@@ -0,0 +1,29 @@
|
||||
.multiplayer__container {
|
||||
background: #141414;
|
||||
border-radius: 32px;
|
||||
padding: 120px 32px 80px;
|
||||
margin-bottom: 160px;
|
||||
}
|
||||
|
||||
.caption {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.multiplayer__photo-container {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 30px;
|
||||
margin-bottom: 80px;
|
||||
}
|
||||
|
||||
.multiplayer__image {
|
||||
width: 553px;
|
||||
filter: drop-shadow(0px -2px 8px rgba(128, 128, 128, 0.15))
|
||||
drop-shadow(0px 2px 8px rgba(0, 0, 0, 0.8));
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.multiplayer__caption {
|
||||
margin-top: 40px;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import "../../styles/styles.css";
|
||||
import "./multiplayer.css";
|
||||
import photo from "./Photo.png";
|
||||
import photo1 from "./Photo1.png";
|
||||
import photo2 from "./Photo2.png";
|
||||
import photo3 from "./Photo3.png";
|
||||
|
||||
export const Multiplayer: React.FC = ({}) => {
|
||||
return (
|
||||
<div className="multiplayer__container">
|
||||
<div className="main-block__container">
|
||||
<div>
|
||||
<p className="main-block__title main-block__title_small">
|
||||
Graff.estate stream
|
||||
</p>
|
||||
<p className="main-block__title_gardient main-block__title_gardient_small">
|
||||
для совместной работы.
|
||||
</p>
|
||||
</div>
|
||||
<p className="main-block__caption multiplayer__caption">
|
||||
Покупатель может вместе с близкими людьми осмотреть жилой комплекс.
|
||||
Это совершенно новый опыт в процессе выбора квартиры.
|
||||
</p>
|
||||
</div>
|
||||
<div className="multiplayer__photo-container">
|
||||
<img src={photo} className="multiplayer__image" />
|
||||
<img src={photo1} className="multiplayer__image" />
|
||||
<img src={photo2} className="multiplayer__image" />
|
||||
<img src={photo3} className="multiplayer__image" />
|
||||
</div>
|
||||
<div className="main-block__subblock-container">
|
||||
<div className="main-block_subblock">
|
||||
Осмотр жилого комплекса доступен в любой <br></br> момент, без
|
||||
необходимости предварительной <br></br> записи на просмотр.
|
||||
<button className="main-block__button">
|
||||
Демоверсия
|
||||
<div className="main-block__icon"></div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,83 @@
|
||||
.slider-container {
|
||||
width: 1200px;
|
||||
background: #141414;
|
||||
border-radius: 32px;
|
||||
padding-top: 120px;
|
||||
padding-bottom: 80px;
|
||||
}
|
||||
|
||||
.slider__block {
|
||||
background: #141414;
|
||||
border-radius: 32px;
|
||||
margin: 0 auto;
|
||||
padding-top: 120px;
|
||||
padding-bottom: 85px;
|
||||
}
|
||||
|
||||
.text_container {
|
||||
width: 416px;
|
||||
margin: 0 auto 80px;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.slider__caption {
|
||||
font-family: "Gilroy";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 18px;
|
||||
line-height: 140%;
|
||||
/* or 25px */
|
||||
|
||||
/* Landing/White */
|
||||
margin: 0;
|
||||
color: #ebebeb;
|
||||
}
|
||||
|
||||
.slider__caption_color {
|
||||
margin-top: 40px;
|
||||
margin-bottom: 20px;
|
||||
font-family: "Gilroy";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
line-height: 150%;
|
||||
/* or 21px */
|
||||
color: #ebebeb;
|
||||
letter-spacing: 0.02em;
|
||||
text-transform: uppercase;
|
||||
color: #d375ff;
|
||||
}
|
||||
|
||||
.slider__gardient {
|
||||
width: 358px;
|
||||
font-family: "Gilroy";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 64px;
|
||||
line-height: 100%;
|
||||
|
||||
margin: 0;
|
||||
background-image: linear-gradient(#d375ff, #798fff);
|
||||
background-size: 100%;
|
||||
background-repeat: repeat;
|
||||
background-color: transparent;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
-moz-background-clip: text;
|
||||
-moz-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.slider__title {
|
||||
width: 358px;
|
||||
|
||||
font-family: "Gilroy";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 64px;
|
||||
line-height: 100%;
|
||||
color: #ebebeb;
|
||||
|
||||
margin: 0;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import React from "react";
|
||||
import "./sliderComponent.css";
|
||||
import "../../styles/styles.css"
|
||||
import { Swiper, SwiperSlide } from "swiper/react";
|
||||
import SwiperCentred from "../swiper/swiper";
|
||||
|
||||
export const SliderComponent: React.FC = React.memo(() => {
|
||||
return (
|
||||
<div className="slider-container">
|
||||
<div className="slider">
|
||||
<div className="main-block__container">
|
||||
<div>
|
||||
<p className="main-block__title">Graff.estate </p>
|
||||
<p className="main-block__title_gardient">stream</p>
|
||||
</div>
|
||||
<p className=" main-block__caption_color">
|
||||
бескомпромиссный уровень графики и полное погружение покупателя в
|
||||
процесс выбора квартиры.
|
||||
</p>
|
||||
<p className="main-block__caption">
|
||||
Покажем все преимущества вашего жилого комплекса клиенту из любого
|
||||
конца мира. Местоположение и устройство значения не имеют. Нужен
|
||||
только интернет.
|
||||
</p>
|
||||
</div>
|
||||
<SwiperCentred
|
||||
slidesPerView={""}
|
||||
centeredSlides={false}
|
||||
spaceBetween={0}
|
||||
modules={[]}
|
||||
className={""}
|
||||
children={undefined}
|
||||
></SwiperCentred>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
After Width: | Height: | Size: 1.4 MiB |
@@ -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="#EBEBEB" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 211 B |
@@ -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="M1 12H23M23 12L15.8 5M23 12L15.8 19" stroke="#EBEBEB" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 215 B |
|
After Width: | Height: | Size: 847 KiB |
|
After Width: | Height: | Size: 1.7 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
@@ -0,0 +1,88 @@
|
||||
.image__slider {
|
||||
width: 100%;
|
||||
height: 428px;
|
||||
object-fit: cover;
|
||||
opacity: 0.5;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.image__slider_active {
|
||||
width: 100%;
|
||||
height: 428px;
|
||||
object-fit: cover;
|
||||
opacity: 1;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.button__container {
|
||||
margin-top: 45px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
gap: 340px;
|
||||
}
|
||||
|
||||
.slider__info {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.swiper__caption {
|
||||
margin: 0;
|
||||
font-family: "Gilroy";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
line-height: 150%;
|
||||
/* identical to box height, or 21px */
|
||||
|
||||
letter-spacing: 0.02em;
|
||||
|
||||
/* Landing/White */
|
||||
|
||||
color: #ebebeb;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 18px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.button {
|
||||
width: 22px;
|
||||
height: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.container1 {
|
||||
font-family: "Gilroy";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
line-height: 150%;
|
||||
/* identical to box height, or 21px */
|
||||
|
||||
letter-spacing: 0.02em;
|
||||
text-transform: uppercase;
|
||||
|
||||
/* Landing/White */
|
||||
|
||||
color: #ebebeb;
|
||||
|
||||
display: flex;
|
||||
color: #ebebeb !important;
|
||||
}
|
||||
|
||||
.swiper__caption {
|
||||
margin: 0;
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
.pagination__container {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
gap: 16px;
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
import React, { useRef, useState } from "react";
|
||||
// Import Swiper React components
|
||||
import { Swiper, SwiperSlide, useSwiperSlide } from "swiper/react";
|
||||
|
||||
// Import Swiper styles
|
||||
import "swiper/css";
|
||||
import "swiper/css/pagination";
|
||||
import "swiper/css/navigation";
|
||||
|
||||
// import required modules
|
||||
import { Pagination, Navigation } from "swiper";
|
||||
|
||||
import img from "./images/Architecture1.png";
|
||||
import img1 from "./images/Floor1.png";
|
||||
import img2 from "./images/Infrastructure1.png";
|
||||
import img3 from "./images/Outside.png";
|
||||
import "./swiper.css";
|
||||
import arrowLeft from "./images/Arrow_Left.svg";
|
||||
import arrowRight from "./images/Arrow_Right.svg";
|
||||
import "swiper/css";
|
||||
import "swiper/css/pagination";
|
||||
import "swiper/css/navigation";
|
||||
|
||||
type propsTypes = {
|
||||
slidesPerView: string;
|
||||
centeredSlides: boolean;
|
||||
spaceBetween: number;
|
||||
modules: Array<any>;
|
||||
className: string;
|
||||
children: React.ReactNode; // 👈️ added type for children
|
||||
};
|
||||
|
||||
export default function SwiperCentred(props: propsTypes) {
|
||||
const swiperSlide = useSwiperSlide();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Swiper
|
||||
centeredSlides={true}
|
||||
spaceBetween={20}
|
||||
initialSlide={1}
|
||||
slidesPerView={2}
|
||||
modules={[Navigation, Pagination]}
|
||||
navigation={{
|
||||
nextEl: ".button_next",
|
||||
prevEl: ".button_prev",
|
||||
}}
|
||||
pagination={{
|
||||
el: ".container1",
|
||||
type: "fraction",
|
||||
}}
|
||||
>
|
||||
<SwiperSlide>
|
||||
{({ isActive }) => (
|
||||
<img
|
||||
className={isActive ? "image__slider_active" : "image__slider"}
|
||||
src={img1}
|
||||
/>
|
||||
)}
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
{({ isActive }) => (
|
||||
<img
|
||||
className={isActive ? "image__slider_active" : "image__slider"}
|
||||
src={img}
|
||||
/>
|
||||
)}
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
{({ isActive }) => (
|
||||
<img
|
||||
className={isActive ? "image__slider_active" : "image__slider"}
|
||||
src={img2}
|
||||
/>
|
||||
)}
|
||||
</SwiperSlide>
|
||||
<SwiperSlide>
|
||||
{({ isActive }) => (
|
||||
<img
|
||||
className={isActive ? "image__slider_active" : "image__slider"}
|
||||
src={img3}
|
||||
/>
|
||||
)}
|
||||
</SwiperSlide>
|
||||
<div className="slider__info">
|
||||
<div className="button__container">
|
||||
<div className="container">
|
||||
<img className="button button_prev" src={arrowLeft}></img>
|
||||
<img className="button button_next" src={arrowRight}></img>
|
||||
</div>
|
||||
<div className="pagination__container">
|
||||
<div className="container1">
|
||||
<p className="swiper__caption"></p>
|
||||
</div>
|
||||
<p className="swiper__caption">Архитектура</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Swiper>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
.timepicker__header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.timepicker__table {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: 4px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.timepicker__table:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.timpicker__cell {
|
||||
font-family: "Gilroy";
|
||||
font-style: normal;
|
||||
padding: 3px 5px;
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 12px;
|
||||
line-height: 130%;
|
||||
cursor: pointer;
|
||||
height: 30px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 480px) {
|
||||
.timpicker__cell {
|
||||
font-size: 14px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.line_time {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.timpicker__cell {
|
||||
background: rgba(86, 126, 206, 0.1);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.appointment__block_time {
|
||||
margin-top: 21px;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
import left from "../calendar/Arrow_Left.svg";
|
||||
import { useEffect, useState } from "react";
|
||||
import moment, { Moment } from "moment";
|
||||
import "moment/locale/ru";
|
||||
import "./timepicker.css";
|
||||
import "../calendar/calendar.css";
|
||||
import point0 from "../calendar/Ellipse0.svg";
|
||||
import point1 from "../calendar/Ellipse1.svg";
|
||||
import { TProps } from "../calendar/calendar";
|
||||
|
||||
export const Timepicker: React.FC<TProps> = ({
|
||||
time,
|
||||
onUpdate,
|
||||
open,
|
||||
setOpen,
|
||||
}) => {
|
||||
|
||||
const [timePicker, settimePicker] = useState<any[]>([]);
|
||||
const startTime = time.clone().hours(8).minutes(0);
|
||||
const endTime = time.clone().hours(19).minutes(0);
|
||||
|
||||
useEffect(() => {
|
||||
const temp = startTime.clone().subtract("30", "minute");
|
||||
const a: any = [];
|
||||
while (temp.isBefore(endTime, "minute")) {
|
||||
a.push(
|
||||
Array(8)
|
||||
.fill(0)
|
||||
.map(() => temp.add(30, "minutes").clone())
|
||||
);
|
||||
}
|
||||
settimePicker(a);
|
||||
}, [time]);
|
||||
|
||||
function updateTime(time: Moment) {
|
||||
onUpdate(time);
|
||||
setOpen({
|
||||
calendar: false,
|
||||
timePicker: false,
|
||||
form: true,
|
||||
});
|
||||
}
|
||||
|
||||
function goBack() {
|
||||
setOpen({
|
||||
calendar: true,
|
||||
timePicker: false,
|
||||
form: false,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div className={open.timePicker ? "calendar_active" : "calendar"}>
|
||||
<div className="timepicker__header">
|
||||
<div className="caption__container">
|
||||
<img onClick={() => goBack()} className="button__arrow_back" alt="left" src={left}></img>
|
||||
<span className="calendar__caption">Выбор времени</span>
|
||||
</div>
|
||||
<div className="line line_time"></div>
|
||||
<div className="date date_time">{time.format("DD MMMM")}</div>
|
||||
</div>
|
||||
<div className="form__block">
|
||||
{timePicker.map((date, i) => (
|
||||
<div key={i} className="timepicker__table">
|
||||
{date.map((time: any, i: number) => (
|
||||
<div
|
||||
key={i}
|
||||
onClick={() => updateTime(time)}
|
||||
className="timpicker__cell"
|
||||
>
|
||||
{time.format("LT")}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
<div className="appointment__block appointment__block_time">
|
||||
<div>
|
||||
<img className="point" src={point1}></img>
|
||||
<span className="appointment__caption_active">Запись есть</span>
|
||||
</div>
|
||||
<div>
|
||||
<img className="point" src={point0}></img>
|
||||
<span>Записи нет</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Timepicker;
|
||||