OPS-249: Add loader and fix app init (#12)

This commit is contained in:
Rinat Arsaev 2023-01-27 13:58:48 +06:00 committed by GitHub
parent ebc9742354
commit 389f405a4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 422 additions and 209 deletions

View File

@ -3,6 +3,6 @@
<component name="PrettierConfiguration">
<option name="myRunOnSave" value="true" />
<option name="myRunOnReformat" value="true" />
<option name="myFilesPattern" value="{**/*,*}.{js,ts,jsx,tsx,json,md}" />
<option name="myFilesPattern" value="{**/*,*}.{js,ts,jsx,tsx,json,md,css}" />
</component>
</project>

View File

@ -0,0 +1,31 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="prod" type="js.build_tools.npm">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="serve" />
</scripts>
<node-interpreter value="project" />
<envs />
<method v="2">
<option name="NpmBeforeRunTask" enabled="true">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="clean" />
</scripts>
<node-interpreter value="project" />
<envs />
</option>
<option name="NpmBeforeRunTask" enabled="true">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="build" />
</scripts>
<node-interpreter value="project" />
<envs />
</option>
</method>
</configuration>
</component>

View File

@ -1,11 +1,30 @@
import * as React from "react";
import type { GatsbyBrowser } from "gatsby";
import { Layout } from "./src/components/Layout";
import { createGlobalStyle } from "./src/styles/global-styles";
import { Global } from "@emotion/react";
import { ThemeProvider } from "@mui/system";
import type { GatsbyBrowser } from "gatsby";
import { Layout } from "./src/components/Layout";
import { createGlobalStyle } from "./src/styles/global-styles";
import { theme } from "./src/theme/theme";
import "./src/styles/global-styles.css";
import "./src/styles/browser-styles.css";
const getLoaderElements = () => {
return [
document.getElementsByClassName("loader").item(0) as HTMLDivElement,
document.getElementsByClassName("loader-wrapper").item(0) as HTMLDivElement,
];
};
export const onInitialClientRender = () => {
getLoaderElements().forEach((el) => (el.style.opacity = "0"));
setTimeout(() => {
document.body.removeChild(getLoaderElements()[1]);
}, 1000);
};
export const wrapPageElement: GatsbyBrowser["wrapPageElement"] = ({
element,
}) => {

View File

@ -9,6 +9,7 @@ const config: GatsbyConfig = {
// If you use VSCode you can also use the GraphQL plugin
// Learn more at: https://gatsby.dev/graphql-typegen
graphqlTypegen: true,
flags: { DEV_SSR: false },
plugins: [
"gatsby-plugin-emotion",
"gatsby-plugin-image",

6
gatsby-ssr.tsx Normal file
View File

@ -0,0 +1,6 @@
import { GatsbySSR } from "gatsby";
import { wrapPageElement as wrapPageElementBrowser } from "./gatsby-browser";
export const wrapPageElement: GatsbySSR["wrapPageElement"] =
wrapPageElementBrowser;

50
package-lock.json generated
View File

@ -11,6 +11,7 @@
"@emotion/css": "^11.10.5",
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@loadable/component": "^5.15.2",
"@mdx-js/react": "^2.2.1",
"@mui/base": "^5.0.0-alpha.110",
"@mui/material": "^5.11.1",
@ -37,6 +38,7 @@
"devDependencies": {
"@babel/cli": "^7.19.3",
"@babel/plugin-transform-typescript": "^7.20.2",
"@types/loadable__component": "^5.13.4",
"@types/node": "^18.11.10",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",
@ -2818,6 +2820,26 @@
"win32"
]
},
"node_modules/@loadable/component": {
"version": "5.15.2",
"resolved": "https://registry.npmjs.org/@loadable/component/-/component-5.15.2.tgz",
"integrity": "sha512-ryFAZOX5P2vFkUdzaAtTG88IGnr9qxSdvLRvJySXcUA4B4xVWurUNADu3AnKPksxOZajljqTrDEDcYjeL4lvLw==",
"dependencies": {
"@babel/runtime": "^7.7.7",
"hoist-non-react-statics": "^3.3.1",
"react-is": "^16.12.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/gregberge"
},
"peerDependencies": {
"react": ">=16.3.0"
}
},
"node_modules/@mdx-js/mdx": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-2.2.1.tgz",
@ -4271,6 +4293,15 @@
"keyv": "*"
}
},
"node_modules/@types/loadable__component": {
"version": "5.13.4",
"resolved": "https://registry.npmjs.org/@types/loadable__component/-/loadable__component-5.13.4.tgz",
"integrity": "sha512-YhoCCxyuvP2XeZNbHbi8Wb9EMaUJuA2VGHxJffcQYrJKIKSkymJrhbzsf9y4zpTmr5pExAAEh5hbF628PAZ8Dg==",
"dev": true,
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/lodash": {
"version": "4.14.182",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz",
@ -21042,6 +21073,16 @@
"integrity": "sha512-cK+Elf3RjEzrm3SerAhrFWL5oQAsZSJ/LmjL1joIpTfEP1etJJ9CTRvdaV6XLYAxaEkfdhk/9hOvHLbR9yIhCA==",
"optional": true
},
"@loadable/component": {
"version": "5.15.2",
"resolved": "https://registry.npmjs.org/@loadable/component/-/component-5.15.2.tgz",
"integrity": "sha512-ryFAZOX5P2vFkUdzaAtTG88IGnr9qxSdvLRvJySXcUA4B4xVWurUNADu3AnKPksxOZajljqTrDEDcYjeL4lvLw==",
"requires": {
"@babel/runtime": "^7.7.7",
"hoist-non-react-statics": "^3.3.1",
"react-is": "^16.12.0"
}
},
"@mdx-js/mdx": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-2.2.1.tgz",
@ -21973,6 +22014,15 @@
"keyv": "*"
}
},
"@types/loadable__component": {
"version": "5.13.4",
"resolved": "https://registry.npmjs.org/@types/loadable__component/-/loadable__component-5.13.4.tgz",
"integrity": "sha512-YhoCCxyuvP2XeZNbHbi8Wb9EMaUJuA2VGHxJffcQYrJKIKSkymJrhbzsf9y4zpTmr5pExAAEh5hbF628PAZ8Dg==",
"dev": true,
"requires": {
"@types/react": "*"
}
},
"@types/lodash": {
"version": "4.14.182",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz",

View File

@ -19,6 +19,7 @@
"@emotion/css": "^11.10.5",
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@loadable/component": "^5.15.2",
"@mdx-js/react": "^2.2.1",
"@mui/base": "^5.0.0-alpha.110",
"@mui/material": "^5.11.1",
@ -45,6 +46,7 @@
"devDependencies": {
"@babel/cli": "^7.19.3",
"@babel/plugin-transform-typescript": "^7.20.2",
"@types/loadable__component": "^5.13.4",
"@types/node": "^18.11.10",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",

View File

@ -10,6 +10,11 @@ import { Menu, MenuItem } from "~/components/Menu";
import { Link } from "./Link";
interface Props {
small?: boolean;
direction?: "top";
}
export const PAGE_IDS = {
ourProducts: "our-products",
processing: "processing",
@ -25,10 +30,7 @@ const LINKS = [
];
export const AppNav: React.FC<
Omit<ComponentProps<typeof Stack>, "direction"> & {
small?: boolean;
direction?: "top";
}
ComponentProps<typeof Menu | typeof Stack> & Props
> = ({ small, direction, ...props }) => {
return small ? (
<Menu
@ -36,6 +38,7 @@ export const AppNav: React.FC<
button={
<Button variant="outlined" color="primary" endIcon={<MenuIcon />} />
}
{...props}
>
{LINKS.map((link) => (
<MenuItem key={link.id} href={`#${link.id}`} target="_self">

View File

@ -30,6 +30,7 @@ export const BackgroundImageBox: React.FC<
z-index: 0;
`}
style={imgStyle}
alt=""
/>
</div>
);

View File

@ -3,32 +3,38 @@ import React, { ReactNode, ComponentProps } from "react";
import styled from "@emotion/styled";
import { Box, Container, Stack } from "@mui/system";
interface Props extends Omit<ComponentProps<typeof Box>, "title"> {
import { theme } from "~/theme/theme";
interface Props {
title?: ReactNode;
inverted?: boolean;
}
export const StyledBlock = styled(Box)<Props>`
background-color: ${({ theme, inverted }) =>
export const StyledBlock = styled(Box)<{ styled: Props }>`
background-color: ${({ theme, styled: { inverted } }) =>
inverted ? theme?.palette?.primary?.[900] : theme?.palette?.common?.white};
padding: ${({ theme }) =>
`${theme?.spacing?.(11)} 0 ${theme?.spacing?.(17)}`};
padding: ${({ theme }) => theme?.spacing?.(11)} 0 ${theme?.spacing?.(17)};
overflow: hidden;
&,
.text {
color: ${({ theme, inverted }) =>
color: ${({ theme, styled: { inverted } }) =>
inverted ? theme?.palette?.common?.white : theme?.palette?.text?.primary};
}
`;
export const Block: React.FC<Props> = ({ title, children, ...props }) => {
export const Block: React.FC<ComponentProps<typeof Box> & Props> = ({
title,
inverted,
children,
...props
}) => {
return (
<StyledBlock {...props}>
<StyledBlock {...props} styled={{ title, inverted }}>
<Container fixed>
<Stack spacing={5.5}>
{title && (
<Box className="text" sx={{ typography: "h2" }}>
<Box className="text" typography="h2">
{title}
</Box>
)}

View File

@ -21,50 +21,95 @@ function getColoredSvgCss(params: SvgColoredParam[] = [], color: string) {
return css(Object.fromEntries(params?.map?.((p) => [p, color]) || []));
}
const ButtonWrapper = styled(ButtonUnstyled)<Props & { hasText: boolean }>(
({ theme, color, variant, size, svgColoredParams, hasText }) => {
const buttonSizes = {
large: 6,
medium: 4,
small: 4,
};
const iconSizes = {
large: 3,
medium: 2,
small: 2,
};
const buttonSize = theme?.spacing?.(buttonSizes[size ?? "medium"]);
const iconSize =
variant === "text"
? buttonSize
: theme?.spacing?.(iconSizes[size ?? "medium"]);
return css`
${css(theme?.typography?.button)}
const StyledButton = styled(ButtonUnstyled)<{
styled: Props & { hasText: boolean };
}>(({ theme, color, styled: { variant, size, svgColoredParams, hasText } }) => {
const buttonSizes = {
large: 6,
medium: 4,
small: 4,
};
const iconSizes = {
large: 3,
medium: 2,
small: 2,
};
const buttonSize = theme?.spacing?.(buttonSizes[size ?? "medium"]);
const iconSize =
variant === "text"
? buttonSize
: theme?.spacing?.(iconSizes[size ?? "medium"]);
return css`
${css(theme?.typography?.button)}
background-color: ${variant === "text"
? "transparent"
: color
? theme?.palette?.[color]?.[variant === "contained" ? "A400" : 900]
: "#fff"};
color: ${color ? theme?.palette?.[color]?.contrastText : undefined};
white-space: nowrap;
background-color: ${variant === "text"
? "transparent"
: color
? theme?.palette?.[color]?.[variant === "contained" ? "A400" : 900]
: "#fff"};
color: ${color ? theme?.palette?.[color]?.contrastText : undefined};
white-space: nowrap;
border-radius: ${theme?.spacing?.(size === "large" ? 1.5 : 1)};
height: ${buttonSize};
line-height: ${buttonSize};
min-width: ${buttonSize};
padding: 0 ${hasText ? theme?.spacing?.(3) : 0};
border-radius: ${theme?.spacing?.(size === "large" ? 1.5 : 1)};
height: ${buttonSize};
line-height: ${buttonSize};
min-width: ${buttonSize};
padding: 0 ${hasText ? theme?.spacing?.(3) : 0};
border: ${variant === "outlined"
? `1px solid ${theme?.palette?.primary?.[700]}`
: "none"};
border: ${variant === "outlined"
? `1px solid ${theme?.palette?.primary?.[700]}`
: "none"};
cursor: pointer;
cursor: pointer;
&,
* {
transition: all 200ms ease;
}
* {
${getColoredSvgCss(
svgColoredParams,
variant === "text"
? theme?.palette?.common?.white
: color === "primary"
? theme?.palette?.text?.primary
: theme?.palette?.grey?.[800]
)}
}
svg {
height: ${iconSize};
width: ${iconSize};
}
&:hover {
box-shadow: ${color === "primary" && variant === "contained"
? "0px 5px 15px rgba(82, 116, 199, 0.7)"
: undefined};
color: ${color === "primary" ? undefined : theme?.palette?.grey?.[800]};
&,
* {
transition: all 200ms ease;
${getColoredSvgCss(
svgColoredParams,
variant === "text"
? theme?.palette?.common?.white
: color
? ""
: theme?.palette?.text?.primary
)}
}
}
&.${buttonUnstyledClasses.active} {
background-color: ${variant === "text"
? ""
: color
? theme?.palette?.[color]?.[400]
: theme?.palette?.grey?.[100]};
box-shadow: ${color || variant === "text"
? undefined
: `0px 0px 0px 1px ${theme?.palette?.grey?.[800]}`};
* {
${getColoredSvgCss(
@ -76,63 +121,18 @@ const ButtonWrapper = styled(ButtonUnstyled)<Props & { hasText: boolean }>(
: theme?.palette?.grey?.[800]
)}
}
}
svg {
height: ${iconSize};
width: ${iconSize};
}
&.${buttonUnstyledClasses.focusVisible} {
outline: none;
}
&:hover {
box-shadow: ${color === "primary" && variant === "contained"
? "0px 5px 15px rgba(82, 116, 199, 0.7)"
: undefined};
color: ${color === "primary" ? undefined : theme?.palette?.grey?.[800]};
* {
${getColoredSvgCss(
svgColoredParams,
variant === "text"
? theme?.palette?.common?.white
: color
? ""
: theme?.palette?.text?.primary
)}
}
}
&.${buttonUnstyledClasses.active} {
background-color: ${variant === "text"
? ""
: color
? theme?.palette?.[color]?.[400]
: theme?.palette?.grey?.[100]};
box-shadow: ${color || variant === "text"
? undefined
: `0px 0px 0px 1px ${theme?.palette?.grey?.[800]}`};
* {
${getColoredSvgCss(
svgColoredParams,
variant === "text"
? theme?.palette?.common?.white
: color === "primary"
? theme?.palette?.text?.primary
: theme?.palette?.grey?.[800]
)}
}
}
&.${buttonUnstyledClasses.focusVisible} {
outline: none;
}
&.${buttonUnstyledClasses.disabled} {
opacity: 0.5;
cursor: not-allowed;
}
`;
}
);
&.${buttonUnstyledClasses.disabled} {
opacity: 0.5;
cursor: not-allowed;
}
`;
});
export const Button: React.FC<Props> = ({
endIcon,
@ -154,13 +154,15 @@ export const Button: React.FC<Props> = ({
: onClick;
return (
<ButtonWrapper
<StyledButton
{...props}
variant={variant || "text"}
size={size || "medium"}
onClick={clickHandler}
svgColoredParams={svgColoredParams || ["fill"]}
hasText={!!children}
styled={{
variant: variant || "text",
size: size || "medium",
svgColoredParams: svgColoredParams || ["fill"],
hasText: !!children,
}}
>
<Stack
direction="row"
@ -170,6 +172,6 @@ export const Button: React.FC<Props> = ({
{children && <Box display="flex">{children}</Box>}
{endIcon}
</Stack>
</ButtonWrapper>
</StyledButton>
);
};

View File

@ -1,4 +1,4 @@
import React, { ReactNode } from "react";
import React, { ReactNode, ComponentProps } from "react";
import styled from "@emotion/styled";
import { Box, Stack } from "@mui/system";
@ -11,8 +11,8 @@ interface Props {
image?: ReactNode;
}
const StyledCard = styled(Box)<Props>`
background-color: ${({ theme, inverted }) =>
const StyledCard = styled(Box)<{ styled: Props }>`
background-color: ${({ theme, styled: { inverted } }) =>
inverted ? theme?.palette?.common?.white : theme?.palette?.primary?.[900]};
border-radius: ${({ theme }) => theme?.spacing?.(2.5)};
${({ theme }) => theme?.breakpoints?.down("sm")} {
@ -21,7 +21,7 @@ const StyledCard = styled(Box)<Props>`
padding: ${({ theme }) => `${theme?.spacing?.(3)} ${theme?.spacing?.(2.5)}`};
&& * {
color: ${({ theme, inverted }) =>
color: ${({ theme, styled: { inverted } }) =>
inverted ? theme?.palette?.text?.primary : theme?.palette?.common?.white};
}
`;
@ -42,10 +42,11 @@ const BottomRightImageWrapper = styled(ImageWrapper)`
margin-right: ${({ theme }) => theme?.spacing?.(-2.5)};
`;
export const Card: React.FC<React.ComponentProps<typeof StyledCard>> = ({
export const Card: React.FC<ComponentProps<typeof Box> & Props> = ({
title,
children,
image,
inverted,
...props
}) => {
const isXl = useBreakpointDown("xl");
@ -56,7 +57,7 @@ export const Card: React.FC<React.ComponentProps<typeof StyledCard>> = ({
const isVerticalTextTop = !isHorizontal && !isVertical;
return (
<StyledCard {...props}>
<StyledCard {...props} styled={{ title, inverted, image }}>
{isVertical && (
<Stack spacing={2.5}>
{!!title && (

View File

@ -17,9 +17,9 @@ interface Props {
const ITEM_SIZE_K = [1, 0.75, 0.52];
const Item = styled(Box)<
{ num: number; fullWidth: number } & Pick<Props, "width">
>(({ num, theme, width, fullWidth }) => {
const Item = styled(Box)<{
styled: { num: number; fullWidth: number } & Pick<Props, "width">;
}>(({ theme, styled: { num, width, fullWidth } }) => {
const absNum = Math.abs(num);
const restWidth = fullWidth - width;
@ -78,9 +78,11 @@ export const Carousel: React.FC<Props> = ({ images, width }) => {
return (
<Item
key={idx}
num={idx + active}
width={width}
fullWidth={fullWidth}
styled={{
num: idx + active,
width,
fullWidth,
}}
onClick={() => setActive(-idx)}
>
{images[idx]}

View File

@ -5,5 +5,5 @@ import { Box } from "@mui/system";
export const Layout: React.FC<{ children: React.ReactNode }> = ({
children,
}) => {
return <Box sx={{ typography: "body1" }}>{children}</Box>;
return <Box typography="body1">{children}</Box>;
};

View File

@ -8,12 +8,12 @@ interface Props {
active?: boolean;
}
const StyledGatsbyLink = styled(GatsbyLink)<Props>`
color: ${({ theme, inverted }) =>
const StyledGatsbyLink = styled(GatsbyLink)<{ styled: Props }>`
color: ${({ theme, styled: { inverted } }) =>
inverted ? theme?.palette?.common?.white : theme?.palette?.text?.primary};
text-decoration: none;
transition: all 200ms ease;
border-bottom: ${({ active, theme }) =>
border-bottom: ${({ theme, styled: { active } }) =>
active ? `1px solid ${theme?.palette?.common?.white}` : undefined};
&:hover {
@ -27,8 +27,8 @@ const StyledGatsbyLink = styled(GatsbyLink)<Props>`
}
`;
export const Link: React.FC<React.ComponentProps<typeof GatsbyLink> & Props> = (
props
) => {
return <StyledGatsbyLink {...props} />;
export const Link: React.FC<
React.ComponentProps<typeof GatsbyLink> & Props
> = ({ inverted, active, ...props }) => {
return <StyledGatsbyLink {...props} styled={{ inverted, active }} />;
};

View File

@ -28,7 +28,7 @@ export const AntifraudBlock: React.FC<React.ComponentProps<typeof Block>> = (
<Card
height="100%"
boxSizing="border-box"
image={<FlexibilityImg height={160} width="auto" />}
image={<FlexibilityImg height={160} />}
>
<Trans>antifraud.info:flexibility</Trans>
</Card>
@ -37,7 +37,7 @@ export const AntifraudBlock: React.FC<React.ComponentProps<typeof Block>> = (
<Card
height="100%"
boxSizing="border-box"
image={<ScaleImg height={160} width="auto" />}
image={<ScaleImg height={160} />}
>
<Trans>antifraud.info:scale</Trans>
</Card>
@ -46,7 +46,7 @@ export const AntifraudBlock: React.FC<React.ComponentProps<typeof Block>> = (
<Card
height="100%"
boxSizing="border-box"
image={<SafetySvg height={160} width="auto" />}
image={<SafetySvg height={160} />}
>
<Trans>antifraud.info:safety</Trans>
</Card>
@ -61,5 +61,3 @@ export const AntifraudBlock: React.FC<React.ComponentProps<typeof Block>> = (
</Block>
);
};
export default AntifraudBlock;

View File

@ -126,5 +126,3 @@ export const ContactsBlock: React.FC<React.ComponentProps<typeof Block>> = (
</Block>
);
};
export default ContactsBlock;

View File

@ -158,5 +158,3 @@ export const HeaderBlock: React.FC<React.ComponentProps<typeof Block>> = (
</Block>
);
};
export default HeaderBlock;

View File

@ -103,5 +103,3 @@ export const OurProductsBlock: React.FC<React.ComponentProps<typeof Block>> = ({
</Block>
);
};
export default OurProductsBlock;

View File

@ -108,9 +108,8 @@ export const ProcessingBlock: React.FC<React.ComponentProps<typeof Block>> = (
{PAYMENT_METHODS_GROUPS.map((group, idx) => (
<React.Fragment key={idx}>
{group.map((pm, k) => (
<Box display="inline-block">
<Box display="inline-block" key={k}>
<Chip
key={k}
startIcon={pm.icon}
marginBottom={2.5}
marginRight={2}
@ -163,5 +162,3 @@ export const ProcessingBlock: React.FC<React.ComponentProps<typeof Block>> = (
</Block>
);
};
export default ProcessingBlock;

43
src/html.js Normal file
View File

@ -0,0 +1,43 @@
import React from "react";
import PropTypes from "prop-types";
export default function HTML(props) {
return (
<html {...props.htmlAttributes}>
<head>
<meta charSet="utf-8" />
<meta httpEquiv="x-ua-compatible" content="ie=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
{props.headComponents}
</head>
<body {...props.bodyAttributes}>
<div className="loader-wrapper">
<div className="loader">
<div></div>
<div></div>
</div>
</div>
{props.preBodyComponents}
<div
key={`body`}
id="___gatsby"
dangerouslySetInnerHTML={{ __html: props.body }}
/>
{props.postBodyComponents}
</body>
</html>
);
}
HTML.propTypes = {
htmlAttributes: PropTypes.object,
headComponents: PropTypes.array,
bodyAttributes: PropTypes.object,
preBodyComponents: PropTypes.array,
body: PropTypes.string,
postBodyComponents: PropTypes.array,
};

View File

@ -1,34 +1,24 @@
import * as React from "react";
import { Box } from "@mui/system";
import type { HeadFC, PageProps } from "gatsby";
import { graphql } from "gatsby";
import { PAGE_IDS } from "~/components/AppNav";
import { AntifraudBlock } from "~/components/index/AntifraudBlock/AntifraudBlock";
import { ContactsBlock } from "~/components/index/ContactsBlock";
import { HeaderBlock } from "~/components/index/HeaderBlock";
const AntifraudBlock = React.lazy(
() => import("~/components/index/AntifraudBlock/AntifraudBlock")
);
const ContactsBlock = React.lazy(
() => import("~/components/index/ContactsBlock")
);
const ProcessingBlock = React.lazy(
() => import("~/components/index/ProcessingBlock")
);
const OurProductsBlock = React.lazy(
() => import("~/components/index/OurProductsBlock")
);
import { OurProductsBlock } from "~/components/index/OurProductsBlock";
import { ProcessingBlock } from "~/components/index/ProcessingBlock";
const IndexPage: React.FC<PageProps> = () => {
return (
<Box>
<>
<HeaderBlock />
<OurProductsBlock id={PAGE_IDS.ourProducts} />
<ProcessingBlock id={PAGE_IDS.processing} />
<AntifraudBlock id={PAGE_IDS.antifraud} />
<ContactsBlock id={PAGE_IDS.contacts} />
</Box>
</>
);
};

View File

@ -0,0 +1,68 @@
.loader-wrapper,
.loader {
opacity: 1;
transition: opacity 0.2s ease-in-out;
}
.loader-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: #000c1f;
z-index: 9999;
}
.loader {
display: inline-block;
position: absolute;
transform: translateX(-50%) translateY(-50%);
left: 50%;
top: 50%;
width: 80px;
height: 80px;
}
.loader div {
position: absolute;
border: 4px solid #fff;
opacity: 1;
border-radius: 50%;
animation: ripple 1s cubic-bezier(0, 0.2, 0.8, 1) infinite;
}
.loader div:nth-child(2) {
animation-delay: -0.5s;
}
@keyframes ripple {
0% {
top: 36px;
left: 36px;
width: 0;
height: 0;
opacity: 0;
}
4.9% {
top: 36px;
left: 36px;
width: 0;
height: 0;
opacity: 0;
}
5% {
top: 36px;
left: 36px;
width: 0;
height: 0;
opacity: 1;
}
100% {
top: 0px;
left: 0px;
width: 72px;
height: 72px;
opacity: 0;
}
}

View File

@ -0,0 +1,26 @@
@font-face {
font-family: "Mont";
/*font-style: normal;*/
/*font-weight: 500;*/
src: url("https://valitydev-statics.s3.eu-central-1.amazonaws.com/Mont/mont_semibold.woff2")
format("woff2");
}
@font-face {
font-family: "Code Next";
/*font-style: normal;*/
/*font-weight: 500;*/
src: url("https://valitydev-statics.s3.eu-central-1.amazonaws.com/Code-Next/code-next_regular.woff2")
format("woff2");
}
html {
font-family: sans-serif;
font-size: 100%;
}
body {
margin: 0;
padding: 0;
shape-rendering: geometricprecision;
}

View File

@ -3,29 +3,7 @@ import { Theme } from "@mui/system";
export const createGlobalStyle = (theme: Theme) =>
css`
@font-face {
font-family: "Mont";
//font-style: normal;
//font-weight: 500;
src: url("https://valitydev-statics.s3.eu-central-1.amazonaws.com/Mont/mont_semibold.woff2")
format("woff2");
}
@font-face {
font-family: "Code Next";
//font-style: normal;
//font-weight: 500;
src: url("https://valitydev-statics.s3.eu-central-1.amazonaws.com/Code-Next/code-next_regular.woff2")
format("woff2");
}
html {
font-family: sans-serif;
}
html {
font-size: 100%;
${theme?.breakpoints?.up?.("md")} {
${(theme?.typography as any)?.h1} {
font-size: 115%;
@ -41,13 +19,7 @@ export const createGlobalStyle = (theme: Theme) =>
}
${theme?.breakpoints?.down?.("sm")} {
font-size: 75%;
font-size: 73%;
}
}
body {
margin: 0;
padding: 0;
shape-rendering: geometricprecision;
}
`;

View File

@ -1,27 +1,28 @@
import {
ComponentType,
LazyExoticComponent,
ComponentProps,
Suspense,
} from "react";
import { ComponentType, LazyExoticComponent, ComponentProps } from "react";
import * as React from "react";
import loadable from "@loadable/component";
import { useBreakpointUp } from "~/utils/use-breakpoints";
export const createLazySvg = <T extends ComponentType<any>>(
factory: () => Promise<{ default: T }>,
largeSvgFactory?: () => Promise<{ default: T }>
) => {
const Comp = React.lazy(factory);
let XlComp: LazyExoticComponent<T>;
if (largeSvgFactory) XlComp = React.lazy(largeSvgFactory);
return (params: ComponentProps<LazyExoticComponent<T>>) => {
const Comp = loadable(factory, { ssr: true });
const XlComp = largeSvgFactory
? loadable(largeSvgFactory, { ssr: true })
: Comp;
return (props: ComponentProps<LazyExoticComponent<T>>) => {
const isLarge = useBreakpointUp("lg");
const Component = isLarge && largeSvgFactory ? XlComp : Comp;
return (
<Suspense>
<Component {...params} />
</Suspense>
<>
{isLarge && largeSvgFactory ? (
<XlComp {...props} />
) : (
<Comp {...props} />
)}
</>
);
};
};