bug: loginform + header navigation adjusted
This commit is contained in:
parent
aa447348b2
commit
9e194da309
@ -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>
|
||||||
|
|||||||
@ -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 */}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user