MVP with new UX
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @ai-summary Bottom navigation component with Material Design 3
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { BottomNavigation as MuiBottomNavigation, BottomNavigationAction } from '@mui/material';
|
||||
|
||||
export interface NavigationItem {
|
||||
key: string;
|
||||
label: string;
|
||||
icon: React.ReactNode;
|
||||
}
|
||||
|
||||
interface BottomNavigationProps {
|
||||
items: NavigationItem[];
|
||||
activeItem: string;
|
||||
onItemSelect: (key: string) => void;
|
||||
}
|
||||
|
||||
export const BottomNavigation: React.FC<BottomNavigationProps> = ({
|
||||
items,
|
||||
activeItem,
|
||||
onItemSelect
|
||||
}) => {
|
||||
const activeIndex = items.findIndex(item => item.key === activeItem);
|
||||
|
||||
return (
|
||||
<MuiBottomNavigation
|
||||
showLabels
|
||||
value={activeIndex}
|
||||
onChange={(_, newValue) => onItemSelect(items[newValue].key)}
|
||||
sx={{
|
||||
position: 'fixed',
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
zIndex: 1000,
|
||||
width: '100%'
|
||||
}}
|
||||
>
|
||||
{items.map(({ key, label, icon }) => (
|
||||
<BottomNavigationAction
|
||||
key={key}
|
||||
label={label}
|
||||
icon={icon}
|
||||
/>
|
||||
))}
|
||||
</MuiBottomNavigation>
|
||||
);
|
||||
};
|
||||
41
frontend/src/shared-minimal/components/mobile/GlassCard.tsx
Normal file
41
frontend/src/shared-minimal/components/mobile/GlassCard.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @ai-summary Glass morphism card component for mobile UI
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { clsx } from 'clsx';
|
||||
|
||||
interface GlassCardProps {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
padding?: 'none' | 'sm' | 'md' | 'lg';
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
export const GlassCard: React.FC<GlassCardProps> = ({
|
||||
children,
|
||||
className,
|
||||
padding = 'md',
|
||||
onClick,
|
||||
}) => {
|
||||
const paddings = {
|
||||
none: '',
|
||||
sm: 'p-3',
|
||||
md: 'p-4',
|
||||
lg: 'p-6',
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
'rounded-3xl border border-slate-200/70 bg-white/80 shadow-sm backdrop-blur',
|
||||
paddings[padding],
|
||||
onClick && 'cursor-pointer hover:shadow-xl hover:-translate-y-0.5 transition',
|
||||
className
|
||||
)}
|
||||
onClick={onClick}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @ai-summary Mobile app container with glass morphism styling
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
interface MobileContainerProps {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const MobileContainer: React.FC<MobileContainerProps> = ({
|
||||
children,
|
||||
className = ''
|
||||
}) => {
|
||||
return (
|
||||
<div className="w-full min-h-screen bg-gradient-to-br from-slate-50 via-white to-rose-50 flex items-start justify-center p-4 md:py-6">
|
||||
<div className={`w-full max-w-[380px] min-h-screen md:min-h-[600px] md:rounded-[32px] shadow-2xl flex flex-col border-0 md:border border-slate-200/70 bg-white/90 md:bg-white/70 backdrop-blur-xl ${className}`}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
40
frontend/src/shared-minimal/components/mobile/MobilePill.tsx
Normal file
40
frontend/src/shared-minimal/components/mobile/MobilePill.tsx
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* @ai-summary Mobile pill button component with gradient styling
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { clsx } from 'clsx';
|
||||
|
||||
// Theme colors now defined in Tailwind config
|
||||
|
||||
interface MobilePillProps {
|
||||
active?: boolean;
|
||||
label: string;
|
||||
onClick?: () => void;
|
||||
icon?: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const MobilePill: React.FC<MobilePillProps> = ({
|
||||
active = false,
|
||||
label,
|
||||
onClick,
|
||||
icon,
|
||||
className
|
||||
}) => {
|
||||
return (
|
||||
<button
|
||||
onClick={onClick}
|
||||
className={clsx(
|
||||
"group h-11 rounded-2xl text-sm font-medium border transition flex items-center justify-center gap-2 backdrop-blur",
|
||||
active
|
||||
? "text-white border-transparent shadow-lg bg-gradient-moto"
|
||||
: "bg-white/80 text-slate-800 border-slate-200 hover:bg-slate-50",
|
||||
className
|
||||
)}
|
||||
>
|
||||
{icon}
|
||||
<span>{label}</span>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user