From 826328460bb64269831ab433284be1045b5e014e Mon Sep 17 00:00:00 2001 From: Diksha Jain Date: Mon, 10 Nov 2025 10:41:47 +0530 Subject: [PATCH] integration app one component search bar created --- .../integrationsAppOneComp.js | 151 ++++++++++++++++-- 1 file changed, 141 insertions(+), 10 deletions(-) diff --git a/src/components/IntegrationsComp/integrationsAppOneComp/integrationsAppOneComp.js b/src/components/IntegrationsComp/integrationsAppOneComp/integrationsAppOneComp.js index b23e758c..e726dd64 100644 --- a/src/components/IntegrationsComp/integrationsAppOneComp/integrationsAppOneComp.js +++ b/src/components/IntegrationsComp/integrationsAppOneComp/integrationsAppOneComp.js @@ -22,6 +22,7 @@ import IntegrationSearchApps from '../integrationsAppComp/integrationSearchApps' import { APPERPAGE } from '@/const/integrations'; import { GrFormPreviousLink, GrFormNextLink } from 'react-icons/gr'; import TemplateContainer from '../templateContainer/templateContainer'; +import { IoMdSearch, IoMdClose } from 'react-icons/io'; export default function IntegrationsAppOneComp({ appOneDetails, @@ -46,6 +47,11 @@ export default function IntegrationsAppOneComp({ const [searchedCategories, setSearchedCategories] = useState(null); const [debounceValue, setDebounceValue] = useState(''); const [activeStep, setActiveStep] = useState(1); + const [comboSearch, setComboSearch] = useState(''); + const [comboSuggestions, setComboSuggestions] = useState([]); + const [selectedAppSlug, setSelectedAppSlug] = useState(null); + const [pairCombosData, setPairCombosData] = useState(null); + const [loadingPair, setLoadingPair] = useState(false); useEffect(() => { const interval = setInterval(() => { @@ -168,6 +174,7 @@ export default function IntegrationsAppOneComp({ onSearchResults={handleSearchResults} onCategoriesResults={handleCategoriesResults} onDebounceValueChange={handleDebounceValueChange} + app={appOneDetails} /> @@ -201,12 +208,134 @@ export default function IntegrationsAppOneComp({
0 && 'dotted-background'}`}>
- {combosData?.combinations?.length > 0 ? ( + {(pairCombosData ? pairCombosData?.combinations?.length > 0 : combosData?.combinations?.length > 0) ? ( <>

{`Ready to use ${appOneDetails?.name} automations`}

+
+ {selectedAppSlug ? ( +

Showing automations for {appOneDetails?.name} + {combosData?.plugins?.[selectedAppSlug]?.name || selectedAppSlug}

+ ) : ( + + )} +
+
+ + { + const val = e.target.value; + setComboSearch(val); + if (!val) { + setComboSuggestions([]); + // If user cleared input, also clear selection and pair results + if (selectedAppSlug) { + setSelectedAppSlug(null); + setPairCombosData(null); + } + return; + } + // If user edits after selecting, auto-clear selection to resume live suggestions + if (selectedAppSlug) { + const selectedName = combosData?.plugins?.[selectedAppSlug]?.name || selectedAppSlug; + if (val !== selectedName) { + setSelectedAppSlug(null); + setPairCombosData(null); + } + } + // Build a unified suggestions map from combosData.plugins and apps prop + const mergedMap = new Map(); + + // From combos data (paired apps) + const comboPluginSlugs = Object.keys(combosData?.plugins || {}); + comboPluginSlugs.forEach((slug) => { + mergedMap.set(slug, { + slug, + name: combosData?.plugins?.[slug]?.name || slug, + iconurl: combosData?.plugins?.[slug]?.iconurl, + }); + }); + + // From apps prop (paginated catalog page) + (apps || []).forEach((app) => { + if (!app?.appslugname) return; + mergedMap.set(app.appslugname, { + slug: app.appslugname, + name: app.name || app.appslugname, + iconurl: app.iconurl, + }); + }); + + // Turn into array, exclude current app, filter by query, limit + const suggestions = Array.from(mergedMap.values()) + .filter((item) => item.slug !== appOneDetails?.appslugname) + .filter((item) => { + const displayName = item.name || item.slug; + return displayName.toLowerCase().includes(val.toLowerCase()); + }) + .slice(0, 8); + setComboSuggestions(suggestions); + }} + placeholder={`Search any app e.g. Gmail, Slack`} + className="w-full outline-none text-base" + /> + {selectedAppSlug && ( + + )} +
+ {comboSuggestions?.length > 0 && ( +
    + {comboSuggestions.map((s) => ( +
  • { + setSelectedAppSlug(s.slug); + setComboSearch(s.name); + setComboSuggestions([]); + // Fetch pair-specific combos + try { + setLoadingPair(true); + const base = process.env.NEXT_PUBLIC_INTEGRATION_URL; + const url = `${base}api/v1/plugins/recommend/integrations?service=${integrationsInfo?.appone}&service=${s.slug}`; + const res = await fetch(url, { cache: 'no-store' }); + if (res.ok) { + const data = await res.json(); + setPairCombosData(data); + setVisibleCombos(12); + setShowMore((data?.combinations?.length || 0) >= 12); + } else { + setPairCombosData({ combinations: [] }); + } + } catch (e) { + setPairCombosData({ combinations: [] }); + } finally { + setLoadingPair(false); + } + }} + > + {s.name} + {s.name} +
  • + ))} +
+ )} +
+
- {combosData?.combinations + {(pairCombosData ? pairCombosData?.combinations : combosData?.combinations) ?.filter( (combo) => combo?.description && @@ -214,18 +343,19 @@ export default function IntegrationsAppOneComp({ ) ?.slice(0, visibleCombos) ?.map((combo, index) => { + const pluginsMap = pairCombosData?.plugins || combosData?.plugins; const integrations = - combosData?.plugins[combo?.trigger?.name]?.rowid + + pluginsMap[combo?.trigger?.name]?.rowid + ',' + - combosData?.plugins[combo?.actions[0]?.name]?.rowid; + pluginsMap[combo?.actions[0]?.name]?.rowid; - const triggerName = combosData?.plugins[ + const triggerName = pluginsMap[ combo?.trigger?.name ]?.events?.find( (event) => event?.rowid === combo?.trigger?.id )?.name; - const actionName = combosData?.plugins[ + const actionName = pluginsMap[ combo?.actions[0]?.name ]?.events?.find( (event) => event?.rowid === combo?.actions[0]?.id @@ -237,14 +367,14 @@ export default function IntegrationsAppOneComp({ trigger={{ name: triggerName, iconurl: - combosData?.plugins[ + (pairCombosData?.plugins || combosData?.plugins)[ combo?.trigger?.name ]?.iconurl || 'https://placehold.co/40x40', }} action={{ name: actionName, iconurl: - combosData?.plugins[ + (pairCombosData?.plugins || combosData?.plugins)[ combo?.actions[0]?.name ]?.iconurl || 'https://placehold.co/40x40', }} @@ -261,13 +391,14 @@ export default function IntegrationsAppOneComp({ )}