Add item page

main
Shuhrat Tulyaganov 2023-03-30 18:38:43 +03:00
parent 9025b62fc5
commit 20dd0804c6
12 changed files with 308 additions and 31 deletions

View File

@ -2,6 +2,7 @@ import React from 'react'
import Card from '@mui/material/Card' import Card from '@mui/material/Card'
import { CardContent, CardMedia, Grid } from '@mui/material' import { CardContent, CardMedia, Grid } from '@mui/material'
import Typography from '@mui/material/Typography' import Typography from '@mui/material/Typography'
import { PropTypes } from 'prop-types'
import styles from './GridComp.module.css' import styles from './GridComp.module.css'
// const Rand = (min, max) => Math.floor(Math.random() * (max - min + 1) + min) // const Rand = (min, max) => Math.floor(Math.random() * (max - min + 1) + min)
@ -18,7 +19,10 @@ export default function GridComp({ name, data }) {
{(data || []).map((item) => ( {(data || []).map((item) => (
<Grid item xs={12} sm={3}> <Grid item xs={12} sm={3}>
<Card sx={{ height: '100%' }}> <Card sx={{ height: '100%' }}>
<a href="/" className={styles.aboximg}> <a
href={`films/item/${item.Id}`}
className={styles.aboximg}
>
<CardMedia className={styles.MediaCard}> <CardMedia className={styles.MediaCard}>
<div style={{ boxSizing: 'inherit' }}> <div style={{ boxSizing: 'inherit' }}>
<div className={styles.divbgimg}> <div className={styles.divbgimg}>
@ -43,17 +47,32 @@ export default function GridComp({ name, data }) {
</a> </a>
<CardContent> <CardContent>
<a
style={{ textDecoration: 'none' }}
href={`/films/item/${item.Id}`}
>
<Typography <Typography
component="h5" component="h5"
className={styles.title} className={styles.title}
> >
{item.Ru_title} {item.Ru_title}
</Typography> </Typography>
</a>
<Typography <Typography
variant="body2" variant="body2"
color="text.secondary" color="text.secondary"
> >
{item.Orig_title} {(item.Countries || []).map((e) => (
<span
style={{
display: 'inline-block',
marginRight: '5px',
}}
>
{e.country}
</span>
))}
</Typography> </Typography>
<Typography <Typography
variant="body2" variant="body2"
@ -73,3 +92,8 @@ export default function GridComp({ name, data }) {
</div> </div>
) )
} }
GridComp.propTypes = {
data: PropTypes.arrayOf(PropTypes.objectOf(PropTypes.any)),
name: PropTypes.string,
}

View File

@ -1,19 +1,20 @@
.title{ .title {
word-break: break-all; word-break: break-all;
color: #000;
} }
.title:hover{ .title:hover {
color: aqua; color: aqua;
} }
.aboximg{ .aboximg {
display:inline-flex; display: inline-flex;
width: 100%; width: 100%;
} }
.MediaCard{ .MediaCard {
width: 100%; width: 100%;
position: relative; position: relative;
} }
.divbgimg{ .divbgimg {
display: inline-block; display: inline-block;
max-width: 100%; max-width: 100%;
overflow: hidden; overflow: hidden;
@ -21,12 +22,12 @@
box-sizing: border-box; box-sizing: border-box;
margin: 0; margin: 0;
} }
.divbgimg2{ .divbgimg2 {
box-sizing: border-box; box-sizing: border-box;
display: block; display: block;
max-width: 100%; max-width: 100%;
} }
.imgBg{ .imgBg {
max-width: 100%; max-width: 100%;
display: block; display: block;
margin: 0; margin: 0;
@ -34,7 +35,7 @@
padding: 0; padding: 0;
} }
.imgPreViev{ .imgPreViev {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
@ -45,12 +46,12 @@
min-height: 100%; min-height: 100%;
max-height: 100%; max-height: 100%;
} }
.Janres{ .Janres {
margin-right: 5px; margin-right: 5px;
display: inline-block; display: inline-block;
color: black; color: black;
text-decoration: none; text-decoration: none;
} }
.Janres:hover{ .Janres:hover {
color: blueviolet; color: blueviolet;
} }

View File

@ -0,0 +1,124 @@
import React from 'react'
import { PropTypes } from 'prop-types'
import { Grid, Card, Typography } from '@mui/material'
import styles from './ItemComp.module.css'
export default function ItemComp({
Id,
Rutitle,
OrigTitle,
PosterUrl,
Countries,
Genres,
KinopoiskId,
RatingKinopoisk,
RatingImdbVoteCount,
RatingKinopoiskVoteCount,
RatingImdb,
Year,
Description,
}) {
return (
<div>
<Typography component="h1" sx={{ fontSize: 30 }}>
{' '}
{Rutitle} / {OrigTitle} /{Year}
</Typography>
<Grid
container
spacing={2}
className={styles.GridContainer}
sx={{ width: '50%', marginLeft: '10%' }}
>
<Grid item xs={12} sm={6} lg={3}>
<Card sx={{ width: '203px' }}>
<div>
<img
style={{ display: 'block' }}
width={203}
height={280}
src={PosterUrl}
alt="dsa"
/>
</div>
</Card>
{/* <Typography component="span">{Rutitle}</Typography> */}
</Grid>
<Grid item xs={12} sm={6} lg={4}>
<Typography sx={{ display: 'block' }} component="span">
Название
<span className={styles.title}>{`: ${Rutitle}`}</span>
</Typography>
<Typography sx={{ display: 'block' }} component="span">
Оригинальное
<span className={styles.title}>{`: ${OrigTitle}`}</span>
</Typography>
<Typography sx={{ display: 'block' }} component="span">
Год <span className={styles.title}>{`: ${Year}`}</span>
</Typography>
<Typography sx={{ display: 'block' }} component="span">
Страна{': '}
{Countries.map((item) => (
<span
className={styles.title}
>{`${item.country} `}</span>
))}
</Typography>
<Typography sx={{ display: 'block' }} component="span">
Жанры{': '}
{Genres.map((item) => (
<span
className={styles.genres}
>{`${item.genre} `}</span>
))}
</Typography>
<Typography sx={{ display: 'block' }} component="span">
KinopoiskId <span>{`: ${KinopoiskId}`}</span>
</Typography>
<Typography sx={{ display: 'block' }} component="span">
Рейтинг <span>{`: ${RatingKinopoisk}`}</span>
</Typography>
<Typography sx={{ display: 'block' }} component="span">
РейтингIMDB <span>{`: ${RatingImdb}`}</span>
</Typography>
<Typography sx={{ display: 'block' }} component="span">
Голосов <span>{`: ${RatingKinopoiskVoteCount}`}</span>
</Typography>
<Typography sx={{ display: 'block' }} component="span">
ГолосовIMDB <span>{`: ${RatingImdbVoteCount}`}</span>
</Typography>
</Grid>
<Grid item xs={12} lg={5} sx={{ marginRight: '0%' }}>
<span className={styles.discription}>Описание</span>
<p>{Description}</p>
</Grid>
</Grid>
{console.log(
Id,
Rutitle,
PosterUrl,
Countries,
Genres,
Year,
Description
)}
</div>
)
}
ItemComp.propTypes = {
Id: PropTypes.number,
Rutitle: PropTypes.string,
OrigTitle: PropTypes.string,
PosterUrl: PropTypes.string,
KinopoiskId: PropTypes.number,
RatingKinopoisk: PropTypes.number,
RatingImdbVoteCount: PropTypes.number,
RatingKinopoiskVoteCount: PropTypes.number,
RatingImdb: PropTypes.number,
Countries: PropTypes.arrayOf(PropTypes.objectOf(PropTypes.any)),
Genres: PropTypes.arrayOf(PropTypes.objectOf(PropTypes.any)),
Year: PropTypes.number,
Description: PropTypes.string,
}

View File

@ -0,0 +1,18 @@
.GridContainer {
margin-left: 50px;
}
.title {
color: #1976d2;
font-weight: 700;
}
.genres {
color: #1976d2;
}
.genres:hover {
text-decoration: underline;
}
.discription {
margin: 25%;
font-weight: 700;
color: #1976d2;
}

View File

@ -0,0 +1,15 @@
import React from 'react'
import Stack from '@mui/material/Stack'
import CircularProgress from '@mui/material/CircularProgress'
export default function LoadComp() {
return (
<div>
<Stack sx={{ color: 'grey.500' }} spacing={2} direction="row">
<CircularProgress color="secondary" />
<CircularProgress color="success" />
<CircularProgress color="inherit" />
</Stack>
</div>
)
}

View File

@ -0,0 +1,33 @@
import React from 'react'
import { useQuery } from 'react-query'
import { useParams } from 'react-router-dom'
import HeaderComp from '../Components/HeaderComp/HeaderComp'
import ItemComp from '../Components/ItemComp/ItemComp'
import api from '../utils/api'
import Load from './Load'
export default function FilmItem() {
const { id } = useParams()
const { data, isLoading } = useQuery(`/${id}`, api)
if (isLoading) return <Load />
return (
<div>
<HeaderComp />
<ItemComp
Id={data.Id}
Rutitle={data.Ru_title}
OrigTitle={data.Orig_title}
PosterUrl={data.PosterUrl}
Countries={data.Countries}
KinopoiskId={data.Kinopoisk_id}
RatingKinopoisk={data.RatingKinopoisk}
RatingImdbVoteCount={data.RatingImdbVoteCount}
RatingKinopoiskVoteCount={data.RatingKinopoiskVoteCount}
RatingImdb={data.RatingImdb}
Genres={data.Genres}
Year={data.Year}
Description={data.Description}
/>
</div>
)
}

View File

@ -1,18 +1,38 @@
import { Container, Pagination } from '@mui/material' import { Container, Pagination, PaginationItem } from '@mui/material'
import React from 'react' import React from 'react'
import { useQuery } from 'react-query'
import { Link, useLocation } from 'react-router-dom'
import GridComp from '../Components/GridComp/GridComp' import GridComp from '../Components/GridComp/GridComp'
import HeaderComp from '../Components/HeaderComp/HeaderComp' import HeaderComp from '../Components/HeaderComp/HeaderComp'
import api from '../utils/api'
export default function Films() { export default function Films() {
const location = useLocation()
const query = new URLSearchParams(location.search)
const { data } = useQuery(
`/page/${query.get('page') === null ? '1' : query.get('page')}`,
api
)
return ( return (
<div> <div>
<HeaderComp /> <HeaderComp />
<Container> <Container>
<GridComp name="Фильмы" /> <GridComp name="Фильмы" data={data} />
<Pagination <Pagination
sx={{ marginTop: '2%', marginLeft: '23%' }} sx={{ marginTop: '2%', marginLeft: '23%' }}
count={10} count={1929}
color="secondary" color="secondary"
renderItem={(item) => (
<PaginationItem
component={Link}
to={{
pathname: '/films',
search: `page=${String(item.page)}`,
}}
// eslint-disable-next-line react/jsx-props-no-spreading
{...item}
/>
)}
/> />
</Container> </Container>
</div> </div>

12
src/Pages/Load.jsx 100644
View File

@ -0,0 +1,12 @@
import React from 'react'
import HeaderComp from '../Components/HeaderComp/HeaderComp'
import LoadComp from '../Components/LoadComp/LoadComp'
export default function Load() {
return (
<div>
<HeaderComp />
<LoadComp />
</div>
)
}

View File

@ -4,20 +4,14 @@ import { Container, Button } from '@mui/material/'
// eslint-disable-next-line import/no-extraneous-dependencies // eslint-disable-next-line import/no-extraneous-dependencies
import { useQuery } from 'react-query' import { useQuery } from 'react-query'
// eslint-disable-next-line import/no-extraneous-dependencies // eslint-disable-next-line import/no-extraneous-dependencies
import axios from 'axios'
import GridComp from '../Components/GridComp/GridComp' import GridComp from '../Components/GridComp/GridComp'
import HeaderComp from '../Components/HeaderComp/HeaderComp' import HeaderComp from '../Components/HeaderComp/HeaderComp'
import ErrorPage from './ErrorPage' import ErrorPage from './ErrorPage'
import api from '../utils/api'
const test = async () => {
const res = await axios.get('http://localhost:8050/api/films/last/')
return res.data
}
export default function Main() { export default function Main() {
// eslint-disable-next-line no-shadow // eslint-disable-next-line no-shadow
const { data, error } = useQuery('repoData', test) const { data, error } = useQuery('/last/', api)
if (error) return <ErrorPage /> if (error) return <ErrorPage />
return ( return (
<div> <div>

View File

@ -0,0 +1,10 @@
import React from 'react'
import ItemComp from '../Components/ItemComp/ItemComp'
export default function Series() {
return (
<div>
<ItemComp />
</div>
)
}

View File

@ -3,6 +3,7 @@ import React from 'react'
import { QueryClientProvider, QueryClient } from 'react-query' import { QueryClientProvider, QueryClient } from 'react-query'
// eslint-disable-next-line import/no-extraneous-dependencies // eslint-disable-next-line import/no-extraneous-dependencies
import { BrowserRouter, Route, Routes } from 'react-router-dom' import { BrowserRouter, Route, Routes } from 'react-router-dom'
import FilmItem from '../Pages/FilmItem'
import Films from '../Pages/Films' import Films from '../Pages/Films'
import Main from '../Pages/Main' import Main from '../Pages/Main'
// eslint-disable-next-line import/no-extraneous-dependencies // eslint-disable-next-line import/no-extraneous-dependencies
@ -21,7 +22,24 @@ export default function Routers() {
</QueryClientProvider> </QueryClientProvider>
} }
/> />
<Route path="/films" element={<Films />} /> <Route
exact
path="/films"
element={
<QueryClientProvider client={queryClient}>
<Films />
</QueryClientProvider>
}
/>
<Route
exact
path="/films/item/:id"
element={
<QueryClientProvider client={queryClient}>
<FilmItem />
</QueryClientProvider>
}
/>
</Routes> </Routes>
</BrowserRouter> </BrowserRouter>
) )

8
src/utils/api.js 100644
View File

@ -0,0 +1,8 @@
import axios from 'axios'
export default async function api({ queryKey }) {
const res = await axios.get(
`http://192.168.1.35:8050/api/films${queryKey[0]}`
)
return res.data
}