diff --git a/features/landing/frontend/src/components/DevUserSwitcher.css b/features/landing/frontend/src/components/DevUserSwitcher.css index 1f56e4ed8..a31e76310 100644 --- a/features/landing/frontend/src/components/DevUserSwitcher.css +++ b/features/landing/frontend/src/components/DevUserSwitcher.css @@ -1,4 +1,5 @@ /* Dev User Switcher - Only visible in development mode */ +/* Supports multi-type selection with primary type */ .dev-user-switcher { position: fixed; @@ -60,7 +61,7 @@ position: absolute; bottom: calc(100% + 8px); left: 0; - width: 280px; + width: 320px; background: rgba(20, 20, 25, 0.98); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 12px; @@ -119,34 +120,118 @@ box-shadow: 0 0 4px rgba(34, 197, 94, 0.5); } +/* Quick actions */ +.dev-user-switcher-actions { + padding: 8px 16px; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); +} + +.dev-user-action { + width: 100%; + padding: 8px 12px; + background: rgba(168, 85, 247, 0.2); + border: 1px solid rgba(168, 85, 247, 0.3); + border-radius: 6px; + color: #a855f7; + font-size: 12px; + font-weight: 500; + cursor: pointer; + transition: all 0.15s ease; +} + +.dev-user-action:hover { + background: rgba(168, 85, 247, 0.3); + border-color: rgba(168, 85, 247, 0.5); +} + +.dev-user-action--danger { + background: rgba(239, 68, 68, 0.2); + border-color: rgba(239, 68, 68, 0.3); + color: #ef4444; +} + +.dev-user-action--danger:hover { + background: rgba(239, 68, 68, 0.3); + border-color: rgba(239, 68, 68, 0.5); +} + +/* Section label */ +.dev-user-switcher-section-label { + padding: 10px 16px 6px; + font-size: 10px; + font-weight: 600; + color: rgba(255, 255, 255, 0.5); + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.dev-user-switcher-hint { + font-weight: 400; + text-transform: none; + letter-spacing: normal; + margin-left: 4px; +} + /* Options list */ .dev-user-switcher-options { - padding: 8px; + padding: 4px 8px 8px; } .dev-user-option { display: flex; align-items: center; - gap: 10px; - width: 100%; - padding: 10px 12px; - background: transparent; - border: 1px solid transparent; + gap: 4px; + margin-bottom: 4px; border-radius: 8px; - color: #fff; - cursor: pointer; - text-align: left; transition: all 0.15s ease; } -.dev-user-option:hover { - background: rgba(255, 255, 255, 0.05); - border-color: rgba(255, 255, 255, 0.1); +.dev-user-option:last-child { + margin-bottom: 0; } .dev-user-option.active { - background: rgba(168, 85, 247, 0.15); - border-color: rgba(168, 85, 247, 0.3); + background: rgba(168, 85, 247, 0.1); +} + +/* Toggle button (checkbox + icon + content) */ +.dev-user-option-toggle { + display: flex; + align-items: center; + gap: 10px; + flex: 1; + padding: 10px 12px; + background: transparent; + border: none; + color: #fff; + cursor: pointer; + text-align: left; + border-radius: 8px; + transition: all 0.15s ease; +} + +.dev-user-option-toggle:hover { + background: rgba(255, 255, 255, 0.05); +} + +/* Checkbox */ +.dev-user-option-checkbox { + display: flex; + align-items: center; + justify-content: center; + width: 18px; + height: 18px; + border: 2px solid rgba(255, 255, 255, 0.3); + border-radius: 4px; + font-size: 11px; + flex-shrink: 0; + transition: all 0.15s ease; +} + +.dev-user-option-checkbox.checked { + background: #a855f7; + border-color: #a855f7; + color: #fff; } .dev-user-option-icon { @@ -171,10 +256,34 @@ color: rgba(255, 255, 255, 0.5); } -.dev-user-option-check { - color: #a855f7; - font-weight: bold; +/* Primary star button */ +.dev-user-option-primary { + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + background: transparent; + border: none; + border-radius: 6px; + color: rgba(255, 255, 255, 0.3); + cursor: pointer; flex-shrink: 0; + transition: all 0.15s ease; +} + +.dev-user-option-primary:hover:not(:disabled) { + background: rgba(255, 255, 255, 0.1); + color: rgba(255, 255, 255, 0.6); +} + +.dev-user-option-primary.is-primary { + color: #f59e0b; +} + +.dev-user-option-primary:disabled { + opacity: 0.3; + cursor: not-allowed; } /* Footer */ @@ -205,5 +314,6 @@ .dev-user-switcher-panel { left: auto; right: 0; + width: 300px; } } diff --git a/features/landing/frontend/src/components/DevUserSwitcher.tsx b/features/landing/frontend/src/components/DevUserSwitcher.tsx index 5f36831e2..369265e56 100644 --- a/features/landing/frontend/src/components/DevUserSwitcher.tsx +++ b/features/landing/frontend/src/components/DevUserSwitcher.tsx @@ -1,29 +1,12 @@ import { useState, useEffect, useCallback } from 'react' +import { Star } from 'lucide-react' -import { useDevUser, DEV_USER_TYPES, type DevUserType } from '../contexts/DevUserContext' +import { useDevUser, getUserTypeEmoji, DEV_USER_TYPES, type DevUserType } from '../contexts' import './DevUserSwitcher.css' -/** Get icon for each user type */ -function getUserTypeIcon(type: DevUserType): string { - switch (type) { - case 'guest': - return '👻' - case 'registered-user': - return '👤' - case 'registered-provider': - return 'ðŸŽ' - case 'registered-client': - return '💜' - case 'registered-investor': - return '💎' - } -} - /** Get short label for each user type */ function getShortLabel(type: DevUserType): string { switch (type) { - case 'guest': - return 'Guest' case 'registered-user': return 'User' case 'registered-provider': @@ -38,8 +21,6 @@ function getShortLabel(type: DevUserType): string { /** Get description for each user type */ function getDescription(type: DevUserType): string { switch (type) { - case 'guest': - return 'Not authenticated' case 'registered-user': return 'Registered via shop, no declared intent' case 'registered-provider': @@ -53,10 +34,23 @@ function getDescription(type: DevUserType): string { /** * Dev-only floating switcher for simulating different user types + * Supports multi-type selection with primary type * Only renders in development mode */ export default function DevUserSwitcher() { - const { userType, setUserType, isDevMode, isAuthenticated, hasDeclaredIntent } = useDevUser() + const { + userTypes, + primaryType, + isDevMode, + isAuthenticated, + hasDeclaredIntent, + toggleType, + setPrimaryType, + signOut, + signInAsUser, + hasType, + canBePrimary, + } = useDevUser() const [isExpanded, setIsExpanded] = useState(false) const toggleExpanded = useCallback(() => { @@ -81,6 +75,9 @@ export default function DevUserSwitcher() { // Don't render in production if (!isDevMode) return null + const displayLabel = primaryType ? getShortLabel(primaryType) : 'Guest' + const displayEmoji = getUserTypeEmoji(primaryType) + return (