Álvaro Valenzuela Valdes commited on
Commit
bc31c2f
·
1 Parent(s): 759a61a

feat: complete tender detail view with attachments, items, and external link

Browse files
Files changed (1) hide show
  1. frontend/components/TenderSearch.tsx +105 -19
frontend/components/TenderSearch.tsx CHANGED
@@ -181,33 +181,119 @@ export default function TenderSearch({ tenders, onSearch, onAnalyze, forceShowFo
181
  const renderDetailView = (tender: Tender) => (
182
  <div className="animate-in slide-in-from-right-8 fade-in duration-700 w-full max-w-[1600px] mx-auto pt-4 pb-20">
183
  <div className="flex justify-between items-end mb-8">
184
- <button onClick={() => setSelectedTenderForModal(null)} className="flex items-center gap-2 text-slate-400 hover:text-white transition group">
185
- <span className="text-xl group-hover:-translate-x-1 transition-transform">←</span>
186
- <span className="text-sm font-bold uppercase tracking-widest">Back to search</span>
187
  </button>
188
  <div className="flex bg-white/5 p-1 rounded-2xl border border-white/10">
189
- <button onClick={() => setActiveDetailTab("Overview")} className={`px-6 py-2.5 rounded-xl text-xs font-black uppercase transition-all ${activeDetailTab === "Overview" ? "bg-purple-600 text-white" : "text-slate-500"}`}>Overview</button>
190
- <button onClick={() => setActiveDetailTab("Agent Chat")} className={`px-6 py-2.5 rounded-xl text-xs font-black uppercase transition-all ${activeDetailTab === "Agent Chat" ? "bg-purple-600 text-white" : "text-slate-500"}`}>Agent Chat</button>
191
  </div>
192
  </div>
193
 
194
  {activeDetailTab === "Overview" ? (
195
- <div className="glass-card rounded-[2.5rem] overflow-hidden border border-white/5 bg-slate-900/40 backdrop-blur-xl p-10 md:p-14">
196
- <div className="flex items-center gap-3 mb-6">
197
- <span className="text-sm font-mono text-purple-400 bg-purple-400/10 px-3 py-1 rounded-lg">{tender.code}</span>
198
- <span className="px-3 py-1 rounded-lg text-xs font-black uppercase bg-green-500/10 text-green-400">{tender.status}</span>
199
- </div>
200
- <h3 className="text-3xl md:text-4xl font-black text-white leading-tight mb-8">{tender.name}</h3>
201
- <div className="grid lg:grid-cols-3 gap-12">
202
- <div className="lg:col-span-2 space-y-8">
203
- <div className="text-slate-300 leading-relaxed text-lg bg-white/[0.02] p-8 rounded-[2rem] border border-white/5 whitespace-pre-wrap">{tender.description || "No description provided."}</div>
 
 
 
 
 
 
 
 
204
  </div>
205
- <div className="space-y-6">
206
- <div className="p-8 rounded-[2rem] bg-purple-600/10 border border-purple-500/20">
207
- <div className="text-[10px] text-slate-500 font-bold uppercase mb-1">Closing Deadline</div>
208
- <div className="text-2xl font-black text-white font-mono">{tender.closing_date ? new Date(tender.closing_date).toLocaleDateString() : "---"}</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  </div>
210
- <button onClick={() => { onAnalyze(tender); setSelectedTenderForModal(null); }} className="w-full premium-gradient text-white px-8 py-4 rounded-2xl font-black uppercase shadow-xl">Analyze with AI</button>
211
  </div>
212
  </div>
213
  </div>
 
181
  const renderDetailView = (tender: Tender) => (
182
  <div className="animate-in slide-in-from-right-8 fade-in duration-700 w-full max-w-[1600px] mx-auto pt-4 pb-20">
183
  <div className="flex justify-between items-end mb-8">
184
+ <button onClick={() => setSelectedTenderForModal(null)} className="flex items-center gap-4 px-4 py-2 rounded-xl bg-white/5 border border-white/10 text-slate-400 hover:text-white hover:bg-white/10 transition-all group active:scale-95">
185
+ <span className="text-2xl group-hover:-translate-x-1 transition-transform">←</span>
186
+ <span className="text-xs font-black uppercase tracking-widest">Back to search</span>
187
  </button>
188
  <div className="flex bg-white/5 p-1 rounded-2xl border border-white/10">
189
+ <button onClick={() => setActiveDetailTab("Overview")} className={`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"}`}>Overview</button>
190
+ <button onClick={() => setActiveDetailTab("Agent Chat")} className={`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"}`}>Agent Chat</button>
191
  </div>
192
  </div>
193
 
194
  {activeDetailTab === "Overview" ? (
195
+ <div className="space-y-8">
196
+ <div className="glass-card rounded-[2.5rem] overflow-hidden border border-white/5 bg-slate-900/40 backdrop-blur-xl p-10 md:p-14 relative">
197
+ <div className="absolute top-0 right-0 p-8">
198
+ <a
199
+ href={`https://www.mercadopublico.cl/fichaLicitacion.html?code=${tender.code}`}
200
+ target="_blank"
201
+ rel="noopener noreferrer"
202
+ className="flex items-center gap-2 px-4 py-2 rounded-xl bg-cyan/10 border border-cyan/30 text-cyan text-[10px] font-black uppercase tracking-widest hover:bg-cyan/20 transition-all"
203
+ >
204
+ Visit Official Site 🔗
205
+ </a>
206
+ </div>
207
+
208
+ <div className="flex items-center gap-3 mb-6">
209
+ <span className="text-sm font-mono text-purple-400 bg-purple-400/10 px-3 py-1 rounded-lg border border-purple-400/20">{tender.code}</span>
210
+ <span className="px-3 py-1 rounded-lg text-xs font-black uppercase bg-green-500/10 text-green-400 border border-green-500/20">{tender.status}</span>
211
+ <span className="px-3 py-1 rounded-lg text-[10px] font-bold uppercase bg-white/5 text-slate-500 border border-white/10">{tender.type || "N/A"}</span>
212
  </div>
213
+
214
+ <h3 className="text-3xl md:text-5xl font-black text-white leading-tight mb-4 max-w-4xl">{tender.name}</h3>
215
+ <p className="text-slate-400 text-xl font-medium mb-12">{tender.buyer}</p>
216
+
217
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-12">
218
+ <div className="bg-white/5 p-6 rounded-3xl border border-white/5">
219
+ <p className="text-[10px] uppercase font-bold text-slate-500 tracking-[0.2em] mb-2">Estimated Investment</p>
220
+ <p className="text-2xl font-black text-white">
221
+ {tender.estimated_amount ? new Intl.NumberFormat("es-CL", { style: "currency", currency: tender.currency || "CLP", maximumFractionDigits: 0 }).format(tender.estimated_amount) : "N/A"}
222
+ </p>
223
+ </div>
224
+ <div className="bg-white/5 p-6 rounded-3xl border border-white/5">
225
+ <p className="text-[10px] uppercase font-bold text-slate-500 tracking-[0.2em] mb-2">Closing Deadline</p>
226
+ <p className="text-2xl font-black text-white font-mono">{tender.closing_date ? new Date(tender.closing_date).toLocaleDateString() : "---"}</p>
227
+ </div>
228
+ <div className="bg-white/5 p-6 rounded-3xl border border-white/5">
229
+ <p className="text-[10px] uppercase font-bold text-slate-500 tracking-[0.2em] mb-2">Region</p>
230
+ <p className="text-2xl font-black text-white truncate" title={tender.region}>{tender.region || "Nacional"}</p>
231
+ </div>
232
+ <div className="bg-white/5 p-6 rounded-3xl border border-white/5">
233
+ <p className="text-[10px] uppercase font-bold text-slate-500 tracking-[0.2em] mb-2">Sector</p>
234
+ <p className="text-2xl font-black text-white truncate">{tender.sector || "General"}</p>
235
+ </div>
236
+ </div>
237
+
238
+ <div className="grid lg:grid-cols-3 gap-12">
239
+ <div className="lg:col-span-2 space-y-8">
240
+ <div>
241
+ <h4 className="text-[10px] font-black uppercase tracking-[0.3em] text-slate-500 mb-4">Detailed Description</h4>
242
+ <div className="text-slate-300 leading-relaxed text-lg bg-white/[0.02] p-10 rounded-[2.5rem] border border-white/5 whitespace-pre-wrap">{tender.description || "No description provided."}</div>
243
+ </div>
244
+
245
+ {tender.items && tender.items.length > 0 && (
246
+ <div>
247
+ <h4 className="text-[10px] font-black uppercase tracking-[0.3em] text-slate-500 mb-4">Products / Services Required</h4>
248
+ <div className="overflow-hidden rounded-3xl border border-white/5 bg-black/20">
249
+ <table className="w-full text-left text-xs">
250
+ <thead className="bg-white/5 text-slate-500 font-bold uppercase text-[9px]">
251
+ <tr>
252
+ <th className="px-6 py-4">Item Name</th>
253
+ <th className="px-6 py-4 text-right">Quantity</th>
254
+ </tr>
255
+ </thead>
256
+ <tbody className="divide-y divide-white/5">
257
+ {tender.items.map((item, idx) => (
258
+ <tr key={idx} className="hover:bg-white/5 transition-colors">
259
+ <td className="px-6 py-4 text-slate-300 font-medium">{item.name}</td>
260
+ <td className="px-6 py-4 text-right font-mono text-cyan">{item.quantity} {item.unit}</td>
261
+ </tr>
262
+ ))}
263
+ </tbody>
264
+ </table>
265
+ </div>
266
+ </div>
267
+ )}
268
+ </div>
269
+
270
+ <div className="space-y-8">
271
+ <div className="p-8 rounded-[2.5rem] bg-purple-600/10 border border-purple-500/20 relative overflow-hidden group">
272
+ <div className="absolute -right-10 -bottom-10 h-32 w-32 bg-purple-500/10 rounded-full blur-3xl group-hover:bg-purple-500/20 transition-all" />
273
+ <h4 className="text-[10px] font-black uppercase tracking-[0.3em] text-purple-400 mb-6">Decision Intelligence</h4>
274
+ <p className="text-xs text-slate-400 leading-relaxed mb-8">Launch our multi-agent AI pipeline to analyze compliance, risks, and win-probability for this opportunity.</p>
275
+ <button onClick={() => { onAnalyze(tender); setSelectedTenderForModal(null); }} className="w-full premium-gradient text-white px-8 py-5 rounded-2xl font-black uppercase shadow-xl shadow-purple-500/20 hover:scale-[1.02] active:scale-[0.98] transition-all">Analyze with AI</button>
276
+ </div>
277
+
278
+ <div className="p-8 rounded-[2.5rem] bg-white/5 border border-white/10">
279
+ <h4 className="text-[10px] font-black uppercase tracking-[0.3em] text-slate-500 mb-6">Documents & Attachments</h4>
280
+ {tender.attachments && tender.attachments.length > 0 ? (
281
+ <div className="space-y-3">
282
+ {tender.attachments.map((att, idx) => (
283
+ <a key={idx} href={att.url} target="_blank" rel="noopener noreferrer" className="flex items-center justify-between p-4 rounded-xl bg-black/40 border border-white/5 hover:border-purple-500/40 transition-all group">
284
+ <span className="text-[11px] text-slate-400 group-hover:text-white truncate max-w-[180px]">{att.name}</span>
285
+ <span className="text-xs">📥</span>
286
+ </a>
287
+ ))}
288
+ </div>
289
+ ) : (
290
+ <div className="text-center py-10 px-4 rounded-2xl bg-black/20 border border-dashed border-white/10">
291
+ <span className="text-2xl mb-2 block">📄</span>
292
+ <p className="text-[10px] text-slate-600 font-bold uppercase leading-relaxed">No direct attachments found. Check the official site for the full bidding package.</p>
293
+ </div>
294
+ )}
295
+ </div>
296
  </div>
 
297
  </div>
298
  </div>
299
  </div>