@fayz-ai/plugin-linkinbio 0.9.0-next.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/LICENSE +21 -0
- package/README.md +52 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/public/BioPage.d.ts +8 -0
- package/dist/public/BioPage.d.ts.map +1 -0
- package/dist/public/BioPageRenderer.d.ts +11 -0
- package/dist/public/BioPageRenderer.d.ts.map +1 -0
- package/dist/public/__tests__/manifest.test.d.ts +2 -0
- package/dist/public/__tests__/manifest.test.d.ts.map +1 -0
- package/dist/public/blocks/BioSection.d.ts +7 -0
- package/dist/public/blocks/BioSection.d.ts.map +1 -0
- package/dist/public/blocks/CTASection.d.ts +7 -0
- package/dist/public/blocks/CTASection.d.ts.map +1 -0
- package/dist/public/blocks/EmbedSection.d.ts +7 -0
- package/dist/public/blocks/EmbedSection.d.ts.map +1 -0
- package/dist/public/blocks/FeaturedBlock.d.ts +7 -0
- package/dist/public/blocks/FeaturedBlock.d.ts.map +1 -0
- package/dist/public/blocks/GallerySection.d.ts +7 -0
- package/dist/public/blocks/GallerySection.d.ts.map +1 -0
- package/dist/public/blocks/HeroSection.d.ts +9 -0
- package/dist/public/blocks/HeroSection.d.ts.map +1 -0
- package/dist/public/blocks/LinksBlock.d.ts +7 -0
- package/dist/public/blocks/LinksBlock.d.ts.map +1 -0
- package/dist/public/blocks/MusicReleasesBlock.d.ts +7 -0
- package/dist/public/blocks/MusicReleasesBlock.d.ts.map +1 -0
- package/dist/public/blocks/ProfileHeader.d.ts +8 -0
- package/dist/public/blocks/ProfileHeader.d.ts.map +1 -0
- package/dist/public/blocks/ProjectSection.d.ts +7 -0
- package/dist/public/blocks/ProjectSection.d.ts.map +1 -0
- package/dist/public/blocks/SocialLinksSection.d.ts +7 -0
- package/dist/public/blocks/SocialLinksSection.d.ts.map +1 -0
- package/dist/public/blocks/StatsSection.d.ts +7 -0
- package/dist/public/blocks/StatsSection.d.ts.map +1 -0
- package/dist/public/blocks/TextSection.d.ts +7 -0
- package/dist/public/blocks/TextSection.d.ts.map +1 -0
- package/dist/public/blocks/TourDatesBlock.d.ts +7 -0
- package/dist/public/blocks/TourDatesBlock.d.ts.map +1 -0
- package/dist/public/blocks/VenueListSection.d.ts +7 -0
- package/dist/public/blocks/VenueListSection.d.ts.map +1 -0
- package/dist/public/blocks/VideoGridSection.d.ts +7 -0
- package/dist/public/blocks/VideoGridSection.d.ts.map +1 -0
- package/dist/public/blocks/index.d.ts +17 -0
- package/dist/public/blocks/index.d.ts.map +1 -0
- package/dist/public/components/Carousel.d.ts +11 -0
- package/dist/public/components/Carousel.d.ts.map +1 -0
- package/dist/public/components/MediaKit.d.ts +6 -0
- package/dist/public/components/MediaKit.d.ts.map +1 -0
- package/dist/public/components/PlatformIcon.d.ts +9 -0
- package/dist/public/components/PlatformIcon.d.ts.map +1 -0
- package/dist/public/components/Reveal.d.ts +13 -0
- package/dist/public/components/Reveal.d.ts.map +1 -0
- package/dist/public/context.d.ts +18 -0
- package/dist/public/context.d.ts.map +1 -0
- package/dist/public/createPublicLinkInBioPlugin.d.ts +38 -0
- package/dist/public/createPublicLinkInBioPlugin.d.ts.map +1 -0
- package/dist/public/data.d.ts +11 -0
- package/dist/public/data.d.ts.map +1 -0
- package/dist/public/data.supabase.d.ts +11 -0
- package/dist/public/data.supabase.d.ts.map +1 -0
- package/dist/public/index.d.ts +18 -0
- package/dist/public/index.d.ts.map +1 -0
- package/dist/public/index.js +1965 -0
- package/dist/public/index.js.map +1 -0
- package/dist/public/registry.d.ts +17 -0
- package/dist/public/registry.d.ts.map +1 -0
- package/dist/public/utils.d.ts +9 -0
- package/dist/public/utils.d.ts.map +1 -0
- package/dist/types.d.ts +264 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +69 -0
- package/src/index.ts +56 -0
- package/src/public/BioPage.tsx +123 -0
- package/src/public/BioPageRenderer.tsx +251 -0
- package/src/public/__tests__/manifest.test.ts +39 -0
- package/src/public/blocks/BioSection.tsx +66 -0
- package/src/public/blocks/CTASection.tsx +56 -0
- package/src/public/blocks/EmbedSection.tsx +53 -0
- package/src/public/blocks/FeaturedBlock.tsx +70 -0
- package/src/public/blocks/GallerySection.tsx +148 -0
- package/src/public/blocks/HeroSection.tsx +107 -0
- package/src/public/blocks/LinksBlock.tsx +80 -0
- package/src/public/blocks/MusicReleasesBlock.tsx +83 -0
- package/src/public/blocks/ProfileHeader.tsx +174 -0
- package/src/public/blocks/ProjectSection.tsx +158 -0
- package/src/public/blocks/SocialLinksSection.tsx +125 -0
- package/src/public/blocks/StatsSection.tsx +46 -0
- package/src/public/blocks/TextSection.tsx +29 -0
- package/src/public/blocks/TourDatesBlock.tsx +83 -0
- package/src/public/blocks/VenueListSection.tsx +91 -0
- package/src/public/blocks/VideoGridSection.tsx +105 -0
- package/src/public/blocks/index.ts +16 -0
- package/src/public/components/Carousel.tsx +90 -0
- package/src/public/components/MediaKit.tsx +249 -0
- package/src/public/components/PlatformIcon.tsx +56 -0
- package/src/public/components/Reveal.tsx +58 -0
- package/src/public/context.tsx +30 -0
- package/src/public/createPublicLinkInBioPlugin.ts +81 -0
- package/src/public/data.supabase.ts +31 -0
- package/src/public/data.ts +29 -0
- package/src/public/index.ts +75 -0
- package/src/public/registry.ts +40 -0
- package/src/public/utils.ts +102 -0
- package/src/types.ts +337 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
export interface BioMediaItem {
|
|
2
|
+
type: 'image' | 'video' | 'audio';
|
|
3
|
+
url: string;
|
|
4
|
+
thumbnailUrl?: string;
|
|
5
|
+
alt?: string;
|
|
6
|
+
caption?: string;
|
|
7
|
+
aspectRatio?: '1:1' | '4:3' | '16:9' | '9:16' | '3:4';
|
|
8
|
+
}
|
|
9
|
+
export interface BioSocialLink {
|
|
10
|
+
platform: 'instagram' | 'spotify' | 'soundcloud' | 'youtube' | 'tiktok' | 'whatsapp' | 'email' | 'twitter' | 'facebook' | 'bandcamp' | 'mixcloud' | 'beatport' | 'apple-music' | 'deezer' | 'telegram' | 'website' | 'drive' | 'custom';
|
|
11
|
+
url: string;
|
|
12
|
+
label?: string;
|
|
13
|
+
icon?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface BioBranding {
|
|
16
|
+
primaryColor: string;
|
|
17
|
+
secondaryColor: string;
|
|
18
|
+
accentColor: string;
|
|
19
|
+
backgroundColor: string;
|
|
20
|
+
textColor: string;
|
|
21
|
+
mutedTextColor: string;
|
|
22
|
+
fontHeading?: string;
|
|
23
|
+
fontBody?: string;
|
|
24
|
+
logoUrl?: string;
|
|
25
|
+
backgroundImageUrl?: string;
|
|
26
|
+
borderRadius?: 'none' | 'sm' | 'md' | 'lg' | 'full';
|
|
27
|
+
sectionAltBg?: string;
|
|
28
|
+
sectionAltBg2?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface BioFloatingCTA {
|
|
31
|
+
label: string;
|
|
32
|
+
url: string;
|
|
33
|
+
}
|
|
34
|
+
export interface BioIdentity {
|
|
35
|
+
name: string;
|
|
36
|
+
slug: string;
|
|
37
|
+
tagline?: string;
|
|
38
|
+
genres: string[];
|
|
39
|
+
location?: string;
|
|
40
|
+
pronouns?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface BioSEO {
|
|
43
|
+
title?: string;
|
|
44
|
+
description?: string;
|
|
45
|
+
ogImageUrl?: string;
|
|
46
|
+
}
|
|
47
|
+
interface BioBlockBase {
|
|
48
|
+
id: string;
|
|
49
|
+
label?: string;
|
|
50
|
+
title?: string;
|
|
51
|
+
visible?: boolean;
|
|
52
|
+
}
|
|
53
|
+
export interface HeroSection extends BioBlockBase {
|
|
54
|
+
type: 'hero';
|
|
55
|
+
backgroundImageUrl: string;
|
|
56
|
+
backgroundImageUrls?: string[];
|
|
57
|
+
overlayGradient?: string;
|
|
58
|
+
layout?: 'centered' | 'bottom-left' | 'bottom-center' | 'split';
|
|
59
|
+
showLogo?: boolean;
|
|
60
|
+
showGenres?: boolean;
|
|
61
|
+
showLocation?: boolean;
|
|
62
|
+
ctaText?: string;
|
|
63
|
+
ctaUrl?: string;
|
|
64
|
+
}
|
|
65
|
+
export interface BioSection extends BioBlockBase {
|
|
66
|
+
type: 'bio';
|
|
67
|
+
content: string;
|
|
68
|
+
imageUrl?: string;
|
|
69
|
+
imagePosition?: 'left' | 'right' | 'top' | 'none';
|
|
70
|
+
}
|
|
71
|
+
export interface GallerySection extends BioBlockBase {
|
|
72
|
+
type: 'gallery';
|
|
73
|
+
media: BioMediaItem[];
|
|
74
|
+
layout?: 'grid' | 'masonry' | 'carousel' | 'featured-grid';
|
|
75
|
+
columns?: 2 | 3 | 4;
|
|
76
|
+
}
|
|
77
|
+
export interface VideoGridSection extends BioBlockBase {
|
|
78
|
+
type: 'video-grid';
|
|
79
|
+
videos: {
|
|
80
|
+
platform: 'youtube' | 'vimeo';
|
|
81
|
+
videoId: string;
|
|
82
|
+
title?: string;
|
|
83
|
+
thumbnailUrl?: string;
|
|
84
|
+
}[];
|
|
85
|
+
layout?: 'grid' | 'list' | 'featured';
|
|
86
|
+
channelUrl?: string;
|
|
87
|
+
}
|
|
88
|
+
export interface SocialLinksSection extends BioBlockBase {
|
|
89
|
+
type: 'social-links';
|
|
90
|
+
links: BioSocialLink[];
|
|
91
|
+
layout?: 'icons' | 'buttons' | 'list';
|
|
92
|
+
}
|
|
93
|
+
export interface EmbedSection extends BioBlockBase {
|
|
94
|
+
type: 'embed';
|
|
95
|
+
embedType: 'soundcloud' | 'spotify' | 'youtube' | 'bandcamp' | 'mixcloud' | 'custom';
|
|
96
|
+
embedUrl: string;
|
|
97
|
+
embedHtml?: string;
|
|
98
|
+
aspectRatio?: '1:1' | '16:9' | 'auto';
|
|
99
|
+
height?: number;
|
|
100
|
+
}
|
|
101
|
+
export interface ProjectSection extends BioBlockBase {
|
|
102
|
+
type: 'project';
|
|
103
|
+
content?: string;
|
|
104
|
+
media?: BioMediaItem[];
|
|
105
|
+
links?: {
|
|
106
|
+
label: string;
|
|
107
|
+
url: string;
|
|
108
|
+
}[];
|
|
109
|
+
date?: string;
|
|
110
|
+
tags?: string[];
|
|
111
|
+
layout?: 'card' | 'full-width' | 'side-by-side';
|
|
112
|
+
}
|
|
113
|
+
export interface StatsSection extends BioBlockBase {
|
|
114
|
+
type: 'stats';
|
|
115
|
+
stats: {
|
|
116
|
+
value: string;
|
|
117
|
+
label: string;
|
|
118
|
+
icon?: string;
|
|
119
|
+
}[];
|
|
120
|
+
layout?: 'row' | 'grid';
|
|
121
|
+
}
|
|
122
|
+
export interface VenueListSection extends BioBlockBase {
|
|
123
|
+
type: 'venue-list';
|
|
124
|
+
venues: {
|
|
125
|
+
name: string;
|
|
126
|
+
city?: string;
|
|
127
|
+
country?: string;
|
|
128
|
+
logoUrl?: string;
|
|
129
|
+
year?: string;
|
|
130
|
+
}[];
|
|
131
|
+
layout?: 'grid' | 'list' | 'logo-cloud';
|
|
132
|
+
}
|
|
133
|
+
export interface CTASection extends BioBlockBase {
|
|
134
|
+
type: 'cta';
|
|
135
|
+
content?: string;
|
|
136
|
+
whatsappNumber?: string;
|
|
137
|
+
whatsappMessage?: string;
|
|
138
|
+
email?: string;
|
|
139
|
+
bookingUrl?: string;
|
|
140
|
+
ctaButtons: {
|
|
141
|
+
label: string;
|
|
142
|
+
url: string;
|
|
143
|
+
variant?: 'primary' | 'secondary' | 'outline';
|
|
144
|
+
icon?: string;
|
|
145
|
+
}[];
|
|
146
|
+
}
|
|
147
|
+
export interface TextSection extends BioBlockBase {
|
|
148
|
+
type: 'text';
|
|
149
|
+
content: string;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Full-bleed profile header: hero/portrait image with the name overlaid, an
|
|
153
|
+
* optional social-icon row, and optional quick-nav pills that scroll to blocks
|
|
154
|
+
* by id. This is the top block of a `link-hub` page.
|
|
155
|
+
*/
|
|
156
|
+
export interface ProfileHeaderSection extends BioBlockBase {
|
|
157
|
+
type: 'profile-header';
|
|
158
|
+
imageUrl?: string;
|
|
159
|
+
/**
|
|
160
|
+
* Push the cover image down the page — a reusable framing knob per creator.
|
|
161
|
+
* Any CSS length (e.g. '6vh', '3rem'); adds space above the hero so the
|
|
162
|
+
* subject isn't jammed against the top edge. Default: none.
|
|
163
|
+
*/
|
|
164
|
+
imageOffsetTop?: string;
|
|
165
|
+
/** CSS object-position for the cover image crop (e.g. 'center 30%'). Default 'center'. */
|
|
166
|
+
imageObjectPosition?: string;
|
|
167
|
+
overlayGradient?: string;
|
|
168
|
+
showLogo?: boolean;
|
|
169
|
+
showGenres?: boolean;
|
|
170
|
+
showLocation?: boolean;
|
|
171
|
+
/** Social icons under the name. Falls back to page.socialLinks when omitted. */
|
|
172
|
+
socials?: BioSocialLink[];
|
|
173
|
+
/** Quick-nav pills that smooth-scroll to a block id (komi's section nav). */
|
|
174
|
+
navPills?: {
|
|
175
|
+
label: string;
|
|
176
|
+
targetId: string;
|
|
177
|
+
}[];
|
|
178
|
+
}
|
|
179
|
+
/** A single tappable link card (thumbnail + title + subtitle + chevron). */
|
|
180
|
+
export interface LinkCardItem {
|
|
181
|
+
title: string;
|
|
182
|
+
subtitle?: string;
|
|
183
|
+
url: string;
|
|
184
|
+
thumbnailUrl?: string;
|
|
185
|
+
/** lucide icon name or social platform key, used when no thumbnail. */
|
|
186
|
+
icon?: string;
|
|
187
|
+
badge?: string;
|
|
188
|
+
}
|
|
189
|
+
export interface LinksSection extends BioBlockBase {
|
|
190
|
+
type: 'links';
|
|
191
|
+
links: LinkCardItem[];
|
|
192
|
+
layout?: 'list' | 'grid';
|
|
193
|
+
}
|
|
194
|
+
/** A music release (artwork + title + artist + play/listen CTA). */
|
|
195
|
+
export interface MusicReleaseItem {
|
|
196
|
+
title: string;
|
|
197
|
+
artist?: string;
|
|
198
|
+
artworkUrl: string;
|
|
199
|
+
url: string;
|
|
200
|
+
}
|
|
201
|
+
export interface MusicReleasesSection extends BioBlockBase {
|
|
202
|
+
type: 'music-releases';
|
|
203
|
+
releases: MusicReleaseItem[];
|
|
204
|
+
layout?: 'carousel' | 'grid';
|
|
205
|
+
ctaLabel?: string;
|
|
206
|
+
}
|
|
207
|
+
/** A tour date (date chip + venue + city + tickets CTA). */
|
|
208
|
+
export interface TourDateItem {
|
|
209
|
+
/** ISO-ish date string, e.g. '2026-07-18'. */
|
|
210
|
+
date: string;
|
|
211
|
+
venue: string;
|
|
212
|
+
city?: string;
|
|
213
|
+
/** Tickets link. With a url → "Ingressos"; without → "Em breve" (or "Esgotado" if soldOut). */
|
|
214
|
+
url?: string;
|
|
215
|
+
soldOut?: boolean;
|
|
216
|
+
}
|
|
217
|
+
export interface TourDatesSection extends BioBlockBase {
|
|
218
|
+
type: 'tour-dates';
|
|
219
|
+
dates: TourDateItem[];
|
|
220
|
+
ctaLabel?: string;
|
|
221
|
+
}
|
|
222
|
+
/** A single large featured link (image + headline + CTA) — komi's "Out Now". */
|
|
223
|
+
export interface FeaturedSection extends BioBlockBase {
|
|
224
|
+
type: 'featured';
|
|
225
|
+
headline: string;
|
|
226
|
+
subtitle?: string;
|
|
227
|
+
imageUrl?: string;
|
|
228
|
+
url: string;
|
|
229
|
+
ctaLabel?: string;
|
|
230
|
+
}
|
|
231
|
+
/** The union of every built-in block. Host-registered niche blocks widen this at runtime. */
|
|
232
|
+
export type BioBlock = HeroSection | BioSection | GallerySection | VideoGridSection | SocialLinksSection | EmbedSection | ProjectSection | StatsSection | VenueListSection | CTASection | TextSection | ProfileHeaderSection | LinksSection | MusicReleasesSection | TourDatesSection | FeaturedSection;
|
|
233
|
+
export interface BioPage {
|
|
234
|
+
identity: BioIdentity;
|
|
235
|
+
branding: BioBranding;
|
|
236
|
+
seo: BioSEO;
|
|
237
|
+
socialLinks: BioSocialLink[];
|
|
238
|
+
/** Ordered content blocks. Named `sections` for backward compat with press_kits.data. */
|
|
239
|
+
sections: BioBlock[];
|
|
240
|
+
floatingCta?: BioFloatingCTA;
|
|
241
|
+
/**
|
|
242
|
+
* Page shell: 'scroll' (default) is the full-bleed EPK/press-kit scroll; 'hub'
|
|
243
|
+
* is the komi/linktree centered narrow column (mobile-first link hub, no
|
|
244
|
+
* alternating section backgrounds).
|
|
245
|
+
*/
|
|
246
|
+
layout?: 'scroll' | 'hub';
|
|
247
|
+
/**
|
|
248
|
+
* Press/media kit — a downloadable-assets modal for bookers. Photos, logo and
|
|
249
|
+
* bio are auto-derived from the page; add `driveUrl` (full kit) and extra
|
|
250
|
+
* `assets` (rider, tech sheet, etc.) here.
|
|
251
|
+
*/
|
|
252
|
+
mediaKit?: {
|
|
253
|
+
driveUrl?: string;
|
|
254
|
+
assets?: {
|
|
255
|
+
label: string;
|
|
256
|
+
url: string;
|
|
257
|
+
kind?: 'image' | 'logo' | 'doc' | 'audio' | 'link';
|
|
258
|
+
}[];
|
|
259
|
+
};
|
|
260
|
+
template?: string;
|
|
261
|
+
updatedAt?: string;
|
|
262
|
+
}
|
|
263
|
+
export {};
|
|
264
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fayz-ai/plugin-linkinbio",
|
|
3
|
+
"fayz": {
|
|
4
|
+
"status": "preview"
|
|
5
|
+
},
|
|
6
|
+
"version": "0.9.0-next.0",
|
|
7
|
+
"description": "Fayz SDK — plugin-linkinbio: komi/linktree-style link-in-bio pages for any creator (public bio page + modular block registry)",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"sideEffects": false,
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"module": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"source": "./src/index.ts",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./public": {
|
|
20
|
+
"source": "./src/public/index.ts",
|
|
21
|
+
"types": "./dist/public/index.d.ts",
|
|
22
|
+
"import": "./dist/public/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"src"
|
|
28
|
+
],
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
31
|
+
"react-dom": "^18.0.0 || ^19.0.0",
|
|
32
|
+
"react-router-dom": "^6.0.0 || ^7.0.0",
|
|
33
|
+
"lucide-react": ">=0.400.0 <1.0.0"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"react-icons": "^5.3.0",
|
|
37
|
+
"@fayz-ai/core": "^0.9.0-next.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/react": "^18.3.0",
|
|
41
|
+
"react": "^18.3.0",
|
|
42
|
+
"react-dom": "^18.3.0",
|
|
43
|
+
"react-router-dom": "^6.30.0",
|
|
44
|
+
"tsup": "^8.2.0",
|
|
45
|
+
"typescript": "^5.5.0",
|
|
46
|
+
"vitest": "^2.1.9",
|
|
47
|
+
"@types/react-dom": "^18.3.0",
|
|
48
|
+
"lucide-react": "^0.400.0"
|
|
49
|
+
},
|
|
50
|
+
"license": "MIT",
|
|
51
|
+
"keywords": [
|
|
52
|
+
"fayz",
|
|
53
|
+
"fayz-plugin",
|
|
54
|
+
"fayz-sdk",
|
|
55
|
+
"link-in-bio",
|
|
56
|
+
"linktree",
|
|
57
|
+
"komi"
|
|
58
|
+
],
|
|
59
|
+
"publishConfig": {
|
|
60
|
+
"access": "public"
|
|
61
|
+
},
|
|
62
|
+
"scripts": {
|
|
63
|
+
"build": "tsup && tsc --emitDeclarationOnly --declaration --declarationMap --noEmit false",
|
|
64
|
+
"dev": "tsup --watch",
|
|
65
|
+
"typecheck": "tsc --noEmit",
|
|
66
|
+
"clean": "rm -rf dist",
|
|
67
|
+
"test": "vitest run"
|
|
68
|
+
}
|
|
69
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// @fayz-ai/plugin-linkinbio — admin entry (v1 stub).
|
|
3
|
+
//
|
|
4
|
+
// The public bio page ships today via the `/public` entry
|
|
5
|
+
// (createPublicLinkInBioPlugin). The in-app editor / settings surface is a v2
|
|
6
|
+
// follow-up: this factory returns a minimal manifest with a placeholder view so
|
|
7
|
+
// the plugin can be listed in an admin shell without shipping the editor yet.
|
|
8
|
+
//
|
|
9
|
+
// For the customer-facing page, import from '@fayz-ai/plugin-linkinbio/public'.
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
import { createElement } from 'react';
|
|
12
|
+
import type { PluginManifest, PluginScope, VerticalId } from '@fayz-ai/core';
|
|
13
|
+
|
|
14
|
+
export interface LinkInBioPluginOptions {
|
|
15
|
+
basePath?: string;
|
|
16
|
+
scope?: PluginScope;
|
|
17
|
+
verticalId?: VerticalId;
|
|
18
|
+
defaultEnabled?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function EditorPlaceholder() {
|
|
22
|
+
return createElement(
|
|
23
|
+
'div',
|
|
24
|
+
{ className: 'p-8 text-sm text-muted-foreground' },
|
|
25
|
+
'O editor de Link in Bio chega no v2. A página pública já está disponível em /p/:slug.',
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function createLinkInBioPlugin(options: LinkInBioPluginOptions = {}): PluginManifest {
|
|
30
|
+
const basePath = options.basePath ?? '/link-in-bio';
|
|
31
|
+
return {
|
|
32
|
+
id: 'linkinbio',
|
|
33
|
+
name: 'Link in Bio',
|
|
34
|
+
icon: 'Link',
|
|
35
|
+
version: '0.1.0',
|
|
36
|
+
scope: options.scope ?? 'universal',
|
|
37
|
+
verticalId: options.verticalId,
|
|
38
|
+
scaffolds: ['saas', 'website'],
|
|
39
|
+
defaultEnabled: options.defaultEnabled ?? false,
|
|
40
|
+
dependencies: [],
|
|
41
|
+
navigation: [{ section: 'main', position: 10, label: 'Link in Bio', route: basePath, icon: 'Link' }],
|
|
42
|
+
routes: [{ path: basePath, component: EditorPlaceholder, guard: 'authenticated' }],
|
|
43
|
+
widgets: [],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export type {
|
|
48
|
+
BioPage,
|
|
49
|
+
BioBlock,
|
|
50
|
+
BioBranding,
|
|
51
|
+
BioIdentity,
|
|
52
|
+
BioSEO,
|
|
53
|
+
BioSocialLink,
|
|
54
|
+
BioMediaItem,
|
|
55
|
+
BioFloatingCTA,
|
|
56
|
+
} from './types';
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { useParams } from 'react-router-dom';
|
|
3
|
+
import type { BioPage as BioPageType } from '../types';
|
|
4
|
+
import { getBrandingVars } from './utils';
|
|
5
|
+
import BioPageRenderer from './BioPageRenderer';
|
|
6
|
+
import { useLinkInBio } from './context';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Public bio-page route component. Reads `:slug` from the URL, resolves the page
|
|
10
|
+
* from the data provider, applies SEO + dynamic Google Fonts + branding CSS vars,
|
|
11
|
+
* and renders the block list. Mounted by the plugin manifest as a guard:'public'
|
|
12
|
+
* route (default path `/p/:slug`).
|
|
13
|
+
*/
|
|
14
|
+
export default function BioPage() {
|
|
15
|
+
const { slug } = useParams<{ slug: string }>();
|
|
16
|
+
const { provider, poweredBy, titleSuffix } = useLinkInBio();
|
|
17
|
+
const [page, setPage] = useState<BioPageType | null>(null);
|
|
18
|
+
const [resolved, setResolved] = useState(false);
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (!slug) {
|
|
22
|
+
setResolved(true);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
let cancelled = false;
|
|
26
|
+
setResolved(false);
|
|
27
|
+
provider
|
|
28
|
+
.getBySlug(slug)
|
|
29
|
+
.then((pk) => {
|
|
30
|
+
if (cancelled) return;
|
|
31
|
+
setPage(pk);
|
|
32
|
+
setResolved(true);
|
|
33
|
+
})
|
|
34
|
+
.catch(() => {
|
|
35
|
+
if (cancelled) return;
|
|
36
|
+
setResolved(true);
|
|
37
|
+
});
|
|
38
|
+
return () => {
|
|
39
|
+
cancelled = true;
|
|
40
|
+
};
|
|
41
|
+
}, [slug, provider]);
|
|
42
|
+
|
|
43
|
+
// Set document title & load custom fonts
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (!page) return;
|
|
46
|
+
|
|
47
|
+
// SEO
|
|
48
|
+
document.title = page.seo.title ?? `${page.identity.name} | ${titleSuffix}`;
|
|
49
|
+
const metaDesc = document.querySelector('meta[name="description"]');
|
|
50
|
+
if (metaDesc && page.seo.description) {
|
|
51
|
+
metaDesc.setAttribute('content', page.seo.description);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Dynamic Google Fonts loading
|
|
55
|
+
const fontsToLoad: string[] = [];
|
|
56
|
+
const { fontHeading, fontBody } = page.branding;
|
|
57
|
+
if (fontHeading && !fontHeading.includes('Space Grotesk')) {
|
|
58
|
+
const family = fontHeading.replace(/['"]/g, '').split(',')[0].trim();
|
|
59
|
+
fontsToLoad.push(family);
|
|
60
|
+
}
|
|
61
|
+
if (fontBody && !fontBody.includes('DM Sans')) {
|
|
62
|
+
const family = fontBody.replace(/['"]/g, '').split(',')[0].trim();
|
|
63
|
+
fontsToLoad.push(family);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const linkElements: HTMLLinkElement[] = [];
|
|
67
|
+
if (fontsToLoad.length > 0) {
|
|
68
|
+
const families = fontsToLoad.map((f) => `family=${f.replace(/\s/g, '+')}:wght@400;600;700`).join('&');
|
|
69
|
+
const link = document.createElement('link');
|
|
70
|
+
link.rel = 'stylesheet';
|
|
71
|
+
link.href = `https://fonts.googleapis.com/css2?${families}&display=swap`;
|
|
72
|
+
document.head.appendChild(link);
|
|
73
|
+
linkElements.push(link);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return () => {
|
|
77
|
+
linkElements.forEach((el) => el.remove());
|
|
78
|
+
};
|
|
79
|
+
}, [page, titleSuffix]);
|
|
80
|
+
|
|
81
|
+
if (!resolved) {
|
|
82
|
+
return (
|
|
83
|
+
<div className="dark fixed inset-0 flex items-center justify-center bg-background text-foreground">
|
|
84
|
+
<div className="w-2 h-2 rounded-full bg-foreground/40 animate-pulse" aria-label="carregando" />
|
|
85
|
+
</div>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (!page) {
|
|
90
|
+
return (
|
|
91
|
+
<div className="dark fixed inset-0 flex items-center justify-center bg-background text-foreground">
|
|
92
|
+
<div className="text-center px-6">
|
|
93
|
+
<h1 className="text-large font-bold mb-4" style={{ fontFamily: 'var(--font-display)' }}>
|
|
94
|
+
404
|
|
95
|
+
</h1>
|
|
96
|
+
<p className="text-foreground-secondary mb-6">Página não encontrada.</p>
|
|
97
|
+
<a
|
|
98
|
+
href="/"
|
|
99
|
+
className="text-sm underline underline-offset-4 text-foreground-secondary hover:text-foreground transition-colors"
|
|
100
|
+
>
|
|
101
|
+
voltar ao início
|
|
102
|
+
</a>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const brandingVars = getBrandingVars(page.branding);
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<div
|
|
112
|
+
className="fixed inset-0 overflow-y-auto overflow-x-hidden"
|
|
113
|
+
style={{
|
|
114
|
+
...brandingVars,
|
|
115
|
+
backgroundColor: 'var(--pk-bg)',
|
|
116
|
+
color: 'var(--pk-text)',
|
|
117
|
+
fontFamily: 'var(--pk-font-body)',
|
|
118
|
+
} as React.CSSProperties}
|
|
119
|
+
>
|
|
120
|
+
<BioPageRenderer page={page} poweredBy={poweredBy} />
|
|
121
|
+
</div>
|
|
122
|
+
);
|
|
123
|
+
}
|