mirror of
https://github.com/valitydev/vality.dev.git
synced 2024-11-06 00:55:20 +00:00
OPS-249: Add loader and fix app init (#12)
This commit is contained in:
parent
ebc9742354
commit
389f405a4a
@ -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>
|
31
.idea/runConfigurations/prod.xml
Normal file
31
.idea/runConfigurations/prod.xml
Normal 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>
|
@ -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,
|
||||
}) => {
|
||||
|
@ -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
6
gatsby-ssr.tsx
Normal 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
50
package-lock.json
generated
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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">
|
||||
|
@ -30,6 +30,7 @@ export const BackgroundImageBox: React.FC<
|
||||
z-index: 0;
|
||||
`}
|
||||
style={imgStyle}
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -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>
|
||||
)}
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -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 && (
|
||||
|
@ -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]}
|
||||
|
@ -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>;
|
||||
};
|
||||
|
@ -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 }} />;
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -126,5 +126,3 @@ export const ContactsBlock: React.FC<React.ComponentProps<typeof Block>> = (
|
||||
</Block>
|
||||
);
|
||||
};
|
||||
|
||||
export default ContactsBlock;
|
||||
|
@ -158,5 +158,3 @@ export const HeaderBlock: React.FC<React.ComponentProps<typeof Block>> = (
|
||||
</Block>
|
||||
);
|
||||
};
|
||||
|
||||
export default HeaderBlock;
|
||||
|
@ -103,5 +103,3 @@ export const OurProductsBlock: React.FC<React.ComponentProps<typeof Block>> = ({
|
||||
</Block>
|
||||
);
|
||||
};
|
||||
|
||||
export default OurProductsBlock;
|
||||
|
@ -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
43
src/html.js
Normal 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,
|
||||
};
|
@ -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>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
68
src/styles/browser-styles.css
Normal file
68
src/styles/browser-styles.css
Normal 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;
|
||||
}
|
||||
}
|
26
src/styles/global-styles.css
Normal file
26
src/styles/global-styles.css
Normal 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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
`;
|
||||
|
@ -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} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user