{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "club-card",
"title": "Club Card",
"description": "Club card with CTA that opens a responsive drawer (right on desktop, bottom on mobile).",
"dependencies": [
"@radix-ui/react-dialog",
"@phosphor-icons/react",
"lucide-react",
"react-markdown",
"remark-gfm",
"rehype-raw",
"rehype-sanitize"
],
"files": [
{
"path": "registry/components/club-card/index.ts",
"content": "export { ClubCard } from \"./index.tsx\"\nexport type { ClubCardProps, CtaTheme, DrawerDirection } from \"./types\"\n",
"type": "registry:block"
},
{
"path": "registry/components/club-card/index.tsx",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ClubCardPreview } from \"./club-card-preview\"\nimport { ClubCardDrawer } from \"./club-card-drawer\"\nimport type { ClubCardProps, DrawerDirection } from \"./types\"\n\nfunction useResolvedDirection(direction: DrawerDirection) {\n const [isDesktop, setIsDesktop] = React.useState(false)\n\n React.useEffect(() => {\n const mediaQuery = window.matchMedia(\"(min-width: 768px)\")\n const sync = () => setIsDesktop(mediaQuery.matches)\n sync()\n mediaQuery.addEventListener(\"change\", sync)\n return () => mediaQuery.removeEventListener(\"change\", sync)\n }, [])\n\n return direction === \"auto\" ? (isDesktop ? \"right\" : \"bottom\") : direction\n}\n\nexport function ClubCard({\n domain,\n name,\n imageUrl,\n miniDescription,\n shouldCompress = false,\n showSuccessIcon = false,\n ctaText,\n cardCtaText,\n drawerCtaText,\n onCtaClick,\n onDrawerOpen,\n onDrawerCtaClick,\n totalMembers,\n detailPoints,\n detailDescription,\n drawerDirection = \"auto\",\n ctaTheme,\n drawerBottomInsetClassName,\n drawerBodyClassName,\n drawerPinFooter = true,\n drawerFooterClassName,\n className,\n}: ClubCardProps) {\n const [open, setOpen] = React.useState(false)\n const wasOpenRef = React.useRef(false)\n const resolvedDirection = useResolvedDirection(drawerDirection)\n const resolvedCardCtaText = cardCtaText ?? ctaText\n const resolvedDrawerCtaText = drawerCtaText ?? ctaText\n\n const handleCtaClick = () => {\n setOpen(true)\n }\n const handleDrawerCtaClick = () => {\n onDrawerCtaClick?.()\n onCtaClick?.()\n }\n\n React.useEffect(() => {\n if (open && !wasOpenRef.current) {\n onDrawerOpen?.()\n }\n wasOpenRef.current = open\n }, [open, onDrawerOpen])\n\n return (\n <>\n
\n {resolvedDomain}\n
\n\n {resolvedDomain}\n
\n\n {resolvedMiniDescription}\n
\n\n {resolvedDomain}\n
\n\n {resolvedName}\n
\n\n {memberCount}{\" \"}\n {memberCount === 1 ? \"member\" : \"members\"}\n
\n