diff --git a/movie-group-8/src/components/MovieList.vue b/movie-group-8/src/components/MovieList.vue index aff845ac398f5703e6e5caf3eb56c0ffabfcb08b..78b0a9e2d4e619722113da6978d27ccaae015ff9 100644 --- a/movie-group-8/src/components/MovieList.vue +++ b/movie-group-8/src/components/MovieList.vue @@ -28,7 +28,6 @@ </template> <script setup> -import { defineProps } from 'vue' const props = defineProps({ movies: { diff --git a/movie-group-8/src/composables/useReviews.js b/movie-group-8/src/composables/useReviews.js new file mode 100644 index 0000000000000000000000000000000000000000..05e0a98cdb1328921771159816e9905ac4b3e911 --- /dev/null +++ b/movie-group-8/src/composables/useReviews.js @@ -0,0 +1,29 @@ +// src/composables/useReviews.js +import { doc, getDoc, setDoc, collectionGroup, query, where, getDocs } from 'firebase/firestore' +import { auth, db } from '@/firebase.js' + +export async function getUserReview(movieId) { + const user = auth.currentUser + if (!user) throw new Error('User not authenticated') + + const ref = doc(db, 'users', user.uid, 'reviews', movieId) + const snap = await getDoc(ref) + return snap.exists() ? snap.data() : null +} + +export async function submitReview({ movieId, rating, text }) { + const user = auth.currentUser + if (!user) throw new Error('User not authenticated') + + const ref = doc(db, 'users', user.uid, 'reviews', movieId) + await setDoc(ref, { movieId, rating, text }, { merge: true }) +} + +export async function getAllReviews(movieId) { + const q = query( + collectionGroup(db, 'reviews'), + where('movieId', '==', movieId) + ) + const snaps = await getDocs(q) + return snaps.docs.map(d => ({ id: d.id, ...d.data() })) +} diff --git a/movie-group-8/src/composables/useWatchlist.js b/movie-group-8/src/composables/useWatchlist.js index 7de03593946235c36f67c8966ec81774b616c01e..c63ca445acc2ddda4820469fdaeb8cee8ff8b5d3 100644 --- a/movie-group-8/src/composables/useWatchlist.js +++ b/movie-group-8/src/composables/useWatchlist.js @@ -1,11 +1,10 @@ -import { getFirestore, doc, setDoc } from 'firebase/firestore' -import { getAuth } from 'firebase/auth' +import { doc, setDoc } from 'firebase/firestore' +import { auth, db } from '@/firebase.js' export const addToWatchlist = async (movie) => { - const user = getAuth().currentUser + const user = auth.currentUser if (!user) return alert('You need to log in.') - const db = getFirestore() const movieRef = doc(db, 'users', user.uid, 'watchlist', String(movie.id)) await setDoc(movieRef, { title: movie.title, diff --git a/movie-group-8/src/firebase.js b/movie-group-8/src/firebase.js new file mode 100644 index 0000000000000000000000000000000000000000..46b814efeb1edf7ccb8b1467ae6ea10211ee0d36 --- /dev/null +++ b/movie-group-8/src/firebase.js @@ -0,0 +1,20 @@ +import { initializeApp } from 'firebase/app' +import { getAuth } from 'firebase/auth' +import { getFirestore } from 'firebase/firestore' + +// Replace with your actual config (you can move the object here or import it) +const firebaseConfig = { + apiKey: "AIzaSyDiAEv_XsHelEiuvJsPDOEBZRcsr4Mg4R4", + authDomain: "movie-group-8.firebaseapp.com", + projectId: "movie-group-8", + storageBucket: "movie-group-8.firebasestorage.app", + messagingSenderId: "767837078763", + appId: "1:767837078763:web:e64ea7235d421e46852aae" + }; + +// Initialize (idempotent if called twice) +const app = initializeApp(firebaseConfig) + +// Export the singleton instances +export const auth = getAuth(app) +export const db = getFirestore(app) \ No newline at end of file diff --git a/movie-group-8/src/main.js b/movie-group-8/src/main.js index ef7fb64cf3f6662784e1f28dd2aa8a99f48ddb0d..30fe276854aea0d9445bf901ad30693350a32187 100644 --- a/movie-group-8/src/main.js +++ b/movie-group-8/src/main.js @@ -1,22 +1,13 @@ +// main.js import { createApp } from 'vue' -import './style.css' -import App from './App.vue' -import router from './router' -import { initializeApp } from "firebase/app"; - -// Your web app's Firebase configuration -const firebaseConfig = { - apiKey: "AIzaSyDiAEv_XsHelEiuvJsPDOEBZRcsr4Mg4R4", - authDomain: "movie-group-8.firebaseapp.com", - projectId: "movie-group-8", - storageBucket: "movie-group-8.firebasestorage.app", - messagingSenderId: "767837078763", - appId: "1:767837078763:web:e64ea7235d421e46852aae" -}; +import App from './App.vue' +import router from './router' -initializeApp(firebaseConfig); +// Ensure the Firebase singleton is initialized +import '@/firebase.js' -const app = createApp(App); -app.use(router); -app.mount("#app"); +import './style.css' +createApp(App) + .use(router) + .mount('#app') \ No newline at end of file diff --git a/movie-group-8/src/views/ReviewPage.vue b/movie-group-8/src/views/ReviewPage.vue index 3f130f965fbd2ad7c5d5d09b54f88f8e6889bcec..7ea921a2631c922299401a5883b07c1a71d559f7 100644 --- a/movie-group-8/src/views/ReviewPage.vue +++ b/movie-group-8/src/views/ReviewPage.vue @@ -34,15 +34,6 @@ <span class="rating-value">{{ userRating }} / 5</span> </div> - <!-- Favourite Toggle --> - <button - class="favourite-btn" - :class="{ fav: isFavourite }" - @click="toggleFavourite" - > - {{ isFavourite ? '★ Favourite' : '☆ Add to Favourites' }} - </button> - <!-- Review Text --> <textarea v-model="reviewText" @@ -52,7 +43,7 @@ ></textarea> <!-- Submit --> - <button class="submit-btn" @click="submitReview"> + <button class="submit-btn" @click="handleSubmit"> Submit Review </button> </div> @@ -62,22 +53,22 @@ <script setup> import { ref, onMounted } from 'vue' import { useRoute, useRouter } from 'vue-router' + import { getUserReview, submitReview } from '@/composables/useReviews.js' const route = useRoute() const router = useRouter() // State - const movie = ref(null) - const loading = ref(true) - const error = ref('') - const userRating = ref(0) - const isFavourite = ref(false) - const reviewText = ref('') + const movie = ref(null) + const loading = ref(true) + const error = ref('') + const userRating = ref(0) + const reviewText = ref('') // Fetch movie details async function fetchMovie() { try { - const id = route.params.id + const id = route.params.id const res = await fetch( `${import.meta.env.VITE_TMDB_BASE}/movie/${id}?api_key=${import.meta.env.VITE_TMDB_API_KEY}` ) @@ -85,36 +76,47 @@ movie.value = await res.json() } catch (err) { error.value = err.message - } finally { - loading.value = false } } - // Rating handlers - function setRating(star) { - userRating.value = star + // Load existing user review + async function loadExistingReview() { + try { + const existing = await getUserReview(route.params.id) + if (existing) { + userRating.value = existing.rating || 0 + reviewText.value = existing.text || '' + } + } catch (err) { + console.error('Error loading review:', err) + } } - // Favourite toggle - function toggleFavourite() { - isFavourite.value = !isFavourite.value + // Rating handler + function setRating(star) { + userRating.value = star } - // Submit handler (stub — wire up to Firestore or your backend) - function submitReview() { - console.log({ - movieId: route.params.id, - rating: userRating.value, - favourite: isFavourite.value, - review: reviewText.value, - }) - // e.g. use Firestore: - // const db = getFirestore(); - // setDoc(doc(db, 'reviews', `${user.uid}_${movieId}`), { ... }) - router.back() + // Submit handler + async function handleSubmit() { + try { + await submitReview({ + movieId: route.params.id, + rating: userRating.value, + text: reviewText.value + }) + router.back() + } catch (err) { + console.error('Error submitting review:', err) + error.value = err.message + } } - onMounted(fetchMovie) + onMounted(async () => { + await fetchMovie() + await loadExistingReview() + loading.value = false + }) </script> <style scoped> @@ -189,20 +191,6 @@ color: #bbb; } - .favourite-btn { - background: #333; - border: none; - color: #bbb; - padding: 0.5rem 1rem; - border-radius: 4px; - cursor: pointer; - margin-bottom: 1rem; - } - .favourite-btn.fav { - background: #d32f2f; - color: #fff; - } - .review-text { width: 100%; padding: 0.75rem;