diff --git a/src/components/CommunityProjectCard.tsx b/src/components/CommunityProjectCard.tsx
new file mode 100644
index 000000000..53dea7cd5
--- /dev/null
+++ b/src/components/CommunityProjectCard.tsx
@@ -0,0 +1,78 @@
+import { Link } from '@tanstack/react-router'
+import { ArrowSquareOutIcon, CodeIcon } from '@phosphor-icons/react'
+import type { PublicShowcase } from '~/db/types'
+import { libraries } from '~/libraries'
+import { showcaseLinkRel } from '~/utils/showcase.shared'
+
+export function CommunityProjectCard({
+ showcase,
+}: {
+ showcase: PublicShowcase
+}) {
+ return (
+
+
+
+ {showcase.logoUrl ? (
+

+ ) : (
+
+ )}
+
+
+
+ {showcase.name}
+
+
+ {showcase.tagline}
+
+
+ {showcase.libraries
+ .slice(0, 3)
+ .map(
+ (id) =>
+ libraries
+ .find((library) => library.id === id)
+ ?.name.replace('TanStack ', '') ?? id,
+ )
+ .join(' ยท ')}
+ {showcase.libraries.length > 3 &&
+ ` +${showcase.libraries.length - 3}`}
+
+
+
+
+ {showcase.sourceUrl && (
+
+
+
+ )}
+
+
+
+
+
+ )
+}
diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx
index daefde3d4..6d2a637b3 100644
--- a/src/components/Navbar.tsx
+++ b/src/components/Navbar.tsx
@@ -35,6 +35,7 @@ import { ShoppingBagIcon } from '@phosphor-icons/react/ShoppingBag'
import { SignInIcon } from '@phosphor-icons/react/SignIn'
import { SparkleIcon } from '@phosphor-icons/react/Sparkle'
import { TrendUpIcon } from '@phosphor-icons/react/TrendUp'
+import { UsersThreeIcon } from '@phosphor-icons/react/UsersThree'
import { UsersIcon } from '@phosphor-icons/react/Users'
import { XIcon } from '@phosphor-icons/react/X'
import { ThemeToggle } from './ThemeToggle'
@@ -221,7 +222,7 @@ const NAV_GROUPS = [
{
label: 'Community projects',
to: '/community-projects',
- icon: CodeIcon,
+ icon: UsersThreeIcon,
},
],
},
diff --git a/src/components/ShowcaseGallery.tsx b/src/components/ShowcaseGallery.tsx
index bec8f058c..c6d588b29 100644
--- a/src/components/ShowcaseGallery.tsx
+++ b/src/components/ShowcaseGallery.tsx
@@ -7,6 +7,7 @@ import {
} from '~/queries/showcases'
import { voteShowcase } from '~/utils/showcase.functions'
import { ShowcaseCard, ShowcaseCardSkeleton } from './ShowcaseCard'
+import { CommunityProjectCard } from './CommunityProjectCard'
import { SubmitShowcasePlaceholder } from './ShowcaseSection'
import { PaginationControls } from './PaginationControls'
import { ShowcaseTopBarFilters } from './ShowcaseTopBarFilters'
@@ -23,6 +24,9 @@ export function ShowcaseGallery({
}: {
community?: boolean
}) {
+ const gridClassName = community
+ ? 'grid grid-cols-1 md:grid-cols-2 gap-x-10'
+ : 'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6'
const from = community ? '/community-projects' : '/showcase/'
const placement = community ? 'community' : 'showcase'
const navigate = useNavigate({ from })
@@ -56,7 +60,7 @@ export function ShowcaseGallery({
const { data: votesData } = useQuery({
...getMyShowcaseVotesQueryOptions(showcaseIds),
- enabled: !!currentUser && showcaseIds.length > 0,
+ enabled: !community && !!currentUser && showcaseIds.length > 0,
})
const votesMap = React.useMemo(() => {
@@ -308,11 +312,21 @@ export function ShowcaseGallery({
return (
{/* Header */}
-
-
+
+
-
+
{community ? 'Community projects' : 'Showcase'}
{!community && (
@@ -366,27 +380,38 @@ export function ShowcaseGallery({
{/* Grid */}
{isLoading ? (
-
- {Array.from({ length: 6 }).map((_, i) => (
-
- ))}
+
+ {Array.from({ length: 6 }).map((_, i) =>
+ community ? (
+
+ ) : (
+
+ ),
+ )}
) : data?.showcases && data.showcases.length > 0 ? (
<>
-
- {data.showcases.map(({ showcase, user }) => (
-
handleVote(showcase.id, value)}
- isVoting={
- voteMutation.isPending &&
- voteMutation.variables?.showcaseId === showcase.id
- }
- />
- ))}
+
+ {data.showcases.map(({ showcase, user }) =>
+ community ? (
+
+ ) : (
+ handleVote(showcase.id, value)}
+ isVoting={
+ voteMutation.isPending &&
+ voteMutation.variables?.showcaseId === showcase.id
+ }
+ />
+ ),
+ )}
{data.pagination.totalPages > 1 && (