-
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add popular items page for movies and shows (#153)
* feat: add popular items page for movies and shows * chore: remove unused html
- Loading branch information
1 parent
261b69b
commit a6cc1a7
Showing
6 changed files
with
299 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
<script lang="ts"> | ||
import { roundOff } from '$lib/helpers'; | ||
import { Star } from 'lucide-svelte'; | ||
import type { PageData } from './$types'; | ||
import ItemRequest from '$lib/components/item-request.svelte'; | ||
import Header from '$lib/components/header.svelte'; | ||
import * as Pagination from '$lib/components/ui/pagination'; | ||
import { getMoviesPopular } from '$lib/tmdb'; | ||
import { writable } from 'svelte/store'; | ||
import { goto } from '$app/navigation'; | ||
export let data: PageData; | ||
let items = data.movies.results; | ||
let totalItems = data.movies.total_results; | ||
let pageNumber = data.page; | ||
$: totalDataItems = writable(totalItems); | ||
async function fetchItems() { | ||
let data = await getMoviesPopular(fetch, 'en-US', pageNumber); | ||
if (data) { | ||
items = data.results; | ||
totalItems = data.total_results; | ||
$totalDataItems = totalItems; | ||
} else { | ||
//pass | ||
} | ||
} | ||
const limit = 20; | ||
const hoveredItem = writable(null); | ||
</script> | ||
|
||
<svelte:head> | ||
<title>Movies | Riven</title> | ||
</svelte:head> | ||
|
||
<div class="!text-zinc-100"> | ||
<Header /> | ||
</div> | ||
|
||
<div class="mt-32 p-8 md:px-24 lg:px-32"> | ||
<h1 class="mb-8 text-center text-4xl text-zinc-50 md:text-left">Popular Movies</h1> | ||
|
||
<div class="grid grid-cols-2 gap-6 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6"> | ||
{#each items as item (item.id)} | ||
<div | ||
class="group relative mb-2 flex flex-shrink-0 flex-col gap-2 rounded-lg p-2" | ||
role="button" | ||
tabindex="0" | ||
on:mouseenter={() => ($hoveredItem = item.id)} | ||
on:mouseleave={() => ($hoveredItem = null)} | ||
on:focus={() => ($hoveredItem = item.id)} | ||
on:blur={() => ($hoveredItem = null)} | ||
on:keydown={(e) => { | ||
if (e.key === 'Enter' || e.key === ' ') { | ||
e.preventDefault(); | ||
$hoveredItem = item.id; | ||
} | ||
}} | ||
on:click={() => goto(`/movie/${item.id}`)} | ||
> | ||
<div class="relative aspect-[1/1.5] w-full overflow-hidden rounded-lg"> | ||
<img | ||
src="https://image.tmdb.org/t/p/w342{item.poster_path}" | ||
alt={item.title || item.name} | ||
loading="lazy" | ||
class="h-full w-full object-cover object-center transition-all duration-300 ease-in-out group-hover:scale-105" | ||
/> | ||
<div | ||
class="absolute right-0 top-1 flex items-center justify-center gap-1 rounded-l-md bg-slate-900/70 px-[5px] py-1" | ||
> | ||
<Star class="size-3 text-yellow-400" /> | ||
<span class="text-xs font-light text-white"> | ||
{roundOff(item.vote_average)} | ||
</span> | ||
</div> | ||
<div | ||
class="absolute inset-0 hidden flex-col justify-end from-zinc-900/70 p-2 group-hover:flex group-hover:bg-gradient-to-t" | ||
> | ||
{#if $hoveredItem === item.id} | ||
<ItemRequest data={item} type="movie" /> | ||
{/if} | ||
</div> | ||
</div> | ||
</div> | ||
{/each} | ||
</div> | ||
|
||
<div class="mt-8 flex flex-wrap overflow-x-auto px-1 lg:p-0"> | ||
<Pagination.Root | ||
count={$totalDataItems} | ||
perPage={limit} | ||
let:pages | ||
let:currentPage | ||
onPageChange={(page) => { | ||
pageNumber = page; | ||
fetchItems(); | ||
}} | ||
> | ||
<Pagination.Content class="flex items-center justify-center space-x-2"> | ||
<Pagination.Item> | ||
<Pagination.PrevButton class="rounded-md bg-primary px-4 py-2 text-primary-foreground" /> | ||
</Pagination.Item> | ||
{#each pages as page (page.key)} | ||
{#if page.type === 'ellipsis'} | ||
<Pagination.Item> | ||
<Pagination.Ellipsis class="px-4 py-2" /> | ||
</Pagination.Item> | ||
{:else} | ||
<Pagination.Item> | ||
<Pagination.Link | ||
{page} | ||
isActive={currentPage === page.value} | ||
class="rounded-md px-4 py-2" | ||
> | ||
{page.value} | ||
</Pagination.Link> | ||
</Pagination.Item> | ||
{/if} | ||
{/each} | ||
<Pagination.Item> | ||
<Pagination.NextButton class="rounded-md bg-primary px-4 py-2 text-primary-foreground" /> | ||
</Pagination.Item> | ||
</Pagination.Content> | ||
</Pagination.Root> | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import type { PageLoad } from './$types'; | ||
import { getMoviesPopular } from '$lib/tmdb'; | ||
|
||
export const load = (async ({ fetch }) => { | ||
const page = 1; | ||
|
||
async function getMovies() { | ||
return await getMoviesPopular(fetch, 'en-US', page); | ||
} | ||
|
||
return { | ||
movies: await getMovies(), | ||
page | ||
}; | ||
}) satisfies PageLoad; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
<script lang="ts"> | ||
import { roundOff } from '$lib/helpers'; | ||
import { Star } from 'lucide-svelte'; | ||
import type { PageData } from './$types'; | ||
import ItemRequest from '$lib/components/item-request.svelte'; | ||
import Header from '$lib/components/header.svelte'; | ||
import * as Pagination from '$lib/components/ui/pagination'; | ||
import { getTVPopular } from '$lib/tmdb'; | ||
import { writable } from 'svelte/store'; | ||
import { goto } from '$app/navigation'; | ||
export let data: PageData; | ||
let items = data.shows.results; | ||
let totalItems = data.shows.total_results; | ||
let pageNumber = data.page; | ||
$: totalDataItems = writable(totalItems); | ||
async function fetchItems() { | ||
let data = await getTVPopular(fetch, 'en-US', pageNumber); | ||
if (data) { | ||
items = data.results; | ||
totalItems = data.total_results; | ||
$totalDataItems = totalItems; | ||
} else { | ||
//pass | ||
} | ||
} | ||
const limit = 20; | ||
const hoveredItem = writable(null); | ||
</script> | ||
|
||
<svelte:head> | ||
<title>Movies | Riven</title> | ||
</svelte:head> | ||
|
||
<div class="!text-zinc-100"> | ||
<Header /> | ||
</div> | ||
|
||
<div class="mt-32 p-8 md:px-24 lg:px-32"> | ||
<h1 class="mb-8 text-center text-4xl text-zinc-50 md:text-left">Popular Shows</h1> | ||
|
||
<div class="grid grid-cols-2 gap-6 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6"> | ||
{#each items as item (item.id)} | ||
<div | ||
class="group relative mb-2 flex flex-shrink-0 flex-col gap-2 rounded-lg p-2" | ||
role="button" | ||
tabindex="0" | ||
on:mouseenter={() => ($hoveredItem = item.id)} | ||
on:mouseleave={() => ($hoveredItem = null)} | ||
on:focus={() => ($hoveredItem = item.id)} | ||
on:blur={() => ($hoveredItem = null)} | ||
on:keydown={(e) => { | ||
if (e.key === 'Enter' || e.key === ' ') { | ||
e.preventDefault(); | ||
$hoveredItem = item.id; | ||
} | ||
}} | ||
on:click={() => goto(`/tv/${item.id}`)} | ||
> | ||
<div class="relative aspect-[1/1.5] w-full overflow-hidden rounded-lg"> | ||
<img | ||
src="https://image.tmdb.org/t/p/w342{item.poster_path}" | ||
alt={item.title || item.name} | ||
loading="lazy" | ||
class="h-full w-full object-cover object-center transition-all duration-300 ease-in-out group-hover:scale-105" | ||
/> | ||
<div | ||
class="absolute right-0 top-1 flex items-center justify-center gap-1 rounded-l-md bg-slate-900/70 px-[5px] py-1" | ||
> | ||
<Star class="size-3 text-yellow-400" /> | ||
<span class="text-xs font-light text-white"> | ||
{roundOff(item.vote_average)} | ||
</span> | ||
</div> | ||
<div | ||
class="absolute inset-0 hidden flex-col justify-end from-zinc-900/70 p-2 group-hover:flex group-hover:bg-gradient-to-t" | ||
> | ||
{#if $hoveredItem === item.id} | ||
<ItemRequest data={item} type="tv" /> | ||
{/if} | ||
</div> | ||
</div> | ||
</div> | ||
{/each} | ||
</div> | ||
|
||
<div class="mt-8 flex flex-wrap overflow-x-auto px-1 lg:p-0"> | ||
<Pagination.Root | ||
count={$totalDataItems} | ||
perPage={limit} | ||
let:pages | ||
let:currentPage | ||
onPageChange={(page) => { | ||
pageNumber = page; | ||
fetchItems(); | ||
}} | ||
> | ||
<Pagination.Content class="flex items-center justify-center space-x-2"> | ||
<Pagination.Item> | ||
<Pagination.PrevButton class="rounded-md bg-primary px-4 py-2 text-primary-foreground" /> | ||
</Pagination.Item> | ||
{#each pages as page (page.key)} | ||
{#if page.type === 'ellipsis'} | ||
<Pagination.Item> | ||
<Pagination.Ellipsis class="px-4 py-2" /> | ||
</Pagination.Item> | ||
{:else} | ||
<Pagination.Item> | ||
<Pagination.Link | ||
{page} | ||
isActive={currentPage === page.value} | ||
class="rounded-md px-4 py-2" | ||
> | ||
{page.value} | ||
</Pagination.Link> | ||
</Pagination.Item> | ||
{/if} | ||
{/each} | ||
<Pagination.Item> | ||
<Pagination.NextButton class="rounded-md bg-primary px-4 py-2 text-primary-foreground" /> | ||
</Pagination.Item> | ||
</Pagination.Content> | ||
</Pagination.Root> | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import type { PageLoad } from './$types'; | ||
import { getTVPopular } from '$lib/tmdb'; | ||
|
||
export const load = (async ({ fetch }) => { | ||
const page = 1; | ||
|
||
async function getShows() { | ||
return await getTVPopular(fetch, 'en-US', page); | ||
} | ||
|
||
return { | ||
shows: await getShows(), | ||
page | ||
}; | ||
}) satisfies PageLoad; |