@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.
- package/CHANGELOG.md +10 -0
- package/CONSUMING.md +4 -4
- package/README.md +3 -3
- package/dist/styles.css +1 -1
- package/docs/component-contracts.md +1 -1
- package/docs/components.md +6 -6
- package/docs/exports.json +1 -13
- package/docs/patterns/components-avatar--dropdown-row.tsx +1 -1
- package/docs/patterns/components-badge--with-avatar.tsx +1 -1
- package/docs/patterns/components-button-button--destructive-action.tsx +1 -1
- package/docs/patterns/components-button-button--ghost-action.tsx +1 -1
- package/docs/patterns/components-button-button--inverse-action.tsx +1 -1
- package/docs/patterns/components-button-button--link-render.tsx +1 -1
- package/docs/patterns/components-button-button--multi-state-badge.tsx +1 -1
- package/docs/patterns/components-button-button--outline-mono.tsx +1 -1
- package/docs/patterns/components-button-button--primary-action.tsx +1 -1
- package/docs/patterns/components-button-button--row-hug.tsx +1 -1
- package/docs/patterns/components-button-button--row-layout.tsx +1 -1
- package/docs/patterns/components-button-button--secondary-action.tsx +1 -1
- package/docs/patterns/components-button-button--suggestion-pills.tsx +1 -1
- package/docs/patterns/components-button-button--with-count.tsx +1 -1
- package/docs/patterns/components-button-button--with-icon.tsx +1 -1
- package/docs/patterns/components-button-floatingactionbutton--vertical-actions.tsx +1 -1
- package/docs/patterns/components-calembed--pattern-skip-in-footer.tsx +1 -1
- package/docs/patterns/components-card-card--body-slot-occupancy-history.tsx +1 -1
- package/docs/patterns/components-card-card--headerless-media.tsx +1 -1
- package/docs/patterns/components-card-card--outlined-layout.tsx +1 -1
- package/docs/patterns/components-card-card--pinned-height.tsx +1 -1
- package/docs/patterns/components-card-selectablecard--selectable-cards-pattern.tsx +1 -1
- package/docs/patterns/components-chart--audience-activity-heatmap.tsx +1 -1
- package/docs/patterns/components-chart--cartesian-no-data-gaps.tsx +1 -1
- package/docs/patterns/components-chart--occupancy-history-in-card.tsx +1 -1
- package/docs/patterns/components-chart--occupancy-in-card.tsx +1 -1
- package/docs/patterns/components-chart--post-reach-distribution.tsx +1 -1
- package/docs/patterns/components-chart--ranked-audience-breakdown.tsx +1 -1
- package/docs/patterns/components-chart--unit-grid-composition.tsx +1 -1
- package/docs/patterns/components-chatqa--pattern-qa-with-reply.tsx +1 -1
- package/docs/patterns/components-checkbox-checkbox--default.tsx +1 -1
- package/docs/patterns/components-checkbox-checkbox--with-description.tsx +1 -1
- package/docs/patterns/components-checkbox-checkboxgroup--default.tsx +1 -1
- package/docs/patterns/components-dialog--alert-dialog-destructive.tsx +1 -1
- package/docs/patterns/components-dialog--default-dialog.tsx +1 -1
- package/docs/patterns/components-dialog--form-dialog.tsx +1 -1
- package/docs/patterns/components-displaycontrols--page-utilities.tsx +1 -1
- package/docs/patterns/components-field--horizontal-input.tsx +1 -1
- package/docs/patterns/components-field--horizontal-text-area.tsx +1 -1
- package/docs/patterns/components-field--multi-control.tsx +1 -1
- package/docs/patterns/components-footerreveal--marketing-hero-pattern.tsx +1 -1
- package/docs/patterns/components-footerreveal--marketing-hero-ruled-pattern.tsx +1 -1
- package/docs/patterns/components-footerreveal--marketing-hero-with-gallery-intro.tsx +1 -1
- package/docs/patterns/components-footerreveal--marketing-page-pattern.tsx +1 -1
- package/docs/patterns/components-footerreveal--ruled-grid-footer-pattern.tsx +1 -1
- package/docs/patterns/components-footerreveal--sequenced-marketing-hero.tsx +1 -1
- package/docs/patterns/components-herointro--two-line-intro.tsx +1 -1
- package/docs/patterns/components-herotilestack--marketing-hero-pattern.tsx +1 -1
- package/docs/patterns/components-herotilestack--marketing-hero-text-sequence.tsx +1 -1
- package/docs/patterns/components-herotilestack--marketing-hero-with-gallery-intro.tsx +1 -1
- package/docs/patterns/components-intakeconfirmation--booked-pattern.tsx +1 -1
- package/docs/patterns/components-intakeconfirmation--emailed-pattern.tsx +1 -1
- package/docs/patterns/components-intakeform--about-you-pattern.tsx +1 -1
- package/docs/patterns/components-intakemodal--intake-modal-pattern.tsx +1 -1
- package/docs/patterns/components-kbd--command-row.tsx +1 -1
- package/docs/patterns/components-kbd--numbered-choices.tsx +1 -1
- package/docs/patterns/components-kbd--shortcut.tsx +1 -1
- package/docs/patterns/components-moremenu--action-menu.tsx +1 -1
- package/docs/patterns/components-moremenu--in-card-header.tsx +1 -1
- package/docs/patterns/components-navlist--side-nav-settings.tsx +1 -1
- package/docs/patterns/components-pageheader--app-header-pattern.tsx +1 -1
- package/docs/patterns/components-pageheader--page-section-header.tsx +1 -1
- package/docs/patterns/components-pageheader--toolbar-header.tsx +1 -1
- package/docs/patterns/components-panel--end-detail-rail.tsx +1 -1
- package/docs/patterns/components-pillgroup--pill-group-pattern.tsx +1 -1
- package/docs/patterns/components-promptbar--pattern-marketing-composer.tsx +3 -3
- package/docs/patterns/components-promptbar--pattern-prompt-bar.tsx +1 -1
- package/docs/patterns/components-radio-radiogroup--default.tsx +1 -1
- package/docs/patterns/components-scrollhorizontal--project-gallery-pattern.tsx +1 -1
- package/docs/patterns/components-scrollhorizontal--with-intro.tsx +1 -1
- package/docs/patterns/components-sheet--bottom-sheet.tsx +1 -1
- package/docs/patterns/components-sheet--end-sheet.tsx +1 -1
- package/docs/patterns/components-sitenav--brand-and-cta.tsx +1 -1
- package/docs/patterns/components-sitenav--centered-links.tsx +1 -1
- package/docs/patterns/components-sitenav--compact.tsx +1 -1
- package/docs/patterns/components-sitenav--marketing-header.tsx +1 -1
- package/docs/patterns/components-sitenav--mega-menu.tsx +1 -1
- package/docs/patterns/components-stat--insights-row.tsx +1 -1
- package/docs/patterns/components-stepprogress--step-progress-pattern.tsx +1 -1
- package/docs/patterns/components-switch--default.tsx +1 -1
- package/docs/patterns/components-switch--settings-row.tsx +1 -1
- package/docs/patterns/components-tab--settings-pages.tsx +1 -1
- package/docs/patterns/components-taskrows--action-details.tsx +1 -1
- package/docs/patterns/components-taskrows--capsules.tsx +1 -1
- package/docs/patterns/components-taskrows--card-with-status-rows.tsx +1 -1
- package/docs/patterns/components-taskrows--controlled-expand.tsx +1 -1
- package/docs/patterns/components-taskrows--custom-slots.tsx +1 -1
- package/docs/patterns/components-taskrows--status-list.tsx +1 -1
- package/docs/patterns/components-taskrows--tag-chips.tsx +1 -1
- package/docs/patterns/components-textlink--external-destination.tsx +1 -1
- package/docs/patterns/components-textlink--inline-prose.tsx +1 -1
- package/docs/patterns/components-textlink--supporting-copy.tsx +1 -1
- package/docs/patterns/components-textsequence--default.tsx +1 -1
- package/docs/patterns/components-textsequence--reduced-motion.tsx +1 -1
- package/docs/patterns/components-textsequence--shapes.tsx +1 -1
- package/docs/patterns/components-toast--stacked-notifications.tsx +1 -1
- package/docs/patterns/components-tooltip--controlled.tsx +1 -1
- package/docs/patterns/components-tooltip--disabled-control.tsx +1 -1
- package/docs/patterns/components-tooltip--icon-action.tsx +1 -1
- package/docs/patterns/components-tooltip--keyboard-shortcut.tsx +1 -1
- package/docs/patterns/components-tooltip--placement.tsx +1 -1
- package/docs/patterns/foundations-scroll-fade--horizontal-rail.tsx +1 -1
- package/docs/patterns/foundations-scroll-fade--overflowing-list.tsx +1 -1
- package/docs/patterns/guides-chart-explorations--comparison-gallery.tsx +1 -1
- package/docs/patterns/guides-overlay-flows--notification-preferences.tsx +1 -1
- package/docs/patterns/guides-profile-typography--editorial-profile.tsx +1 -1
- package/docs/patterns/index.json +1 -153
- package/package.json +1 -1
- package/docs/patterns/sites-pitchkit-account-settings--account-settings-owner.tsx +0 -265
- package/docs/patterns/sites-pitchkit-creator-identity--creator-identity-owner-settings.tsx +0 -154
- package/docs/patterns/sites-pitchkit-creator-identity--creator-identity-public.tsx +0 -96
- package/docs/patterns/sites-pitchkit-insights-and-kit--creator-insights-loading.tsx +0 -1006
- package/docs/patterns/sites-pitchkit-insights-and-kit--creator-insights.tsx +0 -1031
- package/docs/patterns/sites-pitchkit-insights-and-kit--insufficient-audience-data.tsx +0 -1015
- package/docs/patterns/sites-pitchkit-insights-and-kit--insufficient-reach-and-audience-data.tsx +0 -1017
- package/docs/patterns/sites-pitchkit-insights-and-kit--insufficient-reach-data.tsx +0 -1033
- package/docs/patterns/sites-pitchkit-insights-and-kit--owner-pitch-kit.tsx +0 -838
- package/docs/patterns/sites-pitchkit-insights-and-kit--shareable-pitch-kit.tsx +0 -608
- package/docs/patterns/sites-pitchkit-intro--intro-owner.tsx +0 -161
- package/docs/patterns/sites-pitchkit-intro--intro-public.tsx +0 -111
- package/docs/patterns/sites-pitchkit-past-brands--past-brands-owner.tsx +0 -611
- package/docs/patterns/sites-pitchkit-past-brands--past-brands-public.tsx +0 -299
- package/docs/patterns/sites-pitchkit-theme-picker--theme-picker-owner.tsx +0 -832
- package/docs/patterns/sites-whatmatters-intake--start-a-project-pattern.tsx +0 -234
- package/docs/patterns/sites-whatmatters-marketing-landing--marketing-landing.tsx +0 -87
- package/docs/patterns/sites-whatmatters-prompt-chat--landing-to-chat.tsx +0 -899
- 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
|
-
}
|