iagofp's picture
DAO pattern
bf652e3
<template>
<v-col cols="12" md="4">
<!-- History -->
<v-card class="panel-card" rounded="xl" elevation="0">
<div class="panel-header px-4 pt-4 pb-2">
<div class="panel-label">
<v-icon size="14" color="amber-darken-1" class="mr-1">mdi-filmstrip</v-icon>
Visto recientemente
</div>
<div class="header-actions">
<v-btn
v-if="history.length"
size="x-small"
variant="text"
color="primary"
class="mr-1"
@click="emit('show-all-history')"
>
Ver todo
</v-btn>
<v-btn
size="x-small"
variant="tonal"
color="error"
icon
:disabled="!history.length || clearLoading"
title="Borrar historial"
@click="emit('clear-history')"
>
<v-icon size="15">mdi-delete-sweep-outline</v-icon>
</v-btn>
</div>
</div>
<v-card-text class="pt-1 pb-3">
<template v-if="history.length">
<div
v-for="item in history.slice(0, 3)"
:key="item.id"
class="history-item"
>
<span class="history-emoji">{{ emotionInfoBySpanish(item.emotion).emoji }}</span>
<div class="history-body">
<div class="history-movie">{{ item.title || item.movie_id }}</div>
<div class="history-meta">
<span>{{ item.emotion || "neutral" }}</span>
<span v-if="item.user_rating != null" class="history-rating">
{{ item.user_rating }}
</span>
</div>
</div>
</div>
<div v-if="history.length > 3" class="more-hint" @click="emit('show-all-history')">
+{{ history.length - 3 }} más
</div>
</template>
<div v-else class="empty-history">
<v-icon size="26" color="blue-grey" class="mb-2">mdi-movie-open-outline</v-icon>
<p>Aún no has marcado ninguna película como vista.</p>
</div>
</v-card-text>
</v-card>
</v-col>
</template>
<script setup>
import { emotionInfoBySpanish } from "../constants/emotions";
defineProps({
history: { type: Array, default: () => [] },
clearLoading: { type: Boolean, default: false },
});
const emit = defineEmits(["clear-history", "show-all-history"]);
</script>
<style scoped>
.panel-card {
border: 1.5px solid var(--vs-border);
background: var(--vs-panel);
backdrop-filter: blur(var(--vs-glass-blur)) saturate(120%);
-webkit-backdrop-filter: blur(var(--vs-glass-blur)) saturate(120%);
box-shadow: var(--vs-card-shadow);
}
.panel-header {
display: flex;
align-items: center;
justify-content: space-between;
}
.header-actions {
display: flex;
align-items: center;
}
.panel-label {
font-size: 0.72rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--vs-muted);
display: flex;
align-items: center;
}
/* History */
.history-item {
display: flex;
align-items: flex-start;
gap: 10px;
padding: 8px 10px;
border-radius: 10px;
margin-bottom: 4px;
background: var(--vs-movie-bg);
border: 1px solid var(--vs-border);
transition: background 0.18s ease;
}
.history-item:hover { background: var(--vs-movie-hover); }
.history-emoji { font-size: 1.1rem; line-height: 1.4; flex-shrink: 0; }
.history-body { min-width: 0; }
.history-movie {
color: var(--vs-text);
font-weight: 600;
font-size: 0.88rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.history-meta {
display: flex;
align-items: center;
gap: 8px;
font-size: 0.76rem;
color: var(--vs-muted);
margin-top: 1px;
}
.history-rating { color: #F59E0B; font-weight: 600; }
.more-hint {
font-size: 0.76rem;
color: var(--vs-muted);
text-align: center;
padding: 6px 0 2px;
cursor: pointer;
transition: color 0.15s;
}
.more-hint:hover { color: var(--vs-text); }
.empty-history {
display: flex;
flex-direction: column;
align-items: center;
padding: 20px 0;
text-align: center;
}
.empty-history p {
margin: 0;
font-size: 0.82rem;
color: var(--vs-muted);
max-width: 22ch;
line-height: 1.5;
}
</style>