@withpotter/components 0.13.0-next.78 → 0.13.0-next.80
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.
|
@@ -64,7 +64,8 @@ function buildActivityItems(recentContent, recentOrders, packages, contentTypeSi
|
|
|
64
64
|
customerName,
|
|
65
65
|
order.orderNumber,
|
|
66
66
|
formatCurrency(order.total),
|
|
67
|
-
industryKey
|
|
67
|
+
industryKey,
|
|
68
|
+
order.paymentStatus === "paid" || order.paymentStatus === "partially_refunded" || order.paymentStatus === "refunded"
|
|
68
69
|
);
|
|
69
70
|
items.push({
|
|
70
71
|
id: `order-${order.id}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/dashboard/activity-feed.tsx"],"sourcesContent":["import type {\n Order,\n Package as PackageType,\n ContentItem,\n Member,\n CustomerSubscription,\n InventoryProduct,\n Invoice,\n} from '@withpotter/lib/api/types';\nimport * as copy from '@withpotter/lib/timeline-copy';\n\n// ─── Types ──────────────────────────────────────────────────────────\n\n/**\n * A single thing that happened to the business. Built here, rendered by\n * `home/home-timeline.tsx`.\n *\n * The React component that used to live in this file is gone: the home merged\n * its feed with \"Next up\" and \"Needs you\" into one timeline, so the events and\n * the open work read as a single list with now as the pivot. What survives is\n * the builder, which is the part several surfaces actually share.\n */\nexport interface ActivityItem {\n id: string;\n type:\n | 'product_added'\n | 'product_updated'\n | 'order_placed'\n | 'order_completed'\n | 'member_signup'\n | 'member_converted'\n | 'subscription_created'\n | 'invoice_paid'\n | 'invoice_sent';\n title: string;\n description: string;\n timestamp: string;\n /** Retained for the mobile feed; the desktop timeline renders an icon. */\n emoji: string;\n href?: string;\n}\n\n// ─── Helpers ────────────────────────────────────────────────────────\n\nfunction formatRelativeTime(dateStr: string): string {\n const now = Date.now();\n const date = new Date(dateStr).getTime();\n const diffMs = now - date;\n const diffSec = Math.floor(diffMs / 1000);\n const diffMin = Math.floor(diffSec / 60);\n const diffHr = Math.floor(diffMin / 60);\n const diffDay = Math.floor(diffHr / 24);\n\n if (diffSec < 60) return 'Just now';\n if (diffMin < 60) return `${diffMin}m ago`;\n if (diffHr < 24) return `${diffHr}h ago`;\n if (diffDay < 7) return `${diffDay}d ago`;\n return new Date(dateStr).toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n });\n}\n\nexport function buildActivityItems(\n recentContent: ContentItem[],\n recentOrders: Order[],\n packages: PackageType[],\n contentTypeSingular: string,\n primaryContentKey: string,\n recentMembers: Member[],\n recentSubscriptions: CustomerSubscription[] = [],\n inventoryProducts: InventoryProduct[] = [],\n recentInvoices: Invoice[] = [],\n formatCurrency: (amount: number, currencyOverride?: string) => string,\n industryKey?: string | null,\n): ActivityItem[] {\n const items: ActivityItem[] = [];\n\n // Product / content activity\n for (const item of recentContent) {\n const isUpdate = item.updatedAt !== item.createdAt;\n const msg = isUpdate\n ? copy.productUpdated(item.title, contentTypeSingular)\n : copy.productAdded(item.title, contentTypeSingular);\n items.push({\n id: `content-${item.id}`,\n type: isUpdate ? 'product_updated' : 'product_added',\n ...msg,\n timestamp: item.updatedAt || item.createdAt,\n href: `/dashboard/content/${primaryContentKey}/${item.id}/edit`,\n });\n }\n\n // Inventory product activity (deduplicate against content items by title)\n const contentTitles = new Set(recentContent.map((c) => c.title));\n for (const prod of inventoryProducts) {\n if (contentTitles.has(prod.title)) continue;\n const created = prod.createdAt ? String(prod.createdAt) : '';\n const updated = prod.updatedAt ? String(prod.updatedAt) : created;\n const isUpdate = updated !== created;\n const msg = isUpdate\n ? copy.productUpdated(prod.title, contentTypeSingular)\n : copy.productAdded(prod.title, contentTypeSingular);\n items.push({\n id: `inv-${prod.id}`,\n type: isUpdate ? 'product_updated' : 'product_added',\n ...msg,\n timestamp: updated || created,\n href: `/dashboard/catalog/${prod.id}`,\n });\n }\n\n // Package activity (only if no content items — avoids duplicates)\n if (recentContent.length === 0 && inventoryProducts.length === 0) {\n for (const pkg of packages) {\n const isUpdate = pkg.updatedAt !== pkg.createdAt;\n const msg = isUpdate\n ? copy.productUpdated(pkg.title, contentTypeSingular)\n : copy.productAdded(pkg.title, contentTypeSingular);\n items.push({\n id: `pkg-${pkg.id}`,\n type: isUpdate ? 'product_updated' : 'product_added',\n ...msg,\n timestamp: pkg.updatedAt || pkg.createdAt,\n href: `/dashboard/content/${primaryContentKey}/${pkg.documentId}/edit`,\n });\n }\n }\n\n // Order activity\n for (const order of recentOrders) {\n const isCompleted = order.status === 'completed';\n const customerName =\n order.customerName || order.customerEmail?.split('@')[0] || 'Someone';\n const msg = isCompleted\n ? copy.orderCompleted(customerName, order.orderNumber)\n : copy.orderPlaced(\n customerName,\n order.orderNumber,\n formatCurrency(order.total),\n industryKey,\n );\n items.push({\n id: `order-${order.id}`,\n type: isCompleted ? 'order_completed' : 'order_placed',\n ...msg,\n timestamp: isCompleted\n ? order.completedAt || order.updatedAt\n : order.createdAt,\n href: `/dashboard/orders/${order.id}`,\n });\n }\n\n // Member signup / conversion activity\n for (const member of recentMembers) {\n const isConverted = !!member.convertedAt;\n const name = member.name || member.email?.split('@')[0] || 'A visitor';\n const msg = isConverted\n ? copy.memberConverted(name, member.email)\n : copy.memberSignup(name, member.email, industryKey);\n items.push({\n id: `member-${member.id}`,\n type: isConverted ? 'member_converted' : 'member_signup',\n ...msg,\n timestamp: isConverted ? member.convertedAt! : member.createdAt,\n href: `/dashboard/customers/${member.id}`,\n });\n }\n\n // Subscription activity\n for (const sub of recentSubscriptions) {\n const name = sub.customerEmail?.split('@')[0] || 'Someone';\n const msg = copy.subscriptionCreated(\n name,\n sub.plan?.name || 'a plan',\n formatCurrency(sub.amount / 100),\n );\n items.push({\n id: `sub-${sub.id}`,\n type: 'subscription_created',\n ...msg,\n timestamp: sub.createdAt,\n href: '/dashboard/subscriptions',\n });\n }\n\n // Invoice activity\n for (const inv of recentInvoices) {\n const customerName =\n inv.customerName || inv.customerEmail?.split('@')[0] || 'Someone';\n const isPaid = inv.status === 'paid' && !!inv.paidAt;\n const isSent = inv.status === 'sent' && !!inv.sentAt;\n if (isPaid) {\n const msg = copy.invoicePaid(\n customerName,\n inv.invoiceNumber,\n formatCurrency(inv.amountPaid || inv.total, inv.currency),\n );\n items.push({\n id: `inv-paid-${inv.id}`,\n type: 'invoice_paid',\n ...msg,\n timestamp: inv.paidAt!,\n href: `/dashboard/invoices/${inv.id}`,\n });\n } else if (isSent) {\n const msg = copy.invoiceSent(\n customerName,\n inv.invoiceNumber,\n formatCurrency(inv.total, inv.currency),\n );\n items.push({\n id: `inv-sent-${inv.id}`,\n type: 'invoice_sent',\n ...msg,\n timestamp: inv.sentAt!,\n href: `/dashboard/invoices/${inv.id}`,\n });\n }\n }\n\n // Sort by timestamp descending\n items.sort(\n (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime(),\n );\n return items;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/dashboard/activity-feed.tsx"],"sourcesContent":["import type {\n Order,\n Package as PackageType,\n ContentItem,\n Member,\n CustomerSubscription,\n InventoryProduct,\n Invoice,\n} from '@withpotter/lib/api/types';\nimport * as copy from '@withpotter/lib/timeline-copy';\n\n// ─── Types ──────────────────────────────────────────────────────────\n\n/**\n * A single thing that happened to the business. Built here, rendered by\n * `home/home-timeline.tsx`.\n *\n * The React component that used to live in this file is gone: the home merged\n * its feed with \"Next up\" and \"Needs you\" into one timeline, so the events and\n * the open work read as a single list with now as the pivot. What survives is\n * the builder, which is the part several surfaces actually share.\n */\nexport interface ActivityItem {\n id: string;\n type:\n | 'product_added'\n | 'product_updated'\n | 'order_placed'\n | 'order_completed'\n | 'member_signup'\n | 'member_converted'\n | 'subscription_created'\n | 'invoice_paid'\n | 'invoice_sent';\n title: string;\n description: string;\n timestamp: string;\n /** Retained for the mobile feed; the desktop timeline renders an icon. */\n emoji: string;\n href?: string;\n}\n\n// ─── Helpers ────────────────────────────────────────────────────────\n\nfunction formatRelativeTime(dateStr: string): string {\n const now = Date.now();\n const date = new Date(dateStr).getTime();\n const diffMs = now - date;\n const diffSec = Math.floor(diffMs / 1000);\n const diffMin = Math.floor(diffSec / 60);\n const diffHr = Math.floor(diffMin / 60);\n const diffDay = Math.floor(diffHr / 24);\n\n if (diffSec < 60) return 'Just now';\n if (diffMin < 60) return `${diffMin}m ago`;\n if (diffHr < 24) return `${diffHr}h ago`;\n if (diffDay < 7) return `${diffDay}d ago`;\n return new Date(dateStr).toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n });\n}\n\nexport function buildActivityItems(\n recentContent: ContentItem[],\n recentOrders: Order[],\n packages: PackageType[],\n contentTypeSingular: string,\n primaryContentKey: string,\n recentMembers: Member[],\n recentSubscriptions: CustomerSubscription[] = [],\n inventoryProducts: InventoryProduct[] = [],\n recentInvoices: Invoice[] = [],\n formatCurrency: (amount: number, currencyOverride?: string) => string,\n industryKey?: string | null,\n): ActivityItem[] {\n const items: ActivityItem[] = [];\n\n // Product / content activity\n for (const item of recentContent) {\n const isUpdate = item.updatedAt !== item.createdAt;\n const msg = isUpdate\n ? copy.productUpdated(item.title, contentTypeSingular)\n : copy.productAdded(item.title, contentTypeSingular);\n items.push({\n id: `content-${item.id}`,\n type: isUpdate ? 'product_updated' : 'product_added',\n ...msg,\n timestamp: item.updatedAt || item.createdAt,\n href: `/dashboard/content/${primaryContentKey}/${item.id}/edit`,\n });\n }\n\n // Inventory product activity (deduplicate against content items by title)\n const contentTitles = new Set(recentContent.map((c) => c.title));\n for (const prod of inventoryProducts) {\n if (contentTitles.has(prod.title)) continue;\n const created = prod.createdAt ? String(prod.createdAt) : '';\n const updated = prod.updatedAt ? String(prod.updatedAt) : created;\n const isUpdate = updated !== created;\n const msg = isUpdate\n ? copy.productUpdated(prod.title, contentTypeSingular)\n : copy.productAdded(prod.title, contentTypeSingular);\n items.push({\n id: `inv-${prod.id}`,\n type: isUpdate ? 'product_updated' : 'product_added',\n ...msg,\n timestamp: updated || created,\n href: `/dashboard/catalog/${prod.id}`,\n });\n }\n\n // Package activity (only if no content items — avoids duplicates)\n if (recentContent.length === 0 && inventoryProducts.length === 0) {\n for (const pkg of packages) {\n const isUpdate = pkg.updatedAt !== pkg.createdAt;\n const msg = isUpdate\n ? copy.productUpdated(pkg.title, contentTypeSingular)\n : copy.productAdded(pkg.title, contentTypeSingular);\n items.push({\n id: `pkg-${pkg.id}`,\n type: isUpdate ? 'product_updated' : 'product_added',\n ...msg,\n timestamp: pkg.updatedAt || pkg.createdAt,\n href: `/dashboard/content/${primaryContentKey}/${pkg.documentId}/edit`,\n });\n }\n }\n\n // Order activity\n for (const order of recentOrders) {\n const isCompleted = order.status === 'completed';\n const customerName =\n order.customerName || order.customerEmail?.split('@')[0] || 'Someone';\n const msg = isCompleted\n ? copy.orderCompleted(customerName, order.orderNumber)\n : copy.orderPlaced(\n customerName,\n order.orderNumber,\n formatCurrency(order.total),\n industryKey,\n order.paymentStatus === 'paid' ||\n order.paymentStatus === 'partially_refunded' ||\n order.paymentStatus === 'refunded',\n );\n items.push({\n id: `order-${order.id}`,\n type: isCompleted ? 'order_completed' : 'order_placed',\n ...msg,\n timestamp: isCompleted\n ? order.completedAt || order.updatedAt\n : order.createdAt,\n href: `/dashboard/orders/${order.id}`,\n });\n }\n\n // Member signup / conversion activity\n for (const member of recentMembers) {\n const isConverted = !!member.convertedAt;\n const name = member.name || member.email?.split('@')[0] || 'A visitor';\n const msg = isConverted\n ? copy.memberConverted(name, member.email)\n : copy.memberSignup(name, member.email, industryKey);\n items.push({\n id: `member-${member.id}`,\n type: isConverted ? 'member_converted' : 'member_signup',\n ...msg,\n timestamp: isConverted ? member.convertedAt! : member.createdAt,\n href: `/dashboard/customers/${member.id}`,\n });\n }\n\n // Subscription activity\n for (const sub of recentSubscriptions) {\n const name = sub.customerEmail?.split('@')[0] || 'Someone';\n const msg = copy.subscriptionCreated(\n name,\n sub.plan?.name || 'a plan',\n formatCurrency(sub.amount / 100),\n );\n items.push({\n id: `sub-${sub.id}`,\n type: 'subscription_created',\n ...msg,\n timestamp: sub.createdAt,\n href: '/dashboard/subscriptions',\n });\n }\n\n // Invoice activity\n for (const inv of recentInvoices) {\n const customerName =\n inv.customerName || inv.customerEmail?.split('@')[0] || 'Someone';\n const isPaid = inv.status === 'paid' && !!inv.paidAt;\n const isSent = inv.status === 'sent' && !!inv.sentAt;\n if (isPaid) {\n const msg = copy.invoicePaid(\n customerName,\n inv.invoiceNumber,\n formatCurrency(inv.amountPaid || inv.total, inv.currency),\n );\n items.push({\n id: `inv-paid-${inv.id}`,\n type: 'invoice_paid',\n ...msg,\n timestamp: inv.paidAt!,\n href: `/dashboard/invoices/${inv.id}`,\n });\n } else if (isSent) {\n const msg = copy.invoiceSent(\n customerName,\n inv.invoiceNumber,\n formatCurrency(inv.total, inv.currency),\n );\n items.push({\n id: `inv-sent-${inv.id}`,\n type: 'invoice_sent',\n ...msg,\n timestamp: inv.sentAt!,\n href: `/dashboard/invoices/${inv.id}`,\n });\n }\n }\n\n // Sort by timestamp descending\n items.sort(\n (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime(),\n );\n return items;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -14,7 +14,7 @@ function TeamWidget() {
|
|
|
14
14
|
const invite = useWorkspaceInvite();
|
|
15
15
|
const [inviteOpen, setInviteOpen] = useState(false);
|
|
16
16
|
const [openMember, setOpenMember] = useState(null);
|
|
17
|
-
const { members } = useWorkspaceMembers();
|
|
17
|
+
const { members, isError, refetch } = useWorkspaceMembers();
|
|
18
18
|
const active = members.filter((m) => m.status !== "removed");
|
|
19
19
|
const shown = active.slice(0, ROW_LIMIT);
|
|
20
20
|
const overflow = active.length - shown.length;
|
|
@@ -27,7 +27,18 @@ function TeamWidget() {
|
|
|
27
27
|
className: "h-full",
|
|
28
28
|
bodyClassName: "flex flex-col",
|
|
29
29
|
children: [
|
|
30
|
-
active.length === 0 ? /* @__PURE__ */
|
|
30
|
+
isError && active.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "flex min-h-[132px] flex-col items-center justify-center gap-2 px-4 py-6 text-center", children: [
|
|
31
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-[var(--text-secondary)]", children: "Couldn\u2019t load your team" }),
|
|
32
|
+
/* @__PURE__ */ jsx(
|
|
33
|
+
"button",
|
|
34
|
+
{
|
|
35
|
+
type: "button",
|
|
36
|
+
onClick: () => void refetch(),
|
|
37
|
+
className: "text-sm font-medium text-[var(--text-tertiary)] transition-colors hover:text-[var(--text-primary)]",
|
|
38
|
+
children: "Retry"
|
|
39
|
+
}
|
|
40
|
+
)
|
|
41
|
+
] }) : active.length === 0 ? /* @__PURE__ */ jsx(
|
|
31
42
|
PanelEmpty,
|
|
32
43
|
{
|
|
33
44
|
title: "Just you so far",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/dashboard/home/widgets/team-widget.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { Plus } from 'lucide-react';\nimport { useWorkspaceInvite } from '@withpotter/lib/use-workspace-invite';\nimport { generatedAvatarUri } from '@withpotter/ui-kit/generated-avatar';\nimport { InviteMemberDialog } from '@withpotter/pages-core/dashboard/settings/team/_components/invite-member-dialog';\nimport { PersonActivity } from '../person-activity';\nimport { Panel, PanelEmpty } from '../panel';\nimport { useWorkspaceMembers } from '@withpotter/hooks/use-workspace-members';\nimport { TEAM_PAGE } from '@withpotter/lib/team-page';\n\n/**\n * Who is in the business, on the board rather than in the header.\n *\n * IT SWAPPED PLACES WITH \"Add widget\". The header held a stack of faces and the\n * board's last slot held a dashed \"Add widget\" tile, and both were in the wrong\n * place: the faces are CONTENT — a thing you look at and click into — which is\n * what a card is for, and adding a widget is a CONTROL, which is what a header\n * is for. A control sitting in the grid it edits was always slightly odd.\n *\n * A ROSTER IS NOT A LIST OF NAMES. Each row carries what that person can do,\n * because \"who is in here\" and \"what are they allowed to touch\" are the same\n * question for an owner — and the answer is invisible everywhere else without\n * opening team settings.\n *\n * CLICKING SOMEONE OPENS WHAT THEY HAVE DONE, from the attributed team log.\n * See `PersonActivity` for why that is a different feed from the home's own\n * Activity card and could never have been a filter on it.\n */\n\n/** Rows before the rest becomes a count. Past this the card stops fitting. */\nconst ROW_LIMIT = 4;\n\nexport function TeamWidget() {\n const invite = useWorkspaceInvite();\n const [inviteOpen, setInviteOpen] = useState(false);\n const [openMember, setOpenMember] = useState<string | null>(null);\n\n const { members } = useWorkspaceMembers();\n const active = members.filter((m) => m.status !== 'removed');\n const shown = active.slice(0, ROW_LIMIT);\n const overflow = active.length - shown.length;\n\n return (\n <>\n <Panel\n title=\"Team\"\n action={{ label: 'Manage', href: TEAM_PAGE }}\n className=\"h-full\"\n bodyClassName=\"flex flex-col\"\n >\n {active.length === 0 ? (\n <PanelEmpty\n title=\"Just you so far\"\n description=\"Add someone and they can take orders without seeing your takings.\"\n />\n ) : (\n <ul className=\"space-y-1\">\n {shown.map((m) => (\n <li key={m.id}>\n <button\n type=\"button\"\n onClick={() => setOpenMember(m.id)}\n className=\"-mx-2 flex w-full items-center gap-3 rounded-lg px-2 py-2 text-left transition-colors hover:bg-[var(--interactive-hover)]\"\n >\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={generatedAvatarUri(m.email || m.id)}\n alt=\"\"\n className=\"h-6 w-6 shrink-0 rounded-full object-cover\"\n />\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium text-[var(--text-primary)]\">\n {m.name || m.email || 'Team member'}\n </span>\n {/* Invited-but-not-joined says so. Showing a role for someone\n who has never arrived implies they are working. */}\n <span className=\"shrink-0 text-sm capitalize text-[var(--text-muted)]\">\n {m.status === 'invited'\n ? 'Invited'\n : (m.roleName ?? m.role)}\n </span>\n </button>\n </li>\n ))}\n {overflow > 0 && (\n <li className=\"px-0 pt-1 text-sm text-[var(--text-muted)]\">\n and {overflow} more\n </li>\n )}\n </ul>\n )}\n\n <div className=\"mt-auto pt-3\">\n <button\n type=\"button\"\n onClick={() => setInviteOpen(true)}\n className=\"inline-flex items-center gap-2 text-sm font-medium text-[var(--text-tertiary)] transition-colors hover:text-[var(--text-primary)]\"\n >\n <Plus />\n Invite someone\n </button>\n </div>\n </Panel>\n\n {openMember && (\n <PersonActivity\n member={active.find((m) => m.id === openMember)!}\n onClose={() => setOpenMember(null)}\n />\n )}\n\n <InviteMemberDialog\n open={inviteOpen}\n onOpenChange={setInviteOpen}\n workspaceRoles={invite.roles}\n wsInviteEmail={invite.email}\n setWsInviteEmail={invite.setEmail}\n wsInvitePhone={invite.phone}\n setWsInvitePhone={invite.setPhone}\n setWsInviteRole={invite.setRole}\n handleWsInvite={invite.invite}\n wsInviting={invite.inviting}\n />\n </>\n );\n}\n"],"mappings":";AA6CI,
|
|
1
|
+
{"version":3,"sources":["../../../../src/dashboard/home/widgets/team-widget.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { Plus } from 'lucide-react';\nimport { useWorkspaceInvite } from '@withpotter/lib/use-workspace-invite';\nimport { generatedAvatarUri } from '@withpotter/ui-kit/generated-avatar';\nimport { InviteMemberDialog } from '@withpotter/pages-core/dashboard/settings/team/_components/invite-member-dialog';\nimport { PersonActivity } from '../person-activity';\nimport { Panel, PanelEmpty } from '../panel';\nimport { useWorkspaceMembers } from '@withpotter/hooks/use-workspace-members';\nimport { TEAM_PAGE } from '@withpotter/lib/team-page';\n\n/**\n * Who is in the business, on the board rather than in the header.\n *\n * IT SWAPPED PLACES WITH \"Add widget\". The header held a stack of faces and the\n * board's last slot held a dashed \"Add widget\" tile, and both were in the wrong\n * place: the faces are CONTENT — a thing you look at and click into — which is\n * what a card is for, and adding a widget is a CONTROL, which is what a header\n * is for. A control sitting in the grid it edits was always slightly odd.\n *\n * A ROSTER IS NOT A LIST OF NAMES. Each row carries what that person can do,\n * because \"who is in here\" and \"what are they allowed to touch\" are the same\n * question for an owner — and the answer is invisible everywhere else without\n * opening team settings.\n *\n * CLICKING SOMEONE OPENS WHAT THEY HAVE DONE, from the attributed team log.\n * See `PersonActivity` for why that is a different feed from the home's own\n * Activity card and could never have been a filter on it.\n */\n\n/** Rows before the rest becomes a count. Past this the card stops fitting. */\nconst ROW_LIMIT = 4;\n\nexport function TeamWidget() {\n const invite = useWorkspaceInvite();\n const [inviteOpen, setInviteOpen] = useState(false);\n const [openMember, setOpenMember] = useState<string | null>(null);\n\n const { members, isError, refetch } = useWorkspaceMembers();\n const active = members.filter((m) => m.status !== 'removed');\n const shown = active.slice(0, ROW_LIMIT);\n const overflow = active.length - shown.length;\n\n return (\n <>\n <Panel\n title=\"Team\"\n action={{ label: 'Manage', href: TEAM_PAGE }}\n className=\"h-full\"\n bodyClassName=\"flex flex-col\"\n >\n {isError && active.length === 0 ? (\n <div className=\"flex min-h-[132px] flex-col items-center justify-center gap-2 px-4 py-6 text-center\">\n <p className=\"text-sm font-medium text-[var(--text-secondary)]\">\n Couldn’t load your team\n </p>\n <button\n type=\"button\"\n onClick={() => void refetch()}\n className=\"text-sm font-medium text-[var(--text-tertiary)] transition-colors hover:text-[var(--text-primary)]\"\n >\n Retry\n </button>\n </div>\n ) : active.length === 0 ? (\n <PanelEmpty\n title=\"Just you so far\"\n description=\"Add someone and they can take orders without seeing your takings.\"\n />\n ) : (\n <ul className=\"space-y-1\">\n {shown.map((m) => (\n <li key={m.id}>\n <button\n type=\"button\"\n onClick={() => setOpenMember(m.id)}\n className=\"-mx-2 flex w-full items-center gap-3 rounded-lg px-2 py-2 text-left transition-colors hover:bg-[var(--interactive-hover)]\"\n >\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={generatedAvatarUri(m.email || m.id)}\n alt=\"\"\n className=\"h-6 w-6 shrink-0 rounded-full object-cover\"\n />\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium text-[var(--text-primary)]\">\n {m.name || m.email || 'Team member'}\n </span>\n {/* Invited-but-not-joined says so. Showing a role for someone\n who has never arrived implies they are working. */}\n <span className=\"shrink-0 text-sm capitalize text-[var(--text-muted)]\">\n {m.status === 'invited'\n ? 'Invited'\n : (m.roleName ?? m.role)}\n </span>\n </button>\n </li>\n ))}\n {overflow > 0 && (\n <li className=\"px-0 pt-1 text-sm text-[var(--text-muted)]\">\n and {overflow} more\n </li>\n )}\n </ul>\n )}\n\n <div className=\"mt-auto pt-3\">\n <button\n type=\"button\"\n onClick={() => setInviteOpen(true)}\n className=\"inline-flex items-center gap-2 text-sm font-medium text-[var(--text-tertiary)] transition-colors hover:text-[var(--text-primary)]\"\n >\n <Plus />\n Invite someone\n </button>\n </div>\n </Panel>\n\n {openMember && (\n <PersonActivity\n member={active.find((m) => m.id === openMember)!}\n onClose={() => setOpenMember(null)}\n />\n )}\n\n <InviteMemberDialog\n open={inviteOpen}\n onOpenChange={setInviteOpen}\n workspaceRoles={invite.roles}\n wsInviteEmail={invite.email}\n setWsInviteEmail={invite.setEmail}\n wsInvitePhone={invite.phone}\n setWsInvitePhone={invite.setPhone}\n setWsInviteRole={invite.setRole}\n handleWsInvite={invite.invite}\n wsInviting={invite.inviting}\n />\n </>\n );\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@withpotter/components",
|
|
3
|
-
"version": "0.13.0-next.
|
|
3
|
+
"version": "0.13.0-next.80",
|
|
4
4
|
"description": "Box dashboard feature components: editors, mobile screens, pickers, and composite UI built on @withpotter/ui-kit.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"sideEffects": [
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"@tiptap/react": "^3.22.5",
|
|
51
51
|
"@tiptap/starter-kit": "^3.22.5",
|
|
52
52
|
"@tiptap/suggestion": "^3.22.5",
|
|
53
|
-
"@withpotter/hooks": "^0.13.0-next.
|
|
54
|
-
"@withpotter/lib": "^0.13.0-next.
|
|
55
|
-
"@withpotter/ui-kit": "^0.13.0-next.
|
|
53
|
+
"@withpotter/hooks": "^0.13.0-next.80",
|
|
54
|
+
"@withpotter/lib": "^0.13.0-next.80",
|
|
55
|
+
"@withpotter/ui-kit": "^0.13.0-next.80",
|
|
56
56
|
"@xyflow/react": "^12.11.2",
|
|
57
57
|
"dompurify": "^3.3.1",
|
|
58
58
|
"jsqr": "1.4.0",
|