Add artist review page and components with basic layout and styling

This commit is contained in:
Esa Kataja
2025-05-04 16:34:23 +03:00
parent 92a192e002
commit 1a20721cbb
12 changed files with 281 additions and 4 deletions
+18 -1
View File
@@ -1 +1,18 @@
@import "tailwindcss"; @import "tailwindcss";
.btn-primary {
@apply bg-blue-600 text-white px-4 py-2 rounded;
}
.btn-secondary {
@apply bg-green-600 text-white px-4 py-2 rounded;
}
.btn-danger {
@apply bg-red-600 text-white px-4 py-2 rounded;
}
.btn-disabled {
@apply bg-gray-400 text-white px-4 py-2 rounded;
}
+19
View File
@@ -0,0 +1,19 @@
<script setup lang="ts">
const { runningOrder, country, artist, title, flag, artistID } = defineProps(['runningOrder', 'country', 'artist', 'title', 'flag', 'artistID'])
</script>
<template>
<NuxtLink :to="`/review/${artistID}`">
<div class="flex gap-4 border border-slate-200 justify-between overflow-clip items-center rounded-2xl">
<h2 class="w-1/4 text-center">{{ runningOrder }}</h2>
<div class="flex flex-col w-1/2">
<h2>{{ country }}</h2>
<p class="flex gap-2 text-sm">
<span class="font-bold">{{ artist }}</span>
<span class="italic">{{ title }}</span>
</p>
</div>
<img class="w-1/4" src="https://placehold.co/100" alt="{{ flag }}">
</div>
</NuxtLink>
</template>
+12
View File
@@ -0,0 +1,12 @@
<template>
<header class="p-4 shadow-md flex justify-between bg-slate-100">
<h1><NuxtLink to="/">Eurovision 2025</NuxtLink></h1>
<nav>
<ul class="flex gap-4">
<li><NuxtLink to="/profile">Profile</NuxtLink></li>
<li><NuxtLink to="/login">Login</NuxtLink></li>
</ul>
</nav>
</header>
</template>
+29
View File
@@ -0,0 +1,29 @@
<script setup lang="ts">
const { category, id } = defineProps(['category', 'id'])
</script>
<template>
<div class="px-6">
<h2>{{ category }}</h2>
<input :id="`slider-${id}`" type="range" min="1" max="100" value="0" class="w-full"/>
<div class="flex justify-between">
<p>0</p>
<p class="sliderSeparator">|</p>
<p>25</p>
<p class="sliderSeparator">|</p>
<p>50</p>
<p class="sliderSeparator">|</p>
<p>75</p>
<p class="sliderSeparator">|</p>
<p>100</p>
</div>
</div>
</template>
<style>
.sliderSeparator {
font-size: 0.8rem;
align-self: center;
}
</style>
+10 -2
View File
@@ -1,5 +1,13 @@
<template> <template>
<div> <title>Eurovision 2025</title>
<Header />
<div class="container mx-auto pt-6 p-4 bg-slate-400">
<slot /> <slot />
</div> </div>
</template> </template>
<style>
body {
background-color: #aaa;
}
</style>
+6
View File
@@ -0,0 +1,6 @@
<template>
<title>Kirjaudu</title>
<div class="container mx-auto">
<slot />
</div>
</template>
+9 -1
View File
@@ -1,5 +1,13 @@
<script setup>
const { data: participants } = await useFetch('/api/participants')
</script>
<template> <template>
<div> <div>
<h1>Index</h1> <div class="grid md:grid-cols-2 gap-4">
<div v-for="participant in participants" :key="participant.id">
<ArtistListItem :runningOrder="participant.runningOrder" :country="participant.country" :artist="participant.artist" :title="participant.title" :flag="participant.flag" :artistID="participant.id" />
</div>
</div>
</div> </div>
</template> </template>
+6
View File
@@ -1,3 +1,9 @@
<script setup lang="ts">
definePageMeta({
layout: 'login'
})
</script>
<template> <template>
<div> <div>
<h1>Login</h1> <h1>Login</h1>
+4
View File
@@ -0,0 +1,4 @@
<template>
<h1>Profile</h1>
</template>
+123
View File
@@ -0,0 +1,123 @@
<script setup lang="ts">
const { id } = useRoute().params
interface Artist {
id: number
year: number
country: string
artist: string
title: string
runningOrder: number
lyricsOriginal: string
lyricsTranslationFI: string
tags: string[]
img: string
flag: string
}
const { data: artist } = await useFetch<Artist>(`/api/artist?id=${id}`)
// State for toggling lyrics visibility
const showOriginalLyrics = ref(false)
const toggleOriginalLyrics = () => {
showOriginalLyrics.value = !showOriginalLyrics.value
}
const showTranslationLyrics = ref(false)
const toggleTranslationLyrics = () => {
showTranslationLyrics.value = !showTranslationLyrics.value
}
const submitReview = () => {
// Get slider values
const songEl = document.getElementById('slider-song') as HTMLInputElement
const showEl = document.getElementById('slider-show') as HTMLInputElement
const costumeEl = document.getElementById('slider-costume') as HTMLInputElement
const songRating = songEl?.value || '0'
const showRating = showEl?.value || '0'
const costumeRating = costumeEl?.value || '0'
// Create review object
const review = {
artistId: id,
ratings: {
song: parseInt(songRating),
show: parseInt(showRating),
costume: parseInt(costumeRating)
},
timestamp: new Date().toISOString()
}
console.log('Submitting review:', review)
// TODO: Send review to API
// await useFetch('/api/reviews', {
// method: 'POST',
// body: review
// })
}
</script>
<template>
<div v-if="artist" class="space-y-4">
<div>
<h1 class="text-2xl font-bold text-center">{{ artist.artist }}</h1>
<p class="text-center italic">{{ artist.title }}</p>
</div>
<img class="w-1/2 mx-auto" :src="artist.img" alt="">
<div>
<h2
@click="toggleOriginalLyrics"
class="cursor-pointer hover:text-blue-600 flex items-center"
>
Sanat
<span class="ml-2 text-sm">
{{ showOriginalLyrics ? '▼' : '►' }}
</span>
</h2>
<pre v-show="showOriginalLyrics" class="lyricsFont transition-all duration-300">{{ artist.lyricsOriginal }}</pre>
</div>
<div v-if="artist.lyricsTranslationFI">
<h2
@click="toggleTranslationLyrics"
class="cursor-pointer hover:text-blue-600 flex items-center"
>
Käännös
<span class="ml-2 text-sm">
{{ showTranslationLyrics ? '▼' : '►' }}
</span>
</h2>
<pre v-show="showTranslationLyrics" class="lyricsFont transition-all duration-300">{{ artist.lyricsTranslationFI }}</pre>
</div>
<ul>
<li class="tag" v-for="tag in artist.tags" :key="tag">{{ tag }}</li>
</ul>
<form @submit.prevent="submitReview">
<ReviewSlider id="song" category="Kappale"/>
<ReviewSlider id="show" category="Lava show"/>
<ReviewSlider id="costume" category="Asuste"/>
<button type="submit" class="btn-primary">Arvostele</button>
</form>
</div>
<div v-else>
<h1>Artist not found</h1>
</div>
</template>
<style>
.tag {
display: inline-block;
padding: 2px 6px;
background-color: #ccc;
margin: 2px;
border-radius: 6px;
font-size: 0.8rem;
}
.lyricsFont {
font-family: Arial, Helvetica, sans-serif;
font-size: 0.8rem;
text-align: center;
}
</style>
+15
View File
@@ -0,0 +1,15 @@
export default defineEventHandler((event) => {
return {
id: 1,
year: 2025,
country: "Suomi",
artist: "Käärijä",
title: "Cha Cha Cha",
runningOrder: 1,
lyricsOriginal: "[Säkeistö 1]\nRankka viikko ja paljon pitkii päiviä takan\nMielenkiintona piña colada ja rata\nIlta on vielä nuori ja aikaa kumota\nTää jäinen ulkokuori on aika tuhota\n\n[Kertosäe]\nPidän kaksin käsin kiinni juomista niinku\n(Cha, cha, cha, cha, cha, cha, cha)\nEi, en mieti huomista ku tartun tuopista niinku\n(Cha, cha, cha, cha, cha, cha, cha)\nEi, haluun olla sekasin ja vapaa huolista niinku\n(Cha, cha, cha, cha, cha, cha, cha)\nEi, ja mä jatkan kunnes en enää pysy tuolissa niinku\n\n[Säkeistö 2]\nMuutama piña colada on jo takana\nSilti mul on vielä naamataulu vakava (Yeah, yeah, ye, ye, yeah)\nIlta on vielä nuori ja aikaa kumota\nTää jäinen ulkokuori on aika tuhota\nParketti kutsuu mua ku en oo enää lukossa\nNiinku cha-cha-cha, mä oon tulossa\n\n[Kertosäe]\nPidän kaksin käsin kiinni juomista niinku\n(Cha, cha, cha, cha, cha, cha, cha)\nEi, en mieti huomista ku tartun tuopista niinku\n(Cha, cha, cha, cha, cha, cha, cha)\nEi, haluun olla sekasin ja vapaa huolista niinku\n(Cha, cha, cha, cha, cha, cha, cha)\nEi, ja mä jatkan kunnes en enää pysy tuolissa niinku vou\nSee upcoming rock shows\nGet tickets for your favorite artists\nYou might also like\n\u200bmietin sua pahalla\n\u200bpehmoaino\nLet 3 - Mama ŠČ! (English Translation)\nGenius English Translations\nViimeinen tanssi\nBEHM & Olavi Uusivirta\n[Jälkikertosäe]\nNyt lähden tanssimaan\nNiinku cha-cha-cha\nEnkä pelkääkään tätä maailmaa\nNiinku cha-cha-cha\nKun mä kaadan päälleni samppanjaa\n\n[Väliosa]\n(Cha) Cha-cha-cha\nToinen silmä jo karsastaa\nJa puhe sammaltaa\nKu tää toinen puoli must vallan saa\n(Cha) Cha-cha-cha\nEn oo arkena tää mies laisinkaan\nEn oo mut tänään oon se mies\nTänään oon se mies (Ei)\n\n[Jälkikertosäe]\nNyt lähden tanssimaan\nNiinku cha-cha-cha\nEnkä pelkääkään tätä maailmaa\nNiinku cha-cha-cha\nKun mä kaadan päälleni samppanjaa\nNiinku cha-cha-cha\nCha, cha, cha, cha, cha, cha, cha, aa-aah\nNiinku cha-cha-cha\nCha, cha, cha, cha, cha, cha, cha\n[Outro]\nCha, cha, cha, cha, cha, cha, cha",
lyricsTranslationFI: null,
tags: ["Juhlat", "Alkoholi", "Sosiaalinen paine"],
img: "https://placehold.co/150",
flag: "fin"
}
})
+30
View File
@@ -0,0 +1,30 @@
export default defineEventHandler((event) => {
return [
{
id: 1,
year: 2025,
country: "Suomi",
artist: "Käärijä",
title: "Cha Cha Cha",
runningOrder: 1,
lyricsOriginal: "Original lyrics",
lyricsTranslationFI: "Käännös suomeksi",
tags: [],
img: "https://via.placeholder.com/150",
flag: "fin"
},
{
id: 2,
year: 2025,
country: "Ruotsi",
artist: "Loreen",
title: "Loreen",
runningOrder: 2,
lyricsOriginal: "Original lyrics",
lyricsTranslationFI: "Käännös suomeksi",
tags: [],
img: "https://via.placeholder.com/150",
flag: "swe"
},
]
})