@fayz-ai/plugin-marketing 0.2.0 → 0.2.1
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/dist/MarketingContext.d.ts +1 -0
- package/dist/MarketingContext.d.ts.map +1 -1
- package/dist/MarketingPage.d.ts +5 -1
- package/dist/MarketingPage.d.ts.map +1 -1
- package/dist/components/icons.d.ts +4 -0
- package/dist/components/icons.d.ts.map +1 -1
- package/dist/data/contentMedia.d.ts +3 -0
- package/dist/data/contentMedia.d.ts.map +1 -0
- package/dist/data/contentMock.d.ts +3 -0
- package/dist/data/contentMock.d.ts.map +1 -0
- package/dist/data/contentSupabase.d.ts +3 -0
- package/dist/data/contentSupabase.d.ts.map +1 -0
- package/dist/data/contentTypes.d.ts +111 -0
- package/dist/data/contentTypes.d.ts.map +1 -0
- package/dist/index.cjs +2776 -129
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2778 -133
- package/dist/index.js.map +1 -1
- package/dist/locales/en.d.ts.map +1 -1
- package/dist/locales/pt-BR.d.ts.map +1 -1
- package/dist/migrations/index.d.ts +4 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/presets.d.ts +2 -0
- package/dist/presets.d.ts.map +1 -1
- package/dist/schema/index.d.ts +717 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema.cjs +65 -0
- package/dist/schema.cjs.map +1 -0
- package/dist/schema.js +61 -0
- package/dist/schema.js.map +1 -0
- package/dist/views/content/ContentPlannerContext.d.ts +13 -0
- package/dist/views/content/ContentPlannerContext.d.ts.map +1 -0
- package/dist/views/content/ContentView.d.ts +5 -0
- package/dist/views/content/ContentView.d.ts.map +1 -0
- package/dist/views/content/PlanBriefView.d.ts +12 -0
- package/dist/views/content/PlanBriefView.d.ts.map +1 -0
- package/dist/views/content/PostPage.d.ts +6 -0
- package/dist/views/content/PostPage.d.ts.map +1 -0
- package/dist/views/content/PostSocialPreview.d.ts +11 -0
- package/dist/views/content/PostSocialPreview.d.ts.map +1 -0
- package/dist/views/content/RecordingChecklist.d.ts +6 -0
- package/dist/views/content/RecordingChecklist.d.ts.map +1 -0
- package/dist/views/content/contentBits.d.ts +28 -0
- package/dist/views/content/contentBits.d.ts.map +1 -0
- package/dist/views/content/contentStore.d.ts +28 -0
- package/dist/views/content/contentStore.d.ts.map +1 -0
- package/dist/views/content/templates.d.ts +3 -0
- package/dist/views/content/templates.d.ts.map +1 -0
- package/package.json +14 -4
- package/src/MarketingContext.tsx +1 -0
- package/src/MarketingPage.tsx +23 -3
- package/src/components/icons.tsx +19 -0
- package/src/data/contentMedia.ts +25 -0
- package/src/data/contentMock.ts +253 -0
- package/src/data/contentSupabase.ts +262 -0
- package/src/data/contentTypes.ts +138 -0
- package/src/index.ts +55 -2
- package/src/locales/en.ts +95 -0
- package/src/locales/pt-BR.ts +95 -0
- package/src/migrations/001_content_planner.sql +94 -0
- package/src/migrations/002_multi_platform.sql +25 -0
- package/src/migrations/003_recording_ops.sql +25 -0
- package/src/migrations/index.ts +152 -0
- package/src/presets.ts +5 -3
- package/src/schema/index.ts +69 -0
- package/src/views/content/ContentPlannerContext.tsx +13 -0
- package/src/views/content/ContentView.tsx +901 -0
- package/src/views/content/PlanBriefView.tsx +268 -0
- package/src/views/content/PostPage.tsx +370 -0
- package/src/views/content/PostSocialPreview.tsx +212 -0
- package/src/views/content/RecordingChecklist.tsx +145 -0
- package/src/views/content/contentBits.tsx +114 -0
- package/src/views/content/contentStore.ts +160 -0
- package/src/views/content/templates.ts +172 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Builders come from @fayz-ai/db (single drizzle-orm instance) — never import
|
|
2
|
+
// pgTable/uuid directly from drizzle-orm/pg-core. See MIGRATION-ARCHITECTURE §6.
|
|
3
|
+
import {
|
|
4
|
+
pgTable, uuid, text, boolean, integer, date, jsonb, index,
|
|
5
|
+
tenantId, timestamps, createdAt,
|
|
6
|
+
} from '@fayz-ai/db'
|
|
7
|
+
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Marketing plugin — Ring-1 schema (schema-as-code), content planner tables.
|
|
10
|
+
// RLS policies + grants are companion SQL (Drizzle doesn't diff those) —
|
|
11
|
+
// see src/migrations/001_content_planner.sql.
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
export const mktSocialAccounts = pgTable('mkt_social_accounts', {
|
|
15
|
+
id: uuid('id').primaryKey().defaultRandom(),
|
|
16
|
+
tenantId: tenantId(),
|
|
17
|
+
name: text('name').notNull(),
|
|
18
|
+
handle: text('handle'),
|
|
19
|
+
// One account, many platform connections (Instagram, YouTube, TikTok, ...)
|
|
20
|
+
platforms: text('platforms').array().notNull().default(['instagram']),
|
|
21
|
+
isActive: boolean('is_active').notNull().default(true),
|
|
22
|
+
...createdAt,
|
|
23
|
+
}, (t) => [index('idx_mkt_social_accounts_tenant').on(t.tenantId)])
|
|
24
|
+
|
|
25
|
+
export const mktContentPlans = pgTable('mkt_content_plans', {
|
|
26
|
+
id: uuid('id').primaryKey().defaultRandom(),
|
|
27
|
+
tenantId: tenantId(),
|
|
28
|
+
accountId: uuid('account_id').notNull().references(() => mktSocialAccounts.id, { onDelete: 'cascade' }),
|
|
29
|
+
name: text('name').notNull(),
|
|
30
|
+
status: text('status').notNull().default('active'),
|
|
31
|
+
weeksCount: integer('weeks_count').notNull().default(8),
|
|
32
|
+
startDate: date('start_date'),
|
|
33
|
+
objective: text('objective'),
|
|
34
|
+
tone: text('tone'),
|
|
35
|
+
pillars: jsonb('pillars').notNull().default([]),
|
|
36
|
+
formats: jsonb('formats').notNull().default([]),
|
|
37
|
+
weeklyFrequency: integer('weekly_frequency').notNull().default(3),
|
|
38
|
+
briefMd: text('brief_md').notNull().default(''),
|
|
39
|
+
...timestamps,
|
|
40
|
+
}, (t) => [
|
|
41
|
+
index('idx_mkt_content_plans_tenant').on(t.tenantId),
|
|
42
|
+
index('idx_mkt_content_plans_account').on(t.accountId),
|
|
43
|
+
])
|
|
44
|
+
|
|
45
|
+
export const mktContentPosts = pgTable('mkt_content_posts', {
|
|
46
|
+
id: uuid('id').primaryKey().defaultRandom(),
|
|
47
|
+
tenantId: tenantId(),
|
|
48
|
+
planId: uuid('plan_id').notNull().references(() => mktContentPlans.id, { onDelete: 'cascade' }),
|
|
49
|
+
weekNumber: integer('week_number').notNull().default(1),
|
|
50
|
+
position: integer('position').notNull().default(0),
|
|
51
|
+
title: text('title').notNull(),
|
|
52
|
+
format: text('format').notNull().default('reel'),
|
|
53
|
+
status: text('status').notNull().default('idea'),
|
|
54
|
+
scheduledDate: date('scheduled_date'),
|
|
55
|
+
// Target platforms for this post; empty = inherit the account's platforms
|
|
56
|
+
platforms: text('platforms').array().notNull().default([]),
|
|
57
|
+
// Recording-day checklist [{ id, text, done }]
|
|
58
|
+
checklist: jsonb('checklist').notNull().default([]),
|
|
59
|
+
// Uploaded asset (static posts: caption + final art instead of a script)
|
|
60
|
+
mediaUrl: text('media_url'),
|
|
61
|
+
hook: text('hook'),
|
|
62
|
+
cta: text('cta'),
|
|
63
|
+
contentMd: text('content_md').notNull().default(''),
|
|
64
|
+
...timestamps,
|
|
65
|
+
}, (t) => [
|
|
66
|
+
index('idx_mkt_content_posts_tenant').on(t.tenantId),
|
|
67
|
+
index('idx_mkt_content_posts_plan').on(t.planId, t.weekNumber, t.position),
|
|
68
|
+
index('idx_mkt_content_posts_status').on(t.tenantId, t.status),
|
|
69
|
+
])
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createPluginContext } from '@fayz-ai/saas'
|
|
2
|
+
import type { ResolvedMarketingConfig } from '../../MarketingContext'
|
|
3
|
+
import type { ContentPlannerProvider } from '../../data/contentTypes'
|
|
4
|
+
import type { ContentPlannerUIState } from './contentStore'
|
|
5
|
+
|
|
6
|
+
// Separate context trio for the content planner — MarketingContext's generics
|
|
7
|
+
// are fixed to the analytics provider/store, so the planner mounts its own.
|
|
8
|
+
const ctx = createPluginContext<ResolvedMarketingConfig, ContentPlannerProvider, ContentPlannerUIState>('ContentPlanner')
|
|
9
|
+
|
|
10
|
+
export const ContentPlannerContextProvider = ctx.ContextProvider
|
|
11
|
+
export const useContentPlannerConfig = ctx.useConfig
|
|
12
|
+
export const useContentPlannerProvider = ctx.useProvider
|
|
13
|
+
export const useContentPlannerStore = ctx.useStore
|