bug: loginform + header navigation adjusted

This commit is contained in:
DeathKaioken 2025-11-17 17:19:11 +01:00
parent aa447348b2
commit 9e194da309
2 changed files with 101 additions and 79 deletions

View File

@ -54,6 +54,8 @@ export default function Header() {
// NEW: permission flag // NEW: permission flag
const [hasReferralPerm, setHasReferralPerm] = useState(false) const [hasReferralPerm, setHasReferralPerm] = useState(false)
// NEW: admin management dropdown state
const [adminMgmtOpen, setAdminMgmtOpen] = useState(false)
const handleLogout = async () => { const handleLogout = async () => {
try { try {
@ -405,31 +407,58 @@ export default function Header() {
> >
Dashboard Dashboard
</button> </button>
<button {/* MOVED: User Verify now before Management */}
onClick={() => { console.log('🧭 Admin: navigate to /admin/user-management'); router.push('/admin/user-management') }}
className="text-sm font-semibold text-[#0F1D37] hover:text-[#7A5E1A]"
>
User Management
</button>
<button <button
onClick={() => { console.log('🧭 Admin: navigate to /admin/user-verify'); router.push('/admin/user-verify') }} onClick={() => { console.log('🧭 Admin: navigate to /admin/user-verify'); router.push('/admin/user-verify') }}
className="text-sm font-semibold text-[#0F1D37] hover:text-[#7A5E1A]" className="text-sm font-semibold text-[#0F1D37] hover:text-[#7A5E1A]"
> >
User Verify User Verify
</button> </button>
{/* Management dropdown (unchanged) */}
<div
className="relative"
onMouseLeave={() => setAdminMgmtOpen(false)}
>
<button <button
onClick={() => { console.log('🧭 Admin: navigate to /admin/matrix-management'); router.push('/admin/matrix-management') }} onClick={() => setAdminMgmtOpen(o => !o)}
className="text-sm font-semibold text-[#0F1D37] hover:text-[#7A5E1A]" className="text-sm font-semibold text-[#0F1D37] hover:text-[#7A5E1A] flex items-center gap-1"
>
Management
<ChevronDownIcon
className={`h-4 w-4 transition-transform ${adminMgmtOpen ? 'rotate-180' : ''}`}
/>
</button>
{adminMgmtOpen && (
<div className="absolute left-1/2 -translate-x-1/2 mt-2 min-w-[15rem] rounded-md bg-white shadow-lg ring-1 ring-black/10 z-50">
<div className="py-2">
<button
onClick={() => { router.push('/admin/user-management'); setAdminMgmtOpen(false); }}
className="w-full text-left px-4 py-2 text-sm text-[#0F1D37] hover:bg-[#F5F3EE]"
>
User Management
</button>
<button
onClick={() => { router.push('/admin/matrix-management'); setAdminMgmtOpen(false); }}
className="w-full text-left px-4 py-2 text-sm text-[#0F1D37] hover:bg-[#F5F3EE]"
> >
Matrix Management Matrix Management
</button> </button>
{/* Contract Management only for admin */}
<button <button
onClick={() => { console.log('🧭 Admin: navigate to /admin/contract-management'); router.push('/admin/contract-management') }} onClick={() => { router.push('/admin/contract-management'); setAdminMgmtOpen(false); }}
className="text-sm font-semibold text-[#0F1D37] hover:text-[#7A5E1A]" className="w-full text-left px-4 py-2 text-sm text-[#0F1D37] hover:bg-[#F5F3EE]"
> >
Contract Management Contract Management
</button> </button>
<button
onClick={() => { router.push('/admin/subscriptions'); setAdminMgmtOpen(false); }}
className="w-full text-left px-4 py-2 text-sm text-[#0F1D37] hover:bg-[#F5F3EE]"
>
Coffee Subscription Management
</button>
</div>
</div>
)}
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -13,28 +13,25 @@ export default function LoginForm() {
password: '', password: '',
rememberMe: false rememberMe: false
}) })
const [viewportWidth, setViewportWidth] = useState<number>(
typeof window !== 'undefined' ? window.innerWidth : 1200
)
const router = useRouter() const router = useRouter()
const { login, error, setError, loading } = useLogin() const { login, error, setError, loading } = useLogin()
// Responsive ball visibility // Responsive ball visibility
useEffect(() => { useEffect(() => {
const handleResize = () => { const handleResizeBall = () => setShowBall(window.innerWidth >= 768)
setShowBall(window.innerWidth >= 768) handleResizeBall()
} window.addEventListener('resize', handleResizeBall)
handleResize() return () => window.removeEventListener('resize', handleResizeBall)
window.addEventListener('resize', handleResize)
return () => window.removeEventListener('resize', handleResize)
}, []) }, [])
// Prevent body scrolling when component mounts // Track viewport width for dynamic scaling
useEffect(() => { useEffect(() => {
document.body.style.overflow = 'hidden' const handleResize = () => setViewportWidth(window.innerWidth)
document.documentElement.style.overflow = 'hidden' window.addEventListener('resize', handleResize)
return () => window.removeEventListener('resize', handleResize)
return () => {
document.body.style.overflow = 'unset'
document.documentElement.style.overflow = 'unset'
}
}, []) }, [])
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
@ -82,63 +79,59 @@ export default function LoginForm() {
}) })
} }
const screenWidth = typeof window !== 'undefined' ? window.innerWidth : 1200 // Dynamic breakpoints
const isMobile = screenWidth < 768 const isMobile = viewportWidth < 640
const isTablet = screenWidth >= 768 && screenWidth <= 1024 const isTablet = viewportWidth >= 640 && viewportWidth < 1024
const isSmallLaptop = screenWidth > 1024 && screenWidth <= 1366 const isSmallLaptop = viewportWidth >= 1024 && viewportWidth < 1366
// Calculate responsive values // Dynamic width & scale
const getFormWidth = () => { const formWidth = isMobile
if (isMobile) return '98vw' ? '98vw'
if (isTablet) return '85vw' : isTablet
if (isSmallLaptop) return '50vw' ? '85vw'
return '40vw' : isSmallLaptop
} ? '50vw'
: '40vw'
const getFormScale = () => { const formMaxWidth = isMobile
if (isMobile) return undefined ? 'none'
if (isTablet) return 'scale(0.95)' : isTablet
if (isSmallLaptop) return 'scale(0.9)' ? '620px'
return 'scale(0.85)' : isSmallLaptop
} ? '660px'
: '720px'
const getFormMaxWidth = () => { const formScale = (() => {
if (isMobile) return 'none' if (isMobile) return 1
if (isTablet) return '600px' if (isTablet) return 0.95
if (isSmallLaptop) return '650px' if (isSmallLaptop) return 0.9
return '700px' if (viewportWidth >= 1366 && viewportWidth < 1680) return 0.85
} return 0.82
})()
return ( return (
<div <div
className="w-full flex justify-center items-center relative" className="w-full flex justify-center items-start relative"
style={{ style={{
minHeight: '100vh', // Removed fixed 100vh + overflow hidden to allow scrolling
height: '100vh', minHeight: 'auto',
overflowY: 'hidden', paddingTop: isMobile ? '0.75rem' : '4rem',
overflowX: 'hidden', paddingBottom: '3rem',
paddingTop: isMobile ? '0.25rem' : '5rem',
paddingBottom: isMobile ? '2.5rem' : '2.5rem',
backgroundImage: 'url(/images/misc/marble_bluegoldwhite_BG.jpg)', backgroundImage: 'url(/images/misc/marble_bluegoldwhite_BG.jpg)',
backgroundSize: 'cover', backgroundSize: 'cover',
backgroundPosition: 'center', backgroundPosition: 'center'
backgroundRepeat: 'no-repeat'
}} }}
> >
<div <div
className="bg-white rounded-2xl shadow-2xl flex flex-col items-center relative border-t-4 border-[#8D6B1D]" className="bg-white rounded-2xl shadow-2xl flex flex-col items-center relative border-t-4 border-[#8D6B1D]"
style={{ style={{
width: getFormWidth(), width: formWidth,
maxWidth: getFormMaxWidth(), maxWidth: formMaxWidth,
minWidth: isMobile ? '0' : '400px', minWidth: isMobile ? '0' : '400px',
minHeight: isMobile ? '320px' : '320px', padding: isMobile ? '0.75rem' : '2rem',
padding: isMobile ? '0.5rem' : '2rem',
marginTop: isMobile ? '0.5rem' : undefined, marginTop: isMobile ? '0.5rem' : undefined,
transform: getFormScale(), transform: formScale !== 1 ? `scale(${formScale})` : undefined,
transformOrigin: 'top center', transformOrigin: 'top center'
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-start'
}} }}
> >
{/* Animated Ball - Desktop Only */} {/* Animated Ball - Desktop Only */}