feat: orientation model, password confirm, frontend build

- Collapse orientation to landscape/portrait (ribbon left = portrait standard)
- Add OrientationPicker component and wire settings sheet in HomeView
- Add password confirmation field to registration form (RepeatedType)
- Build frontend SPA to public/build/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-04 16:59:03 -04:00
parent 6c7c7a1a6f
commit 6c891d6fad
119 changed files with 82314 additions and 75 deletions
+91 -1
View File
@@ -28,7 +28,9 @@
:name="devicesStore.devices[0].name"
size="large"
status="ok"
:orientation="devicesStore.devices[0].orientation"
@add-photo="onAddPhoto"
@edit="onEdit"
/>
</div>
@@ -41,16 +43,50 @@
:name="device.name"
size="compact"
status="ok"
:orientation="device.orientation"
@add-photo="onAddPhoto"
@edit="onEdit"
/>
</div>
</main>
<!-- Frame settings sheet -->
<BaseBottomSheet v-model="sheetOpen" label="Frame settings">
<h2 class="home-view__sheet-title">Frame settings</h2>
<div class="home-view__sheet-field">
<BaseInput
v-model="editName"
label="Frame name"
maxlength="100"
/>
</div>
<div class="home-view__sheet-field">
<p class="home-view__sheet-label">Orientation</p>
<OrientationPicker v-model="editOrientation" />
</div>
<BaseButton
variant="primary"
class="home-view__sheet-save"
:disabled="saving"
@click="saveSettings"
>
{{ saving ? 'Saving…' : 'Save' }}
</BaseButton>
</BaseBottomSheet>
</template>
<script setup lang="ts">
import { onMounted } from 'vue'
import { onMounted, ref } from 'vue'
import { useDevicesStore } from '@/stores/devices'
import type { Device } from '@/types'
import FrameCard from '@/components/FrameCard.vue'
import BaseBottomSheet from '@/components/BaseBottomSheet.vue'
import BaseButton from '@/components/BaseButton.vue'
import BaseInput from '@/components/BaseInput.vue'
import OrientationPicker from '@/components/OrientationPicker.vue'
const devicesStore = useDevicesStore()
@@ -60,6 +96,37 @@ function onAddPhoto(deviceId: number) {
// Photo upload flow — Epic 3
console.log('add-photo', deviceId)
}
// ── Settings sheet ────────────────────────────────────────────────────────────
const sheetOpen = ref(false)
const saving = ref(false)
const editingDevice = ref<Device | null>(null)
const editName = ref('')
const editOrientation = ref<Device['orientation']>('landscape')
function onEdit(deviceId: number) {
const device = devicesStore.devices.find(d => d.id === deviceId)
if (!device) return
editingDevice.value = device
editName.value = device.name
editOrientation.value = device.orientation
sheetOpen.value = true
}
async function saveSettings() {
if (!editingDevice.value) return
saving.value = true
try {
await devicesStore.updateDevice(editingDevice.value.id, {
name: editName.value.trim() || editingDevice.value.name,
orientation: editOrientation.value,
})
sheetOpen.value = false
} finally {
saving.value = false
}
}
</script>
<style scoped lang="scss">
@@ -122,5 +189,28 @@ function onAddPhoto(deviceId: number) {
flex-direction: column;
gap: var(--space-2);
}
&__sheet-title {
font-size: var(--text-md);
font-weight: 700;
margin-bottom: var(--space-4);
}
&__sheet-field {
margin-bottom: var(--space-4);
}
&__sheet-label {
display: block;
font-size: var(--text-sm);
font-weight: 600;
color: var(--color-text-muted);
margin-bottom: var(--space-2);
}
&__sheet-save {
width: 100%;
margin-top: var(--space-2);
}
}
</style>