|
1 | | -import { Box, Input, VStack } from '@chakra-ui/react'; |
| 1 | +import { Box, Button, HStack, Input, Text, VStack } from '@chakra-ui/react'; |
2 | 2 | import { MDXEditor } from '@mdxeditor/editor'; |
3 | 3 | import { ALL_PLUGINS } from './AllPlugins'; |
4 | 4 | import '@mdxeditor/editor/style.css'; |
5 | | -import { useCursor } from '@components'; |
6 | | -import { useLayoutEffect } from 'react'; |
7 | | - |
8 | | -const MD_Example = ` |
9 | | -# Hello world |
10 | | -This is a paragraph |
11 | | -
|
12 | | -- This is a list |
13 | | -- This is another list |
14 | | -
|
15 | | -\`\`\`js |
16 | | -console.log('Hello world'); |
17 | | -\`\`\` |
18 | | -
|
19 | | -This is a code block |
20 | | -
|
21 | | -`; |
| 5 | +import { ArticleCard, MdPreview, useCursor } from '@components'; |
| 6 | +import { useCallback, useLayoutEffect, useState } from 'react'; |
| 7 | +import { ARTICLE_DEFAULT } from './constants'; |
| 8 | +import { ArticleWithContent } from './types'; |
| 9 | +import { getRequestObject, isValidArticle } from './utils'; |
| 10 | +import { useAddArticle } from '@services'; |
22 | 11 |
|
23 | 12 | const ArticleEditor = () => { |
24 | 13 | const { setCursorType } = useCursor(); |
| 14 | + const [state, setState] = useState<ArticleWithContent>(ARTICLE_DEFAULT); |
| 15 | + const { mutate } = useAddArticle(); |
| 16 | + |
25 | 17 | useLayoutEffect(() => { |
26 | 18 | setCursorType('none'); |
27 | | - return () => { |
28 | | - setCursorType('follow'); |
29 | | - }; |
30 | 19 | }, [setCursorType]); |
| 20 | + |
| 21 | + const onSubmit = useCallback(() => { |
| 22 | + mutate(getRequestObject(state)); |
| 23 | + console.log('Submitting article', state); |
| 24 | + }, [mutate, state]); |
| 25 | + |
31 | 26 | return ( |
32 | 27 | <VStack px={10} pt={20} width={'100vw'} rowGap={4} bg={'black'}> |
33 | | - <VStack w={'50%'} rowGap={4}> |
34 | | - <Input placeholder="Title" /> |
35 | | - <Input placeholder="Subtitle" /> |
36 | | - </VStack> |
37 | | - <Box |
| 28 | + <HStack width={'100%'} justifyContent={'space-between'} align={'start'}> |
| 29 | + <VStack w={'80%'} rowGap={4}> |
| 30 | + <HStack w={'100%'} justifyContent={'space-between'}> |
| 31 | + <Text |
| 32 | + fontSize={'3xl'} |
| 33 | + fontWeight={'bold'} |
| 34 | + color={'white'} |
| 35 | + textAlign={'center'} |
| 36 | + > |
| 37 | + Article editor |
| 38 | + </Text> |
| 39 | + <Button |
| 40 | + onClick={() => setState(ARTICLE_DEFAULT)} |
| 41 | + colorScheme={'red'} |
| 42 | + > |
| 43 | + Clear Article |
| 44 | + </Button> |
| 45 | + </HStack> |
| 46 | + <HStack w={'100%'} rowGap={4}> |
| 47 | + <Input |
| 48 | + placeholder="Article Key" |
| 49 | + value={state.article_key} |
| 50 | + onChange={(e) => |
| 51 | + setState((prev) => ({ |
| 52 | + ...prev, |
| 53 | + article_key: e.target.value, |
| 54 | + })) |
| 55 | + } |
| 56 | + /> |
| 57 | + <Input |
| 58 | + placeholder="Article Title" |
| 59 | + value={state.title} |
| 60 | + onChange={(e) => |
| 61 | + setState((prev) => ({ |
| 62 | + ...prev, |
| 63 | + title: e.target.value, |
| 64 | + })) |
| 65 | + } |
| 66 | + /> |
| 67 | + <Input |
| 68 | + placeholder="Article description" |
| 69 | + value={state.description} |
| 70 | + onChange={(e) => |
| 71 | + setState((prev) => ({ |
| 72 | + ...prev, |
| 73 | + description: e.target.value, |
| 74 | + })) |
| 75 | + } |
| 76 | + /> |
| 77 | + </HStack> |
| 78 | + <HStack w={'100%'} rowGap={4}> |
| 79 | + <Input |
| 80 | + placeholder="Author" |
| 81 | + value={state.author} |
| 82 | + onChange={(e) => |
| 83 | + setState((prev) => ({ |
| 84 | + ...prev, |
| 85 | + author: e.target.value, |
| 86 | + })) |
| 87 | + } |
| 88 | + /> |
| 89 | + <Input |
| 90 | + placeholder="Group Id" |
| 91 | + value={state.group_id} |
| 92 | + onChange={(e) => |
| 93 | + setState((prev) => ({ |
| 94 | + ...prev, |
| 95 | + group_id: e.target.value, |
| 96 | + })) |
| 97 | + } |
| 98 | + /> |
| 99 | + <Input |
| 100 | + placeholder="Group Name" |
| 101 | + value={state.group_name} |
| 102 | + onChange={(e) => |
| 103 | + setState((prev) => ({ |
| 104 | + ...prev, |
| 105 | + group_name: e.target.value, |
| 106 | + })) |
| 107 | + } |
| 108 | + /> |
| 109 | + </HStack> |
| 110 | + <Input |
| 111 | + placeholder="Image" |
| 112 | + value={state.image} |
| 113 | + onChange={(e) => |
| 114 | + setState((prev) => ({ |
| 115 | + ...prev, |
| 116 | + image: e.target.value, |
| 117 | + })) |
| 118 | + } |
| 119 | + /> |
| 120 | + <Button |
| 121 | + w={'100%'} |
| 122 | + onClick={onSubmit} |
| 123 | + isDisabled={!isValidArticle(state)} |
| 124 | + > |
| 125 | + Submit Article |
| 126 | + </Button> |
| 127 | + </VStack> |
| 128 | + <ArticleCard |
| 129 | + views={0} |
| 130 | + likes={0} |
| 131 | + last_updated={new Date().toISOString()} |
| 132 | + {...state} |
| 133 | + /> |
| 134 | + </HStack> |
| 135 | + <HStack |
38 | 136 | width={'100%'} |
39 | 137 | border={'1px solid white'} |
40 | 138 | borderRadius={'md'} |
41 | 139 | p={2} |
42 | 140 | className=" min-h-[100vh]" |
| 141 | + align={'start'} |
43 | 142 | > |
44 | 143 | <MDXEditor |
45 | 144 | className="bg-white" |
46 | | - markdown={MD_Example} |
| 145 | + markdown={state.md_data} |
47 | 146 | plugins={ALL_PLUGINS} |
48 | 147 | spellCheck={true} |
49 | 148 | contentEditableClassName="min-h-[100vh] px-6 py-6 prose" |
| 149 | + onChange={(md) => { |
| 150 | + setState((prev) => ({ |
| 151 | + ...prev, |
| 152 | + md_data: md, |
| 153 | + })); |
| 154 | + }} |
50 | 155 | /> |
51 | | - </Box> |
| 156 | + <Box w={'100%'} h={'100%'} bg={'gray.900'} borderRadius={'md'}> |
| 157 | + <Text |
| 158 | + textAlign={'center'} |
| 159 | + color={'white'} |
| 160 | + fontSize={'2xl'} |
| 161 | + fontWeight={'bold'} |
| 162 | + > |
| 163 | + Preview |
| 164 | + </Text> |
| 165 | + <MdPreview mdString={state.md_data} /> |
| 166 | + </Box> |
| 167 | + </HStack> |
52 | 168 | </VStack> |
53 | 169 | ); |
54 | 170 | }; |
|
0 commit comments