Γlvaro Valenzuela Valdes commited on
Commit Β·
73126b2
1
Parent(s): f80a9d9
feat: improve mobile responsiveness for agent chat and tender tabs, verified groq integration
Browse files
frontend/components/AgentChat.tsx
CHANGED
|
@@ -161,7 +161,7 @@ export default function AgentChat({ tender, companyProfile }: Props) {
|
|
| 161 |
};
|
| 162 |
|
| 163 |
return (
|
| 164 |
-
<div className="flex flex-col h-[600px] md:h-[650px] glass-card rounded-[2rem] overflow-hidden border border-white/10 bg-slate-900/60 backdrop-blur-xl shadow-2xl transition-all duration-500">
|
| 165 |
<input
|
| 166 |
type="file"
|
| 167 |
ref={fileInputRef}
|
|
@@ -266,15 +266,15 @@ export default function AgentChat({ tender, companyProfile }: Props) {
|
|
| 266 |
)}
|
| 267 |
|
| 268 |
{/* Input Area */}
|
| 269 |
-
<div className="p-
|
| 270 |
-
<div className="flex gap-
|
| 271 |
<button
|
| 272 |
onClick={() => fileInputRef.current?.click()}
|
| 273 |
disabled={isUploading || isLoading}
|
| 274 |
-
className="w-
|
| 275 |
title="Attach Document"
|
| 276 |
>
|
| 277 |
-
<span className={`text-xl ${isUploading ? 'animate-spin' : ''}`}>{isUploading ? 'β' : 'π'}</span>
|
| 278 |
</button>
|
| 279 |
|
| 280 |
<input
|
|
@@ -282,30 +282,30 @@ export default function AgentChat({ tender, companyProfile }: Props) {
|
|
| 282 |
value={input}
|
| 283 |
onChange={(e) => setInput(e.target.value)}
|
| 284 |
onKeyDown={(e) => e.key === 'Enter' && handleSend()}
|
| 285 |
-
placeholder={isUploading ? "Uploading
|
| 286 |
disabled={isUploading}
|
| 287 |
-
className="flex-1 bg-black/40 border border-white/10 rounded-2xl px-
|
| 288 |
/>
|
| 289 |
|
| 290 |
<button
|
| 291 |
onClick={startSpeechRecognition}
|
| 292 |
disabled={isListening || isLoading || isUploading}
|
| 293 |
-
className={`w-
|
| 294 |
isListening
|
| 295 |
? 'bg-red-500/20 border-red-500 shadow-[0_0_20px_rgba(239,68,68,0.4)] animate-pulse'
|
| 296 |
: 'bg-white/5 border-white/10 text-slate-400 hover:bg-white/10'
|
| 297 |
}`}
|
| 298 |
title="Voice Command"
|
| 299 |
>
|
| 300 |
-
<span className="text-xl">{isListening ? 'π' : 'ποΈ'}</span>
|
| 301 |
</button>
|
| 302 |
|
| 303 |
<button
|
| 304 |
onClick={() => handleSend()}
|
| 305 |
disabled={!input.trim() || isLoading || isUploading}
|
| 306 |
-
className="w-
|
| 307 |
>
|
| 308 |
-
<span className="text-xl">βοΈ</span>
|
| 309 |
</button>
|
| 310 |
</div>
|
| 311 |
</div>
|
|
|
|
| 161 |
};
|
| 162 |
|
| 163 |
return (
|
| 164 |
+
<div className="flex flex-col h-[550px] sm:h-[600px] md:h-[650px] lg:h-[700px] glass-card rounded-[2rem] overflow-hidden border border-white/10 bg-slate-900/60 backdrop-blur-xl shadow-2xl transition-all duration-500">
|
| 165 |
<input
|
| 166 |
type="file"
|
| 167 |
ref={fileInputRef}
|
|
|
|
| 266 |
)}
|
| 267 |
|
| 268 |
{/* Input Area */}
|
| 269 |
+
<div className="p-3 md:p-6 bg-white/5 border-t border-white/5">
|
| 270 |
+
<div className="flex gap-1.5 md:gap-3 items-center">
|
| 271 |
<button
|
| 272 |
onClick={() => fileInputRef.current?.click()}
|
| 273 |
disabled={isUploading || isLoading}
|
| 274 |
+
className="w-9 h-9 md:w-12 md:h-12 rounded-xl md:rounded-2xl bg-white/5 border border-white/10 text-slate-400 flex items-center justify-center transition-all hover:bg-white/10 active:scale-95 disabled:opacity-30 shrink-0"
|
| 275 |
title="Attach Document"
|
| 276 |
>
|
| 277 |
+
<span className={`text-lg md:text-xl ${isUploading ? 'animate-spin' : ''}`}>{isUploading ? 'β' : 'π'}</span>
|
| 278 |
</button>
|
| 279 |
|
| 280 |
<input
|
|
|
|
| 282 |
value={input}
|
| 283 |
onChange={(e) => setInput(e.target.value)}
|
| 284 |
onKeyDown={(e) => e.key === 'Enter' && handleSend()}
|
| 285 |
+
placeholder={isUploading ? "Uploading..." : `Message...`}
|
| 286 |
disabled={isUploading}
|
| 287 |
+
className="flex-1 min-w-0 bg-black/40 border border-white/10 rounded-xl md:rounded-2xl px-3 md:px-5 py-2.5 md:py-3 text-white text-xs md:text-sm placeholder:text-slate-600 focus:outline-none focus:ring-2 focus:ring-purple-500/40 transition-all disabled:opacity-50"
|
| 288 |
/>
|
| 289 |
|
| 290 |
<button
|
| 291 |
onClick={startSpeechRecognition}
|
| 292 |
disabled={isListening || isLoading || isUploading}
|
| 293 |
+
className={`w-9 h-9 md:w-12 md:h-12 rounded-xl md:rounded-2xl flex items-center justify-center transition-all active:scale-95 disabled:opacity-30 border shrink-0 ${
|
| 294 |
isListening
|
| 295 |
? 'bg-red-500/20 border-red-500 shadow-[0_0_20px_rgba(239,68,68,0.4)] animate-pulse'
|
| 296 |
: 'bg-white/5 border-white/10 text-slate-400 hover:bg-white/10'
|
| 297 |
}`}
|
| 298 |
title="Voice Command"
|
| 299 |
>
|
| 300 |
+
<span className="text-lg md:text-xl">{isListening ? 'π' : 'ποΈ'}</span>
|
| 301 |
</button>
|
| 302 |
|
| 303 |
<button
|
| 304 |
onClick={() => handleSend()}
|
| 305 |
disabled={!input.trim() || isLoading || isUploading}
|
| 306 |
+
className="w-9 h-9 md:w-12 md:h-12 rounded-xl md:rounded-2xl premium-gradient text-white flex items-center justify-center transition-all active:scale-95 disabled:opacity-30 shadow-lg shadow-purple-500/20 shrink-0"
|
| 307 |
>
|
| 308 |
+
<span className="text-lg md:text-xl">βοΈ</span>
|
| 309 |
</button>
|
| 310 |
</div>
|
| 311 |
</div>
|
frontend/components/TenderSearch.tsx
CHANGED
|
@@ -210,28 +210,30 @@ export default function TenderSearch({ tenders, onSearch, onAnalyze, forceShowFo
|
|
| 210 |
// VIEW: Detail Modal
|
| 211 |
const renderDetailView = (tender: Tender) => (
|
| 212 |
<div className="animate-in slide-in-from-right-8 fade-in duration-700 w-full max-w-[1600px] mx-auto pt-4 pb-20">
|
| 213 |
-
<div className="flex justify-between items-end mb-8 relative z-20">
|
| 214 |
<button
|
| 215 |
onClick={() => {
|
| 216 |
console.log("[TenderSearch] Returning to list...");
|
| 217 |
setSelectedTenderForModal(null);
|
| 218 |
}}
|
| 219 |
-
className="flex items-center gap-4 px-6 py-3 rounded-2xl bg-white/5 border border-white/10 text-slate-400 hover:text-white hover:bg-white/10 transition-all group active:scale-95 cursor-pointer relative z-30"
|
| 220 |
>
|
| 221 |
<span className="text-2xl group-hover:-translate-x-1 transition-transform">β</span>
|
| 222 |
<span className="text-xs font-black uppercase tracking-widest">Back to search</span>
|
| 223 |
</button>
|
| 224 |
-
<div className="flex items-center gap-3 bg-white/5 p-1 rounded-2xl border border-white/10">
|
| 225 |
<button
|
| 226 |
onClick={() => toggleFollow(tender)}
|
| 227 |
-
className={`px-4 py-2.5 rounded-xl text-[10px] font-black uppercase transition-all flex items-center gap-2 ${followedCodes.includes(tender.code) ? "bg-amber-500/20 text-amber-400 border border-amber-500/30" : "bg-white/5 text-slate-400 hover:bg-white/10"}`}
|
| 228 |
>
|
| 229 |
<span>{followedCodes.includes(tender.code) ? "β
" : "β"}</span>
|
| 230 |
<span>{followedCodes.includes(tender.code) ? "In Portfolio" : "Add to Portfolio"}</span>
|
| 231 |
</button>
|
| 232 |
-
<div className="w-px h-6 bg-white/10 mx-1" />
|
| 233 |
-
<
|
| 234 |
-
|
|
|
|
|
|
|
| 235 |
</div>
|
| 236 |
</div>
|
| 237 |
|
|
|
|
| 210 |
// VIEW: Detail Modal
|
| 211 |
const renderDetailView = (tender: Tender) => (
|
| 212 |
<div className="animate-in slide-in-from-right-8 fade-in duration-700 w-full max-w-[1600px] mx-auto pt-4 pb-20">
|
| 213 |
+
<div className="flex flex-col md:flex-row md:justify-between md:items-end gap-6 mb-8 relative z-20">
|
| 214 |
<button
|
| 215 |
onClick={() => {
|
| 216 |
console.log("[TenderSearch] Returning to list...");
|
| 217 |
setSelectedTenderForModal(null);
|
| 218 |
}}
|
| 219 |
+
className="flex items-center gap-4 px-6 py-3 rounded-2xl bg-white/5 border border-white/10 text-slate-400 hover:text-white hover:bg-white/10 transition-all group active:scale-95 cursor-pointer relative z-30 w-fit"
|
| 220 |
>
|
| 221 |
<span className="text-2xl group-hover:-translate-x-1 transition-transform">β</span>
|
| 222 |
<span className="text-xs font-black uppercase tracking-widest">Back to search</span>
|
| 223 |
</button>
|
| 224 |
+
<div className="flex flex-col sm:flex-row items-stretch sm:items-center gap-3 bg-white/5 p-1 rounded-2xl border border-white/10 w-full md:w-auto">
|
| 225 |
<button
|
| 226 |
onClick={() => toggleFollow(tender)}
|
| 227 |
+
className={`px-4 py-2.5 rounded-xl text-[10px] font-black uppercase transition-all flex items-center justify-center gap-2 ${followedCodes.includes(tender.code) ? "bg-amber-500/20 text-amber-400 border border-amber-500/30" : "bg-white/5 text-slate-400 hover:bg-white/10"}`}
|
| 228 |
>
|
| 229 |
<span>{followedCodes.includes(tender.code) ? "β
" : "β"}</span>
|
| 230 |
<span>{followedCodes.includes(tender.code) ? "In Portfolio" : "Add to Portfolio"}</span>
|
| 231 |
</button>
|
| 232 |
+
<div className="hidden sm:block w-px h-6 bg-white/10 mx-1" />
|
| 233 |
+
<div className="flex gap-2">
|
| 234 |
+
<button onClick={() => setActiveDetailTab("Overview")} className={`flex-1 md:flex-none px-6 py-2.5 rounded-xl text-xs font-black uppercase transition-all ${activeDetailTab === "Overview" ? "bg-purple-600 text-white shadow-lg" : "text-slate-500 bg-white/5"}`}>Overview</button>
|
| 235 |
+
<button onClick={() => setActiveDetailTab("Agent Chat")} className={`flex-1 md:flex-none px-6 py-2.5 rounded-xl text-xs font-black uppercase transition-all ${activeDetailTab === "Agent Chat" ? "bg-purple-600 text-white shadow-lg" : "text-slate-500 bg-white/5"}`}>Agent Chat</button>
|
| 236 |
+
</div>
|
| 237 |
</div>
|
| 238 |
</div>
|
| 239 |
|