Álvaro Valenzuela Valdes commited on
Commit
482905a
·
1 Parent(s): 05e0832

Fix TenderSearch button interaction, guard duplicate submits, and add portal link in results

Browse files
frontend/app/page.tsx CHANGED
@@ -116,7 +116,7 @@ export default function HomePage() {
116
  window.history.pushState({}, '', `?tab=tender_search&q=${encodeURIComponent(value)}`);
117
  };
118
 
119
- const handleSearch = async (params: { keyword?: string; buyer?: string; provider_code?: string; date?: string; skip?: number; limit?: number; isAgile?: boolean }) => {
120
  try {
121
  let results: Tender[];
122
  if (params.isAgile && params.keyword) {
 
116
  window.history.pushState({}, '', `?tab=tender_search&q=${encodeURIComponent(value)}`);
117
  };
118
 
119
+ const handleSearch = async (params: { keyword?: string; buyer?: string; provider_code?: string; org_code?: string; status?: string; code?: string; date?: string; skip?: number; limit?: number; isAgile?: boolean }) => {
120
  try {
121
  let results: Tender[];
122
  if (params.isAgile && params.keyword) {
frontend/components/TenderSearch.tsx CHANGED
@@ -1,6 +1,6 @@
1
  "use client";
2
 
3
- import { Fragment, useMemo, useState, useEffect } from "react";
4
  import BrandLoader from "./BrandLoader";
5
  import type { Tender } from "../lib/types";
6
  import { Language, translations } from "../lib/translations";
@@ -39,6 +39,7 @@ export default function TenderSearch({ tenders, onSearch, onAnalyze, forceShowFo
39
  const [showOnlyFollowed, setShowOnlyFollowed] = useState(forceShowFollowed);
40
  const [isLoading, setIsLoading] = useState(false);
41
  const [isAgileMode, setIsAgileMode] = useState(false);
 
42
  const itemsPerPage = 50;
43
 
44
  const isTenderCode = /^[0-9]+-[0-9]+-[A-Z0-9]+$/i.test(keyword);
@@ -101,6 +102,8 @@ export default function TenderSearch({ tenders, onSearch, onAnalyze, forceShowFo
101
 
102
  const handleSearch = async (e?: React.FormEvent) => {
103
  if (e) e.preventDefault();
 
 
104
  setIsLoading(true);
105
  try {
106
  // Logic: If the query looks like a code (contains hyphens), prioritize code search
@@ -122,6 +125,7 @@ export default function TenderSearch({ tenders, onSearch, onAnalyze, forceShowFo
122
  console.error(error);
123
  } finally {
124
  setIsLoading(false);
 
125
  }
126
  };
127
 
@@ -380,6 +384,16 @@ export default function TenderSearch({ tenders, onSearch, onAnalyze, forceShowFo
380
  {followedCodes.includes(tender.code) ? "★" : "☆"}
381
  </button>
382
  <span className="font-mono text-purple-400 text-[9px] truncate">{tender.code}</span>
 
 
 
 
 
 
 
 
 
 
383
  </div>
384
  </td>
385
  <td className="px-4 py-5">
 
1
  "use client";
2
 
3
+ import { Fragment, useMemo, useState, useRef, useEffect } from "react";
4
  import BrandLoader from "./BrandLoader";
5
  import type { Tender } from "../lib/types";
6
  import { Language, translations } from "../lib/translations";
 
39
  const [showOnlyFollowed, setShowOnlyFollowed] = useState(forceShowFollowed);
40
  const [isLoading, setIsLoading] = useState(false);
41
  const [isAgileMode, setIsAgileMode] = useState(false);
42
+ const isSearchPending = useRef(false);
43
  const itemsPerPage = 50;
44
 
45
  const isTenderCode = /^[0-9]+-[0-9]+-[A-Z0-9]+$/i.test(keyword);
 
102
 
103
  const handleSearch = async (e?: React.FormEvent) => {
104
  if (e) e.preventDefault();
105
+ if (isSearchPending.current) return;
106
+ isSearchPending.current = true;
107
  setIsLoading(true);
108
  try {
109
  // Logic: If the query looks like a code (contains hyphens), prioritize code search
 
125
  console.error(error);
126
  } finally {
127
  setIsLoading(false);
128
+ isSearchPending.current = false;
129
  }
130
  };
131
 
 
384
  {followedCodes.includes(tender.code) ? "★" : "☆"}
385
  </button>
386
  <span className="font-mono text-purple-400 text-[9px] truncate">{tender.code}</span>
387
+ <a
388
+ href={`https://www.mercadopublico.cl/fichaLicitacion.html?code=${tender.code}`}
389
+ target="_blank"
390
+ rel="noopener noreferrer"
391
+ onClick={(e) => e.stopPropagation()}
392
+ className="ml-2 text-[10px] text-slate-400 hover:text-white transition"
393
+ title="Open Tender in Mercado Público"
394
+ >
395
+
396
+ </a>
397
  </div>
398
  </td>
399
  <td className="px-4 py-5">