add media data to /article/show page

This commit is contained in:
maxim 2025-02-13 18:34:47 +03:00
parent 92ad041aa2
commit c75853ce88
5 changed files with 96 additions and 15 deletions

View File

@ -4,24 +4,25 @@
"private": true,
"type": "module",
"dependencies": {
"@emotion/react": "^11.8.2",
"@emotion/styled": "^11.8.1",
"@mui/icons-material": "^6.1.6",
"@mui/lab": "^6.0.0-beta.14",
"@mui/material": "^6.1.7",
"@mui/x-data-grid": "^7.22.2",
"@refinedev/cli": "^2.16.21",
"@refinedev/core": "^4.47.1",
"@refinedev/devtools": "^1.1.32",
"@refinedev/kbar": "^1.3.6",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-router": "^7.0.2",
"@refinedev/simple-rest": "^5.0.1",
"@refinedev/mui": "^6.0.0",
"@refinedev/react-hook-form": "^4.8.14",
"@mui/icons-material": "^6.1.6",
"@emotion/react": "^11.8.2",
"@emotion/styled": "^11.8.1",
"@mui/lab": "^6.0.0-beta.14",
"@mui/material": "^6.1.7",
"@mui/x-data-grid": "^7.22.2",
"@refinedev/react-router": "^1.0.0",
"@refinedev/simple-rest": "^5.0.1",
"axios": "^1.7.9",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-hook-form": "^7.30.0",
"@refinedev/react-router": "^1.0.0"
"react-router": "^7.0.2"
},
"devDependencies": {
"@types/node": "^18.16.2",

View File

@ -50,6 +50,9 @@ importers:
'@refinedev/simple-rest':
specifier: ^5.0.1
version: 5.0.10(@refinedev/core@4.57.5(@tanstack/react-query@4.36.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
axios:
specifier: ^1.7.9
version: 1.7.9
react:
specifier: ^18.0.0
version: 18.3.1

View File

@ -27,6 +27,7 @@ import {VehicleList, VehicleCreate, VehicleEdit} from './pages/vehicle'
import {RouteList, RouteCreate, RouteEdit} from './pages/route'
import {CountryIcon, CityIcon, CarrierIcon, MediaIcon, ArticleIcon, SightIcon, StationIcon, VehicleIcon, RouteIcon} from './components/ui/Icons'
import {BACKEND_URL} from './lib/constants'
function App() {
return (
@ -38,7 +39,7 @@ function App() {
<RefineSnackbarProvider>
<DevtoolsProvider>
<Refine
dataProvider={dataProvider('https://wn.krbl.ru')}
dataProvider={dataProvider(BACKEND_URL)}
notificationProvider={useNotificationProvider}
routerProvider={routerBindings}
authProvider={authProvider}
@ -97,7 +98,6 @@ function App() {
create: '/article/create',
edit: '/article/edit/:id',
show: '/article/show/:id',
// добавить SHOW для article->media (https://wn.krbl.ru/article/2/media)
meta: {
canDelete: true,
label: 'Статьи',

1
src/lib/constants.ts Normal file
View File

@ -0,0 +1 @@
export const BACKEND_URL = 'https://wn.krbl.ru'

View File

@ -1,19 +1,47 @@
import {Stack, Typography} from '@mui/material'
import {Stack, Typography, Box, Grid2 as Grid} from '@mui/material'
import {useShow} from '@refinedev/core'
import {Show, TextFieldComponent as TextField} from '@refinedev/mui'
import {useEffect, useState} from 'react'
import axios from 'axios'
import {BACKEND_URL} from '../../lib/constants'
export const ArticleShow = () => {
const {query} = useShow({})
const {data, isLoading} = query
const record = data?.data
const [media, setMedia] = useState<any[]>([])
const [mediaLoading, setMediaLoading] = useState(true)
useEffect(() => {
if (record?.id) {
axios
.get(`${BACKEND_URL}/article/${record.id}/media`)
.then((response) => {
setMedia(response?.data || [])
setMediaLoading(false)
})
.catch(() => {
setMedia([])
setMediaLoading(false)
})
}
}, [record?.id])
const fields = [
{label: 'ID', data: 'id'},
{label: 'Heading', data: 'heading'},
{label: 'Body', data: 'body'},
]
const mediaFields = [
{label: 'ID', data: 'id'},
{label: 'Filename', data: 'filename'},
{label: 'Media Type', data: 'media_type'},
]
return (
<Show isLoading={isLoading}>
<Stack gap={4}>
@ -25,6 +53,54 @@ export const ArticleShow = () => {
<TextField value={record?.[data]} />
</Stack>
))}
<Stack gap={2}>
<Typography variant="body1" fontWeight="bold">
Media
</Typography>
<Grid container gap={2}>
{mediaLoading ? (
<Typography>Loading media...</Typography>
) : media.length > 0 ? (
media.map((mediaItem, index) => (
<Box key={index} sx={{border: '2px solid #dddddd25', padding: '20px', marginBottom: '8px'}}>
{record && (
<Box
sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
marginBottom: '20px',
}}
>
<img
src={`${BACKEND_URL}/media/${mediaItem?.id}/download`}
alt={mediaItem?.filename}
style={{
maxWidth: '100%',
height: '20vh',
objectFit: 'contain',
borderRadius: 8,
}}
/>
</Box>
)}
<Stack gap={0.5}>
{mediaFields.map(({label, data}) => (
<Typography key={data}>
<strong>{label}:</strong> {mediaItem?.[data]}
</Typography>
))}
</Stack>
</Box>
))
) : (
<Typography>No media found</Typography>
)}
</Grid>
</Stack>
</Stack>
</Show>
)