fix(D5): add responsive dashboard breakpoints
Move fixed shell dimensions into responsive classes so sub-1024px layouts hide the right panel, turn the sidebar into a bottom nav, and keep dashboard content usable with adaptive grids and horizontal screener scrolling. Refs: docs/AUDIT_REDESIGN.md item D5. Co-Authored-By: GPT-5 Codex <noreply@openai.com>
This commit is contained in:
parent
ce25712e59
commit
a9c33b1c14
@ -13,41 +13,19 @@ import { SettingsView } from '../../views/SettingsView';
|
||||
|
||||
export function AppShell() {
|
||||
return (
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
minHeight: '100vh',
|
||||
background: '#F3F4F6',
|
||||
fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
|
||||
}}>
|
||||
<div className="dashboard-shell">
|
||||
{/* Fixed left sidebar */}
|
||||
<Sidebar />
|
||||
|
||||
{/* Main area (right of sidebar) */}
|
||||
<div style={{
|
||||
marginLeft: 72,
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
minHeight: '100vh',
|
||||
overflow: 'hidden',
|
||||
}}>
|
||||
<div className="dashboard-main">
|
||||
{/* Sticky header */}
|
||||
<Header />
|
||||
|
||||
{/* Content row: main + right panel */}
|
||||
<div style={{
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
overflow: 'hidden',
|
||||
minHeight: 0,
|
||||
}}>
|
||||
<div className="dashboard-content-row">
|
||||
{/* Scrollable main content */}
|
||||
<main style={{
|
||||
flex: 1,
|
||||
overflowY: 'auto',
|
||||
padding: '24px 24px 32px',
|
||||
minWidth: 0,
|
||||
}}>
|
||||
<main className="dashboard-content">
|
||||
<Routes>
|
||||
<Route path="/" element={<HomeView />} />
|
||||
<Route path="/portfolio" element={<PortfolioView />} />
|
||||
|
||||
@ -227,8 +227,7 @@ function NewsFeed() {
|
||||
|
||||
export function RightPanel() {
|
||||
return (
|
||||
<aside style={{
|
||||
width: 308, minWidth: 308, maxWidth: 308,
|
||||
<aside className="dashboard-right-panel" style={{
|
||||
background: '#ffffff',
|
||||
borderLeft: '1px solid #E5E7EB',
|
||||
display: 'flex',
|
||||
|
||||
@ -23,24 +23,9 @@ export function Sidebar() {
|
||||
: 'US';
|
||||
|
||||
return (
|
||||
<aside style={{
|
||||
width: 72,
|
||||
minHeight: '100vh',
|
||||
background: '#ffffff',
|
||||
borderRight: '1px solid #E5E7EB',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
paddingTop: 16,
|
||||
paddingBottom: 20,
|
||||
position: 'fixed',
|
||||
left: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
zIndex: 50,
|
||||
}}>
|
||||
<aside className="trading-sidebar">
|
||||
{/* Logo */}
|
||||
<div style={{
|
||||
<div className="trading-sidebar-logo" style={{
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderRadius: 10,
|
||||
@ -58,25 +43,18 @@ export function Sidebar() {
|
||||
</div>
|
||||
|
||||
{/* Nav items */}
|
||||
<nav style={{
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
width: '100%',
|
||||
alignItems: 'center',
|
||||
gap: 2,
|
||||
}}>
|
||||
<nav className="trading-sidebar-nav">
|
||||
{NAV.map(({ to, icon: Icon, label, end }) => (
|
||||
<NavLink
|
||||
key={to}
|
||||
to={to}
|
||||
end={end}
|
||||
className="trading-sidebar-link"
|
||||
style={({ isActive }) => ({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: '100%',
|
||||
padding: '10px 0 8px',
|
||||
gap: 3,
|
||||
borderLeft: isActive ? '3px solid #2563EB' : '3px solid transparent',
|
||||
@ -105,6 +83,7 @@ export function Sidebar() {
|
||||
|
||||
{/* User avatar */}
|
||||
<div
|
||||
className="trading-sidebar-avatar"
|
||||
title={`${user?.email ?? ''} — click to sign out`}
|
||||
onClick={handleSignOut}
|
||||
style={{
|
||||
|
||||
@ -60,4 +60,128 @@ body {
|
||||
@keyframes spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard-shell {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
background: #F3F4F6;
|
||||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
||||
}
|
||||
|
||||
.dashboard-main {
|
||||
margin-left: 72px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.dashboard-content-row {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.dashboard-content {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 24px 24px 32px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.dashboard-right-panel {
|
||||
width: 308px;
|
||||
min-width: 308px;
|
||||
max-width: 308px;
|
||||
}
|
||||
|
||||
.trading-sidebar {
|
||||
width: 72px;
|
||||
min-height: 100vh;
|
||||
background: #ffffff;
|
||||
border-right: 1px solid #E5E7EB;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding-top: 16px;
|
||||
padding-bottom: 20px;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
.trading-sidebar-nav {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.trading-sidebar-link {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 1023px) {
|
||||
.dashboard-shell {
|
||||
padding-bottom: 68px;
|
||||
}
|
||||
|
||||
.dashboard-main {
|
||||
margin-left: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.dashboard-content-row {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.dashboard-content {
|
||||
padding: 16px 14px 24px;
|
||||
}
|
||||
|
||||
.dashboard-right-panel {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.trading-sidebar {
|
||||
width: 100%;
|
||||
min-height: 64px;
|
||||
height: 64px;
|
||||
top: auto;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: stretch;
|
||||
padding: 0 8px;
|
||||
border-right: 0;
|
||||
border-top: 1px solid #E5E7EB;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.trading-sidebar-logo,
|
||||
.trading-sidebar-avatar {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.trading-sidebar-nav {
|
||||
flex: 0 1 auto;
|
||||
flex-direction: row;
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
align-items: stretch;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.trading-sidebar-link {
|
||||
width: 68px;
|
||||
min-width: 68px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -534,7 +534,7 @@ function QuickStats({ symbol }: { symbol: string }) {
|
||||
];
|
||||
|
||||
return (
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 12, marginBottom: 20 }}>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(140px, 1fr))', gap: 12, marginBottom: 20 }}>
|
||||
{stats.map(s => (
|
||||
<div key={s.label} style={{
|
||||
background: '#fff',
|
||||
@ -605,7 +605,7 @@ function ResearchCards({
|
||||
];
|
||||
|
||||
return (
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 16 }}>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 16 }}>
|
||||
{/* Company Profile */}
|
||||
<div style={{ background: '#fff', borderRadius: 12, border: '1px solid #E5E7EB', padding: 16 }}>
|
||||
<div style={{ fontSize: 13, fontWeight: 700, color: '#111827', marginBottom: 10 }}>
|
||||
|
||||
@ -265,7 +265,7 @@ export function ScreenerView() {
|
||||
)}
|
||||
|
||||
{/* Results table */}
|
||||
<div style={{ background: '#fff', borderRadius: 12, border: '1px solid #E5E7EB', overflow: 'hidden' }}>
|
||||
<div style={{ background: '#fff', borderRadius: 12, border: '1px solid #E5E7EB', overflowX: 'auto', overflowY: 'hidden' }}>
|
||||
{/* Header */}
|
||||
<div style={{
|
||||
display: 'grid',
|
||||
|
||||
Loading…
Reference in New Issue
Block a user