first commit
|
|
@ -17,7 +17,10 @@
|
||||||
"storybook:build": "storybook build"
|
"storybook:build": "storybook build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@mantine/carousel": "^7.1.7",
|
||||||
"@mantine/core": "7.1.7",
|
"@mantine/core": "7.1.7",
|
||||||
|
"@mantine/ds": "^7.1.7",
|
||||||
|
"@mantine/form": "^7.2.0",
|
||||||
"@mantine/hooks": "7.1.7",
|
"@mantine/hooks": "7.1.7",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
|
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
|
||||||
import { HomePage } from './pages/Home.page';
|
import { HomePage } from './pages/Home/Home.page';
|
||||||
|
|
||||||
const router = createBrowserRouter([
|
const router = createBrowserRouter([
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { useToggle, upperFirst } from '@mantine/hooks';
|
||||||
|
import { useForm } from '@mantine/form';
|
||||||
|
import {
|
||||||
|
TextInput,
|
||||||
|
PasswordInput,
|
||||||
|
Text,
|
||||||
|
Paper,
|
||||||
|
Group,
|
||||||
|
PaperProps,
|
||||||
|
Button,
|
||||||
|
Divider,
|
||||||
|
Checkbox,
|
||||||
|
Anchor,
|
||||||
|
Stack,
|
||||||
|
Title,
|
||||||
|
} from '@mantine/core';
|
||||||
|
import GoogleButton from '../GoogleButton/GoogleButton';
|
||||||
|
import classes from './AuthenticationImage.module.css';
|
||||||
|
const Authen = (props: PaperProps) => {
|
||||||
|
const [type, toggle] = useToggle(['login', 'register']);
|
||||||
|
const form = useForm({
|
||||||
|
initialValues: {
|
||||||
|
email: '',
|
||||||
|
name: '',
|
||||||
|
password: '',
|
||||||
|
terms: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
validate: {
|
||||||
|
email: (val) => (/^\S+@\S+$/.test(val) ? null : 'Invalid email'),
|
||||||
|
password: (val) => (val.length <= 6 ? 'Password should include at least 6 characters' : null),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Paper radius="md" p="xl" withBorder {...props}>
|
||||||
|
<Text size="lg" fw={500}>
|
||||||
|
Welcome to Mantine, {type} with
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Group grow mb="md" mt="md">
|
||||||
|
<GoogleButton radius="xl">Google</GoogleButton>
|
||||||
|
</Group>
|
||||||
|
|
||||||
|
<Divider label="Or continue with email" labelPosition="center" my="lg" />
|
||||||
|
|
||||||
|
<form onSubmit={form.onSubmit(() => {})}>
|
||||||
|
<Stack>
|
||||||
|
{type === 'register' && (
|
||||||
|
<TextInput
|
||||||
|
label="Name"
|
||||||
|
placeholder="Your name"
|
||||||
|
value={form.values.name}
|
||||||
|
onChange={(event) => form.setFieldValue('name', event.currentTarget.value)}
|
||||||
|
radius="md"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<TextInput
|
||||||
|
required
|
||||||
|
label="Email"
|
||||||
|
placeholder="hello@mantine.dev"
|
||||||
|
value={form.values.email}
|
||||||
|
onChange={(event) => form.setFieldValue('email', event.currentTarget.value)}
|
||||||
|
error={form.errors.email && 'Invalid email'}
|
||||||
|
radius="md"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<PasswordInput
|
||||||
|
required
|
||||||
|
label="Password"
|
||||||
|
placeholder="Your password"
|
||||||
|
value={form.values.password}
|
||||||
|
onChange={(event) => form.setFieldValue('password', event.currentTarget.value)}
|
||||||
|
error={form.errors.password && 'Password should include at least 6 characters'}
|
||||||
|
radius="md"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{type === 'register' && (
|
||||||
|
<Checkbox
|
||||||
|
label="I accept terms and conditions"
|
||||||
|
checked={form.values.terms}
|
||||||
|
onChange={(event) => form.setFieldValue('terms', event.currentTarget.checked)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Group justify="space-between" mt="xl">
|
||||||
|
<Anchor component="button" type="button" c="dimmed" onClick={() => toggle()} size="xs">
|
||||||
|
{type === 'register'
|
||||||
|
? 'Already have an account? Login'
|
||||||
|
: "Don't have an account? Register"}
|
||||||
|
</Anchor>
|
||||||
|
<Button type="submit" radius="xl">
|
||||||
|
{upperFirst(type)}
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
|
</form>
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Authen;
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
.wrapper {
|
||||||
|
min-height: rem(900px);
|
||||||
|
background-size: cover;
|
||||||
|
background-image: url(https://images.unsplash.com/photo-1484242857719-4b9144542727?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1280&q=80);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form {
|
||||||
|
border-right: rem(1px) solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-7));
|
||||||
|
min-height: rem(900px);
|
||||||
|
max-width: rem(450px);
|
||||||
|
padding-top: rem(80px);
|
||||||
|
|
||||||
|
@media (max-width: $mantine-breakpoint-sm) {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
|
||||||
|
font-family: Greycliff CF, var(--mantine-font-family);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { Card, Overlay, Button, Text } from '@mantine/core';
|
||||||
|
import classes from './ImageActionBanner.module.css';
|
||||||
|
|
||||||
|
const Banner = () => {
|
||||||
|
return (
|
||||||
|
<Card radius="md" className={classes.card}>
|
||||||
|
<Overlay className={classes.overlay} opacity={0.55} zIndex={0} />
|
||||||
|
|
||||||
|
<div className={classes.content}>
|
||||||
|
<Text size="xl" fw={700} className={classes.title}>
|
||||||
|
Banner component
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text size="sm" className={classes.description}>
|
||||||
|
Save up to 25% at Fifth Season Hotels in Europe, the Middle East, Africa and Asia Pacific
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Button className={classes.action} variant="white" color="dark" size="xs">
|
||||||
|
Action button
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Banner
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
.card {
|
||||||
|
height: rem(500px);
|
||||||
|
width: rem(1300px);
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
background-image: url(https://images.unsplash.com/photo-1596394516093-501ba68a0ba6?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80);
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
padding: var(--mantine-spacing-xl);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action {
|
||||||
|
position: absolute;
|
||||||
|
bottom: var(--mantine-spacing-xl);
|
||||||
|
right: var(--mantine-spacing-xl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: var(--mantine-color-white);
|
||||||
|
margin-bottom: calc(var(--mantine-spacing-xs) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
color: var(--mantine-color-white);
|
||||||
|
max-width: rem(220px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay {
|
||||||
|
background-color: transparent;
|
||||||
|
background-image: linear-gradient(
|
||||||
|
105deg,
|
||||||
|
var(--mantine-color-black) 20%,
|
||||||
|
#312f2f 50%,
|
||||||
|
var(--mantine-color-gray-4) 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { AppShell, Box, Title } from '@mantine/core'
|
||||||
|
import React from 'react'
|
||||||
|
import Header from '../Header/Header'
|
||||||
|
import LeadGird from '../LeadGird/LeadGird'
|
||||||
|
import Banner from '../Banner/Banner'
|
||||||
|
import Footer from '../Footer/Footer'
|
||||||
|
|
||||||
|
const BasePage = ({header, setHeader, main}) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<AppShell
|
||||||
|
header={{ height: { base: 60, md: 70, lg: 80 } }}
|
||||||
|
padding="md"
|
||||||
|
footer={{ height: 320 }}
|
||||||
|
>
|
||||||
|
<AppShell.Header>
|
||||||
|
<Header header={header} setHeader={setHeader}></Header>
|
||||||
|
</AppShell.Header>
|
||||||
|
<AppShell.Main pb={0}>
|
||||||
|
{main}
|
||||||
|
</AppShell.Main>
|
||||||
|
<AppShell.Footer pos={'relative'}>
|
||||||
|
<Footer></Footer>
|
||||||
|
</AppShell.Footer>
|
||||||
|
</AppShell>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BasePage
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
.card {
|
||||||
|
height: rem(440px);
|
||||||
|
width: 30%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-start;
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-family: Greycliff CF, sans-serif;
|
||||||
|
font-weight: 900;
|
||||||
|
color: var(--mantine-color-white);
|
||||||
|
line-height: 1.2;
|
||||||
|
font-size: rem(32px);
|
||||||
|
margin-top: var(--mantine-spacing-xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
.category {
|
||||||
|
color: var(--mantine-color-white);
|
||||||
|
opacity: 0.7;
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { Carousel } from '@mantine/carousel';
|
||||||
|
import { useMediaQuery } from '@mantine/hooks';
|
||||||
|
import { Paper, Text, Title, Button, useMantineTheme, rem } from '@mantine/core';
|
||||||
|
import classes from './CardsCarousel.module.css';
|
||||||
|
|
||||||
|
interface CardProps {
|
||||||
|
image: string;
|
||||||
|
title: string;
|
||||||
|
category: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Card({ image, title, category }: CardProps) {
|
||||||
|
return (
|
||||||
|
<Paper
|
||||||
|
shadow="md"
|
||||||
|
p="xl"
|
||||||
|
radius="md"
|
||||||
|
style={{ backgroundImage: `url(${image})` }}
|
||||||
|
className={classes.card}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<Text className={classes.category} size="xs">
|
||||||
|
{category}
|
||||||
|
</Text>
|
||||||
|
<Title order={3} className={classes.title}>
|
||||||
|
{title}
|
||||||
|
</Title>
|
||||||
|
</div>
|
||||||
|
<Button variant="white" color="dark">
|
||||||
|
Read article
|
||||||
|
</Button>
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = [
|
||||||
|
{
|
||||||
|
image:
|
||||||
|
'https://images.unsplash.com/photo-1508193638397-1c4234db14d8?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=400&q=80',
|
||||||
|
title: 'Best forests to visit in North America',
|
||||||
|
category: 'nature',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image:
|
||||||
|
'https://images.unsplash.com/photo-1559494007-9f5847c49d94?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=400&q=80',
|
||||||
|
title: 'Hawaii beaches review: better than you think',
|
||||||
|
category: 'beach',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image:
|
||||||
|
'https://images.unsplash.com/photo-1608481337062-4093bf3ed404?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=400&q=80',
|
||||||
|
title: 'Mountains at night: 12 best locations to enjoy the view',
|
||||||
|
category: 'nature',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image:
|
||||||
|
'https://images.unsplash.com/photo-1507272931001-fc06c17e4f43?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=400&q=80',
|
||||||
|
title: 'Aurora in Norway: when to visit for best experience',
|
||||||
|
category: 'nature',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image:
|
||||||
|
'https://images.unsplash.com/photo-1510798831971-661eb04b3739?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=400&q=80',
|
||||||
|
title: 'Best places to visit this winter',
|
||||||
|
category: 'tourism',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image:
|
||||||
|
'https://images.unsplash.com/photo-1582721478779-0ae163c05a60?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=400&q=80',
|
||||||
|
title: 'Active volcanos reviews: travel at your own risk',
|
||||||
|
category: 'nature',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const Carousels = () => {
|
||||||
|
const theme = useMantineTheme();
|
||||||
|
const mobile = useMediaQuery(`(max-width: ${theme.breakpoints.sm})`);
|
||||||
|
const slides = data.map((item) => (
|
||||||
|
<Carousel.Slide key={item.title} style={{backgroundColor:"blue", display:"flex", flexFlow:"row"}}>
|
||||||
|
<Card {...item} />
|
||||||
|
</Carousel.Slide>
|
||||||
|
));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Carousel
|
||||||
|
slideSize={{ base: '100%', sm: '50%' }}
|
||||||
|
slideGap={{ base: rem(2), sm: 'xl' }}
|
||||||
|
align="start"
|
||||||
|
slidesToScroll={mobile ? 1 : 2}
|
||||||
|
>
|
||||||
|
{slides}
|
||||||
|
</Carousel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Carousels
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
.icon {
|
||||||
|
width: rem(22px);
|
||||||
|
height: rem(22px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
@mixin dark {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin light {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.light {
|
||||||
|
@mixin light {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin dark {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,13 +1,22 @@
|
||||||
import { Button, Group, useMantineColorScheme } from '@mantine/core';
|
import { ActionIcon, Button, Group, Switch, rem, useComputedColorScheme, useMantineColorScheme, useMantineTheme } from '@mantine/core';
|
||||||
|
import { IconSun, IconMoon } from '@tabler/icons-react';
|
||||||
|
import cx from 'clsx';
|
||||||
|
import classes from './ActionToggle.module.css';
|
||||||
export function ColorSchemeToggle() {
|
export function ColorSchemeToggle() {
|
||||||
const { setColorScheme } = useMantineColorScheme();
|
const { setColorScheme } = useMantineColorScheme();
|
||||||
|
const computedColorScheme = useComputedColorScheme('light', { getInitialValueInEffect: true });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Group justify="center" mt="xl">
|
<Group justify="center">
|
||||||
<Button onClick={() => setColorScheme('light')}>Light</Button>
|
<ActionIcon
|
||||||
<Button onClick={() => setColorScheme('dark')}>Dark</Button>
|
onClick={() => setColorScheme(computedColorScheme === 'light' ? 'dark' : 'light')}
|
||||||
<Button onClick={() => setColorScheme('auto')}>Auto</Button>
|
variant="default"
|
||||||
|
size="md"
|
||||||
|
aria-label="Toggle color scheme"
|
||||||
|
>
|
||||||
|
<IconSun className={cx(classes.icon, classes.light)} stroke={1.5} />
|
||||||
|
<IconMoon className={cx(classes.icon, classes.dark)} stroke={1.5} />
|
||||||
|
</ActionIcon>
|
||||||
</Group>
|
</Group>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
import React from 'react'
|
||||||
|
import {
|
||||||
|
Text,
|
||||||
|
Title,
|
||||||
|
SimpleGrid,
|
||||||
|
TextInput,
|
||||||
|
Textarea,
|
||||||
|
Button,
|
||||||
|
Group,
|
||||||
|
ActionIcon,
|
||||||
|
} from '@mantine/core';
|
||||||
|
import { IconBrandTwitter, IconBrandYoutube, IconBrandInstagram } from '@tabler/icons-react';
|
||||||
|
import { ContactIconsList } from './ContactIcons';
|
||||||
|
import classes from './ContactUs.module.css';
|
||||||
|
|
||||||
|
const social = [IconBrandTwitter, IconBrandYoutube, IconBrandInstagram];
|
||||||
|
|
||||||
|
const Contact = () => {
|
||||||
|
const icons = social.map((Icon, index) => (
|
||||||
|
<ActionIcon key={index} size={28} className={classes.social} variant="transparent">
|
||||||
|
<Icon size="1.4rem" stroke={1.5} />
|
||||||
|
</ActionIcon>
|
||||||
|
));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classes.wrapper}>
|
||||||
|
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing={50}>
|
||||||
|
<div>
|
||||||
|
<Title className={classes.title}>Contact us</Title>
|
||||||
|
<Text className={classes.description} mt="sm" mb={30}>
|
||||||
|
Leave your email and we will get back to you within 24 hours
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<ContactIconsList />
|
||||||
|
|
||||||
|
<Group mt="xl">{icons}</Group>
|
||||||
|
</div>
|
||||||
|
<div className={classes.form}>
|
||||||
|
<TextInput
|
||||||
|
label="Email"
|
||||||
|
placeholder="your@email.com"
|
||||||
|
required
|
||||||
|
classNames={{ input: classes.input, label: classes.inputLabel }}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
label="Name"
|
||||||
|
placeholder="John Doe"
|
||||||
|
mt="md"
|
||||||
|
classNames={{ input: classes.input, label: classes.inputLabel }}
|
||||||
|
/>
|
||||||
|
<Textarea
|
||||||
|
required
|
||||||
|
label="Your message"
|
||||||
|
placeholder="I want to order your goods"
|
||||||
|
minRows={4}
|
||||||
|
mt="md"
|
||||||
|
classNames={{ input: classes.input, label: classes.inputLabel }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Group justify="flex-end" mt="md">
|
||||||
|
<Button className={classes.control}>Send message</Button>
|
||||||
|
</Group>
|
||||||
|
</div>
|
||||||
|
</SimpleGrid>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Contact
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
.wrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: var(--mantine-color-white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
margin-right: var(--mantine-spacing-md);
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: var(--mantine-color-blue-0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
color: var(--mantine-color-white);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
import { Text, Box, Stack, rem } from '@mantine/core';
|
||||||
|
import { IconSun, IconPhone, IconMapPin, IconAt } from '@tabler/icons-react';
|
||||||
|
import classes from './ContactIcons.module.css';
|
||||||
|
|
||||||
|
interface ContactIconProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'title'> {
|
||||||
|
icon: typeof IconSun;
|
||||||
|
title: React.ReactNode;
|
||||||
|
description: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ContactIcon({ icon: Icon, title, description, ...others }: ContactIconProps) {
|
||||||
|
return (
|
||||||
|
<div className={classes.wrapper} {...others}>
|
||||||
|
<Box mr="md">
|
||||||
|
<Icon style={{ width: rem(24), height: rem(24) }} />
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Text size="xs" className={classes.title}>
|
||||||
|
{title}
|
||||||
|
</Text>
|
||||||
|
<Text className={classes.description}>{description}</Text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const MOCKDATA = [
|
||||||
|
{ title: 'Email', description: 'hello@mantine.dev', icon: IconAt },
|
||||||
|
{ title: 'Phone', description: '+49 (800) 335 35 35', icon: IconPhone },
|
||||||
|
{ title: 'Address', description: '844 Morris Park avenue', icon: IconMapPin },
|
||||||
|
{ title: 'Working hours', description: '8 a.m. – 11 p.m.', icon: IconSun },
|
||||||
|
];
|
||||||
|
|
||||||
|
export function ContactIconsList() {
|
||||||
|
const items = MOCKDATA.map((item, index) => <ContactIcon key={index} {...item} />);
|
||||||
|
return <Stack>{items}</Stack>;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
.wrapper {
|
||||||
|
min-height: rem(400px);
|
||||||
|
background-image: linear-gradient(
|
||||||
|
-60deg,
|
||||||
|
var(--mantine-color-blue-4) 0%,
|
||||||
|
var(--mantine-color-blue-7) 100%
|
||||||
|
);
|
||||||
|
border-radius: var(--mantine-radius-md);
|
||||||
|
padding: calc(var(--mantine-spacing-xl) * 2.5);
|
||||||
|
|
||||||
|
@media (max-width: $mantine-breakpoint-sm) {
|
||||||
|
padding: calc(var(--mantine-spacing-xl) * 1.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-family: Greycliff CF, var(--mantine-font-family);
|
||||||
|
color: var(--mantine-color-white);
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
color: var(--mantine-color-blue-0);
|
||||||
|
max-width: rem(300px);
|
||||||
|
|
||||||
|
@media (max-width: $mantine-breakpoint-sm) {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form {
|
||||||
|
background-color: var(--mantine-color-white);
|
||||||
|
padding: var(--mantine-spacing-xl);
|
||||||
|
border-radius: var(--mantine-radius-md);
|
||||||
|
box-shadow: var(--mantine-shadow-lg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.social {
|
||||||
|
color: var(--mantine-color-white);
|
||||||
|
|
||||||
|
@mixin hover {
|
||||||
|
color: var(--mantine-color-blue-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
background-color: var(--mantine-color-white);
|
||||||
|
border-color: var(--mantine-color-gray-4);
|
||||||
|
color: var(--mantine-color-black);
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
color: var(--mantine-color-gray-5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputLabel {
|
||||||
|
color: var(--mantine-color-black);
|
||||||
|
}
|
||||||
|
|
||||||
|
.control {
|
||||||
|
background-color: var(--mantine-color-blue-6);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { Text, Container, ActionIcon, Group, rem } from '@mantine/core';
|
||||||
|
import { IconBrandTwitter, IconBrandYoutube, IconBrandInstagram } from '@tabler/icons-react';
|
||||||
|
import { MantineLogo } from '@mantine/ds';
|
||||||
|
import classes from './FooterLinks.module.css';
|
||||||
|
|
||||||
|
const data = [
|
||||||
|
{
|
||||||
|
title: 'About',
|
||||||
|
links: [
|
||||||
|
{ label: 'Features', link: '#' },
|
||||||
|
{ label: 'Pricing', link: '#' },
|
||||||
|
{ label: 'Support', link: '#' },
|
||||||
|
{ label: 'Forums', link: '#' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Project',
|
||||||
|
links: [
|
||||||
|
{ label: 'Contribute', link: '#' },
|
||||||
|
{ label: 'Media assets', link: '#' },
|
||||||
|
{ label: 'Changelog', link: '#' },
|
||||||
|
{ label: 'Releases', link: '#' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Community',
|
||||||
|
links: [
|
||||||
|
{ label: 'Join Discord', link: '#' },
|
||||||
|
{ label: 'Follow on Twitter', link: '#' },
|
||||||
|
{ label: 'Email newsletter', link: '#' },
|
||||||
|
{ label: 'GitHub discussions', link: '#' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const Footer = () => {
|
||||||
|
const groups = data.map((group) => {
|
||||||
|
const links = group.links.map((link, index) => (
|
||||||
|
<Text<'a'>
|
||||||
|
key={index}
|
||||||
|
className={classes.link}
|
||||||
|
component="a"
|
||||||
|
href={link.link}
|
||||||
|
onClick={(event) => event.preventDefault()}
|
||||||
|
>
|
||||||
|
{link.label}
|
||||||
|
</Text>
|
||||||
|
));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classes.wrapper} key={group.title}>
|
||||||
|
<Text className={classes.title}>{group.title}</Text>
|
||||||
|
{links}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<footer className={classes.footer}>
|
||||||
|
<Container className={classes.inner}>
|
||||||
|
<div className={classes.logo}>
|
||||||
|
<MantineLogo size={30} />
|
||||||
|
<Text size="xs" c="dimmed" className={classes.description}>
|
||||||
|
Build fully functional accessible web applications faster than ever
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
<div className={classes.groups}>{groups}</div>
|
||||||
|
</Container>
|
||||||
|
<Container className={classes.afterFooter}>
|
||||||
|
<Text c="dimmed" size="sm">
|
||||||
|
© 2020 mantine.dev. All rights reserved.
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Group gap={0} className={classes.social} justify="flex-end" wrap="nowrap">
|
||||||
|
<ActionIcon size="lg" color="gray" variant="subtle">
|
||||||
|
<IconBrandTwitter style={{ width: rem(18), height: rem(18) }} stroke={1.5} />
|
||||||
|
</ActionIcon>
|
||||||
|
<ActionIcon size="lg" color="gray" variant="subtle">
|
||||||
|
<IconBrandYoutube style={{ width: rem(18), height: rem(18) }} stroke={1.5} />
|
||||||
|
</ActionIcon>
|
||||||
|
<ActionIcon size="lg" color="gray" variant="subtle">
|
||||||
|
<IconBrandInstagram style={{ width: rem(18), height: rem(18) }} stroke={1.5} />
|
||||||
|
</ActionIcon>
|
||||||
|
</Group>
|
||||||
|
</Container>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Footer
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
.footer {
|
||||||
|
/* margin-top: rem(120px); */
|
||||||
|
padding-top: calc(var(--mantine-spacing-xl) * 2);
|
||||||
|
padding-bottom: calc(var(--mantine-spacing-xl) * 2);
|
||||||
|
background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6));
|
||||||
|
border-top: rem(1px) solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-5));
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
max-width: rem(200px);
|
||||||
|
|
||||||
|
@media (max-width: $mantine-breakpoint-sm) {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
margin-top: rem(5px);
|
||||||
|
|
||||||
|
@media (max-width: $mantine-breakpoint-sm) {
|
||||||
|
margin-top: var(--mantine-spacing-xs);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
@media (max-width: $mantine-breakpoint-sm) {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.groups {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
@media (max-width: $mantine-breakpoint-sm) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
width: rem(160px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.link {
|
||||||
|
display: block;
|
||||||
|
color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-1));
|
||||||
|
font-size: var(--mantine-font-size-sm);
|
||||||
|
padding-top: rem(3px);
|
||||||
|
padding-bottom: rem(3px);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: var(--mantine-font-size-lg);
|
||||||
|
font-weight: 700;
|
||||||
|
font-family: Greycliff CF, var(--mantine-font-family);
|
||||||
|
margin-bottom: calc(var(--mantine-spacing-xs) / 2);
|
||||||
|
color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
|
||||||
|
}
|
||||||
|
|
||||||
|
.afterFooter {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: var(--mantine-spacing-xl);
|
||||||
|
padding-top: var(--mantine-spacing-xl);
|
||||||
|
padding-bottom: var(--mantine-spacing-xl);
|
||||||
|
border-top: rem(1px) solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-4));
|
||||||
|
|
||||||
|
@media (max-width: $mantine-breakpoint-sm) {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.social {
|
||||||
|
@media (max-width: $mantine-breakpoint-sm) {
|
||||||
|
margin-top: var(--mantine-spacing-xs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
.title {
|
||||||
|
font-size: rem(26px);
|
||||||
|
font-weight: 900;
|
||||||
|
font-family: Greycliff CF, var(--mantine-font-family);
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls {
|
||||||
|
@media (max-width: $mantine-breakpoint-xs) {
|
||||||
|
flex-direction: column-reverse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.control {
|
||||||
|
@media (max-width: $mantine-breakpoint-xs) {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Paper,
|
||||||
|
Title,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
Button,
|
||||||
|
Container,
|
||||||
|
Group,
|
||||||
|
Anchor,
|
||||||
|
Center,
|
||||||
|
Box,
|
||||||
|
rem,
|
||||||
|
} from '@mantine/core';
|
||||||
|
import { IconArrowLeft } from '@tabler/icons-react';
|
||||||
|
import classes from './ForgotPassword.module.css';
|
||||||
|
const ForgotPassword = () => {
|
||||||
|
return (
|
||||||
|
<Container size={460} my={30}>
|
||||||
|
<Title className={classes.title} ta="center">
|
||||||
|
Forgot your password?
|
||||||
|
</Title>
|
||||||
|
<Text c="dimmed" fz="sm" ta="center">
|
||||||
|
Enter your email to get a reset link
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Paper withBorder shadow="md" p={30} radius="md" mt="xl">
|
||||||
|
<TextInput label="Your email" placeholder="me@mantine.dev" required />
|
||||||
|
<Group justify="space-between" mt="lg" className={classes.controls}>
|
||||||
|
<Anchor c="dimmed" size="sm" className={classes.control}>
|
||||||
|
<Center inline>
|
||||||
|
<IconArrowLeft style={{ width: rem(12), height: rem(12) }} stroke={1.5} />
|
||||||
|
<Box ml={5}>Back to the login page</Box>
|
||||||
|
</Center>
|
||||||
|
</Anchor>
|
||||||
|
<Button className={classes.control}>Reset password</Button>
|
||||||
|
</Group>
|
||||||
|
</Paper>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ForgotPassword;
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { Button, ButtonProps } from '@mantine/core';
|
||||||
|
|
||||||
|
function GoogleIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
preserveAspectRatio="xMidYMid"
|
||||||
|
viewBox="0 0 256 262"
|
||||||
|
style={{ width: '0.9rem', height: '0.9rem' }}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="#4285F4"
|
||||||
|
d="M255.878 133.451c0-10.734-.871-18.567-2.756-26.69H130.55v48.448h71.947c-1.45 12.04-9.283 30.172-26.69 42.356l-.244 1.622 38.755 30.023 2.685.268c24.659-22.774 38.875-56.282 38.875-96.027"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="#34A853"
|
||||||
|
d="M130.55 261.1c35.248 0 64.839-11.605 86.453-31.622l-41.196-31.913c-11.024 7.688-25.82 13.055-45.257 13.055-34.523 0-63.824-22.773-74.269-54.25l-1.531.13-40.298 31.187-.527 1.465C35.393 231.798 79.49 261.1 130.55 261.1"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="#FBBC05"
|
||||||
|
d="M56.281 156.37c-2.756-8.123-4.351-16.827-4.351-25.82 0-8.994 1.595-17.697 4.206-25.82l-.073-1.73L15.26 71.312l-1.335.635C5.077 89.644 0 109.517 0 130.55s5.077 40.905 13.925 58.602l42.356-32.782"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="#EB4335"
|
||||||
|
d="M130.55 50.479c24.514 0 41.05 10.589 50.479 19.438l36.844-35.974C195.245 12.91 165.798 0 130.55 0 79.49 0 35.393 29.301 13.925 71.947l42.211 32.783c10.59-31.477 39.891-54.251 74.414-54.251"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const GoogleButton = (props: ButtonProps & React.ComponentPropsWithoutRef<'button'>) => {
|
||||||
|
return <Button leftSection={<GoogleIcon />} variant="default" {...props} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GoogleButton
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
.header {
|
||||||
|
height: rem(84px);
|
||||||
|
margin-bottom: rem(80px);
|
||||||
|
background-color: var(--mantine-color-body);
|
||||||
|
border-bottom: rem(1px) solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner {
|
||||||
|
height: rem(84px);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.links {
|
||||||
|
padding-top: var(--mantine-spacing-lg);
|
||||||
|
height: rem(84px);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: rem(600px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mainLinks {
|
||||||
|
margin-right: calc(var(--mantine-spacing-sm) * -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mainLink {
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: var(--mantine-font-size-xs);
|
||||||
|
color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-1));
|
||||||
|
padding: rem(7px) var(--mantine-spacing-sm);
|
||||||
|
font-weight: 700;
|
||||||
|
border-bottom: rem(2px) solid transparent;
|
||||||
|
transition: border-color 100ms ease, color 100ms ease;
|
||||||
|
|
||||||
|
@mixin hover {
|
||||||
|
color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-active] {
|
||||||
|
color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
|
||||||
|
border-bottom-color: var(--mantine-color-blue-6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.secondaryLink {
|
||||||
|
color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-1));
|
||||||
|
font-size: var(--mantine-font-size-xs);
|
||||||
|
text-transform: uppercase;
|
||||||
|
transition: color 100ms ease;
|
||||||
|
|
||||||
|
@mixin hover {
|
||||||
|
color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { Container, Anchor, Group, Burger, Box } from '@mantine/core';
|
||||||
|
import { useDisclosure } from '@mantine/hooks';
|
||||||
|
import { MantineLogo } from '@mantine/ds';
|
||||||
|
import classes from './DoubleHeader.module.css';
|
||||||
|
import { ColorSchemeToggle } from '../ColorSchemeToggle/ColorSchemeToggle';
|
||||||
|
import LanguagePicker from '../LanguagePicker/LanguagePicker';
|
||||||
|
|
||||||
|
const userLinks = [
|
||||||
|
{ link: '#', label: 'Privacy & Security' },
|
||||||
|
{ link: '#', label: 'Account settings' },
|
||||||
|
{ link: '#', label: 'Support options' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const mainLinks = [
|
||||||
|
{ link: '#', label: 'Introduction' },
|
||||||
|
{ link: '#', label: 'Authentication' },
|
||||||
|
{ link: '#', label: 'Data' },
|
||||||
|
{ link: '#', label: 'Contact' },
|
||||||
|
{ link: '#', label: 'form element' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const Header = ({ header, setHeader }) => {
|
||||||
|
const [opened, { toggle }] = useDisclosure(false);
|
||||||
|
const [active, setActive] = useState(0);
|
||||||
|
|
||||||
|
const mainItems = mainLinks.map((item, index) => (
|
||||||
|
<Anchor<'a'>
|
||||||
|
href={item.link}
|
||||||
|
key={item.label}
|
||||||
|
className={classes.mainLink}
|
||||||
|
data-active={index === active || undefined}
|
||||||
|
onClick={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
setHeader(index);
|
||||||
|
setActive(index);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{item.label}
|
||||||
|
</Anchor>
|
||||||
|
));
|
||||||
|
|
||||||
|
const secondaryItems = userLinks.map((item) => (
|
||||||
|
<Anchor
|
||||||
|
href={item.link}
|
||||||
|
key={item.label}
|
||||||
|
onClick={(event) => event.preventDefault()}
|
||||||
|
className={classes.secondaryLink}
|
||||||
|
>
|
||||||
|
{item.label}
|
||||||
|
</Anchor>
|
||||||
|
));
|
||||||
|
|
||||||
|
// console.log(header);
|
||||||
|
return (
|
||||||
|
<header className={classes.header}>
|
||||||
|
<Container className={classes.inner} size={'xl'}>
|
||||||
|
<MantineLogo size={34} />
|
||||||
|
<Box className={classes.links} visibleFrom="md">
|
||||||
|
<Group justify="flex-end">{secondaryItems}</Group>
|
||||||
|
<Group gap={0} justify="flex-end" className={classes.mainLinks}>
|
||||||
|
{mainItems}
|
||||||
|
</Group>
|
||||||
|
</Box>
|
||||||
|
<Burger
|
||||||
|
opened={opened}
|
||||||
|
onClick={toggle}
|
||||||
|
className={classes.burger}
|
||||||
|
size="sm"
|
||||||
|
hiddenFrom="sm"
|
||||||
|
/>
|
||||||
|
<Box size={'sm'} display={'flex'}>
|
||||||
|
<LanguagePicker></LanguagePicker>
|
||||||
|
<ColorSchemeToggle />
|
||||||
|
</Box>
|
||||||
|
</Container>
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Header;
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
.control {
|
||||||
|
width: rem(150px);
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: rem(5px) rem(8px);
|
||||||
|
border-radius: var(--mantine-radius-md);
|
||||||
|
border: rem(1px) solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-6));
|
||||||
|
transition: background-color 150ms ease;
|
||||||
|
background-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-6));
|
||||||
|
margin-right: rem(5px);
|
||||||
|
&[data-expanded] {
|
||||||
|
background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin hover {
|
||||||
|
background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: var(--mantine-font-size-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
transition: transform 150ms ease;
|
||||||
|
transform: rotate(0deg);
|
||||||
|
|
||||||
|
[data-expanded] & {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { UnstyledButton, Menu, Image, Group } from '@mantine/core';
|
||||||
|
import { IconChevronDown } from '@tabler/icons-react';
|
||||||
|
import english from "./images/english.png";
|
||||||
|
import vietnam from "./images/vietnam.png";
|
||||||
|
import classes from './LanguagePicker.module.css';
|
||||||
|
|
||||||
|
const data = [
|
||||||
|
{ label: 'English', image: english },
|
||||||
|
{ label: 'Vietnamses', image: vietnam }
|
||||||
|
];
|
||||||
|
const LanguagePicker = () => {
|
||||||
|
const [opened, setOpened] = useState(false);
|
||||||
|
const [selected, setSelected] = useState(data[0]);
|
||||||
|
const items = data.map((item) => (
|
||||||
|
<Menu.Item
|
||||||
|
leftSection={<Image src={item.image} width={18} height={18} />}
|
||||||
|
onClick={() => setSelected(item)}
|
||||||
|
key={item.label}
|
||||||
|
>
|
||||||
|
{item.label}
|
||||||
|
</Menu.Item>
|
||||||
|
));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Menu
|
||||||
|
onOpen={() => setOpened(true)}
|
||||||
|
onClose={() => setOpened(false)}
|
||||||
|
radius="sm"
|
||||||
|
width="target"
|
||||||
|
withinPortal
|
||||||
|
>
|
||||||
|
<Menu.Target>
|
||||||
|
<UnstyledButton className={classes.control} data-expanded={opened || undefined}>
|
||||||
|
<Group gap="xs">
|
||||||
|
<Image src={selected.image} width={15} height={15} />
|
||||||
|
<span className={classes.label}>{selected.label}</span>
|
||||||
|
</Group>
|
||||||
|
<IconChevronDown size="1rem" className={classes.icon} stroke={1.5} />
|
||||||
|
</UnstyledButton>
|
||||||
|
</Menu.Target>
|
||||||
|
<Menu.Dropdown>{items}</Menu.Dropdown>
|
||||||
|
</Menu>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LanguagePicker
|
||||||
|
After Width: | Height: | Size: 8.4 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -0,0 +1,78 @@
|
||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Container,
|
||||||
|
Grid,
|
||||||
|
SimpleGrid,
|
||||||
|
Skeleton,
|
||||||
|
rem,
|
||||||
|
Image,
|
||||||
|
BackgroundImage,
|
||||||
|
Center,
|
||||||
|
Text,
|
||||||
|
Flex,
|
||||||
|
Button,
|
||||||
|
Tooltip,
|
||||||
|
} from '@mantine/core';
|
||||||
|
import image1 from '../../img/pexels-irina-iriser-1379640.jpg';
|
||||||
|
import image2 from '../../img/pexels-eberhard-grossgasteiger-640781.jpg';
|
||||||
|
import image3 from '../../img/pexels-pixabay-51387.jpg';
|
||||||
|
import image4 from '../../img/pexels-pok-rie-982263.jpg';
|
||||||
|
import { useToggle } from '@mantine/hooks';
|
||||||
|
const PRIMARY_COL_HEIGHT = rem(500);
|
||||||
|
|
||||||
|
const LeadGird = () => {
|
||||||
|
let images = [image1, image2, image3, image4]
|
||||||
|
const [value, toggle] = useToggle([0, 1, 2, 3]);
|
||||||
|
const SECONDARY_COL_HEIGHT = `calc(${PRIMARY_COL_HEIGHT} / 2 - var(--mantine-spacing-md) / 2)`;
|
||||||
|
return (
|
||||||
|
<Container my="xl" size={'xl'}>
|
||||||
|
<SimpleGrid cols={{ base: 1, xl: 2 }} spacing="md">
|
||||||
|
<BackgroundImage radius="md" src={images[value]} style={{ height: PRIMARY_COL_HEIGHT }}>
|
||||||
|
{/* <Center p="md"> */}
|
||||||
|
<Flex
|
||||||
|
h={'100%'}
|
||||||
|
gap="xs"
|
||||||
|
justify="flex-start"
|
||||||
|
align="end"
|
||||||
|
direction="row"
|
||||||
|
wrap="wrap"
|
||||||
|
p={30}
|
||||||
|
fs={'italic'}
|
||||||
|
bg="rgba(0, 0, 0, .3)"
|
||||||
|
c={"white"}
|
||||||
|
>
|
||||||
|
{'<Flex >'}
|
||||||
|
<br></br>
|
||||||
|
Flex component is an alternative to Group and Stack. Flex is more flexible, it allows
|
||||||
|
creating both horizontal and vertical flexbox layouts, but requires more configuration.
|
||||||
|
Unlike Group and Stack Flex is polymorphic and supports responsive props.
|
||||||
|
<Text c="white" fw={600}>
|
||||||
|
BackgroundImage component can be used to add any content on image. It is useful for
|
||||||
|
hero headers and other similar sections
|
||||||
|
</Text>
|
||||||
|
{'</Flex>'}
|
||||||
|
</Flex>
|
||||||
|
{/* </Center> */}
|
||||||
|
</BackgroundImage>
|
||||||
|
<Grid gutter="md">
|
||||||
|
<Grid.Col>
|
||||||
|
<Image radius="md" src={value+2>3?images[value+2-4]:images[value+2]} style={{ height: SECONDARY_COL_HEIGHT }} />
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<Image radius="md" src={value+1>3?images[value+1-4]:images[value+1]} style={{ height: SECONDARY_COL_HEIGHT }} />
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={6}>
|
||||||
|
<Image radius="md" src={value+3>3?images[value+3-4]:images[value+3]} style={{ height: SECONDARY_COL_HEIGHT }} />
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
</SimpleGrid>
|
||||||
|
<Tooltip label='Toggle button'>
|
||||||
|
<Button mt={10} onClick={() => {toggle()}}>
|
||||||
|
Click
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LeadGird;
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
.wrapper {
|
||||||
|
padding-top: calc(var(--mantine-spacing-xl) * 2);
|
||||||
|
padding-bottom: calc(var(--mantine-spacing-xl) * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin-bottom: var(--mantine-spacing-md);
|
||||||
|
padding-left: var(--mantine-spacing-md);
|
||||||
|
color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
|
||||||
|
font-family: Greycliff CF, var(--mantine-font-family);
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
font-size: var(--mantine-font-size-sm);
|
||||||
|
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1));
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Image, Accordion, Grid, Container, Title } from '@mantine/core';
|
||||||
|
import image from './image.svg';
|
||||||
|
import classes from './FaqWithImage.module.css';
|
||||||
|
|
||||||
|
const placeholder =
|
||||||
|
'It can’t help but hear a pin drop from over half a mile away, so it lives deep in the mountains where there aren’t many people or Pokémon.';
|
||||||
|
const Questions = () => {
|
||||||
|
return (
|
||||||
|
<div className={classes.wrapper}>
|
||||||
|
<Container size="lg">
|
||||||
|
<Grid id="faq-grid" gutter={50}>
|
||||||
|
<Grid.Col span={{ base: 12, md: 6 }}>
|
||||||
|
<Image src={image} alt="Frequently Asked Questions" />
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col span={{ base: 12, md: 6 }}>
|
||||||
|
<Title order={2} ta="left" className={classes.title}>
|
||||||
|
Frequently Asked Questions
|
||||||
|
</Title>
|
||||||
|
|
||||||
|
<Accordion chevronPosition="right" defaultValue="reset-password" variant="separated">
|
||||||
|
<Accordion.Item className={classes.item} value="reset-password">
|
||||||
|
<Accordion.Control>How can I reset my password?</Accordion.Control>
|
||||||
|
<Accordion.Panel>{placeholder}</Accordion.Panel>
|
||||||
|
</Accordion.Item>
|
||||||
|
|
||||||
|
<Accordion.Item className={classes.item} value="another-account">
|
||||||
|
<Accordion.Control>Can I create more that one account?</Accordion.Control>
|
||||||
|
<Accordion.Panel>{placeholder}</Accordion.Panel>
|
||||||
|
</Accordion.Item>
|
||||||
|
|
||||||
|
<Accordion.Item className={classes.item} value="newsletter">
|
||||||
|
<Accordion.Control>How can I subscribe to monthly newsletter?</Accordion.Control>
|
||||||
|
<Accordion.Panel>{placeholder}</Accordion.Panel>
|
||||||
|
</Accordion.Item>
|
||||||
|
|
||||||
|
<Accordion.Item className={classes.item} value="credit-card">
|
||||||
|
<Accordion.Control>
|
||||||
|
Do you store credit card information securely?
|
||||||
|
</Accordion.Control>
|
||||||
|
<Accordion.Panel>{placeholder}</Accordion.Panel>
|
||||||
|
</Accordion.Item>
|
||||||
|
</Accordion>
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Questions;
|
||||||
|
After Width: | Height: | Size: 94 KiB |
|
|
@ -0,0 +1,239 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { useState } from 'react';
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
ScrollArea,
|
||||||
|
UnstyledButton,
|
||||||
|
Group,
|
||||||
|
Text,
|
||||||
|
Center,
|
||||||
|
TextInput,
|
||||||
|
rem,
|
||||||
|
keys,
|
||||||
|
} from '@mantine/core';
|
||||||
|
import { IconSelector, IconChevronDown, IconChevronUp, IconSearch } from '@tabler/icons-react';
|
||||||
|
import classes from './TableSort.module.css';
|
||||||
|
|
||||||
|
interface RowData {
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
company: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ThProps {
|
||||||
|
children: React.ReactNode;
|
||||||
|
reversed: boolean;
|
||||||
|
sorted: boolean;
|
||||||
|
onSort(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Th({ children, reversed, sorted, onSort }: ThProps) {
|
||||||
|
const Icon = sorted ? (reversed ? IconChevronUp : IconChevronDown) : IconSelector;
|
||||||
|
return (
|
||||||
|
<Table.Th className={classes.th}>
|
||||||
|
<UnstyledButton onClick={onSort} className={classes.control}>
|
||||||
|
<Group justify="space-between">
|
||||||
|
<Text fw={500} fz="sm">
|
||||||
|
{children}
|
||||||
|
</Text>
|
||||||
|
<Center className={classes.icon}>
|
||||||
|
<Icon style={{ width: rem(16), height: rem(16) }} stroke={1.5} />
|
||||||
|
</Center>
|
||||||
|
</Group>
|
||||||
|
</UnstyledButton>
|
||||||
|
</Table.Th>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterData(data: RowData[], search: string) {
|
||||||
|
const query = search.toLowerCase().trim();
|
||||||
|
return data.filter((item) =>
|
||||||
|
keys(data[0]).some((key) => item[key].toLowerCase().includes(query))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortData(
|
||||||
|
data: RowData[],
|
||||||
|
payload: { sortBy: keyof RowData | null; reversed: boolean; search: string }
|
||||||
|
) {
|
||||||
|
const { sortBy } = payload;
|
||||||
|
|
||||||
|
if (!sortBy) {
|
||||||
|
return filterData(data, payload.search);
|
||||||
|
}
|
||||||
|
|
||||||
|
return filterData(
|
||||||
|
[...data].sort((a, b) => {
|
||||||
|
if (payload.reversed) {
|
||||||
|
return b[sortBy].localeCompare(a[sortBy]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return a[sortBy].localeCompare(b[sortBy]);
|
||||||
|
}),
|
||||||
|
payload.search
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = [
|
||||||
|
{
|
||||||
|
name: 'Athena Weissnat',
|
||||||
|
company: 'Little - Rippin',
|
||||||
|
email: 'Elouise.Prohaska@yahoo.com',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Deangelo Runolfsson',
|
||||||
|
company: 'Greenfelder - Krajcik',
|
||||||
|
email: 'Kadin_Trantow87@yahoo.com',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Danny Carter',
|
||||||
|
company: 'Kohler and Sons',
|
||||||
|
email: 'Marina3@hotmail.com',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Trace Tremblay PhD',
|
||||||
|
company: 'Crona, Aufderhar and Senger',
|
||||||
|
email: 'Antonina.Pouros@yahoo.com',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Derek Dibbert',
|
||||||
|
company: 'Gottlieb LLC',
|
||||||
|
email: 'Abagail29@hotmail.com',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Viola Bernhard',
|
||||||
|
company: 'Funk, Rohan and Kreiger',
|
||||||
|
email: 'Jamie23@hotmail.com',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Austin Jacobi',
|
||||||
|
company: 'Botsford - Corwin',
|
||||||
|
email: 'Genesis42@yahoo.com',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Hershel Mosciski',
|
||||||
|
company: 'Okuneva, Farrell and Kilback',
|
||||||
|
email: 'Idella.Stehr28@yahoo.com',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Mylene Ebert',
|
||||||
|
company: 'Kirlin and Sons',
|
||||||
|
email: 'Hildegard17@hotmail.com',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Lou Trantow',
|
||||||
|
company: 'Parisian - Lemke',
|
||||||
|
email: 'Hillard.Barrows1@hotmail.com',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Dariana Weimann',
|
||||||
|
company: 'Schowalter - Donnelly',
|
||||||
|
email: 'Colleen80@gmail.com',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Dr. Christy Herman',
|
||||||
|
company: 'VonRueden - Labadie',
|
||||||
|
email: 'Lilyan98@gmail.com',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Katelin Schuster',
|
||||||
|
company: 'Jacobson - Smitham',
|
||||||
|
email: 'Erich_Brekke76@gmail.com',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Melyna Macejkovic',
|
||||||
|
company: 'Schuster LLC',
|
||||||
|
email: 'Kylee4@yahoo.com',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Pinkie Rice',
|
||||||
|
company: 'Wolf, Trantow and Zulauf',
|
||||||
|
email: 'Fiona.Kutch@hotmail.com',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Brain Kreiger',
|
||||||
|
company: 'Lueilwitz Group',
|
||||||
|
email: 'Rico98@hotmail.com',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const TableData = () => {
|
||||||
|
const [search, setSearch] = useState('');
|
||||||
|
const [sortedData, setSortedData] = useState(data);
|
||||||
|
const [sortBy, setSortBy] = useState<keyof RowData | null>(null);
|
||||||
|
const [reverseSortDirection, setReverseSortDirection] = useState(false);
|
||||||
|
|
||||||
|
const setSorting = (field: keyof RowData) => {
|
||||||
|
const reversed = field === sortBy ? !reverseSortDirection : false;
|
||||||
|
setReverseSortDirection(reversed);
|
||||||
|
setSortBy(field);
|
||||||
|
setSortedData(sortData(data, { sortBy: field, reversed, search }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const { value } = event.currentTarget;
|
||||||
|
setSearch(value);
|
||||||
|
setSortedData(sortData(data, { sortBy, reversed: reverseSortDirection, search: value }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const rows = sortedData.map((row) => (
|
||||||
|
<Table.Tr key={row.name}>
|
||||||
|
<Table.Td>{row.name}</Table.Td>
|
||||||
|
<Table.Td>{row.email}</Table.Td>
|
||||||
|
<Table.Td>{row.company}</Table.Td>
|
||||||
|
</Table.Tr>
|
||||||
|
));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ScrollArea>
|
||||||
|
<TextInput
|
||||||
|
placeholder="Search by any field"
|
||||||
|
mb="md"
|
||||||
|
leftSection={<IconSearch style={{ width: rem(16), height: rem(16) }} stroke={1.5} />}
|
||||||
|
value={search}
|
||||||
|
onChange={handleSearchChange}
|
||||||
|
/>
|
||||||
|
<Table horizontalSpacing="md" verticalSpacing="xs" miw={700} layout="fixed">
|
||||||
|
<Table.Tbody>
|
||||||
|
<Table.Tr>
|
||||||
|
<Th
|
||||||
|
sorted={sortBy === 'name'}
|
||||||
|
reversed={reverseSortDirection}
|
||||||
|
onSort={() => setSorting('name')}
|
||||||
|
>
|
||||||
|
Name
|
||||||
|
</Th>
|
||||||
|
<Th
|
||||||
|
sorted={sortBy === 'email'}
|
||||||
|
reversed={reverseSortDirection}
|
||||||
|
onSort={() => setSorting('email')}
|
||||||
|
>
|
||||||
|
Email
|
||||||
|
</Th>
|
||||||
|
<Th
|
||||||
|
sorted={sortBy === 'company'}
|
||||||
|
reversed={reverseSortDirection}
|
||||||
|
onSort={() => setSorting('company')}
|
||||||
|
>
|
||||||
|
Company
|
||||||
|
</Th>
|
||||||
|
</Table.Tr>
|
||||||
|
</Table.Tbody>
|
||||||
|
<Table.Tbody>
|
||||||
|
{rows.length > 0 ? (
|
||||||
|
rows
|
||||||
|
) : (
|
||||||
|
<Table.Tr>
|
||||||
|
<Table.Td colSpan={Object.keys(data[0]).length}>
|
||||||
|
<Text fw={500} ta="center">
|
||||||
|
Nothing found
|
||||||
|
</Text>
|
||||||
|
</Table.Td>
|
||||||
|
</Table.Tr>
|
||||||
|
)}
|
||||||
|
</Table.Tbody>
|
||||||
|
</Table>
|
||||||
|
</ScrollArea>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TableData
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
.th {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control {
|
||||||
|
width: 100%;
|
||||||
|
padding: var(--mantine-spacing-xs) var(--mantine-spacing-md);
|
||||||
|
|
||||||
|
@mixin hover {
|
||||||
|
background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: rem(21px);
|
||||||
|
height: rem(21px);
|
||||||
|
border-radius: rem(21px);
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 2.7 MiB |
|
After Width: | Height: | Size: 2.2 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 518 KiB |
|
|
@ -1,11 +0,0 @@
|
||||||
import { Welcome } from '../components/Welcome/Welcome';
|
|
||||||
import { ColorSchemeToggle } from '../components/ColorSchemeToggle/ColorSchemeToggle';
|
|
||||||
|
|
||||||
export function HomePage() {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Welcome />
|
|
||||||
<ColorSchemeToggle />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,196 @@
|
||||||
|
import { AppShell, Box, Title, useMantineTheme } from '@mantine/core';
|
||||||
|
import Banner from '../../components/Banner/Banner';
|
||||||
|
import Footer from '../../components/Footer/Footer';
|
||||||
|
import Header from '../../components/Header/Header';
|
||||||
|
import LeadGird from '../../components/LeadGird/LeadGird';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import BasePage from '../../components/BasePage/BasePage';
|
||||||
|
import Authen from '../../components/Authen/Authen';
|
||||||
|
import ForgotPassword from '../../components/ForgotPassword/ForgotPassword';
|
||||||
|
import TableData from '../../components/TableData/TableData';
|
||||||
|
import Questions from '../../components/Questions/Questions';
|
||||||
|
import Contact from '../../components/Contact/Contact';
|
||||||
|
|
||||||
|
export function HomePage() {
|
||||||
|
const theme = useMantineTheme();
|
||||||
|
const [header, setHeader] = useState(0);
|
||||||
|
|
||||||
|
switch (header) {
|
||||||
|
case 0:
|
||||||
|
return (
|
||||||
|
<BasePage
|
||||||
|
header={header}
|
||||||
|
setHeader={setHeader}
|
||||||
|
main={
|
||||||
|
<>
|
||||||
|
<Box
|
||||||
|
my={'xl'}
|
||||||
|
style={{ justifyContent: 'center', justifyItems: 'center', display: 'flex' }}
|
||||||
|
>
|
||||||
|
<Banner></Banner>
|
||||||
|
</Box>
|
||||||
|
<Box ml={150}>
|
||||||
|
<Title order={1}>LeadGird component</Title>
|
||||||
|
</Box>
|
||||||
|
<LeadGird></LeadGird>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
></BasePage>
|
||||||
|
);
|
||||||
|
case 1:
|
||||||
|
return (
|
||||||
|
<BasePage
|
||||||
|
header={header}
|
||||||
|
setHeader={setHeader}
|
||||||
|
main={
|
||||||
|
<>
|
||||||
|
<Box my={'xl'}>
|
||||||
|
<Title ml={150} order={1}>
|
||||||
|
Login form
|
||||||
|
</Title>
|
||||||
|
<Box
|
||||||
|
w={'100%'}
|
||||||
|
style={{
|
||||||
|
justifyContent: 'center',
|
||||||
|
justifyItems: 'center',
|
||||||
|
display: 'flex',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Authen w={'25%'} />
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Title ml={150} order={1}>
|
||||||
|
Forgot password form
|
||||||
|
</Title>
|
||||||
|
<ForgotPassword />
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
></BasePage>
|
||||||
|
);
|
||||||
|
case 2:
|
||||||
|
return (
|
||||||
|
<BasePage
|
||||||
|
header={header}
|
||||||
|
setHeader={setHeader}
|
||||||
|
main={
|
||||||
|
<>
|
||||||
|
<Box my={'xl'}>
|
||||||
|
<Title ml={150} order={1}>
|
||||||
|
Data table
|
||||||
|
</Title>
|
||||||
|
<Box
|
||||||
|
w={'100%'}
|
||||||
|
style={{
|
||||||
|
justifyContent: 'center',
|
||||||
|
justifyItems: 'center',
|
||||||
|
display: 'flex',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box w={'60%'} p={20} style={{ border: 'solid 1px gray', borderRadius: 10 }}>
|
||||||
|
<TableData />
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Title ml={150} order={1}>
|
||||||
|
Frequently Asked Questions
|
||||||
|
</Title>
|
||||||
|
<Questions />
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
></BasePage>
|
||||||
|
);
|
||||||
|
case 3:
|
||||||
|
return (
|
||||||
|
<BasePage
|
||||||
|
header={header}
|
||||||
|
setHeader={setHeader}
|
||||||
|
main={
|
||||||
|
<>
|
||||||
|
<Box
|
||||||
|
my={'xl'}
|
||||||
|
style={{
|
||||||
|
justifyContent: 'center',
|
||||||
|
justifyItems: 'center',
|
||||||
|
display: 'flex',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box w={'60%'}>
|
||||||
|
<Contact />
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
></BasePage>
|
||||||
|
);
|
||||||
|
case 4:
|
||||||
|
return(
|
||||||
|
<BasePage
|
||||||
|
header={header}
|
||||||
|
setHeader={setHeader}
|
||||||
|
main={
|
||||||
|
<>
|
||||||
|
<Box
|
||||||
|
my={'xl'}
|
||||||
|
style={{
|
||||||
|
justifyContent: 'center',
|
||||||
|
justifyItems: 'center',
|
||||||
|
display: 'flex', flexFlow:"column"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Title ml={150} order={1}>
|
||||||
|
Button
|
||||||
|
</Title>
|
||||||
|
<iframe height={"1000"} src='https://mantine.dev/core/button/'></iframe>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box
|
||||||
|
my={'xl'}
|
||||||
|
style={{
|
||||||
|
justifyContent: 'center',
|
||||||
|
justifyItems: 'center',
|
||||||
|
display: 'flex', flexFlow:"column"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Title ml={150} order={1}>
|
||||||
|
Input
|
||||||
|
</Title>
|
||||||
|
<iframe height={"1000"} src='https://ui.mantine.dev/category/inputs/'></iframe>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box
|
||||||
|
my={'xl'}
|
||||||
|
style={{
|
||||||
|
justifyContent: 'center',
|
||||||
|
justifyItems: 'center',
|
||||||
|
display: 'flex', flexFlow:"column"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Title ml={150} order={1}>
|
||||||
|
Input
|
||||||
|
</Title>
|
||||||
|
<iframe height={"1000"} src='https://ui.mantine.dev/category/inputs/'></iframe>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box
|
||||||
|
my={'xl'}
|
||||||
|
style={{
|
||||||
|
justifyContent: 'center',
|
||||||
|
justifyItems: 'center',
|
||||||
|
display: 'flex', flexFlow:"column"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Title ml={150} order={1}>
|
||||||
|
Dropzones
|
||||||
|
</Title>
|
||||||
|
<iframe height={"800"} src='https://ui.mantine.dev/category/dropzones/'></iframe>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
></BasePage>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||