RC-7-home-page #5

Merged
evgeniywas merged 8 commits from RC-7-home-page into dev 2023-08-06 17:46:08 +03:00
30 changed files with 838 additions and 352 deletions

View File

@@ -1,4 +1,3 @@
/**
* HEY HO
*/
@@ -14,15 +13,15 @@
*,
::before,
::after {
box-sizing: border-box; /* 1 */
border-width: 0; /* 2 */
border-style: solid; /* 2 */
border-color: #EEEEEE; /* 2 */
box-sizing: border-box; /* 1 */
border-width: 0; /* 2 */
border-style: solid; /* 2 */
border-color: #eeeeee; /* 2 */
}
::before,
::after {
--tw-content: '';
--tw-content: '';
}
/*
@@ -33,10 +32,12 @@
*/
html {
line-height: 1.5; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */ /* 3 */
tab-size: 4; /* 3 */
font-family: Inter var, Roboto, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */
line-height: 1.5; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */ /* 3 */
tab-size: 4; /* 3 */
font-family: Inter var, Roboto, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
'Segoe UI Symbol', 'Noto Color Emoji'; /* 4 */
}
/*
@@ -45,8 +46,8 @@ html {
*/
body {
margin: 0; /* 1 */
line-height: inherit; /* 2 */
margin: 0; /* 1 */
line-height: inherit; /* 2 */
}
/*
@@ -56,9 +57,9 @@ body {
*/
hr {
height: 0; /* 1 */
color: inherit; /* 2 */
border-top-width: 1px; /* 3 */
height: 0; /* 1 */
color: inherit; /* 2 */
border-top-width: 1px; /* 3 */
}
/*
@@ -66,7 +67,7 @@ Add the correct text decoration in Chrome, Edge, and Safari.
*/
abbr:where([title]) {
text-decoration: underline dotted;
text-decoration: underline dotted;
}
/*
@@ -79,8 +80,8 @@ h3,
h4,
h5,
h6 {
font-size: inherit;
font-weight: inherit;
font-size: inherit;
font-weight: inherit;
}
/*
@@ -88,8 +89,8 @@ Reset links to optimize for opt-in styling instead of opt-out.
*/
a {
color: inherit;
text-decoration: inherit;
color: inherit;
text-decoration: inherit;
}
/*
@@ -98,7 +99,7 @@ Add the correct font weight in Edge and Safari.
b,
strong {
font-weight: bolder;
font-weight: bolder;
}
/*
@@ -110,8 +111,9 @@ code,
kbd,
samp,
pre {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* 1 */
font-size: 1em; /* 2 */
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
'Courier New', monospace; /* 1 */
font-size: 1em; /* 2 */
}
/*
@@ -119,7 +121,7 @@ Add the correct font size in all browsers.
*/
small {
font-size: 80%;
font-size: 80%;
}
/*
@@ -128,18 +130,18 @@ Prevent `sub` and `sup` elements from affecting the line height in all browsers.
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
bottom: -0.25em;
}
sup {
top: -0.5em;
top: -0.5em;
}
/*
@@ -149,9 +151,9 @@ sup {
*/
table {
text-indent: 0; /* 1 */
border-color: inherit; /* 2 */
border-collapse: collapse; /* 3 */
text-indent: 0; /* 1 */
border-color: inherit; /* 2 */
border-collapse: collapse; /* 3 */
}
/*
@@ -165,12 +167,12 @@ input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: inherit; /* 1 */
color: inherit; /* 1 */
margin: 0; /* 2 */
padding: 0; /* 3 */
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: inherit; /* 1 */
color: inherit; /* 1 */
margin: 0; /* 2 */
padding: 0; /* 3 */
}
/*
@@ -179,7 +181,7 @@ Remove the inheritance of text transform in Edge and Firefox.
button,
select {
text-transform: none;
text-transform: none;
}
/*
@@ -191,9 +193,9 @@ button,
[type='button'],
[type='reset'],
[type='submit'] {
-webkit-appearance: button; /* 1 */
background-color: transparent; /* 2 */
background-image: none; /* 2 */
-webkit-appearance: button; /* 1 */
background-color: transparent; /* 2 */
background-image: none; /* 2 */
}
/*
@@ -201,7 +203,7 @@ Use the modern Firefox focus style for all focusable elements.
*/
:-moz-focusring {
outline: auto;
outline: auto;
}
/*
@@ -209,7 +211,7 @@ Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/
*/
:-moz-ui-invalid {
box-shadow: none;
box-shadow: none;
}
/*
@@ -217,7 +219,7 @@ Add the correct vertical alignment in Chrome and Firefox.
*/
progress {
vertical-align: baseline;
vertical-align: baseline;
}
/*
@@ -226,7 +228,7 @@ Correct the cursor style of increment and decrement buttons in Safari.
::-webkit-inner-spin-button,
::-webkit-outer-spin-button {
height: auto;
height: auto;
}
/*
@@ -235,8 +237,8 @@ Correct the cursor style of increment and decrement buttons in Safari.
*/
[type='search'] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/*
@@ -244,7 +246,7 @@ Remove the inner padding in Chrome and Safari on macOS.
*/
::-webkit-search-decoration {
-webkit-appearance: none;
-webkit-appearance: none;
}
/*
@@ -253,8 +255,8 @@ Remove the inner padding in Chrome and Safari on macOS.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/*
@@ -262,7 +264,7 @@ Add the correct display in Chrome and Safari.
*/
summary {
display: list-item;
display: list-item;
}
/*
@@ -282,24 +284,24 @@ hr,
figure,
p,
pre {
margin: 0;
margin: 0;
}
fieldset {
margin: 0;
padding: 0;
margin: 0;
padding: 0;
}
legend {
padding: 0;
padding: 0;
}
ol,
ul,
menu {
list-style: none;
margin: 0;
padding: 0;
list-style: none;
margin: 0;
padding: 0;
}
/*
@@ -307,7 +309,7 @@ Prevent resizing textareas horizontally by default.
*/
textarea {
resize: vertical;
resize: vertical;
}
/*
@@ -317,8 +319,8 @@ textarea {
input::placeholder,
textarea::placeholder {
opacity: 1; /* 1 */
color: #BDBDBD; /* 2 */
opacity: 1; /* 1 */
color: #bdbdbd; /* 2 */
}
/*
@@ -326,8 +328,8 @@ Set the default cursor for buttons.
*/
button,
[role="button"] {
cursor: pointer;
[role='button'] {
cursor: pointer;
}
/*
@@ -335,7 +337,7 @@ Make sure disabled buttons don't get the pointer cursor.
*/
:disabled {
cursor: default;
cursor: default;
}
/*
@@ -352,8 +354,8 @@ audio,
iframe,
embed,
object {
display: block; /* 1 */
vertical-align: middle; /* 2 */
display: block; /* 1 */
vertical-align: middle; /* 2 */
}
/*
@@ -362,8 +364,8 @@ Constrain images and videos to the parent width and preserve their intrinsic asp
img,
video {
max-width: 100%;
height: auto;
max-width: 100%;
height: auto;
}
/*
@@ -371,50 +373,52 @@ Ensure the default browser behavior of the `hidden` attribute.
*/
[hidden] {
display: none;
display: none;
}
*, ::before, ::after {
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: '';
--tw-pan-y: '';
--tw-pinch-zoom: '';
--tw-scroll-snap-strictness: proximity;
--tw-ordinal: '';
--tw-slashed-zero: '';
--tw-numeric-figure: '';
--tw-numeric-spacing: '';
--tw-numeric-fraction: '';
--tw-ring-inset: '';
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(33 150 243 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: '';
--tw-brightness: '';
--tw-contrast: '';
--tw-grayscale: '';
--tw-hue-rotate: '';
--tw-invert: '';
--tw-saturate: '';
--tw-sepia: '';
--tw-drop-shadow: '';
--tw-backdrop-blur: '';
--tw-backdrop-brightness: '';
--tw-backdrop-contrast: '';
--tw-backdrop-grayscale: '';
--tw-backdrop-hue-rotate: '';
--tw-backdrop-invert: '';
--tw-backdrop-opacity: '';
--tw-backdrop-saturate: '';
--tw-backdrop-sepia: '';
*,
::before,
::after {
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: '';
--tw-pan-y: '';
--tw-pinch-zoom: '';
--tw-scroll-snap-strictness: proximity;
--tw-ordinal: '';
--tw-slashed-zero: '';
--tw-numeric-figure: '';
--tw-numeric-spacing: '';
--tw-numeric-fraction: '';
--tw-ring-inset: '';
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(33 150 243 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: '';
--tw-brightness: '';
--tw-contrast: '';
--tw-grayscale: '';
--tw-hue-rotate: '';
--tw-invert: '';
--tw-saturate: '';
--tw-sepia: '';
--tw-drop-shadow: '';
--tw-backdrop-blur: '';
--tw-backdrop-brightness: '';
--tw-backdrop-contrast: '';
--tw-backdrop-grayscale: '';
--tw-backdrop-hue-rotate: '';
--tw-backdrop-invert: '';
--tw-backdrop-opacity: '';
--tw-backdrop-saturate: '';
--tw-backdrop-sepia: '';
}

View File

@@ -52,15 +52,15 @@ const inputGlobalStyles = (
// textDecoration: 'none',
// },
// },
'[class*="MuiOutlinedInput-root"]': {
borderRadius: `${theme.spacing('10px')}!important`,
},
'[class^="border"]': {
borderColor: theme.palette.divider,
},
'[class*="border"]': {
borderColor: theme.palette.divider,
},
// '[class*="MuiOutlinedInput-root"]': {
// borderRadius: `${theme.spacing('10px')}`,
// },
// '[class^="border"]': {
// borderColor: theme.palette.divider,
// },
// '[class*="border"]': {
// borderColor: theme.palette.divider,
// },
'[class*="divide-"] > :not([hidden]) ~ :not([hidden])': {
borderColor: theme.palette.divider,
},

20
src/app/hooks/index.js Normal file
View File

@@ -0,0 +1,20 @@
import { useState, useEffect } from 'react';
export function useWindowDimensions() {
const getWindowDimensions = () => {
const { innerWidth: width, innerHeight: height } = window;
return { width, height };
};
const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());
useEffect(() => {
const onRecize = () => setWindowDimensions(getWindowDimensions());
window.addEventListener('resize', onRecize);
return () => window.removeEventListener('resize', onRecize);
}, []);
return windowDimensions;
}

View File

@@ -4,6 +4,7 @@ import Button from '@mui/material/Button';
import Paper from '@mui/material/Paper';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import { forwardRef } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { withTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
@@ -15,6 +16,19 @@ const defaultValues = {
email: '',
};
const StyledTextField = forwardRef((props, ref) => (
<TextField
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
borderRadius: '10px',
},
}}
{...props}
ref={ref}
/>
));
function ForgotPasswordPage({ t }) {
const schema = yup.object().shape({
email: yup.string().email(t('email_error')).required(t('email_error')),
@@ -63,7 +77,7 @@ function ForgotPasswordPage({ t }) {
name="email"
control={control}
render={({ field }) => (
<TextField
<StyledTextField
{...field}
label={t('email')}
type="email"
@@ -72,11 +86,6 @@ function ForgotPasswordPage({ t }) {
variant="outlined"
required
fullWidth
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
},
}}
/>
)}
/>

View File

@@ -7,6 +7,7 @@ import FormControlLabel from '@mui/material/FormControlLabel';
import Paper from '@mui/material/Paper';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import { forwardRef } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { withTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
@@ -20,6 +21,19 @@ const defaultValues = {
remember: false,
};
const StyledTextField = forwardRef((props, ref) => (
<TextField
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
borderRadius: '10px',
},
}}
{...props}
ref={ref}
/>
));
function SignInPage({ t }) {
const schema = yup.object().shape({
email: yup.string().email(t('email_error')).required(t('email_error')),
@@ -72,7 +86,7 @@ function SignInPage({ t }) {
name="email"
control={control}
render={({ field }) => (
<TextField
<StyledTextField
{...field}
className="mb-28"
label={t('email')}
@@ -83,11 +97,6 @@ function SignInPage({ t }) {
variant="outlined"
required
fullWidth
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
},
}}
/>
)}
/>
@@ -96,7 +105,7 @@ function SignInPage({ t }) {
name="password"
control={control}
render={({ field }) => (
<TextField
<StyledTextField
{...field}
className="mb-28"
label={t('password')}
@@ -106,11 +115,6 @@ function SignInPage({ t }) {
variant="outlined"
required
fullWidth
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
},
}}
/>
)}
/>
@@ -146,7 +150,7 @@ function SignInPage({ t }) {
variant="contained"
color="secondary"
className="w-[220px] mt-32 text-base uppercase rounded-xl"
aria-label="Sign in"
aria-label={t('sign_in_btn')}
disabled={_.isEmpty(dirtyFields) || !isValid}
type="submit"
size="large"

View File

@@ -4,6 +4,7 @@ import Button from '@mui/material/Button';
import Paper from '@mui/material/Paper';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import { forwardRef } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { withTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
@@ -18,6 +19,19 @@ const defaultValues = {
passwordConfirm: '',
};
const StyledTextField = forwardRef((props, ref) => (
<TextField
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
borderRadius: '10px',
},
}}
{...props}
ref={ref}
/>
));
function SignUpPage({ t }) {
const schema = yup.object().shape({
name: yup.string().required(t('name_error')),
@@ -78,7 +92,7 @@ function SignUpPage({ t }) {
name="name"
control={control}
render={({ field }) => (
<TextField
<StyledTextField
{...field}
className="mb-28"
label={t('name')}
@@ -89,11 +103,6 @@ function SignUpPage({ t }) {
variant="outlined"
required
fullWidth
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
},
}}
/>
)}
/>
@@ -102,7 +111,7 @@ function SignUpPage({ t }) {
name="email"
control={control}
render={({ field }) => (
<TextField
<StyledTextField
{...field}
className="mb-28"
label={t('email')}
@@ -112,11 +121,6 @@ function SignUpPage({ t }) {
variant="outlined"
required
fullWidth
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
},
}}
/>
)}
/>
@@ -125,7 +129,7 @@ function SignUpPage({ t }) {
name="password"
control={control}
render={({ field }) => (
<TextField
<StyledTextField
{...field}
className="mb-28"
label={t('password')}
@@ -135,11 +139,6 @@ function SignUpPage({ t }) {
variant="outlined"
required
fullWidth
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
},
}}
/>
)}
/>
@@ -148,7 +147,7 @@ function SignUpPage({ t }) {
name="passwordConfirm"
control={control}
render={({ field }) => (
<TextField
<StyledTextField
{...field}
className="mb-28"
label={t('password_confirm')}
@@ -158,11 +157,6 @@ function SignUpPage({ t }) {
variant="outlined"
required
fullWidth
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
},
}}
/>
)}
/>

View File

@@ -1,7 +1,67 @@
import { memo } from 'react';
import { useEffect, useState } from 'react';
import { withTranslation } from 'react-i18next';
import AboutUs from './components/AboutUs';
import ArticleCardsList from './components/ArticleCardsList';
import FeedbackForm from './components/FeedbackForm';
import Statistics from './components/Statistics';
import Welcome from './components/Welcome';
function Home(props) {
return <div>Heeeeelloooooo!</div>;
const articleCardsMock = [
{
id: '123',
title: 'Lorem ipsum dolor sit amet ornare amet consequat ultricies auctor.',
description:
'Lorem ipsum dolor sit amet consectetur. Quam molestie non eget rhoncus ut sed. Egestas scelerisque fames lorem id luctus viverra ligula placerat mus. Lorem ipsum dolor sit amet consectetur. Quam molestie non eget rhoncus ut sed. Egestas scelerisque fames lorem id luctus viverra ligula placmeget rhoncus ut settrnhg ips...',
image:
'https://images.unsplash.com/photo-1664575602276-acd073f104c1?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1170&q=80',
updated: '12.12.2022',
},
{
id: '234',
title: 'Lorem ipsum dolor sit amet ornare amet consequat us auctoit amet orare ametr...',
description:
'Lorem ipsum dolor sit amet consectetur. Quam molestie non eget rhoncusnon eget rhoncus ut sed. Egestas scelerisque fames lorem id luctus viverra ligula placerat mus.',
image:
'https://images.unsplash.com/photo-1664575602276-acd073f104c1?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1170&q=80',
updated: '12.12.2022',
},
{
id: '345',
title: 'Lorem ipsum dolor sit amet ornare amet consequat ultricies auctor.',
description:
'Lorem ipsum dolor sit amet consectetur. Quam molestie non eget rhoncus ut sed. Egestas scelerisque fames lorem id luctus viverra ligula placerat mus. Lorem ipsum dolor sit amet consectetur. Quames lorem id luctus viverra ligula placerat mus.',
image:
'https://images.unsplash.com/photo-1664575602276-acd073f104c1?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1170&q=80',
updated: '12.12.2022',
},
];
function Home({ t }) {
const [servicesCards, setServicesCards] = useState([]);
const [blogCards, setBlogCards] = useState([]);
useEffect(() => {
setServicesCards(articleCardsMock);
setBlogCards(articleCardsMock);
}, []);
return (
<div className="w-full bg-primary-main">
<Welcome />
<div className="max-w-8xl w-full px-10 mx-auto">
<Statistics />
<AboutUs />
<ArticleCardsList title={t('services_title')} cards={servicesCards} className="mb-20" />
<ArticleCardsList
title={t('blog_title')}
cards={blogCards}
id="blog"
className="pt-72 mb-28"
/>
<FeedbackForm />
</div>
</div>
);
}
export default memo(Home);
export default withTranslation('homePage')(Home);

View File

@@ -0,0 +1,37 @@
import { memo } from 'react';
import { withTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
function AboutUs({ t }) {
return (
<section id="about-us" className="flex flex-col items-center pt-72 mb-80">
<h2 className="self-start mb-56 text-[48px] font-semibold">{t('about_us_title')}</h2>
<div className="flex gap-64 mb-[126px]">
<div className="flex items-center">
<iframe
className="rounded-[20px]"
width="715"
height="402"
src="https://www.youtube.com/embed/rNSIwjmynYQ?controls=0"
title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
/>
</div>
<aside className="flex flex-col items-center py-40 px-52 bg-primary-light rounded-[20px]">
<h3 className="mb-16 text-lg text-common-layout font-medium">{t('about_us_subject')}</h3>
<p className="mb-16 text-lg text-common-layout font-light">{t('about_us_text_1')}</p>
<p className="mb-16 text-lg text-common-layout font-light">{t('about_us_text_2')}</p>
</aside>
</div>
<Link
className="w-[220px] py-[17px] text-center text-base text-primary-light font-semibold tracking-widest uppercase rounded-2xl bg-secondary-light shadow hover:shadow-hover hover:shadow-secondary-light ease-in-out duration-300"
to="/rent-and-buy"
>
{t('research_btn')}
</Link>
</section>
);
}
export default withTranslation('homePage')(memo(AboutUs));

View File

@@ -0,0 +1,33 @@
import { memo } from 'react';
import { withTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
function ArticleCard({ t, id, title, description, image, updated }) {
return (
<article className="flex flex-col justify-between max-w-[460px] w-full h-[526px] bg-primary-light rounded-[20px] shadow-light">
<div>
<img
className="w-full h-[230px] mb-20 rounded-[20px] object-cover"
src={image}
alt={title}
width="460"
height="230"
loading="lazy"
/>
<h3 className="px-[15px] mb-20 text-xl leading-light font-medium">{title}</h3>
<p className="px-[15px] text-lg text-common-layout font-light">{description}</p>
</div>
<div className="px-[15px] mb-[17px] flex justify-between items-center">
<p className="text-lg text-common-secondary font-light">{updated}</p>
<Link
className="flex items-center justify-center w-[60px] h-[60px] text-secondary-main rounded-full border-2 border-secondary-main"
to={`/blog/${id}`}
>
{t('article_btn')}
</Link>
</div>
</article>
);
}
export default withTranslation('homePage')(memo(ArticleCard));

View File

@@ -0,0 +1,17 @@
import { memo } from 'react';
import ArticleCard from './ArticleCard';
function ArticleCardsList({ title, cards, ...attrs }) {
return (
<section {...attrs}>
<h2 className="mb-56 text-[48px] font-semibold">{title}</h2>
<div className="flex gap-20">
{cards.map((card) => (
<ArticleCard {...card} key={card.id} />
))}
</div>
</section>
);
}
export default memo(ArticleCardsList);

View File

@@ -0,0 +1,157 @@
import { yupResolver } from '@hookform/resolvers/yup';
import _ from '@lodash';
import Button from '@mui/material/Button';
import TextField from '@mui/material/TextField';
import { forwardRef, memo, useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { withTranslation } from 'react-i18next';
import * as yup from 'yup';
const defaultValues = {
name: '',
email: '',
message: '',
};
const StyledTextField = forwardRef((props, ref) => (
<TextField
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
borderRadius: '10px',
},
}}
{...props}
ref={ref}
/>
));
function FeedbackForm({ t }) {
const [isFormSubmitted, setIsFormSubmitted] = useState(false);
const schema = yup.object().shape({
name: yup.string().required(t('feedback_required')),
email: yup.string().email(t('feedback_email_error')).required(t('feedback_required')),
message: yup
.string()
.required(t('feedback_required'))
.min(5, t('min_length_error', { length: 5 }))
.max(255, t('max_length_error', { length: 255 })),
});
const { control, formState, handleSubmit, setError } = useForm({
mode: 'onChange',
defaultValues,
resolver: yupResolver(schema),
});
const { isValid, dirtyFields, errors } = formState;
function onSubmit() {
// setError('root', 'error');
setIsFormSubmitted(true);
}
return (
<section id="contacts" className="pt-72 mb-88">
{!isFormSubmitted && (
<form
name="signinForm"
noValidate
className="grid grid-cols-2 gap-x-20 gap-y-32 px-80 py-40 bg-primary-light rounded-[20px]"
onSubmit={handleSubmit(onSubmit)}
>
<legend className="col-span-2 justify-self-center max-w-[860px] mb-8 text-4xl font-medium text-center">
{t('feedback_title')}
</legend>
<Controller
name="name"
control={control}
render={({ field }) => (
<StyledTextField
{...field}
label={t('feedback_name')}
type="text"
error={!!errors.name}
helperText={errors?.name?.message}
variant="outlined"
required
fullWidth
/>
)}
/>
<Controller
name="email"
control={control}
render={({ field }) => (
<StyledTextField
{...field}
label={t('feedback_email')}
type="email"
error={!!errors.email}
helperText={errors?.email?.message}
variant="outlined"
required
fullWidth
/>
)}
/>
<Controller
name="message"
control={control}
render={({ field }) => (
<TextField
{...field}
className="col-span-2 mb-8"
label={t('feedback_message')}
type="text"
error={!!errors.message}
helperText={errors?.message?.message}
variant="outlined"
required
multiline
rows={5}
fullWidth
InputProps={{
sx: {
padding: 0,
background: (theme) => theme.palette.background.paper,
borderRadius: '10px',
},
}}
// eslint-disable-next-line react/jsx-no-duplicate-props
inputProps={{
sx: {
padding: '16.5px 14px',
},
}}
/>
)}
/>
<div className="col-span-2 justify-self-center flex flex-col items-center justify-center gap-10 w-full">
<Button
variant="contained"
color="secondary"
className="w-[220px] text-base uppercase rounded-xl"
aria-label={t('feedback_btn')}
disabled={_.isEmpty(dirtyFields) || !isValid}
type="submit"
size="large"
>
{t('feedback_btn')}
</Button>
{errors.root?.message && (
<p className="text-l text-error-main">{errors.root?.message}</p>
)}
</div>
</form>
)}
</section>
);
}
export default withTranslation('homePage')(memo(FeedbackForm));

View File

@@ -0,0 +1,18 @@
import { memo } from 'react';
import { withTranslation } from 'react-i18next';
import StatisticsCard from './StatisticsCard';
function Statistics({ t }) {
return (
<section className="flex flex-col items-center">
<div className="flex gap-20 mb-[136px]">
<StatisticsCard title={t('stat_title_1')} text={t('stat_text_1')} />
<StatisticsCard title={t('stat_title_2')} text={t('stat_text_2')} />
<StatisticsCard title={t('stat_title_3')} text={t('stat_text_3')} />
</div>
<h2 className="max-w-[1020px] mb-4 text-5xl text-center">{t('caption')}</h2>
</section>
);
}
export default withTranslation('homePage')(memo(Statistics));

View File

@@ -0,0 +1,12 @@
import { memo } from 'react';
function StatisticsCard({ title, text }) {
return (
<article className="flex flex-col justify-start items-center max-w-[460px] w-full min-h-[356px] h-full pt-32 px-40 text-common-primary bg-primary-light rounded-[20px] shadow-light even:bg-secondary-main even:text-primary-light">
<h3 className="mb-52 text-[80px] font-semibold">{title}</h3>
<p className="text-xl leading-5 font-light">{text}</p>
</article>
);
}
export default memo(StatisticsCard);

View File

@@ -0,0 +1,41 @@
import { memo, useState } from 'react';
import { withTranslation } from 'react-i18next';
import SearchInput from '../../shared-components/SearchInput';
function Welcome({ t }) {
const [query, setQuery] = useState('');
const onInputType = (event) => {
const { target } = event;
const value = target?.value ?? '';
console.log(value);
setQuery(value);
};
const onSearch = () => {
// query
};
return (
<section className="h-[calc(100vh-72px)] mb-[105px] bg-home-welcome bg-cover">
<div className="flex flex-col max-w-8xl w-full mx-auto pt-160 px-10">
<h1 className="max-w-[910px] mb-[30px] text-7xl font-bold text-primary-light">
{t('title')}
</h1>
<p className="max-w-[820px] mb-[100px] text-2xl font-medium text-primary-light">
{t('subtitle')}
</p>
<SearchInput
mode="simple"
placeholder={t('main_input_placeholder')}
btnText={t('main_input_btn')}
query={query}
onType={onInputType}
onSearch={onSearch}
/>
</div>
</section>
);
}
export default withTranslation('homePage')(memo(Welcome));

View File

@@ -1,3 +1,41 @@
const locale = {};
const locale = {
title: 'Lorem ipsum dolor sit amet ornare amet consequat ultricies auctor.',
subtitle:
'Lorem ipsum dolor sit amet consectetur. Quam molestie non eget rhoncus ut sed. Egestas scelerisque fames lorem id luctus viverra ligula placerat mus.',
main_input_placeholder: 'Lorem ipsum dolor sit amemolestie non eget rhoncus ut sed.',
main_input_btn: 'calculate',
stat_title_1: '158',
stat_text_1:
'Lorem ipsum dolor sit amet consectetur. Quam molestie non eget rhoncus ut sed. Egestas scelerisque fames lorem id luctus viverra ligula placerat mus.',
stat_title_2: '89%',
stat_text_2:
'Lorem ipsum dolor sit amet consectetur. Quam molestie non eget rhoncus ut sed. Egestas scelerisque fames lom id luctus viverra ligula placerat mus.',
stat_title_3: '10k+',
stat_text_3:
'Egestas scelerisque fames lorem. Lorem ipsum dolor sit amet consectetur. Quam molestie non eget rhoncus ut sed. Egestas scelerisque fames lorem id luctus viverra ligula placerat mus.',
caption:
'Lorem ipsum dolor sit amet ornare amet consequat ultricies sit amet ornare amet consequat ultricie auctor.',
about_us_title: 'About us',
about_us_watch: 'Watch Demo',
about_us_subject:
'Lorem ipsum dolor sit amet consectetur. Eu amet tellus tristique viverra accumsan ac vel eu. Ut morbi tempor quam elit orci nulla mattis. Vitae vitae egestas amet at gravida montes sit. Eu sit at sapien enim platea eget arcu. Sed consectetur sit in aliquam mi tellus at scelerisque. Tempor lacus sit ut augue amet penatibus amet malesuada orci.',
about_us_text_1:
'Lorevinar adipiscing tempus interdum lobortis. Mauris porta sagittis sed tempor tra urna. Volutpat dui nisl lorem gravida enim ut habitant sit. Natoque viverra habitasse tincidunt tristique sit.',
about_us_text_2:
'Vel phasellus pellentesque duis lorem maecenas. Vestibulum dui massa elit suspendisse porttitor integer praesent. Aliquam massa ante vestibulum neque sed imperdiet rhoncus. Turpis quam sed nibh id ultricies. Mattis mattis sit enim nunc interdum adipiscing. Arcu maecenas quis eget eget nunc quam. Id et quis enim morbi magnis. Nam ut habitasse sagittis magna morbi augue at.',
research_btn: 'research',
services_title: 'Services',
blog_title: 'Blog',
article_btn: 'See',
feedback_title: 'Lorem ipsum dolor sit amet ornare amet consequat us auctoit amet orare ametr...',
feedback_name: 'Name',
feedback_email: 'Email',
feedback_email_error: 'incorrect email',
feedback_message: 'Message',
feedback_btn: 'send',
feedback_required: 'this field is required',
max_length_error: 'The maximum length is {{length}}',
min_length_error: 'The minimum length is {{length}}',
};
export default locale;

View File

@@ -12,6 +12,7 @@ import { withTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
import * as yup from 'yup';
import { toBase64 } from 'src/app/utils';
import { forwardRef } from 'react';
const MAX_PICTURE_SIZE = 5000000;
const AVAILABLE_MEDIA_TYPES = ['image/png', 'image/jpeg'];
@@ -26,6 +27,19 @@ const Root = styled(FusePageSimple)(({ theme }) => ({
'& .FusePageSimple-sidebarContent': {},
}));
const StyledTextField = forwardRef((props, ref) => (
<TextField
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
borderRadius: '10px',
},
}}
{...props}
ref={ref}
/>
));
function ProfilePage({ t }) {
const dispatch = useDispatch();
const user = useSelector(selectUser);
@@ -193,7 +207,7 @@ function ProfilePage({ t }) {
name="firstName"
control={control}
render={({ field }) => (
<TextField
<StyledTextField
{...field}
className="col-span-2"
label={t('first_name')}
@@ -202,11 +216,6 @@ function ProfilePage({ t }) {
helperText={errors?.firstName?.message}
variant="outlined"
fullWidth
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
},
}}
/>
)}
/>
@@ -215,7 +224,7 @@ function ProfilePage({ t }) {
name="lastName"
control={control}
render={({ field }) => (
<TextField
<StyledTextField
{...field}
className="col-span-2"
label={t('last_name')}
@@ -224,11 +233,6 @@ function ProfilePage({ t }) {
helperText={errors?.lastName?.message}
variant="outlined"
fullWidth
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
},
}}
/>
)}
/>
@@ -237,7 +241,7 @@ function ProfilePage({ t }) {
name="displayName"
control={control}
render={({ field }) => (
<TextField
<StyledTextField
{...field}
className="col-span-2"
label={t('display_name')}
@@ -247,11 +251,6 @@ function ProfilePage({ t }) {
variant="outlined"
required
fullWidth
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
},
}}
/>
)}
/>
@@ -260,7 +259,7 @@ function ProfilePage({ t }) {
name="email"
control={control}
render={({ field }) => (
<TextField
<StyledTextField
{...field}
className="col-span-3"
label={t('email')}
@@ -270,11 +269,6 @@ function ProfilePage({ t }) {
variant="outlined"
required
fullWidth
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
},
}}
/>
)}
/>
@@ -283,7 +277,7 @@ function ProfilePage({ t }) {
name="mobileNumber"
control={control}
render={({ field }) => (
<TextField
<StyledTextField
{...field}
className="col-span-3"
label={t('mobile_number')}
@@ -292,11 +286,6 @@ function ProfilePage({ t }) {
helperText={errors?.mobileNumber?.message}
variant="outlined"
fullWidth
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
},
}}
/>
)}
/>
@@ -318,8 +307,9 @@ function ProfilePage({ t }) {
fullWidth
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
padding: 0,
background: (theme) => theme.palette.background.paper,
borderRadius: '10px',
},
}}
// eslint-disable-next-line react/jsx-no-duplicate-props
@@ -349,8 +339,9 @@ function ProfilePage({ t }) {
fullWidth
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
padding: 0,
background: (theme) => theme.palette.background.paper,
borderRadius: '10px',
},
}}
// eslint-disable-next-line react/jsx-no-duplicate-props

View File

@@ -0,0 +1,55 @@
import { forwardRef, memo, useCallback } from 'react';
import TextField from '@mui/material/TextField';
import Button from '@mui/material/Button';
import _ from '@lodash';
const StyledTextField = forwardRef((props, ref) => (
<TextField
InputProps={{
sx: {
background: (theme) => theme.palette.background.paper,
borderRadius: '15px',
borderColor: (theme) => theme.palette.secondary.light,
borderWidth: '1px',
boxShadow: '1px 1px 4px 0px rgba(0, 0, 0, 0.25)',
},
}}
{...props}
ref={ref}
/>
));
function SearchInput({ mode, placeholder, btnText, query, onType, onSearch }) {
const isSimpleMode = mode === 'simple';
const debouncedOnType = useCallback(_.debounce(onType, 250), [onType]);
return (
<form className="flex items-center gap-20">
<StyledTextField
type="text"
variant="outlined"
className="max-w-[620px] w-full bourder-0"
defaultValue={query}
placeholder={placeholder}
onChange={debouncedOnType}
/>
{isSimpleMode && (
<Button
variant="contained"
color="inherit"
className="text-center text-base text-primary-light font-semibold tracking-widest uppercase rounded-2xl bg-secondary-light shadow hover:shadow-hover hover:shadow-secondary-light ease-in-out duration-300"
aria-label={btnText}
type="button"
size="large"
onClick={onSearch}
>
{btnText}
</Button>
)}
</form>
);
}
export default memo(SearchInput);

View File

@@ -1,39 +0,0 @@
import { forwardRef, useState } from 'react';
import { styled } from '@mui/material/styles';
import { convertToRaw, EditorState } from 'draft-js';
import { Editor } from 'react-draft-wysiwyg';
import draftToHtml from 'draftjs-to-html';
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';
import clsx from 'clsx';
const Root = styled('div')({
'& .rdw-dropdown-selectedtext': {
color: 'inherit',
},
'& .rdw-editor-toolbar': {
borderWidth: '0 0 1px 0!important',
margin: '0!important',
},
'& .rdw-editor-main': {
padding: '8px 12px',
height: `${256}px!important`,
},
});
const WYSIWYGEditor = forwardRef((props, ref) => {
const [editorState, setEditorState] = useState(EditorState.createEmpty());
function onEditorStateChange(_editorState) {
setEditorState(_editorState);
return props.onChange(draftToHtml(convertToRaw(_editorState.getCurrentContent())));
}
return (
<Root className={clsx('rounded-4 border-1 overflow-hidden w-full', props.className)} ref={ref}>
<Editor editorState={editorState} onEditorStateChange={onEditorStateChange} />
</Root>
);
});
export default WYSIWYGEditor;

View File

@@ -2,12 +2,14 @@ import FuseDialog from '@fuse/core/FuseDialog';
import FuseMessage from '@fuse/core/FuseMessage';
import FuseSuspense from '@fuse/core/FuseSuspense';
import { styled } from '@mui/material/styles';
import Hidden from '@mui/material/Hidden';
import AppContext from 'src/app/contexts/AppContext';
import { selectFuseCurrentLayoutConfig } from 'app/store/fuse/settingsSlice';
import { memo, useContext } from 'react';
import { useSelector } from 'react-redux';
import { useRoutes } from 'react-router-dom';
import NavbarWrapperLayout1 from './components/NavbarWrapperLayout1';
import NavbarToggleButton from '../shared-components/NavbarToggleButton';
const Root = styled('div')(({ theme, config }) => ({
...(config.mode === 'boxed' && {
@@ -36,6 +38,10 @@ function Layout1(props) {
{config.navbar.display && config.navbar.position === 'left' && <NavbarWrapperLayout1 />}
<main id="fuse-main" className="flex flex-col flex-auto min-h-full min-w-0 relative z-10">
<Hidden lgUp>
<NavbarToggleButton className="w-40 h-40 p-0 mx-0 sm:mx-8" />
</Hidden>
<div className="flex flex-col flex-auto min-h-0 relative z-10">
<FuseDialog />

View File

@@ -2,9 +2,9 @@ import FuseSuspense from '@fuse/core/FuseSuspense';
import AppContext from 'src/app/contexts/AppContext';
import { selectFuseCurrentLayoutConfig } from 'app/store/fuse/settingsSlice';
import i18next from 'i18next';
import { memo, useContext } from 'react';
import { memo, useContext, useEffect } from 'react';
import { useSelector } from 'react-redux';
import { useRoutes } from 'react-router-dom';
import { useLocation, useRoutes } from 'react-router-dom';
import { useAuth } from 'src/app/contexts/AuthContext';
import FooterLayout2 from './components/FooterLayout2';
import HeaderLayout2 from './components/HeaderLayout2';
@@ -18,6 +18,16 @@ function Layout2(props) {
const authContext = useAuth();
const appContext = useContext(AppContext);
const { routes } = appContext;
const location = useLocation();
useEffect(() => {
const { hash } = location;
if (hash) {
const target = document.querySelector(hash);
target.scrollIntoView({ behavior: 'smooth' });
}
}, [location]);
return (
<>

View File

@@ -1,7 +1,7 @@
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import linksConfigLayout2 from './linksLayout2Config';
import NavLinks from './NavLinks';
function FooterLayout2() {
const { t } = useTranslation('layout2');
@@ -35,14 +35,8 @@ function FooterLayout2() {
</a>
</li>
</ul>
<ul className="flex flex-col gap-16 mt-96">
{linksConfigLayout2.map((path) => (
<li key={path}>
<Link className="text-lg leading-5 text-white no-underline" to={`/${path}`}>
{t(path)}
</Link>
</li>
))}
<ul className="flex flex-col gap-16 mt-[61px]">
<NavLinks className="text-lg leading-5 text-white no-underline" />
</ul>
</div>
</footer>

View File

@@ -2,7 +2,7 @@ import FuseSvgIcon from '@fuse/core/FuseSvgIcon/FuseSvgIcon';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import linksConfigLayout2 from './linksLayout2Config';
import Links from './NavLinks';
function HeaderLayout2(props) {
const { t } = useTranslation('layout2');
@@ -19,15 +19,7 @@ function HeaderLayout2(props) {
</Link>
<nav className="flex grow justify-center gap-72 items-center">
{linksConfigLayout2.map((path) => (
<Link
className="text-lg leading-5 text-common-layout no-underline"
to={`/${path}`}
key={path}
>
{t(path)}
</Link>
))}
<Links className="text-lg leading-5 text-common-layout no-underline" />
</nav>
{props.isAuthenticated || (

View File

@@ -0,0 +1,26 @@
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
function NavLinks({ className }) {
const { t } = useTranslation('layout2');
return (
<>
<Link className={className} to="/rent-and-buy">
{t('rent_and_buy')}
</Link>
<Link className={className} to={{ hash: 'about-us' }}>
{t('about_us')}
</Link>
<Link className={className} to={{ hash: 'blog' }}>
{t('blog')}
</Link>
<Link className={className} to={{ hash: 'contacts' }}>
{t('contacts')}
</Link>
</>
);
}
export default memo(NavLinks);

View File

@@ -1,3 +0,0 @@
const linksConfigLayout2 = ['rent-and-buy', 'about-us', 'blog', 'contacts'];
export default linksConfigLayout2;

View File

@@ -1,6 +1,6 @@
const locale = {
'rent-and-buy': 'Rent&Buy Analysis',
'about-us': 'About Us',
rent_and_buy: 'Rent&Buy Analysis',
about_us: 'About Us',
blog: 'Blog',
contacts: 'Contacts',
sign_in: 'Log In',

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

View File

@@ -1,5 +0,0 @@
const en = {
translation: {},
};
export default en;

View File

@@ -1,9 +1,12 @@
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import en from './assets/locales/en';
// the translations
// (tip move them in a JSON file and import them)
const resources = {
en,
en: {
translation: {},
},
};
i18n

View File

@@ -1,153 +1,162 @@
/**
* Custom base styles
*/
* {
/* Text rendering */
text-rendering: optimizeLegibility;
-o-text-rendering: optimizeLegibility;
-ms-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility;
-webkit-text-rendering: optimizeLegibility;
-webkit-tap-highlight-color: transparent;
/* Text rendering */
text-rendering: optimizeLegibility;
-o-text-rendering: optimizeLegibility;
-ms-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility;
-webkit-text-rendering: optimizeLegibility;
-webkit-tap-highlight-color: transparent;
}
* :focus {
outline: none !important;
outline: none !important;
}
html {
font-size: 62.5%;
font-family: 'Inter var', Roboto, Helvetica Neue, Arial, sans-serif;
background-color: #121212;
font-size: 62.5%;
font-family: 'Inter var', Roboto, Helvetica Neue, Arial, sans-serif;
background-color: #121212;
}
body {
font-size: 14px;
line-height: 1.4;
overflow-x: hidden;
font-feature-settings: "salt";
font-size: 14px;
line-height: normal;
overflow-x: hidden;
font-feature-settings: 'salt';
}
html, body {
-webkit-font-smoothing: auto;
-moz-osx-font-smoothing: auto;
html,
body {
-webkit-font-smoothing: auto;
-moz-osx-font-smoothing: auto;
}
html, body {
display: flex;
flex-direction: column;
position: relative;
margin: 0;
min-height: 100%;
width: 100%;
flex: 1 1 auto;
html,
body {
display: flex;
flex-direction: column;
position: relative;
margin: 0;
min-height: 100%;
width: 100%;
flex: 1 1 auto;
}
#root {
display: flex;
flex-direction: column;
flex: 1 1 auto;
width: 100%;
height: 100%;
display: flex;
flex: 1 1 auto;
width: 100%;
height: 100%;
}
/* layout 2 workaround */
#root:has(> #fuse-main) {
flex-direction: column;
}
h1, .h1 {
font-size: 24px;
h1,
.h1 {
font-size: 24px;
}
h2, .h2 {
font-size: 20px;
h2,
.h2 {
font-size: 20px;
}
h3, .h3 {
font-size: 16px;
h3,
.h3 {
font-size: 16px;
}
h4, .h4 {
font-size: 15px;
h4,
.h4 {
font-size: 15px;
}
h5, .h5 {
font-size: 13px;
h5,
.h5 {
font-size: 13px;
}
h6, .h6 {
font-size: 12px;
h6,
.h6 {
font-size: 12px;
}
.ps > .ps__rail-y,
.ps > .ps__rail-x {
z-index: 99;
z-index: 99;
}
a[role=button] {
text-decoration: none;
a[role='button'] {
text-decoration: none;
}
[role="tooltip"] {
z-index: 9999;
[role='tooltip'] {
z-index: 9999;
}
.MuiModal-root {
/*z-index: 9999;*/
/*z-index: 9999;*/
}
/* Medium Devices, Desktops Only */
@media only screen and (min-width: 992px) {
::-webkit-scrollbar {
width: 8px;
height: 8px;
background-color: rgba(0, 0, 0, 0);
}
::-webkit-scrollbar {
width: 8px;
height: 8px;
background-color: rgba(0, 0, 0, 0);
}
::-webkit-scrollbar:hover {
width: 8px;
height: 8px;
background-color: rgba(0, 0, 0, 0.06);
}
::-webkit-scrollbar:hover {
width: 8px;
height: 8px;
background-color: rgba(0, 0, 0, 0.06);
}
::-webkit-scrollbar-thumb {
border: 2px solid transparent;
border-radius: 20px;
}
::-webkit-scrollbar-thumb {
border: 2px solid transparent;
border-radius: 20px;
}
::-webkit-scrollbar-thumb:active {
border-radius: 20px;
}
::-webkit-scrollbar-thumb:active {
border-radius: 20px;
}
}
form label {
z-index: 99;
z-index: 99;
}
body.no-animate *,
body.no-animate *::before,
body.no-animate *::after {
transition: none !important;
animation: none !important;
transition: none !important;
animation: none !important;
}
button:focus {
outline: none;
outline: none;
}
/* Removes webkit's autofill backgorund color */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active
{
transitionDelay: 9999s;
transitionProperty: background-color, color;
input:-webkit-autofill:active {
transitiondelay: 9999s;
transitionproperty: background-color, color;
}
:focus {
outline-color: transparent;
outline-color: transparent;
}
/*fullcalendar Fix*/
.fc-scrollgrid-section-liquid {
height: 1px !important;
height: 1px !important;
}

View File

@@ -53,6 +53,7 @@ module.exports = {
'gradient-to-bl': 'linear-gradient(to bottom left, var(--tw-gradient-stops))',
'gradient-to-l': 'linear-gradient(to left, var(--tw-gradient-stops))',
'gradient-to-tl': 'linear-gradient(to top left, var(--tw-gradient-stops))',
'home-welcome': 'url(/src/assets/images/welcome-background.webp)',
},
backgroundOpacity: ({ theme }) => theme('opacity'),
backgroundPosition: {
@@ -130,6 +131,7 @@ module.exports = {
'2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
inner: 'inset 0 2px 4px 0 rgba(0,0,0,0.06)',
none: 'none',
light: '1px 1px 5px 0px rgba(0, 0, 0, 0.1)',
active: '2px 2px 5px 0px rgba(0, 0, 0, 0.2)',
hover: '2px 2px 5px 0px rgba(0, 0, 0, 0.4)',
0: '0px 0px 0px 0px rgba(0, 0, 0, 0.2), 0px 0px 0px 0px rgba(0, 0, 0, 0.14), 0px 0px 0px 0px rgba(0, 0, 0, 0.12)',
@@ -1258,6 +1260,7 @@ module.exports = {
'5xl': '102.4rem',
'6xl': '115.2rem',
'7xl': '128rem',
'8xl': '142rem',
px: '1px',
0: '0px',
0.5: '0.05rem',