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

View File

@ -50,6 +50,9 @@ importers:
'@refinedev/simple-rest': '@refinedev/simple-rest':
specifier: ^5.0.1 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)) 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: react:
specifier: ^18.0.0 specifier: ^18.0.0
version: 18.3.1 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 {RouteList, RouteCreate, RouteEdit} from './pages/route'
import {CountryIcon, CityIcon, CarrierIcon, MediaIcon, ArticleIcon, SightIcon, StationIcon, VehicleIcon, RouteIcon} from './components/ui/Icons' import {CountryIcon, CityIcon, CarrierIcon, MediaIcon, ArticleIcon, SightIcon, StationIcon, VehicleIcon, RouteIcon} from './components/ui/Icons'
import {BACKEND_URL} from './lib/constants'
function App() { function App() {
return ( return (
@ -38,7 +39,7 @@ function App() {
<RefineSnackbarProvider> <RefineSnackbarProvider>
<DevtoolsProvider> <DevtoolsProvider>
<Refine <Refine
dataProvider={dataProvider('https://wn.krbl.ru')} dataProvider={dataProvider(BACKEND_URL)}
notificationProvider={useNotificationProvider} notificationProvider={useNotificationProvider}
routerProvider={routerBindings} routerProvider={routerBindings}
authProvider={authProvider} authProvider={authProvider}
@ -97,7 +98,6 @@ function App() {
create: '/article/create', create: '/article/create',
edit: '/article/edit/:id', edit: '/article/edit/:id',
show: '/article/show/:id', show: '/article/show/:id',
// добавить SHOW для article->media (https://wn.krbl.ru/article/2/media)
meta: { meta: {
canDelete: true, canDelete: true,
label: 'Статьи', 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 {useShow} from '@refinedev/core'
import {Show, TextFieldComponent as TextField} from '@refinedev/mui' 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 = () => { export const ArticleShow = () => {
const {query} = useShow({}) const {query} = useShow({})
const {data, isLoading} = query const {data, isLoading} = query
const record = data?.data 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 = [ const fields = [
{label: 'ID', data: 'id'}, {label: 'ID', data: 'id'},
{label: 'Heading', data: 'heading'}, {label: 'Heading', data: 'heading'},
{label: 'Body', data: 'body'}, {label: 'Body', data: 'body'},
] ]
const mediaFields = [
{label: 'ID', data: 'id'},
{label: 'Filename', data: 'filename'},
{label: 'Media Type', data: 'media_type'},
]
return ( return (
<Show isLoading={isLoading}> <Show isLoading={isLoading}>
<Stack gap={4}> <Stack gap={4}>
@ -25,6 +53,54 @@ export const ArticleShow = () => {
<TextField value={record?.[data]} /> <TextField value={record?.[data]} />
</Stack> </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> </Stack>
</Show> </Show>
) )