From 8899bd205f929fbd0157c8bebfd28e8ffde9a229 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Thu, 8 Oct 2026 14:42:31 -0400 Subject: [PATCH] DRY pass #2, batch 5, F15: the four signed-out pages share AuthLayout (#5372) Sign in, register, forgot and reset each wrote the same page: a centred column, the app icon, a title, a subtitle, the form and a footer link. That is now components/AuthLayout.vue, with the title as a prop and the subtitle, the form, the footer and anything after it as slots. The footer links wear the new .text-link class. Markup and classes are unchanged, so the pages render as before. Co-Authored-By: Claude Opus 5.5 --- frontend/src/components/AuthLayout.vue | 37 ++++++++ frontend/src/style.css | 4 + frontend/src/views/ForgotPasswordView.vue | 77 +++++++--------- frontend/src/views/LoginView.vue | 101 ++++++++++----------- frontend/src/views/RegisterView.vue | 103 ++++++++++------------ frontend/src/views/ResetPasswordView.vue | 89 ++++++++----------- 6 files changed, 202 insertions(+), 209 deletions(-) create mode 100644 frontend/src/components/AuthLayout.vue diff --git a/frontend/src/components/AuthLayout.vue b/frontend/src/components/AuthLayout.vue new file mode 100644 index 0000000..b877aa2 --- /dev/null +++ b/frontend/src/components/AuthLayout.vue @@ -0,0 +1,37 @@ + + + diff --git a/frontend/src/style.css b/frontend/src/style.css index 3c9dfd4..162ffce 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -334,6 +334,10 @@ body { .form-error { @apply text-sm text-red-600 dark:text-red-400; } + /* A link that is a way out of a form: "Create one", "Back to sign in". */ + .text-link { + @apply font-semibold text-brand-700 hover:underline dark:text-brand; + } /* A form's error as a banner over its submit button. */ .alert-error { @apply rounded-lg bg-red-50 px-3 py-2 text-sm text-red-700 dark:bg-red-950/50 dark:text-red-300; diff --git a/frontend/src/views/ForgotPasswordView.vue b/frontend/src/views/ForgotPasswordView.vue index ae66851..73e6bf7 100644 --- a/frontend/src/views/ForgotPasswordView.vue +++ b/frontend/src/views/ForgotPasswordView.vue @@ -3,14 +3,13 @@ import { ref } from "vue"; import { useRoute } from "vue-router"; import { api } from "../api/client"; import { errorMessage } from "../api/errors"; -import { useConfigStore } from "../stores/config"; import BaseInput from "../components/BaseInput.vue"; +import AuthLayout from "../components/AuthLayout.vue"; import BaseButton from "../components/BaseButton.vue"; // Ask for a password reset link by email (#5266). The server answers the same way // whether or not the address has an account, so this page does too. -const config = useConfigStore(); const route = useRoute(); const email = ref(typeof route.query.email === "string" ? route.query.email : ""); @@ -33,52 +32,40 @@ async function submit() { diff --git a/frontend/src/views/LoginView.vue b/frontend/src/views/LoginView.vue index 2d3a32c..2f9e46d 100644 --- a/frontend/src/views/LoginView.vue +++ b/frontend/src/views/LoginView.vue @@ -4,6 +4,7 @@ import { useRouter, useRoute } from "vue-router"; import { useSessionStore } from "../stores/session"; import { useConfigStore } from "../stores/config"; import BaseInput from "../components/BaseInput.vue"; +import AuthLayout from "../components/AuthLayout.vue"; import BaseButton from "../components/BaseButton.vue"; import { errorMessage } from "../api/errors"; @@ -41,62 +42,52 @@ async function submit() {