Spaces:
Sleeping
Sleeping
| 'use client'; | |
| import React from 'react'; | |
| import { SAMPLE_QUESTIONS } from '@/lib/mockData'; | |
| interface QuestionInputProps { | |
| onSubmit: (question: string) => void; | |
| isLoading?: boolean; | |
| onSampleQuestion?: (q: string) => void; | |
| showWelcome?: boolean; | |
| } | |
| export function QuestionInput({ onSubmit, isLoading, onSampleQuestion, showWelcome }: QuestionInputProps) { | |
| const [value, setValue] = React.useState(''); | |
| const textareaRef = React.useRef<HTMLTextAreaElement>(null); | |
| const handleSubmit = () => { | |
| const q = value.trim(); | |
| if (!q || isLoading) return; | |
| onSubmit(q); | |
| setValue(''); | |
| if (textareaRef.current) { | |
| textareaRef.current.style.height = 'auto'; | |
| } | |
| }; | |
| const handleKeyDown = (e: React.KeyboardEvent) => { | |
| if (e.key === 'Enter' && !e.shiftKey) { | |
| e.preventDefault(); | |
| handleSubmit(); | |
| } | |
| }; | |
| const handleInput = () => { | |
| const el = textareaRef.current; | |
| if (el) { | |
| el.style.height = 'auto'; | |
| el.style.height = Math.min(el.scrollHeight, 140) + 'px'; | |
| } | |
| }; | |
| return ( | |
| <div className="chat-input-area"> | |
| <div style={{ maxWidth: '780px', margin: '0 auto', width: '100%' }}> | |
| <div className="chat-input-wrapper"> | |
| {/* Document scope indicator */} | |
| <div style={{ | |
| flexShrink: 0, | |
| display: 'flex', | |
| alignItems: 'center', | |
| gap: '0.3rem', | |
| padding: '0.2rem 0.5rem', | |
| background: 'var(--enbd-blue-muted)', | |
| border: '1px solid var(--enbd-blue-border)', | |
| borderRadius: 'var(--radius-sm)', | |
| fontSize: '0.62rem', | |
| color: 'var(--enbd-blue)', | |
| fontWeight: 600, | |
| alignSelf: 'flex-end', | |
| marginBottom: '2px', | |
| whiteSpace: 'nowrap', | |
| }}> | |
| <svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"> | |
| <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/> | |
| <polyline points="14 2 14 8 20 8"/> | |
| </svg> | |
| IR Docs | |
| </div> | |
| <textarea | |
| ref={textareaRef} | |
| id="finbot-question-input" | |
| className="chat-textarea" | |
| value={value} | |
| onChange={e => { setValue(e.target.value); handleInput(); }} | |
| onKeyDown={handleKeyDown} | |
| onInput={handleInput} | |
| rows={1} | |
| placeholder="Ask about financial performance, KPIs, NIM, profitability, capital ratios…" | |
| disabled={isLoading} | |
| /> | |
| <button | |
| className="chat-submit-btn" | |
| id="finbot-submit-btn" | |
| onClick={handleSubmit} | |
| disabled={!value.trim() || isLoading} | |
| title="Submit question (Enter)" | |
| > | |
| {isLoading ? ( | |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" style={{ animation: 'spin 1s linear infinite' }}> | |
| <path d="M21 12a9 9 0 11-6.219-8.56"/> | |
| </svg> | |
| ) : ( | |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"> | |
| <line x1="22" y1="2" x2="11" y2="13"/> | |
| <polygon points="22 2 15 22 11 13 2 9 22 2"/> | |
| </svg> | |
| )} | |
| </button> | |
| </div> | |
| {/* Hint bar */} | |
| <div className="chat-input-hints"> | |
| <span style={{ fontSize: '0.65rem', color: 'var(--text-disabled)' }}> | |
| IR Intelligence · Emirates NBD · Responses grounded in validated document evidence | |
| </span> | |
| <span style={{ fontSize: '0.6rem', color: 'var(--text-disabled)' }}> | |
| Enter ↵ to submit · Shift+Enter for new line | |
| </span> | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| } | |