@burdenoff/microfe-comradecircle 2026.819.1 → 2026.830.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/comradecircle/components/AvatarUploadField.js +8 -8
- package/dist/comradecircle/components/CircleCard.js +4 -4
- package/dist/comradecircle/components/CommentThread.d.ts.map +1 -1
- package/dist/comradecircle/components/CommentThread.js +66 -61
- package/dist/comradecircle/components/CommentThread.js.map +1 -1
- package/dist/comradecircle/components/CreateCircleDialog.d.ts.map +1 -1
- package/dist/comradecircle/components/CreateCircleDialog.js +89 -88
- package/dist/comradecircle/components/CreateCircleDialog.js.map +1 -1
- package/dist/comradecircle/components/CreateEventDialog.d.ts.map +1 -1
- package/dist/comradecircle/components/CreateEventDialog.js +28 -27
- package/dist/comradecircle/components/CreateEventDialog.js.map +1 -1
- package/dist/comradecircle/components/DraftsPanel.d.ts +32 -0
- package/dist/comradecircle/components/DraftsPanel.d.ts.map +1 -0
- package/dist/comradecircle/components/DraftsPanel.js +176 -0
- package/dist/comradecircle/components/DraftsPanel.js.map +1 -0
- package/dist/comradecircle/components/EventCard.js +5 -5
- package/dist/comradecircle/components/FileImage.js +5 -5
- package/dist/comradecircle/components/ImageAttachments.js +21 -21
- package/dist/comradecircle/components/MemberIdentity.js +4 -4
- package/dist/comradecircle/components/MobileBottomNav.d.ts.map +1 -1
- package/dist/comradecircle/components/MobileBottomNav.js +37 -30
- package/dist/comradecircle/components/MobileBottomNav.js.map +1 -1
- package/dist/comradecircle/components/Pagination.d.ts.map +1 -1
- package/dist/comradecircle/components/Pagination.js +37 -28
- package/dist/comradecircle/components/Pagination.js.map +1 -1
- package/dist/comradecircle/components/PollCard.js +13 -13
- package/dist/comradecircle/components/PostCard.d.ts.map +1 -1
- package/dist/comradecircle/components/PostCard.js +102 -89
- package/dist/comradecircle/components/PostCard.js.map +1 -1
- package/dist/comradecircle/components/PostComposer.d.ts +11 -5
- package/dist/comradecircle/components/PostComposer.d.ts.map +1 -1
- package/dist/comradecircle/components/PostComposer.js +60 -48
- package/dist/comradecircle/components/PostComposer.js.map +1 -1
- package/dist/comradecircle/components/ReactionBar.d.ts.map +1 -1
- package/dist/comradecircle/components/ReactionBar.js +65 -55
- package/dist/comradecircle/components/ReactionBar.js.map +1 -1
- package/dist/comradecircle/components/StateViews.d.ts.map +1 -1
- package/dist/comradecircle/components/StateViews.js +38 -30
- package/dist/comradecircle/components/StateViews.js.map +1 -1
- package/dist/comradecircle/components/UpcomingEvents.d.ts +26 -0
- package/dist/comradecircle/components/UpcomingEvents.d.ts.map +1 -0
- package/dist/comradecircle/components/UpcomingEvents.js +126 -0
- package/dist/comradecircle/components/UpcomingEvents.js.map +1 -0
- package/dist/comradecircle/components/index.d.ts +2 -0
- package/dist/comradecircle/components/index.d.ts.map +1 -1
- package/dist/comradecircle/hooks/index.d.ts +1 -0
- package/dist/comradecircle/hooks/index.d.ts.map +1 -1
- package/dist/comradecircle/hooks/index.js +1 -0
- package/dist/comradecircle/hooks/useTr.d.ts +18 -0
- package/dist/comradecircle/hooks/useTr.d.ts.map +1 -0
- package/dist/comradecircle/hooks/useTr.js +12 -0
- package/dist/comradecircle/hooks/useTr.js.map +1 -0
- package/dist/comradecircle/pages/FeedPage.d.ts +5 -0
- package/dist/comradecircle/pages/FeedPage.d.ts.map +1 -1
- package/dist/comradecircle/pages/FeedPage.js +76 -62
- package/dist/comradecircle/pages/FeedPage.js.map +1 -1
- package/dist/comradecircle/pages/circles/CircleDetailPage.d.ts.map +1 -1
- package/dist/comradecircle/pages/circles/CircleDetailPage.js +454 -409
- package/dist/comradecircle/pages/circles/CircleDetailPage.js.map +1 -1
- package/dist/comradecircle/pages/circles/CirclesPage.d.ts.map +1 -1
- package/dist/comradecircle/pages/circles/CirclesPage.js +124 -117
- package/dist/comradecircle/pages/circles/CirclesPage.js.map +1 -1
- package/dist/comradecircle/pages/events/EventDetailPage.d.ts.map +1 -1
- package/dist/comradecircle/pages/events/EventDetailPage.js +182 -153
- package/dist/comradecircle/pages/events/EventDetailPage.js.map +1 -1
- package/dist/comradecircle/pages/events/EventsPage.d.ts.map +1 -1
- package/dist/comradecircle/pages/events/EventsPage.js +100 -91
- package/dist/comradecircle/pages/events/EventsPage.js.map +1 -1
- package/dist/comradecircle/pages/members/MemberProfilePage.d.ts.map +1 -1
- package/dist/comradecircle/pages/members/MemberProfilePage.js +172 -159
- package/dist/comradecircle/pages/members/MemberProfilePage.js.map +1 -1
- package/dist/comradecircle/pages/members/MembersPage.d.ts.map +1 -1
- package/dist/comradecircle/pages/members/MembersPage.js +103 -104
- package/dist/comradecircle/pages/members/MembersPage.js.map +1 -1
- package/dist/comradecircle/pages/monetization/MonetizationPage.d.ts.map +1 -1
- package/dist/comradecircle/pages/monetization/MonetizationPage.js +319 -297
- package/dist/comradecircle/pages/monetization/MonetizationPage.js.map +1 -1
- package/dist/comradecircle/pages/posts/PostThreadPage.d.ts.map +1 -1
- package/dist/comradecircle/pages/posts/PostThreadPage.js +37 -32
- package/dist/comradecircle/pages/posts/PostThreadPage.js.map +1 -1
- package/dist/comradecircle/pages/profile/MyProfilePage.d.ts.map +1 -1
- package/dist/comradecircle/pages/profile/MyProfilePage.js +182 -177
- package/dist/comradecircle/pages/profile/MyProfilePage.js.map +1 -1
- package/dist/comradecircle/utils/i18n.js +15 -0
- package/dist/comradecircle/utils/i18n.js.map +1 -0
- package/dist/comradecircle/utils/pageContext.d.ts.map +1 -1
- package/dist/comradecircle/utils/pageContext.js +3 -1
- package/dist/comradecircle/utils/pageContext.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MemberProfilePage.js","names":[],"sources":["../../../../src/comradecircle/pages/members/MemberProfilePage.tsx"],"sourcesContent":["/**\n * MemberProfilePage — a single member's public social profile.\n * @module comradecircle/pages/members\n *\n * Reads `comProfile(memberId)` (the social-identity layer). The visitor can\n * follow / unfollow the member (state derived from `comMyFollows('MEMBER')`);\n * on their own profile the action becomes an \"Edit profile\" shortcut. Interests\n * and skills render as differentiated chips (accent-tinted vs. outlined) and\n * hide when empty. The identity card gets a social-hero treatment: a living\n * gloss/aurora cover strip with the avatar overlapping upward onto it.\n */\n\nimport {\n ArrowLeft,\n Coins,\n Gift,\n Package,\n Ticket,\n UserX,\n UserMinus,\n UserPlus,\n UserCheck,\n Pencil,\n} from 'lucide-react';\nimport { Button, GlassCard, GradientText, AuroraBackground, Skeleton } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { Avatar } from '../../components/Avatar';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { EmptyState } from '../../components/EmptyState';\nimport { ErrorView } from '../../components/StateViews';\nimport {\n useComProfile,\n useComMyFollows,\n useComFollow,\n useComUnfollow,\n useComListMembershipTiers,\n useComListPaidEvents,\n useComListDigitalProducts,\n} from '../../hooks';\nimport { useComradeCircle } from '../../context';\nimport { notify, describeError } from '../../lib/toast';\nimport { cn } from '../../utils/cn';\nimport { useParams } from 'react-router';\n\nfunction formatMoney(amount: number, currency: string): string {\n try {\n return new Intl.NumberFormat(undefined, { style: 'currency', currency }).format(amount);\n } catch {\n return `${currency} ${amount.toFixed(2)}`;\n }\n}\n\n/**\n * Fan-facing \"Support this creator\" panel — browses the creator's PUBLISHED\n * membership tiers / paid events / digital products (BOFF-4454 bounded\n * monetization CATALOG core). Every purchase CTA is disabled with a\n * \"Payment integration pending\" label: this ticket ships pricing/catalog\n * only, never a live checkout.\n */\nfunction SupportCreatorSection({ creatorId }: { creatorId: string }) {\n const tiers = useComListMembershipTiers(creatorId);\n const events = useComListPaidEvents(creatorId);\n const products = useComListDigitalProducts(creatorId);\n\n const tierItems = tiers.data?.items ?? [];\n const eventItems = events.data?.items ?? [];\n const productItems = products.data?.items ?? [];\n const isLoading = tiers.isLoading || events.isLoading || products.isLoading;\n const hasAnything = tierItems.length > 0 || eventItems.length > 0 || productItems.length > 0;\n\n if (isLoading || !hasAnything) return null;\n\n return (\n <GlassCard treatment=\"plain\" className=\"flex flex-col gap-5 p-5 sm:p-6\">\n <div className=\"flex items-center gap-2\">\n <Coins className=\"h-4 w-4 text-accent\" />\n <h3 className=\"text-base font-semibold text-text-primary\">Support this creator</h3>\n </div>\n <div className=\"flex items-start gap-2 rounded-lg border border-status-warning-border bg-status-warning-bg-subtle px-3 py-2 text-xs text-status-warning-text\">\n <Gift className=\"mt-0.5 h-3.5 w-3.5 shrink-0\" />\n Payment integration pending — these are catalog listings, not a live checkout yet.\n </div>\n\n {tierItems.length > 0 && (\n <div className=\"grid gap-2\">\n <p className=\"text-xs font-medium text-text-tertiary\">Membership tiers</p>\n {tierItems.map((tier) => (\n <div\n key={tier.id}\n className=\"flex items-center justify-between gap-3 rounded-lg border border-border-seam bg-bg-surface p-3\"\n >\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{tier.name}</p>\n {tier.description && (\n <p className=\"truncate text-xs text-text-secondary\">{tier.description}</p>\n )}\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n <span className=\"text-sm font-semibold tabular-nums text-text-primary\">\n {formatMoney(tier.priceAmount, tier.currency)}/\n {tier.billingInterval === 'YEARLY' ? 'yr' : 'mo'}\n </span>\n <Button size=\"sm\" disabled title=\"Payment integration pending\">\n Support\n </Button>\n </div>\n </div>\n ))}\n </div>\n )}\n\n {eventItems.length > 0 && (\n <div className=\"grid gap-2\">\n <p className=\"text-xs font-medium text-text-tertiary\">Paid events</p>\n {eventItems.map((event) => (\n <div\n key={event.id}\n className=\"flex items-center justify-between gap-3 rounded-lg border border-border-seam bg-bg-surface p-3\"\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n <Ticket className=\"h-4 w-4 shrink-0 text-text-tertiary\" />\n <p className=\"truncate text-sm font-medium text-text-primary\">{event.title}</p>\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n <span className=\"text-sm font-semibold tabular-nums text-text-primary\">\n {formatMoney(event.priceAmount, event.currency)}\n </span>\n <Button size=\"sm\" disabled title=\"Payment integration pending\">\n Get ticket\n </Button>\n </div>\n </div>\n ))}\n </div>\n )}\n\n {productItems.length > 0 && (\n <div className=\"grid gap-2\">\n <p className=\"text-xs font-medium text-text-tertiary\">Digital products</p>\n {productItems.map((product) => (\n <div\n key={product.id}\n className=\"flex items-center justify-between gap-3 rounded-lg border border-border-seam bg-bg-surface p-3\"\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n <Package className=\"h-4 w-4 shrink-0 text-text-tertiary\" />\n <p className=\"truncate text-sm font-medium text-text-primary\">{product.title}</p>\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n <span className=\"text-sm font-semibold tabular-nums text-text-primary\">\n {formatMoney(product.priceAmount, product.currency)}\n </span>\n <Button size=\"sm\" disabled title=\"Payment integration pending\">\n Buy\n </Button>\n </div>\n </div>\n ))}\n </div>\n )}\n </GlassCard>\n );\n}\n\n/**\n * A wrap of tag chips. `interest` chips read as accent-tinted affinities;\n * `skill` chips read as outlined competencies — a quiet visual grammar that\n * lets the two sets be told apart at a glance. Hover gives a tasteful lift.\n */\nfunction ChipList({ items, variant }: { items: string[]; variant: 'interest' | 'skill' }) {\n return (\n <ul className=\"flex flex-wrap gap-2\">\n {items.map((item) => (\n <li\n key={item}\n className={cn(\n 'rounded-full px-3 py-1 text-xs font-medium motion-safe:transition-transform motion-safe:duration-150 motion-safe:hover:-translate-y-0.5',\n variant === 'interest'\n ? 'bg-[var(--color-accent-soft)] text-accent'\n : 'border border-border-seam text-text-primary hover:border-border-strong'\n )}\n >\n {item}\n </li>\n ))}\n </ul>\n );\n}\n\n/** Profile-shaped skeleton — mirrors the hero cover strip, overlapping avatar,\n * identity block and the two chip sections so the layout doesn't jump. */\nfunction ProfileSkeleton() {\n return (\n <div className=\"mx-auto flex max-w-2xl flex-col gap-6\">\n <GlassCard treatment=\"plain\" className=\"overflow-hidden p-0\">\n <Skeleton className=\"h-24 w-full rounded-none sm:h-28\" />\n <div className=\"px-5 pb-5 sm:px-6 sm:pb-6\">\n <div className=\"flex flex-col items-center gap-4 sm:flex-row sm:items-end\">\n <Skeleton className=\"-mt-16 h-28 w-28 rounded-full sm:-mt-20\" />\n <div className=\"w-full space-y-2 pb-1 text-center sm:text-left\">\n <Skeleton className=\"mx-auto h-7 w-44 sm:mx-0\" />\n <Skeleton className=\"mx-auto h-4 w-56 sm:mx-0\" />\n <Skeleton className=\"mx-auto h-5 w-20 rounded-full sm:mx-0\" />\n </div>\n </div>\n <div className=\"mt-5 space-y-2\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-3/4\" />\n </div>\n </div>\n </GlassCard>\n <GlassCard treatment=\"plain\" className=\"flex flex-col gap-6 p-5 sm:p-6\">\n {[0, 1].map((s) => (\n <div key={s} className=\"space-y-3\">\n <Skeleton className=\"h-4 w-24\" />\n <div className=\"flex flex-wrap gap-2\">\n {[0, 1, 2, 3].map((c) => (\n <Skeleton key={c} className=\"h-6 w-20 rounded-full\" />\n ))}\n </div>\n </div>\n ))}\n </GlassCard>\n </div>\n );\n}\n\nexport function MemberProfilePage() {\n const { memberId } = useParams<{ memberId: string }>();\n const { navigateTo, currentUser } = useComradeCircle();\n const { data: profile, isLoading, isError, refetch } = useComProfile(memberId);\n\n const follows = useComMyFollows('MEMBER');\n const follow = useComFollow();\n const unfollow = useComUnfollow();\n\n const back = (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => navigateTo('members')}>\n <ArrowLeft className=\"mr-1.5 h-4 w-4\" /> Back\n </Button>\n );\n\n if (isLoading) {\n return (\n <PageLayout title=\"Profile\" actions={back}>\n <ProfileSkeleton />\n </PageLayout>\n );\n }\n\n if (isError) {\n return (\n <PageLayout title=\"Profile\" actions={back}>\n <ErrorView message=\"We couldn't load this member's profile.\" onRetry={() => refetch()} />\n </PageLayout>\n );\n }\n\n if (!profile) {\n return (\n <PageLayout title=\"Profile\" actions={back}>\n <EmptyState\n icon={<UserX className=\"h-10 w-10\" />}\n title=\"No profile\"\n description=\"This member hasn't set up a ComradeCircle profile yet.\"\n />\n </PageLayout>\n );\n }\n\n const isSelf = Boolean(memberId && currentUser?.id === memberId);\n const isFollowing = (follows.data ?? []).some(\n (f) => f.targetId === memberId && f.targetType === 'MEMBER'\n );\n const followPending = follow.isPending || unfollow.isPending;\n\n const toggleFollow = async () => {\n if (!memberId) return;\n try {\n if (isFollowing) {\n await unfollow.mutateAsync({ targetId: memberId, targetType: 'MEMBER' });\n notify.success('Unfollowed', profile.displayName);\n } else {\n await follow.mutateAsync({ targetId: memberId, targetType: 'MEMBER' });\n notify.success('Following', profile.displayName);\n }\n } catch (err) {\n notify.error('Could not update follow', describeError(err));\n }\n };\n\n const action = isSelf ? (\n <Button variant=\"outline\" onClick={() => navigateTo('profile')}>\n <Pencil className=\"mr-1.5 h-4 w-4\" /> Edit profile\n </Button>\n ) : isFollowing ? (\n <Button\n variant=\"outline\"\n onClick={toggleFollow}\n disabled={followPending}\n aria-label={`Following ${profile.displayName}. Activate to unfollow.`}\n className=\"group/follow min-w-[8rem] justify-center motion-safe:transition-colors hover:border-status-error-border hover:bg-status-error-subtle hover:text-status-error-text\"\n >\n <UserCheck className=\"mr-1.5 h-4 w-4 group-hover/follow:hidden\" />\n <UserMinus className=\"mr-1.5 hidden h-4 w-4 group-hover/follow:inline\" />\n <span className=\"group-hover/follow:hidden\">Following</span>\n <span className=\"hidden group-hover/follow:inline\">Unfollow</span>\n </Button>\n ) : (\n <Button onClick={toggleFollow} disabled={followPending}>\n <UserPlus className=\"mr-1.5 h-4 w-4\" /> Follow\n </Button>\n );\n\n const hasTags = profile.interests.length > 0 || profile.skills.length > 0;\n\n return (\n <PageLayout title=\"Profile\" actions={back}>\n <div className=\"mx-auto flex max-w-2xl flex-col gap-6\">\n {/* Identity hero */}\n <GlassCard treatment=\"plain\" className=\"overflow-hidden p-0\">\n {/* Living cover strip — gloss + drifting aurora, reduced-motion safe */}\n <div className=\"relative h-24 overflow-hidden bg-gloss-card sm:h-28\">\n <AuroraBackground intensity=\"subtle\" />\n </div>\n\n <div className=\"px-5 pb-5 sm:px-6 sm:pb-6\">\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between\">\n <div className=\"flex flex-col items-center gap-4 sm:flex-row sm:items-end\">\n <Avatar\n name={profile.displayName}\n presence={profile.presence}\n size=\"2xl\"\n seed={profile.memberId}\n fileId={profile.avatar?.id}\n ring\n className=\"-mt-16 sm:-mt-20\"\n />\n <div className=\"min-w-0 pb-1 text-center sm:text-left\">\n <GradientText as=\"h2\" className=\"text-2xl font-semibold sm:text-[1.75rem]\">\n {profile.displayName}\n </GradientText>\n {profile.headline && (\n <p className=\"mt-1 text-sm text-text-secondary\">{profile.headline}</p>\n )}\n <div className=\"mt-3 flex justify-center sm:justify-start\">\n <StatusBadge status={profile.presence} />\n </div>\n </div>\n </div>\n <div className=\"flex shrink-0 justify-center pb-1 sm:justify-end\">{action}</div>\n </div>\n\n {profile.bio && (\n <p className=\"mt-5 whitespace-pre-wrap text-sm leading-relaxed text-text-secondary\">\n {profile.bio}\n </p>\n )}\n </div>\n </GlassCard>\n\n {/* Interests & skills — differentiated chip grammar */}\n {hasTags && (\n <GlassCard treatment=\"plain\" className=\"flex flex-col gap-6 p-5 sm:p-6\">\n {profile.interests.length > 0 && (\n <div>\n <h3 className=\"mb-3 text-base font-semibold text-text-primary\">Interests</h3>\n <ChipList items={profile.interests} variant=\"interest\" />\n </div>\n )}\n {profile.skills.length > 0 && (\n <div>\n <h3 className=\"mb-3 text-base font-semibold text-text-primary\">Skills</h3>\n <ChipList items={profile.skills} variant=\"skill\" />\n </div>\n )}\n </GlassCard>\n )}\n\n {/* Creator monetization catalog — browse-only, payment pending (BOFF-4454) */}\n {memberId && <SupportCreatorSection creatorId={memberId} />}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MemberProfilePage.js","names":[],"sources":["../../../../src/comradecircle/pages/members/MemberProfilePage.tsx"],"sourcesContent":["/**\n * MemberProfilePage — a single member's public social profile.\n * @module comradecircle/pages/members\n *\n * Reads `comProfile(memberId)` (the social-identity layer). The visitor can\n * follow / unfollow the member (state derived from `comMyFollows('MEMBER')`);\n * on their own profile the action becomes an \"Edit profile\" shortcut. Interests\n * and skills render as differentiated chips (accent-tinted vs. outlined) and\n * hide when empty. The identity card gets a social-hero treatment: a living\n * gloss/aurora cover strip with the avatar overlapping upward onto it.\n */\n\nimport {\n ArrowLeft,\n Coins,\n Gift,\n Package,\n Ticket,\n UserX,\n UserMinus,\n UserPlus,\n UserCheck,\n Pencil,\n} from 'lucide-react';\nimport { Button, GlassCard, GradientText, AuroraBackground, Skeleton } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { Avatar } from '../../components/Avatar';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { EmptyState } from '../../components/EmptyState';\nimport { ErrorView } from '../../components/StateViews';\nimport {\n useComProfile,\n useComMyFollows,\n useComFollow,\n useComUnfollow,\n useComListMembershipTiers,\n useComListPaidEvents,\n useComListDigitalProducts,\n useTr,\n} from '../../hooks';\nimport { useComradeCircle } from '../../context';\nimport { notify, describeError } from '../../lib/toast';\nimport { cn } from '../../utils/cn';\nimport { useParams } from 'react-router';\n\nfunction formatMoney(amount: number, currency: string): string {\n try {\n return new Intl.NumberFormat(undefined, { style: 'currency', currency }).format(amount);\n } catch {\n return `${currency} ${amount.toFixed(2)}`;\n }\n}\n\n/**\n * Fan-facing \"Support this creator\" panel — browses the creator's PUBLISHED\n * membership tiers / paid events / digital products (BOFF-4454 bounded\n * monetization CATALOG core). Every purchase CTA is disabled with a\n * \"Payment integration pending\" label: this ticket ships pricing/catalog\n * only, never a live checkout.\n */\nfunction SupportCreatorSection({ creatorId }: { creatorId: string }) {\n const tr = useTr();\n const tiers = useComListMembershipTiers(creatorId);\n const events = useComListPaidEvents(creatorId);\n const products = useComListDigitalProducts(creatorId);\n\n const tierItems = tiers.data?.items ?? [];\n const eventItems = events.data?.items ?? [];\n const productItems = products.data?.items ?? [];\n const isLoading = tiers.isLoading || events.isLoading || products.isLoading;\n const hasAnything = tierItems.length > 0 || eventItems.length > 0 || productItems.length > 0;\n\n if (isLoading || !hasAnything) return null;\n\n return (\n <GlassCard treatment=\"plain\" className=\"flex flex-col gap-5 p-5 sm:p-6\">\n <div className=\"flex items-center gap-2\">\n <Coins className=\"h-4 w-4 text-accent\" />\n <h3 className=\"text-base font-semibold text-text-primary\">\n {tr('comradecircle.pages.memberProfile.supportCreator', 'Support this creator')}\n </h3>\n </div>\n <div className=\"flex items-start gap-2 rounded-lg border border-status-warning-border bg-status-warning-bg-subtle px-3 py-2 text-xs text-status-warning-text\">\n <Gift className=\"mt-0.5 h-3.5 w-3.5 shrink-0\" />\n {tr(\n 'comradecircle.pages.memberProfile.paymentPending',\n 'Payment integration pending — these are catalog listings, not a live checkout yet.'\n )}\n </div>\n\n {tierItems.length > 0 && (\n <div className=\"grid gap-2\">\n <p className=\"text-xs font-medium text-text-tertiary\">\n {tr('comradecircle.pages.memberProfile.membershipTiers', 'Membership tiers')}\n </p>\n {tierItems.map((tier) => (\n <div\n key={tier.id}\n className=\"flex items-center justify-between gap-3 rounded-lg border border-border-seam bg-bg-surface p-3\"\n >\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{tier.name}</p>\n {tier.description && (\n <p className=\"truncate text-xs text-text-secondary\">{tier.description}</p>\n )}\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n <span className=\"text-sm font-semibold tabular-nums text-text-primary\">\n {formatMoney(tier.priceAmount, tier.currency)}/\n {tier.billingInterval === 'YEARLY' ? 'yr' : 'mo'}\n </span>\n <Button\n size=\"sm\"\n disabled\n title={tr(\n 'comradecircle.pages.memberProfile.paymentPending',\n 'Payment integration pending'\n )}\n >\n {tr('comradecircle.pages.memberProfile.support', 'Support')}\n </Button>\n </div>\n </div>\n ))}\n </div>\n )}\n\n {eventItems.length > 0 && (\n <div className=\"grid gap-2\">\n <p className=\"text-xs font-medium text-text-tertiary\">\n {tr('comradecircle.pages.memberProfile.paidEvents', 'Paid events')}\n </p>\n {eventItems.map((event) => (\n <div\n key={event.id}\n className=\"flex items-center justify-between gap-3 rounded-lg border border-border-seam bg-bg-surface p-3\"\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n <Ticket className=\"h-4 w-4 shrink-0 text-text-tertiary\" />\n <p className=\"truncate text-sm font-medium text-text-primary\">{event.title}</p>\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n <span className=\"text-sm font-semibold tabular-nums text-text-primary\">\n {formatMoney(event.priceAmount, event.currency)}\n </span>\n <Button\n size=\"sm\"\n disabled\n title={tr(\n 'comradecircle.pages.memberProfile.paymentPending',\n 'Payment integration pending'\n )}\n >\n {tr('comradecircle.pages.memberProfile.getTicket', 'Get ticket')}\n </Button>\n </div>\n </div>\n ))}\n </div>\n )}\n\n {productItems.length > 0 && (\n <div className=\"grid gap-2\">\n <p className=\"text-xs font-medium text-text-tertiary\">\n {tr('comradecircle.pages.memberProfile.digitalProducts', 'Digital products')}\n </p>\n {productItems.map((product) => (\n <div\n key={product.id}\n className=\"flex items-center justify-between gap-3 rounded-lg border border-border-seam bg-bg-surface p-3\"\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n <Package className=\"h-4 w-4 shrink-0 text-text-tertiary\" />\n <p className=\"truncate text-sm font-medium text-text-primary\">{product.title}</p>\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n <span className=\"text-sm font-semibold tabular-nums text-text-primary\">\n {formatMoney(product.priceAmount, product.currency)}\n </span>\n <Button\n size=\"sm\"\n disabled\n title={tr(\n 'comradecircle.pages.memberProfile.paymentPending',\n 'Payment integration pending'\n )}\n >\n {tr('comradecircle.pages.memberProfile.buy', 'Buy')}\n </Button>\n </div>\n </div>\n ))}\n </div>\n )}\n </GlassCard>\n );\n}\n\n/**\n * A wrap of tag chips. `interest` chips read as accent-tinted affinities;\n * `skill` chips read as outlined competencies — a quiet visual grammar that\n * lets the two sets be told apart at a glance. Hover gives a tasteful lift.\n */\nfunction ChipList({ items, variant }: { items: string[]; variant: 'interest' | 'skill' }) {\n return (\n <ul className=\"flex flex-wrap gap-2\">\n {items.map((item) => (\n <li\n key={item}\n className={cn(\n 'rounded-full px-3 py-1 text-xs font-medium motion-safe:transition-transform motion-safe:duration-150 motion-safe:hover:-translate-y-0.5',\n variant === 'interest'\n ? 'bg-[var(--color-accent-soft)] text-accent'\n : 'border border-border-seam text-text-primary hover:border-border-strong'\n )}\n >\n {item}\n </li>\n ))}\n </ul>\n );\n}\n\n/** Profile-shaped skeleton — mirrors the hero cover strip, overlapping avatar,\n * identity block and the two chip sections so the layout doesn't jump. */\nfunction ProfileSkeleton() {\n return (\n <div className=\"mx-auto flex max-w-2xl flex-col gap-6\">\n <GlassCard treatment=\"plain\" className=\"overflow-hidden p-0\">\n <Skeleton className=\"h-24 w-full rounded-none sm:h-28\" />\n <div className=\"px-5 pb-5 sm:px-6 sm:pb-6\">\n <div className=\"flex flex-col items-center gap-4 sm:flex-row sm:items-end\">\n <Skeleton className=\"-mt-16 h-28 w-28 rounded-full sm:-mt-20\" />\n <div className=\"w-full space-y-2 pb-1 text-center sm:text-left\">\n <Skeleton className=\"mx-auto h-7 w-44 sm:mx-0\" />\n <Skeleton className=\"mx-auto h-4 w-56 sm:mx-0\" />\n <Skeleton className=\"mx-auto h-5 w-20 rounded-full sm:mx-0\" />\n </div>\n </div>\n <div className=\"mt-5 space-y-2\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-3/4\" />\n </div>\n </div>\n </GlassCard>\n <GlassCard treatment=\"plain\" className=\"flex flex-col gap-6 p-5 sm:p-6\">\n {[0, 1].map((s) => (\n <div key={s} className=\"space-y-3\">\n <Skeleton className=\"h-4 w-24\" />\n <div className=\"flex flex-wrap gap-2\">\n {[0, 1, 2, 3].map((c) => (\n <Skeleton key={c} className=\"h-6 w-20 rounded-full\" />\n ))}\n </div>\n </div>\n ))}\n </GlassCard>\n </div>\n );\n}\n\nexport function MemberProfilePage() {\n const tr = useTr();\n const { memberId } = useParams<{ memberId: string }>();\n const { navigateTo, currentUser } = useComradeCircle();\n const { data: profile, isLoading, isError, refetch } = useComProfile(memberId);\n\n const follows = useComMyFollows('MEMBER');\n const follow = useComFollow();\n const unfollow = useComUnfollow();\n\n const back = (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => navigateTo('members')}>\n <ArrowLeft className=\"mr-1.5 h-4 w-4\" /> {tr('common.back', 'Back')}\n </Button>\n );\n\n if (isLoading) {\n return (\n <PageLayout title={tr('comradecircle.pages.memberProfile.title', 'Profile')} actions={back}>\n <ProfileSkeleton />\n </PageLayout>\n );\n }\n\n if (isError) {\n return (\n <PageLayout title={tr('comradecircle.pages.memberProfile.title', 'Profile')} actions={back}>\n <ErrorView\n message={tr(\n 'comradecircle.pages.memberProfile.errorMessage',\n \"We couldn't load this member's profile.\"\n )}\n onRetry={() => refetch()}\n />\n </PageLayout>\n );\n }\n\n if (!profile) {\n return (\n <PageLayout title={tr('comradecircle.pages.memberProfile.title', 'Profile')} actions={back}>\n <EmptyState\n icon={<UserX className=\"h-10 w-10\" />}\n title={tr('comradecircle.pages.memberProfile.noProfileTitle', 'No profile')}\n description={tr(\n 'comradecircle.pages.memberProfile.noProfileDescription',\n \"This member hasn't set up a ComradeCircle profile yet.\"\n )}\n />\n </PageLayout>\n );\n }\n\n const isSelf = Boolean(memberId && currentUser?.id === memberId);\n const isFollowing = (follows.data ?? []).some(\n (f) => f.targetId === memberId && f.targetType === 'MEMBER'\n );\n const followPending = follow.isPending || unfollow.isPending;\n\n const toggleFollow = async () => {\n if (!memberId) return;\n try {\n if (isFollowing) {\n await unfollow.mutateAsync({ targetId: memberId, targetType: 'MEMBER' });\n notify.success(\n tr('comradecircle.pages.memberProfile.unfollowed', 'Unfollowed'),\n profile.displayName\n );\n } else {\n await follow.mutateAsync({ targetId: memberId, targetType: 'MEMBER' });\n notify.success(\n tr('comradecircle.pages.memberProfile.following', 'Following'),\n profile.displayName\n );\n }\n } catch (err) {\n notify.error(\n tr('comradecircle.pages.memberProfile.followError', 'Could not update follow'),\n describeError(err)\n );\n }\n };\n\n const action = isSelf ? (\n <Button variant=\"outline\" onClick={() => navigateTo('profile')}>\n <Pencil className=\"mr-1.5 h-4 w-4\" />{' '}\n {tr('comradecircle.pages.memberProfile.editProfile', 'Edit profile')}\n </Button>\n ) : isFollowing ? (\n <Button\n variant=\"outline\"\n onClick={toggleFollow}\n disabled={followPending}\n aria-label={tr(\n 'comradecircle.pages.memberProfile.followingAriaLabel',\n 'Following {{name}}. Activate to unfollow.',\n { name: profile.displayName }\n )}\n className=\"group/follow min-w-[8rem] justify-center motion-safe:transition-colors hover:border-status-error-border hover:bg-status-error-subtle hover:text-status-error-text\"\n >\n <UserCheck className=\"mr-1.5 h-4 w-4 group-hover/follow:hidden\" />\n <UserMinus className=\"mr-1.5 hidden h-4 w-4 group-hover/follow:inline\" />\n <span className=\"group-hover/follow:hidden\">\n {tr('comradecircle.pages.memberProfile.following', 'Following')}\n </span>\n <span className=\"hidden group-hover/follow:inline\">\n {tr('comradecircle.pages.memberProfile.unfollow', 'Unfollow')}\n </span>\n </Button>\n ) : (\n <Button onClick={toggleFollow} disabled={followPending}>\n <UserPlus className=\"mr-1.5 h-4 w-4\" />{' '}\n {tr('comradecircle.pages.memberProfile.follow', 'Follow')}\n </Button>\n );\n\n const hasTags = profile.interests.length > 0 || profile.skills.length > 0;\n\n return (\n <PageLayout title={tr('comradecircle.pages.memberProfile.title', 'Profile')} actions={back}>\n <div className=\"mx-auto flex max-w-2xl flex-col gap-6\">\n {/* Identity hero */}\n <GlassCard treatment=\"plain\" className=\"overflow-hidden p-0\">\n {/* Living cover strip — gloss + drifting aurora, reduced-motion safe */}\n <div className=\"relative h-24 overflow-hidden bg-gloss-card sm:h-28\">\n <AuroraBackground intensity=\"subtle\" />\n </div>\n\n <div className=\"px-5 pb-5 sm:px-6 sm:pb-6\">\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between\">\n <div className=\"flex flex-col items-center gap-4 sm:flex-row sm:items-end\">\n <Avatar\n name={profile.displayName}\n presence={profile.presence}\n size=\"2xl\"\n seed={profile.memberId}\n fileId={profile.avatar?.id}\n ring\n className=\"-mt-16 sm:-mt-20\"\n />\n <div className=\"min-w-0 pb-1 text-center sm:text-left\">\n <GradientText as=\"h2\" className=\"text-2xl font-semibold sm:text-[1.75rem]\">\n {profile.displayName}\n </GradientText>\n {profile.headline && (\n <p className=\"mt-1 text-sm text-text-secondary\">{profile.headline}</p>\n )}\n <div className=\"mt-3 flex justify-center sm:justify-start\">\n <StatusBadge status={profile.presence} />\n </div>\n </div>\n </div>\n <div className=\"flex shrink-0 justify-center pb-1 sm:justify-end\">{action}</div>\n </div>\n\n {profile.bio && (\n <p className=\"mt-5 whitespace-pre-wrap text-sm leading-relaxed text-text-secondary\">\n {profile.bio}\n </p>\n )}\n </div>\n </GlassCard>\n\n {/* Interests & skills — differentiated chip grammar */}\n {hasTags && (\n <GlassCard treatment=\"plain\" className=\"flex flex-col gap-6 p-5 sm:p-6\">\n {profile.interests.length > 0 && (\n <div>\n <h3 className=\"mb-3 text-base font-semibold text-text-primary\">\n {tr('comradecircle.pages.memberProfile.interests', 'Interests')}\n </h3>\n <ChipList items={profile.interests} variant=\"interest\" />\n </div>\n )}\n {profile.skills.length > 0 && (\n <div>\n <h3 className=\"mb-3 text-base font-semibold text-text-primary\">\n {tr('comradecircle.pages.memberProfile.skills', 'Skills')}\n </h3>\n <ChipList items={profile.skills} variant=\"skill\" />\n </div>\n )}\n </GlassCard>\n )}\n\n {/* Creator monetization catalog — browse-only, payment pending (BOFF-4454) */}\n {memberId && <SupportCreatorSection creatorId={memberId} />}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MembersPage.d.ts","sourceRoot":"","sources":["../../../../src/comradecircle/pages/members/MembersPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"MembersPage.d.ts","sourceRoot":"","sources":["../../../../src/comradecircle/pages/members/MembersPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAiDH,wBAAgB,WAAW,4CA2Q1B"}
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import { useComradeCircle as e } from "../../context/ComradeCircleContext.js";
|
|
2
2
|
import "../../context/index.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { useComFollow as t, useComMyFollows as n, useComProfiles as r, useComUnfollow as i } from "../../hooks/useComradeCircleApi.js";
|
|
4
|
+
import { useCursorPager as a } from "../../hooks/useCursorPager.js";
|
|
5
|
+
import { useTr as o } from "../../hooks/useTr.js";
|
|
6
6
|
import "../../hooks/index.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
7
|
+
import { PageLayout as s } from "../../components/PageLayout.js";
|
|
8
|
+
import { Avatar as c } from "../../components/Avatar.js";
|
|
9
|
+
import { describeError as l, notify as u } from "../../lib/toast.js";
|
|
10
|
+
import { EmptyState as d } from "../../components/EmptyState.js";
|
|
11
|
+
import { ErrorView as f } from "../../components/StateViews.js";
|
|
12
|
+
import { Pagination as p } from "../../components/Pagination.js";
|
|
13
|
+
import { useMemo as m, useState as h } from "react";
|
|
14
|
+
import { Check as g, Loader2 as _, Search as v, UserMinus as y, UserPlus as b } from "lucide-react";
|
|
15
|
+
import { Fragment as x, jsx as S, jsxs as C } from "react/jsx-runtime";
|
|
16
|
+
import { Button as w, GlassCard as T, Input as E, Skeleton as D } from "@burdenoff/fe-libs/ui";
|
|
16
17
|
//#region src/comradecircle/pages/members/MembersPage.tsx
|
|
17
|
-
var
|
|
18
|
+
var O = 12, k = [
|
|
18
19
|
"s1",
|
|
19
20
|
"s2",
|
|
20
21
|
"s3",
|
|
@@ -24,199 +25,197 @@ var D = 12, O = [
|
|
|
24
25
|
"s7",
|
|
25
26
|
"s8"
|
|
26
27
|
];
|
|
27
|
-
function
|
|
28
|
-
return /* @__PURE__ */
|
|
28
|
+
function A() {
|
|
29
|
+
return /* @__PURE__ */ C(T, {
|
|
29
30
|
treatment: "plain",
|
|
30
31
|
className: "flex flex-col p-5",
|
|
31
32
|
children: [
|
|
32
|
-
/* @__PURE__ */
|
|
33
|
+
/* @__PURE__ */ C("div", {
|
|
33
34
|
className: "flex items-start gap-3",
|
|
34
|
-
children: [/* @__PURE__ */
|
|
35
|
+
children: [/* @__PURE__ */ S(D, { className: "h-14 w-14 rounded-full" }), /* @__PURE__ */ C("div", {
|
|
35
36
|
className: "min-w-0 flex-1 space-y-2 py-1",
|
|
36
37
|
children: [
|
|
37
|
-
/* @__PURE__ */
|
|
38
|
-
/* @__PURE__ */
|
|
39
|
-
/* @__PURE__ */
|
|
38
|
+
/* @__PURE__ */ S(D, { className: "h-4 w-2/3" }),
|
|
39
|
+
/* @__PURE__ */ S(D, { className: "h-3 w-1/2" }),
|
|
40
|
+
/* @__PURE__ */ S(D, { className: "h-3 w-4/5" })
|
|
40
41
|
]
|
|
41
42
|
})]
|
|
42
43
|
}),
|
|
43
|
-
/* @__PURE__ */
|
|
44
|
+
/* @__PURE__ */ C("div", {
|
|
44
45
|
className: "mt-3 flex flex-wrap gap-1.5",
|
|
45
|
-
children: [/* @__PURE__ */
|
|
46
|
+
children: [/* @__PURE__ */ S(D, { className: "h-5 w-16 rounded-full" }), /* @__PURE__ */ S(D, { className: "h-5 w-20 rounded-full" })]
|
|
46
47
|
}),
|
|
47
|
-
/* @__PURE__ */
|
|
48
|
+
/* @__PURE__ */ S("div", {
|
|
48
49
|
className: "mt-4 flex justify-end border-t border-border-seam pt-3",
|
|
49
|
-
children: /* @__PURE__ */
|
|
50
|
+
children: /* @__PURE__ */ S(D, { className: "h-8 w-28 rounded-button" })
|
|
50
51
|
})
|
|
51
52
|
]
|
|
52
53
|
});
|
|
53
54
|
}
|
|
54
|
-
function
|
|
55
|
-
let { navigateTo:
|
|
55
|
+
function j() {
|
|
56
|
+
let j = o(), { navigateTo: M, currentUser: N } = e(), P = a(), [F, I] = h(""), [L, R] = h(null), { data: z, isLoading: B, isError: V, refetch: H } = r({
|
|
56
57
|
discoverable: !0,
|
|
57
58
|
pagination: {
|
|
58
|
-
limit:
|
|
59
|
-
cursor:
|
|
59
|
+
limit: O,
|
|
60
|
+
cursor: P.cursor
|
|
60
61
|
}
|
|
61
|
-
}), { data:
|
|
62
|
-
let e =
|
|
63
|
-
return e ?
|
|
62
|
+
}), { data: U } = n("MEMBER"), W = t(), G = i(), K = m(() => new Set((U ?? []).map((e) => e.targetId)), [U]), q = m(() => z?.items ?? [], [z]), J = m(() => {
|
|
63
|
+
let e = F.trim().toLowerCase();
|
|
64
|
+
return e ? q.filter((t) => [
|
|
64
65
|
t.displayName,
|
|
65
66
|
t.headline ?? "",
|
|
66
67
|
...t.skills,
|
|
67
68
|
...t.interests
|
|
68
|
-
].join(" ").toLowerCase().includes(e)) :
|
|
69
|
-
}, [
|
|
70
|
-
let t =
|
|
69
|
+
].join(" ").toLowerCase().includes(e)) : q;
|
|
70
|
+
}, [q, F]), Y = async (e) => {
|
|
71
|
+
let t = K.has(e.memberId), n = {
|
|
71
72
|
targetId: e.memberId,
|
|
72
73
|
targetType: "MEMBER"
|
|
73
74
|
};
|
|
74
|
-
|
|
75
|
+
R(e.memberId);
|
|
75
76
|
try {
|
|
76
|
-
t ? (await
|
|
77
|
+
t ? (await G.mutateAsync(n), u.success(j("comradecircle.pages.members.unfollowed", "Unfollowed"), e.displayName)) : (await W.mutateAsync(n), u.success(j("comradecircle.pages.members.following", "Following"), e.displayName));
|
|
77
78
|
} catch (e) {
|
|
78
|
-
|
|
79
|
+
u.error(t ? j("comradecircle.pages.members.unfollowError", "Could not unfollow") : j("comradecircle.pages.members.followError", "Could not follow"), l(e));
|
|
79
80
|
} finally {
|
|
80
|
-
|
|
81
|
+
R(null);
|
|
81
82
|
}
|
|
82
83
|
};
|
|
83
|
-
return /* @__PURE__ */
|
|
84
|
-
title: "Members",
|
|
85
|
-
description: "Discover and follow people across your circles — search by name, headline, or skills.",
|
|
86
|
-
children:
|
|
84
|
+
return /* @__PURE__ */ S(s, {
|
|
85
|
+
title: j("comradecircle.pages.members.title", "Members"),
|
|
86
|
+
description: j("comradecircle.pages.members.description", "Discover and follow people across your circles — search by name, headline, or skills."),
|
|
87
|
+
children: B ? /* @__PURE__ */ C("div", {
|
|
87
88
|
className: "flex flex-col gap-5",
|
|
88
|
-
children: [/* @__PURE__ */
|
|
89
|
+
children: [/* @__PURE__ */ S(D, { className: "h-9 w-full max-w-sm rounded-button" }), /* @__PURE__ */ S("div", {
|
|
89
90
|
className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4",
|
|
90
|
-
children:
|
|
91
|
+
children: k.map((e) => /* @__PURE__ */ S(A, {}, e))
|
|
91
92
|
})]
|
|
92
|
-
}) :
|
|
93
|
-
message: "We couldn't load the member directory.",
|
|
94
|
-
onRetry: () =>
|
|
95
|
-
}) :
|
|
93
|
+
}) : V ? /* @__PURE__ */ S(f, {
|
|
94
|
+
message: j("comradecircle.pages.members.errorMessage", "We couldn't load the member directory."),
|
|
95
|
+
onRetry: () => H()
|
|
96
|
+
}) : q.length === 0 && P.page === 0 ? /* @__PURE__ */ S(d, {
|
|
96
97
|
illustration: "empty-people",
|
|
97
|
-
title: "No members to discover yet",
|
|
98
|
-
description: "When members make their profiles discoverable, they'll show up here for you to follow."
|
|
99
|
-
}) : /* @__PURE__ */
|
|
98
|
+
title: j("comradecircle.pages.members.noMembersTitle", "No members to discover yet"),
|
|
99
|
+
description: j("comradecircle.pages.members.noMembersDescription", "When members make their profiles discoverable, they'll show up here for you to follow.")
|
|
100
|
+
}) : /* @__PURE__ */ C("div", {
|
|
100
101
|
className: "flex flex-col gap-5",
|
|
101
102
|
children: [
|
|
102
|
-
/* @__PURE__ */
|
|
103
|
+
/* @__PURE__ */ C("div", {
|
|
103
104
|
className: "relative w-full max-w-sm",
|
|
104
|
-
children: [/* @__PURE__ */
|
|
105
|
+
children: [/* @__PURE__ */ S(v, {
|
|
105
106
|
className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary",
|
|
106
107
|
"aria-hidden": "true"
|
|
107
|
-
}), /* @__PURE__ */
|
|
108
|
-
value:
|
|
109
|
-
onChange: (e) =>
|
|
110
|
-
placeholder: "Search by name, headline, or skills",
|
|
111
|
-
"aria-label": "Search members",
|
|
108
|
+
}), /* @__PURE__ */ S(E, {
|
|
109
|
+
value: F,
|
|
110
|
+
onChange: (e) => I(e.target.value),
|
|
111
|
+
placeholder: j("comradecircle.pages.members.searchPlaceholder", "Search by name, headline, or skills"),
|
|
112
|
+
"aria-label": j("comradecircle.pages.members.searchAriaLabel", "Search members"),
|
|
112
113
|
className: "pl-9"
|
|
113
114
|
})]
|
|
114
115
|
}),
|
|
115
|
-
|
|
116
|
-
icon: /* @__PURE__ */
|
|
117
|
-
title: "No matches on this page",
|
|
118
|
-
description: "No members on this page match your search. Try a different term or browse another page."
|
|
119
|
-
}) : /* @__PURE__ */
|
|
116
|
+
J.length === 0 ? /* @__PURE__ */ S(d, {
|
|
117
|
+
icon: /* @__PURE__ */ S(v, { className: "h-9 w-9" }),
|
|
118
|
+
title: j("comradecircle.pages.members.noMatchesTitle", "No matches on this page"),
|
|
119
|
+
description: j("comradecircle.pages.members.noMatchesDescription", "No members on this page match your search. Try a different term or browse another page.")
|
|
120
|
+
}) : /* @__PURE__ */ C(x, { children: [/* @__PURE__ */ S("p", {
|
|
120
121
|
className: "text-xs font-medium text-text-tertiary",
|
|
121
|
-
children:
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
]
|
|
127
|
-
}), /* @__PURE__ */ x("div", {
|
|
122
|
+
children: j("comradecircle.pages.members.showingCount", "Showing {{count}} member{{suffix}}", {
|
|
123
|
+
count: J.length,
|
|
124
|
+
suffix: J.length === 1 ? "" : "s"
|
|
125
|
+
})
|
|
126
|
+
}), /* @__PURE__ */ S("div", {
|
|
128
127
|
className: "grid gap-4 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4",
|
|
129
|
-
children:
|
|
130
|
-
let t = !!(
|
|
131
|
-
return /* @__PURE__ */
|
|
128
|
+
children: J.map((e) => {
|
|
129
|
+
let t = !!(N?.id && e.memberId === N.id), n = K.has(e.memberId), r = L === e.memberId, i = Array.from(new Set([...e.skills, ...e.interests])).slice(0, 4);
|
|
130
|
+
return /* @__PURE__ */ C(T, {
|
|
132
131
|
treatment: "plain",
|
|
133
132
|
className: "flex flex-col p-5 transition-all duration-200 motion-safe:hover:-translate-y-0.5 hover:border-[var(--color-accent-soft)]",
|
|
134
133
|
children: [
|
|
135
|
-
/* @__PURE__ */
|
|
134
|
+
/* @__PURE__ */ C("button", {
|
|
136
135
|
type: "button",
|
|
137
|
-
onClick: () =>
|
|
138
|
-
"aria-label":
|
|
136
|
+
onClick: () => M(`members/${e.memberId}`),
|
|
137
|
+
"aria-label": j("comradecircle.pages.members.viewProfileAriaLabel", "View {{name}}'s profile", { name: e.displayName }),
|
|
139
138
|
className: "group/head flex w-full items-start gap-3 rounded-lg text-left outline-none focus-visible:ring-1 focus-visible:ring-[var(--color-focus-ring)]",
|
|
140
|
-
children: [/* @__PURE__ */
|
|
139
|
+
children: [/* @__PURE__ */ S(c, {
|
|
141
140
|
name: e.displayName,
|
|
142
141
|
presence: e.presence,
|
|
143
142
|
size: "lg",
|
|
144
143
|
fileId: e.avatar?.id,
|
|
145
144
|
seed: e.memberId
|
|
146
|
-
}), /* @__PURE__ */
|
|
145
|
+
}), /* @__PURE__ */ C("div", {
|
|
147
146
|
className: "min-w-0 flex-1",
|
|
148
147
|
children: [
|
|
149
|
-
/* @__PURE__ */
|
|
148
|
+
/* @__PURE__ */ S("span", {
|
|
150
149
|
className: "block max-w-full truncate text-base font-semibold text-text-primary group-hover/head:underline",
|
|
151
150
|
children: e.displayName
|
|
152
151
|
}),
|
|
153
|
-
e.headline && /* @__PURE__ */
|
|
152
|
+
e.headline && /* @__PURE__ */ S("p", {
|
|
154
153
|
className: "truncate text-sm text-text-secondary",
|
|
155
154
|
children: e.headline
|
|
156
155
|
}),
|
|
157
|
-
e.bio && /* @__PURE__ */
|
|
156
|
+
e.bio && /* @__PURE__ */ S("p", {
|
|
158
157
|
className: "mt-0.5 line-clamp-1 text-xs text-text-tertiary",
|
|
159
158
|
children: e.bio
|
|
160
159
|
})
|
|
161
160
|
]
|
|
162
161
|
})]
|
|
163
162
|
}),
|
|
164
|
-
i.length > 0 && /* @__PURE__ */
|
|
163
|
+
i.length > 0 && /* @__PURE__ */ S("div", {
|
|
165
164
|
className: "mt-3 flex flex-wrap gap-1.5",
|
|
166
|
-
children: i.map((e) => /* @__PURE__ */
|
|
165
|
+
children: i.map((e) => /* @__PURE__ */ S("span", {
|
|
167
166
|
className: "rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary",
|
|
168
167
|
children: e
|
|
169
168
|
}, e))
|
|
170
169
|
}),
|
|
171
|
-
!t && /* @__PURE__ */
|
|
170
|
+
!t && /* @__PURE__ */ S("div", {
|
|
172
171
|
className: "mt-4 flex items-center justify-end border-t border-border-seam pt-3",
|
|
173
|
-
children: n ? /* @__PURE__ */
|
|
172
|
+
children: n ? /* @__PURE__ */ S(w, {
|
|
174
173
|
size: "sm",
|
|
175
174
|
variant: "outline",
|
|
176
175
|
onClick: (t) => {
|
|
177
|
-
t.stopPropagation(),
|
|
176
|
+
t.stopPropagation(), Y(e);
|
|
178
177
|
},
|
|
179
178
|
disabled: r,
|
|
180
|
-
"aria-label":
|
|
179
|
+
"aria-label": j("comradecircle.pages.members.followingAriaLabel", "Following {{name}}. Activate to unfollow.", { name: e.displayName }),
|
|
181
180
|
className: "group/follow min-w-[7.5rem] justify-center hover:border-status-error-border hover:bg-status-error-bg-subtle hover:text-status-error-text",
|
|
182
|
-
children: r ? /* @__PURE__ */
|
|
183
|
-
/* @__PURE__ */
|
|
184
|
-
/* @__PURE__ */
|
|
185
|
-
/* @__PURE__ */
|
|
181
|
+
children: r ? /* @__PURE__ */ C(x, { children: [/* @__PURE__ */ S(_, { className: "motion-safe:animate-spin" }), /* @__PURE__ */ S("span", { children: j("comradecircle.pages.members.following", "Following") })] }) : /* @__PURE__ */ C(x, { children: [
|
|
182
|
+
/* @__PURE__ */ S(g, { className: "group-hover/follow:hidden" }),
|
|
183
|
+
/* @__PURE__ */ S(y, { className: "hidden group-hover/follow:inline" }),
|
|
184
|
+
/* @__PURE__ */ S("span", {
|
|
186
185
|
className: "group-hover/follow:hidden",
|
|
187
|
-
children: "Following"
|
|
186
|
+
children: j("comradecircle.pages.members.following", "Following")
|
|
188
187
|
}),
|
|
189
|
-
/* @__PURE__ */
|
|
188
|
+
/* @__PURE__ */ S("span", {
|
|
190
189
|
className: "hidden group-hover/follow:inline",
|
|
191
|
-
children: "Unfollow"
|
|
190
|
+
children: j("comradecircle.pages.members.unfollow", "Unfollow")
|
|
192
191
|
})
|
|
193
192
|
] })
|
|
194
|
-
}) : /* @__PURE__ */
|
|
193
|
+
}) : /* @__PURE__ */ C(w, {
|
|
195
194
|
size: "sm",
|
|
196
195
|
onClick: (t) => {
|
|
197
|
-
t.stopPropagation(),
|
|
196
|
+
t.stopPropagation(), Y(e);
|
|
198
197
|
},
|
|
199
198
|
disabled: r,
|
|
200
199
|
className: "min-w-[7.5rem] justify-center",
|
|
201
|
-
children: [r ? /* @__PURE__ */
|
|
200
|
+
children: [r ? /* @__PURE__ */ S(_, { className: "motion-safe:animate-spin" }) : /* @__PURE__ */ S(b, {}), j("comradecircle.pages.members.follow", "Follow")]
|
|
202
201
|
})
|
|
203
202
|
})
|
|
204
203
|
]
|
|
205
204
|
}, e.id);
|
|
206
205
|
})
|
|
207
206
|
})] }),
|
|
208
|
-
/* @__PURE__ */
|
|
209
|
-
page:
|
|
210
|
-
pageSize:
|
|
211
|
-
itemCount:
|
|
212
|
-
hasMore:
|
|
213
|
-
onPageChange: (e) =>
|
|
207
|
+
/* @__PURE__ */ S(p, {
|
|
208
|
+
page: P.page,
|
|
209
|
+
pageSize: O,
|
|
210
|
+
itemCount: q.length,
|
|
211
|
+
hasMore: z?.pageInfo.hasMore ?? !1,
|
|
212
|
+
onPageChange: (e) => P.onPageChange(e, z?.pageInfo.cursor)
|
|
214
213
|
})
|
|
215
214
|
]
|
|
216
215
|
})
|
|
217
216
|
});
|
|
218
217
|
}
|
|
219
218
|
//#endregion
|
|
220
|
-
export {
|
|
219
|
+
export { j as MembersPage };
|
|
221
220
|
|
|
222
221
|
//# sourceMappingURL=MembersPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MembersPage.js","names":[],"sources":["../../../../src/comradecircle/pages/members/MembersPage.tsx"],"sourcesContent":["/**\n * MembersPage — the discoverable member directory.\n * @module comradecircle/pages/members\n *\n * Reads `comListProfiles(discoverable: true)` — every member who has opted into\n * discovery via their {@link ComProfile}. Each card resolves display identity\n * from the social-identity layer (never a raw actor id), links to the member's\n * public profile, and offers a Follow/Following toggle wired to `comFollow` /\n * `comUnfollow` (targetType MEMBER). An optional client-side search narrows the\n * current page by name, headline, skills, or interests.\n */\n\nimport { useMemo, useState } from 'react';\nimport { Search, UserPlus, UserMinus, Check, Loader2 } from 'lucide-react';\nimport { GlassCard, Button, Input, Skeleton } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { Avatar } from '../../components/Avatar';\nimport { EmptyState } from '../../components/EmptyState';\nimport { ErrorView } from '../../components/StateViews';\nimport { Pagination } from '../../components/Pagination';\nimport {\n useComProfiles,\n useComMyFollows,\n useComFollow,\n useComUnfollow,\n useCursorPager,\n} from '../../hooks';\nimport { useComradeCircle } from '../../context';\nimport { notify, describeError } from '../../lib/toast';\nimport type { ComProfile } from '../../types';\n\nconst PAGE_SIZE = 12;\n\nconst SKELETON_KEYS = ['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8'] as const;\n\n/** Card-shaped placeholder that mirrors the member card while the page loads. */\nfunction MemberCardSkeleton() {\n return (\n <GlassCard treatment=\"plain\" className=\"flex flex-col p-5\">\n <div className=\"flex items-start gap-3\">\n <Skeleton className=\"h-14 w-14 rounded-full\" />\n <div className=\"min-w-0 flex-1 space-y-2 py-1\">\n <Skeleton className=\"h-4 w-2/3\" />\n <Skeleton className=\"h-3 w-1/2\" />\n <Skeleton className=\"h-3 w-4/5\" />\n </div>\n </div>\n <div className=\"mt-3 flex flex-wrap gap-1.5\">\n <Skeleton className=\"h-5 w-16 rounded-full\" />\n <Skeleton className=\"h-5 w-20 rounded-full\" />\n </div>\n <div className=\"mt-4 flex justify-end border-t border-border-seam pt-3\">\n <Skeleton className=\"h-8 w-28 rounded-button\" />\n </div>\n </GlassCard>\n );\n}\n\nexport function MembersPage() {\n const { navigateTo, currentUser } = useComradeCircle();\n const pager = useCursorPager();\n const [search, setSearch] = useState('');\n const [pendingId, setPendingId] = useState<string | null>(null);\n\n const { data, isLoading, isError, refetch } = useComProfiles({\n discoverable: true,\n pagination: { limit: PAGE_SIZE, cursor: pager.cursor },\n });\n\n const { data: follows } = useComMyFollows('MEMBER');\n const follow = useComFollow();\n const unfollow = useComUnfollow();\n\n const followSet = useMemo(() => new Set((follows ?? []).map((f) => f.targetId)), [follows]);\n\n const profiles = useMemo(() => data?.items ?? [], [data]);\n\n const visible = useMemo(() => {\n const q = search.trim().toLowerCase();\n if (!q) return profiles;\n return profiles.filter((p) => {\n const haystack = [p.displayName, p.headline ?? '', ...p.skills, ...p.interests]\n .join(' ')\n .toLowerCase();\n return haystack.includes(q);\n });\n }, [profiles, search]);\n\n const toggleFollow = async (profile: ComProfile) => {\n const wasFollowing = followSet.has(profile.memberId);\n const input = { targetId: profile.memberId, targetType: 'MEMBER' as const };\n setPendingId(profile.memberId);\n try {\n if (wasFollowing) {\n await unfollow.mutateAsync(input);\n notify.success('Unfollowed', profile.displayName);\n } else {\n await follow.mutateAsync(input);\n notify.success('Following', profile.displayName);\n }\n } catch (err) {\n notify.error(wasFollowing ? 'Could not unfollow' : 'Could not follow', describeError(err));\n } finally {\n setPendingId(null);\n }\n };\n\n return (\n <PageLayout\n title=\"Members\"\n description=\"Discover and follow people across your circles — search by name, headline, or skills.\"\n >\n {isLoading ? (\n <div className=\"flex flex-col gap-5\">\n <Skeleton className=\"h-9 w-full max-w-sm rounded-button\" />\n <div className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4\">\n {SKELETON_KEYS.map((key) => (\n <MemberCardSkeleton key={key} />\n ))}\n </div>\n </div>\n ) : isError ? (\n <ErrorView message=\"We couldn't load the member directory.\" onRetry={() => refetch()} />\n ) : profiles.length === 0 && pager.page === 0 ? (\n <EmptyState\n illustration=\"empty-people\"\n title=\"No members to discover yet\"\n description=\"When members make their profiles discoverable, they'll show up here for you to follow.\"\n />\n ) : (\n <div className=\"flex flex-col gap-5\">\n <div className=\"relative w-full max-w-sm\">\n <Search\n className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary\"\n aria-hidden=\"true\"\n />\n <Input\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search by name, headline, or skills\"\n aria-label=\"Search members\"\n className=\"pl-9\"\n />\n </div>\n\n {visible.length === 0 ? (\n <EmptyState\n icon={<Search className=\"h-9 w-9\" />}\n title=\"No matches on this page\"\n description=\"No members on this page match your search. Try a different term or browse another page.\"\n />\n ) : (\n <>\n <p className=\"text-xs font-medium text-text-tertiary\">\n Showing {visible.length} member{visible.length === 1 ? '' : 's'}\n </p>\n\n <div className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4\">\n {visible.map((p) => {\n const isSelf = Boolean(currentUser?.id && p.memberId === currentUser.id);\n const isFollowing = followSet.has(p.memberId);\n const isPending = pendingId === p.memberId;\n const chips = Array.from(new Set([...p.skills, ...p.interests])).slice(0, 4);\n\n return (\n <GlassCard\n key={p.id}\n treatment=\"plain\"\n className=\"flex flex-col p-5 transition-all duration-200 motion-safe:hover:-translate-y-0.5 hover:border-[var(--color-accent-soft)]\"\n >\n <button\n type=\"button\"\n onClick={() => navigateTo(`members/${p.memberId}`)}\n aria-label={`View ${p.displayName}'s profile`}\n className=\"group/head flex w-full items-start gap-3 rounded-lg text-left outline-none focus-visible:ring-1 focus-visible:ring-[var(--color-focus-ring)]\"\n >\n <Avatar\n name={p.displayName}\n presence={p.presence}\n size=\"lg\"\n fileId={p.avatar?.id}\n seed={p.memberId}\n />\n <div className=\"min-w-0 flex-1\">\n <span className=\"block max-w-full truncate text-base font-semibold text-text-primary group-hover/head:underline\">\n {p.displayName}\n </span>\n {p.headline && (\n <p className=\"truncate text-sm text-text-secondary\">{p.headline}</p>\n )}\n {p.bio && (\n <p className=\"mt-0.5 line-clamp-1 text-xs text-text-tertiary\">\n {p.bio}\n </p>\n )}\n </div>\n </button>\n\n {chips.length > 0 && (\n <div className=\"mt-3 flex flex-wrap gap-1.5\">\n {chips.map((chip) => (\n <span\n key={chip}\n className=\"rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary\"\n >\n {chip}\n </span>\n ))}\n </div>\n )}\n\n {!isSelf && (\n <div className=\"mt-4 flex items-center justify-end border-t border-border-seam pt-3\">\n {isFollowing ? (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={(e) => {\n e.stopPropagation();\n void toggleFollow(p);\n }}\n disabled={isPending}\n aria-label={`Following ${p.displayName}. Activate to unfollow.`}\n className=\"group/follow min-w-[7.5rem] justify-center hover:border-status-error-border hover:bg-status-error-bg-subtle hover:text-status-error-text\"\n >\n {isPending ? (\n <>\n <Loader2 className=\"motion-safe:animate-spin\" />\n <span>Following</span>\n </>\n ) : (\n <>\n <Check className=\"group-hover/follow:hidden\" />\n <UserMinus className=\"hidden group-hover/follow:inline\" />\n <span className=\"group-hover/follow:hidden\">Following</span>\n <span className=\"hidden group-hover/follow:inline\">Unfollow</span>\n </>\n )}\n </Button>\n ) : (\n <Button\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation();\n void toggleFollow(p);\n }}\n disabled={isPending}\n className=\"min-w-[7.5rem] justify-center\"\n >\n {isPending ? (\n <Loader2 className=\"motion-safe:animate-spin\" />\n ) : (\n <UserPlus />\n )}\n Follow\n </Button>\n )}\n </div>\n )}\n </GlassCard>\n );\n })}\n </div>\n </>\n )}\n\n <Pagination\n page={pager.page}\n pageSize={PAGE_SIZE}\n itemCount={profiles.length}\n hasMore={data?.pageInfo.hasMore ?? false}\n onPageChange={(target) => pager.onPageChange(target, data?.pageInfo.cursor)}\n />\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MembersPage.js","names":[],"sources":["../../../../src/comradecircle/pages/members/MembersPage.tsx"],"sourcesContent":["/**\n * MembersPage — the discoverable member directory.\n * @module comradecircle/pages/members\n *\n * Reads `comListProfiles(discoverable: true)` — every member who has opted into\n * discovery via their {@link ComProfile}. Each card resolves display identity\n * from the social-identity layer (never a raw actor id), links to the member's\n * public profile, and offers a Follow/Following toggle wired to `comFollow` /\n * `comUnfollow` (targetType MEMBER). An optional client-side search narrows the\n * current page by name, headline, skills, or interests.\n */\n\nimport { useMemo, useState } from 'react';\nimport { Search, UserPlus, UserMinus, Check, Loader2 } from 'lucide-react';\nimport { GlassCard, Button, Input, Skeleton } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { Avatar } from '../../components/Avatar';\nimport { EmptyState } from '../../components/EmptyState';\nimport { ErrorView } from '../../components/StateViews';\nimport { Pagination } from '../../components/Pagination';\nimport {\n useComProfiles,\n useComMyFollows,\n useComFollow,\n useComUnfollow,\n useCursorPager,\n useTr,\n} from '../../hooks';\nimport { useComradeCircle } from '../../context';\nimport { notify, describeError } from '../../lib/toast';\nimport type { ComProfile } from '../../types';\n\nconst PAGE_SIZE = 12;\n\nconst SKELETON_KEYS = ['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8'] as const;\n\n/** Card-shaped placeholder that mirrors the member card while the page loads. */\nfunction MemberCardSkeleton() {\n return (\n <GlassCard treatment=\"plain\" className=\"flex flex-col p-5\">\n <div className=\"flex items-start gap-3\">\n <Skeleton className=\"h-14 w-14 rounded-full\" />\n <div className=\"min-w-0 flex-1 space-y-2 py-1\">\n <Skeleton className=\"h-4 w-2/3\" />\n <Skeleton className=\"h-3 w-1/2\" />\n <Skeleton className=\"h-3 w-4/5\" />\n </div>\n </div>\n <div className=\"mt-3 flex flex-wrap gap-1.5\">\n <Skeleton className=\"h-5 w-16 rounded-full\" />\n <Skeleton className=\"h-5 w-20 rounded-full\" />\n </div>\n <div className=\"mt-4 flex justify-end border-t border-border-seam pt-3\">\n <Skeleton className=\"h-8 w-28 rounded-button\" />\n </div>\n </GlassCard>\n );\n}\n\nexport function MembersPage() {\n const tr = useTr();\n const { navigateTo, currentUser } = useComradeCircle();\n const pager = useCursorPager();\n const [search, setSearch] = useState('');\n const [pendingId, setPendingId] = useState<string | null>(null);\n\n const { data, isLoading, isError, refetch } = useComProfiles({\n discoverable: true,\n pagination: { limit: PAGE_SIZE, cursor: pager.cursor },\n });\n\n const { data: follows } = useComMyFollows('MEMBER');\n const follow = useComFollow();\n const unfollow = useComUnfollow();\n\n const followSet = useMemo(() => new Set((follows ?? []).map((f) => f.targetId)), [follows]);\n\n const profiles = useMemo(() => data?.items ?? [], [data]);\n\n const visible = useMemo(() => {\n const q = search.trim().toLowerCase();\n if (!q) return profiles;\n return profiles.filter((p) => {\n const haystack = [p.displayName, p.headline ?? '', ...p.skills, ...p.interests]\n .join(' ')\n .toLowerCase();\n return haystack.includes(q);\n });\n }, [profiles, search]);\n\n const toggleFollow = async (profile: ComProfile) => {\n const wasFollowing = followSet.has(profile.memberId);\n const input = { targetId: profile.memberId, targetType: 'MEMBER' as const };\n setPendingId(profile.memberId);\n try {\n if (wasFollowing) {\n await unfollow.mutateAsync(input);\n notify.success(\n tr('comradecircle.pages.members.unfollowed', 'Unfollowed'),\n profile.displayName\n );\n } else {\n await follow.mutateAsync(input);\n notify.success(\n tr('comradecircle.pages.members.following', 'Following'),\n profile.displayName\n );\n }\n } catch (err) {\n notify.error(\n wasFollowing\n ? tr('comradecircle.pages.members.unfollowError', 'Could not unfollow')\n : tr('comradecircle.pages.members.followError', 'Could not follow'),\n describeError(err)\n );\n } finally {\n setPendingId(null);\n }\n };\n\n return (\n <PageLayout\n title={tr('comradecircle.pages.members.title', 'Members')}\n description={tr(\n 'comradecircle.pages.members.description',\n 'Discover and follow people across your circles — search by name, headline, or skills.'\n )}\n >\n {isLoading ? (\n <div className=\"flex flex-col gap-5\">\n <Skeleton className=\"h-9 w-full max-w-sm rounded-button\" />\n <div className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4\">\n {SKELETON_KEYS.map((key) => (\n <MemberCardSkeleton key={key} />\n ))}\n </div>\n </div>\n ) : isError ? (\n <ErrorView\n message={tr(\n 'comradecircle.pages.members.errorMessage',\n \"We couldn't load the member directory.\"\n )}\n onRetry={() => refetch()}\n />\n ) : profiles.length === 0 && pager.page === 0 ? (\n <EmptyState\n illustration=\"empty-people\"\n title={tr('comradecircle.pages.members.noMembersTitle', 'No members to discover yet')}\n description={tr(\n 'comradecircle.pages.members.noMembersDescription',\n \"When members make their profiles discoverable, they'll show up here for you to follow.\"\n )}\n />\n ) : (\n <div className=\"flex flex-col gap-5\">\n <div className=\"relative w-full max-w-sm\">\n <Search\n className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary\"\n aria-hidden=\"true\"\n />\n <Input\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder={tr(\n 'comradecircle.pages.members.searchPlaceholder',\n 'Search by name, headline, or skills'\n )}\n aria-label={tr('comradecircle.pages.members.searchAriaLabel', 'Search members')}\n className=\"pl-9\"\n />\n </div>\n\n {visible.length === 0 ? (\n <EmptyState\n icon={<Search className=\"h-9 w-9\" />}\n title={tr('comradecircle.pages.members.noMatchesTitle', 'No matches on this page')}\n description={tr(\n 'comradecircle.pages.members.noMatchesDescription',\n 'No members on this page match your search. Try a different term or browse another page.'\n )}\n />\n ) : (\n <>\n <p className=\"text-xs font-medium text-text-tertiary\">\n {tr(\n 'comradecircle.pages.members.showingCount',\n 'Showing {{count}} member{{suffix}}',\n { count: visible.length, suffix: visible.length === 1 ? '' : 's' }\n )}\n </p>\n\n <div className=\"grid gap-4 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4\">\n {visible.map((p) => {\n const isSelf = Boolean(currentUser?.id && p.memberId === currentUser.id);\n const isFollowing = followSet.has(p.memberId);\n const isPending = pendingId === p.memberId;\n const chips = Array.from(new Set([...p.skills, ...p.interests])).slice(0, 4);\n\n return (\n <GlassCard\n key={p.id}\n treatment=\"plain\"\n className=\"flex flex-col p-5 transition-all duration-200 motion-safe:hover:-translate-y-0.5 hover:border-[var(--color-accent-soft)]\"\n >\n <button\n type=\"button\"\n onClick={() => navigateTo(`members/${p.memberId}`)}\n aria-label={tr(\n 'comradecircle.pages.members.viewProfileAriaLabel',\n \"View {{name}}'s profile\",\n { name: p.displayName }\n )}\n className=\"group/head flex w-full items-start gap-3 rounded-lg text-left outline-none focus-visible:ring-1 focus-visible:ring-[var(--color-focus-ring)]\"\n >\n <Avatar\n name={p.displayName}\n presence={p.presence}\n size=\"lg\"\n fileId={p.avatar?.id}\n seed={p.memberId}\n />\n <div className=\"min-w-0 flex-1\">\n <span className=\"block max-w-full truncate text-base font-semibold text-text-primary group-hover/head:underline\">\n {p.displayName}\n </span>\n {p.headline && (\n <p className=\"truncate text-sm text-text-secondary\">{p.headline}</p>\n )}\n {p.bio && (\n <p className=\"mt-0.5 line-clamp-1 text-xs text-text-tertiary\">\n {p.bio}\n </p>\n )}\n </div>\n </button>\n\n {chips.length > 0 && (\n <div className=\"mt-3 flex flex-wrap gap-1.5\">\n {chips.map((chip) => (\n <span\n key={chip}\n className=\"rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary\"\n >\n {chip}\n </span>\n ))}\n </div>\n )}\n\n {!isSelf && (\n <div className=\"mt-4 flex items-center justify-end border-t border-border-seam pt-3\">\n {isFollowing ? (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={(e) => {\n e.stopPropagation();\n void toggleFollow(p);\n }}\n disabled={isPending}\n aria-label={tr(\n 'comradecircle.pages.members.followingAriaLabel',\n 'Following {{name}}. Activate to unfollow.',\n { name: p.displayName }\n )}\n className=\"group/follow min-w-[7.5rem] justify-center hover:border-status-error-border hover:bg-status-error-bg-subtle hover:text-status-error-text\"\n >\n {isPending ? (\n <>\n <Loader2 className=\"motion-safe:animate-spin\" />\n <span>\n {tr('comradecircle.pages.members.following', 'Following')}\n </span>\n </>\n ) : (\n <>\n <Check className=\"group-hover/follow:hidden\" />\n <UserMinus className=\"hidden group-hover/follow:inline\" />\n <span className=\"group-hover/follow:hidden\">\n {tr('comradecircle.pages.members.following', 'Following')}\n </span>\n <span className=\"hidden group-hover/follow:inline\">\n {tr('comradecircle.pages.members.unfollow', 'Unfollow')}\n </span>\n </>\n )}\n </Button>\n ) : (\n <Button\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation();\n void toggleFollow(p);\n }}\n disabled={isPending}\n className=\"min-w-[7.5rem] justify-center\"\n >\n {isPending ? (\n <Loader2 className=\"motion-safe:animate-spin\" />\n ) : (\n <UserPlus />\n )}\n {tr('comradecircle.pages.members.follow', 'Follow')}\n </Button>\n )}\n </div>\n )}\n </GlassCard>\n );\n })}\n </div>\n </>\n )}\n\n <Pagination\n page={pager.page}\n pageSize={PAGE_SIZE}\n itemCount={profiles.length}\n hasMore={data?.pageInfo.hasMore ?? false}\n onPageChange={(target) => pager.onPageChange(target, data?.pageInfo.cursor)}\n />\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MonetizationPage.d.ts","sourceRoot":"","sources":["../../../../src/comradecircle/pages/monetization/MonetizationPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"MonetizationPage.d.ts","sourceRoot":"","sources":["../../../../src/comradecircle/pages/monetization/MonetizationPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA0zBH,wBAAgB,gBAAgB,4CAuE/B"}
|