add strapi, search

master
gtitov 3 years ago
parent ed3e2098de
commit c747285171

@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
<title>Литкарта</title>
</head>
<body>
<div id="root"></div>

9
package-lock.json generated

@ -12,6 +12,7 @@
"@mantine/core": "^6.0.17",
"@mantine/hooks": "^6.0.17",
"@tabler/icons-react": "^2.28.0",
"fuse.js": "^6.6.2",
"maplibre-gl": "^3.2.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
@ -2494,6 +2495,14 @@
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"node_modules/fuse.js": {
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.6.2.tgz",
"integrity": "sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==",
"engines": {
"node": ">=10"
}
},
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",

@ -14,6 +14,7 @@
"@mantine/core": "^6.0.17",
"@mantine/hooks": "^6.0.17",
"@tabler/icons-react": "^2.28.0",
"fuse.js": "^6.6.2",
"maplibre-gl": "^3.2.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",

@ -1,22 +1,22 @@
import { AppShell, Container, ScrollArea } from '@mantine/core';
import { HeaderSimple } from './Header';
import { Box } from '@mantine/core';
import { KartaPage } from './KartaPage';
import { Landing } from './Landing';
import { Article } from './Article';
import { HeaderSimple } from './Header';
import { FooterLinks } from './Footer';
// import { ArticleCardPanel } from './ArticleCardPanel';
// import { ArticleCardVertical } from './ArticleCard';
// import articleCard from './assets/card.json';
import footerLinks from './assets/footer.json';
import headerLinks from './assets/header.json';
import footerLinks from './assets/footer.json';
function App() {
return (
<Container fluid p={0} pos={'absolute'} w={'100%'} top={0}>
<Box pos={'absolute'} w={'100%'} top={0}>
<HeaderSimple links={headerLinks.links} />
<KartaPage></KartaPage>
{/* <Article></Article> */}
{/* <Landing></Landing> */}
<FooterLinks data={footerLinks.data} />
</Container >
</Box >
);
}

@ -0,0 +1,69 @@
import { Title, Text, Container, Blockquote, rem, createStyles } from '@mantine/core';
const useStyles = createStyles((theme) => ({
content: {
padding: rem(30)
},
title: {
color: theme.colorScheme === 'dark' ? theme.white : theme.black,
fontFamily: `Greycliff CF, ${theme.fontFamily}`,
fontSize: rem(55),
lineHeight: 1.2,
fontWeight: 900,
padding: rem(20),
[theme.fn.smallerThan('xs')]: {
fontSize: rem(28),
},
},
heading2: {
color: theme.colorScheme === 'dark' ? theme.white : theme.black,
paddingTop: rem(11)
}
}));
export function Article() {
const { classes } = useStyles();
return (
<Container className={classes.content}>
<Title order={1} className={classes.title}>
Михаил Михайлович Пришвин
</Title>
<Text>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis iusto blanditiis exercitationem voluptates itaque eligendi, consequatur in distinctio eius explicabo. Aliquid in vel explicabo assumenda, molestiae consequatur illum eius voluptates? Lorem ipsum dolor sit amet consectetur, adipisicing elit. Ipsum, a similique reprehenderit nesciunt corporis nemo autem neque, ratione assumenda eveniet ex maxime quae vero non expedita dicta. Laudantium, ea numquam?
Explicabo eos dolores aliquid quos velit, provident, autem ipsam, hic impedit quis cupiditate distinctio ipsum a perferendis. Fugiat in ad consequuntur! Numquam suscipit nostrum commodi repudiandae nulla minus vel tempora.
Tempora repellendus incidunt voluptatum, obcaecati eos reiciendis repellat corrupti velit cupiditate unde modi enim sed sunt fugiat, quasi, quidem at maiores. At et tenetur magni delectus, voluptates perspiciatis. Tempore, vero?
Facilis, architecto ducimus? Dolor sed saepe omnis? Quam dolorum sequi magni necessitatibus eveniet, assumenda ducimus iste obcaecati optio voluptatibus ad expedita odio dolorem amet impedit saepe molestias esse dolores eaque?
Soluta facilis incidunt, illo quibusdam hic voluptate officia quae aspernatur esse ullam voluptas, temporibus, cum atque quas nihil perferendis excepturi pariatur mollitia delectus nisi. Iusto fugit at voluptatem. Nam, quidem!
</Text>
<Blockquote color="indigo" cite=" Михаил Пришвин">
Life is like an npm install you never know what you are going to get.
</Blockquote>
<Title order={2} className={classes.heading2}>
Юбилей
</Title>
<Text>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis iusto blanditiis exercitationem voluptates itaque eligendi, consequatur in distinctio eius explicabo. Aliquid in vel explicabo assumenda, molestiae consequatur illum eius voluptates?
</Text>
<Text>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis iusto blanditiis exercitationem voluptates itaque eligendi, consequatur in distinctio eius explicabo. Aliquid in vel explicabo assumenda, molestiae consequatur illum eius voluptates?
</Text>
<Title order={2} className={classes.heading2}>
Ранние годы
</Title>
<Text>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis iusto blanditiis exercitationem voluptates itaque eligendi, consequatur in distinctio eius explicabo. Aliquid in vel explicabo assumenda, molestiae consequatur illum eius voluptates?
</Text>
<Text>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis iusto blanditiis exercitationem voluptates itaque eligendi, consequatur in distinctio eius explicabo. Aliquid in vel explicabo assumenda, molestiae consequatur illum eius voluptates?
</Text>
<Text>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis iusto blanditiis exercitationem voluptates itaque eligendi, consequatur in distinctio eius explicabo. Aliquid in vel explicabo assumenda, molestiae consequatur illum eius voluptates?
</Text>
<Text>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quis iusto blanditiis exercitationem voluptates itaque eligendi, consequatur in distinctio eius explicabo. Aliquid in vel explicabo assumenda, molestiae consequatur illum eius voluptates?
</Text>
</Container>
);
}

@ -36,7 +36,7 @@ export function ArticleCardVertical({
}: ArticleCardVerticalProps) {
const { classes } = useStyles();
return (
<Card withBorder radius="md" p={0} className={classes.card}>
<Card withBorder shadow="sm" radius="md" p={0} w={'100%'} className={classes.card}>
<Group noWrap spacing={0}>
<Image src={image} height={140} width={140} />
<div className={classes.body}>

@ -1,35 +1,86 @@
import { Grid, Skeleton, Box, Flex, ScrollArea, Autocomplete, Container } from '@mantine/core';
import { Paper, Flex, ScrollArea, Autocomplete } from '@mantine/core';
import { ArticleCardVertical } from './ArticleCard';
import articleCard from './assets/card.json';
import Map from 'react-map-gl/maplibre';
import mapstyle from './assets/basemap.json'
import mapstyle from './assets/basemap.json';
import { useState, useEffect } from 'react';
import Fuse from 'fuse.js'
export function KartaPage() {
const [initial, setInitial] = useState(null);
const [articles, setArticles] = useState(null);
const [search, setSearch] = useState('');
const [res, setRes] = useState();
useEffect(() => {
// let initialArticles
fetch("http://strapi.wg.gateway.ts/api/articles?populate=*")
.then(r => r.json())
.then(d => {
setInitial(d.data)
setArticles(d.data)
})
}, [])
const fuseOptions = {
// isCaseSensitive: false,
// includeScore: false,
// shouldSort: true,
// includeMatches: false,
// findAllMatches: false,
// minMatchCharLength: 1,
// location: 0,
// threshold: 0.6,
// distance: 100,
// useExtendedSearch: false,
// ignoreLocation: false,
// ignoreFieldNorm: false,
// fieldNormWeight: 1,
keys: [
"attributes.title"
]
};
const fuse = initial !== null && new Fuse(initial, fuseOptions);
useEffect(() => {
const foundArticles = fuse && fuse.search(search).map(e => e.item)
const updatedArticles = search.length > 0 ? foundArticles : initial
setArticles(updatedArticles)
}, [search])
return (
<div style={{position: 'relative'}}>
<div style={{ position: 'relative' }}>
<Map
initialViewState={{
longitude: 55,
longitude: 60,
latitude: 60,
zoom: 3
zoom: 4
}}
style={{
height: '90vh'
}}
mapStyle={mapstyle}
/>
<Box style={{
<Paper shadow={'md'} withBorder style={{
position: 'absolute',
top: '1rem',
right: '1rem',
width: '40rem',
height: '80vh',
backgroundColor: 'white',
borderRadius: '5px',
opacity: '80%',
width: '36rem',
height: '83vh',
opacity: '90%',
padding: '1rem 0 1rem 1rem'
}}>
<ScrollArea h={'80vh'} type="auto">
<Autocomplete
mr={20}
mb={30}
placeholder="Поиск"
limit={2}
value={search}
onChange={setSearch}
data={[]}
/>
<ScrollArea h={'73vh'} type="auto">
<Flex
mih={50}
gap="md"
@ -39,23 +90,34 @@ export function KartaPage() {
wrap="wrap"
mr={20}
>
<Autocomplete
w={'100%'}
placeholder="Поиск"
limit={2}
data={['Паустовский', 'Бианки', 'Пришвин', 'Брюсов', 'Островский']}
/>
{articles !== null && articles.length > 0 && articles.map(article => {
const articleInfo = {
"image": article.attributes.cover.data !== null ? "http://strapi.wg.gateway.ts" + article.attributes.cover.data.attributes.url : "https://images.unsplash.com/photo-1628890923662-2cb23c2e0cfe?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=200&q=80",
"category": "technology",
"title": article.attributes.title,
"date": new Date(article.attributes.publishedAt).toLocaleDateString("ru-RU"),
"author": {
"name": "Elsa Brown",
"avatar": "https://images.unsplash.com/photo-1628890923662-2cb23c2e0cfe?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=200&q=80"
}
}
return <ArticleCardVertical key={article.id} {...articleInfo} />
}
)}
{/* <ArticleCardVertical {...articleCard} />
<ArticleCardVertical {...articleCard} />
<ArticleCardVertical {...articleCard} />
<ArticleCardVertical {...articleCard} />
<ArticleCardVertical {...articleCard} />
<Skeleton mb={10} animate={false} height={100} />
<Skeleton mb={10} animate={false} height={100} />
<Skeleton mb={10} animate={false} height={100} />
<ArticleCardVertical {...articleCard} />
<Skeleton mb={10} animate={false} height={100} />
<Skeleton mb={10} animate={false} height={100} />
<Skeleton mb={10} animate={false} height={100} />
<ArticleCardVertical {...articleCard} /> */}
</Flex>
</ScrollArea>
</Box>
</Paper>
</div>
);

@ -0,0 +1,120 @@
import {
createStyles,
Title,
SimpleGrid,
Text,
Button,
ThemeIcon,
Grid,
Col,
rem,
Container,
} from '@mantine/core';
import { IconReceiptOff, IconFlame, IconCircleDotted, IconFileCode } from '@tabler/icons-react';
const useStyles = createStyles((theme) => ({
wrapper: {
padding: `calc(${theme.spacing.xl} * 2) ${theme.spacing.xl}`,
minHeight: '58vh',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
overflowX: 'hidden'
},
title: {
fontFamily: `Greycliff CF, ${theme.fontFamily}`,
fontSize: rem(36),
fontWeight: 900,
lineHeight: 1.1,
marginBottom: theme.spacing.md,
color: theme.colorScheme === 'dark' ? theme.white : theme.black,
},
}));
const features = [
{
icon: IconReceiptOff,
title: 'Открывает',
description: 'All packages are published under MIT license, you can use Mantine in any project',
},
{
icon: IconFileCode,
title: 'Сохраняет',
description: 'Build type safe applications, all components and hooks export types',
},
{
icon: IconCircleDotted,
title: 'Объединяет',
description:
'With new :focus-visible selector focus ring will appear only when user navigates with keyboard',
},
{
icon: IconFlame,
title: 'Помогает',
description:
'Customize colors, spacing, shadows, fonts and many other settings with global theme object',
},
];
export function Landing() {
const { classes } = useStyles();
const items = features.map((feature) => (
<div key={feature.title}>
<ThemeIcon
size={44}
radius="md"
variant="gradient"
gradient={{ deg: 133, from: 'blue', to: 'cyan' }}
>
<feature.icon size={rem(26)} stroke={1.5} />
</ThemeIcon>
<Text fz="lg" mt="sm" fw={500}>
{feature.title}
</Text>
<Text c="dimmed" fz="sm">
{feature.description}
</Text>
</div>
));
return (
<Container size={'xl'} className={classes.wrapper}>
<Grid gutter={80}>
<Col span={12} md={5}>
<Title className={classes.title} order={2}>
Литкарта
</Title>
<Text c="dimmed">
Пространство для русской литературы
</Text>
<Button
variant='outline'
size="lg"
radius="md"
mt="xl"
mr={'md'}
>
Подробнее
</Button>
<Button
variant="gradient"
gradient={{ deg: 133, from: 'blue', to: 'cyan' }}
size="lg"
radius="md"
mt="xl"
>
К карте
</Button>
</Col>
<Col span={12} md={7}>
<SimpleGrid cols={2} spacing={30} breakpoints={[{ maxWidth: 'md', cols: 1 }]}>
{items}
</SimpleGrid>
</Col>
</Grid>
</Container>
);
}
Loading…
Cancel
Save