PageSourceSearch

https://ridedna.ai/assets/MarketplaceBrowsePage-CmwnFlB8.js

js ridedna.ai collected 2026-10-05 14:39:49 UTC 6,330 bytes, 25 lines download raw bytes

1import { H as S, r as a, e as k, j as e, B as h, aL as u, bt as C, bp as P, aG as L, I as H, S as G, f as F, g as A, h as B, l as t, aN as x, C as g, a4 as p, a$ as I, b0 as M, a5 as j, by as T, cO as $, cP as q, cQ as D, aa as E } from "./index-B9miRpwC.js";
2import { S as R } from "./skeleton-DJ-iAzH6.js";
3import { P as z } from "./PageMeta-DyAuYyJA.js";
4import { G as Q } from "./CommunityHelpContent-D62tMJgB.js";
5import { S as O } from "./star-DznhT8iW.js";
6import { E as U } from "./eye-3Ma80GoX.js";
7import "./compass-DzB6ojpN.js";
8import "./trending-up-Cbn6FDrL.js";
9import "./git-fork-D8ArLQHf.js";
10import "./archive-DBpbWSvX.js";
11function ae() {
12  const { user: f } = S(), [r, v] = a.useState(""), [l, y] = a.useState("featured"), [N, o] = a.useState(!1), [i, w] = a.useState(!1), c = a.useMemo(() => {
13    const s = new URLSearchParams();
14    return r.trim() && s.set("q", r.trim()), i && s.set("hasPhotos", "true"), s.set("sort", l), s.toString();
15  }, [r, l, i]), { data: n, isLoading: b } = k({ queryKey: ["/api/marketplace/listings", c], queryFn: async () => {
16    const s = await fetch(`/api/marketplace/listings?${c}`, { credentials: "include" });
17    if (!s.ok) throw new Error("Failed to load");
18    return s.json();
19  } }), d = n?.items ?? [];
20  return e.jsxs("div", { className: "max-w-6xl mx-auto px-4 py-8", children: [e.jsx(z, { title: "Geometry Library \u2014 Public geometries", description: "Browse rider-published bike geometries from the RideDNA community and save any build to your own garage. Photos, descriptions, ratings and full geometry numbers.", canonical: "https://ridedna.ai/community/marketplace" }), e.jsxs("header", { className: "glass-light rounded-md p-4 mb-4 flex flex-wrap items-end justify-between gap-3", children: [e.jsxs("div", { children: [e.jsx("h1", { className: "text-3xl font-semibold tracking-tight", "data-testid": "text-marketplace-title", children: "Geometry Library" }), e.jsx("p", { className: "text-muted-foreground mt-1 max-w-2xl", children: "Public geometries shared by the community \u2014 save any build to your own garage and dial it in further." })] }), e.jsxs("div", { className: "flex items-center gap-2", children: [f && e.jsx(h, { asChild: !0, variant: "outline", "data-testid": "link-marketplace-owner", children: e.jsxs(u, { href: "/community/marketplace/me", children: [e.jsx(C, { className: "h-4 w-4 mr-2" }), "My listings"] }) }), e.jsx(P, { onClick: () => o(!0), tooltipText: "Learn how to use the Geometry Library \u2014 browsing, forking, rating and publishing" })] })] }), e.jsxs("div", { className: "glass-light rounded-md p-3 mb-6 grid gap-3 sm:grid-cols-[1fr,180px,auto]", children: [e.jsxs("div", { className: "relative", children: [e.jsx(L, { className: "h-4 w-4 absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground" }), e.jsx(H, { value: r, onChange: (s) => v(s.target.value), placeholder: "Search listings...", className: "pl-9", "data-testid": "input-search-marketplace" })] }), e.jsxs(G, { value: l, onValueChange: (s) => y(s), children: [e.jsx(F, { "data-testid": "select-sort", children: e.jsx(A, {}) }), e.jsxs(B, { children: [e.jsx(t, { value: "featured", children: "Featured" }), e.jsx(t, { value: "trending", children: "Trending" }), e.jsx(t, { value: "top-rated", children: "Top-rated" }), e.jsx(t, { value: "newest", children: "Newest" }), e.jsx(t, { value: "most-forked", children: "Most forked" })] })] }), e.jsxs(h, { variant: i ? "default" : "outline", onClick: () => w(!i), "data-testid": "button-filter-photos", children: [e.jsx(x, { className: "h-4 w-4 mr-2" }), "Has photos"] })] }), b ? e.jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: [0, 1, 2, 3, 4, 5].map((s) => e.jsx(R, { className: "h-72" }, s)) }) : d.length === 0 ? e.jsx(g, { variant: "glass", children: e.jsx(p, { className: "py-10 text-center text-muted-foreground", children: "No listings match these filters yet." }) }) : e.jsx("div", { className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3", children: d.map((s) => {
21    const m = s.ratingCount > 0 ? s.ratingSum / s.ratingCount : null;
22    return e.jsx(u, { href: `/community/marketplace/${s.slug}`, "data-testid": `card-listing-${s.slug}`, children: e.jsxs(g, { variant: "glass", className: "h-full hover-elevate active-elevate-2 cursor-pointer overflow-hidden", children: [s.heroPhoto ? e.jsx("div", { className: "aspect-video bg-muted overflow-hidden", children: e.jsx("img", { src: s.heroPhoto, alt: s.name, className: "w-full h-full object-cover", loading: "lazy" }) }) : e.jsx("div", { className: "aspect-video bg-gradient-to-br from-muted to-muted/40 flex items-center justify-center", children: e.jsx(x, { className: "h-10 w-10 text-muted-foreground
22/30" }) }), e.jsxs(I, { children: [e.jsxs("div", { className: "flex items-start justify-between gap-2", children: [e.jsx(M, { className: "text-lg line-clamp-1", "data-testid": `text-listing-${s.slug}`, children: s.name }), s.isFeatured && e.jsx(j, { variant: "secondary", children: "Featured" })] }), e.jsxs(T, { className: "line-clamp-1", children: [s.bikeModelName ?? "Custom build", s.frameSize ? ` \u2014 ${s.frameSize}` : ""] })] }), e.jsxs(p, { className: "pt-0 space-y-3", children: [s.discipline && e.jsx("div", { className: "flex flex-wrap gap-1", children: e.jsx(j, { variant: "secondary", className: "text-xs", children: s.discipline }) }), e.jsxs("div", { className: "flex items-center justify-between gap-2 text-xs", children: [e.jsxs("div", { className: "flex items-center gap-2", children: [e.jsxs($, { className: "h-6 w-6", children: [e.jsx(q, { src: s.ownerAvatar ?? void 0 }), e.jsx(D, { children: (s.ownerName ?? "R").slice(0, 1).toUpperCase() })] }), e.jsx("span", { className: "truncate", children: s.ownerName ?? "Rider" })] }), e.jsxs("div", { className: "flex items-center gap-3 text-muted-foreground", children: [e.jsxs("span", { className: "inline-flex items-center gap-0.5", children: [e.jsx(O, { className: "h-3 w-3" }), m !== null ? m.toFixed(1) : "\u2014"] }), e.jsxs("span", { className: "inline-flex items-center gap-0.5", children: [e.jsx(U, { className: "h-3 w-3" }), s.viewCount] })] })] })] })] }) }, s.id);
23  }) }), e.jsx(E, { pageId: "geometry-library", title: "Geometry Library Guide", open: N, onOpenChange: o, children: e.jsx(Q, {}) })] });
24}
25export { ae as default };

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.