feat(setup): post-link redirects to SPA so first-setup matches live UI
CI / test (push) Has been cancelled
CI / test (push) Has been cancelled
Twig configure page replaced with a redirect: SetupController's index,
register, login, and the legacy /configure route all post-link redirect
to /?setup=<deviceId> for unconfigured devices. The SPA's HomeView
auto-opens its existing settings sheet for that id, with the same
controls everyone uses for live edits — themed to the user's choice,
pre-populated from the device record.
Fixes Matt's report:
- "every 6 hours" lost on save: the configure form posted
rotation_interval_hours but the controller read
rotation_interval_minutes, so the value silently defaulted to
1440 every time. Now the SPA's PATCH flow handles it correctly.
- "old settings still there in live settings": SPA settings sheet
pre-populates from the device's current state via onEdit.
- "uniqueness window in setup but not live settings": removed
from the (now-deleted) Twig form; both surfaces are consistent.
- "color scheme didn't match account": SPA respects the user's
theme natively (data-theme on <html>), so the first-setup screen
looks like the rest of the app.
Also adds a "Sign out of pictureFrame" link at the bottom of the
per-frame settings sheet (the existing /settings tab still has the
primary one). Easy escape hatch from a deeply-nested settings flow.
Tests:
- SetupControllerTest: S-03/04/05/06/08 updated for new redirect
targets, S-CLAIM-03 updated.
- HomeView.test.ts: useRoute now mockable per-test, two new cases
pinning the ?setup=<id> auto-open and its absence.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -231,6 +231,8 @@
|
||||
class="home-view__remove"
|
||||
@click="removeConfirmOpen = true"
|
||||
>Remove this frame</button>
|
||||
|
||||
<a href="/logout" class="home-view__logout">Sign out of pictureFrame</a>
|
||||
</BaseBottomSheet>
|
||||
|
||||
<Teleport to="body">
|
||||
@@ -279,7 +281,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { useDevicesStore } from '@/stores/devices'
|
||||
import { useUploadStore } from '@/stores/upload'
|
||||
import { useDeviceMercure } from '@/composables/useDeviceMercure'
|
||||
@@ -402,6 +404,7 @@ import OrientationPicker from '@/components/OrientationPicker.vue'
|
||||
import PullToRefresh from '@/components/PullToRefresh.vue'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const devicesStore = useDevicesStore()
|
||||
const uploadStore = useUploadStore()
|
||||
|
||||
@@ -409,9 +412,22 @@ const uploadStore = useUploadStore()
|
||||
// (and on PATCH/lock/unlock); the composable splats it into the store.
|
||||
useDeviceMercure()
|
||||
|
||||
onMounted(() => {
|
||||
devicesStore.fetchDevices()
|
||||
onMounted(async () => {
|
||||
await devicesStore.fetchDevices()
|
||||
document.addEventListener('visibilitychange', onVisibility)
|
||||
|
||||
// First-time setup landing: SetupController redirects new users to
|
||||
// /?setup=<deviceId> after register/login, instead of a separate
|
||||
// Twig configure page. Auto-open the settings sheet for that device
|
||||
// so the user sees the same rich UI everyone else uses for live edits
|
||||
// — pre-populated, themed, with no duplicated form to maintain.
|
||||
const setupId = Number(route.query.setup)
|
||||
if (setupId) {
|
||||
onEdit(setupId)
|
||||
// Clean the query param off the URL so a refresh doesn't keep
|
||||
// re-opening the sheet, but keep the user on the home view.
|
||||
router.replace({ query: { ...route.query, setup: undefined } })
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
@@ -1150,5 +1166,21 @@ async function saveSettings() {
|
||||
border-color: var(--color-danger, #c0392b);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&__logout {
|
||||
display: block;
|
||||
margin-top: var(--space-3);
|
||||
text-align: center;
|
||||
font-size: var(--text-xs);
|
||||
color: var(--color-text-muted);
|
||||
text-decoration: none;
|
||||
padding: var(--space-2);
|
||||
|
||||
&:hover, &:focus-visible {
|
||||
color: var(--color-text);
|
||||
text-decoration: underline;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user