11"use client" ;
22
33import { useState } from "react" ;
4+ import { Badge } from "@/components/ui/badge" ;
45import { Card , CardContent , CardHeader , CardTitle } from "@/components/ui/card" ;
56import { Tabs , TabsList , TabsTrigger } from "@/components/ui/tabs" ;
67import { DashboardGlow } from "./DashboardGlow" ;
@@ -109,6 +110,98 @@ function InsightGrid({
109110 ) ;
110111}
111112
113+ // --- Prompt bar ---
114+
115+ function PromptBar ( { shared, cards } : { shared : string ; cards : CardConfig } ) {
116+ const [ value , setValue ] = useState ( "" ) ;
117+ const hasInput = value . trim ( ) . length > 0 ;
118+
119+ return (
120+ < div className = "group rounded-2xl p-[2px] focus-within:bg-gradient-to-r focus-within:from-insight-500/75 focus-within:to-primary-400/75 transition-all" >
121+ { /* Suggestion pills */ }
122+ < div className = "grid grid-rows-[0fr] focus-within:grid-rows-[1fr] group-focus-within:grid-rows-[1fr] transition-[grid-template-rows] duration-300" >
123+ < div className = "overflow-hidden" >
124+ < div className = "px-3 pt-2 pb-2 flex gap-2" >
125+ < Badge
126+ variant = "secondary"
127+ status = "info"
128+ className = "!bg-white/35 !text-foreground opacity-0 translate-y-2 group-focus-within:opacity-100 group-focus-within:translate-y-0 transition-all duration-300 cursor-pointer"
129+ >
130+ Show me top risk factors
131+ </ Badge >
132+ < Badge
133+ variant = "secondary"
134+ status = "info"
135+ className = "!bg-white/35 !text-foreground opacity-0 translate-y-2 group-focus-within:opacity-100 group-focus-within:translate-y-0 transition-all duration-300 delay-75 cursor-pointer"
136+ >
137+ Compare Q1 vs Q2 performance
138+ </ Badge >
139+ </ div >
140+ </ div >
141+ </ div >
142+ { /* Input */ }
143+ < div
144+ className = { `flex items-center rounded-[14px] px-4 py-3 !bg-white/80 backdrop-blur-sm transition-colors ${ shared } ` }
145+ style = { cardBgStyle (
146+ cards . promptBg ,
147+ cards . promptOpacity ,
148+ cards . promptGradient ,
149+ ) }
150+ >
151+ < input
152+ type = "text"
153+ value = { value }
154+ onChange = { ( e ) => setValue ( e . target . value ) }
155+ placeholder = "What would you like to understand about loan performance?"
156+ className = "flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground"
157+ />
158+ < div className = "flex items-center gap-2 ml-3" >
159+ < button
160+ type = "button"
161+ className = "text-muted-foreground hover:text-foreground transition-colors"
162+ aria-label = "Voice input"
163+ >
164+ < svg
165+ xmlns = "http://www.w3.org/2000/svg"
166+ viewBox = "0 0 24 24"
167+ fill = "none"
168+ stroke = "currentColor"
169+ strokeWidth = "2"
170+ strokeLinecap = "round"
171+ strokeLinejoin = "round"
172+ className = "size-4"
173+ >
174+ < path d = "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" />
175+ < path d = "M19 10v2a7 7 0 0 1-14 0v-2" />
176+ < line x1 = "12" x2 = "12" y1 = "19" y2 = "22" />
177+ </ svg >
178+ </ button >
179+ < button
180+ type = "button"
181+ disabled = { ! hasInput }
182+ className = "size-8 rounded-full bg-gradient-to-br from-insight-500 to-primary-400 flex items-center justify-center text-white transition-opacity disabled:opacity-30"
183+ aria-label = "Submit"
184+ >
185+ < svg
186+ xmlns = "http://www.w3.org/2000/svg"
187+ viewBox = "0 0 24 24"
188+ fill = "none"
189+ stroke = "currentColor"
190+ strokeWidth = "2"
191+ strokeLinecap = "round"
192+ strokeLinejoin = "round"
193+ className = "size-4"
194+ >
195+ < path d = "m5 12 7-7 7 7" />
196+ < path d = "M12 19V5" />
197+ </ svg >
198+ </ button >
199+ </ div >
200+ </ div >
201+ </ div >
202+ ) ;
203+ }
204+
112205// --- Layout renderers ---
113206
114207function ExecutiveLayout ( {
@@ -124,18 +217,12 @@ function ExecutiveLayout({
124217 const gapStyle = { gap : `${ layout . gap } px` } ;
125218
126219 return (
127- < div className = "grid grid-cols-1 lg:grid-cols-2" style = { gapStyle } >
220+ < div className = "grid grid-cols-1 lg:grid-cols-2 h-full " style = { gapStyle } >
128221 { /* Left half */ }
129- < div
130- className = "grid"
131- style = { {
132- ...gapStyle ,
133- gridTemplateRows : `${ layout . overviewRatio } fr ${ layout . promptRatio } fr` ,
134- } }
135- >
222+ < div className = "flex flex-col" style = { gapStyle } >
136223 < Card
137224 variant = "glass"
138- className = { `!bg-white ${ shared } ` }
225+ className = { `!bg-white flex-1 ${ shared } ` }
139226 style = { cardBgStyle (
140227 cards . overviewBg ,
141228 cards . overviewOpacity ,
@@ -155,26 +242,7 @@ function ExecutiveLayout({
155242 < p > Avg. deal cycle: 32 days (-4 days)</ p >
156243 </ CardContent >
157244 </ Card >
158- < Card
159- variant = "glass"
160- className = { `!bg-white/80 ${ shared } ` }
161- style = { cardBgStyle (
162- cards . promptBg ,
163- cards . promptOpacity ,
164- cards . promptGradient ,
165- ) }
166- >
167- < CardHeader >
168- < CardTitle className = "text-sm font-bold tracking-tight" >
169- Conversational Prompt Bar
170- </ CardTitle >
171- </ CardHeader >
172- < CardContent className = "text-sm text-muted-foreground" >
173- < div className = "rounded-md border px-3 py-2 bg-muted/50" >
174- Ask a question about your data...
175- </ div >
176- </ CardContent >
177- </ Card >
245+ < PromptBar shared = { shared } cards = { cards } />
178246 </ div >
179247 { /* Right half — insight grid */ }
180248 < InsightGrid layout = { layout } shared = { shared } cards = { cards } />
@@ -214,7 +282,7 @@ export function DashboardContent() {
214282
215283 return (
216284 < div
217- className = "relative"
285+ className = "relative h-full "
218286 style = {
219287 layoutCfg . containerBg === "none"
220288 ? { }
@@ -231,7 +299,7 @@ export function DashboardContent() {
231299 onLayoutChange = { setLayoutCfg }
232300 />
233301 < div
234- className = "space-y -4 relative z-10"
302+ className = "flex flex-col gap -4 relative z-10 h-full "
235303 style = { { padding : layoutCfg . padding } }
236304 >
237305 { /* Header with layout toggle */ }
@@ -259,11 +327,13 @@ export function DashboardContent() {
259327 </ div >
260328
261329 { /* Layout content */ }
262- { layout === "executive" && (
263- < ExecutiveLayout cards = { darkCards } layout = { layoutCfg } />
264- ) }
265- { layout === "operational" && < OperationalLayout /> }
266- { layout === "analytics" && < AnalyticsLayout /> }
330+ < div className = "flex-1 min-h-0" >
331+ { layout === "executive" && (
332+ < ExecutiveLayout cards = { darkCards } layout = { layoutCfg } />
333+ ) }
334+ { layout === "operational" && < OperationalLayout /> }
335+ { layout === "analytics" && < AnalyticsLayout /> }
336+ </ div >
267337 </ div >
268338 </ div >
269339 ) ;
0 commit comments