movie-night-web/app/components/panels/movie-details.vue

130 lines
2.7 KiB
Vue
Raw Normal View History

2026-02-16 19:12:00 -06:00
<script lang="ts" setup>
import type {Movie} from "~/types/movie";
import type {MovieCriticScore} from "~/types/movie-critic-score";
import posterPlaceholder from "~/assets/img/poster-placeholder.svg";
2026-02-16 19:12:00 -06:00
const props = defineProps<{
2026-02-16 19:12:00 -06:00
selectedMovie: Movie;
}>();
const emit = defineEmits(['remove-movie']);
const criticScores = computed(() => {
const scores: MovieCriticScore[] = []
props.selectedMovie.critic_scores.map((score: MovieCriticScore) => {
scores.push({Value: score.Value, Source: score.Source})
})
return scores
})
2026-02-16 19:12:00 -06:00
</script>
<template>
<div class="movie-details">
<div class="movie-details-header">
<img :alt="selectedMovie.title"
:src="selectedMovie.poster"
class="movie-poster"
@error="(e) => (e.target as HTMLImageElement).src = posterPlaceholder"
/>
<h2 class="movie-title">{{ selectedMovie.title }} ({{ selectedMovie.year }})</h2>
</div>
<dl class="movie-details-list">
<div class="movie-detail">
<dt>Plot</dt>
<dd>{{ selectedMovie.plot }}</dd>
</div>
<div class="movie-detail">
<dt>Genre</dt>
<dd>{{ selectedMovie.genre }}</dd>
</div>
<div class="movie-detail">
<dt>Actors</dt>
<dd>{{ selectedMovie.actors }}</dd>
</div>
<div class="movie-detail">
<dt>Directed By</dt>
<dd>{{ selectedMovie.director }}</dd>
</div>
<div class="movie-detail">
<dt class="detail-title">Critic Scores:</dt>
<div v-for="score in criticScores" v-if="criticScores && criticScores.length > 0" :key="score.Source">
<dd class="critic-score-source">{{ score.Source }}</dd>
<dd>{{ score.Value }}</dd>
</div>
<dd v-else>No critic scores available</dd>
</div>
</dl>
<button type="button" @click="emit('remove-movie', selectedMovie.id)">Remove From List</button>
2026-02-16 19:12:00 -06:00
</div>
</template>
<style scoped>
dt {
font-weight: bold;
}
.critic-score-source {
}
.movie-detail {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
2026-02-16 19:12:00 -06:00
.movie-details {
display: flex;
flex-direction: column;
padding: 2rem;
justify-content: center;
max-width: 40rem;
margin: 0 auto;
}
.movie-details img {
max-width: 20em;
max-height: 25em;
margin: 2rem auto;
2026-02-16 19:12:00 -06:00
}
.movie-details-header {
margin: 2em 0;
}
.movie-details-list {
display: flex;
flex-direction: column;
gap: 1rem;
margin: 2em 0;
}
2026-02-16 19:12:00 -06:00
.movie-poster {
width: 100%;
}
.movie-title {
text-align: center;
}
@media (max-width: 1300px) {
.movie-plot {
margin: unset;
}
}
2026-02-16 19:12:00 -06:00
@media (max-width: 767px) {
.movie-details {
align-items: center;
}
.movie-details img {
max-height: 15em;
max-width: 10em;
2026-02-16 19:12:00 -06:00
}
}
</style>