mirror of
https://github.com/mmahdium/TBW.git
synced 2025-12-20 04:33:54 +01:00
Compare commits
6 Commits
4a19199fbb
...
eb9dff9f15
| Author | SHA1 | Date | |
|---|---|---|---|
| eb9dff9f15 | |||
| e1346156c8 | |||
| c14934adae | |||
| 97fc93608b | |||
| 97174ff945 | |||
| 542484e8e6 |
11
.github/workflows/deploy.yml
vendored
11
.github/workflows/deploy.yml
vendored
@@ -1,10 +1,11 @@
|
|||||||
name: Deploy to GitHub Pages
|
name: Deploy to GitHub Pages
|
||||||
|
|
||||||
# on:
|
on:
|
||||||
# push:
|
# push:
|
||||||
# branches: [main]
|
# branches: [main]
|
||||||
# pull_request:
|
# pull_request:
|
||||||
# branches: [main]
|
# branches: [main]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-and-deploy:
|
build-and-deploy:
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<router-link
|
<router-link
|
||||||
to="/add"
|
to="/add"
|
||||||
class="card relative w-full h-full flex items-center justify-center aspect-2/3 bg-white/40 backdrop-blur-md rounded-lg transition-all duration-300"
|
class="card relative w-full h-full flex items-center justify-center aspect-2/3 bg-base-300/40 backdrop-blur-md rounded-lg transition-all duration-300 hover:bg-base-200/50"
|
||||||
v-motion-fade-visible-once
|
v-motion-fade-visible-once
|
||||||
>
|
>
|
||||||
<!-- Plus icon -->
|
<!-- Plus icon -->
|
||||||
<div
|
<div
|
||||||
class="flex flex-col items-center justify-center text-gray-400 hover:text-gray-600 transition"
|
class="flex flex-col items-center justify-center text-base-content/50 hover:text-base-content/70 transition"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const imageSource = computed(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<figure class="overflow-hidden flex items-center justify-center bg-gray-50 aspect-2/3">
|
<figure class="overflow-hidden flex items-center justify-center bg-base-300 aspect-2/3">
|
||||||
<span v-if="!loaded" class="loading loading-ring loading-lg text-primary"></span>
|
<span v-if="!loaded" class="loading loading-ring loading-lg text-primary"></span>
|
||||||
|
|
||||||
<div v-else-if="imageLoadFailed" class="flex items-center justify-center">
|
<div v-else-if="imageLoadFailed" class="flex items-center justify-center">
|
||||||
@@ -33,7 +33,7 @@ const imageSource = computed(() => {
|
|||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
stroke-width="1.5"
|
stroke-width="1.5"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
class="w-12 h-12 text-gray-300"
|
class="w-12 h-12 text-base-content/40"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
|
|||||||
@@ -21,23 +21,23 @@ const alreadyAdded = computed(() => store.mediaList.some((media) => media.Id ===
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="card relative w-full h-full overflow-hidden bg-white/70 backdrop-blur-md border border-gray-200/60 shadow-xs hover:shadow-xl transition-all duration-300"
|
class="card relative w-full h-full overflow-hidden bg-base-200/70 backdrop-blur-md border border-base-content/20 shadow-xs hover:shadow-xl transition-all duration-300"
|
||||||
v-motion-fade-visible-once
|
v-motion-fade-visible-once
|
||||||
>
|
>
|
||||||
<div class="relative w-full">
|
<div class="relative w-full">
|
||||||
<router-link
|
<router-link
|
||||||
:to="{ name: 'details', params: { type: props.media.MediaType, id: props.media.Id } }"
|
:to="{ name: 'details', params: { type: props.media.MediaType, id: props.media.Id } }"
|
||||||
class="block w-full aspect-2/3 overflow-hidden bg-gray-100 relative"
|
class="block w-full aspect-2/3 overflow-hidden bg-base-300 relative"
|
||||||
>
|
>
|
||||||
<ImageWithFallback
|
<ImageWithFallback
|
||||||
:src="props.media.PosterPath"
|
:src="props.media.PosterPath"
|
||||||
:alt="props.media.Title"
|
:alt="props.media.Title"
|
||||||
size="w300"
|
size="w300"
|
||||||
class="w-full h-full object-cover transform transition-transform duration-500 hover:scale-105"
|
class="w-full h-full object-cover transform transition-transform duration-500 hover:scale-101"
|
||||||
/>
|
/>
|
||||||
<!-- Glassy gradient shadow overlay -->
|
<!-- Glassy gradient shadow overlay -->
|
||||||
<div
|
<div
|
||||||
class="absolute bottom-0 left-0 right-0 h-16 bg-linear-to-t from-white/40 via-white/20 to-transparent backdrop-blur-[0.5px] pointer-events-none"
|
class="absolute bottom-0 left-0 right-0 h-16 bg-gradient-to-t from-base-100/40 via-base-100/20 to-transparent backdrop-blur-[0.5px] pointer-events-none"
|
||||||
></div>
|
></div>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
@@ -54,12 +54,12 @@ const alreadyAdded = computed(() => store.mediaList.some((media) => media.Id ===
|
|||||||
class="block"
|
class="block"
|
||||||
>
|
>
|
||||||
<h2
|
<h2
|
||||||
class="card-title text-base font-semibold bg-linear-to-r from-gray-700 to-gray-500 bg-clip-text text-transparent break-words"
|
class="card-title text-base font-semibold bg-gradient-to-r from-base-content to-base-content/75 bg-clip-text text-transparent break-words"
|
||||||
>
|
>
|
||||||
{{ props.media.Title }}
|
{{ props.media.Title }}
|
||||||
</h2>
|
</h2>
|
||||||
<time
|
<time
|
||||||
class="text-sm text-gray-400"
|
class="text-sm text-base-content/60"
|
||||||
:datetime="
|
:datetime="
|
||||||
props.media.ReleaseDate === '' && props.media.FirstAirDate === ''
|
props.media.ReleaseDate === '' && props.media.FirstAirDate === ''
|
||||||
? 'unknown'
|
? 'unknown'
|
||||||
@@ -93,7 +93,7 @@ const alreadyAdded = computed(() => store.mediaList.some((media) => media.Id ===
|
|||||||
<!-- Type badge -->
|
<!-- Type badge -->
|
||||||
<span
|
<span
|
||||||
class="badge badge-outline text-xs font-medium px-2 py-1"
|
class="badge badge-outline text-xs font-medium px-2 py-1"
|
||||||
:class="props.media.Adult ? 'badge-error' : ''"
|
:class="props.media.Adult ? 'badge-error' : 'text-base-content'"
|
||||||
>
|
>
|
||||||
{{ props.media.MediaType === 'movie' ? 'Movie' : 'Show' }}
|
{{ props.media.MediaType === 'movie' ? 'Movie' : 'Show' }}
|
||||||
</span>
|
</span>
|
||||||
@@ -103,7 +103,7 @@ const alreadyAdded = computed(() => store.mediaList.some((media) => media.Id ===
|
|||||||
<button
|
<button
|
||||||
v-motion-fade-visible-once
|
v-motion-fade-visible-once
|
||||||
v-if="!alreadyAdded"
|
v-if="!alreadyAdded"
|
||||||
class="btn btn-circle btn-md px-1.5 bg-linear-to-r from-gray-100 to-gray-200 border-gray-300 text-gray-700 hover:from-gray-200 hover:to-gray-300 hover:text-gray-900 transition"
|
class="btn btn-circle btn-md px-1.5 bg-gradient-to-r from-base-300 to-base-200 border-base-content/30 text-base-content hover:from-base-200 hover:to-base-100 hover:text-base-content/90 transition"
|
||||||
@click="emit('add-media', props.media)"
|
@click="emit('add-media', props.media)"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@@ -124,7 +124,7 @@ const alreadyAdded = computed(() => store.mediaList.some((media) => media.Id ===
|
|||||||
<button
|
<button
|
||||||
v-motion-fade-visible-once
|
v-motion-fade-visible-once
|
||||||
v-else
|
v-else
|
||||||
class="btn btn-circle btn-md px-1.5 bg-linear-to-r from-red-50 to-red-100 border border-red-200 text-red-600 hover:from-red-100 hover:to-red-200 hover:text-red-700 transition"
|
class="btn btn-circle btn-md px-1.5 bg-gradient-to-r from-error/10 to-error/20 border border-error/30 text-error hover:from-error/20 hover:to-error/30 hover:text-error-content transition"
|
||||||
@click="emit('remove-media', props.media.Id)"
|
@click="emit('remove-media', props.media.Id)"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
|
|||||||
@@ -50,36 +50,38 @@ watch(
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<form class="flex gap-2 justify-center mb-8">
|
<form class="flex gap-2 justify-center mb-8 flex-wrap">
|
||||||
<label>
|
<label class="btn btn-outline" :class="local.includeAdult ? 'btn-error' : 'btn-ghost'">
|
||||||
<input
|
<input
|
||||||
class="btn"
|
|
||||||
:class="local.includeAdult ? 'btn-error' : ''"
|
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
:checked="local.includeAdult"
|
:checked="local.includeAdult"
|
||||||
@change="toggleIncludeAdult"
|
@change="toggleIncludeAdult"
|
||||||
aria-label="Adult"
|
aria-label="Adult"
|
||||||
|
class="sr-only"
|
||||||
/>
|
/>
|
||||||
|
Adult
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label>
|
<label class="btn btn-outline" :class="local.onlyMovies ? 'btn-primary' : 'btn-ghost'">
|
||||||
<input
|
<input
|
||||||
class="btn"
|
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
:checked="local.onlyMovies"
|
:checked="local.onlyMovies"
|
||||||
@change="toggleOnlyMovies"
|
@change="toggleOnlyMovies"
|
||||||
aria-label="Movies"
|
aria-label="Movies"
|
||||||
|
class="sr-only"
|
||||||
/>
|
/>
|
||||||
|
Movies
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label>
|
<label class="btn btn-outline" :class="local.onlySeries ? 'btn-primary' : 'btn-ghost'">
|
||||||
<input
|
<input
|
||||||
class="btn"
|
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
:checked="local.onlySeries"
|
:checked="local.onlySeries"
|
||||||
@change="toggleOnlySeries"
|
@change="toggleOnlySeries"
|
||||||
aria-label="TV Series"
|
aria-label="TV Series"
|
||||||
|
class="sr-only"
|
||||||
/>
|
/>
|
||||||
|
TV Series
|
||||||
</label>
|
</label>
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -31,10 +31,13 @@ window.addEventListener('scroll', () => {
|
|||||||
<div>
|
<div>
|
||||||
<p
|
<p
|
||||||
v-if="props.medias.length === 0"
|
v-if="props.medias.length === 0"
|
||||||
class="text-center text-gray-500 py-12 bg-gray-50/60 rounded-lg border border-gray-200"
|
class="text-center text-base-content/60 py-12 bg-base-300/60 rounded-lg border border-base-content/20"
|
||||||
>
|
>
|
||||||
No media found.<br />
|
No media found.<br />
|
||||||
<RouterLink to="/add" class="text-gray-700 font-semibold hover:text-gray-900 transition">
|
<RouterLink
|
||||||
|
to="/add"
|
||||||
|
class="text-base-content/70 font-semibold hover:text-base-content transition"
|
||||||
|
>
|
||||||
Add media
|
Add media
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</p>
|
</p>
|
||||||
@@ -62,7 +65,7 @@ window.addEventListener('scroll', () => {
|
|||||||
|
|
||||||
<div v-if="props.isSearch && props.medias.length > 0" class="flex justify-center mt-8">
|
<div v-if="props.isSearch && props.medias.length > 0" class="flex justify-center mt-8">
|
||||||
<button
|
<button
|
||||||
class="btn px-6 bg-linear-to-r from-gray-100 to-gray-200 border border-gray-300 text-gray-700 hover:from-gray-200 hover:to-gray-300 hover:text-gray-900 disabled:opacity-50"
|
class="btn px-6 bg-gradient-to-r from-base-300 to-base-200 border border-base-content/30 text-base-content hover:from-base-200 hover:to-base-100 hover:text-base-content/90 disabled:opacity-50"
|
||||||
@click="emit('loadMore')"
|
@click="emit('loadMore')"
|
||||||
:disabled="props.loadingMore"
|
:disabled="props.loadingMore"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<span
|
<span
|
||||||
:class="`flex items-center w-max px-3 py-1 rounded-md text-sm bg-linear-to-r from-gray-100 to-gray-200 ${type ? 'badge-' + type : ''} text-gray-700 border border-gray-300`"
|
:class="`flex items-center w-max px-3 py-1 rounded-md text-sm bg-gradient-to-r from-base-300 to-base-200 ${type ? 'badge-' + type : ''} text-base-content border border-base-content/30`"
|
||||||
>
|
>
|
||||||
{{ props.text }}
|
{{ props.text }}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ const alreadyAdded = computed(() =>
|
|||||||
<template>
|
<template>
|
||||||
<!-- Hero -->
|
<!-- Hero -->
|
||||||
<div
|
<div
|
||||||
class="flex flex-col lg:flex-row gap-12 items-center max-w-6xl w-full bg-white/70 border border-gray-200/60 rounded-xl p-8 transition"
|
class="flex flex-col lg:flex-row gap-12 items-center max-w-6xl w-full bg-base-200/70 border border-base-content/20 rounded-xl p-8 transition"
|
||||||
v-motion-fade-visible-once
|
v-motion-fade-visible-once
|
||||||
>
|
>
|
||||||
<!-- Poster -->
|
<!-- Poster -->
|
||||||
@@ -34,18 +34,18 @@ const alreadyAdded = computed(() =>
|
|||||||
|
|
||||||
<!-- Text -->
|
<!-- Text -->
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<h1 class="text-4xl font-bold text-gray-800 mb-2">
|
<h1 class="text-4xl font-bold text-base-content/95 mb-2">
|
||||||
{{ props.movie!.Title }}
|
{{ props.movie!.Title }}
|
||||||
<span class="text-gray-400 text-lg font-normal"
|
<span class="text-base-content/70 text-lg font-normal"
|
||||||
>({{ props.movie!.ReleaseDate?.slice(0, 4) }})</span
|
>({{ props.movie!.ReleaseDate?.slice(0, 4) }})</span
|
||||||
>
|
>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p v-if="props.movie!.Tagline" class="italic text-gray-500 mb-2">
|
<p v-if="props.movie!.Tagline" class="italic text-base-content/65 mb-2">
|
||||||
{{ props.movie!.Tagline }}
|
{{ props.movie!.Tagline }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class="text-accent leading-relaxed mb-6">
|
<p class="text-base-content leading-relaxed mb-6">
|
||||||
{{ props.movie!.Overview }}
|
{{ props.movie!.Overview }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@@ -54,19 +54,21 @@ const alreadyAdded = computed(() =>
|
|||||||
<MediaTypeBadge v-for="g in props.movie!.Genres" :key="g.id" :text="g.name" />
|
<MediaTypeBadge v-for="g in props.movie!.Genres" :key="g.id" :text="g.name" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card bg-base-200 w-full lg:w-96 shadow-sm mb-6 mt-6">
|
<div class="card border border-accent bg-base-200 w-full lg:w-96 shadow-sm mb-6 mt-6">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p class="font-semibold text-gray-900">
|
<p class="font-semibold text-base-content/90">
|
||||||
Runtime: <span class="text-gray-600">{{ props.movie!.Runtime }} minutes</span>
|
Runtime: <span class="text-base-content/70">{{ props.movie!.Runtime }} minutes</span>
|
||||||
</p>
|
</p>
|
||||||
<p class="font-semibold text-gray-900">
|
<p class="font-semibold text-base-content/90">
|
||||||
Language:
|
Language:
|
||||||
<span class="text-gray-600">{{ props.movie!.SpokenLanguages[0]?.englishName }}</span>
|
<span class="text-base-content/70">{{
|
||||||
|
props.movie!.SpokenLanguages[0]?.englishName
|
||||||
|
}}</span>
|
||||||
</p>
|
</p>
|
||||||
<p class="font-semibold text-gray-900">
|
<p class="font-semibold text-base-content/90">
|
||||||
Release Date:
|
Release Date:
|
||||||
<time
|
<time
|
||||||
class="text-sm font-semibold text-gray-600"
|
class="text-sm font-semibold text-base-content/70"
|
||||||
:datetime="
|
:datetime="
|
||||||
props.movie!.ReleaseDate === ''
|
props.movie!.ReleaseDate === ''
|
||||||
? 'unknown'
|
? 'unknown'
|
||||||
@@ -90,9 +92,9 @@ const alreadyAdded = computed(() =>
|
|||||||
:href="`https://www.themoviedb.org/movie/${props.movie?.Id}`"
|
:href="`https://www.themoviedb.org/movie/${props.movie?.Id}`"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
class="btn btn-square btn-md bg-accent border-none"
|
class="btn btn-square btn-md bg-base-300 border border-base-content/30"
|
||||||
>
|
>
|
||||||
<img src="/logos/tmdb.svg" alt="TMDB" class="m-0.5" />
|
<img src="/logos/tmdb.svg" alt="TMDB" class="h-6 w-6" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<!-- IMDB button -->
|
<!-- IMDB button -->
|
||||||
@@ -101,9 +103,9 @@ const alreadyAdded = computed(() =>
|
|||||||
:href="`https://www.imdb.com/title/${props.movie.ImdbId}`"
|
:href="`https://www.imdb.com/title/${props.movie.ImdbId}`"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
class="btn btn-square btn-md bg-[#f5c518] border-none"
|
class="btn btn-square btn-md bg-[#f5c518] border border-[#f5c518]/30"
|
||||||
>
|
>
|
||||||
<img src="/logos/imdb.svg" alt="IMDB" class="m-0.5" />
|
<img src="/logos/imdb.svg" alt="IMDB" class="h-6 w-6" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -114,7 +116,7 @@ const alreadyAdded = computed(() =>
|
|||||||
<template v-if="props.movie && props.media">
|
<template v-if="props.movie && props.media">
|
||||||
<button
|
<button
|
||||||
v-if="!alreadyAdded"
|
v-if="!alreadyAdded"
|
||||||
class="btn btn-square bg-linear-to-r from-gray-100 to-gray-200 border border-gray-300 text-gray-700 hover:from-gray-200 hover:to-gray-300"
|
class="btn btn-square bg-gradient-to-r from-base-300 to-base-200 border border-base-content/30 text-base-content hover:from-base-200 hover:to-base-100"
|
||||||
@click="store.addMedia(props.media)"
|
@click="store.addMedia(props.media)"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@@ -134,7 +136,7 @@ const alreadyAdded = computed(() =>
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-else
|
v-else
|
||||||
class="btn btn-square bg-linear-to-r from-red-50 to-red-100 border border-red-200 text-red-600 hover:from-red-100 hover:to-red-200"
|
class="btn btn-square bg-gradient-to-r from-error/10 to-error/20 border border-error/30 text-error hover:from-error/20 hover:to-error/30"
|
||||||
@click="store.removeMedia(props.media.Id)"
|
@click="store.removeMedia(props.media.Id)"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@@ -164,7 +166,7 @@ const alreadyAdded = computed(() =>
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="btn relative flex items-center gap-2 px-6 bg-linear-to-r from-indigo-500 to-violet-500 text-white border-0 shadow-md hover:opacity-90 transition"
|
class="btn relative flex items-center gap-2 px-6 bg-gradient-to-r from-primary to-secondary text-primary-content border-0 shadow-md hover:opacity-90 transition"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<nav
|
<nav
|
||||||
class="navbar sticky top-0 z-30 bg-white/70 backdrop-blur-md border-b border-gray-200/60 shadow-sm"
|
class="navbar sticky top-0 z-30 bg-base-100/70 backdrop-blur-md border-b border-base-content/20 shadow-sm"
|
||||||
>
|
>
|
||||||
<!-- Left: Logo + Mobile Menu -->
|
<!-- Left: Logo + Mobile Menu -->
|
||||||
<div class="navbar-start">
|
<div class="navbar-start">
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<label tabindex="0" class="btn btn-ghost p-2" aria-label="Menu">
|
<label tabindex="0" class="btn btn-ghost p-2" aria-label="Menu">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
class="h-6 w-6 text-gray-700"
|
class="h-6 w-6 text-base-content/70"
|
||||||
fill="none"
|
fill="none"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
</label>
|
</label>
|
||||||
<ul
|
<ul
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
class="menu menu-sm dropdown-content mt-3 w-52 rounded-md bg-white/90 backdrop-blur-md shadow-lg border border-gray-200/60"
|
class="menu menu-sm dropdown-content mt-3 w-52 rounded-md bg-base-200/90 backdrop-blur-md shadow-lg border border-base-content/20"
|
||||||
>
|
>
|
||||||
<li><RouterLink to="/" class="nav-link">Home</RouterLink></li>
|
<li><RouterLink to="/" class="nav-link">Home</RouterLink></li>
|
||||||
<li><RouterLink to="/list" class="nav-link">Library</RouterLink></li>
|
<li><RouterLink to="/list" class="nav-link">Library</RouterLink></li>
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
<!-- Logo -->
|
<!-- Logo -->
|
||||||
<RouterLink
|
<RouterLink
|
||||||
to="/"
|
to="/"
|
||||||
class="text-2xl font-extrabold tracking-tight bg-linear-to-r from-gray-700 via-indigo-500 to-cyan-400 bg-clip-text text-transparent"
|
class="text-2xl font-extrabold tracking-tight bg-gradient-to-r from-base-content/70 via-primary to-base-content/70 bg-clip-text text-transparent"
|
||||||
>
|
>
|
||||||
TBW
|
TBW
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
<div class="navbar-end">
|
<div class="navbar-end">
|
||||||
<RouterLink
|
<RouterLink
|
||||||
to="/list"
|
to="/list"
|
||||||
class="btn px-5 bg-linear-to-r from-gray-100 to-gray-200 border border-gray-300 text-gray-700 hover:from-gray-200 hover:to-gray-300 hover:text-gray-900 transition"
|
class="btn px-5 bg-gradient-to-r from-base-300 to-base-200 border border-base-content/30 text-base-content hover:from-base-200 hover:to-base-100 hover:text-base-content/90 transition"
|
||||||
>
|
>
|
||||||
Go to Library
|
Go to Library
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
@@ -63,11 +63,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@reference "tailwindcss";
|
@reference "@/style.css";
|
||||||
.nav-link {
|
.nav-link {
|
||||||
@apply text-gray-700 font-medium transition-colors hover:text-gray-900;
|
@apply text-base-content font-medium transition-colors hover:text-base-content;
|
||||||
}
|
}
|
||||||
.router-link-active.nav-link {
|
.router-link-active.nav-link {
|
||||||
@apply text-indigo-600 font-semibold;
|
@apply text-primary font-semibold;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ function onSubmit() {
|
|||||||
<template>
|
<template>
|
||||||
<form @submit.prevent="onSubmit" class="flex justify-center mb-3">
|
<form @submit.prevent="onSubmit" class="flex justify-center mb-3">
|
||||||
<div
|
<div
|
||||||
class="flex items-center w-full max-w-md bg-white/70 backdrop-blur-md border border-gray-200/60 shadow-sm hover:shadow-md transition rounded-lg overflow-hidden"
|
class="flex items-center w-full max-w-md bg-base-200/70 backdrop-blur-md border border-base-content/20 shadow-sm hover:shadow-md transition rounded-lg overflow-hidden"
|
||||||
>
|
>
|
||||||
<!-- Icon -->
|
<!-- Icon -->
|
||||||
<span class="pl-3 text-gray-400">
|
<span class="pl-3 text-base-content/50">
|
||||||
<svg
|
<svg
|
||||||
class="h-5 w-5"
|
class="h-5 w-5"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@@ -41,7 +41,7 @@ function onSubmit() {
|
|||||||
required
|
required
|
||||||
:value="props.modelValue"
|
:value="props.modelValue"
|
||||||
@input="emit('update:modelValue', ($event.target as HTMLInputElement).value)"
|
@input="emit('update:modelValue', ($event.target as HTMLInputElement).value)"
|
||||||
class="flex-1 px-3 py-2 bg-transparent outline-none text-gray-700 placeholder-gray-400"
|
class="flex-1 px-3 py-2 bg-transparent outline-none text-base-content/70 placeholder-base-content/50"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Optional button -->
|
<!-- Optional button -->
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ const alreadyAdded = computed(() =>
|
|||||||
<template>
|
<template>
|
||||||
<!-- Hero -->
|
<!-- Hero -->
|
||||||
<div
|
<div
|
||||||
class="flex flex-col lg:flex-row gap-12 items-center max-w-6xl w-full bg-white/70 border border-gray-200/60 rounded-xl p-8 transition"
|
class="flex flex-col lg:flex-row gap-12 items-center max-w-6xl w-full bg-base-200/70 border border-base-content/20 rounded-xl p-8 transition"
|
||||||
v-motion-fade-visible-once
|
v-motion-fade-visible-once
|
||||||
>
|
>
|
||||||
<!-- Poster -->
|
<!-- Poster -->
|
||||||
@@ -34,18 +34,18 @@ const alreadyAdded = computed(() =>
|
|||||||
|
|
||||||
<!-- Text -->
|
<!-- Text -->
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<h1 class="text-4xl font-bold text-gray-800 mb-2">
|
<h1 class="text-4xl font-bold text-base-content/95 mb-2">
|
||||||
{{ props.tvSeries!.Name }}
|
{{ props.tvSeries!.Name }}
|
||||||
<span class="text-gray-400 text-lg font-normal"
|
<span class="text-base-content/70 text-lg font-normal"
|
||||||
>({{ props.tvSeries!.FirstAirDate?.slice(0, 4) }})</span
|
>({{ props.tvSeries!.FirstAirDate?.slice(0, 4) }})</span
|
||||||
>
|
>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p v-if="props.tvSeries!.Tagline" class="italic text-gray-500 mb-2">
|
<p v-if="props.tvSeries!.Tagline" class="italic text-base-content/65 mb-2">
|
||||||
{{ props.tvSeries!.Tagline }}
|
{{ props.tvSeries!.Tagline }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class="text-accent leading-relaxed mb-6">
|
<p class="text-base-content leading-relaxed mb-6">
|
||||||
{{ props.tvSeries!.Overview }}
|
{{ props.tvSeries!.Overview }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@@ -54,18 +54,18 @@ const alreadyAdded = computed(() =>
|
|||||||
<MediaTypeBadge v-for="g in props.tvSeries!.Genres" :key="g.id" :text="g.name" />
|
<MediaTypeBadge v-for="g in props.tvSeries!.Genres" :key="g.id" :text="g.name" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card bg-base-200 w-full lg:w-96 shadow-sm mb-6 mt-6">
|
<div class="card bg-base-200 w-full lg:w-96 shadow-sm border border-accent mb-6 mt-6">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="inline-flex items-center gap-2">
|
<div class="inline-flex items-center gap-2">
|
||||||
<span class="flex items-center font-semibold text-gray-900">
|
<span class="flex items-center font-semibold text-base-content/90">
|
||||||
Seasons:
|
Seasons:
|
||||||
<span class="ml-1 text-gray-600">{{ props.tvSeries!.NumberOfSeasons }}</span>
|
<span class="ml-1 text-base-content/70">{{ props.tvSeries!.NumberOfSeasons }}</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<!-- SVG star separator -->
|
<!-- SVG star separator -->
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
class="w-4 h-4 text-yellow-500 shrink-0"
|
class="w-4 h-4 text-warning shrink-0"
|
||||||
viewBox="0 0 20 20"
|
viewBox="0 0 20 20"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@@ -75,24 +75,26 @@ const alreadyAdded = computed(() =>
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<span class="flex items-center font-semibold text-gray-900">
|
<span class="flex items-center font-semibold text-base-content/90">
|
||||||
Episodes:
|
Episodes:
|
||||||
<span class="ml-1 text-gray-600">{{ props.tvSeries!.NumberOfEpisodes }}</span>
|
<span class="ml-1 text-base-content/70">{{ props.tvSeries!.NumberOfEpisodes }}</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="font-semibold text-gray-900">
|
<p class="font-semibold text-base-content/90">
|
||||||
Last Episode:
|
Last Episode:
|
||||||
<span class="text-gray-600">{{ props.tvSeries!.LastEpisodeToAir?.name }}</span>
|
<span class="text-base-content/70">{{ props.tvSeries!.LastEpisodeToAir?.name }}</span>
|
||||||
</p>
|
</p>
|
||||||
<p class="font-semibold text-gray-900">
|
<p class="font-semibold text-base-content/90">
|
||||||
Language:
|
Language:
|
||||||
<span class="text-gray-600">{{ props.tvSeries!.SpokenLanguages[0]?.englishName }}</span>
|
<span class="text-base-content/70">{{
|
||||||
|
props.tvSeries!.SpokenLanguages[0]?.englishName
|
||||||
|
}}</span>
|
||||||
</p>
|
</p>
|
||||||
<p class="font-semibold text-gray-900">
|
<p class="font-semibold text-base-content/90">
|
||||||
First Air Date:
|
First Air Date:
|
||||||
<time
|
<time
|
||||||
class="text-sm font-semibold text-gray-600"
|
class="text-sm font-semibold text-base-content/70"
|
||||||
:datetime="
|
:datetime="
|
||||||
props.tvSeries!.FirstAirDate === ''
|
props.tvSeries!.FirstAirDate === ''
|
||||||
? 'unknown'
|
? 'unknown'
|
||||||
@@ -116,9 +118,9 @@ const alreadyAdded = computed(() =>
|
|||||||
:href="`https://www.themoviedb.org/tv/${props.tvSeries?.Id}`"
|
:href="`https://www.themoviedb.org/tv/${props.tvSeries?.Id}`"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
class="btn btn-square btn-md bg-accent border-none"
|
class="btn btn-square btn-md bg-base-300 border border-base-content/30"
|
||||||
>
|
>
|
||||||
<img src="/logos/tmdb.svg" alt="TMDB" class="m-0.5" />
|
<img src="/logos/tmdb.svg" alt="TMDB" class="h-6 w-6" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<!-- IMDB button -->
|
<!-- IMDB button -->
|
||||||
@@ -127,9 +129,9 @@ const alreadyAdded = computed(() =>
|
|||||||
:href="props.tvSeries.Homepage"
|
:href="props.tvSeries.Homepage"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
class="btn btn-square btn-md bg-[#f5c518] border-none"
|
class="btn btn-square btn-md bg-[#f5c518] border border-[#f5c518]/30"
|
||||||
>
|
>
|
||||||
<img src="/logos/imdb.svg" alt="IMDB" class="m-0.5" />
|
<img src="/logos/imdb.svg" alt="IMDB" class="h-6 w-6" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -140,7 +142,7 @@ const alreadyAdded = computed(() =>
|
|||||||
<template v-if="props.tvSeries && props.media">
|
<template v-if="props.tvSeries && props.media">
|
||||||
<button
|
<button
|
||||||
v-if="!alreadyAdded"
|
v-if="!alreadyAdded"
|
||||||
class="btn btn-square bg-linear-to-r from-gray-100 to-gray-200 border border-gray-300 text-gray-700 hover:from-gray-200 hover:to-gray-300"
|
class="btn btn-square bg-gradient-to-r from-base-300 to-base-200 border border-base-content/30 text-base-content hover:from-base-200 hover:to-base-100"
|
||||||
@click="store.addMedia(props.media)"
|
@click="store.addMedia(props.media)"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@@ -160,7 +162,7 @@ const alreadyAdded = computed(() =>
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
v-else
|
v-else
|
||||||
class="btn btn-square bg-linear-to-r from-red-50 to-red-100 border border-red-200 text-red-600 hover:from-red-100 hover:to-red-200"
|
class="btn btn-square bg-gradient-to-r from-error/10 to-error/20 border border-error/30 text-error hover:from-error/20 hover:to-error/30"
|
||||||
@click="store.removeMedia(props.media.Id)"
|
@click="store.removeMedia(props.media.Id)"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@@ -190,7 +192,7 @@ const alreadyAdded = computed(() =>
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="btn relative flex items-center gap-2 px-6 bg-linear-to-r from-indigo-500 to-violet-500 text-white border-0 shadow-md hover:opacity-90 transition"
|
class="btn relative flex items-center gap-2 px-6 bg-gradient-to-r from-primary to-secondary text-primary-content border-0 shadow-md hover:opacity-90 transition"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'
|
import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'
|
||||||
|
import HomeView from '@/views/HomeView.vue'
|
||||||
|
|
||||||
const routes: RouteRecordRaw[] = [
|
const routes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
@@ -9,7 +10,7 @@ const routes: RouteRecordRaw[] = [
|
|||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
name: 'home',
|
name: 'home',
|
||||||
component: () => import('@/views/HomeView.vue'),
|
component: HomeView,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/list',
|
path: '/list',
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
@import 'tailwindcss';
|
@import 'tailwindcss';
|
||||||
@plugin "daisyui" {
|
@plugin "daisyui" {
|
||||||
themes: lofi --default;
|
themes: halloween --default;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ watch(filters, () => {
|
|||||||
<div class="container mx-auto px-4 py-12" v-motion-fade-visible-once>
|
<div class="container mx-auto px-4 py-12" v-motion-fade-visible-once>
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<h1
|
<h1
|
||||||
class="text-4xl font-extrabold text-center mb-10 bg-linear-to-r from-gray-700 to-gray-500 bg-clip-text text-transparent"
|
class="text-4xl font-extrabold text-center mb-10 bg-gradient-to-r from-base-content to-base-content/70 bg-clip-text text-transparent"
|
||||||
>
|
>
|
||||||
Add Media
|
Add Media
|
||||||
</h1>
|
</h1>
|
||||||
@@ -151,7 +151,7 @@ watch(filters, () => {
|
|||||||
<!-- Empty state -->
|
<!-- Empty state -->
|
||||||
<p
|
<p
|
||||||
v-else
|
v-else
|
||||||
class="text-center text-gray-500 mt-16 bg-gray-50/60 border border-gray-200 rounded-lg py-12"
|
class="text-center text-base-content/60 mt-16 bg-base-300/60 border border-base-content/20 rounded-lg py-12"
|
||||||
>
|
>
|
||||||
Search for a movie or TV Serie to add it to your list
|
Search for a movie or TV Serie to add it to your list
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script setup lang="ts"></script>
|
<script setup lang="ts"></script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="relative isolate bg-white px-6 pt-16 lg:px-8">
|
<div class="relative isolate bg-base-100 px-6 pt-16 lg:px-8">
|
||||||
<!-- Top blurred gradient background -->
|
<!-- Top blurred gradient background -->
|
||||||
<div
|
<div
|
||||||
class="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80"
|
class="absolute inset-x-0 -top-40 -z-10 transform-gpu overflow-hidden blur-3xl sm:-top-80"
|
||||||
@@ -42,13 +42,13 @@
|
|||||||
<span class="text-6xl font-extrabold gradient-text"> To Be Watched </span>
|
<span class="text-6xl font-extrabold gradient-text"> To Be Watched </span>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p class="text-lg text-gray-600 max-w-2xl mx-auto mb-12">
|
<p class="text-lg text-base-content/70 max-w-2xl mx-auto mb-12">
|
||||||
A simple and beautiful media list app built with Vue 3 and Tailwind CSS (daisyUI).
|
A simple and beautiful media list app built with Vue 3 and Tailwind CSS (daisyUI).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<RouterLink
|
<RouterLink
|
||||||
to="/add"
|
to="/add"
|
||||||
class="btn px-8 py-3 text-lg font-medium bg-linear-to-r from-gray-100 to-gray-200 border border-gray-300 text-gray-700 hover:from-gray-200 hover:to-gray-300 hover:text-gray-900 transition"
|
class="btn px-8 py-3 text-lg font-medium bg-gradient-to-r from-base-300 to-base-200 border border-base-content/30 text-base-content hover:from-base-200 hover:to-base-100 hover:text-base-content/90 transition"
|
||||||
>
|
>
|
||||||
Get Started
|
Get Started
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
@@ -90,9 +90,9 @@
|
|||||||
.gradient-text {
|
.gradient-text {
|
||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
90deg,
|
90deg,
|
||||||
#6b7280 0%,
|
oklch(77.48% 0.204 60.62) 0%,
|
||||||
/* gray-500 */ #818cf8 50%,
|
/* primary */ oklch(45.98% 0.248 305.03) 50%,
|
||||||
/* indigo-400 */ #22d3ee 100% /* cyan-400 */
|
/* secondary */ oklch(77.48% 0.204 60.62) 100% /* accent */
|
||||||
);
|
);
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
background-clip: text;
|
background-clip: text;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const handleRemoveMedia = (mediaId: number) => {
|
|||||||
<template>
|
<template>
|
||||||
<div class="container mx-auto px-4 py-12" v-motion-fade-visible-once>
|
<div class="container mx-auto px-4 py-12" v-motion-fade-visible-once>
|
||||||
<h1
|
<h1
|
||||||
class="text-4xl font-extrabold text-center mb-10 bg-linear-to-r from-gray-700 to-gray-500 bg-clip-text text-transparent"
|
class="text-4xl font-extrabold text-center mb-10 bg-gradient-to-r from-base-content to-base-content/70 bg-clip-text text-transparent"
|
||||||
>
|
>
|
||||||
Media Library
|
Media Library
|
||||||
</h1>
|
</h1>
|
||||||
|
|||||||
@@ -2,24 +2,24 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="min-h-screen flex flex-col items-center justify-center bg-linear-to-b from-gray-50 to-white px-4"
|
class="min-h-screen flex flex-col items-center justify-center bg-gradient-to-b from-base-300 to-base-100 px-4"
|
||||||
>
|
>
|
||||||
<!-- Big 404 -->
|
<!-- Big 404 -->
|
||||||
<h1
|
<h1
|
||||||
class="text-8xl font-extrabold mb-4 bg-linear-to-r from-gray-700 to-gray-500 bg-clip-text text-transparent"
|
class="text-8xl font-extrabold mb-4 bg-gradient-to-r from-base-content/70 to-base-content/50 bg-clip-text text-transparent"
|
||||||
>
|
>
|
||||||
404
|
404
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<!-- Message -->
|
<!-- Message -->
|
||||||
<p class="text-xl text-gray-600 mb-8 text-center">
|
<p class="text-xl text-base-content/70 mb-8 text-center">
|
||||||
Oops! The page you’re looking for doesn’t exist.
|
Oops! The page you’re looking for doesn’t exist.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- Button back home -->
|
<!-- Button back home -->
|
||||||
<RouterLink
|
<RouterLink
|
||||||
to="/"
|
to="/"
|
||||||
class="btn px-6 py-3 bg-linear-to-r from-gray-100 to-gray-200 border border-gray-300 text-gray-700 hover:from-gray-200 hover:to-gray-300 hover:text-gray-900 transition"
|
class="btn px-6 py-3 bg-gradient-to-r from-base-300 to-base-200 border border-base-content/30 text-base-content hover:from-base-200 hover:to-base-100 hover:text-base-content/90 transition"
|
||||||
>
|
>
|
||||||
Back to Home
|
Back to Home
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const isLoaded = ref(false)
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col items-center w-full min-h-screen bg-black text-white">
|
<div class="flex flex-col items-center w-full min-h-screen bg-base-100 text-base-content">
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<h1 class="text-2xl md:text-3xl font-bold my-4">
|
<h1 class="text-2xl md:text-3xl font-bold my-4">
|
||||||
{{ mediaName }}
|
{{ mediaName }}
|
||||||
@@ -17,7 +17,7 @@ const isLoaded = ref(false)
|
|||||||
|
|
||||||
<!-- Loading spinner -->
|
<!-- Loading spinner -->
|
||||||
<div v-if="!isLoaded" class="flex justify-center items-center flex-1 w-full">
|
<div v-if="!isLoaded" class="flex justify-center items-center flex-1 w-full">
|
||||||
<span class="loading loading-ring loading-lg text-white"></span>
|
<span class="loading loading-ring loading-xl text-primary"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Video player -->
|
<!-- Video player -->
|
||||||
@@ -32,7 +32,7 @@ const isLoaded = ref(false)
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Disclaimer -->
|
<!-- Disclaimer -->
|
||||||
<p class="mt-4 text-xs text-gray-400 text-center px-4 max-w-xl">
|
<p class="mt-4 text-xs text-base-content/60 text-center px-4 max-w-xl">
|
||||||
⚠️ This player is provided by a <span class="font-semibold">third‑party service</span>. Ads
|
⚠️ This player is provided by a <span class="font-semibold">third‑party service</span>. Ads
|
||||||
and pop‑ups may appear, and I do not control or endorse them.
|
and pop‑ups may appear, and I do not control or endorse them.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user