@thewhatmatters/wmds 0.2.0 → 0.3.0

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.
Files changed (134) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/CONSUMING.md +4 -4
  3. package/README.md +3 -3
  4. package/dist/styles.css +1 -1
  5. package/docs/component-contracts.md +1 -1
  6. package/docs/components.md +6 -6
  7. package/docs/exports.json +1 -13
  8. package/docs/patterns/components-avatar--dropdown-row.tsx +1 -1
  9. package/docs/patterns/components-badge--with-avatar.tsx +1 -1
  10. package/docs/patterns/components-button-button--destructive-action.tsx +1 -1
  11. package/docs/patterns/components-button-button--ghost-action.tsx +1 -1
  12. package/docs/patterns/components-button-button--inverse-action.tsx +1 -1
  13. package/docs/patterns/components-button-button--link-render.tsx +1 -1
  14. package/docs/patterns/components-button-button--multi-state-badge.tsx +1 -1
  15. package/docs/patterns/components-button-button--outline-mono.tsx +1 -1
  16. package/docs/patterns/components-button-button--primary-action.tsx +1 -1
  17. package/docs/patterns/components-button-button--row-hug.tsx +1 -1
  18. package/docs/patterns/components-button-button--row-layout.tsx +1 -1
  19. package/docs/patterns/components-button-button--secondary-action.tsx +1 -1
  20. package/docs/patterns/components-button-button--suggestion-pills.tsx +1 -1
  21. package/docs/patterns/components-button-button--with-count.tsx +1 -1
  22. package/docs/patterns/components-button-button--with-icon.tsx +1 -1
  23. package/docs/patterns/components-button-floatingactionbutton--vertical-actions.tsx +1 -1
  24. package/docs/patterns/components-calembed--pattern-skip-in-footer.tsx +1 -1
  25. package/docs/patterns/components-card-card--body-slot-occupancy-history.tsx +1 -1
  26. package/docs/patterns/components-card-card--headerless-media.tsx +1 -1
  27. package/docs/patterns/components-card-card--outlined-layout.tsx +1 -1
  28. package/docs/patterns/components-card-card--pinned-height.tsx +1 -1
  29. package/docs/patterns/components-card-selectablecard--selectable-cards-pattern.tsx +1 -1
  30. package/docs/patterns/components-chart--audience-activity-heatmap.tsx +1 -1
  31. package/docs/patterns/components-chart--cartesian-no-data-gaps.tsx +1 -1
  32. package/docs/patterns/components-chart--occupancy-history-in-card.tsx +1 -1
  33. package/docs/patterns/components-chart--occupancy-in-card.tsx +1 -1
  34. package/docs/patterns/components-chart--post-reach-distribution.tsx +1 -1
  35. package/docs/patterns/components-chart--ranked-audience-breakdown.tsx +1 -1
  36. package/docs/patterns/components-chart--unit-grid-composition.tsx +1 -1
  37. package/docs/patterns/components-chatqa--pattern-qa-with-reply.tsx +1 -1
  38. package/docs/patterns/components-checkbox-checkbox--default.tsx +1 -1
  39. package/docs/patterns/components-checkbox-checkbox--with-description.tsx +1 -1
  40. package/docs/patterns/components-checkbox-checkboxgroup--default.tsx +1 -1
  41. package/docs/patterns/components-dialog--alert-dialog-destructive.tsx +1 -1
  42. package/docs/patterns/components-dialog--default-dialog.tsx +1 -1
  43. package/docs/patterns/components-dialog--form-dialog.tsx +1 -1
  44. package/docs/patterns/components-displaycontrols--page-utilities.tsx +1 -1
  45. package/docs/patterns/components-field--horizontal-input.tsx +1 -1
  46. package/docs/patterns/components-field--horizontal-text-area.tsx +1 -1
  47. package/docs/patterns/components-field--multi-control.tsx +1 -1
  48. package/docs/patterns/components-footerreveal--marketing-hero-pattern.tsx +1 -1
  49. package/docs/patterns/components-footerreveal--marketing-hero-ruled-pattern.tsx +1 -1
  50. package/docs/patterns/components-footerreveal--marketing-hero-with-gallery-intro.tsx +1 -1
  51. package/docs/patterns/components-footerreveal--marketing-page-pattern.tsx +1 -1
  52. package/docs/patterns/components-footerreveal--ruled-grid-footer-pattern.tsx +1 -1
  53. package/docs/patterns/components-footerreveal--sequenced-marketing-hero.tsx +1 -1
  54. package/docs/patterns/components-herointro--two-line-intro.tsx +1 -1
  55. package/docs/patterns/components-herotilestack--marketing-hero-pattern.tsx +1 -1
  56. package/docs/patterns/components-herotilestack--marketing-hero-text-sequence.tsx +1 -1
  57. package/docs/patterns/components-herotilestack--marketing-hero-with-gallery-intro.tsx +1 -1
  58. package/docs/patterns/components-intakeconfirmation--booked-pattern.tsx +1 -1
  59. package/docs/patterns/components-intakeconfirmation--emailed-pattern.tsx +1 -1
  60. package/docs/patterns/components-intakeform--about-you-pattern.tsx +1 -1
  61. package/docs/patterns/components-intakemodal--intake-modal-pattern.tsx +1 -1
  62. package/docs/patterns/components-kbd--command-row.tsx +1 -1
  63. package/docs/patterns/components-kbd--numbered-choices.tsx +1 -1
  64. package/docs/patterns/components-kbd--shortcut.tsx +1 -1
  65. package/docs/patterns/components-moremenu--action-menu.tsx +1 -1
  66. package/docs/patterns/components-moremenu--in-card-header.tsx +1 -1
  67. package/docs/patterns/components-navlist--side-nav-settings.tsx +1 -1
  68. package/docs/patterns/components-pageheader--app-header-pattern.tsx +1 -1
  69. package/docs/patterns/components-pageheader--page-section-header.tsx +1 -1
  70. package/docs/patterns/components-pageheader--toolbar-header.tsx +1 -1
  71. package/docs/patterns/components-panel--end-detail-rail.tsx +1 -1
  72. package/docs/patterns/components-pillgroup--pill-group-pattern.tsx +1 -1
  73. package/docs/patterns/components-promptbar--pattern-marketing-composer.tsx +3 -3
  74. package/docs/patterns/components-promptbar--pattern-prompt-bar.tsx +1 -1
  75. package/docs/patterns/components-radio-radiogroup--default.tsx +1 -1
  76. package/docs/patterns/components-scrollhorizontal--project-gallery-pattern.tsx +1 -1
  77. package/docs/patterns/components-scrollhorizontal--with-intro.tsx +1 -1
  78. package/docs/patterns/components-sheet--bottom-sheet.tsx +1 -1
  79. package/docs/patterns/components-sheet--end-sheet.tsx +1 -1
  80. package/docs/patterns/components-sitenav--brand-and-cta.tsx +1 -1
  81. package/docs/patterns/components-sitenav--centered-links.tsx +1 -1
  82. package/docs/patterns/components-sitenav--compact.tsx +1 -1
  83. package/docs/patterns/components-sitenav--marketing-header.tsx +1 -1
  84. package/docs/patterns/components-sitenav--mega-menu.tsx +1 -1
  85. package/docs/patterns/components-stat--insights-row.tsx +1 -1
  86. package/docs/patterns/components-stepprogress--step-progress-pattern.tsx +1 -1
  87. package/docs/patterns/components-switch--default.tsx +1 -1
  88. package/docs/patterns/components-switch--settings-row.tsx +1 -1
  89. package/docs/patterns/components-tab--settings-pages.tsx +1 -1
  90. package/docs/patterns/components-taskrows--action-details.tsx +1 -1
  91. package/docs/patterns/components-taskrows--capsules.tsx +1 -1
  92. package/docs/patterns/components-taskrows--card-with-status-rows.tsx +1 -1
  93. package/docs/patterns/components-taskrows--controlled-expand.tsx +1 -1
  94. package/docs/patterns/components-taskrows--custom-slots.tsx +1 -1
  95. package/docs/patterns/components-taskrows--status-list.tsx +1 -1
  96. package/docs/patterns/components-taskrows--tag-chips.tsx +1 -1
  97. package/docs/patterns/components-textlink--external-destination.tsx +1 -1
  98. package/docs/patterns/components-textlink--inline-prose.tsx +1 -1
  99. package/docs/patterns/components-textlink--supporting-copy.tsx +1 -1
  100. package/docs/patterns/components-textsequence--default.tsx +1 -1
  101. package/docs/patterns/components-textsequence--reduced-motion.tsx +1 -1
  102. package/docs/patterns/components-textsequence--shapes.tsx +1 -1
  103. package/docs/patterns/components-toast--stacked-notifications.tsx +1 -1
  104. package/docs/patterns/components-tooltip--controlled.tsx +1 -1
  105. package/docs/patterns/components-tooltip--disabled-control.tsx +1 -1
  106. package/docs/patterns/components-tooltip--icon-action.tsx +1 -1
  107. package/docs/patterns/components-tooltip--keyboard-shortcut.tsx +1 -1
  108. package/docs/patterns/components-tooltip--placement.tsx +1 -1
  109. package/docs/patterns/foundations-scroll-fade--horizontal-rail.tsx +1 -1
  110. package/docs/patterns/foundations-scroll-fade--overflowing-list.tsx +1 -1
  111. package/docs/patterns/guides-chart-explorations--comparison-gallery.tsx +1 -1
  112. package/docs/patterns/guides-overlay-flows--notification-preferences.tsx +1 -1
  113. package/docs/patterns/guides-profile-typography--editorial-profile.tsx +1 -1
  114. package/docs/patterns/index.json +1 -153
  115. package/package.json +1 -1
  116. package/docs/patterns/sites-pitchkit-account-settings--account-settings-owner.tsx +0 -265
  117. package/docs/patterns/sites-pitchkit-creator-identity--creator-identity-owner-settings.tsx +0 -154
  118. package/docs/patterns/sites-pitchkit-creator-identity--creator-identity-public.tsx +0 -96
  119. package/docs/patterns/sites-pitchkit-insights-and-kit--creator-insights-loading.tsx +0 -1006
  120. package/docs/patterns/sites-pitchkit-insights-and-kit--creator-insights.tsx +0 -1031
  121. package/docs/patterns/sites-pitchkit-insights-and-kit--insufficient-audience-data.tsx +0 -1015
  122. package/docs/patterns/sites-pitchkit-insights-and-kit--insufficient-reach-and-audience-data.tsx +0 -1017
  123. package/docs/patterns/sites-pitchkit-insights-and-kit--insufficient-reach-data.tsx +0 -1033
  124. package/docs/patterns/sites-pitchkit-insights-and-kit--owner-pitch-kit.tsx +0 -838
  125. package/docs/patterns/sites-pitchkit-insights-and-kit--shareable-pitch-kit.tsx +0 -608
  126. package/docs/patterns/sites-pitchkit-intro--intro-owner.tsx +0 -161
  127. package/docs/patterns/sites-pitchkit-intro--intro-public.tsx +0 -111
  128. package/docs/patterns/sites-pitchkit-past-brands--past-brands-owner.tsx +0 -611
  129. package/docs/patterns/sites-pitchkit-past-brands--past-brands-public.tsx +0 -299
  130. package/docs/patterns/sites-pitchkit-theme-picker--theme-picker-owner.tsx +0 -832
  131. package/docs/patterns/sites-whatmatters-intake--start-a-project-pattern.tsx +0 -234
  132. package/docs/patterns/sites-whatmatters-marketing-landing--marketing-landing.tsx +0 -87
  133. package/docs/patterns/sites-whatmatters-prompt-chat--landing-to-chat.tsx +0 -899
  134. package/docs/patterns/sites-whatmatters-rfp-submitted--rfp-submitted.tsx +0 -302
@@ -1,265 +0,0 @@
1
- // @thewhatmatters/wmds@0.2.0 · Pattern — account settings (owner)
2
- // Storybook: Sites/PitchKit/Account settings → Pattern — account settings (owner) (?path=/story/sites-pitchkit-account-settings--account-settings-owner)
3
- // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
-
5
- import { useState } from "react";
6
- import {
7
- AlertDialog,
8
- Avatar,
9
- Badge,
10
- Button,
11
- Card,
12
- Chip,
13
- Dialog,
14
- Dropdown,
15
- TextLink,
16
- Toaster,
17
- cardTitleClasses,
18
- toast,
19
- } from "@thewhatmatters/wmds";
20
-
21
- const compactNumber = new Intl.NumberFormat("en", {
22
- notation: "compact",
23
- maximumFractionDigits: 1,
24
- });
25
-
26
-
27
- export interface PitchKitCreatorIdentity {
28
- displayName?: string;
29
- /** Without the @ — shown as @handle, shared as /k/[handle]. */
30
- handle: string;
31
- profilePictureUrl?: string;
32
- followersCount?: number;
33
- professionalAccount?: "Business" | "Creator";
34
- connected?: boolean;
35
- lastSyncedLabel?: string;
36
- }
37
-
38
- function CreatorIdentityStrip({
39
- identity,
40
- nameAs = "h1",
41
- showProfessionalChip = false,
42
- }: {
43
- identity: PitchKitCreatorIdentity;
44
- nameAs?: "h1" | "p";
45
- showProfessionalChip?: boolean;
46
- }) {
47
- const NameTag = nameAs;
48
- const avatarName = identity.displayName ?? identity.handle;
49
- const handleLabel = `@${identity.handle}`;
50
- const followerLabel =
51
- identity.followersCount == null
52
- ? null
53
- : `${compactNumber.format(identity.followersCount)} followers`;
54
- const meta = [handleLabel, followerLabel].filter(Boolean).join(" · ");
55
- const showTitleRow =
56
- identity.displayName != null ||
57
- (showProfessionalChip && identity.professionalAccount != null);
58
-
59
- return (
60
- <div className="flex flex-wrap items-center gap-4">
61
- <Avatar
62
- name={avatarName}
63
- src={identity.profilePictureUrl}
64
- size="lg"
65
- />
66
- <div className="flex min-w-0 flex-col gap-1">
67
- {showTitleRow ? (
68
- <div className="flex flex-wrap items-center gap-2">
69
- {identity.displayName != null ? (
70
- <NameTag className="type-heading-2 text-fg">
71
- {identity.displayName}
72
- </NameTag>
73
- ) : null}
74
- {showProfessionalChip && identity.professionalAccount != null ? (
75
- <Chip readOnly size="sm">
76
- {identity.professionalAccount}
77
- </Chip>
78
- ) : null}
79
- </div>
80
- ) : null}
81
- <p className="type-body text-fg text-muted">{meta}</p>
82
- </div>
83
- </div>
84
- );
85
- }
86
-
87
-
88
- function copyShareKitUrl(handle: string) {
89
- const path = `/k/${handle}`;
90
- void navigator.clipboard.writeText(path);
91
- toast.add({
92
- title: "Kit URL copied",
93
- description: path,
94
- tone: "success",
95
- });
96
- }
97
-
98
- function AccountSettingsDialog({
99
- identity,
100
- open,
101
- onOpenChange,
102
- }: {
103
- identity: PitchKitCreatorIdentity;
104
- open: boolean;
105
- onOpenChange: (open: boolean) => void;
106
- }) {
107
- return (
108
- <Dialog open={open} onOpenChange={onOpenChange}>
109
- <Dialog.Content size="md" title="Account settings">
110
- <div className="flex w-full min-w-0 flex-col gap-4">
111
- <Card variant="outlined" shape="rounded" bodyTerminal className="col-span-full">
112
- <Card.Header
113
- start={<h2 className={cardTitleClasses}>Connected Instagram</h2>}
114
- end={
115
- identity.connected ? (
116
- <Badge variant="success" emphasis="muted" size="sm">
117
- Connected
118
- </Badge>
119
- ) : null
120
- }
121
- />
122
- <Card.Body>
123
- <div className="flex min-w-0 flex-col gap-4 px-3.5 py-[16px]">
124
- <CreatorIdentityStrip
125
- identity={identity}
126
- nameAs="p"
127
- showProfessionalChip
128
- />
129
- {identity.lastSyncedLabel != null ? (
130
- <p className="type-supporting text-muted text-muted">
131
- Last synced {identity.lastSyncedLabel}
132
- </p>
133
- ) : null}
134
- </div>
135
- </Card.Body>
136
- </Card>
137
- </div>
138
- </Dialog.Content>
139
- </Dialog>
140
- );
141
- }
142
-
143
- function OwnerAccountMenu({ identity }: { identity: PitchKitCreatorIdentity }) {
144
- const [menuOpen, setMenuOpen] = useState(false);
145
- const [settingsOpen, setSettingsOpen] = useState(false);
146
- const [deleteOpen, setDeleteOpen] = useState(false);
147
-
148
- function handleAction(actionId: string) {
149
- setMenuOpen(false);
150
- if (actionId === "settings") {
151
- setSettingsOpen(true);
152
- return;
153
- }
154
- if (actionId === "share") {
155
- copyShareKitUrl(identity.handle);
156
- return;
157
- }
158
- if (actionId === "delete") {
159
- setDeleteOpen(true);
160
- }
161
- }
162
-
163
- return (
164
- <>
165
- <div className="relative">
166
- <Button
167
- type="button"
168
- role="ghost"
169
- size="sm"
170
- aria-label="My account"
171
- aria-haspopup="menu"
172
- aria-expanded={menuOpen}
173
- className="size-9 min-h-9 gap-0 px-0 py-0 focus-visible:ring-offset-0"
174
- onClick={() => setMenuOpen((open) => !open)}
175
- >
176
- <Avatar
177
- name={identity.displayName ?? identity.handle}
178
- src={identity.profilePictureUrl}
179
- size="md"
180
- />
181
- </Button>
182
- {menuOpen ? (
183
- <Dropdown.Menu
184
- role="menu"
185
- aria-label="My account"
186
- className="absolute end-0 top-full mt-1 min-w-56"
187
- >
188
- <li role="presentation">
189
- <p className="type-supporting font-medium uppercase tracking-wider text-muted px-3.5 py-2">My account</p>
190
- </li>
191
- <li role="presentation">
192
- <Dropdown.Item role="menuitem" truncate={false} onClick={() => handleAction("settings")}>
193
- Account settings
194
- </Dropdown.Item>
195
- </li>
196
- <li role="presentation">
197
- <Dropdown.Item role="menuitem" truncate={false} onClick={() => handleAction("share")}>
198
- Share kit
199
- </Dropdown.Item>
200
- </li>
201
- <li role="separator" className="mx-1.5 my-0.5 border-0 border-t border-border" />
202
- <li role="presentation">
203
- <Dropdown.Item role="menuitem" truncate={false} onClick={() => handleAction("signout")}>
204
- Sign out
205
- </Dropdown.Item>
206
- </li>
207
- <li role="presentation">
208
- <Dropdown.Item role="menuitem" truncate={false} onClick={() => handleAction("disconnect")}>
209
- Disconnect
210
- </Dropdown.Item>
211
- </li>
212
- <li role="presentation">
213
- <Dropdown.Item role="menuitem" truncate={false} onClick={() => handleAction("delete")}>Delete</Dropdown.Item>
214
- </li>
215
- </Dropdown.Menu>
216
- ) : null}
217
- </div>
218
- <AccountSettingsDialog
219
- identity={identity}
220
- open={settingsOpen}
221
- onOpenChange={setSettingsOpen}
222
- />
223
- <AlertDialog
224
- open={deleteOpen}
225
- onOpenChange={setDeleteOpen}
226
- title="Delete your Pitchkit account?"
227
- description="This permanently deletes your kit, stored media copies, and connection. Your Instagram account is not deleted. This cannot be undone."
228
- cancelLabel="Cancel"
229
- confirmLabel="Delete account"
230
- confirmRole="destructive"
231
- onConfirm={() => setDeleteOpen(false)}
232
- />
233
- </>
234
- );
235
- }
236
-
237
- function PitchKitPageFooter() {
238
- return (
239
- <div className="band pb-6 pt-10">
240
- <footer className="col-span-full flex items-center justify-center gap-4">
241
- <TextLink href="/privacy">Privacy</TextLink>
242
- <TextLink href="mailto:hello@whatmatters.com">Support</TextLink>
243
- </footer>
244
- </div>
245
- );
246
- }
247
-
248
-
249
- export function AccountSettingsOwnerPage({ identity }: { identity: PitchKitCreatorIdentity }) {
250
- return (
251
- <main className="grid-page min-h-screen bg-body [--grid-column-gap:8px] [--grid-max:1140px] [padding-bottom:44px]">
252
- <div className="band pb-4">
253
- <header className="col-span-full grid grid-cols-[1fr_auto_1fr] items-center gap-3">
254
- <span className="type-heading-4 text-fg text-fg">PitchKit</span>
255
- <span />
256
- <span className="justify-self-end">
257
- <OwnerAccountMenu identity={identity} />
258
- </span>
259
- </header>
260
- </div>
261
- <PitchKitPageFooter />
262
- <Toaster position="bottom-right" />
263
- </main>
264
- );
265
- }
@@ -1,154 +0,0 @@
1
- // @thewhatmatters/wmds@0.2.0 · Pattern — creator identity (owner settings)
2
- // Storybook: Sites/PitchKit/Creator identity → Pattern — creator identity (owner settings) (?path=/story/sites-pitchkit-creator-identity--creator-identity-owner-settings)
3
- // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
-
5
- import { Avatar, Badge, Button, Card, Chip, PageHeader, TextLink, Toaster, cardTitleClasses, toast } from "@thewhatmatters/wmds";
6
- import { Copy } from "lucide-react";
7
-
8
- const compactNumber = new Intl.NumberFormat("en", {
9
- notation: "compact",
10
- maximumFractionDigits: 1,
11
- });
12
-
13
-
14
- export interface PitchKitCreatorIdentity {
15
- displayName?: string;
16
- /** Without the @ — shown as @handle, shared as /k/[handle]. */
17
- handle: string;
18
- profilePictureUrl?: string;
19
- followersCount?: number;
20
- professionalAccount?: "Business" | "Creator";
21
- connected?: boolean;
22
- lastSyncedLabel?: string;
23
- }
24
-
25
- function CreatorIdentityStrip({
26
- identity,
27
- nameAs = "h1",
28
- showProfessionalChip = false,
29
- }: {
30
- identity: PitchKitCreatorIdentity;
31
- nameAs?: "h1" | "p";
32
- showProfessionalChip?: boolean;
33
- }) {
34
- const NameTag = nameAs;
35
- const avatarName = identity.displayName ?? identity.handle;
36
- const handleLabel = `@${identity.handle}`;
37
- const followerLabel =
38
- identity.followersCount == null
39
- ? null
40
- : `${compactNumber.format(identity.followersCount)} followers`;
41
- const meta = [handleLabel, followerLabel].filter(Boolean).join(" · ");
42
- const showTitleRow =
43
- identity.displayName != null ||
44
- (showProfessionalChip && identity.professionalAccount != null);
45
-
46
- return (
47
- <div className="flex flex-wrap items-center gap-4">
48
- <Avatar
49
- name={avatarName}
50
- src={identity.profilePictureUrl}
51
- size="lg"
52
- />
53
- <div className="flex min-w-0 flex-col gap-1">
54
- {showTitleRow ? (
55
- <div className="flex flex-wrap items-center gap-2">
56
- {identity.displayName != null ? (
57
- <NameTag className="type-heading-2 text-fg">
58
- {identity.displayName}
59
- </NameTag>
60
- ) : null}
61
- {showProfessionalChip && identity.professionalAccount != null ? (
62
- <Chip readOnly size="sm">
63
- {identity.professionalAccount}
64
- </Chip>
65
- ) : null}
66
- </div>
67
- ) : null}
68
- <p className="type-body text-fg text-muted">{meta}</p>
69
- </div>
70
- </div>
71
- );
72
- }
73
-
74
-
75
- export function CreatorIdentityOwnerSettingsPage({ identity }: { identity: PitchKitCreatorIdentity }) {
76
- const sharePath = `/k/${identity.handle}`;
77
-
78
- function copyShareKitUrl() {
79
- void navigator.clipboard.writeText(sharePath);
80
- toast.add({
81
- title: "Kit URL copied",
82
- description: sharePath,
83
- tone: "success",
84
- });
85
- }
86
-
87
- return (
88
- <main className="grid-page min-h-screen bg-body [--grid-column-gap:8px] [--grid-max:1140px] [padding-bottom:44px]">
89
- <div className="band pb-4">
90
- <header className="col-span-full grid grid-cols-[1fr_auto_1fr] items-center gap-3">
91
- <span className="type-heading-4 text-fg text-fg">PitchKit</span>
92
- <span />
93
- <span className="justify-self-end">
94
- <Avatar
95
- name={identity.displayName ?? identity.handle}
96
- src={identity.profilePictureUrl}
97
- size="md"
98
- />
99
- </span>
100
- </header>
101
- </div>
102
-
103
- <div className="band pt-6 sm:pt-8">
104
- <div className="band min-w-0 gap-y-6 sm:gap-y-8">
105
- <section className="col-span-full">
106
- <PageHeader variant="page" title="Settings" />
107
- <div className="flex max-w-2xl flex-col gap-1">
108
- <p className="type-body text-fg text-muted">
109
- Instagram connection for this PitchKit.
110
- </p>
111
- </div>
112
- </section>
113
-
114
- <Card variant="outlined" shape="rounded" bodyTerminal className="col-span-full">
115
- <Card.Header
116
- start={<h2 className={cardTitleClasses}>Connected Instagram</h2>}
117
- end={
118
- identity.connected ? (
119
- <Badge variant="success" emphasis="muted" size="sm">
120
- Connected
121
- </Badge>
122
- ) : null
123
- }
124
- />
125
- <Card.Body>
126
- <div className="flex min-w-0 flex-col gap-4 px-3.5 py-[16px]">
127
- <CreatorIdentityStrip
128
- identity={identity}
129
- nameAs="p"
130
- showProfessionalChip
131
- />
132
- <div className="flex min-w-0 flex-col gap-2">
133
- <span className="type-supporting font-medium uppercase tracking-wider text-muted text-muted">Share kit</span>
134
- <div className="flex min-w-0 flex-wrap items-center gap-3">
135
- <TextLink href={sharePath}>{sharePath}</TextLink>
136
- <Button role="secondary" size="sm" icon={<Copy />} onClick={copyShareKitUrl}>
137
- Copy
138
- </Button>
139
- </div>
140
- </div>
141
- {identity.lastSyncedLabel != null ? (
142
- <p className="type-supporting text-muted text-muted">
143
- Last synced {identity.lastSyncedLabel}
144
- </p>
145
- ) : null}
146
- </div>
147
- </Card.Body>
148
- </Card>
149
- </div>
150
- </div>
151
- <Toaster position="bottom-right" />
152
- </main>
153
- );
154
- }
@@ -1,96 +0,0 @@
1
- // @thewhatmatters/wmds@0.2.0 · Pattern — creator identity (public)
2
- // Storybook: Sites/PitchKit/Creator identity → Pattern — creator identity (public) (?path=/story/sites-pitchkit-creator-identity--creator-identity-public)
3
- // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
-
5
- import { Avatar, Chip } from "@thewhatmatters/wmds";
6
-
7
- const compactNumber = new Intl.NumberFormat("en", {
8
- notation: "compact",
9
- maximumFractionDigits: 1,
10
- });
11
-
12
-
13
- export interface PitchKitCreatorIdentity {
14
- displayName?: string;
15
- /** Without the @ — shown as @handle, shared as /k/[handle]. */
16
- handle: string;
17
- profilePictureUrl?: string;
18
- followersCount?: number;
19
- professionalAccount?: "Business" | "Creator";
20
- connected?: boolean;
21
- lastSyncedLabel?: string;
22
- }
23
-
24
- function CreatorIdentityStrip({
25
- identity,
26
- nameAs = "h1",
27
- showProfessionalChip = false,
28
- }: {
29
- identity: PitchKitCreatorIdentity;
30
- nameAs?: "h1" | "p";
31
- showProfessionalChip?: boolean;
32
- }) {
33
- const NameTag = nameAs;
34
- const avatarName = identity.displayName ?? identity.handle;
35
- const handleLabel = `@${identity.handle}`;
36
- const followerLabel =
37
- identity.followersCount == null
38
- ? null
39
- : `${compactNumber.format(identity.followersCount)} followers`;
40
- const meta = [handleLabel, followerLabel].filter(Boolean).join(" · ");
41
- const showTitleRow =
42
- identity.displayName != null ||
43
- (showProfessionalChip && identity.professionalAccount != null);
44
-
45
- return (
46
- <div className="flex flex-wrap items-center gap-4">
47
- <Avatar
48
- name={avatarName}
49
- src={identity.profilePictureUrl}
50
- size="lg"
51
- />
52
- <div className="flex min-w-0 flex-col gap-1">
53
- {showTitleRow ? (
54
- <div className="flex flex-wrap items-center gap-2">
55
- {identity.displayName != null ? (
56
- <NameTag className="type-heading-2 text-fg">
57
- {identity.displayName}
58
- </NameTag>
59
- ) : null}
60
- {showProfessionalChip && identity.professionalAccount != null ? (
61
- <Chip readOnly size="sm">
62
- {identity.professionalAccount}
63
- </Chip>
64
- ) : null}
65
- </div>
66
- ) : null}
67
- <p className="type-body text-fg text-muted">{meta}</p>
68
- </div>
69
- </div>
70
- );
71
- }
72
-
73
-
74
- export function CreatorIdentityPublicPage({ identity }: { identity: PitchKitCreatorIdentity }) {
75
- return (
76
- <main className="grid-page min-h-screen bg-body [--grid-column-gap:8px] [--grid-max:1140px] [padding-bottom:44px]">
77
- <div className="band pb-4">
78
- <header className="col-span-full grid grid-cols-[1fr_auto_1fr] items-center gap-3">
79
- <span className="type-heading-4 text-fg text-fg">PitchKit</span>
80
- </header>
81
- </div>
82
-
83
- <div className="band pt-6 sm:pt-8">
84
- <div className="band min-w-0 gap-y-6 sm:gap-y-8">
85
- <section className="col-span-full border-b border-border pb-6">
86
- <CreatorIdentityStrip
87
- identity={identity}
88
- nameAs="h1"
89
- showProfessionalChip
90
- />
91
- </section>
92
- </div>
93
- </div>
94
- </main>
95
- );
96
- }