mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-28 00:56:26 +00:00
homepage
This commit is contained in:
30
client/src/components/CommunityModal/index.tsx
Normal file
30
client/src/components/CommunityModal/index.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import React from 'react';
|
||||
import { Button, ModalFooter, ModalBody } from '@chakra-ui/react';
|
||||
import MyModal from '../MyModal';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Markdown from '../Markdown';
|
||||
|
||||
const md = `
|
||||
| 交流群 | 小助手 |
|
||||
| ----------------------- | -------------------- |
|
||||
|  |  |
|
||||
`;
|
||||
|
||||
const CommunityModal = ({ onClose }: { onClose: () => void }) => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<MyModal isOpen={true} onClose={onClose} title={t('home.Community')}>
|
||||
<ModalBody textAlign={'center'}>
|
||||
<Markdown source={md} />
|
||||
</ModalBody>
|
||||
|
||||
<ModalFooter>
|
||||
<Button variant={'base'} onClick={onClose}>
|
||||
关闭
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</MyModal>
|
||||
);
|
||||
};
|
||||
|
||||
export default CommunityModal;
|
1
client/src/components/Icon/icons/fill/play.svg
Normal file
1
client/src/components/Icon/icons/fill/play.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1691412437336" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2312" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M512 14.8973037a497.1026963 497.1026963 0 1 0 497.1026963 497.1026963A497.1026963 497.1026963 0 0 0 512 14.8973037z m165.70089876 581.8863224l-207.12612345 124.27567408L346.29910124 796.45320912V255.16360691l125.38034629 75.39390894 207.12612347 124.27567407 118.47614261 70.97521873z" p-id="2313"></path></svg>
|
After Width: | Height: | Size: 642 B |
@@ -73,7 +73,8 @@ const map = {
|
||||
language_zh: require('./icons/language/zh.svg').default,
|
||||
outlink_share: require('./icons/outlink/share.svg').default,
|
||||
outlink_iframe: require('./icons/outlink/iframe.svg').default,
|
||||
addCircle: require('./icons/circle/add.svg').default
|
||||
addCircle: require('./icons/circle/add.svg').default,
|
||||
playFill: require('./icons/fill/play.svg').default
|
||||
};
|
||||
|
||||
export type IconName = keyof typeof map;
|
||||
|
@@ -1,27 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Button, ModalFooter, ModalBody, Image } from '@chakra-ui/react';
|
||||
import MyModal from '../MyModal';
|
||||
|
||||
const WxConcat = ({ onClose }: { onClose: () => void }) => {
|
||||
return (
|
||||
<MyModal isOpen={true} onClose={onClose} title={'联系方式-wx'}>
|
||||
<ModalBody textAlign={'center'}>
|
||||
<Image
|
||||
style={{ margin: 'auto' }}
|
||||
src={'https://otnvvf-imgs.oss.laf.run/wx300.jpg'}
|
||||
width={'200px'}
|
||||
height={'200px'}
|
||||
alt=""
|
||||
/>
|
||||
</ModalBody>
|
||||
|
||||
<ModalFooter>
|
||||
<Button variant={'base'} onClick={onClose}>
|
||||
关闭
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</MyModal>
|
||||
);
|
||||
};
|
||||
|
||||
export default WxConcat;
|
@@ -65,7 +65,6 @@ function App({ Component, pageProps }: AppProps) {
|
||||
/>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
<Script src="/js/particles.js"></Script>
|
||||
<Script src="/js/qrcode.min.js" strategy="lazyOnload"></Script>
|
||||
<Script src="/js/pdf.js" strategy="lazyOnload"></Script>
|
||||
<Script src="/js/html2pdf.bundle.min.js" strategy="lazyOnload"></Script>
|
||||
|
106
client/src/pages/components/Ability.tsx
Normal file
106
client/src/pages/components/Ability.tsx
Normal file
@@ -0,0 +1,106 @@
|
||||
import { Box, Image, BoxProps, Grid, useTheme } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
const Ability = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const CardStyles: BoxProps = {
|
||||
pt: 4,
|
||||
borderRadius: 'xl',
|
||||
overflow: 'hidden',
|
||||
border: theme.borders.base
|
||||
};
|
||||
const TitleStyles: BoxProps = {
|
||||
px: 4,
|
||||
fontSize: ['xl', '30px'],
|
||||
fontWeight: 'bold'
|
||||
};
|
||||
const DescStyles: BoxProps = {
|
||||
px: 4,
|
||||
mt: 2,
|
||||
mb: 5,
|
||||
fontSize: ['sm', 'lg'],
|
||||
whiteSpace: 'pre-wrap'
|
||||
};
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Box
|
||||
className="textlg"
|
||||
py={['30px', '60px']}
|
||||
textAlign={'center'}
|
||||
fontSize={['22px', '30px']}
|
||||
fontWeight={'bold'}
|
||||
>
|
||||
{t('home.FastGPT Ability')}
|
||||
</Box>
|
||||
<Grid px={[5, 0]} minH={'400px'} gridTemplateColumns={['1fr', `500px 1fr`]} gridGap={6}>
|
||||
<Box
|
||||
{...CardStyles}
|
||||
backgroundImage={'linear-gradient(to bottom right, #00A9A6 0%, #33BABB 100%)'}
|
||||
>
|
||||
<Box {...TitleStyles} color={'white'}>
|
||||
{t('home.AI Assistant')}
|
||||
</Box>
|
||||
<Box {...DescStyles} color={'rgba(255,255,255,0.9)'}>
|
||||
{t('home.AI Assistant Desc')}
|
||||
</Box>
|
||||
<Image
|
||||
src="/imgs/home/ai_assiatant.png"
|
||||
alt={''}
|
||||
w={'100%'}
|
||||
borderRadius={'lg'}
|
||||
transform={'translateX(20px)'}
|
||||
/>
|
||||
</Box>
|
||||
<Box
|
||||
{...CardStyles}
|
||||
pb={4}
|
||||
backgroundImage={'linear-gradient(120deg, #3370ff 0%, #4e83fd 100%)'}
|
||||
>
|
||||
<Box {...TitleStyles} color={'white'}>
|
||||
{t('home.Dateset')}
|
||||
</Box>
|
||||
<Box {...DescStyles} color={'rgba(255,255,255,0.9)'}>
|
||||
{t('home.Dateset Desc')}
|
||||
</Box>
|
||||
<Image
|
||||
src="/imgs/home/dataset_import.png"
|
||||
alt={''}
|
||||
w={'90%'}
|
||||
mx={'auto'}
|
||||
borderRadius={'lg'}
|
||||
/>
|
||||
</Box>
|
||||
</Grid>
|
||||
<Grid
|
||||
mt={6}
|
||||
px={[5, 0]}
|
||||
minH={'400px'}
|
||||
gridTemplateColumns={['1fr', `1fr 500px`]}
|
||||
gridGap={6}
|
||||
>
|
||||
<Box {...CardStyles} backgroundImage={'linear-gradient(to top, #6a85b6 0%, #bac8e0 100%)'}>
|
||||
<Box {...TitleStyles}>{t('home.Advanced Settings')}</Box>
|
||||
<Box {...DescStyles} fontSize={['sm', 'md']}>
|
||||
{t('home.Advanced Settings Desc')}
|
||||
</Box>
|
||||
<Image src="/imgs/home/advanced_settings.png" alt={''} w={'100%'} />
|
||||
</Box>
|
||||
<Box
|
||||
{...CardStyles}
|
||||
pb={4}
|
||||
backgroundImage={'linear-gradient(to right, #FDCBB1 0%, #FEE5D8 100%)'}
|
||||
>
|
||||
<Box {...TitleStyles}>{t('home.OpenAPI')}</Box>
|
||||
<Box {...DescStyles}>{t('home.OpenAPI Desc')}</Box>
|
||||
<Image src="/imgs/home/openapi.png" alt={''} w={'90%'} mx={'auto'} borderRadius={'lg'} />
|
||||
</Box>
|
||||
</Grid>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default Ability;
|
103
client/src/pages/components/Choice.tsx
Normal file
103
client/src/pages/components/Choice.tsx
Normal file
@@ -0,0 +1,103 @@
|
||||
import { Box, Image, Flex, Grid, useTheme } from '@chakra-ui/react';
|
||||
import React, { useRef } from 'react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import MyTooltip from '@/components/MyTooltip';
|
||||
import MyIcon from '@/components/Icon';
|
||||
|
||||
const Choice = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const list = [
|
||||
{
|
||||
icon: '/imgs/home/icon_1.svg',
|
||||
title: t('home.Choice Open'),
|
||||
desc: t('home.Choice Open Desc'),
|
||||
tooltip: '前往 GitHub',
|
||||
onClick: () => window.open('https://github.com/labring/FastGPT', '_blank')
|
||||
},
|
||||
{
|
||||
icon: '/imgs/home/icon_2.svg',
|
||||
title: t('home.Choice QA'),
|
||||
desc: t('home.Choice QA Desc'),
|
||||
onClick: () => {}
|
||||
},
|
||||
{
|
||||
icon: '/imgs/home/icon_3.svg',
|
||||
title: t('home.Choice Visual'),
|
||||
desc: t('home.Choice Visual Desc'),
|
||||
onClick: () => {}
|
||||
},
|
||||
{
|
||||
icon: '/imgs/home/icon_4.svg',
|
||||
title: t('home.Choice Extension'),
|
||||
desc: t('home.Choice Extension Desc'),
|
||||
onClick: () => {}
|
||||
},
|
||||
{
|
||||
icon: '/imgs/home/icon_5.svg',
|
||||
title: t('home.Choice Debug'),
|
||||
desc: t('home.Choice Debug Desc'),
|
||||
onClick: () => {}
|
||||
},
|
||||
{
|
||||
icon: '/imgs/home/icon_6.svg',
|
||||
title: t('home.Choice Models'),
|
||||
desc: t('home.Choice Models Desc'),
|
||||
onClick: () => {}
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Box
|
||||
className="textlg"
|
||||
py={['30px', '60px']}
|
||||
textAlign={'center'}
|
||||
fontSize={['22px', '30px']}
|
||||
fontWeight={'bold'}
|
||||
>
|
||||
{t('home.Why FastGPT')}
|
||||
</Box>
|
||||
<Grid px={[5, 0]} gridTemplateColumns={['1fr', `1fr 1fr`, 'repeat(3,1fr)']} gridGap={6}>
|
||||
{list.map((item) => (
|
||||
<MyTooltip key={item.title} label={item.tooltip}>
|
||||
<Flex
|
||||
alignItems={'flex-start'}
|
||||
border={theme.borders.md}
|
||||
borderRadius={'lg'}
|
||||
p={'40px'}
|
||||
transition={'0.1s'}
|
||||
cursor={'default'}
|
||||
_hover={{
|
||||
bg: 'rgba(255,255,255,0.8)'
|
||||
}}
|
||||
onClick={item.onClick}
|
||||
>
|
||||
<Flex
|
||||
flex={'0 0 48px'}
|
||||
h={'48px'}
|
||||
alignItems={'center'}
|
||||
justifyContent={'center'}
|
||||
boxShadow={theme.shadows.base}
|
||||
borderRadius={'14px'}
|
||||
>
|
||||
<Image src={item.icon} w={'28px'} alt={''} />
|
||||
</Flex>
|
||||
<Box ml={5}>
|
||||
<Box fontSize={['lg', '2xl']} fontWeight={'bold'} color={'myGray.900'}>
|
||||
{item.title}
|
||||
</Box>
|
||||
<Box mt={1} fontSize={['md', 'lg']}>
|
||||
{item.desc}
|
||||
</Box>
|
||||
</Box>
|
||||
</Flex>
|
||||
</MyTooltip>
|
||||
))}
|
||||
</Grid>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default Choice;
|
123
client/src/pages/components/Footer.tsx
Normal file
123
client/src/pages/components/Footer.tsx
Normal file
@@ -0,0 +1,123 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { Box, Flex, useDisclosure } from '@chakra-ui/react';
|
||||
import { feConfigs } from '@/store/static';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import { useRouter } from 'next/router';
|
||||
import CommunityModal from '@/components/CommunityModal';
|
||||
|
||||
const Footer = () => {
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
const list = useMemo(
|
||||
() => [
|
||||
{
|
||||
label: t('home.Footer Product'),
|
||||
child: [
|
||||
{
|
||||
label: t('home.Footer FastGPT Cloud'),
|
||||
onClick: () => {
|
||||
router.push('/app/list');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Sealos',
|
||||
onClick: () => {
|
||||
window.open('https://github.com/labring/sealos', '_blank');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Laf',
|
||||
onClick: () => {
|
||||
window.open('https://github.com/labring/laf', '_blank');
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: t('home.Footer Developer'),
|
||||
child: [
|
||||
{
|
||||
label: t('home.Footer Git'),
|
||||
onClick: () => {
|
||||
window.open('https://github.com/labring/FastGPT', '_blank');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: t('home.Footer Docs'),
|
||||
onClick: () => {
|
||||
window.open('https://doc.fastgpt.run/docs/intro', '_blank');
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: t('home.Footer Support'),
|
||||
child: [
|
||||
{
|
||||
label: t('home.Footer Feedback'),
|
||||
onClick: () => {
|
||||
window.open('https://github.com/labring/FastGPT/issues', '_blank');
|
||||
}
|
||||
},
|
||||
{
|
||||
label: t('home.Community'),
|
||||
onClick: () => {
|
||||
onOpen();
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
[onOpen, t]
|
||||
);
|
||||
|
||||
return (
|
||||
<Box
|
||||
display={['block', 'flex']}
|
||||
px={[5, 0]}
|
||||
maxW={'1200px'}
|
||||
m={'auto'}
|
||||
py={['30px', '60px']}
|
||||
flexWrap={'wrap'}
|
||||
>
|
||||
<Box flex={1}>
|
||||
<Flex alignItems={'center'}>
|
||||
<Avatar src="/icon/logo.png" w={['24px', '30px']} />
|
||||
<Box
|
||||
className="textlg"
|
||||
fontSize={['xl', '2xl']}
|
||||
fontWeight={'bold'}
|
||||
ml={3}
|
||||
fontStyle={'italic'}
|
||||
>
|
||||
{feConfigs?.systemTitle}
|
||||
</Box>
|
||||
</Flex>
|
||||
<Box mt={5} fontSize={'sm'} color={'myGray.600'} maxW={'380px'} textAlign={'justify'}>
|
||||
{t('home.FastGPT Desc')}
|
||||
</Box>
|
||||
</Box>
|
||||
{list.map((item) => (
|
||||
<Box key={item.label} w={'200px'} mt={[5, 0]}>
|
||||
<Box color={'myGray.500'}>{item.label}</Box>
|
||||
{item.child.map((child) => (
|
||||
<Box
|
||||
key={child.label}
|
||||
mt={[2, 3]}
|
||||
cursor={'pointer'}
|
||||
_hover={{ textDecoration: 'underline' }}
|
||||
onClick={child.onClick}
|
||||
>
|
||||
{child.label}
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
))}
|
||||
{isOpen && <CommunityModal onClose={onClose} />}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
86
client/src/pages/components/Hero.tsx
Normal file
86
client/src/pages/components/Hero.tsx
Normal file
@@ -0,0 +1,86 @@
|
||||
import { Box, Flex, Button, Image } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { feConfigs } from '@/store/static';
|
||||
import { useGlobalStore } from '@/store/global';
|
||||
import MyIcon from '@/components/Icon';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useToast } from '@/hooks/useToast';
|
||||
|
||||
const Hero = () => {
|
||||
const router = useRouter();
|
||||
const { toast } = useToast();
|
||||
const { t } = useTranslation();
|
||||
const { isPc, gitStar } = useGlobalStore();
|
||||
|
||||
return (
|
||||
<Flex flexDirection={'column'} pt={['24px', '50px']} alignItems={'center'}>
|
||||
<Box fontSize={['38px', '60px']} fontWeight={'bold'}>
|
||||
{t('home.slogan')}
|
||||
</Box>
|
||||
<Box fontSize={['xl', '3xl']} py={5} color={'myGray.600'} textAlign={'center'} maxW={'400px'}>
|
||||
{t('home.desc')}
|
||||
</Box>
|
||||
<Flex zIndex={1} flexDirection={['column', 'row']} mt={[5, 8]}>
|
||||
{feConfigs?.show_git && (
|
||||
<Button
|
||||
mr={[0, 5]}
|
||||
mb={[5, 0]}
|
||||
fontSize={['xl', '3xl']}
|
||||
h={'auto'}
|
||||
py={[2, 3]}
|
||||
variant={'base'}
|
||||
border={'2px solid'}
|
||||
borderColor={'myGray.800'}
|
||||
transition={'0.3s'}
|
||||
borderRadius={'xl'}
|
||||
_hover={{
|
||||
bg: 'myGray.800',
|
||||
color: 'white'
|
||||
}}
|
||||
leftIcon={<MyIcon name={'git'} w={'20px'} />}
|
||||
onClick={() => window.open('https://github.com/labring/FastGPT', '_blank')}
|
||||
>
|
||||
Stars {(gitStar / 1000).toFixed(1)}k
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
fontSize={['xl', '3xl']}
|
||||
h={['38px', 'auto']}
|
||||
borderRadius={'xl'}
|
||||
py={[2, 3]}
|
||||
w={'150px'}
|
||||
onClick={() => router.push(`/app/list`)}
|
||||
>
|
||||
{t('home.Start Now')}
|
||||
</Button>
|
||||
</Flex>
|
||||
<Box mt={['', '-50px']} position={'relative'}>
|
||||
<Image
|
||||
minH={['auto', '400px']}
|
||||
src={isPc ? '/imgs/home/videobgpc.png' : '/imgs/home/videobgphone.png'}
|
||||
mx={['-10%', 'auto']}
|
||||
maxW={['120%', '950px']}
|
||||
alt=""
|
||||
/>
|
||||
<MyIcon
|
||||
name={'playFill'}
|
||||
position={'absolute'}
|
||||
w={['30px', '40px']}
|
||||
cursor={'pointer'}
|
||||
left={'50%'}
|
||||
top={'50%'}
|
||||
color={'#363c42b8'}
|
||||
transform={['translate(-50%,5px)', 'translate(-50%,40px)']}
|
||||
onClick={() => {
|
||||
toast({
|
||||
title: '录制中~'
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default Hero;
|
144
client/src/pages/components/Navbar.tsx
Normal file
144
client/src/pages/components/Navbar.tsx
Normal file
@@ -0,0 +1,144 @@
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { Flex, Box, type BoxProps, Button, useDisclosure } from '@chakra-ui/react';
|
||||
import { feConfigs } from '@/store/static';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useRouter } from 'next/router';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import CommunityModal from '@/components/CommunityModal';
|
||||
import { useGlobalStore } from '@/store/global';
|
||||
import MyIcon from '@/components/Icon';
|
||||
|
||||
const Navbar = () => {
|
||||
const router = useRouter();
|
||||
const { t } = useTranslation();
|
||||
const [scrollTop, setScrollTop] = useState(0);
|
||||
const {
|
||||
isOpen: isOpenCommunity,
|
||||
onOpen: onOpenCommunity,
|
||||
onClose: onCloseCommunity
|
||||
} = useDisclosure();
|
||||
const { isOpen: isOpenMenu, onOpen: onOpenMenu, onClose: onCloseMenu } = useDisclosure();
|
||||
const { isPc } = useGlobalStore();
|
||||
const menuList = useMemo(
|
||||
() => [
|
||||
// { label: t('home.Features'), key: 'features', onClick: () => {} },
|
||||
{
|
||||
label: t('home.Community'),
|
||||
key: 'community',
|
||||
onClick: () => {
|
||||
onOpenCommunity();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: t('home.Docs'),
|
||||
key: 'docs',
|
||||
onClick: () => {
|
||||
window.open('https://doc.fastgpt.run/docs/intro');
|
||||
}
|
||||
}
|
||||
],
|
||||
[onOpenCommunity, t]
|
||||
);
|
||||
const bgOpacity = useMemo(() => {
|
||||
const rate = scrollTop / 120;
|
||||
if (rate > 0.7) {
|
||||
return 0.7;
|
||||
}
|
||||
return rate;
|
||||
}, [scrollTop]);
|
||||
|
||||
const menuStyles: BoxProps = {
|
||||
mr: 4,
|
||||
px: 5,
|
||||
py: 2,
|
||||
cursor: 'pointer',
|
||||
transition: '0.5s',
|
||||
borderRadius: 'xl',
|
||||
fontSize: 'lg',
|
||||
_hover: {
|
||||
bg: 'myGray.100'
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const scrollListen = (e: any) => {
|
||||
setScrollTop(e?.target?.scrollTop);
|
||||
};
|
||||
const dom = document.getElementById('home');
|
||||
if (!dom) return;
|
||||
|
||||
dom.addEventListener('scroll', scrollListen);
|
||||
|
||||
return () => {
|
||||
dom.removeEventListener('scroll', scrollListen);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Box
|
||||
bg={`rgba(255,255,255,${bgOpacity})`}
|
||||
backdropFilter={'blur(24px)'}
|
||||
py={[3, 5]}
|
||||
px={5}
|
||||
transition={'0.4s ease'}
|
||||
h={isOpenMenu ? '100vh' : 'auto'}
|
||||
>
|
||||
<Flex maxW={'1000px'} m={'auto'} alignItems={'center'}>
|
||||
<Avatar src="/icon/logo.png" w={['30px', '38px']} />
|
||||
<Box
|
||||
className="textlg"
|
||||
fontSize={['3xl', '4xl']}
|
||||
fontWeight={'bold'}
|
||||
ml={3}
|
||||
fontStyle={'italic'}
|
||||
>
|
||||
{feConfigs?.systemTitle}
|
||||
</Box>
|
||||
<Box flex={1} />
|
||||
{isPc ? (
|
||||
<>
|
||||
{menuList.map((item) => (
|
||||
<Box key={item.key} {...menuStyles} onClick={item.onClick}>
|
||||
{item.label}
|
||||
</Box>
|
||||
))}
|
||||
<Box px={4} color={'myGray.500'}>
|
||||
|
|
||||
</Box>
|
||||
<Box {...menuStyles} onClick={() => router.push('/login')}>
|
||||
{t('home.Login')}
|
||||
</Box>
|
||||
<Button ml={4} h={'36px'} borderRadius={'3xl'} onClick={() => router.push('/app/list')}>
|
||||
{t('home.Start Now')}
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<MyIcon
|
||||
name={isOpenMenu ? 'closeLight' : 'menu'}
|
||||
w={'20px'}
|
||||
onClick={() => (isOpenMenu ? onCloseMenu() : onOpenMenu())}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
{isOpenMenu && !isPc && (
|
||||
<Box mt={'15vh'} ml={'10vw'}>
|
||||
{menuList.map((item) => (
|
||||
<Box key={item.key} mb={8} onClick={item.onClick}>
|
||||
{item.label}
|
||||
</Box>
|
||||
))}
|
||||
<Box bg={'myGray.500'} h={'1.5px'} w={'20px'} mb={8} />
|
||||
<Box mb={10} onClick={() => router.push('/login')}>
|
||||
{t('home.Login')}
|
||||
</Box>
|
||||
<Button h={'36px'} borderRadius={'3xl'} onClick={() => router.push('/app/list')}>
|
||||
{t('home.Start Now')}
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
{isOpenCommunity && <CommunityModal onClose={onCloseCommunity} />}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default Navbar;
|
@@ -1,220 +1,31 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Card, Box, Link, Flex, Image, Button } from '@chakra-ui/react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useGlobalStore } from '@/store/global';
|
||||
import { feConfigs } from '@/store/static';
|
||||
import { serviceSideProps } from '@/utils/i18n';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import React, { useEffect } from 'react';
|
||||
import { Box } from '@chakra-ui/react';
|
||||
|
||||
import styles from './index.module.scss';
|
||||
import MyIcon from '@/components/Icon';
|
||||
import { serviceSideProps } from '@/utils/i18n';
|
||||
|
||||
import Navbar from './components/Navbar';
|
||||
import Hero from './components/Hero';
|
||||
import Ability from './components/Ability';
|
||||
import Choice from './components/Choice';
|
||||
import Footer from './components/Footer';
|
||||
|
||||
const Home = () => {
|
||||
const router = useRouter();
|
||||
const { t } = useTranslation();
|
||||
const { inviterId } = router.query as { inviterId: string };
|
||||
const { isPc, gitStar } = useGlobalStore();
|
||||
|
||||
useEffect(() => {
|
||||
if (inviterId) {
|
||||
localStorage.setItem('inviterId', inviterId);
|
||||
}
|
||||
}, [inviterId]);
|
||||
|
||||
/* 加载动画 */
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
try {
|
||||
window.particlesJS?.('particles-js', {
|
||||
particles: {
|
||||
number: {
|
||||
value: 40,
|
||||
density: {
|
||||
enable: true,
|
||||
value_area: 500
|
||||
}
|
||||
},
|
||||
color: {
|
||||
value: '#4e83fd'
|
||||
},
|
||||
shape: {
|
||||
type: 'circle',
|
||||
stroke: {
|
||||
width: 0,
|
||||
color: '#000000'
|
||||
},
|
||||
polygon: {
|
||||
nb_sides: 5
|
||||
}
|
||||
},
|
||||
opacity: {
|
||||
value: 0.5,
|
||||
random: false,
|
||||
anim: {
|
||||
enable: false,
|
||||
speed: 0.1,
|
||||
opacity_min: 0.1,
|
||||
sync: false
|
||||
}
|
||||
},
|
||||
size: {
|
||||
value: 3,
|
||||
random: true,
|
||||
anim: {
|
||||
enable: false,
|
||||
speed: 10,
|
||||
size_min: 0.1,
|
||||
sync: false
|
||||
}
|
||||
},
|
||||
line_linked: {
|
||||
enable: true,
|
||||
distance: 150,
|
||||
color: '#adceff',
|
||||
opacity: 0.4,
|
||||
width: 1
|
||||
},
|
||||
move: {
|
||||
enable: true,
|
||||
speed: 2,
|
||||
direction: 'none',
|
||||
random: true,
|
||||
straight: false,
|
||||
out_mode: 'out',
|
||||
bounce: false,
|
||||
attract: {
|
||||
enable: false,
|
||||
rotateX: 600,
|
||||
rotateY: 1200
|
||||
}
|
||||
}
|
||||
},
|
||||
interactivity: {
|
||||
detect_on: 'canvas',
|
||||
events: {
|
||||
onhover: {
|
||||
enable: true,
|
||||
mode: 'grab'
|
||||
},
|
||||
onclick: {
|
||||
enable: true,
|
||||
mode: 'push'
|
||||
},
|
||||
resize: true
|
||||
},
|
||||
modes: {
|
||||
grab: {
|
||||
distance: 140,
|
||||
line_linked: {
|
||||
opacity: 1
|
||||
}
|
||||
},
|
||||
bubble: {
|
||||
distance: 400,
|
||||
size: 40,
|
||||
duration: 2,
|
||||
opacity: 8,
|
||||
speed: 3
|
||||
},
|
||||
repulse: {
|
||||
distance: 200,
|
||||
duration: 0.4
|
||||
},
|
||||
push: {
|
||||
particles_nb: 4
|
||||
},
|
||||
remove: {
|
||||
particles_nb: 2
|
||||
}
|
||||
}
|
||||
},
|
||||
retina_detect: true
|
||||
});
|
||||
} catch (error) {}
|
||||
}, 500);
|
||||
}, [isPc]);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
className={styles.home}
|
||||
position={'relative'}
|
||||
flexDirection={'column'}
|
||||
alignItems={'center'}
|
||||
h={'100%'}
|
||||
overflow={'overlay'}
|
||||
>
|
||||
<Box id={'particles-js'} position={'absolute'} top={0} left={0} right={0} bottom={0} />
|
||||
|
||||
<Flex
|
||||
flexDirection={'column'}
|
||||
alignItems={'center'}
|
||||
justifyContent={'center'}
|
||||
mt={'22vh'}
|
||||
position={'absolute'}
|
||||
userSelect={'none'}
|
||||
textAlign={'center'}
|
||||
>
|
||||
<Image src="/icon/logo2.png" w={['70px', '120px']} h={['70px', '120px']} alt={''}></Image>
|
||||
<Box
|
||||
className={styles.textlg}
|
||||
fontWeight={'bold'}
|
||||
fontSize={['40px', '70px']}
|
||||
letterSpacing={'5px'}
|
||||
>
|
||||
{feConfigs?.systemTitle || 'AI知识库'}
|
||||
</Box>
|
||||
<Box className={styles.textlg} fontWeight={'bold'} fontSize={['30px', '50px']}>
|
||||
{t('home.Visual AI orchestration')}
|
||||
</Box>
|
||||
<Box className={styles.textlg} fontWeight={'bold'} fontSize={['30px', '50px']}>
|
||||
{t('home.Quickly build AI question and answer library')}
|
||||
</Box>
|
||||
|
||||
<Flex flexDirection={['column', 'row']} my={5}>
|
||||
{feConfigs?.show_git && (
|
||||
<Button
|
||||
mr={[0, 5]}
|
||||
mb={[5, 0]}
|
||||
fontSize={['xl', '3xl']}
|
||||
h={'auto'}
|
||||
py={[2, 3]}
|
||||
variant={'base'}
|
||||
border={'2px solid'}
|
||||
borderColor={'myGray.800'}
|
||||
transition={'0.3s'}
|
||||
_hover={{
|
||||
bg: 'myGray.800',
|
||||
color: 'white'
|
||||
}}
|
||||
leftIcon={<MyIcon name={'git'} w={'20px'} />}
|
||||
onClick={() => window.open('https://github.com/labring/FastGPT', '_blank')}
|
||||
>
|
||||
Stars {(gitStar / 1000).toFixed(1)}k
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
fontSize={['xl', '3xl']}
|
||||
h={'auto'}
|
||||
py={[2, 3]}
|
||||
onClick={() => router.push(`/app/list`)}
|
||||
>
|
||||
{t('home.Start Now')}
|
||||
</Button>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
<Box w={'100%'} mt={'100vh'} px={[5, 10]} pb={[5, 10]}>
|
||||
<Card p={5} mt={4} textAlign={'center'}>
|
||||
{feConfigs?.beianText && (
|
||||
<Link href="https://beian.miit.gov.cn/" target="_blank">
|
||||
{feConfigs.beianText}
|
||||
</Link>
|
||||
)}
|
||||
|
||||
{feConfigs?.authorText && <Box>{feConfigs?.authorText}</Box>}
|
||||
</Card>
|
||||
<Box id="home" bg={'myWhite.600'} h={'100vh'} overflowY={'auto'} overflowX={'hidden'}>
|
||||
<Box position={'fixed'} zIndex={10} top={0} left={0} right={0}>
|
||||
<Navbar />
|
||||
</Box>
|
||||
</Flex>
|
||||
<Box maxW={'1200px'} pt={'70px'} m={'auto'}>
|
||||
<Hero />
|
||||
<Ability />
|
||||
<Box my={[4, 6]}>
|
||||
<Choice />
|
||||
</Box>
|
||||
</Box>
|
||||
<Box bg={'white'}>
|
||||
<Footer />
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
|
@@ -12,7 +12,7 @@ import dynamic from 'next/dynamic';
|
||||
import { serviceSideProps } from '@/utils/i18n';
|
||||
import { setToken } from '@/utils/user';
|
||||
import { feConfigs } from '@/store/static';
|
||||
import WxConcat from '@/components/WxConcat';
|
||||
import CommunityModal from '@/components/CommunityModal';
|
||||
const RegisterForm = dynamic(() => import('./components/RegisterForm'));
|
||||
const ForgetPasswordForm = dynamic(() => import('./components/ForgetPasswordForm'));
|
||||
|
||||
@@ -115,7 +115,7 @@ const Login = () => {
|
||||
</Box>
|
||||
</Flex>
|
||||
|
||||
{isOpen && <WxConcat onClose={onClose} />}
|
||||
{isOpen && <CommunityModal onClose={onClose} />}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
@@ -8,14 +8,15 @@ import { setToken } from '@/utils/user';
|
||||
import { gitLogin } from '@/api/user';
|
||||
import { useToast } from '@/hooks/useToast';
|
||||
import Loading from '@/components/Loading';
|
||||
import { serviceSideProps } from '@/utils/i18n';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
const provider = () => {
|
||||
const provider = ({ code }: { code: string }) => {
|
||||
const { loginStore } = useGlobalStore();
|
||||
const { setLastChatId, setLastChatAppId } = useChatStore();
|
||||
const { setUserInfo } = useUserStore();
|
||||
const router = useRouter();
|
||||
const { toast } = useToast();
|
||||
const { code } = router.query as { code?: string };
|
||||
|
||||
const loginSuccess = useCallback(
|
||||
(res: ResLogin) => {
|
||||
@@ -64,11 +65,21 @@ const provider = () => {
|
||||
}
|
||||
}, [code, loginStore, loginSuccess]);
|
||||
|
||||
useEffect(() => {
|
||||
useQuery(['init', code], () => {
|
||||
authCode();
|
||||
}, [authCode]);
|
||||
return null;
|
||||
});
|
||||
|
||||
return <Loading />;
|
||||
};
|
||||
|
||||
export async function getServerSideProps(content: any) {
|
||||
return {
|
||||
props: {
|
||||
code: content?.query?.code,
|
||||
...(await serviceSideProps(content))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default provider;
|
||||
|
Reference in New Issue
Block a user