@fayz-ai/plugin-sites 0.9.0 → 0.9.2
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/README.md +4 -4
- package/package.json +4 -6
- package/src/index.ts +0 -52
- package/src/views/SitesHome.tsx +0 -82
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @fayz-ai/plugin-sites
|
|
2
2
|
|
|
3
|
-
> **Status: experimental (incubating).** Not capability-complete — missing some or all of the capability bar (data-provider contract w/ supabase+mock pair, entity registries, settings, migrations; see `docs/PLUGIN-PATTERNS.md`). Fine to explore in dogfoods; NOT ready for fresh installs or generated apps, and its API may change without notice.
|
|
3
|
+
> **Status: experimental (incubating).** Not capability-complete — missing some or all of the capability bar (data-provider contract w/ supabase+mock pair, entity registries, settings, migrations; see `docs/plugins/PLUGIN-PATTERNS.md`). Fine to explore in dogfoods; NOT ready for fresh installs or generated apps, and its API may change without notice.
|
|
4
4
|
|
|
5
5
|
> Websites, funnels, and landing pages — built into the same app as your CRM.
|
|
6
6
|
|
|
@@ -28,7 +28,7 @@ Peer deps: `react`, `react-dom`. Runtime deps: `@fayz-ai/core`, `@fayz-ai/ui`.
|
|
|
28
28
|
|
|
29
29
|
## Usage
|
|
30
30
|
```tsx
|
|
31
|
-
import { defineSaas } from '@fayz-ai/
|
|
31
|
+
import { defineSaas } from '@fayz-ai/admin'
|
|
32
32
|
import { createSitesPlugin } from '@fayz-ai/plugin-sites'
|
|
33
33
|
|
|
34
34
|
export const app = defineSaas({
|
|
@@ -43,7 +43,7 @@ export const app = defineSaas({
|
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
## Part of the Fayz SDK
|
|
46
|
-
One of the composable plugins for `@fayz-ai/
|
|
46
|
+
One of the composable plugins for `@fayz-ai/admin` — this one owns the convert surface: funnels, landing pages, and websites.
|
|
47
47
|
|
|
48
48
|
## Roadmap & contributing
|
|
49
|
-
Built and evolving in the open. See the [Fayz SDK roadmap](../../docs/ROADMAP.md#plugin-sites) for current gaps, missing features, and good first issues.
|
|
49
|
+
Built and evolving in the open. See the [Fayz SDK roadmap](../../docs/platform/ROADMAP.md#plugin-sites) for current gaps, missing features, and good first issues.
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"fayz": {
|
|
4
4
|
"status": "preview"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.9.
|
|
6
|
+
"version": "0.9.2",
|
|
7
7
|
"description": "[experimental] Fayz SDK — sites, funnels & landing pages plugin",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"sideEffects": false,
|
|
@@ -12,14 +12,12 @@
|
|
|
12
12
|
"types": "./dist/index.d.ts",
|
|
13
13
|
"exports": {
|
|
14
14
|
".": {
|
|
15
|
-
"source": "./src/index.ts",
|
|
16
15
|
"types": "./dist/index.d.ts",
|
|
17
16
|
"import": "./dist/index.js"
|
|
18
17
|
}
|
|
19
18
|
},
|
|
20
19
|
"files": [
|
|
21
|
-
"dist"
|
|
22
|
-
"src"
|
|
20
|
+
"dist"
|
|
23
21
|
],
|
|
24
22
|
"peerDependencies": {
|
|
25
23
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -27,8 +25,8 @@
|
|
|
27
25
|
"lucide-react": ">=0.400.0 <1.0.0"
|
|
28
26
|
},
|
|
29
27
|
"dependencies": {
|
|
30
|
-
"@fayz-ai/core": "^0.
|
|
31
|
-
"@fayz-ai/ui": "^0.
|
|
28
|
+
"@fayz-ai/core": "^0.11.0",
|
|
29
|
+
"@fayz-ai/ui": "^0.11.0"
|
|
32
30
|
},
|
|
33
31
|
"devDependencies": {
|
|
34
32
|
"@types/react": "^18.3.0",
|
package/src/index.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import type { PluginManifest, PluginScope, VerticalId } from '@fayz-ai/core'
|
|
3
|
-
import { SitesHome } from './views/SitesHome'
|
|
4
|
-
|
|
5
|
-
// ---------------------------------------------------------------------------
|
|
6
|
-
// @fayz-ai/plugin-sites — websites, funnels & landing pages (GoHighLevel "Sites").
|
|
7
|
-
// Universal plugin. M1 ships a rich mock home; the drag-and-drop page builder
|
|
8
|
-
// (block system from architecture-v2 + public surfaces) ships in a later milestone.
|
|
9
|
-
// ---------------------------------------------------------------------------
|
|
10
|
-
|
|
11
|
-
export interface SitesPluginOptions {
|
|
12
|
-
navPosition?: number
|
|
13
|
-
navSection?: 'main' | 'secondary' | 'settings'
|
|
14
|
-
navLabel?: string
|
|
15
|
-
scope?: PluginScope
|
|
16
|
-
verticalId?: VerticalId
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function createSitesPlugin(options?: SitesPluginOptions): PluginManifest {
|
|
20
|
-
const PageComponent: React.ComponentType<unknown> = () => React.createElement(SitesHome)
|
|
21
|
-
PageComponent.displayName = 'SitesHome'
|
|
22
|
-
|
|
23
|
-
return {
|
|
24
|
-
id: 'sites',
|
|
25
|
-
name: options?.navLabel ?? 'Sites',
|
|
26
|
-
icon: 'LayoutTemplate',
|
|
27
|
-
version: '1.0.0',
|
|
28
|
-
scope: options?.scope ?? 'universal',
|
|
29
|
-
verticalId: options?.verticalId,
|
|
30
|
-
defaultEnabled: true,
|
|
31
|
-
dependencies: [],
|
|
32
|
-
declaredFeatures: [{ id: 'sites', label: 'Sites & Funnels', group: 'Convert' }],
|
|
33
|
-
navigation: [
|
|
34
|
-
{
|
|
35
|
-
section: options?.navSection ?? 'main',
|
|
36
|
-
position: options?.navPosition ?? 7,
|
|
37
|
-
label: options?.navLabel ?? 'Sites',
|
|
38
|
-
route: '/sites',
|
|
39
|
-
icon: 'LayoutTemplate',
|
|
40
|
-
permission: { feature: 'sites', action: 'read' as const },
|
|
41
|
-
},
|
|
42
|
-
],
|
|
43
|
-
routes: [
|
|
44
|
-
{
|
|
45
|
-
path: '/sites',
|
|
46
|
-
component: PageComponent,
|
|
47
|
-
permission: { feature: 'sites', action: 'read' as const },
|
|
48
|
-
},
|
|
49
|
-
],
|
|
50
|
-
widgets: [],
|
|
51
|
-
}
|
|
52
|
-
}
|
package/src/views/SitesHome.tsx
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { Plus, ExternalLink, MousePointerClick, Eye, Globe, Layers, FileText } from 'lucide-react'
|
|
3
|
-
import { Button, PageHeaderActions } from '@fayz-ai/ui'
|
|
4
|
-
|
|
5
|
-
interface Site {
|
|
6
|
-
id: string
|
|
7
|
-
name: string
|
|
8
|
-
type: 'Funnel' | 'Website' | 'Landing page'
|
|
9
|
-
status: 'Published' | 'Draft'
|
|
10
|
-
visits: number
|
|
11
|
-
conversion: number
|
|
12
|
-
accent: string
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const SITES: Site[] = [
|
|
16
|
-
{ id: '1', name: 'Free Consultation Funnel', type: 'Funnel', status: 'Published', visits: 3820, conversion: 12.4, accent: '#6366f1' },
|
|
17
|
-
{ id: '2', name: 'Summer Promo Landing', type: 'Landing page', status: 'Published', visits: 1560, conversion: 8.1, accent: '#ec4899' },
|
|
18
|
-
{ id: '3', name: 'Agency Website', type: 'Website', status: 'Published', visits: 9240, conversion: 3.2, accent: '#0ea5e9' },
|
|
19
|
-
{ id: '4', name: 'Webinar Registration', type: 'Funnel', status: 'Draft', visits: 0, conversion: 0, accent: '#f59e0b' },
|
|
20
|
-
{ id: '5', name: 'Lead Magnet — Ebook', type: 'Landing page', status: 'Draft', visits: 0, conversion: 0, accent: '#14b8a6' },
|
|
21
|
-
]
|
|
22
|
-
|
|
23
|
-
const TYPE_ICON = { Funnel: Layers, Website: Globe, 'Landing page': FileText } as const
|
|
24
|
-
|
|
25
|
-
function Stat({ icon: Icon, label, value }: { icon: React.ComponentType<{ className?: string }>; label: string; value: string }) {
|
|
26
|
-
return (
|
|
27
|
-
<div className="rounded-card border border-border bg-card p-4">
|
|
28
|
-
<div className="flex items-center gap-2 text-muted-foreground">
|
|
29
|
-
<Icon className="h-4 w-4" /><span className="text-xs font-medium">{label}</span>
|
|
30
|
-
</div>
|
|
31
|
-
<p className="mt-2 text-2xl font-semibold text-foreground">{value}</p>
|
|
32
|
-
</div>
|
|
33
|
-
)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function SitesHome() {
|
|
37
|
-
return (
|
|
38
|
-
<div className="mx-auto max-w-6xl p-6">
|
|
39
|
-
<PageHeaderActions>
|
|
40
|
-
<Button><Plus className="mr-1.5 h-4 w-4" /> New funnel</Button>
|
|
41
|
-
</PageHeaderActions>
|
|
42
|
-
|
|
43
|
-
<div className="mt-6 grid grid-cols-2 gap-4 lg:grid-cols-4">
|
|
44
|
-
<Stat icon={Eye} label="Total visits (30d)" value="14,620" />
|
|
45
|
-
<Stat icon={MousePointerClick} label="Avg. conversion" value="7.1%" />
|
|
46
|
-
<Stat icon={Layers} label="Published funnels" value="3" />
|
|
47
|
-
<Stat icon={FileText} label="Leads captured" value="1,038" />
|
|
48
|
-
</div>
|
|
49
|
-
|
|
50
|
-
<div className="mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
|
51
|
-
{SITES.map((s) => {
|
|
52
|
-
const Icon = TYPE_ICON[s.type]
|
|
53
|
-
return (
|
|
54
|
-
<div key={s.id} className="group overflow-hidden rounded-card border border-border bg-card">
|
|
55
|
-
<div className="flex h-28 items-center justify-center" style={{ backgroundColor: `${s.accent}1a` }}>
|
|
56
|
-
<Icon className="h-8 w-8" style={{ color: s.accent }} />
|
|
57
|
-
</div>
|
|
58
|
-
<div className="p-4">
|
|
59
|
-
<div className="flex items-center justify-between">
|
|
60
|
-
<span className="text-xs font-medium text-muted-foreground">{s.type}</span>
|
|
61
|
-
<span className={`rounded-full px-2 py-0.5 text-xs font-medium ${s.status === 'Published' ? 'bg-emerald-100 text-emerald-700' : 'bg-muted text-muted-foreground'}`}>{s.status}</span>
|
|
62
|
-
</div>
|
|
63
|
-
<p className="mt-1 text-sm font-semibold text-foreground">{s.name}</p>
|
|
64
|
-
<div className="mt-3 flex items-center justify-between text-xs text-muted-foreground">
|
|
65
|
-
<span>{s.visits.toLocaleString()} visits</span>
|
|
66
|
-
<span>{s.conversion}% conv.</span>
|
|
67
|
-
</div>
|
|
68
|
-
<Button variant="outline" size="sm" className="mt-3 w-full">
|
|
69
|
-
<ExternalLink className="mr-1.5 h-3.5 w-3.5" /> Open editor
|
|
70
|
-
</Button>
|
|
71
|
-
</div>
|
|
72
|
-
</div>
|
|
73
|
-
)
|
|
74
|
-
})}
|
|
75
|
-
</div>
|
|
76
|
-
|
|
77
|
-
<p className="mt-4 text-center text-xs text-muted-foreground">
|
|
78
|
-
Mock preview · the drag-and-drop page builder (block system + public surfaces) ships in a later milestone.
|
|
79
|
-
</p>
|
|
80
|
-
</div>
|
|
81
|
-
)
|
|
82
|
-
}
|