'use client' /** * @file Integrations overview page with search, category filters, and grouped grid. * * Displays all 75+ integrations in a filterable, searchable grid. * Features: search with result count, category chips, popular section, * keyboard shortcut (/ to focus search), and "Missing something?" card. */ import { useState, useMemo, useRef, useEffect, useCallback } from 'react' import Link from 'next/link' import { motion, AnimatePresence } from 'framer-motion' import { ArrowRightIcon } from '@ciphera-net/ui' import { integrations, categoryLabels, categoryOrder, type IntegrationCategory, } from '@/lib/integrations' // * IDs of popular integrations shown in the pinned "Popular" row const POPULAR_IDS = [ 'nextjs', 'react', 'wordpress', 'shopify', 'webflow', 'vue', 'astro', 'vercel', ] export default function IntegrationsPage() { const [query, setQuery] = useState('') const [activeCategory, setActiveCategory] = useState('all') const searchRef = useRef(null) // * Keyboard shortcut: "/" to focus search useEffect(() => { function handleKeyDown(e: KeyboardEvent) { if ( e.key === '/' && !['INPUT', 'TEXTAREA', 'SELECT'].includes((e.target as HTMLElement).tagName) ) { e.preventDefault() searchRef.current?.focus() } } document.addEventListener('keydown', handleKeyDown) return () => document.removeEventListener('keydown', handleKeyDown) }, []) // * Filter integrations by search query + active category const { filteredGroups, totalResults, popularIntegrations } = useMemo(() => { const q = query.toLowerCase().trim() const isSearching = q.length > 0 const isCategoryFiltered = activeCategory !== 'all' let filtered = integrations if (isSearching) { filtered = filtered.filter( (i) => i.name.toLowerCase().includes(q) || i.description.toLowerCase().includes(q) || categoryLabels[i.category].toLowerCase().includes(q), ) } if (isCategoryFiltered) { filtered = filtered.filter((i) => i.category === activeCategory) } const groups = categoryOrder .map((cat) => ({ category: cat as IntegrationCategory, label: categoryLabels[cat], items: filtered.filter((i) => i.category === cat), })) .filter((g) => g.items.length > 0) // * Only show popular row when not searching/filtering const popular = !isSearching && !isCategoryFiltered ? POPULAR_IDS.map((id) => integrations.find((i) => i.id === id)).filter(Boolean) : [] return { filteredGroups: groups, totalResults: filtered.length, popularIntegrations: popular } }, [query, activeCategory]) const hasResults = filteredGroups.length > 0 const isFiltering = query.length > 0 || activeCategory !== 'all' const handleCategoryClick = useCallback((cat: IntegrationCategory | 'all') => { setActiveCategory(cat) }, []) return (
{/* * --- ATMOSPHERE (Background) --- */}
{/* * --- Title with count badge --- */}

Integrations

{integrations.length}+

Connect Pulse with {integrations.length}+ frameworks and platforms in minutes.

{/* * --- Search Input with "/" hint --- */}
setQuery(e.target.value)} placeholder="Search integrations..." className="w-full pl-12 pr-16 py-3 bg-neutral-900/70 backdrop-blur-sm border border-white/[0.08] rounded-xl text-white placeholder:text-neutral-400 focus:outline-none focus:ring-2 focus:ring-brand-orange/50 focus:border-brand-orange/50 transition-all" /> {query ? ( ) : (
/
)}
{/* * --- Result count (shown when filtering) --- */} {isFiltering && ( {totalResults} {totalResults === 1 ? 'integration' : 'integrations'} found {query && <> for “{query}”} )}
{/* * --- Category Filter Chips --- */} {categoryOrder.map((cat) => ( ))} {hasResults ? ( {/* * --- Popular Integrations (pinned row) --- */} {popularIntegrations.length > 0 && (
Popular
{popularIntegrations.map((integration, i) => (
{integration!.icon}
{integration!.name}
))}
)} {/* * --- Category Groups --- */} {filteredGroups.map((group) => (
{group.label}
{group.items.map((integration, i) => (
{integration.icon}

{integration.name}

{integration.description}

View Guide
))}
))}
) : ( // * --- No Results: "Missing something?" card ---

Missing something?

No integrations found for “{query}”.

Let us know which integration you'd like to see next.

Request Integration
)}
{/* * Request Integration Card — always shown when there ARE results */} {hasResults && (

Missing something?

Let us know which integration you'd like to see next.

Request Integration
)}
) }