From 3c8c2f76d30632638b0f9f8f33844ce38f036a74 Mon Sep 17 00:00:00 2001 From: Esa Kataja Date: Tue, 13 May 2025 20:22:49 +0300 Subject: [PATCH] refactor: improve review page with TypeScript interfaces and error handling --- pages/review/[id].vue | 181 ++++++++++++++++++++++++++---------------- 1 file changed, 111 insertions(+), 70 deletions(-) diff --git a/pages/review/[id].vue b/pages/review/[id].vue index 9a65b0e..db7808c 100644 --- a/pages/review/[id].vue +++ b/pages/review/[id].vue @@ -9,44 +9,49 @@ interface Review { score_song: number score_show: number score_costume: number - review_text: string - created_at: string - updated_at: string + text_review?: string + created_at?: string + updated_at?: string } +interface Artist { + id: number + artist: string + title: string + img: string + lyrics_original: string + lyrics_translation_fi?: string + tags: string[] +} + +interface User { + id: number + [key: string]: any +} + +// Config and route setup const config = useRuntimeConfig() const apiBase = config.public.apiBase - const route = useRoute() const { id } = route.params -// Initialize reactive data -const artist = ref(null) -const review = ref({}) -const showOriginalLyrics = ref(false) -const showTranslationLyrics = ref(false) +// Reactive state +const artist = ref(null) +const user = ref(null) +const review = ref(null) -// Form data +// Form state with default values const song = ref(50) const show = ref(50) const costume = ref(50) const textReview = ref('') +const isSubmitting = ref(false) -// Get user from localStorage -const user = ref(null) +// UI state +const showOriginalLyrics = ref(false) +const showTranslationLyrics = ref(false) -// Initialize user data from localStorage on client side only -onMounted(() => { - if (process.client) { - const userData = localStorage.getItem('user') - if (userData) { - user.value = JSON.parse(userData) - } - } -}) - - -// Functions to toggle lyrics visibility +// Toggle functions for lyrics display function toggleOriginalLyrics() { showOriginalLyrics.value = !showOriginalLyrics.value } @@ -55,63 +60,99 @@ function toggleTranslationLyrics() { showTranslationLyrics.value = !showTranslationLyrics.value } -// Form submission function -function submitReview() { - const payload = { - song_id: id, - user_id: user.value?.id, - score_song: song.value, - score_show: show.value, - score_costume: costume.value, - text_review: text_review.value - } - - // Implement your review submission logic here - console.log('Review submitted with data:', payload) - const response = fetch(`${apiBase}/reviews/`, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(payload), - }) +// Load user data from localStorage +function loadUserData(): User | null { + if (!process.client) return null + + const userData = localStorage.getItem('user') + return userData ? JSON.parse(userData) : null } -// Fetch artist data based on ID -onMounted(async () => { +// Fetch artist data +async function fetchArtist() { try { - // Fetch song data const response = await fetch(`${apiBase}/songs/${id}`) + if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`) + artist.value = await response.json() } catch (error) { console.error('Error fetching artist data:', error) } - - // Get user from localStorage and then fetch reviews if user exists - if (process.client) { - const userData = localStorage.getItem('user') - if (userData) { - user.value = JSON.parse(userData) - - // Now fetch reviews with the user ID - try { - const response = await fetch(`${apiBase}/reviews/?song_id=${id}&user_id=${user.value.id}`) - review.value = await response.json() - - // If there's existing review data, populate the form - if (review.value) { - song.value = review.value.score_song || 0 - show.value = review.value.score_show || 0 - costume.value = review.value.score_costume || 0 - textReview.value = review.value.text_review || '' - } - } catch (error) { - console.error('Error fetching review data:', error) - } +} + +// Fetch user's existing review for this song +async function fetchUserReview(userId: number) { + try { + const response = await fetch(`${apiBase}/reviews/?song_id=${id}&user_id=${userId}`) + if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`) + + const reviewData = await response.json() + review.value = reviewData + + // Pre-fill form with existing review data + if (reviewData) { + song.value = reviewData.score_song || 50 + show.value = reviewData.score_show || 50 + costume.value = reviewData.score_costume || 50 + textReview.value = reviewData.text_review || '' } + } catch (error) { + console.error('Error fetching review data:', error) + } +} + +// Submit review to the API +async function submitReview() { + if (!user.value?.id) { + console.error('User not authenticated') + return + } + + isSubmitting.value = true + + const payload: Review = { + song_id: Number(id), + user_id: user.value.id, + score_song: song.value, + score_show: show.value, + score_costume: costume.value, + text_review: textReview.value + } + + try { + const response = await fetch(`${apiBase}/reviews/`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(payload), + }) + + if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`) + + console.log('Review submitted successfully') + // You could add a success notification or redirect here + } catch (error) { + console.error('Error submitting review:', error) + // You could add an error notification here + } finally { + isSubmitting.value = false + } +} + +// Initialize data on component mount +onMounted(async () => { + // Get user from localStorage + user.value = loadUserData() + + // Fetch artist data + await fetchArtist() + + // If user is logged in, fetch their review for this song + if (user.value?.id) { + await fetchUserReview(user.value.id) } }) -