mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 09:33:46 +00:00
fix: bottom nav overlap and safe area handling in referral network
- Raise portal z-index to z-50 so it covers MobileBottomNav - Use TG SDK bottom safe area (JS) via CSS variable instead of unreliable env() - Fix TicketNotificationBell regression: conditional inline style for fullscreen only - Add bottom safe area padding to detail panel scroll areas
This commit is contained in:
@@ -37,7 +37,7 @@ export default function TicketNotificationBell({ isAdmin = false }: TicketNotifi
|
||||
const { showToast } = useToast();
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const dropdownRef = useRef<HTMLDivElement>(null);
|
||||
const { mobile: dropdownTop } = useHeaderHeight();
|
||||
const { mobile: dropdownTop, isMobileFullscreen } = useHeaderHeight();
|
||||
|
||||
// Show toast for WebSocket notification
|
||||
const showWSNotificationToast = useCallback(
|
||||
@@ -255,7 +255,7 @@ export default function TicketNotificationBell({ isAdmin = false }: TicketNotifi
|
||||
{isOpen && (
|
||||
<div
|
||||
className="fixed left-4 right-4 z-50 mt-0 w-auto animate-scale-in overflow-hidden rounded-2xl border border-dark-700/50 bg-dark-900/95 shadow-2xl shadow-black/30 backdrop-blur-xl sm:absolute sm:left-auto sm:right-0 sm:top-auto sm:mt-2 sm:w-96"
|
||||
style={{ top: dropdownTop }}
|
||||
style={isMobileFullscreen ? { top: dropdownTop } : undefined}
|
||||
>
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between border-b border-dark-700/50 bg-dark-800/30 px-4 py-3">
|
||||
|
||||
@@ -6,8 +6,14 @@ import { UI } from '@/config/constants';
|
||||
* Telegram MiniApp safe area insets in fullscreen mode.
|
||||
*
|
||||
* Desktop: 56px (h-14). Mobile: 64px (h-16) + safe area + TG header when fullscreen.
|
||||
* bottomSafeArea: TG SDK bottom inset (home indicator etc.), 0 outside TG.
|
||||
*/
|
||||
export function useHeaderHeight(): { mobile: number; desktop: number } {
|
||||
export function useHeaderHeight(): {
|
||||
mobile: number;
|
||||
desktop: number;
|
||||
bottomSafeArea: number;
|
||||
isMobileFullscreen: boolean;
|
||||
} {
|
||||
const { isFullscreen, safeAreaInset, contentSafeAreaInset, platform, isMobile } =
|
||||
useTelegramSDK();
|
||||
const isMobileFullscreen = isFullscreen && isMobile;
|
||||
@@ -21,5 +27,9 @@ export function useHeaderHeight(): { mobile: number; desktop: number } {
|
||||
telegramHeaderHeight
|
||||
: UI.MOBILE_HEADER_HEIGHT_PX;
|
||||
|
||||
return { mobile, desktop: UI.DESKTOP_HEADER_HEIGHT_PX };
|
||||
const bottomSafeArea = isMobileFullscreen
|
||||
? Math.max(safeAreaInset.bottom, contentSafeAreaInset.bottom)
|
||||
: 0;
|
||||
|
||||
return { mobile, desktop: UI.DESKTOP_HEADER_HEIGHT_PX, bottomSafeArea, isMobileFullscreen };
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ export function ReferralNetwork() {
|
||||
const removeScope = useReferralNetworkStore((s) => s.removeScope);
|
||||
const clearScope = useReferralNetworkStore((s) => s.clearScope);
|
||||
|
||||
const { mobile: mobileHeaderHeight } = useHeaderHeight();
|
||||
const { mobile: mobileHeaderHeight, bottomSafeArea } = useHeaderHeight();
|
||||
|
||||
const hasScope = scope.length > 0;
|
||||
|
||||
@@ -41,8 +41,13 @@ export function ReferralNetwork() {
|
||||
return createPortal(
|
||||
<div
|
||||
id="referral-network-container"
|
||||
className="fixed inset-x-0 bottom-0 z-40 grid grid-rows-[auto_1fr] bg-[#0a0a0f] lg:!top-14"
|
||||
style={{ top: mobileHeaderHeight }}
|
||||
className="fixed inset-x-0 bottom-0 z-50 grid grid-rows-[auto_1fr] bg-[#0a0a0f] lg:!top-14"
|
||||
style={
|
||||
{
|
||||
top: mobileHeaderHeight,
|
||||
'--safe-bottom': `${bottomSafeArea}px`,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
>
|
||||
<div className="z-20 border-b border-dark-700/50 bg-dark-900/90 backdrop-blur-md">
|
||||
{/* Mobile: two rows — title on top, selector below */}
|
||||
@@ -122,15 +127,15 @@ export function ReferralNetwork() {
|
||||
<>
|
||||
<NetworkGraph data={networkData} className="absolute inset-0 h-full w-full" />
|
||||
|
||||
<div className="absolute bottom-3 left-3 z-10 sm:bottom-4 sm:left-4">
|
||||
<div className="absolute bottom-[calc(12px+var(--safe-bottom,0px))] left-3 z-10 sm:bottom-4 sm:left-4">
|
||||
<NetworkStats data={networkData} />
|
||||
</div>
|
||||
|
||||
<div className="absolute bottom-3 right-3 z-10 hidden sm:bottom-4 sm:right-4 sm:block">
|
||||
<div className="absolute bottom-[calc(12px+var(--safe-bottom,0px))] right-3 z-10 hidden sm:bottom-4 sm:right-4 sm:block">
|
||||
<NetworkLegend />
|
||||
</div>
|
||||
|
||||
<div className="absolute bottom-3 left-1/2 z-10 -translate-x-1/2 sm:bottom-4">
|
||||
<div className="absolute bottom-[calc(12px+var(--safe-bottom,0px))] left-1/2 z-10 -translate-x-1/2 sm:bottom-4">
|
||||
<NetworkControls />
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -50,7 +50,7 @@ export function CampaignDetailPanel({ campaignId, className }: CampaignDetailPan
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="overflow-y-auto p-4">
|
||||
<div className="overflow-y-auto p-4 pb-[calc(1rem+var(--safe-bottom,0px))]">
|
||||
{isLoading && (
|
||||
<div className="flex items-center justify-center py-8">
|
||||
<div className="h-6 w-6 animate-spin rounded-full border-2 border-dark-600 border-t-accent-400" />
|
||||
|
||||
@@ -50,7 +50,7 @@ export function UserDetailPanel({ userId, className }: UserDetailPanelProps) {
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="overflow-y-auto p-4">
|
||||
<div className="overflow-y-auto p-4 pb-[calc(1rem+var(--safe-bottom,0px))]">
|
||||
{isLoading && (
|
||||
<div className="flex items-center justify-center py-8">
|
||||
<div className="h-6 w-6 animate-spin rounded-full border-2 border-dark-600 border-t-accent-400" />
|
||||
|
||||
Reference in New Issue
Block a user