diff --git a/movie-group-8/src/views/Profile.vue b/movie-group-8/src/views/Profile.vue index 8e3a4b8caefddcb6f16a23faac61bd18ba50dec5..50eed15283f6142cc70917aed1a7392ff4047ce2 100644 --- a/movie-group-8/src/views/Profile.vue +++ b/movie-group-8/src/views/Profile.vue @@ -11,12 +11,12 @@ <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">{{ description }}</p> - <button - @click="showForm = !showForm" - class="mt-4 px-5 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition" - > - {{ showForm ? 'Close Update Form' : 'Update Profile' }} - </button> + <router-link + to="/settings" + class="mt-4 inline-block px-5 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition" + > + Edit Profile + </router-link> </div> <!-- Update Form --> diff --git a/movie-group-8/src/views/Settings.vue b/movie-group-8/src/views/Settings.vue index 4c5d407983bd7e51dd0c6b32680470d99bd2029a..3056533ebd24813d46047059c97038d1e0c773b4 100644 --- a/movie-group-8/src/views/Settings.vue +++ b/movie-group-8/src/views/Settings.vue @@ -1 +1,163 @@ -<template>Settings</template> \ No newline at end of file +<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">Edit Profile</h1> + + <div class="max-w-xl mx-auto space-y-6"> + <!-- Profile Info --> + <div class="space-y-4"> + <div> + <label class="block text-sm font-medium mb-1 text-gray-700 dark:text-white">Display Name</label> + <input + type="text" + v-model="displayName" + class="w-full p-3 rounded-lg border border-gray-300 dark:border-neutral-700 dark:bg-neutral-800 dark:text-white" + /> + </div> + + <div> + <label class="block text-sm font-medium mb-1 text-gray-700 dark:text-white">Description</label> + <textarea + v-model="description" + rows="3" + class="w-full p-3 rounded-lg border border-gray-300 dark:border-neutral-700 dark:bg-neutral-800 dark:text-white" + ></textarea> + </div> + + <div class="flex items-center gap-2"> + <input + id="hidden" + type="checkbox" + v-model="hidden" + class="form-checkbox h-5 w-5 text-blue-600 dark:bg-neutral-800 dark:border-neutral-700" + /> + <label for="hidden" class="text-sm text-gray-700 dark:text-white">Hide profile from others</label> + </div> + + <button + @click="handleProfileUpdate" + class="w-full py-3 text-white rounded-lg font-medium bg-blue-600 hover:bg-blue-700 transition" + > + Save Changes + </button> + </div> + + <!-- Change Password --> + <div class="border-t border-gray-300 dark:border-neutral-700 pt-6"> + <h2 class="text-xl font-semibold text-gray-900 dark:text-white mb-4">Change Password</h2> + + <div v-if="isGoogleUser" class="text-gray-600 dark:text-neutral-400 italic"> + Your account is linked with Google. Password changes are managed through your Google account. + </div> + + <div v-else class="space-y-4"> + <div> + <label class="block text-sm font-medium mb-1 text-gray-700 dark:text-white">New Password</label> + <input + type="password" + v-model="newPassword" + class="w-full p-3 rounded-lg border border-gray-300 dark:border-neutral-700 dark:bg-neutral-800 dark:text-white" + /> + </div> + + <div> + <label class="block text-sm font-medium mb-1 text-gray-700 dark:text-white">Confirm New Password</label> + <input + type="password" + v-model="confirmPassword" + class="w-full p-3 rounded-lg border border-gray-300 dark:border-neutral-700 dark:bg-neutral-800 dark:text-white" + /> + </div> + + <button + @click="handleChangePassword" + :disabled="!newPassword || !confirmPassword || newPassword !== confirmPassword" + class="w-full py-3 text-white rounded-lg font-medium bg-blue-600 hover:bg-blue-700 transition disabled:opacity-50 disabled:pointer-events-none" + > + Update Password + </button> + </div> + </div> + </div> + </div> + </template> + + <script setup> + import { ref, onMounted } from 'vue' + import { getAuth, updateProfile as firebaseUpdateProfile, updatePassword } from 'firebase/auth' + import { getFirestore, doc, getDoc, setDoc } from 'firebase/firestore' + + const auth = getAuth() + const db = getFirestore() + + const displayName = ref('') + const description = ref('') + const hidden = ref(false) + + const newPassword = ref('') + const confirmPassword = ref('') + + const isGoogleUser = ref(false) + + onMounted(async () => { + const user = auth.currentUser + if (user) { + displayName.value = user.displayName || '' + const docRef = doc(db, 'users', user.uid) + const docSnap = await getDoc(docRef) + if (docSnap.exists()) { + const data = docSnap.data() + description.value = data.description || '' + hidden.value = data.hidden || false + } + + // Detect if user signed in with Google + isGoogleUser.value = user.providerData.some( + (provider) => provider.providerId === 'google.com' + ) + } + }) + + const handleProfileUpdate = async () => { + const user = auth.currentUser + if (user) { + try { + await firebaseUpdateProfile(user, { + displayName: displayName.value + }) + + await setDoc(doc(db, 'users', user.uid), { + displayName: displayName.value, + description: description.value, + hidden: hidden.value + }) + + alert('Profile updated successfully!') + } catch (error) { + console.error('Error updating profile:', error) + alert('Failed to update profile.') + } + } + } + + const handleChangePassword = async () => { + const user = auth.currentUser + if (isGoogleUser.value) { + alert('Password changes are not allowed for Google accounts. Please change your password via your Google account settings.') + return + } + if (user && newPassword.value === confirmPassword.value) { + try { + await updatePassword(user, newPassword.value) + alert('Password updated successfully!') + newPassword.value = '' + confirmPassword.value = '' + } catch (error) { + console.error('Error updating password:', error) + alert('Failed to update password.') + } + } else { + alert("Passwords don't match.") + } + } + </script> + \ No newline at end of file