More blurriness, and stylish

This commit is contained in:
2025-06-27 01:26:05 +05:00
parent ef68e4a84d
commit b7e8a033c3
8 changed files with 153 additions and 123 deletions

11
app.vue Normal file
View File

@ -0,0 +1,11 @@
<template>
<div class="relative flex flex-col min-h-svh">
<header class="w-full sticky top-0 z-50">
<Navbar />
</header>
<main class="flex flex-1 flex-col">
<NuxtPage />
</main>
<Toaster />
</div>
</template>

3
assets/css/main.css Normal file
View File

@ -0,0 +1,3 @@
.dark img {
filter: brightness(1.1) contrast(0.9);
}

View File

@ -0,0 +1,14 @@
<script setup lang="ts">
import { AspectRatio, type AspectRatioProps } from 'reka-ui'
const props = defineProps<AspectRatioProps>()
</script>
<template>
<AspectRatio
data-slot="aspect-ratio"
v-bind="props"
>
<slot />
</AspectRatio>
</template>

View File

@ -0,0 +1 @@
export { default as AspectRatio } from './AspectRatio.vue'

View File

@ -1,32 +1,34 @@
<script setup lang="ts"> <script setup lang="ts">
import { Icon } from '@iconify/vue' import { Icon } from '@iconify/vue'
const colorMode = useColorMode() const colorMode = useColorMode()
function toggleColorMode(): void { function toggleColorMode(): void {
const currentColorMode = colorMode.value const currentColorMode = colorMode.value
if (currentColorMode === 'light') { if (currentColorMode === 'light') {
colorMode.preference = 'dark' colorMode.preference = 'dark'
} }
if (currentColorMode === 'dark') { if (currentColorMode === 'dark') {
colorMode.preference = 'light' colorMode.preference = 'light'
} }
} }
</script> </script>
<template> <template>
<div class="absolute w-screen flex justify-around items-center p-2 border-b-2"> <div class="flex justify-around items-center p-2 border-b-2 backdrop-blur">
<div class="self-start"> <div class="self-start">
<h3 class="scroll-m-20 text-2xl font-semibold tracking-tight select-none"> <h3 class="scroll-m-20 text-2xl font-semibold tracking-tight select-none">
Anyame Anyame
</h3> </h3>
</div>
<div class="self-end">
<Button variant="outline" @click="toggleColorMode()">
<Icon icon="radix-icons:moon"
class="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Icon icon="radix-icons:sun"
class="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span class="sr-only">Toggle theme</span>
</Button>
</div>
</div> </div>
<div class="self-end"> </template>
<Button variant="outline" @click="toggleColorMode()">
<Icon icon="radix-icons:moon" class="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Icon icon="radix-icons:sun" class="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span class="sr-only">Toggle theme</span>
</Button>
</div>
</div>
</template>

View File

@ -8,7 +8,10 @@ export default defineNuxtConfig({
colorMode: { colorMode: {
classSuffix: '' classSuffix: ''
}, },
css: ['~/assets/css/tailwind.css'], css: [
'~/assets/css/tailwind.css',
'~/assets/css/main.css',
],
vite: { vite: {
plugins: [ plugins: [
tailwindcss(), tailwindcss(),

View File

@ -3,85 +3,78 @@
import kodikImage from "assets/img/kodik.png"; import kodikImage from "assets/img/kodik.png";
import shikimoriImage from "assets/img/shikimori.png"; import shikimoriImage from "assets/img/shikimori.png";
import { import {
Select, Select,
SelectContent, SelectContent,
SelectGroup, SelectGroup,
SelectItem, SelectItem,
SelectLabel, SelectLabel,
SelectTrigger, SelectTrigger,
SelectValue SelectValue
} from "~/components/ui/select"; } from "~/components/ui/select";
import { toast } from "vue-sonner"; import { toast } from "vue-sonner";
import { Toaster } from "~/components/ui/sonner";
import { Navbar } from "~/components/ui/navbar";
import 'vue-sonner/style.css' import 'vue-sonner/style.css'
import { Icon } from "#components"; import { Icon } from "#components";
const router = useRouter() const router = useRouter()
const searchProvider = ref('kodik') const searchProvider = ref('kodik')
const displaySearchProvider = computed(() => { const displaySearchProvider = computed(() => {
let label = ''; let label = '';
let image; let image;
if (searchProvider.value === 'kodik') { if (searchProvider.value === 'kodik') {
label = 'Kodik'; label = 'Kodik';
image = kodikImage; image = kodikImage;
} }
if (searchProvider.value === 'shikimori') { if (searchProvider.value === 'shikimori') {
label = 'Shikimori'; label = 'Shikimori';
image = shikimoriImage; image = shikimoriImage;
} }
return { return {
label, label,
image image
} }
}) })
const search = defineModel<string>("") const search = defineModel<string>("")
function querySearch() { function querySearch() {
if (!search.value || search.value.trim() === "") { if (!search.value || search.value.trim() === "") {
toast('Please enter a value'); toast('Please enter a value');
return; return;
} }
router.push({ path: '/search', query: { title: search.value, provider: searchProvider.value } }) router.push({ path: '/search', query: { title: search.value, provider: searchProvider.value } })
.catch(err => { .catch(err => {
console.error('Navigation error:', err); console.error('Navigation error:', err);
toast.error('Failed to navigate to search results'); toast.error('Failed to navigate to search results');
}); });
} }
</script> </script>
<template> <template>
<div> <div class="bg-background flex-1 w-screen flex justify-center items-center gap-1">
<Toaster /> <form @submit.prevent="querySearch" class="flex items-center gap-2">
<Navbar /> <Select v-model="searchProvider">
<SelectTrigger>
<div class="bg-background h-lvh w-screen flex justify-center items-center gap-1"> <SelectValue placeholder="Select an provider">
<form @submit.prevent="querySearch" class="flex items-center gap-2"> <img :src="displaySearchProvider.image" alt="" class="w-5 h-5 rounded border border-gray-300">
<Select v-model="searchProvider"> <span>{{ displaySearchProvider.label }}</span>
<SelectTrigger> </SelectValue>
<SelectValue placeholder="Select an provider"> </SelectTrigger>
<img :src="displaySearchProvider.image" alt="" class="w-5 h-5 rounded border border-gray-300"> <SelectContent>
<span>{{ displaySearchProvider.label }}</span> <SelectGroup>
</SelectValue> <SelectLabel>Providers</SelectLabel>
</SelectTrigger> <SelectItem value="kodik">
<SelectContent> <img :src="kodikImage" alt="" class="w-5 h-5 rounded border border-gray-300">
<SelectGroup> <span>Kodik</span>
<SelectLabel>Providers</SelectLabel> </SelectItem>
<SelectItem value="kodik"> <SelectItem value="shikimori">
<img :src="kodikImage" alt="" class="w-5 h-5 rounded border border-gray-300"> <img :src="shikimoriImage" alt="" class="w-5 h-5 rounded border border-gray-300">
<span>Kodik</span> Shikimori
</SelectItem> </SelectItem>
<SelectItem value="shikimori"> </SelectGroup>
<img :src="shikimoriImage" alt="" class="w-5 h-5 rounded border border-gray-300"> </SelectContent>
Shikimori </Select>
</SelectItem> <Input v-model="search" class="w-64" type="text" placeholder="Search anime..." />
</SelectGroup> <Button type="submit">
</SelectContent> <Icon name="heroicons:magnifying-glass-16-solid" class="w-6 h-6" />
</Select> </Button>
<Input v-model="search" class="w-64" type="text" placeholder="Search anime..." /> </form>
<Button type="submit">
<Icon name="heroicons:magnifying-glass-16-solid" class="w-6 h-6" />
</Button>
</form>
</div> </div>
</div>
</template> </template>

View File

@ -9,50 +9,53 @@ const isLoading = ref(false)
const error = ref<unknown>(null) const error = ref<unknown>(null)
watchEffect(async () => { watchEffect(async () => {
if (!searchQuery.value) return if (!searchQuery.value) return
try { try {
isLoading.value = true isLoading.value = true
error.value = null error.value = null
const response = await search({ title: searchQuery.value }) const response = await search({ title: searchQuery.value })
results.value = response.data.results || [] results.value = response.data.results || []
} catch (err) { } catch (err) {
error.value = err error.value = err
console.error('Search failed:', err) console.error('Search failed:', err)
} finally { } finally {
isLoading.value = false isLoading.value = false
} }
}) })
</script> </script>
<template> <template>
<div> <div>
<div v-if="isLoading"> <div v-if="isLoading">
Loading results... Loading results...
</div> </div>
<div v-if="error"> <div v-if="error">
Error loading results: {{ error }} Error loading results: {{ error }}
</div> </div>
<div v-if="results.length > 0" class="grid grid-cols-[repeat(auto-fill,32rem)] justify-around gap-8 grid-flow-row"> <div v-if="results.length > 0"
<div v-for="item in results" :key="item.id" class="flex w-[32rem]"> class="grid grid-cols-[repeat(auto-fill,16rem)] justify-around gap-8 grid-flow-row">
<NuxtLink :to="`/anime/${item.id}`"> <div v-for="item in results" :key="item.id" class="flex w-[16rem]">
<img v-if="item.material_data?.anime_poster_url" :src="item.material_data.anime_poster_url" :alt="item.title" <NuxtLink :to="`/anime/${item.id}`" class="w-full">
class="rounded-md"> <div v-if="item.material_data?.anime_poster_url" :style="{ 'background-image': 'url('+item.material_data.anime_poster_url+')' }"
<div> :alt="item.title" class="flex items-end justify-end p-2 rounded-md bg-cover bg-center bg-no-repeat h-96">
<h3 className="text-2xl font-semibold tracking-tight">{{ item.title }}</h3> <Button class="backdrop-blur-none bg-primary/80">2 episodes</Button>
<p v-if="item.material_data?.year">Year: {{ item.material_data.year }}</p> </div>
<p v-if="item.material_data?.anime_kind">Type: {{ item.material_data.anime_kind }}</p> <div>
<p v-if="item.material_data?.episodes_total">Episodes: {{ item.material_data.episodes_total }} <h3 className="text-2xl font-semibold tracking-tight">{{ item.title }}</h3>
</p> <p v-if="item.material_data?.year">Year: {{ item.material_data.year }}</p>
</div> <p v-if="item.material_data?.anime_kind">Type: {{ item.material_data.anime_kind }}</p>
</NuxtLink> <p v-if="item.material_data?.episodes_total">Episodes: {{ item.material_data.episodes_total }}
</div> </p>
</div> </div>
</NuxtLink>
</div>
</div>
<div v-if="!isLoading && !error && results.length === 0 && searchQuery"> <div v-if="!isLoading && !error && results.length === 0 && searchQuery">
No results found for "{{ searchQuery }}" No results found for "{{ searchQuery }}"
</div>
</div> </div>
</div>
</template> </template>