add media
data to /article/show
page
This commit is contained in:
parent
92ad041aa2
commit
c75853ce88
23
package.json
23
package.json
@ -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",
|
||||||
|
@ -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
|
||||||
|
@ -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
1
src/lib/constants.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const BACKEND_URL = 'https://wn.krbl.ru'
|
@ -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>
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user