integrate article
data into /sight/show
page
This commit is contained in:
parent
3af49c5a23
commit
bf72f78020
@ -110,7 +110,6 @@ function App() {
|
|||||||
create: '/sight/create',
|
create: '/sight/create',
|
||||||
edit: '/sight/edit/:id',
|
edit: '/sight/edit/:id',
|
||||||
show: '/sight/show/:id',
|
show: '/sight/show/:id',
|
||||||
// добавить SHOW для sight->article (https://wn.krbl.ru/sight/2/article)
|
|
||||||
meta: {
|
meta: {
|
||||||
canDelete: true,
|
canDelete: true,
|
||||||
label: 'Виды',
|
label: 'Виды',
|
||||||
|
@ -1,13 +1,101 @@
|
|||||||
import {Stack, Typography} from '@mui/material'
|
import {Stack, Typography, Box, Grid2 as Grid, Button, MenuItem, Select, FormControl, InputLabel, TextField} from '@mui/material'
|
||||||
import {useShow} from '@refinedev/core'
|
import {useShow} from '@refinedev/core'
|
||||||
import {Show, TextFieldComponent as TextField} from '@refinedev/mui'
|
import {Show, TextFieldComponent} from '@refinedev/mui'
|
||||||
|
|
||||||
|
import {useEffect, useState} from 'react'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
import {BACKEND_URL} from '../../lib/constants'
|
||||||
|
|
||||||
|
type ArticleItem = {
|
||||||
|
id: number
|
||||||
|
heading: string
|
||||||
|
body: string
|
||||||
|
}
|
||||||
|
|
||||||
export const SightShow = () => {
|
export const SightShow = () => {
|
||||||
const {query} = useShow({})
|
const {query} = useShow({})
|
||||||
const {data, isLoading} = query
|
const {data, isLoading} = query
|
||||||
|
|
||||||
const record = data?.data
|
const record = data?.data
|
||||||
|
|
||||||
|
const [articles, setArticles] = useState<ArticleItem[]>([])
|
||||||
|
const [linkedArticles, setLinkedArticles] = useState<ArticleItem[]>([])
|
||||||
|
const [selectedArticleId, setSelectedArticleId] = useState<number | ''>('')
|
||||||
|
const [pageNum, setPageNum] = useState<number>(1)
|
||||||
|
const [articlesLoading, setArticlesLoading] = useState<boolean>(true)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (record?.id) {
|
||||||
|
axios
|
||||||
|
.get(`${BACKEND_URL}/sight/${record.id}/article`)
|
||||||
|
.then((response) => {
|
||||||
|
setLinkedArticles(response?.data || [])
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setLinkedArticles([])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [record?.id])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
axios
|
||||||
|
.get(`${BACKEND_URL}/article/`)
|
||||||
|
.then((response) => {
|
||||||
|
setArticles(response?.data || [])
|
||||||
|
setArticlesLoading(false)
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setArticles([])
|
||||||
|
setArticlesLoading(false)
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const availableArticles = articles.filter((article) => !linkedArticles.some((linked) => linked.id === article.id))
|
||||||
|
|
||||||
|
const linkArticle = () => {
|
||||||
|
if (selectedArticleId) {
|
||||||
|
const requestData = {
|
||||||
|
article_id: selectedArticleId,
|
||||||
|
page_num: pageNum,
|
||||||
|
}
|
||||||
|
|
||||||
|
axios
|
||||||
|
.post(`${BACKEND_URL}/sight/${record?.id}/article`, requestData, {
|
||||||
|
headers: {
|
||||||
|
accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
axios
|
||||||
|
.get(`${BACKEND_URL}/sight/${record?.id}/article`)
|
||||||
|
.then((response) => {
|
||||||
|
setLinkedArticles(response?.data || [])
|
||||||
|
setPageNum(pageNum + 1)
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setLinkedArticles([])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error linking article:', error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteArticle = (articleId: number) => {
|
||||||
|
axios
|
||||||
|
.delete(`${BACKEND_URL}/sight/${record?.id}/article`, {
|
||||||
|
data: {article_id: articleId},
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
setLinkedArticles((prev) => prev.filter((item) => item.id !== articleId))
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error unlinking article:', error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const fields = [
|
const fields = [
|
||||||
{label: 'ID', data: 'id'},
|
{label: 'ID', data: 'id'},
|
||||||
{label: 'Name', data: 'name'},
|
{label: 'Name', data: 'name'},
|
||||||
@ -24,9 +112,70 @@ export const SightShow = () => {
|
|||||||
<Typography variant="body1" fontWeight="bold">
|
<Typography variant="body1" fontWeight="bold">
|
||||||
{label}
|
{label}
|
||||||
</Typography>
|
</Typography>
|
||||||
<TextField value={record?.[data]} />
|
<TextFieldComponent value={record?.[data]} />
|
||||||
</Stack>
|
</Stack>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
<Stack gap={2}>
|
||||||
|
<Typography variant="body1" fontWeight="bold">
|
||||||
|
Linked Articles
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Grid container gap={2}>
|
||||||
|
{articlesLoading ? (
|
||||||
|
<Typography>Loading articles...</Typography>
|
||||||
|
) : linkedArticles.length > 0 ? (
|
||||||
|
linkedArticles.map((article) => (
|
||||||
|
<Box key={article.id} sx={{border: '2px solid #dddddd25', padding: '20px', marginBottom: '8px'}}>
|
||||||
|
<Stack gap={0.5}>
|
||||||
|
<Typography>
|
||||||
|
<strong>ID:</strong> {article.id}
|
||||||
|
</Typography>
|
||||||
|
<Typography>
|
||||||
|
<strong>Heading:</strong> {article.heading}
|
||||||
|
</Typography>
|
||||||
|
<Typography>
|
||||||
|
<strong>Body:</strong> {article.body}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Button variant="outlined" color="error" onClick={() => deleteArticle(article.id)} sx={{mt: 2}}>
|
||||||
|
Unlink Article
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
</Box>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<Typography>No articles linked</Typography>
|
||||||
|
)}
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Stack gap={2}>
|
||||||
|
<Typography variant="body1" fontWeight="bold">
|
||||||
|
Link Article
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Stack gap={2.5}>
|
||||||
|
<FormControl fullWidth>
|
||||||
|
<InputLabel>Article</InputLabel>
|
||||||
|
<Select value={selectedArticleId} onChange={(e) => setSelectedArticleId(Number(e.target.value))} label="Article" fullWidth>
|
||||||
|
{availableArticles.map((article) => (
|
||||||
|
<MenuItem key={article.id} value={article.id}>
|
||||||
|
{article.heading}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<FormControl fullWidth>
|
||||||
|
<TextField type="number" label="Page Number" name="page_num" value={pageNum} onChange={(e) => setPageNum(Number(e.target.value))} fullWidth InputLabelProps={{shrink: true}} />
|
||||||
|
</FormControl>
|
||||||
|
|
||||||
|
<Button variant="contained" onClick={linkArticle} disabled={!selectedArticleId}>
|
||||||
|
Link Article
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Show>
|
</Show>
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user