Skip to content

Commit

Permalink
Merge pull request #6 from LukaBRa/task-8
Browse files Browse the repository at this point in the history
Implemented router and pagination
  • Loading branch information
LukaBRa authored Feb 20, 2024
2 parents 92a2b39 + cc197fb commit 190786b
Show file tree
Hide file tree
Showing 19 changed files with 412 additions and 55 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: test-on-push
on:
push:
branches:
- main

pull_request:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: npm install
run: |
npm install --force
- name: npm run build
run: |
npm run build
- name: npm run test:unit
run: |
npm run test:unit
25 changes: 24 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"dependencies": {
"axios": "^1.6.7",
"pinia": "^2.1.7",
"vue": "^3.3.11"
"vue": "^3.3.11",
"vue-router": "^4.2.5"
},
"devDependencies": {
"@babel/preset-env": "^7.23.9",
Expand Down
21 changes: 1 addition & 20 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,29 +1,10 @@
<script setup lang="ts">
import HomePage from "./views/HomePage.vue";
import MoviePage from "./views/MoviePage.vue";
import { ref, computed } from "vue";
const movieIdSelected = ref(-1);
const selectMovie = (id:number) => {
movieIdSelected.value = id;
}
const showMoviePage = computed(() => {
return movieIdSelected.value > -1;
})
const closeMoviePage = () => {
movieIdSelected.value = -1;
}
</script>

<template>

<HomePage v-if="!showMoviePage" @selectMovie="selectMovie"/>

<MoviePage v-else="showMoviePage" :movieId="movieIdSelected" @closeMoviePage="closeMoviePage"/>
<router-view></router-view>

</template>

Expand Down
4 changes: 4 additions & 0 deletions src/assets/main.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300&display=swap');

html {
scroll-behavior: smooth;
}

* {
box-sizing: border-box;
margin: 0;
Expand Down
3 changes: 3 additions & 0 deletions src/components/ActionBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import { ref } from "vue";
import type { Ref } from "vue";
import useMoviesStore from "@/store/moviesStore";
import useFilterButtonsStore from "@/store/filterButtonsStore";
import { useRouter } from "vue-router";
const inputSearchText: Ref<string> = ref("");
const movieStore = useMoviesStore();
const filterStore = useFilterButtonsStore();
const router = useRouter();
const handleSearch = () => {
movieStore.searchMovies(inputSearchText.value, filterStore.selectedSearchFilter);
router.push("/?page=1");
}
</script>
Expand Down
7 changes: 6 additions & 1 deletion src/components/MovieCard.vue
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
<script setup lang="ts">
import { computed } from "vue";
import { formatGenres } from "@/utils/formatGenres";
import { useRouter } from "vue-router";
const props = defineProps(["movie"]);
const router = useRouter();
const releaseDate = computed(() => {
return new Date(props.movie.releaseDate).getFullYear();
})
const selectMovie = (id: number) => {
router.push("/movie/" + id);
}
</script>

<template>

<div class="movie-card">

<img id="card-image" data-cy="card-img" @click="$emit('selectMovie', movie.id)" v-lazyload="movie.posterurl" :alt="movie.title">
<img id="card-image" data-cy="card-img" @click="selectMovie(movie.id)" v-lazyload="movie.posterurl" :alt="movie.title">

<div class="movie-info">

Expand Down
31 changes: 25 additions & 6 deletions src/components/MovieList.vue
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
<script setup lang="ts">
import MovieCard from './MovieCard.vue';
import Pagination from './Pagination.vue';
import useMoviesStore from '@/store/moviesStore';
import useFilterButtonsStore from '@/store/filterButtonsStore';
import { watch } from "vue";
import { watch, ref, onMounted } from "vue";
import { useRoute } from 'vue-router';
const moviesStore = useMoviesStore();
const filterStore = useFilterButtonsStore();
const emit = defineEmits(['selectMovie']);
const displayMovies = ref();
const route = useRoute();
const populateDisplayMovies = () => {
const pageNumber:number = parseInt(route.query.page as string) || 1;
displayMovies.value = moviesStore.movies.slice((pageNumber - 1) * 20, ((pageNumber - 1) * 20) + 20);
}
onMounted(() => {
populateDisplayMovies();
}),
watch(() => filterStore.selectedSortFilter, (newSortFilter, oldSortFilter) => {
moviesStore.sortMovies(newSortFilter);
populateDisplayMovies();
})
const selectMovie = (id: number) => {
emit('selectMovie', id);
}
watch(() => route.query.page, (newSortFilter, oldSortFilter) => {
populateDisplayMovies();
})
watch(() => moviesStore.movies, (newSortFilter, oldSortFilter) => {
populateDisplayMovies();
})
</script>

Expand All @@ -24,11 +41,13 @@ const selectMovie = (id: number) => {

<div class="container">
<div id="movies" v-if="moviesStore.moviesCount > 0" class="movie-list">
<MovieCard data-cy="movie-card" v-for="movie in moviesStore.movies" :key="movie.id" :movie="movie" @selectMovie="selectMovie"/>
<MovieCard data-cy="movie-card" v-for="movie in displayMovies" :key="movie.id" :movie="movie" />
</div>
<h1 id="no-movies" v-else>No films found</h1>
</div>

<Pagination />

</section>

</template>
Expand Down
53 changes: 53 additions & 0 deletions src/components/PageNumber.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<script setup lang="ts">
import { useRouter, useRoute, type LocationQueryValue } from 'vue-router';
import { computed } from 'vue';
const router = useRouter();
const route = useRoute();
const props = defineProps<{
pageNumber: {
n: number
}
}>();
const togglePage = (page: number) => {
if(route && route.name == "homepage"){
router.push(`/?page=${page}`);
}
if(route && route.name == "moviepage"){
router.push({ path: route.fullPath, query: { page } });
}
}
const activePage = computed(() => {
if(route && !route.query.page && props.pageNumber.n == 1){
return true
}
return parseInt(route && route.query.page as string) == props.pageNumber.n;
});
</script>

<template>

<button id="page-number-button" @click="togglePage(pageNumber.n)" :class="{ active: activePage }">{{ pageNumber.n }}</button>

</template>

<style scoped>
button {
font-size: 1.1rem;
padding: 5px 10px;
background: transparent;
color: #FFFFFF;
border: none;
text-decoration: underline;
cursor: pointer;
}
button.active {
background-color: #F65261;
}
</style>
29 changes: 29 additions & 0 deletions src/components/Pagination.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<script setup lang="ts">
import PageNumber from './PageNumber.vue';
import useMoviesStore from '@/store/moviesStore';
import { computed } from 'vue';
const moviesStore = useMoviesStore();
const pagesNumber = computed(() => {
return Math.ceil(moviesStore.moviesCount / 20);
});
</script>

<template>

<div class="pagination">
<PageNumber v-for="n in pagesNumber" :pageNumber={n} />
</div>

</template>

<style scoped>
.pagination {
margin-top: 30px;
margin-inline: auto;
width: max-content;
}
</style>
22 changes: 21 additions & 1 deletion src/components/tests/unit/ActionBar.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@ import { createPinia, defineStore, setActivePinia } from "pinia";
import { createTestingPinia } from "@pinia/testing";
import useMoviesStore from "@/store/moviesStore";
import useFilterButtonsStore from "@/store/filterButtonsStore";
import { useRoute, useRouter } from "vue-router";

vi.mock('vue-router', () => ({
useRoute: vi.fn(),
useRouter: vi.fn(() => ({
push: () => {}
}))
}))

useRoute.mockImplementationOnce(() => ({
params: {
id: 1
}
}))

const push = vi.fn()
useRouter.mockImplementationOnce(() => ({
push
}))

const wrapper = mount(ActionBar, {
global: {
Expand All @@ -13,7 +32,8 @@ const wrapper = mount(ActionBar, {
stubActions: false,
createSpy: vi.fn,
})
]
],
stubs: ["router-link", "router-view"]
}
});

Expand Down
Loading

0 comments on commit 190786b

Please sign in to comment.