You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
6.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import {
chakra,
Flex,
Button,
useColorModeValue,
Box,
useRadioGroup,
HStack,
Input,
Drawer,
useDisclosure,
DrawerOverlay,
DrawerContent,
Divider,
Heading,
Tag as ChakraTag,
TagLabel,
TagCloseButton
} from "@chakra-ui/react"
import { useViewportScroll } from "framer-motion"
import NextLink from "next/link"
import React, { useEffect, useState } from "react"
import Logo, { LogoIcon } from "src/components/logo"
import RadioCard from "components/radio-card"
import { EditMode } from "src/types/editor"
import Card from "components/card"
import TagInput from "components/tag-input"
import { Tag } from "src/types/tag"
import { cloneDeep, remove } from "lodash"
import { requestApi } from "utils/axios/request"
import DarkMode from "components/dark-mode"
function HeaderContent(props: any) {
const [tags,setTags]:[Tag[],any] = useState([])
const [allTags,setAllTags] = useState([])
const { isOpen, onOpen, onClose } = useDisclosure()
useEffect(() => {
requestApi.get('/tags').then(res => {
setAllTags(res.data)
const t = []
props.ar.tags?.forEach(id => {
res.data.forEach(tag => {
if (tag.id === id) {
t.push(tag)
}
})
})
setTags(t)
})
},[props.ar])
const editOptions = [EditMode.Edit, EditMode.Preview]
const { getRootProps, getRadioProps } = useRadioGroup({
name: "framework",
defaultValue: EditMode.Edit,
onChange: (v) => {
props.changeEditMode(v)
},
})
const group = getRootProps()
const addTag = t => {
setTags(t)
const ids = []
t.forEach(tag => ids.push(tag.id))
props.ar.tags = ids
}
const removeTag = t => {
const newTags = cloneDeep(tags)
remove(newTags, tag => tag.id === t.id)
setTags(newTags)
const ids = []
newTags.forEach(tag => ids.push(tag.id))
props.ar.tags = ids
}
return (
<>
<Flex w="100%" h="100%" align="center" justify="space-between" px={{ base: "4", md: "6" }}>
<Flex align="center">
<NextLink href="/" passHref>
<chakra.a display={{ base: "none", md: "block" }} style={{ marginTop: '-5px' }} aria-label="Chakra UI, Back to homepage">
<Logo width="130" />
</chakra.a>
</NextLink>
<NextLink href="/" passHref>
<chakra.a display={{ base: "block", md: "none" }} aria-label="Chakra UI, Back to homepage">
<LogoIcon />
</chakra.a>
</NextLink>
</Flex>
<Box>
<Input value={props.ar.title} placeholder="Title..." onChange={props.changeTitle} focusBorderColor={useColorModeValue('teal.400', 'teal.100')} variant="flushed" />
</Box>
<HStack {...group}>
{editOptions.map((value) => {
const radio = getRadioProps({ value })
return (
<RadioCard key={value} {...radio} bg="teal" color="white">
{value}
</RadioCard>
)
})}
</HStack>
<Box
color={useColorModeValue("gray.500", "gray.400")}
>
<DarkMode />
<Button layerStyle="colorButton" ml="2" onClick={onOpen}></Button>
</Box>
</Flex>
<Drawer
isOpen={isOpen}
placement="right"
onClose={onClose}
size="md"
motionPreset="none"
>
<DrawerOverlay>
<DrawerContent p="4">
<Flex justifyContent="space-between" alignItems="center">
<Heading size="sm"></Heading>
<Button layerStyle="colorButton" ml="2" onClick={props.publish}></Button>
</Flex>
<Divider mt="5" mb="5"/>
<Card>
<Heading size="xs">
</Heading>
<Input value={props.ar.cover} onChange={(e) => {props.ar.cover = e.target.value; props.onChange()}} mt="4" variant="unstyled" size="sm" placeholder="输入链接可以用github或postimg.cc当图片存储服务.." focusBorderColor="teal.400"/>
</Card>
<Card mt="4">
<Heading size="xs">
</Heading>
<TagInput options={allTags} selected={tags} onChange={addTag}/>
{tags.length > 0&& <Box mt="2">
{
tags.map(tag =>
<ChakraTag key={tag.id} mr="2" colorScheme="teal" variant="solid" px="2" py="1">
<TagLabel>{tag.title}</TagLabel>
<TagCloseButton onClick={ _ => removeTag(tag)}/>
</ChakraTag>)
}
</Box>}
</Card>
</DrawerContent>
</DrawerOverlay>
</Drawer>
</>
)
}
function EditorNav(props) {
const ref = React.useRef<HTMLHeadingElement>()
const [y, setY] = React.useState(0)
const { height = 0 } = ref.current?.getBoundingClientRect() ?? {}
const { scrollY } = useViewportScroll()
React.useEffect(() => {
return scrollY.onChange(() => setY(scrollY.get()))
}, [scrollY])
return (
<chakra.header
ref={ref}
shadow={y > height ? "sm" : undefined}
transition="box-shadow 0.2s"
pos="fixed"
top="0"
zIndex="3"
bg={useColorModeValue('white','gray.800')}
left="0"
right="0"
borderTop="4px solid"
borderTopColor="teal.400"
width="full"
>
<chakra.div height="4.5rem" mx="auto" maxW="1200px">
<HeaderContent {...props} />
</chakra.div>
</chakra.header>
)
}
export default EditorNav