<template> <section class="flex flex-col items-center min-h-screen"> <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" :href="film.title" :to="'/details/' + film.id" class="hover:bg-slate-200 w-full flex flex-col bg-emerald-800 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"> <h2 class="text-xl font-bold"> {{ film.title }} </h2> <span v-if="film.release_date"> {{ useDateFormat(film.release_date, 'D MMM YYYY') }} </span> {{ formatPercentage(film.vote_average) }}% </span> </NuxtLink> </main> </div> </section> </template> <script setup lang="ts"> import { useDateFormat } from '@vueuse/core' const config = useRuntimeConfig() const terms = ref('') const films = ref([]) const page = ref(1) const loading = ref(false) const { onScrollEnd } = useScrollEnd() const search = async () => { loading.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) } loading.value = false } const pressEnter = () => { page.value = 1 films.value = [] search() } const fromPercentToDegree = (percent) => { let deg = Math.round((percent / 10) * 180) console.log(deg) return [`rotate-[calc(${deg}deg-45deg)]`] } const formatPercentage = (percent) => { return Math.round(percent * 10) } const setPlaceholder = (event) => { event.target.src = 'https://via.placeholder.com/200x300' } onScrollEnd(() => { page.value += 1 search() }) onMounted(() => { nextTick(() => { search() }) }) </script> <style> .title b { @apply text-green-400 capitalize; } .icon { @apply w-4 h-4 mx-2; } .icon-container { color: #8094ae; @apply flex items-center } .icon-container .icon { color: rgb(109, 109, 109); } .icon-size p { color: rgb(54, 150, 75); } .icon-seed p { color: rgb(12, 108, 233); } .loader>div { animation: loader 2.4s cubic-bezier(0, 0.2, 0.8, 1) infinite; } @keyframes loader { 0%, 100% { animation-timing-function: cubic-bezier(0.5, 0, 1, 0.5); } 0% { transform: rotateY(0deg); } 50% { transform: rotateY(1800deg); animation-timing-function: cubic-bezier(0, 0.5, 0.5, 1); } 100% { transform: rotateY(3600deg); } } </style>