mirror of
				https://github.com/mmahdium/TBW.git
				synced 2025-11-03 20:20:49 +01:00 
			
		
		
		
	Added Rating ring to the media card
This commit is contained in:
		@@ -3,7 +3,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <router-link
 | 
			
		||||
    to="/add"
 | 
			
		||||
    class="card relative w-full h-full flex items-center justify-center aspect-2/3 bg-white/40 backdrop-blur-md border-2 border-dashed border-gray-300 rounded-lg shadow-sm hover:shadow-md hover:border-gray-400 transition-all duration-300"
 | 
			
		||||
    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"
 | 
			
		||||
    v-motion-fade-visible-once
 | 
			
		||||
  >
 | 
			
		||||
    <!-- Plus icon -->
 | 
			
		||||
 
 | 
			
		||||
@@ -23,47 +23,107 @@ const alreadyAdded = computed(() => store.mediaList.some((media) => media.Id ===
 | 
			
		||||
    class="card relative w-full h-full overflow-hidden bg-white/70 backdrop-blur-md border border-gray-200/60 shadow-md hover:shadow-xl transition-all duration-300"
 | 
			
		||||
    v-motion-fade-visible-once
 | 
			
		||||
  >
 | 
			
		||||
    <!-- Poster -->
 | 
			
		||||
    <router-link
 | 
			
		||||
      :to="{ name: 'details', params: { type: props.media.MediaType, id: props.media.Id } }"
 | 
			
		||||
    >
 | 
			
		||||
      <ImageWithFallback
 | 
			
		||||
        :src="props.media.PosterPath"
 | 
			
		||||
        :alt="props.media.Title"
 | 
			
		||||
        size="w300"
 | 
			
		||||
        class="aspect-2/3 object-cover w-full h-full transform transition-transform duration-500 hover:scale-105"
 | 
			
		||||
      />
 | 
			
		||||
    </router-link>
 | 
			
		||||
 | 
			
		||||
    <!-- Body -->
 | 
			
		||||
    <div class="card-body p-4 flex flex-col">
 | 
			
		||||
    <!-- Poster wrapper with fixed aspect -->
 | 
			
		||||
    <div class="relative w-full">
 | 
			
		||||
      <router-link
 | 
			
		||||
        :to="{ name: 'details', params: { type: props.media.MediaType, id: props.media.Id } }"
 | 
			
		||||
        class="block w-full aspect-2/3 overflow-hidden bg-gray-100"
 | 
			
		||||
      >
 | 
			
		||||
        <ImageWithFallback
 | 
			
		||||
          :src="props.media.PosterPath"
 | 
			
		||||
          :alt="props.media.Title"
 | 
			
		||||
          size="w300"
 | 
			
		||||
          class="w-full h-full object-cover transform transition-transform duration-500 hover:scale-105"
 | 
			
		||||
        />
 | 
			
		||||
      </router-link>
 | 
			
		||||
 | 
			
		||||
      <!-- Radial progress placed on the right edge, centered on the seam between poster and body -->
 | 
			
		||||
      <div class="absolute left-3 bottom-0 z-20 translate-y-1/2" aria-hidden="true">
 | 
			
		||||
        <div
 | 
			
		||||
          class="radial-progress bg-primary text-primary-content border-primary border-4 font-bold flex items-center justify-center"
 | 
			
		||||
          :style="{
 | 
			
		||||
            '--value': props.media.VoteAverage * 10,
 | 
			
		||||
            '--size': '2rem',
 | 
			
		||||
            '--thickness': '3px',
 | 
			
		||||
          }"
 | 
			
		||||
          :aria-valuenow="props.media.VoteAverage"
 | 
			
		||||
          role="progressbar"
 | 
			
		||||
        >
 | 
			
		||||
          <span class="flex items-baseline text-[0.7em]">
 | 
			
		||||
            {{ props.media.VoteAverage === 0 ? '?' : (props.media.VoteAverage * 10).toFixed(0) }}
 | 
			
		||||
            <span class="text-[0.5em] relative -top-1 ml-0.5">%</span>
 | 
			
		||||
          </span>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <!-- Body: add top padding to ensure title sits below the ring seam -->
 | 
			
		||||
    <div class="card-body p-4 flex flex-col pt-6">
 | 
			
		||||
      <router-link
 | 
			
		||||
        :to="{ name: 'details', params: { type: props.media.MediaType, id: props.media.Id } }"
 | 
			
		||||
        class="block"
 | 
			
		||||
      >
 | 
			
		||||
        <h2
 | 
			
		||||
          class="card-title text-base font-semibold bg-linear-to-r from-gray-700 to-gray-500 bg-clip-text text-transparent"
 | 
			
		||||
          class="card-title text-base font-semibold bg-linear-to-r from-gray-700 to-gray-500 bg-clip-text text-transparent wrap-break-word"
 | 
			
		||||
        >
 | 
			
		||||
          {{ props.media.Title }}
 | 
			
		||||
        </h2>
 | 
			
		||||
        <p class="text-sm text-gray-400">{{ props.media.ReleaseDate.slice(0, 4) }}</p>
 | 
			
		||||
        <time
 | 
			
		||||
          class="text-sm text-gray-400"
 | 
			
		||||
          :datetime="new Date(props.media.ReleaseDate).toISOString()"
 | 
			
		||||
        >
 | 
			
		||||
          {{
 | 
			
		||||
            new Intl.DateTimeFormat('default', {
 | 
			
		||||
              year: 'numeric',
 | 
			
		||||
              month: 'long',
 | 
			
		||||
              day: 'numeric',
 | 
			
		||||
            }).format(new Date(props.media.ReleaseDate))
 | 
			
		||||
          }}
 | 
			
		||||
        </time>
 | 
			
		||||
      </router-link>
 | 
			
		||||
 | 
			
		||||
      <div class="card-actions justify-end mt-auto">
 | 
			
		||||
        <button
 | 
			
		||||
          v-motion-fade-visible-once
 | 
			
		||||
          v-if="!alreadyAdded"
 | 
			
		||||
          class="btn btn-sm px-4 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"
 | 
			
		||||
          @click="$emit('add-media', props.media)"
 | 
			
		||||
          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"
 | 
			
		||||
          @click="emit('add-media', props.media)"
 | 
			
		||||
        >
 | 
			
		||||
          Add
 | 
			
		||||
          <svg
 | 
			
		||||
            xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
            fill="none"
 | 
			
		||||
            viewBox="0 0 24 24"
 | 
			
		||||
            stroke-width="1.5"
 | 
			
		||||
            stroke="currentColor"
 | 
			
		||||
            class="size-6"
 | 
			
		||||
          >
 | 
			
		||||
            <path
 | 
			
		||||
              stroke-linecap="round"
 | 
			
		||||
              stroke-linejoin="round"
 | 
			
		||||
              d="M17.593 3.322c1.1.128 1.907 1.077 1.907 2.185V21L12 17.25 4.5 21V5.507c0-1.108.806-2.057 1.907-2.185a48.507 48.507 0 0 1 11.186 0Z"
 | 
			
		||||
            />
 | 
			
		||||
          </svg>
 | 
			
		||||
        </button>
 | 
			
		||||
        <button
 | 
			
		||||
          v-motion-fade-visible-once
 | 
			
		||||
          v-else
 | 
			
		||||
          class="btn btn-sm px-4 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"
 | 
			
		||||
          @click="$emit('remove-media', props.media.Id)"
 | 
			
		||||
          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"
 | 
			
		||||
          @click="emit('remove-media', props.media.Id)"
 | 
			
		||||
        >
 | 
			
		||||
          Remove
 | 
			
		||||
          <svg
 | 
			
		||||
            xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
            fill="none"
 | 
			
		||||
            viewBox="0 0 24 24"
 | 
			
		||||
            stroke-width="1.5"
 | 
			
		||||
            stroke="currentColor"
 | 
			
		||||
            class="size-6"
 | 
			
		||||
          >
 | 
			
		||||
            <path
 | 
			
		||||
              stroke-linecap="round"
 | 
			
		||||
              stroke-linejoin="round"
 | 
			
		||||
              d="m3 3 1.664 1.664M21 21l-1.5-1.5m-5.485-1.242L12 17.25 4.5 21V8.742m.164-4.078a2.15 2.15 0 0 1 1.743-1.342 48.507 48.507 0 0 1 11.186 0c1.1.128 1.907 1.077 1.907 2.185V19.5M4.664 4.664 19.5 19.5"
 | 
			
		||||
            />
 | 
			
		||||
          </svg>
 | 
			
		||||
        </button>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -32,9 +32,13 @@ const emit = defineEmits<{
 | 
			
		||||
    <ul
 | 
			
		||||
      v-auto-animate
 | 
			
		||||
      v-else
 | 
			
		||||
      class="grid gap-4 grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5"
 | 
			
		||||
      class="grid gap-4 grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6"
 | 
			
		||||
    >
 | 
			
		||||
      <li v-for="media in props.medias" :key="media.Id" v-auto-animate>
 | 
			
		||||
      <li
 | 
			
		||||
        v-for="media in props.medias.filter((media) => media.PosterPath)"
 | 
			
		||||
        :key="media.Id"
 | 
			
		||||
        v-auto-animate
 | 
			
		||||
      >
 | 
			
		||||
        <MediaCard
 | 
			
		||||
          :media="media"
 | 
			
		||||
          @add-media="$emit('add-media', $event)"
 | 
			
		||||
 
 | 
			
		||||
@@ -15,4 +15,3 @@ app.use(autoAnimatePlugin)
 | 
			
		||||
app.use(MotionPlugin)
 | 
			
		||||
 | 
			
		||||
app.mount('#app')
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user