refactor: improve review page with TypeScript interfaces and error handling

This commit is contained in:
Esa Kataja
2025-05-13 20:22:49 +03:00
parent 5d05175bc4
commit 3c8c2f76d3
+111 -70
View File
@@ -9,44 +9,49 @@ interface Review {
score_song: number score_song: number
score_show: number score_show: number
score_costume: number score_costume: number
review_text: string text_review?: string
created_at: string created_at?: string
updated_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 config = useRuntimeConfig()
const apiBase = config.public.apiBase const apiBase = config.public.apiBase
const route = useRoute() const route = useRoute()
const { id } = route.params const { id } = route.params
// Initialize reactive data // Reactive state
const artist = ref(null) const artist = ref<Artist | null>(null)
const review = ref<Review>({}) const user = ref<User | null>(null)
const showOriginalLyrics = ref(false) const review = ref<Review | null>(null)
const showTranslationLyrics = ref(false)
// Form data // Form state with default values
const song = ref(50) const song = ref(50)
const show = ref(50) const show = ref(50)
const costume = ref(50) const costume = ref(50)
const textReview = ref('') const textReview = ref('')
const isSubmitting = ref(false)
// Get user from localStorage // UI state
const user = ref(null) const showOriginalLyrics = ref(false)
const showTranslationLyrics = ref(false)
// Initialize user data from localStorage on client side only // Toggle functions for lyrics display
onMounted(() => {
if (process.client) {
const userData = localStorage.getItem('user')
if (userData) {
user.value = JSON.parse(userData)
}
}
})
// Functions to toggle lyrics visibility
function toggleOriginalLyrics() { function toggleOriginalLyrics() {
showOriginalLyrics.value = !showOriginalLyrics.value showOriginalLyrics.value = !showOriginalLyrics.value
} }
@@ -55,63 +60,99 @@ function toggleTranslationLyrics() {
showTranslationLyrics.value = !showTranslationLyrics.value showTranslationLyrics.value = !showTranslationLyrics.value
} }
// Form submission function // Load user data from localStorage
function submitReview() { function loadUserData(): User | null {
const payload = { if (!process.client) return null
song_id: id,
user_id: user.value?.id, const userData = localStorage.getItem('user')
score_song: song.value, return userData ? JSON.parse(userData) : null
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),
})
} }
// Fetch artist data based on ID // Fetch artist data
onMounted(async () => { async function fetchArtist() {
try { try {
// Fetch song data
const response = await fetch(`${apiBase}/songs/${id}`) const response = await fetch(`${apiBase}/songs/${id}`)
if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`)
artist.value = await response.json() artist.value = await response.json()
} catch (error) { } catch (error) {
console.error('Error fetching artist data:', error) console.error('Error fetching artist data:', error)
} }
}
// Get user from localStorage and then fetch reviews if user exists
if (process.client) { // Fetch user's existing review for this song
const userData = localStorage.getItem('user') async function fetchUserReview(userId: number) {
if (userData) { try {
user.value = JSON.parse(userData) const response = await fetch(`${apiBase}/reviews/?song_id=${id}&user_id=${userId}`)
if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`)
// Now fetch reviews with the user ID
try { const reviewData = await response.json()
const response = await fetch(`${apiBase}/reviews/?song_id=${id}&user_id=${user.value.id}`) review.value = reviewData
review.value = await response.json()
// Pre-fill form with existing review data
// If there's existing review data, populate the form if (reviewData) {
if (review.value) { song.value = reviewData.score_song || 50
song.value = review.value.score_song || 0 show.value = reviewData.score_show || 50
show.value = review.value.score_show || 0 costume.value = reviewData.score_costume || 50
costume.value = review.value.score_costume || 0 textReview.value = reviewData.text_review || ''
textReview.value = review.value.text_review || ''
}
} catch (error) {
console.error('Error fetching review data:', error)
}
} }
} 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)
} }
}) })
</script> </script>
<template> <template>