├── .gitignore
├── .npmrc
├── LICENSE
├── README.md
├── babel.config.js
├── package-lock.json
├── package.json
├── pnpm-lock.yaml
├── public
├── favicon.ico
└── index.html
└── src
├── App.vue
├── assets
└── logo.png
├── components
├── MovieDetails.vue
├── SearchResults.vue
├── TvDetails.vue
├── UI
│ ├── Footer.vue
│ ├── Navbar.vue
│ ├── Placeholder.vue
│ └── Spinner.vue
├── homepage
│ ├── Hero.vue
│ ├── Home.vue
│ ├── PopularMovies.vue
│ ├── PopularSeries.vue
│ ├── TopRatedMovies.vue
│ └── TopRatedSeries.vue
└── layouts
│ ├── DetailsContainer.vue
│ └── MyCarousel.vue
├── main.js
├── route
└── index.js
└── store
├── index.js
└── modules
├── hero.js
├── popularMovies.js
├── popularSeries.js
├── topRatedMovies.js
└── topRatedSeries.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | shamefully-hoist=true
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Rangga Dimas
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # kinohub-movie-app
2 | [Live Web](https://kinohub.netlify.app).
3 |
4 | ## Project setup
5 | ```
6 | pnpm install
7 | ```
8 |
9 | ### Compiles and hot-reloads for development
10 | ```
11 | pnpm run serve
12 | ```
13 |
14 | ### Compiles and minifies for production
15 | ```
16 | pnpm run build
17 | ```
18 |
19 | ### Lints and fixes files
20 | ```
21 | pnpm run lint
22 | ```
23 | ### Dont forget to register your own tmdb apikey and put it in store/index.js
24 |
25 | ### Customize configuration
26 | See [Configuration Reference](https://cli.vuejs.org/config/).
27 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "kinohub-movie-app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "core-js": "^3.6.5",
12 | "vue": "^2.6.11",
13 | "vue-carousel": "^0.18.0",
14 | "vue-router": "^3.4.9",
15 | "vuex": "^3.5.1"
16 | },
17 | "devDependencies": {
18 | "@vue/cli-plugin-babel": "~4.5.0",
19 | "@vue/cli-plugin-eslint": "~4.5.0",
20 | "@vue/cli-service": "~4.5.0",
21 | "babel-eslint": "^10.1.0",
22 | "eslint": "^6.7.2",
23 | "eslint-plugin-vue": "^6.2.2",
24 | "vue-template-compiler": "^2.6.11"
25 | },
26 | "eslintConfig": {
27 | "root": true,
28 | "env": {
29 | "node": true
30 | },
31 | "extends": [
32 | "plugin:vue/essential",
33 | "eslint:recommended"
34 | ],
35 | "parserOptions": {
36 | "parser": "babel-eslint"
37 | },
38 | "rules": {}
39 | },
40 | "browserslist": [
41 | "> 1%",
42 | "last 2 versions",
43 | "not dead"
44 | ]
45 | }
46 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buckypinkman/kinohub-movie-app/6bb1487750be0195910fb24169b62233e4c6a902/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/buckypinkman/kinohub-movie-app/6bb1487750be0195910fb24169b62233e4c6a902/src/assets/logo.png
--------------------------------------------------------------------------------
/src/components/MovieDetails.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |

12 |
![]()
18 |
19 |
20 |
![]()
25 |
26 |
{{ results.status }}
27 |
28 | {{ results.title }}
29 | ({{ getYear }})
30 |
31 |
Rating : {{ results.vote_average }}
32 |
33 |
34 | {{ res.name }}
35 |
36 | | {{ lang }}
37 |
38 |
Watch Now
43 |
44 |
Watch Trailer
54 |
55 |
56 |
57 |
58 |
59 |
68 |
69 |
CASTS
70 |
71 | No data available.
72 |
73 |
74 |
75 |
![]()
80 |
81 |
{{ result.name }}
82 |
{{ result.character }}
83 |
84 |
85 |
86 |
87 |
88 |
89 |
Similiar Movies
90 |
91 | No data available.
92 |
93 |
94 |
97 |
98 |
103 |
104 |
105 |
{{ result.title }}
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 | Back to home
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
196 |
--------------------------------------------------------------------------------
/src/components/SearchResults.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Movie not found.
7 |
Search results for : "{{ this.searchQuery }}"
8 |
9 |
15 |
18 |
19 |
24 |
25 |
{{ result.title }}
26 |
27 |
28 |
29 |
35 |
36 |
37 |
42 |
43 |
{{ result.name }}
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
98 |
99 |
--------------------------------------------------------------------------------
/src/components/TvDetails.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |

11 |
![]()
17 |
18 |
19 |
![]()
24 |
25 |
{{ results.status }}
26 |
27 | Created by :
28 | {{ getCreator }}
29 |
30 |
31 | {{ results.name }}
32 | ({{ getYear }} - {{ getLastYear }})
33 |
34 |
35 | Rating : {{ results.vote_average }} |
36 |
37 | {{ res.name }}
38 |
39 | | {{ lang }}
40 |
41 |
42 | Episodes :
43 | {{ results.number_of_episodes }} | Seasons :
44 | {{ results.number_of_seasons }}
45 |
46 |
Watch Now
51 |
52 |
Watch Trailer
62 |
63 |
64 |
65 |
66 |
67 |
76 |
77 |
CASTS
78 |
79 | No data available.
80 |
81 |
82 |
83 |
![]()
88 |
89 |
{{ result.name }}
90 |
{{ result.character }}
91 |
92 |
93 |
94 |
95 |
96 |
97 |
Similiar TV Shows
98 |
99 | No data available.
100 |
101 |
102 |
105 |
106 |
111 |
112 |
113 |
{{ result.name }}
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 | Back to home
122 |
123 |
124 |
125 |
126 |
127 |
128 |
216 |
--------------------------------------------------------------------------------
/src/components/UI/Footer.vue:
--------------------------------------------------------------------------------
1 |
2 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/src/components/UI/Navbar.vue:
--------------------------------------------------------------------------------
1 |
2 |
25 |
26 |
27 |
37 |
38 |
79 |
--------------------------------------------------------------------------------
/src/components/UI/Placeholder.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
--------------------------------------------------------------------------------
/src/components/UI/Spinner.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/components/homepage/Hero.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
![]()
15 |
16 |
19 |
20 |
21 |
LATEST
22 | {{ result.title }}
23 |
24 | Rating : {{ result.vote_average }} |
25 | {{ result.original_language.toUpperCase() }}
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
54 |
55 |
134 |
--------------------------------------------------------------------------------
/src/components/homepage/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
12 |
13 |
14 |
15 |
16 |
36 |
37 |
90 |
--------------------------------------------------------------------------------
/src/components/homepage/PopularMovies.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Popular Movies
4 |
5 |
6 |
7 |
10 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
54 |
--------------------------------------------------------------------------------
/src/components/homepage/PopularSeries.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Popular Series
4 |
5 |
6 |
7 |
8 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
38 |
--------------------------------------------------------------------------------
/src/components/homepage/TopRatedMovies.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Top Rated Movies
4 |
5 |
6 |
7 |
10 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
40 |
41 |
--------------------------------------------------------------------------------
/src/components/homepage/TopRatedSeries.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Top Rated Series
4 |
5 |
6 |
7 |
8 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/components/layouts/DetailsContainer.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/components/layouts/MyCarousel.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import Navbar from './components/UI/Navbar.vue'
4 | import Placeholder from './components/UI/Placeholder.vue'
5 | import Spinner from './components/UI/Spinner.vue'
6 | import VueCarousel from 'vue-carousel'
7 | import MyCarousel from './components/layouts/MyCarousel.vue'
8 | Vue.config.productionTip = false
9 | import router from './route/index'
10 | import store from './store/index'
11 |
12 | Vue.component('navbar', Navbar)
13 | Vue.component('placeholder', Placeholder)
14 | Vue.component('spinner', Spinner)
15 | Vue.component('my-carousel', MyCarousel)
16 |
17 | Vue.use(VueCarousel)
18 |
19 | new Vue({
20 | store,
21 | router,
22 | render: h => h(App),
23 | }).$mount('#app')
--------------------------------------------------------------------------------
/src/route/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 | import MovieDetails from '../components/MovieDetails.vue'
4 | import Home from '../components/homepage/Home.vue'
5 | import TvDetails from '../components/TvDetails.vue'
6 | import SearchResults from '../components/SearchResults.vue'
7 |
8 | Vue.use(VueRouter)
9 |
10 | export default new VueRouter({
11 | routes: [{
12 | path: '/',
13 | name: 'Home',
14 | component: Home
15 | },
16 | {
17 | path: "/movie/details/:movieId",
18 | name: 'MovieDetails',
19 | component: MovieDetails,
20 | props: true
21 | },
22 | {
23 | path: "/tv/details/:tvId",
24 | name: 'TvDetails',
25 | component: TvDetails,
26 | props: true
27 | },
28 | {
29 | path: "/search/:searchQuery",
30 | name: 'Search',
31 | component: SearchResults,
32 | props: true
33 | }
34 | ],
35 | scrollBehavior(to, from, savedPosition) {
36 | if (savedPosition) {
37 | return savedPosition
38 | } else {
39 | return {
40 | x: 0,
41 | y: 0
42 | }
43 | }
44 | }
45 | })
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | //homepage modules
5 | import popularMovies from './modules/popularMovies'
6 | import popularSeries from './modules/popularSeries'
7 | import topRatedMovies from './modules/topRatedMovies'
8 | import topRatedSeries from './modules/topRatedSeries'
9 | import hero from './modules/hero'
10 |
11 |
12 | Vue.use(Vuex)
13 |
14 | const store = new Vuex.Store({
15 | modules: {
16 | popularMovies,
17 | popularSeries,
18 | topRatedMovies,
19 | topRatedSeries,
20 | hero,
21 | },
22 | state() {
23 | return {
24 | api_key: '', //your apikey here
25 | isLoading: false
26 | }
27 | },
28 | getters: {
29 | chevRight() {
30 | return ""
31 | },
32 | chevLeft() {
33 | return ""
34 | }
35 | }
36 | })
37 |
38 | export default store
--------------------------------------------------------------------------------
/src/store/modules/hero.js:
--------------------------------------------------------------------------------
1 | export default {
2 | state() {
3 | return {
4 | heroResults: ""
5 | }
6 | },
7 | getters: {
8 | heroResults(state) {
9 | return state.heroResults
10 | }
11 | },
12 | actions: {
13 | async heroResults({
14 | state, rootState
15 | }) {
16 | await fetch(
17 | `https://api.themoviedb.org/3/movie/now_playing?api_key=${rootState.api_key}&language=en-US&page=1`
18 | )
19 | .then((response) => response.json())
20 | .then((response) => {
21 | console.log(response);
22 | state.heroResults = response.results;
23 | });
24 | },
25 | }
26 | }
--------------------------------------------------------------------------------
/src/store/modules/popularMovies.js:
--------------------------------------------------------------------------------
1 | export default {
2 | state() {
3 | return {
4 | movieResults: ""
5 | }
6 | },
7 | getters: {
8 | movieResults(state) {
9 | return state.movieResults
10 | }
11 | },
12 | actions: {
13 | async movieResults({
14 | state, rootState
15 | }) {
16 | await fetch(
17 | `https://api.themoviedb.org/3/movie/popular?api_key=${rootState.api_key}&language=en-US&page=1`
18 | )
19 | .then((response) => response.json())
20 | .then((response) => {
21 | console.log(response);
22 | state.movieResults = response.results;
23 | });
24 | },
25 | }
26 | }
--------------------------------------------------------------------------------
/src/store/modules/popularSeries.js:
--------------------------------------------------------------------------------
1 | export default {
2 | state() {
3 | return {
4 | seriesResults: ""
5 | }
6 | },
7 | getters: {
8 | seriesResults(state) {
9 | return state.seriesResults
10 | }
11 | },
12 | actions: {
13 | async seriesResults({
14 | state, rootState
15 | }) {
16 | await fetch(
17 | `https://api.themoviedb.org/3/tv/popular?api_key=${rootState.api_key}&language=en-US&page=1`
18 | )
19 | .then((response) => response.json())
20 | .then((response) => {
21 | console.log(response);
22 | state.seriesResults = response.results;
23 | });
24 | },
25 | }
26 | }
--------------------------------------------------------------------------------
/src/store/modules/topRatedMovies.js:
--------------------------------------------------------------------------------
1 | export default {
2 | state() {
3 | return {
4 | topMovies: ""
5 | }
6 | },
7 | getters: {
8 | topMoviesResults(state) {
9 | return state.topMovies
10 | }
11 | },
12 | actions: {
13 | async topMoviesResults({
14 | state, rootState
15 | }) {
16 | await fetch(
17 | `https://api.themoviedb.org/3/movie/top_rated?api_key=${rootState.api_key}&language=en-US&page=1`
18 | )
19 | .then((response) => response.json())
20 | .then((response) => {
21 | console.log(response);
22 | state.topMovies = response.results;
23 | });
24 | },
25 | }
26 | }
--------------------------------------------------------------------------------
/src/store/modules/topRatedSeries.js:
--------------------------------------------------------------------------------
1 | export default {
2 | state() {
3 | return {
4 | topSeries: ""
5 | }
6 | },
7 | getters: {
8 | topSeriesResults(state) {
9 | return state.topSeries
10 | }
11 | },
12 | actions: {
13 | async topSeriesResults({
14 | state, rootState
15 | }) {
16 | rootState.isLoading = true
17 | await fetch(
18 | `https://api.themoviedb.org/3/tv/top_rated?api_key=${rootState.api_key}&language=en-US&page=1`
19 | )
20 | .then((response) => response.json())
21 | .then((response) => {
22 | console.log(response);
23 | state.topSeries = response.results;
24 | rootState.isLoading = false
25 | });
26 | },
27 | }
28 | }
--------------------------------------------------------------------------------