first commit

This commit is contained in:
DmitriyB
2022-08-25 11:55:26 +05:00
commit 73b082d874
77 changed files with 36497 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
.analytics__container {
background: #141414;
border-radius: 32px;
padding: 120px 32px 80px;
}
+24
View File
@@ -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>
);
};
+3
View File
@@ -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

+3
View File
@@ -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

+3
View File
@@ -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

+3
View File
@@ -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

+232
View File
@@ -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;
}
+187
View File
@@ -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>
);
};
Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

+55
View File
@@ -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;
}
+52
View File
@@ -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>
);
};
Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

+239
View File
@@ -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;
}
+57
View File
@@ -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;
+3
View File
@@ -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

+55
View File
@@ -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%;
}
+17
View File
@@ -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>
})
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 217 KiB

+4
View File
@@ -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

+77
View File
@@ -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;
}
+28
View File
@@ -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>
);
});
Binary file not shown.

After

Width:  |  Height:  |  Size: 350 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

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>
);
});
Binary file not shown.

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

+88
View File
@@ -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;
}
+102
View File
@@ -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>
</>
);
}
+56
View File
@@ -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;
}
+93
View File
@@ -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;