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:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user