From 0aa601c4ff021939e6852014c53c2b9ff1ee5b94 Mon Sep 17 00:00:00 2001 From: "Leon.Schmidt" Date: Tue, 18 Aug 2026 14:34:32 +0200 Subject: [PATCH] FIX - simplify VaultX account flows Keep login and registration actions visible in a dedicated footer and enlarge the password guidance. Remove the network badge, gradients, and glows from VaultX action buttons. Fix the registration mock by tracking registration state and persisting the submitted password so the new mock account can authenticate afterward. --- .../src/views/apps/CryptoApp.contract.test.ts | 51 +++ frontend/src/views/apps/CryptoApp.vue | 340 +++++++++--------- frontend/testserver/index.cjs | 8 +- 3 files changed, 235 insertions(+), 164 deletions(-) diff --git a/frontend/src/views/apps/CryptoApp.contract.test.ts b/frontend/src/views/apps/CryptoApp.contract.test.ts index 06d5aa9..9b55972 100644 --- a/frontend/src/views/apps/CryptoApp.contract.test.ts +++ b/frontend/src/views/apps/CryptoApp.contract.test.ts @@ -95,6 +95,57 @@ describe('VaultX crypto app contracts', () => { ) expect(source).toContain('class="password-strength"') + expect(source).not.toContain('class="auth-status"') + expect(source).toContain('class="auth-action-dock"') + expect(source).toContain('form="vault-auth-form"') + expect(source).toMatch( + /\.auth-action-dock\s*\{[^}]*flex:\s*0 0 auto;[^}]*border-top:[^}]*background:\s*#05080d;/s, + ) + expect(source).toMatch( + /\.auth\s*\{[^}]*min-height:\s*0;[^}]*flex:\s*1 1 auto;/s, + ) + expect(source).toMatch( + /\.auth-submit\s*\{[^}]*background:\s*var\(--vault-mint\);[^}]*box-shadow:\s*none;/s, + ) + for (const selector of [ + 'transfer-submit', + 'settlement-submit', + 'profile-save-button', + ]) { + expect(source).toMatch( + new RegExp( + `\\.${selector}\\s*\\{[^}]*background:\\s*var\\(--vault-mint\\);[^}]*box-shadow:\\s*none;`, + 's', + ), + ) + } + for (const selector of [ + 'detail-trade-action--buy', + 'detail-trade-action--sell', + 'trade-submit--buy', + 'trade-submit--sell', + ]) { + const rule = source.match( + new RegExp(`\\.${selector}\\s*\\{([^}]*)\\}`, 's'), + ) + expect(rule?.[1]).not.toContain('linear-gradient') + expect(rule?.[1]).toContain('box-shadow: none') + } + expect(source).toMatch( + /\.password-rules span\s*\{[^}]*font-size:\s*10\.5px;/s, + ) + expect(source).toMatch( + /\.password-strength i\.active\s*\{[^}]*background:\s*var\(--vault-mint\);/s, + ) + expect(source).not.toMatch( + /\.password-strength i\.active\s*\{[^}]*linear-gradient/s, + ) + expect(testServer).toContain('let cryptoRegistered = true') + expect(testServer).toContain('registered: cryptoRegistered') + expect(testServer).toContain( + "cryptoRegistered = testScenario !== 'crypto-register'", + ) + expect(testServer).toContain('cryptoPassword = password') expect(source).toContain('v-model="confirmPassword"') expect(source).toContain(' { >

{{ t('loading') }}

- -
- - {{ t('auth.network') }} -

{{ t('auth.eyebrow') }}

-

- {{ - t(authMode === 'login' ? 'auth.loginTitle' : 'auth.registerTitle') - }} -

- {{ t('auth.body') }} -
- {{ t('auth.serverSecured') }} - {{ t('auth.personalKey') }} - {{ t('auth.characterBound') }} -
-
-
- {{ t('auth.login') }}{{ t('auth.register') }} -
- {{ authMode === 'login' ? '01' : '02' }} -
- {{ t(`auth.${authMode}PanelTitle`) }} - {{ t(`auth.${authMode}PanelBody`) }} + { .auth { align-content: start; gap: 14px; + min-height: 0; + flex: 1 1 auto; padding-top: 12px !important; padding-bottom: 28px !important; } -.auth-status { - display: inline-flex; - gap: 6px; - align-items: center; - margin-top: 4px; - padding: 5px 9px; - color: var(--vault-mint); - font-size: 10px; - font-weight: 800; - background: rgba(101, 251, 210, 0.08); - border: 1px solid rgba(101, 251, 210, 0.16); - border-radius: var(--sky-radius-pill); -} -.auth-status i { - width: 5px; - height: 5px; - background: currentColor; - border-radius: 50%; - box-shadow: 0 0 7px currentColor; -} .auth-benefits { display: grid; grid-template-columns: repeat(3, 1fr); @@ -2067,7 +2062,7 @@ onUnmounted(() => { gap: 5px; padding: 7px 4px; color: rgba(255, 255, 255, 0.7); - font-size: 9px; + font-size: 10px; line-height: 1.15; background: rgba(255, 255, 255, 0.035); border: 1px solid rgba(255, 255, 255, 0.055); @@ -2128,7 +2123,7 @@ onUnmounted(() => { } .auth-panel__heading small { color: var(--muted); - font-size: 10px; + font-size: 11px; } .auth-form { padding: 0 4px 4px; @@ -2144,25 +2139,31 @@ onUnmounted(() => { border-radius: 3px; } .password-strength i.active { - background: linear-gradient(90deg, var(--vault-mint), var(--vault-blue)); + background: var(--vault-mint); } .password-strength span { display: block; margin-top: 5px; color: var(--muted); - font-size: 10px; + font-size: 11px; } .password-rules { display: grid; grid-template-columns: 1fr 1fr; - gap: 5px; + gap: 8px 6px; } .password-rules span { display: flex; - gap: 5px; + gap: 6px; align-items: center; color: rgba(255, 255, 255, 0.35); - font-size: 9px; + font-size: 10.5px; + line-height: 1.2; +} +.password-rules svg { + width: 15px; + height: 15px; + flex: 0 0 15px; } .password-rules span.done { color: var(--vault-mint); @@ -2185,15 +2186,26 @@ onUnmounted(() => { } .auth-consent small { color: var(--muted); - font-size: 9px; + font-size: 10px; line-height: 1.35; } +.auth-action-dock { + flex: 0 0 auto; + padding: 9px calc(var(--sky-page-gutter) + var(--sky-safe-area-right)) + calc(var(--sky-safe-area-bottom) + 9px) + calc(var(--sky-page-gutter) + var(--sky-safe-area-left)); + border-top: 1px solid rgba(255, 255, 255, 0.07); + background: #05080d; +} .auth-submit { min-height: 50px; color: #06110e; + font-size: 13px; font-weight: 900; - background: linear-gradient(135deg, #7dffe0, #4da3ff); - border-radius: 15px; + border: 1px solid rgba(101, 251, 210, 0.48); + border-radius: 12px; + background: var(--vault-mint); + box-shadow: none; } .auth-footer { display: flex; @@ -2202,7 +2214,7 @@ onUnmounted(() => { justify-content: center; padding: 9px 4px 2px; color: rgba(255, 255, 255, 0.36); - font-size: 9px; + font-size: 10px; } .form { display: grid; @@ -4042,12 +4054,13 @@ onUnmounted(() => { white-space: nowrap; } .detail-trade-action--buy { - background: linear-gradient(135deg, #179d7d, #0f8068); - box-shadow: 0 10px 24px rgba(23, 157, 125, 0.24); + background: #179d7d; + box-shadow: none; } .detail-trade-action--sell { - background: linear-gradient(135deg, #272d37, #171c24); + background: #202630; border: 1px solid rgba(255, 117, 136, 0.22); + box-shadow: none; } .vault-view { animation: vault-view-in 220ms cubic-bezier(0.22, 1, 0.36, 1); @@ -4282,10 +4295,12 @@ onUnmounted(() => { font-weight: 850; } .trade-submit--buy { - background: linear-gradient(135deg, #179d7d, #0f8068); + background: #179d7d; + box-shadow: none; } .trade-submit--sell { - background: linear-gradient(135deg, #d75268, #a9334b); + background: #c4475c; + box-shadow: none; } .transfer-intro, .transfer-recipient, @@ -4421,8 +4436,9 @@ onUnmounted(() => { gap: 8px; color: #06110e; font-weight: 900; - background: linear-gradient(135deg, #70f7d2, #4b9eff); + background: var(--vault-mint); border-radius: 16px; + box-shadow: none; } .sheet-copy { color: var(--muted); @@ -4553,13 +4569,13 @@ onUnmounted(() => { color: #06110e; font-size: 13px; font-weight: 900; - background: linear-gradient(135deg, #78f8d5, #4fd9ba 55%, #5aa7ff); - border: 1px solid rgba(255, 255, 255, 0.2); + background: var(--vault-mint); + border: 1px solid rgba(101, 251, 210, 0.48); border-radius: 17px; - box-shadow: 0 14px 30px rgba(54, 220, 178, 0.18); + box-shadow: none; } .settlement-submit:active { - box-shadow: 0 7px 18px rgba(54, 220, 178, 0.13); + box-shadow: none; transform: translateY(1px); } @media (hover: hover) { @@ -4606,13 +4622,13 @@ onUnmounted(() => { color: #06110e; font-size: 13px; font-weight: 900; - background: linear-gradient(135deg, #70f7d2, #4fd9ba 58%, #4b9eff); - border: 1px solid rgba(255, 255, 255, 0.18); + background: var(--vault-mint); + border: 1px solid rgba(101, 251, 210, 0.48); border-radius: 16px; - box-shadow: 0 13px 30px rgba(54, 220, 178, 0.17); + box-shadow: none; } .profile-save-button:active { - box-shadow: 0 6px 18px rgba(54, 220, 178, 0.13); + box-shadow: none; transform: translateY(1px); } .quote { diff --git a/frontend/testserver/index.cjs b/frontend/testserver/index.cjs index 5b0118b..c984767 100644 --- a/frontend/testserver/index.cjs +++ b/frontend/testserver/index.cjs @@ -198,10 +198,11 @@ async function fetchYoutubeMetadata(videoId) { } let mockBankBalance = 24787 let cryptoAuthenticated = true +let cryptoRegistered = true let cryptoCashBalance = 18420 let cryptoQuote = null let nextCryptoActivityId = 5 -const cryptoPassword = 'VaultX123!' +let cryptoPassword = 'VaultX123!' function createCryptoMarket({ changePercent, color, @@ -6940,7 +6941,7 @@ app.post('/api/:endpoint', (request, response) => { ), ), profile: cryptoAuthenticated ? cryptoProfile : null, - registered: true, + registered: cryptoRegistered, } } const billingInvoice = (invoice) => ({ @@ -8443,6 +8444,8 @@ app.post('/api/:endpoint', (request, response) => { return } cryptoAuthenticated = true + cryptoRegistered = true + cryptoPassword = password cryptoProfile = { createdAt: Date.now(), handle, @@ -9373,6 +9376,7 @@ app.post('/api/:endpoint', (request, response) => { return } if (endpoint === 'development:bootstrap') { + cryptoRegistered = testScenario !== 'crypto-register' cryptoAuthenticated = !['crypto-login', 'crypto-register'].includes( testScenario, )