feat: redesign dashboard layout with calendar, open sessions, and glass-card panels
New layout: greeting → calendar+actions → sessions+stats → activity Replaces old QuickStats and SessionsPanel with new dashboard components Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -12,8 +12,7 @@ import { usePinnedFlowsStore } from '@/store/pinnedFlowsStore'
|
||||
import { useUserPreferencesStore } from '@/store/userPreferencesStore'
|
||||
import { usePaginationParams } from '@/hooks/usePaginationParams'
|
||||
import { useCachedQuota } from '@/hooks/useCachedQuota'
|
||||
import { QuickStats } from '@/components/dashboard/QuickStats'
|
||||
import { SessionsPanel } from '@/components/dashboard/SessionsPanel'
|
||||
// QuickStats and SessionsPanel replaced by new dashboard panels
|
||||
import { TreeGridView } from '@/components/library/TreeGridView'
|
||||
import { TreeListView } from '@/components/library/TreeListView'
|
||||
import { TreeTableView } from '@/components/library/TreeTableView'
|
||||
@@ -22,6 +21,10 @@ import { AIFlowBuilderModal } from '@/components/ai-builder/AIFlowBuilderModal'
|
||||
import { CreateFlowDropdown } from '@/components/common/CreateFlowDropdown'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { toast } from '@/lib/toast'
|
||||
import { WeeklyCalendar } from '@/components/dashboard/WeeklyCalendar'
|
||||
import { QuickActions } from '@/components/dashboard/QuickActions'
|
||||
import { OpenSessions } from '@/components/dashboard/OpenSessions'
|
||||
import { RecentActivity } from '@/components/dashboard/RecentActivity'
|
||||
|
||||
function timeAgo(dateStr: string): string {
|
||||
const now = Date.now()
|
||||
@@ -215,16 +218,22 @@ export function QuickStartPage() {
|
||||
const now = new Date()
|
||||
return d.toDateString() === now.toDateString()
|
||||
}).length
|
||||
const completedSessions = allSessions.filter(s => s.completed_at).length
|
||||
// completedSessions removed — no longer displayed in new layout
|
||||
|
||||
const recentSessionItems = allSessions.slice(0, 5).map(s => ({
|
||||
// Open sessions for the new panel (3 oldest)
|
||||
const openSessionItems = activeSessions
|
||||
.sort((a, b) => new Date(a.started_at).getTime() - new Date(b.started_at).getTime())
|
||||
.slice(0, 3)
|
||||
.map(s => ({
|
||||
id: s.id,
|
||||
treeName: s.tree_snapshot?.name || 'Unknown',
|
||||
status: (s.completed_at ? 'completed' : 'in_progress') as 'completed' | 'in_progress',
|
||||
ticketNumber: s.ticket_number || undefined,
|
||||
treeId: s.tree_id,
|
||||
treeType: (s.tree_snapshot as unknown as Record<string, unknown>)?.tree_type as string | undefined,
|
||||
timeAgo: timeAgo(s.started_at),
|
||||
}))
|
||||
|
||||
// recentSessionItems removed — replaced by RecentActivity component
|
||||
|
||||
// Favorites display
|
||||
const MAX_VISIBLE_FAVORITES = 8
|
||||
const visibleFavorites = showAllFavorites ? pinnedItems : pinnedItems.slice(0, MAX_VISIBLE_FAVORITES)
|
||||
@@ -270,27 +279,61 @@ export function QuickStartPage() {
|
||||
|
||||
return (
|
||||
<div className="p-6 space-y-6">
|
||||
{/* Page Header */}
|
||||
<div className="flex items-start justify-between">
|
||||
<div>
|
||||
<h1 className="font-heading text-[1.375rem] font-bold tracking-tight text-foreground">
|
||||
Dashboard
|
||||
{/* Greeting */}
|
||||
<div className="fade-in" style={{ animationDelay: '100ms' }}>
|
||||
<h1 className="font-heading text-4xl font-extrabold tracking-tight text-foreground">
|
||||
Good {new Date().getHours() < 12 ? 'morning' : new Date().getHours() < 18 ? 'afternoon' : 'evening'}, {user?.name?.split(' ')[0] || 'there'}
|
||||
</h1>
|
||||
<p className="mt-1 text-sm text-muted-foreground">
|
||||
Welcome back. Here's what's happening with your flows.
|
||||
{new Date().toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' })}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Row 1: Calendar + Quick Actions */}
|
||||
<div className="flex gap-4" style={{ alignItems: 'stretch' }}>
|
||||
<div className="flex-1 min-w-0">
|
||||
<WeeklyCalendar />
|
||||
</div>
|
||||
<div className="w-72 shrink-0">
|
||||
<QuickActions />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Quick Stats */}
|
||||
<QuickStats
|
||||
stats={[
|
||||
{ label: 'My Flows', value: myFlows.length, gradient: true },
|
||||
{ label: 'Sessions Today', value: todaySessions, color: '#f59e0b' },
|
||||
{ label: 'Open Sessions', value: openSessions, meta: `${completedSessions} completed` },
|
||||
{/* Row 2: Open Sessions + Stats 2x2 */}
|
||||
<div className="flex gap-4" style={{ alignItems: 'stretch' }}>
|
||||
<div className="flex-1 min-w-0">
|
||||
<OpenSessions sessions={openSessionItems} />
|
||||
</div>
|
||||
<div className="w-72 shrink-0">
|
||||
<div className="grid grid-cols-2 gap-3 h-full">
|
||||
{[
|
||||
{ label: 'Active Flows', value: myFlows.length, gradient: true, glow: true },
|
||||
{ label: 'This Week', value: todaySessions },
|
||||
{ label: 'Open Sessions', value: openSessions },
|
||||
{ label: 'Favorites', value: pinnedItems.length },
|
||||
]}
|
||||
/>
|
||||
].map((stat, i) => (
|
||||
<div
|
||||
key={stat.label}
|
||||
className={cn('glass-card p-4 flex flex-col justify-between fade-in', stat.glow && 'active-glow')}
|
||||
style={{ animationDelay: `${500 + i * 70}ms` }}
|
||||
>
|
||||
<p className="font-label text-[0.625rem] font-medium uppercase tracking-[0.1em] text-muted-foreground">
|
||||
{stat.label}
|
||||
</p>
|
||||
<p className={cn('font-heading text-2xl font-extrabold tracking-tight', stat.gradient && 'text-gradient-brand')}>
|
||||
{stat.value}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Row 3: Recent Activity */}
|
||||
<RecentActivity />
|
||||
|
||||
{/* ── Existing content below ── */}
|
||||
<div style={{ borderTop: '1px solid var(--glass-border)' }} className="pt-6 space-y-6">
|
||||
|
||||
{/* Search */}
|
||||
<div ref={searchRef} className="relative">
|
||||
@@ -332,9 +375,6 @@ export function QuickStartPage() {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Recent Sessions */}
|
||||
<SessionsPanel sessions={recentSessionItems} delay={150} />
|
||||
|
||||
{/* Favorites Section */}
|
||||
<div>
|
||||
<div className="mb-3 flex items-center justify-between">
|
||||
@@ -562,6 +602,7 @@ export function QuickStartPage() {
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Fork Modal */}
|
||||
{forkTarget && (
|
||||
|
||||
Reference in New Issue
Block a user