RC-7-home-page (#5)
https://ru.yougile.com/team/a605078664af/#chat:2ae00178ba0d Reviewed-on: #5
This commit is contained in:
@@ -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: '';
|
||||
}
|
||||
|
||||
@@ -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
20
src/app/hooks/index.js
Normal 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;
|
||||
}
|
||||
@@ -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,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -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);
|
||||
|
||||
37
src/app/main/home/components/AboutUs.js
Normal file
37
src/app/main/home/components/AboutUs.js
Normal 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));
|
||||
33
src/app/main/home/components/ArticleCard.js
Normal file
33
src/app/main/home/components/ArticleCard.js
Normal 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));
|
||||
17
src/app/main/home/components/ArticleCardsList.js
Normal file
17
src/app/main/home/components/ArticleCardsList.js
Normal 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);
|
||||
157
src/app/main/home/components/FeedbackForm.js
Normal file
157
src/app/main/home/components/FeedbackForm.js
Normal 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));
|
||||
18
src/app/main/home/components/Statistics.js
Normal file
18
src/app/main/home/components/Statistics.js
Normal 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));
|
||||
12
src/app/main/home/components/StatisticsCard.js
Normal file
12
src/app/main/home/components/StatisticsCard.js
Normal 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);
|
||||
41
src/app/main/home/components/Welcome.js
Normal file
41
src/app/main/home/components/Welcome.js
Normal 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));
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
55
src/app/main/shared-components/SearchInput.js
Normal file
55
src/app/main/shared-components/SearchInput.js
Normal 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);
|
||||
@@ -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;
|
||||
@@ -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 />
|
||||
|
||||
|
||||
@@ -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 (
|
||||
<>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 || (
|
||||
|
||||
26
src/app/theme-layouts/layout2/components/NavLinks.js
Normal file
26
src/app/theme-layouts/layout2/components/NavLinks.js
Normal 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);
|
||||
@@ -1,3 +0,0 @@
|
||||
const linksConfigLayout2 = ['rent-and-buy', 'about-us', 'blog', 'contacts'];
|
||||
|
||||
export default linksConfigLayout2;
|
||||
@@ -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',
|
||||
|
||||
BIN
src/assets/images/welcome-background.webp
Normal file
BIN
src/assets/images/welcome-background.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 MiB |
@@ -1,5 +0,0 @@
|
||||
const en = {
|
||||
translation: {},
|
||||
};
|
||||
|
||||
export default en;
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user