# Kinovtopku

Kinovtopku app

Demo

Приложение показывает самые плохие фильмы разных стран. Написано с помощью фреймворка Vue 3. Данные берутся по API открытой базы данных [TheMovieDB](https://www.themoviedb.org/).

# Стэк технологий

  • Vue 3
  • Vue router
  • Vue datepicker
  • Fetch
  • Sass
  • Eslint
  • Bootstrap

# Структура проекта

/public
/src
	/assets
	/components
		MovieTypeSelector.vue
		YearPick.vue
	/router
		index.js
	/views
		Home.vue
		SingleMovie.vue
	App.vue
	env.js
	main.js

# Sass

Практически во всем приложении удается ограничиться использованием готовых элементов Bootstrap. А там где есть кастомные стили они написаны на Sass.

# Адаптивность

Kinovtopku для смартфона

Адаптивность приложения достигается использованием стилей CSS-фреймворка Bootstrap.

# Страницы

Kinovtopku страница одного фильма

В приложении 2 страницы.

  • Главная - каталог фильмов. У каждого фильма своя карточка с обложкой, названием и кратким описанием
  • Страница одного фильма - на которой указано название, полное описание, дата выхода, режиссер, актеры и кадры из фильма

# Фильтры

Kinovtopku фильтры

Список фильмов на главной странице можно отфильтровать по году выхода и типу: полнометражный фильм или сериал.

Для каждого фильтра создан отдельный компонент. YearPick и MovieTypeSelector.

При выборе радио-кнопки типа фильма или при вводе года, компонент эмитит событие change-type или change-year соответственно. Эти события слушает родительский компонент.

<template>
...

    <input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio1" value="movie"
           v-model="film_type" @change="changeFilmType">

...
</template>

<script>
...

export default {
  ...

  methods: {
    changeFilmType() {
      this.$emit('change-type', this.film_type);
    }
  },
  emits: ['change-type']
}

...
</script>

/src/components/MovieTypeSelector.vue

# Слайдер

Kinovtopku слайдер

На странице фильма внизу расположен слайдер с кадрами из фильма. Если картинок нет, слайдер не выводится. Для реализации слайдера использован функционал Bootstrap.

...

<div id="custCarousel" class="carousel slide" data-ride="carousel" align="center" v-if="show_images">
	  <!-- slides -->
	  <div class="carousel-inner">
	    <div class="carousel-item" v-for="(image, index) in images" :key="index" :class="[index === 0 ? 'active': '']">
	      <img :src="'http://image.tmdb.org/t/p/w500' + image.file_path" alt="Hills"
	      :width="image.width" :height="image.height">
	    </div>
	  </div>
	  <!-- Left right -->
	  <a class="carousel-control-prev" href="#custCarousel" data-slide="prev"> <span class="carousel-control-prev-icon"></span> </a> <a class="carousel-control-next" href="#custCarousel" data-slide="next"> <span class="carousel-control-next-icon"></span> </a> <!-- Thumbnails -->
	  <ol class="carousel-indicators list-inline">
	        <li class="list-inline-item" v-for="(image, index) in images" :key="index"
	            :class="[index === 1 ? 'active': '']">
	          <a id="carousel-selector-0" class="selected" data-slide-to="0" data-target="#custCarousel">
	            <img :src="'http://image.tmdb.org/t/p/w200' + image.file_path" class="img-fluid">
	          </a>
	        </li>
	  </ol>
	</div>
	<p v-else>
	  No images for this movie.
	</p>

...

</div>

/src/views/SingleMovie.vue

# API

Все данные берутся из API открытой базы данных фильмов TheMovieDB.

...

  methods: {
    async fetchMoviesList() {
      const res = await fetch(`https://api.themoviedb.org/3/discover/${this.type}?api_key=${env.apikey}&language=en-US&sort_by=popularity.asc&${this.type === 'movie' ? 'primary_release_year' : 'first_air_date_year'}=${this.year}&page=1`)
      this.movies = await res.json();
      this.movies = this.movies.results;
    },
    
    ...
  },
  mounted() {
    this.fetchMoviesList();
  }

...

/src/views/Home.vue

# Router

Для перемещения между страницами приложения используется Vue-router.

...

const routes = [
  {
    path: '/movie/:id',
    name: 'Single Movie',
    component: SingleMovie
  },
  {
    path: '/',
    name: 'Home',
    component: Home
  }
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

...

/src/router/index.js

# Исходный код на GitHub

Kinovtopku (opens new window)