<template> <section class="flex flex-col items-center min-h-screen"> <uiLoader v-if="isLoading" class="fixed z-50 backdrop-blur-sm p-4 rounded-full top-1/2" /> <div class="container w-full p-6 max-w-6xl grow flex flex-col items-center"> <nav class="w-full flex bg-slate-800 font-semibold rounded-full backdrop-blur sticky top-0 justify-center items-center hover:ring"> <input ref="searchInput" v-model="terms" autofocus placeholder="search" type="search" class="rounded-full text-xl w-full text-center text-white p-4 bg-transparent focus-visible:border-none" @keypress.enter="pressEnter()"> <b v-if="films && films.length" class="px-4 py-2 absolute right-2 block bg-green-400 text-slate-800 rounded-full"> {{ films.length }} </b> </nav> <main class="flex max-w-screen-2xl justify-center flex-wrap m-6"> <NuxtLink v-for="(film, index) in films" :key="index" :title="film.title" :to="'/details/' + film.id" class="hover:bg-green-500 transition flex flex-col bg-slate-400 rounded-lg w-60 m-4"> <img @error="setPlaceholder" :src="config.public.IMG_BASE_URL + film.poster_path" :alt="film.title" class="w-full rounded-t-lg"> <span class="p-4 text-white flex flex-col"> <h2 class="text-xl font-bold pb-2"> {{ film.title }} </h2> <span v-if="film.release_date"> {{ useDateFormat(film.release_date, 'D MMM YYYY') }} </span> <span class="font-bold"> {{ formatPercent(film.vote_average) }}% </span> </span> </NuxtLink> </main> </div> </section> </template> <script setup lang="ts"> import { useDateFormat } from '@vueuse/core' interface Film { title: string, id: number, poster_path: string, release_date: number, vote_average: number, } const config = useRuntimeConfig() const terms = ref('') const films: Ref<Film[]> = ref([]) const page = ref(1) const isLoading = ref(true) const { onScrollEnd } = useScrollEnd() const search = async () => { isLoading.value = true if (terms.value !== '') { const { data } = await useFetch(`/api/search/${terms.value}-${page.value}`) console.log(data) films.value.push(...data.value) } else { const { data } = await useFetch(`/api/explore/${page.value}`) films.value.push(...data.value) } isLoading.value = false } const pressEnter = () => { page.value = 1 films.value = [] search() } const setPlaceholder = (event: Event) => { const target = event.target as HTMLImageElement target.src = 'https://via.placeholder.com/200x300' } onScrollEnd(() => { page.value += 1 search() }) onMounted(() => { nextTick(() => { search() }) }) </script>