From 257d1bdaee5b255facd413e50bb428c5beedf1a5 Mon Sep 17 00:00:00 2001 From: "Builder.io" Date: Sat, 8 Nov 2025 01:34:24 +0000 Subject: [PATCH] CreatorDirectory page - browse creators with arm filtering cgen-20c280821a2d4d1b906b054ea5a20517 --- client/pages/creators/CreatorDirectory.tsx | 201 +++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 client/pages/creators/CreatorDirectory.tsx diff --git a/client/pages/creators/CreatorDirectory.tsx b/client/pages/creators/CreatorDirectory.tsx new file mode 100644 index 00000000..b06cefc0 --- /dev/null +++ b/client/pages/creators/CreatorDirectory.tsx @@ -0,0 +1,201 @@ +import { useState, useEffect } from "react"; +import { useSearchParams } from "react-router-dom"; +import Layout from "@/components/Layout"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Loader2, Search, Users } from "lucide-react"; +import { getCreators } from "@/api/creators"; +import { CreatorCard } from "@/components/creator-network/CreatorCard"; +import { ArmFilter } from "@/components/creator-network/ArmFilter"; +import type { Creator } from "@/api/creators"; + +export default function CreatorDirectory() { + const [searchParams, setSearchParams] = useSearchParams(); + const [creators, setCreators] = useState([]); + const [isLoading, setIsLoading] = useState(true); + const [search, setSearch] = useState(searchParams.get("search") || ""); + const [selectedArm, setSelectedArm] = useState( + searchParams.get("arm") || undefined + ); + const [page, setPage] = useState(parseInt(searchParams.get("page") || "1")); + const [totalPages, setTotalPages] = useState(0); + + useEffect(() => { + const fetchCreators = async () => { + setIsLoading(true); + try { + const result = await getCreators({ + arm: selectedArm, + search: search || undefined, + page, + limit: 12, + }); + setCreators(result.data); + setTotalPages(result.pagination.pages); + + // Update URL params + const params = new URLSearchParams(); + if (selectedArm) params.set("arm", selectedArm); + if (search) params.set("search", search); + if (page > 1) params.set("page", String(page)); + setSearchParams(params); + } catch (error) { + console.error("Failed to fetch creators:", error); + setCreators([]); + } finally { + setIsLoading(false); + } + }; + + fetchCreators(); + }, [selectedArm, search, page, setSearchParams]); + + const handleSearch = (e: React.FormEvent) => { + e.preventDefault(); + setPage(1); + }; + + const handleArmChange = (arm: string | undefined) => { + setSelectedArm(arm); + setPage(1); + }; + + return ( + +
+ {/* Background */} +
+
+
+
+
+ +
+ {/* Hero Section */} +
+
+
+
+ +

+ Creator Directory +

+
+

+ Discover talented creators across all AeThex arms. Filter by specialty, skills, and arm affiliation. +

+
+ + {/* Search Bar */} +
+
+ + setSearch(e.target.value)} + className="pl-10 h-12 bg-slate-800/50 border-slate-700 text-white placeholder:text-gray-400" + /> + +
+
+
+
+ + {/* Main Content */} +
+
+
+ {/* Filters Sidebar */} +
+
+ +
+
+ + {/* Creators Grid */} +
+ {isLoading ? ( +
+ +
+ ) : creators.length === 0 ? ( +
+ +

+ No creators found +

+

+ Try adjusting your filters or search terms +

+ +
+ ) : ( + <> +
+ {creators.map((creator) => ( + + ))} +
+ + {/* Pagination */} + {totalPages > 1 && ( +
+ +
+ {Array.from({ length: totalPages }, (_, i) => i + 1).map( + (p) => ( + + ) + )} +
+ +
+ )} + + )} +
+
+
+
+
+
+ + ); +}