From 91173021b2026a0693bf82cade23e7090ba3e9f9 Mon Sep 17 00:00:00 2001 From: "Edward Tirado Jr." Date: Sun, 5 Apr 2026 00:36:20 -0500 Subject: [PATCH] hooked up all items on the list settings section --- app/app.vue | 7 + app/assets/css/variables.css | 2 +- app/components/common/card.vue | 4 +- app/components/common/page-title.vue | 1 - .../forms/auth/new-password-form.vue | 56 ++++++ .../forms/auth/registration-form.vue | 45 +++++ app/components/forms/create-list-form.vue | 13 +- app/components/header.vue | 1 - app/components/list-settings.vue | 175 +++++++++++------- app/components/movie-list.vue | 9 +- app/components/panels/movie-details.vue | 16 +- app/components/panels/movie-search.vue | 7 +- app/composables/$api.ts | 4 +- app/composables/useAuth.ts | 50 ++++- app/layouts/auth.vue | 3 +- app/middleware/auth.global.ts | 10 +- app/pages/account.vue | 24 +-- app/pages/auth/login.vue | 13 +- app/pages/auth/register.vue | 32 ++++ app/pages/auth/reset-password/[token].vue | 30 +++ app/pages/index.vue | 3 +- app/pages/invitations/[token]/accept.vue | 62 +++++++ app/pages/invitations/[token]/decline.vue | 11 ++ app/pages/lists/[id].vue | 60 +++--- app/pages/lists/index.vue | 78 ++++---- app/types/api.ts | 2 + app/types/collaborator.ts | 6 - app/types/movie-list-group.ts | 7 + app/types/movie-list-settings.ts | 4 +- app/types/movie-list.ts | 8 +- app/types/movie.ts | 6 +- app/types/user.ts | 7 + 32 files changed, 578 insertions(+), 178 deletions(-) create mode 100644 app/components/forms/auth/new-password-form.vue create mode 100644 app/components/forms/auth/registration-form.vue create mode 100644 app/pages/auth/register.vue create mode 100644 app/pages/auth/reset-password/[token].vue create mode 100644 app/pages/invitations/[token]/accept.vue create mode 100644 app/pages/invitations/[token]/decline.vue create mode 100644 app/types/api.ts delete mode 100644 app/types/collaborator.ts create mode 100644 app/types/movie-list-group.ts create mode 100644 app/types/user.ts diff --git a/app/app.vue b/app/app.vue index b7f3694..763eb3c 100644 --- a/app/app.vue +++ b/app/app.vue @@ -14,6 +14,13 @@ body { background-color: #f5f5f5; } +.content { + display: flex; + flex-direction: column; + gap: 1rem; + margin: 1rem 0; +} + /* sm */ @media (min-width: 640px) { } diff --git a/app/assets/css/variables.css b/app/assets/css/variables.css index eb0d4a8..21b5ea4 100644 --- a/app/assets/css/variables.css +++ b/app/assets/css/variables.css @@ -1,4 +1,4 @@ :root { --color-primary: #000; --color-surface: #fff; -} \ No newline at end of file +} diff --git a/app/components/common/card.vue b/app/components/common/card.vue index d00eeae..32bc1ff 100644 --- a/app/components/common/card.vue +++ b/app/components/common/card.vue @@ -11,8 +11,10 @@ \ No newline at end of file diff --git a/app/components/common/page-title.vue b/app/components/common/page-title.vue index 8103f99..ed38462 100644 --- a/app/components/common/page-title.vue +++ b/app/components/common/page-title.vue @@ -13,6 +13,5 @@ const props = defineProps<{ h1 { font-size: 2rem; font-weight: bold; - margin-bottom: 1rem; } \ No newline at end of file diff --git a/app/components/forms/auth/new-password-form.vue b/app/components/forms/auth/new-password-form.vue new file mode 100644 index 0000000..a98eccc --- /dev/null +++ b/app/components/forms/auth/new-password-form.vue @@ -0,0 +1,56 @@ + + + + + \ No newline at end of file diff --git a/app/components/forms/auth/registration-form.vue b/app/components/forms/auth/registration-form.vue new file mode 100644 index 0000000..2c16f70 --- /dev/null +++ b/app/components/forms/auth/registration-form.vue @@ -0,0 +1,45 @@ + + + + + \ No newline at end of file diff --git a/app/components/forms/create-list-form.vue b/app/components/forms/create-list-form.vue index a92539d..c3d657a 100644 --- a/app/components/forms/create-list-form.vue +++ b/app/components/forms/create-list-form.vue @@ -21,7 +21,7 @@ const createList = () => { \ No newline at end of file diff --git a/app/components/header.vue b/app/components/header.vue index 077a9be..095f01e 100644 --- a/app/components/header.vue +++ b/app/components/header.vue @@ -28,7 +28,6 @@ gap: 1rem; font: bold 1.5rem sans-serif; justify-content: center; - margin-bottom: 2rem; } .links { diff --git a/app/components/list-settings.vue b/app/components/list-settings.vue index f5252c4..b50429f 100644 --- a/app/components/list-settings.vue +++ b/app/components/list-settings.vue @@ -1,91 +1,123 @@ \ No newline at end of file diff --git a/app/composables/$api.ts b/app/composables/$api.ts index 1145da3..abfd25b 100644 --- a/app/composables/$api.ts +++ b/app/composables/$api.ts @@ -13,8 +13,8 @@ export const $api = ( ...(xsrfToken.value ? {'X-XSRF-TOKEN': xsrfToken.value} : {}), }, onResponseError({response}) { - if (response.status === 401) { - navigateTo('/auth/login') + if (response.status === 401 || response.status === 419) { + useAuth().logout() } }, ...options, diff --git a/app/composables/useAuth.ts b/app/composables/useAuth.ts index d362854..222f0ca 100644 --- a/app/composables/useAuth.ts +++ b/app/composables/useAuth.ts @@ -10,10 +10,54 @@ export const useAuth = () => { await navigateTo('/') } - const logout = async () => { - await $api('/api/logout', {method: 'POST'}) + const register = async (email: string, username: string) => { + await $fetch('/sanctum/csrf-cookie', { + baseURL: config.public.apiBase, + credentials: 'include', + }) + await $api('/api/register', {method: 'POST', body: {email, username}}) await navigateTo('/auth/login') } - return {login, logout} + const resetPassword = async (password: string, passwordConfirmation: string, token: string, email: string) => { + await $fetch('/sanctum/csrf-cookie', { + baseURL: config.public.apiBase, + credentials: 'include', + }) + await $api('/api/reset-password', { + method: 'POST', + body: { + password, + password_confirmation: passwordConfirmation, + token, + email + }, + onResponseError: (context) => { + if (context.response.status === 401) { + throw new Error('TOKEN_EXPIRED') + } + } + }) + await navigateTo('/lists') + } + + const xsrfToken = useCookie('XSRF-TOKEN') + + const logout = async () => { + await $fetch('/api/logout', { + baseURL: config.public.apiBase, + method: 'POST', + credentials: 'include', + headers: { + ...(xsrfToken.value ? {'X-XSRF-TOKEN': xsrfToken.value} : {}), + }, + }).catch(() => { + alert("Failed to logout. Please try again.") + }) + + useCookie('XSRF-TOKEN').value = '' + navigateTo('/auth/login') + } + + return {login, register, resetPassword, logout} } diff --git a/app/layouts/auth.vue b/app/layouts/auth.vue index 864a55c..bf617ce 100644 --- a/app/layouts/auth.vue +++ b/app/layouts/auth.vue @@ -10,6 +10,7 @@ justify-content: center; align-items: center; min-height: 100vh; - padding: 1rem; + flex-direction: column; + gap: 3rem; } diff --git a/app/middleware/auth.global.ts b/app/middleware/auth.global.ts index 3212b86..b329c1f 100644 --- a/app/middleware/auth.global.ts +++ b/app/middleware/auth.global.ts @@ -1,6 +1,12 @@ export default defineNuxtRouteMiddleware((to) => { - const publicRoutes = ['/auth/login'] - if (publicRoutes.includes(to.path)) return + const publicRoutes = [ + 'auth-login', + 'auth-register', + 'auth-reset-password', + 'invitations-token-accept', + 'invitations-token-decline', + ] + if (publicRoutes.includes(String(to.name))) return const xsrfToken = useCookie('XSRF-TOKEN') if (!xsrfToken.value) { diff --git a/app/pages/account.vue b/app/pages/account.vue index de2f29c..4fb9e74 100644 --- a/app/pages/account.vue +++ b/app/pages/account.vue @@ -6,22 +6,24 @@ import ProfileForm from "~/components/forms/profile-form.vue"; diff --git a/app/pages/auth/login.vue b/app/pages/auth/login.vue index 6f800ce..42ca645 100644 --- a/app/pages/auth/login.vue +++ b/app/pages/auth/login.vue @@ -7,10 +7,21 @@ definePageMeta({ \ No newline at end of file diff --git a/app/pages/auth/register.vue b/app/pages/auth/register.vue new file mode 100644 index 0000000..e6f22ec --- /dev/null +++ b/app/pages/auth/register.vue @@ -0,0 +1,32 @@ + + + + + \ No newline at end of file diff --git a/app/pages/auth/reset-password/[token].vue b/app/pages/auth/reset-password/[token].vue new file mode 100644 index 0000000..35c34f5 --- /dev/null +++ b/app/pages/auth/reset-password/[token].vue @@ -0,0 +1,30 @@ + + + + + \ No newline at end of file diff --git a/app/pages/index.vue b/app/pages/index.vue index b00cc92..86101b4 100644 --- a/app/pages/index.vue +++ b/app/pages/index.vue @@ -6,9 +6,8 @@ const welcomeMessage = computed(() => `Welcome, ${user}!`)