@nuxt-customer-portal/ui 0.9.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @nuxt-customer-portal/ui
2
2
 
3
+ ## 0.10.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 1235d0f: Let portal administrators upload separate desktop and mobile authentication backgrounds in Appearance settings. Add responsive image selection, single-image fallback, preview and removal controls, validated image uploads, and English/Dutch descriptions. Keep existing settings compatible. Position authentication forms near the top on mobile while preserving desktop positioning, with or without a background image.
8
+
9
+ ### Patch Changes
10
+
11
+ - 1235d0f: Redirect the portal home route to `/dashboard` instead of showing the public landing page. Preserve dashboard authentication, onboarding, and saved homepage content. Send portal logout directly to `/login` instead of the home route, and remove the home back button from authentication pages.
12
+
13
+ Use a neutral welcome heading on the sign-in page in English and Dutch so it also welcomes first-time visitors.
14
+
15
+ Show translated email and password prompts instead of technical validation errors when sign-in fields are empty or missing.
16
+
17
+ - Updated dependencies [f115496]
18
+ - @nuxt-customer-portal/core@0.10.0
19
+
3
20
  ## 0.9.1
4
21
 
5
22
  ### Patch Changes
@@ -26,7 +26,7 @@ const signOut = async () => {
26
26
  await authClient.signOut()
27
27
  userStore.clearUserData()
28
28
  emit('navigate')
29
- await navigateTo('/')
29
+ await navigateTo('/login', { replace: true })
30
30
  }
31
31
 
32
32
  const userMenuItems = computed(() => {
@@ -1,22 +1,21 @@
1
1
  <!-- eslint-disable vue/multi-word-component-names -->
2
2
  <script setup lang="ts">
3
+ import { resolveAuthBackgrounds, type AuthBackgroundBranding } from '../utils/auth-background'
4
+
3
5
  const route = useRoute()
4
6
  const { t } = useI18n()
5
7
  const bootstrap = useState<{ adminExists?: boolean; completed?: boolean } | null>('portal-bootstrap-state', () => null)
8
+ const settings = useState<{ branding?: AuthBackgroundBranding } | null>('portal-runtime-settings', () => null)
9
+ const backgrounds = computed(() => resolveAuthBackgrounds(settings.value?.branding))
6
10
  </script>
7
11
 
8
12
  <template>
9
- <div class="auth-shell h-screen flex items-center justify-center px-4">
10
- <UButton
11
- icon="i-lucide-chevron-left"
12
- to="/"
13
- size="xl"
14
- color="neutral"
15
- variant="subtle"
16
- class="auth-back-button absolute left-8 top-8 rounded-full z-10"
17
- />
18
-
19
- <UPageCard variant="subtle" class="max-w-sm w-full">
13
+ <div class="auth-shell" :class="{ 'auth-shell--illustrated': backgrounds.desktop }">
14
+ <picture v-if="backgrounds.desktop" class="auth-background" aria-hidden="true">
15
+ <source media="(max-width: 1023px)" :srcset="backgrounds.mobile" />
16
+ <img :src="backgrounds.desktop" alt="" fetchpriority="high" decoding="async" />
17
+ </picture>
18
+ <UPageCard variant="subtle" class="auth-card relative w-full max-w-sm shrink-0">
20
19
  <UAlert
21
20
  v-if="route.path === '/signup' && bootstrap && !bootstrap.adminExists"
22
21
  class="mb-5"
@@ -30,3 +29,50 @@ const bootstrap = useState<{ adminExists?: boolean; completed?: boolean } | null
30
29
  </UPageCard>
31
30
  </div>
32
31
  </template>
32
+
33
+ <style scoped>
34
+ .auth-shell {
35
+ position: relative;
36
+ isolation: isolate;
37
+ display: flex;
38
+ align-items: center;
39
+ justify-content: center;
40
+ min-height: 100dvh;
41
+ padding: max(1.5rem, env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right))
42
+ max(1.5rem, env(safe-area-inset-bottom)) max(1rem, env(safe-area-inset-left));
43
+ }
44
+ .auth-background {
45
+ position: absolute;
46
+ inset: 0;
47
+ z-index: 0;
48
+ overflow: hidden;
49
+ pointer-events: none;
50
+ }
51
+ .auth-background img {
52
+ width: 100%;
53
+ height: 100%;
54
+ object-fit: cover;
55
+ object-position: center bottom;
56
+ }
57
+ .auth-card {
58
+ z-index: 1;
59
+ }
60
+ .auth-shell--illustrated .auth-card {
61
+ background: var(--ui-bg-elevated);
62
+ box-shadow: 0 1.5rem 4.5rem color-mix(in srgb, var(--ui-text) 12%, transparent);
63
+ }
64
+ @media (max-width: 1023px) {
65
+ .auth-shell {
66
+ align-items: flex-start;
67
+ }
68
+ }
69
+ @media (min-width: 1024px) {
70
+ .auth-shell--illustrated {
71
+ justify-content: flex-start;
72
+ padding-inline: clamp(3rem, 12vw, 12rem);
73
+ }
74
+ .auth-background img {
75
+ object-position: right center;
76
+ }
77
+ }
78
+ </style>
@@ -0,0 +1,11 @@
1
+ export interface AuthBackgroundBranding {
2
+ authBackgroundDesktop?: string
3
+ authBackgroundMobile?: string
4
+ }
5
+
6
+ export function resolveAuthBackgrounds(branding?: AuthBackgroundBranding | null) {
7
+ return {
8
+ desktop: branding?.authBackgroundDesktop || branding?.authBackgroundMobile || '',
9
+ mobile: branding?.authBackgroundMobile || branding?.authBackgroundDesktop || ''
10
+ }
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuxt-customer-portal/ui",
3
- "version": "0.9.1",
3
+ "version": "0.10.0",
4
4
  "license": "MIT",
5
5
  "homepage": "https://nuxt-customer-portal.com",
6
6
  "repository": {
@@ -39,7 +39,7 @@
39
39
  "remark-parse": "^11.0.0",
40
40
  "unified": "^11.0.5",
41
41
  "zod": "^4.4.3",
42
- "@nuxt-customer-portal/core": "^0.9.1"
42
+ "@nuxt-customer-portal/core": "^0.10.0"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "nuxt": "^4.5.1",
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  id: 'ui',
3
- version: '0.9.1',
3
+ version: '0.10.0',
4
4
  source: '@nuxt-customer-portal/ui',
5
5
  dependsOn: ['core']
6
6
  }