diff --git a/movie-group-8/src/assets/default_avatar.png b/movie-group-8/src/assets/default_avatar.png
new file mode 100644
index 0000000000000000000000000000000000000000..778e051529c32dc9e845d961a9229d0addaf09ea
Binary files /dev/null and b/movie-group-8/src/assets/default_avatar.png differ
diff --git a/movie-group-8/src/components/Navbar.vue b/movie-group-8/src/components/Navbar.vue
index 7abd7a88907732e7e5cb61faa5c7cbbd8d27570d..64d7e5700bc6baec7c66c76e9357bbc787de6f9e 100644
--- a/movie-group-8/src/components/Navbar.vue
+++ b/movie-group-8/src/components/Navbar.vue
@@ -74,6 +74,7 @@ import { ref, computed, onMounted } from 'vue';
 import { useRoute, useRouter } from 'vue-router';
 import { getAuth, onAuthStateChanged, signOut } from 'firebase/auth';
 import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/vue';
+import defaultAvatar from '@/assets/default_avatar.png'
 
 // Firebase Authentication instance
 const auth = getAuth(); 
@@ -87,6 +88,7 @@ const navigation = ref([
   { name: 'Films', href: '/films', authRequired: true },
   { name: 'Watchlist', href: '/watchlist', authRequired: true },
   { name: 'Top Rated', href: '/top-rated', authRequired: true },
+  { name: 'Social', href: '/social', authRequired: true },
 
 ]);
 
@@ -109,7 +111,7 @@ onMounted(() => {
     if(user && user.photoURL) {
       userPhotoURL.value = user.photoURL;
     } else {
-      userPhotoURL.value = 'https://static.vecteezy.com/system/resources/previews/009/292/244/non_2x/default-avatar-icon-of-social-media-user-vector.jpg';
+      userPhotoURL.value = defaultAvatar;
     }
   });
 });
diff --git a/movie-group-8/src/components/TopRatedMovies.vue b/movie-group-8/src/components/TopRatedMovies.vue
index 5df1ea21187c2f57bfa5dd31e65a7fe185cdc3a0..090e315b6344a73ba91f116b5f0b5aad23b124a1 100644
--- a/movie-group-8/src/components/TopRatedMovies.vue
+++ b/movie-group-8/src/components/TopRatedMovies.vue
@@ -1,6 +1,5 @@
 <script setup>
 import { ref, onMounted, watch } from 'vue'
-import { addToWatchlist } from '@/composables/useWatchlist.js'
 
 const year = ref(2000)
 const genre = ref('')
@@ -28,41 +27,45 @@ watch([year, genre], async () => {
 </script>
 
 <template>
-    <div class="nyt-header">
-      <h1>The Movies We've Loved Since 2000</h1>
-      <p>
-        Explore top-rated films using the filters below — by genre and year — and rediscover hidden gems.
-      </p>
-    </div>
-  
-    <div class="filters">
-      <select v-model="genre">
-        <option value="">Pick a genre ...</option>
-        <option v-for="g in genres" :key="g.id" :value="g.id">{{ g.name }}</option>
-      </select>
-  
-      <select v-model="year">
-        <option v-for="y in Array.from({length: 25}, (_, i) => 2000 + i)" :key="y" :value="y">
-          {{ y }}
-        </option>
-      </select>
-    </div>
-  
-    <h2 class="section-title">Our favorite movies from {{ year }}</h2>
-  
-    <div class="movie-grid">
-      <div v-for="movie in movies" :key="movie.id" class="movie-card">
-        <img
-          v-if="movie.poster_path"
-          :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>
-        <button @click="addToWatchlist(movie)">Add to Watchlist</button>
-      </div>
-    </div>
-  </template>
+  <div class="nyt-header">
+    <h1>The Movies We've Loved Since 2000</h1>
+    <p>
+      Explore top-rated films using the filters below — by genre and year — and rediscover hidden gems.
+    </p>
+  </div>
+
+  <div class="filters">
+    <select v-model="genre">
+      <option value="">Pick a genre ...</option>
+      <option v-for="g in genres" :key="g.id" :value="g.id">{{ g.name }}</option>
+    </select>
+
+    <select v-model="year">
+      <option v-for="y in Array.from({length: 25}, (_, i) => 2000 + i)" :key="y" :value="y">
+        {{ y }}
+      </option>
+    </select>
+  </div>
+
+  <h2 class="section-title">Our favorite movies from {{ year }}</h2>
+
+  <div class="movie-grid">
+    <router-link
+      v-for="movie in movies"
+      :key="movie.id"
+      :to="`/films/${movie.id}`"
+      class="movie-card block hover:opacity-90 transition"
+    >
+      <img
+        v-if="movie.poster_path"
+        :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>
+    </router-link>
+  </div>
+</template>
   
 <style scoped>
 .nyt-header {
diff --git a/movie-group-8/src/components/Watchlist.vue b/movie-group-8/src/components/Watchlist.vue
index 968bb92b4ce92aa74b7431459b883eb435ee6006..724082258be8667655500d595f6361458acab0c9 100644
--- a/movie-group-8/src/components/Watchlist.vue
+++ b/movie-group-8/src/components/Watchlist.vue
@@ -20,6 +20,12 @@
             <p class="title">{{ movie.title }}</p>
             <p class="rating">⭐ {{ movie.vote_average }}</p>
             <p class="status">📌 {{ movie.status }}</p>
+            <button
+                @click="removeFromWatchlist(movie)"
+                class="mt-2 px-3 py-1 bg-red-600 text-white rounded hover:bg-red-700 transition"
+                >
+                Remove
+            </button>
             </div>
         </div>
     </div>
@@ -27,7 +33,7 @@
   
 <script setup>
     import { ref, computed, onMounted } from 'vue'
-    import { getFirestore, collection, getDocs } from 'firebase/firestore'
+    import { getFirestore, collection, getDocs, doc, deleteDoc } from 'firebase/firestore'
     import { getAuth } from 'firebase/auth'
   
     const db = getFirestore()
@@ -43,6 +49,16 @@
         const snapshot = await getDocs(collection(db, 'users', user.uid, 'watchlist'))
         watchlist.value = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }))
     }
+
+    const removeFromWatchlist = async (movie) => {
+        const user = auth.currentUser
+        const movieRef = doc(db, 'users', user.uid, 'watchlist', String(movie.id))
+        await deleteDoc(movieRef)
+
+        // remove locally
+        watchlist.value = watchlist.value.filter(m => m.id !== movie.id)
+        alert(`Removed "${movie.title}" from your watchlist.`)
+    }
   
     const filteredWatchlist = computed(() => {
         if (!filter.value) return watchlist.value
diff --git a/movie-group-8/src/components/WatchlistButton.vue b/movie-group-8/src/components/WatchlistButton.vue
new file mode 100644
index 0000000000000000000000000000000000000000..91458232887237079c738f99224113fc42242682
--- /dev/null
+++ b/movie-group-8/src/components/WatchlistButton.vue
@@ -0,0 +1,37 @@
+<template>
+  <button
+    type="button"
+    @click="toggleWatchlist"
+    class="mt-2 px-3 py-1 rounded text-white text-sm transition"
+    :class="isInWatchlist
+      ? 'bg-red-600 hover:bg-red-700'
+      : 'bg-green-600 hover:bg-green-700'"
+  >
+    {{ isInWatchlist ? 'Remove from Watchlist' : 'Add to Watchlist' }}
+  </button>
+</template>
+
+<script setup>
+import { ref, watch } from 'vue'
+import { useWatchlist } from '@/composables/useWatchlist.js'
+
+const props = defineProps({
+  movie: {
+    type: Object,
+    required: true
+  }
+})
+
+// We need a ref for the ID and a ref for the data
+const movieId = ref(props.movie.id)
+const movieData = ref(props.movie)
+
+// Pull in the composable
+const { isInWatchlist, toggleWatchlist } = useWatchlist(movieId, movieData)
+
+// If parent updates the prop, keep our ref in sync
+watch(() => props.movie, m => {
+  movieId.value = m.id
+  movieData.value = m
+})
+</script>
\ No newline at end of file
diff --git a/movie-group-8/src/composables/useWatchlist.js b/movie-group-8/src/composables/useWatchlist.js
index c63ca445acc2ddda4820469fdaeb8cee8ff8b5d3..7dc09f0315ba6d966362d22a40f381bbf7b30da6 100644
--- a/movie-group-8/src/composables/useWatchlist.js
+++ b/movie-group-8/src/composables/useWatchlist.js
@@ -1,17 +1,47 @@
-import { doc, setDoc } from 'firebase/firestore'
-import { auth, db }    from '@/firebase.js'
+import { ref, watchEffect } from 'vue'
+import { getAuth } from 'firebase/auth'
+import { getFirestore, doc, getDoc, setDoc, deleteDoc } from 'firebase/firestore'
 
-export const addToWatchlist = async (movie) => {
-  const user = auth.currentUser
-  if (!user) return alert('You need to log in.')
+export function useWatchlist(movieId, movieData) {
+  const auth = getAuth()
+  const db = getFirestore()
+  const isInWatchlist = ref(false)
 
-  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'
+  // Check on load & whenever movieId or user changes
+  watchEffect(async (onInvalidate) => {
+    const user = auth.currentUser
+    if (!user.value ?? user) {
+      isInWatchlist.value = false
+      return
+    }
+    const ref = doc(db, 'users', user.uid, 'watchlist', String(movieId.value ?? movieId))
+    const snap = await getDoc(ref)
+    isInWatchlist.value = snap.exists()
   })
 
-  alert('Movie added to watchlist!')
+  // Toggle function
+  const toggleWatchlist = async () => {
+    const user = auth.currentUser
+    if (!user) {
+      return alert('You need to log in.')
+    }
+    const ref = doc(db, 'users', user.uid, 'watchlist', String(movieId.value ?? movieId))
+
+    if (isInWatchlist.value) {
+      await deleteDoc(ref)
+      isInWatchlist.value = false
+      alert('Removed from watchlist')
+    } else {
+      await setDoc(ref, {
+        title: movieData.value.title,
+        poster_path: movieData.value.poster_path,
+        vote_average: movieData.value.vote_average,
+        status: 'planned'
+      })
+      isInWatchlist.value = true
+      alert('Added to watchlist')
+    }
+  }
+
+  return { isInWatchlist, toggleWatchlist }
 }
\ No newline at end of file
diff --git a/movie-group-8/src/router/index.js b/movie-group-8/src/router/index.js
index f4763b4c1ce260ab69a24d77e4ab2956d5b63c49..fcbec63700fcb695109d7a419820f479345ec6d5 100644
--- a/movie-group-8/src/router/index.js
+++ b/movie-group-8/src/router/index.js
@@ -10,7 +10,7 @@ const router = createRouter({
         
         
         { path: '/', component: () => import('../views/Home.vue') },
-        {path: '/top-rated', component: () => import('../views/TopRated.vue'), meta: { requiresAuth: true }},
+        { path: '/top-rated', component: () => import('../views/TopRated.vue'), meta: { requiresAuth: true }},
         { path: '/register', component: () => import('../views/Register.vue') },
         { path: '/login', component: () => import('../views/Login.vue') },
         { path: '/recover-account', component: () => import('../views/RecoverAccount.vue') },
@@ -48,7 +48,17 @@ const router = createRouter({
             component: () => import('../views/Settings.vue'), 
             meta: { requiresAuth: true },
         },
-
+        {
+            path: '/social',
+            name: 'Social',
+            component: () => import('../views/Social.vue'),
+            meta: { requiresAuth: true },
+        },
+        {
+            path: '/user/:id',
+            name: 'UserProfile',
+            component: () => import('../views/UserProfile.vue')
+        },
     ],
 });
 
diff --git a/movie-group-8/src/views/FilmDetails.vue b/movie-group-8/src/views/FilmDetails.vue
index d2b8e333a8be1b3bb1f4ea4dc9aad358a2f6be11..4880f46bcb33e425fd8571e0bca0d24e79c32a8b 100644
--- a/movie-group-8/src/views/FilmDetails.vue
+++ b/movie-group-8/src/views/FilmDetails.vue
@@ -30,12 +30,7 @@
           ></iframe>
         </div>
 
-        <button
-          @click="addToWatchlist(movie)"
-          class="mt-4 px-4 py-2 bg-green-600 rounded text-white hover:bg-green-700"
-        >
-          Add to Watchlist
-        </button>
+        <WatchlistButton :movie="movie" class="mt-4" />
 
         <RouterLink
           :to="{ name: 'ReviewFilm', params: { id: movie.id } }"
@@ -64,17 +59,18 @@
 <script setup>
 import { ref, onMounted } from 'vue'
 import { useRoute } from 'vue-router'
-import { addToWatchlist } from '@/composables/useWatchlist.js'
-import { getAllReviews }  from '@/composables/useReviews.js'
-
+import { useWatchlist } from '@/composables/useWatchlist.js'
+import WatchlistButton from '@/components/WatchlistButton.vue'
+import { getAuth } from 'firebase/auth'
+import { getFirestore, doc, getDoc } from 'firebase/firestore'
 
 const route = useRoute()
 const movie = ref(null)
 const trailerUrl = ref('')
 const loading = ref(true)
 const error = ref('')
-const reviews = ref([])      
-const reviewsLoading = ref(true)
+const movieId = ref(route.params.id)
+const { isInWatchlist } = useWatchlist(movieId, movie)
 
 function formatDate(dateString) {
   if (!dateString) return 'Unknown'
@@ -117,16 +113,16 @@ onMounted(async () => {
   const id = route.params.id
   await fetchMovieDetails(id)
   await fetchMovieVideos(id)
-  try {
-    const res = await getAllReviews(id)
-    console.log('Raw reviews from Firestore:', res)
-    reviews.value = res
-  } catch (revErr) {
-    console.error('Failed to load reviews', revErr)
-  } finally {
-    reviewsLoading.value = false
-    loading.value        = false
+
+  const user = getAuth().currentUser
+  if (user) {
+    const db = getFirestore()
+    const watchRef = doc(db, 'users', user.uid, 'watchlist', String(id))
+    const snap = await getDoc(watchRef)
+    isInWatchlist.value = snap.exists()
   }
+
+  loading.value = false
 })
 </script>
 
diff --git a/movie-group-8/src/views/Login.vue b/movie-group-8/src/views/Login.vue
index eecffe4823239b2c0feac6450cd4b1938ed3d129..0b539b1f8a6880c589d20a59837fc7afc0c1f5fc 100644
--- a/movie-group-8/src/views/Login.vue
+++ b/movie-group-8/src/views/Login.vue
@@ -61,47 +61,83 @@
         </div>
       </div>
     </div>
-  </template>
+</template>
   
-  <script setup>
-  import { ref } from 'vue';
-  import { getAuth, signInWithEmailAndPassword, signInWithPopup, GoogleAuthProvider } from 'firebase/auth';
-  import { useRouter } from 'vue-router';
-  
-  const email = ref('');
-  const password = ref('');
-  const router = useRouter();
-  const loading = ref(false);
-  
-  const login = async () => {
-    try {
-      loading.value = true;
-      const auth = getAuth();
-      await signInWithEmailAndPassword(auth, email.value, password.value);
-      console.log('Successfully logged in!');
-      router.push('/films');
-    } catch (error) {
-      console.error(error);
-      alert(error.message);
-    } finally {
-      loading.value = false;
-    }
-  };
-  
-  const signInWithGoogle = async () => {
-    try {
-      loading.value = true;
-      const auth = getAuth();
-      const provider = new GoogleAuthProvider();
-      await signInWithPopup(auth, provider);
-      console.log('Successfully signed in with Google!');
-      router.push('/films');
-    } catch (error) {
-      console.error(error);
-      alert(error.message);
-    } finally {
-      loading.value = false;
-    }
-  };
-  </script>
-  
\ No newline at end of file
+<script setup>
+import { ref } from 'vue';
+import {
+  getAuth,
+  signInWithEmailAndPassword,
+  signInWithPopup,
+  GoogleAuthProvider
+} from 'firebase/auth';
+import {
+  getFirestore,
+  doc,
+  getDoc,
+  setDoc
+} from 'firebase/firestore';
+import { useRouter } from 'vue-router';
+import defaultAvatar from '@/assets/default_avatar.png'
+
+const email = ref('');
+const password = ref('');
+const router = useRouter();
+const loading = ref(false);
+
+const db = getFirestore();
+
+const createUserIfNotExists = async (user) => {
+  const userRef = doc(db, 'users', user.uid)
+  const userSnap = await getDoc(userRef)
+
+  if (!userSnap.exists()) {
+    const photoURLToSave = user.photoURL || defaultAvatar
+
+    await setDoc(userRef, {
+      uid: user.uid,
+      displayName: user.displayName || 'Anonymous',
+      photoURL: photoURLToSave
+    })
+  }
+}
+
+const login = async () => {
+  try {
+    loading.value = true;
+    const auth = getAuth();
+    const userCredential = await signInWithEmailAndPassword(auth, email.value, password.value);
+    const user = userCredential.user;
+
+    await createUserIfNotExists(user);
+
+    console.log('Successfully logged in!');
+    router.push('/films');
+  } catch (error) {
+    console.error(error);
+    alert(error.message);
+  } finally {
+    loading.value = false;
+  }
+};
+
+const signInWithGoogle = async () => {
+  try {
+    loading.value = true;
+    const auth = getAuth();
+    const provider = new GoogleAuthProvider();
+    const result = await signInWithPopup(auth, provider);
+    const user = result.user;
+
+    await createUserIfNotExists(user);
+
+    console.log('Successfully signed in with Google!');
+    router.push('/films');
+  } catch (error) {
+    console.error(error);
+    alert(error.message);
+  } finally {
+    loading.value = false;
+  }
+};
+</script>
\ 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 733b4eefd0e59443c462995e23715c1aa7fa71d1..065de78bfe03ba517b7fdb499bcce3d8981ec898 100644
--- a/movie-group-8/src/views/Profile.vue
+++ b/movie-group-8/src/views/Profile.vue
@@ -9,7 +9,7 @@
       />
       <h1 class="text-3xl font-bold text-gray-800 dark:text-white">{{ displayName || 'Anonymous' }}</h1>
       <p class="text-sm text-gray-600 dark:text-neutral-400">{{ userEmail }}</p>
-      <p class="mt-2 text-base text-gray-600 dark:text-neutral-400">Movie fan and scene collector.</p>
+      <p class="mt-2 text-base text-gray-600 dark:text-neutral-400">{{ description }}</p>
 
       <button
         @click="showForm = !showForm"
@@ -19,6 +19,7 @@
       </button>
     </div>
 
+    <!-- Update Form -->
     <div v-if="showForm" class="max-w-xl mx-auto mb-12 bg-white dark:bg-neutral-800 p-6 rounded-xl border dark:border-neutral-700">
       <form @submit.prevent="handleUpdateProfile" class="grid gap-6">
         <div>
@@ -26,6 +27,11 @@
           <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">Description</label>
+          <textarea v-model="description" rows="3" class="w-full border border-gray-400 rounded-lg p-2 dark:text-white" />
+        </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" />
@@ -43,74 +49,114 @@
       </form>
     </div>
 
-    <div>
-      <h2 class="text-2xl font-semibold text-gray-800 dark:text-white mb-6">Your Watchlist</h2>
+    <!-- Tabs -->
+    <div class="flex justify-center gap-4 mb-6">
+      <button
+        v-for="tab in ['watchlist', 'followers', 'following']"
+        :key="tab"
+        @click="activeTab = tab"
+        :class="[
+          'px-4 py-2 rounded-lg text-sm font-medium',
+          activeTab === tab
+            ? 'bg-blue-600 text-white'
+            : 'bg-white dark:bg-neutral-700 text-gray-800 dark:text-white border border-gray-300 dark:border-neutral-600'
+        ]"
+      >
+        {{ tab.charAt(0).toUpperCase() + tab.slice(1) }}
+      </button>
+    </div>
 
-      <div v-if="watchlist.length === 0" class="text-gray-500 dark:text-gray-400 text-sm">
-        Your watchlist is empty.
+    <!-- Tab Content -->
+    <div v-if="activeTab === 'watchlist'" class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
+      <router-link
+        v-for="movie in watchlist"
+        :key="movie.id"
+        :to="`/films/${movie.id}`"
+        class="block bg-white dark:bg-neutral-800 border dark:border-neutral-700 rounded-lg p-3 hover:opacity-90 transition"
+      >
+        <img
+          v-if="movie.poster_path"
+          :src="'https://image.tmdb.org/t/p/w342' + movie.poster_path"
+          alt="Poster"
+          class="w-full h-60 object-cover rounded mb-3"
+        />
+        <p class="font-semibold text-gray-800 dark:text-white">{{ movie.title }}</p>
+        <p class="text-sm text-gray-600 dark:text-neutral-400">⭐ {{ movie.vote_average }} — {{ movie.status }}</p>
+      </router-link>
+    </div>
+
+    <!-- Followers -->
+    <div v-else-if="activeTab === 'followers'" class="grid gap-4 max-w-xl mx-auto">
+      <div
+        v-for="follower in followers"
+        :key="follower.uid"
+        class="flex items-center justify-between p-4 bg-white dark:bg-neutral-800 border dark:border-neutral-700 rounded-lg"
+      >
+        <router-link :to="`/user/${follower.uid}`" class="flex items-center gap-4">
+          <img
+            :src="follower.photoURL || 'https://via.placeholder.com/150'"
+            alt="Avatar"
+            class="w-12 h-12 rounded-full object-cover"
+          />
+          <span class="text-lg font-semibold text-gray-800 dark:text-white">{{ follower.displayName }}</span>
+        </router-link>
       </div>
+    </div>
 
-      <div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
-        <div
-          v-for="movie in watchlist"
-          :key="movie.id"
-          class="bg-white dark:bg-neutral-800 border dark:border-neutral-700 rounded-lg p-3 text-left"
-        >
+    <!-- Following -->
+    <div v-else-if="activeTab === 'following'" class="grid gap-4 max-w-xl mx-auto">
+      <div
+        v-for="followed in following"
+        :key="followed.uid"
+        class="flex items-center justify-between p-4 bg-white dark:bg-neutral-800 border dark:border-neutral-700 rounded-lg"
+      >
+        <router-link :to="`/user/${followed.uid}`" class="flex items-center gap-4">
           <img
-            v-if="movie.poster_path"
-            :src="'https://image.tmdb.org/t/p/w342' + movie.poster_path"
-            alt="Poster"
-            class="w-full h-60 object-cover rounded mb-3"
+            :src="followed.photoURL || 'https://via.placeholder.com/150'"
+            alt="Avatar"
+            class="w-12 h-12 rounded-full object-cover"
           />
-          <p class="font-semibold text-gray-800 dark:text-white">{{ movie.title }}</p>
-          <p class="text-sm text-gray-600 dark:text-neutral-400">⭐ {{ movie.vote_average }} — {{ movie.status }}</p>
-        </div>
+          <span class="text-lg font-semibold text-gray-800 dark:text-white">{{ followed.displayName }}</span>
+        </router-link>
       </div>
     </div>
   </div>
 </template>
 
 <script setup>
-import { ref, computed, onMounted } from 'vue'
+import {
+  collection,
+  getDocs,
+  doc,
+  getDoc,
+  updateDoc,
+  getFirestore,
+} from 'firebase/firestore'
+
 import {
   getAuth,
   updateProfile as firebaseUpdateProfile,
-  updatePassword,
+  updatePassword
 } from 'firebase/auth'
-import {
-  getFirestore,
-  collection,
-  getDocs
-} from 'firebase/firestore'
 
+import { ref, computed, onMounted } from 'vue'
 const auth = getAuth()
 const db = getFirestore()
 
-const user = auth.currentUser
-
-const loading = ref(false)
+const user = ref(null)
 const userEmail = ref('')
 const displayName = ref('')
-const newPassword = ref('')
+const description = ref('')
 const userPhotoURL = ref('')
+const newPassword = ref('')
 const showForm = ref(false)
+const activeTab = ref('watchlist')
+const loading = ref(false)
 
 const watchlist = ref([])
+const followers = ref([])
+const following = ref([])
 
-// Load profile info
-onMounted(async () => {
-  if (user) {
-    userEmail.value = user.email
-    displayName.value = user.displayName || ''
-    userPhotoURL.value = user.photoURL || ''
-
-    // Fetch watchlist
-    const snapshot = await getDocs(collection(db, 'users', user.uid, 'watchlist'))
-    watchlist.value = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }))
-  }
-})
-
-// Password validation
 const passwordError = computed(() => {
   if (!newPassword.value) return ''
   if (newPassword.value.length < 8) return 'Password must be at least 8 characters.'
@@ -120,30 +166,104 @@ const passwordError = computed(() => {
   return ''
 })
 
-// Update profile function
+const fetchFollowing = async () => {
+  const followingSnap = await getDocs(collection(db, 'users', user.value.uid, 'following'))
+  const followedIds = followingSnap.docs.map(doc => doc.id)
+
+  const usersList = []
+
+  for (const id of followedIds) {
+    const docSnap = await getDoc(doc(db, 'users', id))
+    if (docSnap.exists()) {
+      const data = docSnap.data()
+      // Only push if the user has a displayName or isn’t hidden
+      if (!data.hidden && data.displayName) {
+        usersList.push({ uid: id, ...data })
+      }
+    }
+  }
+
+  following.value = usersList
+}
+
+const fetchFollowers = async () => {
+  if (!user.value) return
+
+  const allUsersSnap = await getDocs(collection(db, 'users'))
+  const followersList = []
+
+  for (const docSnap of allUsersSnap.docs) {
+    const otherUid = docSnap.id
+    if (otherUid === user.value.uid) continue
+
+    const followDocRef = doc(db, 'users', otherUid, 'following', user.value.uid)
+    const followDocSnap = await getDoc(followDocRef)
+
+    if (followDocSnap.exists()) {
+      const otherUserData = docSnap.data()
+      if (otherUserData.displayName && !otherUserData.hidden) {
+        followersList.push({ uid: otherUid, ...otherUserData })
+      }
+    }
+  }
+
+  followers.value = followersList
+}
+
 const handleUpdateProfile = async () => {
   if (passwordError.value) return
 
   loading.value = true
   try {
-    if (user) {
-      await firebaseUpdateProfile(user, {
-        displayName: displayName.value
-      })
+    const authUser = auth.currentUser
+    if (!authUser) throw new Error('No authenticated user')
 
-      if (newPassword.value) {
-        await updatePassword(user, newPassword.value)
-      }
+    // Update the Firebase Auth profile
+    await firebaseUpdateProfile(authUser, {
+      displayName: displayName.value
+    })
 
-      alert('Profile updated successfully!')
-      showForm.value = false
+    if (newPassword.value) {
+      await updatePassword(authUser, newPassword.value)
     }
+
+    // Update your Firestore user document
+    const userDocRef = doc(db, 'users', authUser.uid)
+    await updateDoc(userDocRef, {
+      displayName: displayName.value,
+      description: description.value
+    })
+
+    alert('Profile updated successfully!')
+    showForm.value = false
+
   } catch (error) {
     alert(error.message)
   } finally {
     loading.value = false
   }
 }
+
+onMounted(async () => {
+  const authUser = auth.currentUser
+  if (!authUser) return
+
+  user.value = authUser
+  userEmail.value = authUser.email
+  displayName.value = authUser.displayName || ''
+  userPhotoURL.value = authUser.photoURL || ''
+
+  const userDoc = await getDoc(doc(db, 'users', user.value.uid))
+  if (userDoc.exists()) {
+    description.value = userDoc.data().description || ''
+  }
+
+  const snapshot = await getDocs(collection(db, 'users', user.value.uid, 'watchlist'))
+  watchlist.value = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }))
+
+  await fetchFollowing()
+  await fetchFollowers()
+})
 </script>
 
 <style scoped>
diff --git a/movie-group-8/src/views/Register.vue b/movie-group-8/src/views/Register.vue
index 2880887871e12186c4e92abcc2b2d1f83fff625f..1f4d10208d7c4e78d2394a6ef467358234f9f5f4 100644
--- a/movie-group-8/src/views/Register.vue
+++ b/movie-group-8/src/views/Register.vue
@@ -62,8 +62,18 @@
 
 <script setup>
 import { ref, computed } from 'vue';
-import { getAuth, createUserWithEmailAndPassword, signInWithPopup, GoogleAuthProvider } from 'firebase/auth';
 import { useRouter } from 'vue-router';
+import defaultAvatar from '@/assets/default_avatar.png'
+
+import { 
+  getAuth,
+  createUserWithEmailAndPassword,
+ } from 'firebase/auth';
+import {
+  getFirestore,
+  doc,
+  setDoc
+} from 'firebase/firestore';
 
 const email = ref('');
 const password = ref('');
@@ -93,9 +103,26 @@ const register = async () => {
 if (passwordError.value || confirmPasswordError.value) return;
 loading.value = true;
 try {
-  const auth = getAuth();
-  await createUserWithEmailAndPassword(auth, email.value, password.value);
-  router.push('/films');
+  const auth = getAuth()
+  const db = getFirestore()
+  const userCredential = await createUserWithEmailAndPassword(auth, email.value, password.value)
+  const user = userCredential.user
+
+  // Set default profile info
+  await updateProfile(user, {
+    displayName: 'New User',
+    photoURL: defaultAvatar
+  })
+
+  // Create Firestore document for this user
+  await setDoc(doc(db, 'users', user.uid), {
+    displayName: 'New User',
+    photoURL: defaultAvatar,
+    description: '',
+    hidden: false
+  })
+
+  router.push('/films')
 } catch (error) {
   alert(error.message);
 } finally {
diff --git a/movie-group-8/src/views/Social.vue b/movie-group-8/src/views/Social.vue
new file mode 100644
index 0000000000000000000000000000000000000000..ed3b9b1e253cf69fa6e2c191f9b1ebea19fcb48f
--- /dev/null
+++ b/movie-group-8/src/views/Social.vue
@@ -0,0 +1,99 @@
+<template>
+  <div class="min-h-screen bg-gray-100 dark:bg-neutral-900 p-6">
+    <h1 class="text-3xl font-bold text-gray-900 dark:text-white mb-6 text-center">Find and Follow Users</h1>
+
+    <div class="max-w-xl mx-auto mb-6">
+      <input
+        type="text"
+        v-model="searchTerm"
+        placeholder="Search by display name..."
+        class="w-full p-3 rounded-lg border border-gray-300 dark:border-neutral-700 dark:bg-neutral-800 dark:text-white"
+      />
+    </div>
+
+    <div class="grid gap-4 max-w-3xl mx-auto">
+      <div
+        v-for="user in filteredUsers"
+        :key="user.uid"
+        class="flex items-center justify-between p-4 bg-white dark:bg-neutral-800 border dark:border-neutral-700 rounded-lg"
+      >
+        <router-link :to="`/user/${user.uid}`" class="flex items-center gap-4">
+          <img
+            :src="user.photoURL"
+            class="w-12 h-12 rounded-full object-cover"
+            alt="Avatar"
+          />
+          <span class="text-lg font-semibold text-gray-800 dark:text-white">{{ user.displayName }}</span>
+        </router-link>
+        <button
+          @click="toggleFollow(user.uid)"
+          class="px-4 py-1.5 text-sm rounded-lg font-medium"
+          :class="isFollowing(user.uid)
+            ? 'bg-red-500 text-white hover:bg-red-600'
+            : 'bg-blue-600 text-white hover:bg-blue-700'"
+        >
+          {{ isFollowing(user.uid) ? 'Unfollow' : 'Follow' }}
+        </button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref, computed, onMounted } from 'vue'
+import { getAuth } from 'firebase/auth'
+import {
+  getFirestore,
+  collection,
+  getDocs,
+  setDoc,
+  deleteDoc,
+  doc
+} from 'firebase/firestore'
+
+const auth = getAuth()
+const db = getFirestore()
+const currentUser = auth.currentUser
+
+const searchTerm = ref('')
+const users = ref([])
+const following = ref([])
+
+onMounted(async () => {
+  await fetchUsers()
+  await fetchFollowing()
+})
+
+const fetchUsers = async () => {
+  const snapshot = await getDocs(collection(db, 'users'))
+  users.value = snapshot.docs
+    .map(doc => doc.data())
+    .filter(u => u.uid !== currentUser?.uid && !u.hidden) // exclude self and test user
+}
+
+const fetchFollowing = async () => {
+  const snapshot = await getDocs(collection(db, 'users', currentUser.uid, 'following'))
+  following.value = snapshot.docs.map(doc => doc.id)
+}
+
+const isFollowing = (uid) => following.value.includes(uid)
+
+const toggleFollow = async (uid) => {
+  const followRef = doc(db, 'users', currentUser.uid, 'following', uid)
+
+  if (isFollowing(uid)) {
+    await deleteDoc(followRef)
+    following.value = following.value.filter(id => id !== uid)
+  } else {
+    await setDoc(followRef, { followedAt: Date.now() })
+    following.value.push(uid)
+  }
+}
+
+const filteredUsers = computed(() => {
+  if (!searchTerm.value.trim()) return users.value
+  return users.value.filter(u =>
+    u.displayName.toLowerCase().includes(searchTerm.value.toLowerCase())
+  )
+})
+</script>
\ No newline at end of file
diff --git a/movie-group-8/src/views/UserProfile.vue b/movie-group-8/src/views/UserProfile.vue
new file mode 100644
index 0000000000000000000000000000000000000000..74c0cfc15940553b93dad02694bb0a5e0f82de7d
--- /dev/null
+++ b/movie-group-8/src/views/UserProfile.vue
@@ -0,0 +1,117 @@
+<template>
+  <div class="min-h-screen bg-gray-100 dark:bg-neutral-900 p-6">
+    <div class="text-center mb-10">
+      <img
+        v-if="user.photoURL"
+        :src="user.photoURL"
+        alt="Profile"
+        class="w-24 h-24 mx-auto rounded-full object-cover"
+      />
+      <h1 class="text-2xl font-bold mt-4 text-gray-800 dark:text-white">
+        {{ user.displayName || 'Unknown User' }}
+      </h1>
+
+      <button
+        v-if="!isOwnProfile"
+        @click="toggleFollow"
+        class="mt-3 px-4 py-2 rounded-lg text-white text-sm"
+        :class="isFollowing ? 'bg-red-500 hover:bg-red-600' : 'bg-blue-600 hover:bg-blue-700'"
+      >
+        {{ isFollowing ? 'Unfollow' : 'Follow' }}
+      </button>
+    </div>
+
+    <h2 class="text-xl font-semibold text-gray-800 dark:text-white mb-4 text-center">
+      Watchlist
+    </h2>
+
+    <div v-if="watchlist.length === 0" class="text-center text-gray-500 dark:text-gray-400">
+      No public watchlist found.
+    </div>
+
+    <div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
+      <router-link
+        v-for="movie in watchlist"
+        :key="movie.id"
+        :to="`/films/${movie.id}`"
+        class="block bg-white dark:bg-neutral-800 border dark:border-neutral-700 rounded-lg p-4 hover:opacity-90 transition"
+      >
+        <img
+          v-if="movie.poster_path"
+          :src="'https://image.tmdb.org/t/p/w342' + movie.poster_path"
+          alt="Poster"
+          class="w-full h-60 object-cover rounded mb-2"
+        />
+        <p class="font-semibold text-gray-800 dark:text-white">{{ movie.title }}</p>
+        <p class="text-sm text-gray-600 dark:text-neutral-400">⭐ {{ movie.vote_average }}</p>
+        <p class="text-xs text-gray-400 dark:text-neutral-500">{{ movie.status }}</p>
+      </router-link>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref, onMounted } from 'vue'
+import { useRoute } from 'vue-router'
+import { getAuth } from 'firebase/auth'
+import {
+  getFirestore,
+  doc,
+  getDoc,
+  collection,
+  getDocs,
+  setDoc,
+  deleteDoc
+} from 'firebase/firestore'
+
+const route = useRoute()
+const db = getFirestore()
+const auth = getAuth()
+
+const profileUserId = route.params.id
+const currentUser = auth.currentUser
+
+const user = ref({})
+const watchlist = ref([])
+const isFollowing = ref(false)
+const isOwnProfile = currentUser?.uid === profileUserId
+
+onMounted(async () => {
+  await fetchUserProfile()
+  await fetchWatchlist()
+  if (!isOwnProfile) await checkIfFollowing()
+})
+
+const fetchUserProfile = async () => {
+  const docRef = doc(db, 'users', profileUserId)
+  const docSnap = await getDoc(docRef)
+  if (docSnap.exists()) {
+    user.value = docSnap.data()
+  } else {
+    user.value = { displayName: 'User Not Found' }
+  }
+}
+
+const fetchWatchlist = async () => {
+  const snapshot = await getDocs(collection(db, 'users', profileUserId, 'watchlist'))
+  watchlist.value = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }))
+}
+
+const checkIfFollowing = async () => {
+  const followRef = doc(db, 'users', currentUser.uid, 'following', profileUserId)
+  const followSnap = await getDoc(followRef)
+  isFollowing.value = followSnap.exists()
+}
+
+const toggleFollow = async () => {
+  const followRef = doc(db, 'users', currentUser.uid, 'following', profileUserId)
+
+  if (isFollowing.value) {
+    await deleteDoc(followRef)
+    isFollowing.value = false
+  } else {
+    await setDoc(followRef, { followedAt: Date.now() })
+    isFollowing.value = true
+  }
+}
+</script>
\ No newline at end of file
diff --git a/movie-group-8/src/views/WatchlistView.vue b/movie-group-8/src/views/WatchlistView.vue
index 4ce8909b73b403ffdd4d855defd6b30761e23de9..071b02ebe222a37ce5d458cfbc3781c56c890380 100644
--- a/movie-group-8/src/views/WatchlistView.vue
+++ b/movie-group-8/src/views/WatchlistView.vue
@@ -10,12 +10,18 @@
           No movies planned yet.
         </div>
         <div class="grid gap-4">
-          <MovieCard
-            v-for="movie in plannedMovies"
-            :key="movie.id"
-            :movie="movie"
-            @status-changed="updateMovieStatus"
-          />
+          <div v-for="movie in plannedMovies" :key="movie.id" class="relative bg-white dark:bg-neutral-800 p-4 rounded">
+            <MovieCard
+              :movie="movie"
+              @status-changed="updateMovieStatus"
+            />
+            <button
+              @click="removeFromWatchlist(movie.id)"
+              class="absolute top-2 right-2 px-2 py-1 bg-red-600 text-white text-xs rounded hover:bg-red-700 transition"
+            >
+              Remove
+            </button>
+          </div>
         </div>
       </div>
 
@@ -26,12 +32,18 @@
           No watched movies yet.
         </div>
         <div class="grid gap-4">
-          <MovieCard
-            v-for="movie in watchedMovies"
-            :key="movie.id"
-            :movie="movie"
-            @status-changed="updateMovieStatus"
-          />
+          <div v-for="movie in watchedMovies" :key="movie.id" class="relative bg-white dark:bg-neutral-800 p-4 rounded">
+            <MovieCard
+              :movie="movie"
+              @status-changed="updateMovieStatus"
+            />
+            <button
+              @click="removeFromWatchlist(movie.id)"
+              class="absolute top-2 right-2 px-2 py-1 bg-red-600 text-white text-xs rounded hover:bg-red-700 transition"
+            >
+              Remove
+            </button>
+          </div>
         </div>
       </div>
     </div>
@@ -41,7 +53,7 @@
 <script setup>
 import { ref, onMounted } from 'vue'
 import { getAuth } from 'firebase/auth'
-import { getFirestore, collection, getDocs, doc, updateDoc } from 'firebase/firestore'
+import { getFirestore, collection, getDocs, doc, updateDoc, deleteDoc } from 'firebase/firestore'
 import MovieCard from '@/components/MovieCard.vue'
 
 const auth = getAuth()
@@ -60,6 +72,15 @@ const fetchWatchlist = async () => {
   watchedMovies.value = all.filter(m => m.status === 'watched')
 }
 
+const removeFromWatchlist = async (movieId) => {
+  const user = auth.currentUser
+  if (!user) return
+
+  const movieRef = doc(db, 'users', user.uid, 'watchlist', movieId)
+  await deleteDoc(movieRef)
+  await fetchWatchlist()
+}
+
 const updateMovieStatus = async (movieId, newStatus) => {
   const user = auth.currentUser
   if (!user) return