diff --git a/.gitignore b/.gitignore index 12b90b4..bcd2ed5 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,6 @@ Thumbs.db # Runtime .pids .gstack/ + +# Playwright MCP artifacts +.playwright-mcp/ diff --git a/frontend/src/components/LegalPage.vue b/frontend/src/components/LegalPage.vue index 23b9617..f3922f6 100644 --- a/frontend/src/components/LegalPage.vue +++ b/frontend/src/components/LegalPage.vue @@ -2,37 +2,7 @@
- +
@@ -42,30 +12,22 @@
-
- -
+
diff --git a/frontend/src/components/PublicFooter.vue b/frontend/src/components/PublicFooter.vue new file mode 100644 index 0000000..3938808 --- /dev/null +++ b/frontend/src/components/PublicFooter.vue @@ -0,0 +1,45 @@ + + + diff --git a/frontend/src/components/PublicNav.vue b/frontend/src/components/PublicNav.vue new file mode 100644 index 0000000..9096986 --- /dev/null +++ b/frontend/src/components/PublicNav.vue @@ -0,0 +1,253 @@ + + + + + diff --git a/frontend/src/components/PublicShell.vue b/frontend/src/components/PublicShell.vue new file mode 100644 index 0000000..48543a2 --- /dev/null +++ b/frontend/src/components/PublicShell.vue @@ -0,0 +1,125 @@ + + + + + diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index 5b238e4..72ba43e 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -28,13 +28,13 @@ const router = createRouter({ path: '/login', name: 'Login', component: Login, - meta: { requiresAuth: false } + meta: { requiresAuth: false, fullBleed: true } }, { path: '/register', name: 'Register', component: () => import('@/views/Register.vue'), - meta: { requiresAuth: false } + meta: { requiresAuth: false, fullBleed: true } }, { path: '/verify', @@ -46,7 +46,7 @@ const router = createRouter({ path: '/book/:slug?', name: 'PublicBooking', component: () => import('@/views/PublicBooking.vue'), - meta: { requiresAuth: false, isPublic: true } + meta: { requiresAuth: false, isPublic: true, fullBleed: true } }, { path: '/dashboard', @@ -138,9 +138,15 @@ const router = createRouter({ }) // Navigation guard -router.beforeEach((to, _from, next) => { +router.beforeEach(async (to, _from, next) => { const authStore = useAuthStore() + // On a hard page load the user is fetched asynchronously; wait for it so + // role-based checks below don't reject a deep link before the user exists. + if (authStore.token && !authStore.user) { + await authStore.ready + } + if (to.meta.isPublic) { next() } else if (to.meta.requiresAuth && !authStore.isAuthenticated) { diff --git a/frontend/src/stores/auth.ts b/frontend/src/stores/auth.ts index 914f9b3..5d0a002 100644 --- a/frontend/src/stores/auth.ts +++ b/frontend/src/stores/auth.ts @@ -37,11 +37,14 @@ export const useAuthStore = defineStore('auth', () => { } } - initFromToken() + // Router guards await this so role checks don't run before the user loads + // on a hard page load (deep link to a manager/admin route). + const ready = initFromToken() return { token, user, + ready, isAuthenticated, isAdmin, isSuperadmin, diff --git a/frontend/src/views/Landing.vue b/frontend/src/views/Landing.vue index 2b4b751..9787ed7 100644 --- a/frontend/src/views/Landing.vue +++ b/frontend/src/views/Landing.vue @@ -2,36 +2,7 @@
- +
@@ -45,10 +16,7 @@

{{ ctaText }} - Vezi cum arată - Rezervă fără cont
-

Cont gratuit, gata în câteva secunde.

@@ -87,13 +55,53 @@
- -
+ +
+
+

Spații deschise rezervării acum

+ +
+ + +
+
+
+ + +
+
+
+

Vezi cum arată aplicația

+

Capturi demonstrative din ROA Space — nu sunt controale reale.

+
roa.space/dashboard + Demonstrație
-
- - -
-

Spații deschise rezervării acum

-

Alege un spațiu și rezervă fără cont, în câteva minute.

- -
- - -
+
@@ -280,17 +258,7 @@ - + @@ -298,6 +266,8 @@