upgrade edit for /sight route to create articles

This commit is contained in:
maxim 2025-04-03 18:44:34 +03:00
parent 9c20c5661a
commit 36cc144798
2 changed files with 127 additions and 3 deletions

View File

@ -0,0 +1,116 @@
import {Typography, Button, Box, Accordion, AccordionSummary, AccordionDetails, useTheme, TextField} from '@mui/material'
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
import {axiosInstance} from '../providers/data'
import {BACKEND_URL} from '../lib/constants'
import {useForm, Controller} from 'react-hook-form'
import {MarkdownEditor} from './MarkdownEditor'
import React from 'react'
const MemoizedSimpleMDE = React.memo(MarkdownEditor)
type Props = {
parentId: string | number
parentResource: string
childResource: string
title: string
}
export const CreateSightArticle = ({parentId, parentResource, childResource, title}: Props) => {
const theme = useTheme()
const {
register: registerItem,
control: controlItem,
handleSubmit: handleSubmitItem,
reset: resetItem,
formState: {errors: itemErrors},
} = useForm({
defaultValues: {
heading: '',
body: '',
},
})
const simpleMDEOptions = React.useMemo(
() => ({
placeholder: 'Введите контент в формате Markdown...',
spellChecker: false,
}),
[],
)
const handleCreate = async (data: {heading: string; body: string}) => {
try {
const response = await axiosInstance.post(`${BACKEND_URL}/${childResource}`, data)
const itemId = response.data.id
const existingItemsResponse = await axiosInstance.get(`${BACKEND_URL}/${parentResource}/${parentId}/${childResource}`)
const existingItems = existingItemsResponse.data || []
const nextPageNum = existingItems.length + 1
await axiosInstance.post(`${BACKEND_URL}/${parentResource}/${parentId}/${childResource}/`, {
[`${childResource}_id`]: itemId,
page_num: nextPageNum,
})
resetItem()
window.location.reload()
} catch (err: any) {
console.error('Error creating item:', err)
if (err?.response) {
console.error('Error response:', err.response.data)
console.error('Error status:', err.response.status)
}
}
}
return (
<Accordion>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
sx={{
marginTop: 2,
background: theme.palette.background.paper,
borderBottom: `1px solid ${theme.palette.divider}`,
}}
>
<Typography variant="subtitle1" fontWeight="bold">
Создать {title}
</Typography>
</AccordionSummary>
<AccordionDetails sx={{background: theme.palette.background.paper}}>
<Box component="form" onSubmit={handleSubmitItem(handleCreate)}>
<TextField
{...registerItem('heading', {
required: 'Это поле является обязательным',
})}
error={!!(itemErrors as any)?.heading}
helperText={(itemErrors as any)?.heading?.message}
margin="normal"
fullWidth
InputLabelProps={{shrink: true}}
type="text"
label="Заголовок *"
/>
<Controller control={controlItem} name="body" rules={{required: 'Это поле является обязательным'}} defaultValue="" render={({field: {onChange, value}}) => <MemoizedSimpleMDE value={value} onChange={onChange} options={simpleMDEOptions} className="my-markdown-editor" />} />
<Box sx={{mt: 2, display: 'flex', gap: 2}}>
<Button variant="contained" color="primary" type="submit">
Создать
</Button>
<Button
variant="outlined"
onClick={() => {
resetItem()
}}
>
Очистить
</Button>
</Box>
</Box>
</AccordionDetails>
</Accordion>
)
}

View File

@ -4,9 +4,12 @@ import {useForm} from '@refinedev/react-hook-form'
import {Controller} from 'react-hook-form' import {Controller} from 'react-hook-form'
import {useParams} from 'react-router' import {useParams} from 'react-router'
import {LinkedItems} from '../../components/LinkedItems' import {LinkedItems} from '../../components/LinkedItems'
import {CreateSightArticle} from '../../components/CreateSightArticle'
import {ArticleItem, articleFields} from './types' import {ArticleItem, articleFields} from './types'
export const SightEdit = () => { export const SightEdit = () => {
const {id: sightId} = useParams<{id: string}>()
const { const {
saveButtonProps, saveButtonProps,
register, register,
@ -14,8 +17,6 @@ export const SightEdit = () => {
formState: {errors}, formState: {errors},
} = useForm({}) } = useForm({})
const {id: sightId} = useParams<{id: string}>()
const {autocompleteProps: cityAutocompleteProps} = useAutocomplete({ const {autocompleteProps: cityAutocompleteProps} = useAutocomplete({
resource: 'city', resource: 'city',
onSearch: (value) => [ onSearch: (value) => [
@ -98,7 +99,14 @@ export const SightEdit = () => {
)} )}
/> />
</Box> </Box>
{sightId && <LinkedItems<ArticleItem> type="edit" parentId={sightId} parentResource="sight" childResource="article" fields={articleFields} title="статьи" />}
{sightId && (
<Box sx={{mt: 3}}>
<LinkedItems<ArticleItem> type="edit" parentId={sightId} parentResource="sight" childResource="article" fields={articleFields} title="статьи" />
<CreateSightArticle parentId={sightId} parentResource="sight" childResource="article" title="статью" />
</Box>
)}
</Edit> </Edit>
) )
} }