Skip to content

Commit

Permalink
- add movie list
Browse files Browse the repository at this point in the history
- add movie list item
  • Loading branch information
andreu6454 committed Oct 5, 2023
1 parent 2be1569 commit 6e5d2e0
Show file tree
Hide file tree
Showing 26 changed files with 296 additions and 88 deletions.
2 changes: 2 additions & 0 deletions extractedTranslations/en/movies.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
"Слоган": "",
"Страна": "Страна",
"Сценарий": "",
"Трейлер": "Трейлер",
"Фильм не найден": "",
"Фильмы не найдены": "Фильмы не найдены",
"Художник": ""
}
3 changes: 2 additions & 1 deletion extractedTranslations/en/translation.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"error": ""
"error": "",
"Фильм не найден": ""
}
36 changes: 19 additions & 17 deletions public/locales/en/movies.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
{
"Фильм не найден": "Фильм не найден",
"О фильме": "О фильме",
"Страна": "Страна",
"Жанр": "Жанр",
"Слоган": "Слоган",
"Режиссера": "Режиссера",
"Сценарий":"Сценарий",
"Год производства": "Год производства",
"Продюсер":"Продюсер",
"Оператор": "Оператор",
"Композитор":"Композитор",
"Художник": "Художник",
"Монтаж":"Монтаж",
"Бюджет": "Бюджет",
"Маркетинг":"Маркетинг",
"Сборы в США": "Сборы в США",
"Сборы в мире": "Сборы в мире"
"Фильм не найден": "Movie not found",
"О фильме": "About",
"Страна": "Country",
"Жанр": "Genre",
"Слоган": "Slogan",
"Режиссера": "Director",
"Сценарий":"Scenario",
"Год производства": "Year",
"Продюсер":"Producer",
"Оператор": "Operator",
"Композитор":"Composer",
"Художник": "Designer",
"Монтаж":"Installation",
"Бюджет": "Budget",
"Маркетинг":"Marketing",
"Сборы в США": "US fees",
"Сборы в мире": "World fees",
"Трейлер": "Trailer",
"Фильмы не найдены": "Фильмы не найдены"
}
4 changes: 3 additions & 1 deletion public/locales/ru/movies.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@
"Бюджет": "Бюджет",
"Маркетинг":"Маркетинг",
"Сборы в США": "Сборы в США",
"Сборы в мире": "Сборы в мире"
"Сборы в мире": "Сборы в мире",
"Трейлер": "Трейлер",
"Фильмы не найдены": "Фильмы не найдены"
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {classNames} from "@/shared/lib/classNames/classNames";
import {useTranslation} from "react-i18next";
import {Article, ArticleBlockType, ArticleTextBlock, ArticleView} from "../../../model/types/article";
import {HTMLAttributeAnchorTarget} from "react";
import {HTMLAttributeAnchorTarget, memo} from "react";
import {Text} from "@/shared/ui/redesigned/Text";
import cls from "./ArticleListItemRedesigned.module.scss";
import {Icon} from "@/shared/ui/redesigned/Icon";
Expand All @@ -22,7 +22,7 @@ interface ArticleListItemProps {
target?: HTMLAttributeAnchorTarget
}

export const ArticleListItemRedesigned = (props: ArticleListItemProps) => {
export const ArticleListItemRedesigned = memo((props: ArticleListItemProps) => {
const {className, article, view, target} = props

const {t} = useTranslation('article')
Expand Down Expand Up @@ -118,4 +118,4 @@ export const ArticleListItemRedesigned = (props: ArticleListItemProps) => {
</Card>
</AppLink>
);
};
});
6 changes: 5 additions & 1 deletion src/entities/Movie/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
export type { MovieSchema } from './model/types/MovieSchema';
export {MovieDetailsReducer} from "./model/slices/movieDetailsSlice";

export {MovieDetails} from "./ui/MovieDetails/MovieDetails";

export type { MovieDetailsSchema } from './model/types/MovieDetailsSchema';

2 changes: 1 addition & 1 deletion src/entities/Movie/model/selectors/movieDetails.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {StateSchema} from "@/app/providers/StoreProvider";

export const getMovieDetailsData = (state: StateSchema) => state.movieDetails?.data
export const getMovieDetailsIsLoading = (state: StateSchema) => state.movieDetails?.isLoading
export const getMovieDetailsIsLoading = (state: StateSchema) => state.movieDetails?.isLoading || false
export const getMovieDetailsError = (state: StateSchema) => state.movieDetails?.error
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {createAsyncThunk} from "@reduxjs/toolkit";
import {ThunkConfig} from "@/app/providers/StoreProvider";
import i18n from "@/shared/config/i18n/i18n";
import {Article} from "@/entities/Article";
import {KinopoiskDev, MovieDtoV13} from "@openmoviedb/kinopoiskdev_client";
import {kpToken} from "@/shared/const/kinopoisk";

export const fetchMovieById =
createAsyncThunk<MovieDtoV13, number, ThunkConfig<string>>(
Expand All @@ -12,7 +12,7 @@ export const fetchMovieById =

const {rejectWithValue} = thunkAPI
try {
const kp = new KinopoiskDev('RREFY7V-4PY4YDX-KDH1NKW-QQC3F3A')
const kp = new KinopoiskDev(kpToken)

const {data} = await kp.movie.getById(id)

Expand Down
3 changes: 0 additions & 3 deletions src/entities/Movie/model/types/MovieSchema.ts

This file was deleted.

3 changes: 1 addition & 2 deletions src/entities/Movie/ui/MovieAbout/MovieAbout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ export const MovieAbout = memo((props: MovieAboutProps) => {
const composer = data?.persons?.filter(
el => el.profession === "композиторы").map((el) => el.enName).slice(0,3).join(', ')

console.log(data?.persons)

return (
<VStack align={'start'} justify={'start'} className={classNames(cls.MovieAbout, {}, [className])}>
Expand Down Expand Up @@ -108,7 +107,7 @@ export const MovieAbout = memo((props: MovieAboutProps) => {
<span className={cls.fieldName}>
{t("Бюджет")}
</span>
{data?.budget?.value + (data?.budget?.currency || "$")}
{(data?.budget?.currency || "$") + data?.budget?.value}
</span>
<span className={cls.field}>
<span className={cls.fieldName}>
Expand Down
34 changes: 19 additions & 15 deletions src/entities/Movie/ui/MovieDetails/MovieDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,25 @@ import {memo, useEffect} from "react";
import {useTranslation} from "react-i18next";
import {useAppDispatch} from "@/shared/lib/hooks/useAppDispatch/useAppDispatch";
import {useSelector} from "react-redux";
import {getMovieDetailsData, getMovieDetailsIsLoading} from "@/entities/Movie/model/selectors/movieDetails";
import {
getMovieDetailsData,
getMovieDetailsError,
getMovieDetailsIsLoading
} from "@/entities/Movie/model/selectors/movieDetails";
import {fetchMovieById} from "@/entities/Movie/model/services/fetchMovieById/fetchMovieById";
import {AppImage} from "@/shared/ui/redesigned/AppImage";
import {VStack} from "@/shared/ui/redesigned/Stack";
import {Text} from "@/shared/ui/redesigned/Text";
import {MovieAbout} from "@/entities/Movie/ui/MovieAbout/MovieAbout";
import {StickyContentLayout} from "@/shared/layouts/StickyContentLayout";
import {MovieDetailsSkeleton} from "@/entities/Movie/ui/MovieDetails/MovieDetailsSkeleton";
import {MovieDtoV13} from "@openmoviedb/kinopoiskdev_client";
import {MovieTrailer} from "@/entities/Movie/ui/MovieTrailer/MovieTrailer";

interface MovieDetailsProps {
className?: string;
id?: number
id?: number;
data?: MovieDtoV13;
}

export const MovieDetails = memo((props: MovieDetailsProps) => {
Expand All @@ -27,6 +34,7 @@ export const MovieDetails = memo((props: MovieDetailsProps) => {
const dispatch = useAppDispatch()
const data = useSelector(getMovieDetailsData)
const isLoading = useSelector(getMovieDetailsIsLoading)
const error = useSelector(getMovieDetailsError)


useEffect(() => {
Expand All @@ -41,8 +49,15 @@ export const MovieDetails = memo((props: MovieDetailsProps) => {
)
}

return (
// if (error) {
// return (
// <div className={classNames(cls.ArticleDetailesPage, {}, [className])}>
// <Text variant={'error'} title={"Ошибка"} text={error}/>
// </div>
// )
// }

return (
<>
<StickyContentLayout
left={
Expand All @@ -66,18 +81,7 @@ export const MovieDetails = memo((props: MovieDetailsProps) => {
</VStack>
}
/>
<VStack gap={'16'} align={'center'} max>
<Text title={'Трейлер'} bold/>
<iframe
width="800px"
height="400px"
src={data?.videos?.trailers?.[0].url}
title="YouTube video player"
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
/>
</VStack>
<MovieTrailer/>
</>
);
});
28 changes: 28 additions & 0 deletions src/entities/Movie/ui/MovieList/MovieList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {classNames} from "@/shared/lib/classNames/classNames";
import {MovieDtoV13} from "@openmoviedb/kinopoiskdev_client";
import {MovieListItem} from "@/entities/Movie/ui/MovieListItem/MovieListItem";
import {memo} from "react";
import {VStack} from "@/shared/ui/redesigned/Stack";

interface MovieListProps {
className?: string;
movies?: MovieDtoV13[]
}

export const MovieList = memo((props: MovieListProps) => {
const {className, movies} = props


const moviesForRender = movies?.map((el, index) => {
return (
<MovieListItem movie={el} key={el.id} index={++index}/>
)
})


return (
<VStack max gap={'16'} className={classNames('', {}, [className])}>
{moviesForRender}
</VStack>
);
});
13 changes: 13 additions & 0 deletions src/entities/Movie/ui/MovieList/MovieListSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {VStack} from "@/shared/ui/redesigned/Stack";
import {MovieListItemSkeleton} from "@/entities/Movie/ui/MovieListItem/MovieListItemSkeleton";

export const MovieListSkeleton = () => {
return (
<VStack max gap={'16'}>
<MovieListItemSkeleton/>
<MovieListItemSkeleton/>
<MovieListItemSkeleton/>
<MovieListItemSkeleton/>
</VStack>
);
};
3 changes: 3 additions & 0 deletions src/entities/Movie/ui/MovieListItem/MovieListItem.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.description {
max-width: 650px;
}
54 changes: 54 additions & 0 deletions src/entities/Movie/ui/MovieListItem/MovieListItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import {classNames} from "@/shared/lib/classNames/classNames";
import {MovieDtoV13} from "@openmoviedb/kinopoiskdev_client";
import {Card} from "@/shared/ui/redesigned/Card";
import {HStack, VStack} from "@/shared/ui/redesigned/Stack";
import {Text} from "@/shared/ui/redesigned/Text";
import {AppImage} from "@/shared/ui/redesigned/AppImage";
import {memo} from "react";
import {AppLink} from "@/shared/ui/redesigned/AppLink";
import {getRouteMoviesDetails} from "@/shared/const/router";
import cls from './MovieListItem.module.scss'

interface MovieListItemProps {
className?: string;
movie: MovieDtoV13;
index?: number;
}

export const MovieListItem = memo((props: MovieListItemProps) => {
const {className, movie, index} = props

const description =
`${movie?.countries?.[0].name}*${movie?.genres?.[0].name}`

const description2 = movie.shortDescription

const votesCount: number = Number(movie?.votes?.kp)

return (
<Card
padding={'24'}
max
border={'partial'}
className={classNames('', {}, [className])}
>
<AppLink to={getRouteMoviesDetails(movie?.id + '')}>
<HStack justify={'between'} gap={'32'} align={'start'}>
<HStack gap={'32'} className={cls.description}>
<Text bold title={index + ''}/>
<AppImage src={movie.poster?.previewUrl} width={72} height={108}/>
<VStack>
<Text title={movie.name} text={movie.alternativeName} bold/>
<Text Opacity={'80%'} size={'s'} text={description}/>
<Text Opacity={'80%'} size={'s'} text={description2}/>
</VStack>
</HStack>
<VStack align={'center'}>
<Text variant={'accent'} bold title={movie.rating?.kp?.toFixed(1) + ''} size={'l'}/>
<Text text={votesCount.toLocaleString('ru-Ru') + ' оценок'}/>
</VStack>
</HStack>
</AppLink>
</Card>
);
});
27 changes: 27 additions & 0 deletions src/entities/Movie/ui/MovieListItem/MovieListItemSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {Card} from "@/shared/ui/redesigned/Card";
import {HStack, VStack} from "@/shared/ui/redesigned/Stack";
import {Skeleton} from "@/shared/ui/redesigned/Skeleton";


export const MovieListItemSkeleton = () => {
return (
<Card padding={'24'} border={'partial'} max>
<HStack justify={'between'} align={'start'} max>
<HStack gap={'32'}>
<Skeleton width={15} height={30} border={'12px'}/>
<Skeleton width={72} height={108}/>
<VStack gap={'8'}>
<Skeleton height={32} width={200} border={'12px'}/>
<Skeleton height={24} width={180} border={'12px'}/>
<Skeleton height={20} width={300} border={'12px'}/>
<Skeleton height={20} width={400} border={'12px'}/>
</VStack>
</HStack>
<VStack gap={'8'} align={'center'}>
<Skeleton width={45} height={45} border={'12px'}/>
<Skeleton width={133} height={24} border={'12px'}/>
</VStack>
</HStack>
</Card>
);
};
39 changes: 39 additions & 0 deletions src/entities/Movie/ui/MovieTrailer/MovieTrailer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {classNames} from "@/shared/lib/classNames/classNames";
import {useTranslation} from "react-i18next";
import {HStack, VStack} from "@/shared/ui/redesigned/Stack";
import {Text} from "@/shared/ui/redesigned/Text";
import {useSelector} from "react-redux";
import {getMovieDetailsData} from "../../model/selectors/movieDetails";
import {memo} from "react";

interface MovieTrailerProps {
className?: string;
}

export const MovieTrailer = memo((props: MovieTrailerProps) => {
const {className} = props
const {t} = useTranslation('movies')

const data = useSelector(getMovieDetailsData)

if(!data?.videos?.trailers?.[0]?.url){
return null
}

return (
<VStack gap={'16'} max className={classNames('', {}, [className])}>
<Text title={t('Трейлер')} bold/>
<HStack max align={'center'} justify={'center'}>
<iframe
width="800px"
height="400px"
src={data?.videos?.trailers?.[0].url}
title="YouTube video player"
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
/>
</HStack>
</VStack>
);
});
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {classNames} from "@/shared/lib/classNames/classNames";
import {memo} from "react";
import {Card} from "@/shared/ui/redesigned/Card";
import {MovieDetails} from "@/entities/Movie/ui/MovieDetails/MovieDetails";
import {MovieDetails} from "@/entities/Movie/";

interface MovieDetailsContainerProps {
className?: string;
Expand Down
Loading

0 comments on commit 6e5d2e0

Please sign in to comment.