diff --git a/movie-group-8/package-lock.json b/movie-group-8/package-lock.json
index c6e9575c2f7e1aca5b9ab83b9e720cd18bd6e052..776cb26126436ac733829e82ef1a9429176c4a92 100644
--- a/movie-group-8/package-lock.json
+++ b/movie-group-8/package-lock.json
@@ -1852,6 +1852,20 @@
         "node": ">=0.8.0"
       }
     },
+    "node_modules/fdir": {
+      "version": "6.4.4",
+      "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz",
+      "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==",
+      "license": "MIT",
+      "peerDependencies": {
+        "picomatch": "^3 || ^4"
+      },
+      "peerDependenciesMeta": {
+        "picomatch": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/firebase": {
       "version": "11.4.0",
       "resolved": "https://registry.npmjs.org/firebase/-/firebase-11.4.0.tgz",
@@ -2200,6 +2214,18 @@
       "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
       "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
     },
+    "node_modules/picomatch": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
+      "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
     "node_modules/postcss": {
       "version": "8.5.3",
       "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
@@ -2359,6 +2385,22 @@
         "node": ">=6"
       }
     },
+    "node_modules/tinyglobby": {
+      "version": "0.2.13",
+      "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz",
+      "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==",
+      "license": "MIT",
+      "dependencies": {
+        "fdir": "^6.4.4",
+        "picomatch": "^4.0.2"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/SuperchupuDev"
+      }
+    },
     "node_modules/tslib": {
       "version": "2.8.1",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
@@ -2370,13 +2412,17 @@
       "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="
     },
     "node_modules/vite": {
-      "version": "6.2.2",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.2.tgz",
-      "integrity": "sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ==",
+      "version": "6.3.4",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.4.tgz",
+      "integrity": "sha512-BiReIiMS2fyFqbqNT/Qqt4CVITDU9M9vE+DKcVAsB+ZV0wvTKd+3hMbkpxz1b+NmEDMegpVbisKiAZOnvO92Sw==",
+      "license": "MIT",
       "dependencies": {
         "esbuild": "^0.25.0",
+        "fdir": "^6.4.4",
+        "picomatch": "^4.0.2",
         "postcss": "^8.5.3",
-        "rollup": "^4.30.1"
+        "rollup": "^4.34.9",
+        "tinyglobby": "^0.2.13"
       },
       "bin": {
         "vite": "bin/vite.js"
diff --git a/movie-group-8/src/components/TopRatedMovies.vue b/movie-group-8/src/components/TopRatedMovies.vue
index 8b5bfc579781e6ae9467420581cd36848010a234..89845c5502db60f794bd399f34cd1fa56da71a8b 100644
--- a/movie-group-8/src/components/TopRatedMovies.vue
+++ b/movie-group-8/src/components/TopRatedMovies.vue
@@ -1,5 +1,6 @@
 <script setup>
 import { ref, onMounted, watch } from 'vue'
+import addToWatchlist from '@/views/Watchlist.vue'
 
 const year = ref(2000)
 const genre = ref('')
@@ -58,6 +59,7 @@ watch([year, genre], async () => {
         />
         <p class="title">{{ movie.title }}</p>
         <p class="rating">⭐ {{ movie.vote_average }}</p>
+        <button @click="addToWatchlist(movie)">Add to Watchlist</button>
       </div>
     </div>
   </template>
diff --git a/movie-group-8/src/components/Watchlist.vue b/movie-group-8/src/components/Watchlist.vue
new file mode 100644
index 0000000000000000000000000000000000000000..f4f4aadaed9e7001aa2a16e99f1cc00984980767
--- /dev/null
+++ b/movie-group-8/src/components/Watchlist.vue
@@ -0,0 +1,74 @@
+<template>
+    <div class="watchlist">
+        <h1>Your Watchlist</h1>
+  
+        <div class="filters">
+            <select v-model="filter">
+                <option value="">All</option>
+                <option value="planned">Plan To Watch</option>
+                <option value="watched">Watched</option>
+            </select>
+        </div>
+  
+        <div class="movie-grid">
+            <div 
+                v-for="movie in filteredWatchlist" 
+                :key="movie.id" 
+                class="movie-card"
+            >
+            <img :src="'https://image.tmdb.org/t/p/w342' + movie.poster_path" alt="poster" />
+            <p class="title">{{ movie.title }}</p>
+            <p class="rating">⭐ {{ movie.vote_average }}</p>
+            <p class="status">📌 {{ movie.status }}</p>
+            </div>
+        </div>
+    </div>
+</template>
+  
+<script setup>
+    import { ref, computed, onMounted } from 'vue'
+    import { getFirestore, collection, getDocs } from 'firebase/firestore'
+    import { getAuth } from 'firebase/auth'
+  
+    const db = getFirestore()
+    const auth = getAuth()
+  
+    const watchlist = ref([])
+    const filter = ref('')
+  
+    const fetchWatchlist = async () => {
+        const user = auth.currentUser
+        if (!user) return
+  
+        const snapshot = await getDocs(collection(db, 'users', user.uid, 'watchlist'))
+        watchlist.value = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }))
+    }
+  
+    const filteredWatchlist = computed(() => {
+        if (!filter.value) return watchlist.value
+        return watchlist.value.filter(movie => movie.status === filter.value)
+    })
+  
+    onMounted(() => {
+        fetchWatchlist()
+    })
+</script>
+  
+<style scoped>
+    /* Reuse your styles or tweak as needed */
+    .watchlist {
+        padding: 2rem;
+        text-align: center;
+    }
+  
+    .filters {
+        margin-bottom: 1rem;
+    }
+  
+    .movie-grid {
+        display: grid;
+        grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
+        gap: 1.2rem;
+    }
+</style>
+  
\ No newline at end of file
diff --git a/movie-group-8/src/views/Profile.vue b/movie-group-8/src/views/Profile.vue
index 3314b81e266a166a519fa0ee6c5461b23a8be0c0..7e01bc735dbae92af82aaa50e9e4bf31980eaab9 100644
--- a/movie-group-8/src/views/Profile.vue
+++ b/movie-group-8/src/views/Profile.vue
@@ -1 +1,103 @@
-<template>Profile</template>
\ No newline at end of file
+<template>
+    <div class="flex items-center justify-center min-h-screen bg-gray-100 dark:bg-neutral-900">
+        <div class="mt-7 bg-white border border-gray-200 rounded-xl shadow-2xs dark:bg-neutral-900 dark:border-neutral-700 min-w-96">
+            <div class="p-4 sm:p-7">
+                <div class="text-center">
+                    <h1 class="block text-2xl font-bold text-gray-800 dark:text-white">Profile</h1>
+                    <p class="mt-2 text-sm text-gray-600 dark:text-neutral-400">
+                    Manage your account information
+                    </p>
+                </div>
+  
+                <div class="mt-5">
+                    <form @submit.prevent="updateProfile">
+                        <div class="grid gap-y-4">
+                            <div>
+                                <label class="block text-sm mb-2 dark:text-white">Email</label>
+                                <input type="email" :value="userEmail" disabled class="w-full border border-gray-400 rounded-lg p-2 bg-gray-100 dark:bg-neutral-800 dark:text-white" />
+                            </div>
+  
+                            <div>
+                                <label class="block text-sm mb-2 dark:text-white">Display Name</label>
+                                <input type="text" v-model="displayName" class="w-full border border-gray-400 rounded-lg p-2 dark:text-white" required />
+                            </div>
+  
+                            <div>
+                                <label class="block text-sm mb-2 dark:text-white">New Password</label>
+                                <input type="password" v-model="newPassword" class="w-full border border-gray-400 rounded-lg p-2 dark:text-white" />
+                                <p v-if="newPassword && passwordError" class="text-red-500 text-sm mt-1">{{ passwordError }}</p>
+                            </div>
+  
+                            <button
+                                type="submit"
+                                :disabled="loading || !!passwordError"
+                                class="w-full py-3 bg-blue-600 text-white rounded-lg flex justify-center items-center gap-2 hover:bg-blue-700 transition duration-300 disabled:opacity-50 disabled:pointer-events-none"
+                            >
+                            <span v-if="!loading">Update Profile</span>
+                            <span v-else>Saving...</span>
+                            </button>
+                        </div>
+                    </form>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+    import { ref, computed, onMounted } from 'vue';
+    import { getAuth, updateProfile, updatePassword } from 'firebase/auth';
+  
+    const auth = getAuth();
+    const user = auth.currentUser;
+  
+    const loading = ref(false);
+    const userEmail = ref('');
+    const displayName = ref('');
+    const newPassword = ref('');
+  
+    // Load current profile info
+    onMounted(() => {
+        if (user) {
+        userEmail.value = user.email;
+        displayName.value = user.displayName || '';
+        }
+    });
+  
+    // Password validation
+    const passwordError = computed(() => {
+        if (!newPassword.value) return '';
+        if (newPassword.value.length < 8) return "Password must be at least 8 characters.";
+        if (!/[A-Z]/.test(newPassword.value)) return "Must include at least 1 uppercase letter.";
+        if (!/[0-9]/.test(newPassword.value)) return "Must include at least 1 number.";
+        if (!/[@$!%*?&]/.test(newPassword.value)) return "Must include at least 1 special character (@$!%*?&).";
+        return '';
+    });
+  
+    // Update function
+    const updateProfile = async () => {
+        if (passwordError.value) return;
+  
+        loading.value = true;
+        try {
+            if (user) {
+            // Update display name
+            await updateProfile(user, {
+                displayName: displayName.value,
+            });
+  
+            // Update password if provided
+            if (newPassword.value) {
+                await updatePassword(user, newPassword.value);
+            }
+  
+            alert('Profile updated successfully!');
+            }
+        } catch (error) {
+        alert(error.message);
+        } finally {
+        loading.value = false;
+        }
+    };
+</script>
+  
\ No newline at end of file
diff --git a/movie-group-8/src/views/Watchlist.vue b/movie-group-8/src/views/Watchlist.vue
index 881fa1732ebc44f101dee618914366c413913c24..58cf86606685c77a69557491d6f210d3ba2ca52d 100644
--- a/movie-group-8/src/views/Watchlist.vue
+++ b/movie-group-8/src/views/Watchlist.vue
@@ -1 +1,26 @@
-<template>Watchlist</template>
\ No newline at end of file
+<template>
+    <Watchlist />
+</template>
+
+<script setup>
+import Watchlist from '@/components/Watchlist.vue'
+
+import { getFirestore, doc, setDoc } from 'firebase/firestore'
+import { getAuth } from 'firebase/auth'
+
+const addToWatchlist = async (movie) => {
+    const user = getAuth().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,
+        poster_path: movie.poster_path,
+        vote_average: movie.vote_average,
+        status: 'planned'
+    })
+
+    alert('Movie added to watchlist!')
+}
+</script>
\ No newline at end of file