refactor(profile): migrate member/profile to PageShell vocabulary

- Replace .profile-page wrapper + nested form with <PageShell as=form @submit.prevent>
- Replace .profile-columns grid with <ColumnsLayout cols=2> + named slots
- Replace all 5 .profile-col-inset wrappers with <PageSection> components
- Replace <hr class=section-divider> separators with <PageSection divider=top>
- Add type=button to Sign In CTA (prevent accidental form submit)
- Delete .profile-page, .profile-authenticated, .page-content, .profile-main, .profile-columns, .profile-col-left/right, .profile-col-inset asymmetric padding, and collapse rules
This commit is contained in:
Jennie Robinson Faber 2026-04-08 17:10:21 +01:00
parent 37fceac3fd
commit 8365feb970

View file

@ -1,5 +1,5 @@
<template>
<div class="profile-page">
<PageShell as="form" @submit.prevent="handleSubmit">
<!-- Loading State -->
<div v-if="loading" class="loading-state">
<p style="color: var(--text-faint)">Loading your profile...</p>
@ -11,6 +11,7 @@
Please sign in to access your profile settings.
</p>
<button
type="button"
class="btn btn-primary"
@click="
openLoginModal({
@ -23,7 +24,7 @@
</button>
</div>
<div v-else class="profile-authenticated">
<template v-else>
<!-- PAGE HEADER -->
<PageHeader
title="Edit Profile"
@ -42,13 +43,11 @@
</NuxtLink>
</PageHeader>
<!-- TWO-COLUMN FORM -->
<form class="page-content" @submit.prevent="handleSubmit">
<div class="profile-main">
<div class="profile-columns">
<!-- TWO-COLUMN FORM BODY -->
<ColumnsLayout cols="2">
<!-- ======== LEFT COLUMN ======== -->
<div class="profile-col-left">
<div class="profile-col-inset">
<template #left>
<PageSection>
<div class="section-label">Basics</div>
<div class="field">
@ -99,11 +98,10 @@
</div>
<PrivacyToggle v-model="formData.avatarPrivacy" />
</div>
</div>
</PageSection>
<!-- About You -->
<hr class="section-divider" />
<div class="profile-col-inset">
<PageSection divider="top">
<div class="section-label">About You</div>
<div class="row-2">
@ -151,11 +149,10 @@
/>
<PrivacyToggle v-model="formData.craftTagsPrivacy" />
</div>
</div>
</PageSection>
<!-- Visibility -->
<hr class="section-divider" />
<div class="profile-col-inset">
<PageSection divider="top">
<div class="section-label">Visibility</div>
<div class="toggle-field">
@ -171,12 +168,12 @@
>
</div>
</div>
</div>
</div>
</PageSection>
</template>
<!-- ======== RIGHT COLUMN ======== -->
<div class="profile-col-right">
<div class="profile-col-inset">
<template #right>
<PageSection>
<div class="section-label">Community Connections</div>
<div class="field">
@ -247,11 +244,10 @@
</div>
</div>
</div>
</div>
</PageSection>
<!-- Notifications -->
<hr class="section-divider" />
<div class="profile-col-inset">
<PageSection divider="top">
<div class="section-label">Notifications</div>
<div class="toggle-field">
@ -292,9 +288,9 @@
>
</div>
</div>
</div>
</div>
</div>
</PageSection>
</template>
</ColumnsLayout>
<!-- ======== SAVE BAR ======== -->
<div class="save-bar">
@ -315,13 +311,11 @@
saveError
}}</span>
</div>
</div>
</form>
</div>
</template>
<!-- Tag Suggest Modal -->
<TagSuggestModal v-model:open="showTagSuggestModal" :pool="tagSuggestPool" />
</div>
</PageShell>
</template>
<script setup>
@ -546,20 +540,6 @@ useHead({
</script>
<style scoped>
.profile-page {
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
}
.profile-authenticated {
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
}
/* ---- LOADING / EMPTY STATE ---- */
.loading-state {
display: flex;
@ -570,66 +550,6 @@ useHead({
text-align: center;
}
.profile-page > .loading-state {
flex: 1;
}
/* ---- CONTENT AREA ---- */
.page-content {
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
padding: 0;
}
.profile-main {
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
}
/* ---- TWO-COLUMN LAYOUT ---- */
.profile-columns {
flex: 1;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr;
gap: 0;
align-items: stretch;
min-height: 0;
}
.profile-col-left,
.profile-col-right {
display: flex;
flex-direction: column;
min-height: 0;
align-self: stretch;
}
@media (min-width: 1025px) {
.profile-col-left {
border-right: 1px dashed var(--border);
}
}
.profile-col-left > .profile-col-inset:first-of-type,
.profile-col-right > .profile-col-inset:first-of-type {
padding-top: 14px;
}
.profile-col-left .profile-col-inset {
padding-left: 28px;
padding-right: 24px;
}
.profile-col-right .profile-col-inset {
padding-left: 24px;
padding-right: 28px;
}
/* ---- MULTI-COLUMN ROWS ---- */
.row-2 {
display: grid;
@ -783,37 +703,11 @@ useHead({
}
/* ---- RESPONSIVE ---- */
@media (max-width: 1024px) {
.profile-columns {
grid-template-columns: 1fr;
grid-template-rows: auto;
}
.profile-col-left {
border-right: none;
border-bottom: 1px dashed var(--border);
padding-bottom: 20px;
margin-bottom: 20px;
}
.profile-col-left .profile-col-inset,
.profile-col-right .profile-col-inset {
padding-left: 28px;
padding-right: 28px;
}
}
@media (max-width: 768px) {
.row-2 {
grid-template-columns: 1fr;
}
.profile-col-left .profile-col-inset,
.profile-col-right .profile-col-inset {
padding-left: 16px;
padding-right: 16px;
}
.save-bar {
padding-left: 16px;
padding-right: 16px;