/* eslint-disable @typescript-eslint/indent */ import { Box } from '@mui/material'; import { alpha, useTheme } from '@mui/material/styles'; import Header from '@blocklet/ui-react/lib/Header'; import { useMobile } from '../../hooks/mobile'; const hiddenScrollbar = { overflowY: 'auto', '&::-webkit-scrollbar': { display: 'none' }, scrollbarWidth: 'none', } as const; // Mobile: whole container fades in const mobileFadeIn = { '@keyframes mobileFadeIn': { from: { opacity: 0 }, to: { opacity: 1 }, }, animation: { xs: 'mobileFadeIn 0.4s ease both', md: 'none' }, } as const; // Desktop: left content fades in with slight upward motion const fadeIn = { '@keyframes fadeIn': { from: { opacity: 0, transform: 'translateY(12px)' }, to: { opacity: 1, transform: 'translateY(0)' }, }, animation: { xs: 'none', md: 'fadeIn 0.6s cubic-bezier(0.16, 1, 0.3, 1) 0.15s both' }, } as const; // Desktop: right panel slides in from right (non-Safari) or fades in (Safari) // Safari has flexbox reflow bugs with translateX(100%), so we use a subtle fade instead const isSafari = typeof navigator !== 'undefined' && /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent); const slideInFromRight = isSafari ? ({ '@keyframes panelFadeIn': { from: { opacity: 0, transform: 'translateX(24px)' }, to: { opacity: 1, transform: 'none' }, }, animation: { xs: 'none', md: 'panelFadeIn 0.5s cubic-bezier(0.16, 1, 0.3, 1) both' }, } as const) : ({ '@keyframes slideInRight': { from: { transform: 'translateX(100%)' }, to: { transform: 'translateX(0)' }, }, animation: { xs: 'none', md: 'slideInRight 0.5s cubic-bezier(0.16, 1, 0.3, 1) forwards' }, } as const); interface CheckoutLayoutProps { left: React.ReactNode; right: React.ReactNode; mode?: string; } export default function CheckoutLayout({ left, right, mode = 'inline' }: CheckoutLayoutProps) { const isFullScreen = mode === 'standalone'; const { isMobile } = useMobile(); const theme = useTheme(); const isDark = theme.palette.mode === 'dark'; const hideLeft = left === null; // Mobile fixed bottom bar for submit button const mobileSubmitBarSx: Record = {}; if (isMobile && !hideLeft) { mobileSubmitBarSx['& .cko-v2-submit-btn'] = { position: 'fixed', bottom: 0, left: 0, right: 0, zIndex: 999, bgcolor: isDark ? 'rgba(30,30,30,0.82)' : 'background.paper', backdropFilter: isDark ? 'blur(12px)' : 'none', p: 1.5, borderTop: '1px solid', borderColor: 'divider', boxShadow: isDark ? '0 -4px 20px rgba(0,0,0,0.4)' : '0 -2px 10px rgba(0,0,0,0.08)', }; } if (!isFullScreen) { // Card (inline) mode return ( (t.palette.mode === 'dark' ? 'background.default' : '#f8faff'), ...mobileFadeIn, }}> {!hideLeft && ( (t.palette.mode === 'dark' ? 'background.default' : '#f8faff'), p: { xs: 3, md: 5 }, pt: { xs: 3, md: 4 }, display: 'flex', flexDirection: 'column', ...fadeIn, }}> {left} )} {right} ); } // Standalone (full-screen) mode — backgrounds fill edge-to-edge, content constrained // Mobile: gray page bg with white card sections; Desktop: gradient bg with slide-in const mobileBg = isDark ? theme.palette.background.default : theme.palette.grey[100]; const desktopBg = isDark ? theme.palette.background.default : '#f8faff'; return ( {/* Header — absolute positioned at top, transparent background, shows logo */}
{ const addons = buildIns.filter((addon: any) => ['locale-selector', 'theme-mode-toggle', 'session-user'].includes(addon.key) ); return addons; }} /> {/* Left panel — hidden when left is null (e.g. mobile success) */} {!hideLeft && ( {left} )} {/* Right panel — full width when left is hidden */} {right} ); }