shared-features 0.0.6 → 0.0.8
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/AI-INTEGRATION-GUIDE.md +315 -0
- package/README.md +2 -0
- package/dist/config/support.d.ts +10 -0
- package/dist/config/support.d.ts.map +1 -0
- package/package.json +8 -4
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
# AI Integration Guide - shared-features
|
|
2
|
+
|
|
3
|
+
Quick reference for AI development agents (Claude Code, Cursor, Copilot, etc.) to integrate shared-features into React + Capacitor projects.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
yarn add shared-features
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Peer Dependencies
|
|
12
|
+
```bash
|
|
13
|
+
yarn add react react-dom firebase @radix-ui/themes zustand lucide-react
|
|
14
|
+
# Optional for mobile:
|
|
15
|
+
yarn add @capacitor/preferences
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Core Concepts
|
|
19
|
+
|
|
20
|
+
shared-features provides two main systems:
|
|
21
|
+
1. **Advertising Campaigns** - Cross-promotion of Zaions products
|
|
22
|
+
2. **Broadcasts/Notifications** - In-app announcements and alerts
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
### 1. Add Environment Variables
|
|
27
|
+
|
|
28
|
+
```env
|
|
29
|
+
VITE_SHARED_FEATURES_API_KEY=
|
|
30
|
+
VITE_SHARED_FEATURES_AUTH_DOMAIN=
|
|
31
|
+
VITE_SHARED_FEATURES_PROJECT_ID=
|
|
32
|
+
VITE_SHARED_FEATURES_STORAGE_BUCKET=
|
|
33
|
+
VITE_SHARED_FEATURES_MESSAGING_SENDER_ID=
|
|
34
|
+
VITE_SHARED_FEATURES_APP_ID=
|
|
35
|
+
VITE_SHARED_FEATURES_MEASUREMENT_ID=
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 2. Initialize
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
// src/main.tsx
|
|
42
|
+
import { initSharedFeatures } from 'shared-features';
|
|
43
|
+
|
|
44
|
+
if (import.meta.env.VITE_SHARED_FEATURES_API_KEY) {
|
|
45
|
+
initSharedFeatures({
|
|
46
|
+
firebaseConfig: {
|
|
47
|
+
apiKey: import.meta.env.VITE_SHARED_FEATURES_API_KEY,
|
|
48
|
+
authDomain: import.meta.env.VITE_SHARED_FEATURES_AUTH_DOMAIN,
|
|
49
|
+
projectId: import.meta.env.VITE_SHARED_FEATURES_PROJECT_ID,
|
|
50
|
+
storageBucket: import.meta.env.VITE_SHARED_FEATURES_STORAGE_BUCKET,
|
|
51
|
+
messagingSenderId: import.meta.env.VITE_SHARED_FEATURES_MESSAGING_SENDER_ID,
|
|
52
|
+
appId: import.meta.env.VITE_SHARED_FEATURES_APP_ID,
|
|
53
|
+
measurementId: import.meta.env.VITE_SHARED_FEATURES_MEASUREMENT_ID,
|
|
54
|
+
},
|
|
55
|
+
projectId: 'your-project-id',
|
|
56
|
+
projectName: 'Your Project Name',
|
|
57
|
+
platform: 'web', // 'web' | 'android' | 'ios' | 'extension'
|
|
58
|
+
debug: import.meta.env.DEV,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Advertising Components
|
|
64
|
+
|
|
65
|
+
### AdPanel (Recommended)
|
|
66
|
+
Best for sidebars and feature areas.
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
import { AdPanel } from 'shared-features';
|
|
70
|
+
|
|
71
|
+
// Small variant (sidebar)
|
|
72
|
+
<AdPanel variant="small" />
|
|
73
|
+
|
|
74
|
+
// Large variant (feature area)
|
|
75
|
+
<AdPanel variant="large" />
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### AdSlider
|
|
79
|
+
Auto-rotating carousel of ads.
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
import { AdSlider } from 'shared-features';
|
|
83
|
+
|
|
84
|
+
<AdSlider
|
|
85
|
+
variant="small"
|
|
86
|
+
autoRotate={true}
|
|
87
|
+
interval={5000}
|
|
88
|
+
/>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### AdBanner
|
|
92
|
+
Horizontal banner for headers/footers.
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
import { AdBanner } from 'shared-features';
|
|
96
|
+
|
|
97
|
+
<AdBanner />
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### AdModal (One-time Welcome)
|
|
101
|
+
Shows once per product, great for onboarding.
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
import { useOneTimeAdModal } from 'shared-features';
|
|
105
|
+
|
|
106
|
+
function App() {
|
|
107
|
+
const { AdModalComponent } = useOneTimeAdModal();
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<>
|
|
111
|
+
{AdModalComponent}
|
|
112
|
+
{/* rest of app */}
|
|
113
|
+
</>
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### AdUpdateModal (What's New)
|
|
119
|
+
Shows once per version update.
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
import { useUpdateAdModal } from 'shared-features';
|
|
123
|
+
|
|
124
|
+
function App() {
|
|
125
|
+
const { UpdateModalComponent } = useUpdateAdModal();
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<>
|
|
129
|
+
{UpdateModalComponent}
|
|
130
|
+
{/* rest of app */}
|
|
131
|
+
</>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Broadcasts/Notifications
|
|
137
|
+
|
|
138
|
+
### BroadcastBanner
|
|
139
|
+
Alert banner at top of page.
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
import { BroadcastBanner } from 'shared-features';
|
|
143
|
+
|
|
144
|
+
<BroadcastBanner position="top" />
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### AnnouncementModal
|
|
148
|
+
Modal announcements.
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
import { AnnouncementModal } from 'shared-features';
|
|
152
|
+
|
|
153
|
+
<AnnouncementModal />
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### useBroadcasts Hook
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
import { useBroadcasts } from 'shared-features';
|
|
160
|
+
|
|
161
|
+
function MyComponent() {
|
|
162
|
+
const { broadcasts, loading, markAsRead, dismissBroadcast } = useBroadcasts();
|
|
163
|
+
|
|
164
|
+
return broadcasts.map(broadcast => (
|
|
165
|
+
<div key={broadcast.id}>
|
|
166
|
+
<h3>{broadcast.title}</h3>
|
|
167
|
+
<p>{broadcast.message}</p>
|
|
168
|
+
<button onClick={() => dismissBroadcast(broadcast.id)}>Dismiss</button>
|
|
169
|
+
</div>
|
|
170
|
+
));
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Hooks Reference
|
|
175
|
+
|
|
176
|
+
| Hook | Description | Returns |
|
|
177
|
+
|------|-------------|---------|
|
|
178
|
+
| `useCampaigns()` | Get active ad campaigns | `{ campaigns, loading, error }` |
|
|
179
|
+
| `useOneTimeAdModal()` | One-time product modal | `{ AdModalComponent }` |
|
|
180
|
+
| `useUpdateAdModal()` | Version update modal | `{ UpdateModalComponent }` |
|
|
181
|
+
| `useBroadcasts()` | Get active broadcasts | `{ broadcasts, loading, markAsRead, dismiss }` |
|
|
182
|
+
|
|
183
|
+
## Services
|
|
184
|
+
|
|
185
|
+
### Analytics Tracking
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
import { trackImpression, trackClick, trackDismissal } from 'shared-features';
|
|
189
|
+
|
|
190
|
+
// Track ad impression
|
|
191
|
+
await trackImpression(campaignId, productId);
|
|
192
|
+
|
|
193
|
+
// Track ad click
|
|
194
|
+
await trackClick(campaignId, productId);
|
|
195
|
+
|
|
196
|
+
// Track dismissal
|
|
197
|
+
await trackDismissal(campaignId);
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Campaigns Service
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
import { getCampaigns, getCampaignById } from 'shared-features';
|
|
204
|
+
|
|
205
|
+
// Get all active campaigns for current project
|
|
206
|
+
const campaigns = await getCampaigns();
|
|
207
|
+
|
|
208
|
+
// Get specific campaign
|
|
209
|
+
const campaign = await getCampaignById('campaign-id');
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Types
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
import type {
|
|
216
|
+
SharedFeaturesConfig,
|
|
217
|
+
Campaign,
|
|
218
|
+
Product,
|
|
219
|
+
Broadcast,
|
|
220
|
+
NotificationTemplate,
|
|
221
|
+
AdVariant,
|
|
222
|
+
Platform,
|
|
223
|
+
} from 'shared-features';
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Configuration Interface
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
interface SharedFeaturesConfig {
|
|
230
|
+
firebaseConfig: {
|
|
231
|
+
apiKey: string;
|
|
232
|
+
authDomain: string;
|
|
233
|
+
projectId: string;
|
|
234
|
+
storageBucket: string;
|
|
235
|
+
messagingSenderId: string;
|
|
236
|
+
appId: string;
|
|
237
|
+
measurementId: string;
|
|
238
|
+
};
|
|
239
|
+
projectId: string; // Your project identifier
|
|
240
|
+
projectName: string; // Display name
|
|
241
|
+
platform: 'web' | 'android' | 'ios' | 'extension';
|
|
242
|
+
debug?: boolean; // Enable debug logging
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Common Patterns
|
|
247
|
+
|
|
248
|
+
### Conditional Rendering (Check Initialization)
|
|
249
|
+
|
|
250
|
+
```tsx
|
|
251
|
+
import { isInitialized } from 'shared-features';
|
|
252
|
+
|
|
253
|
+
function AdSection() {
|
|
254
|
+
if (!isInitialized()) {
|
|
255
|
+
return null; // Don't render until initialized
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return <AdPanel variant="small" />;
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Footer Ad Integration
|
|
263
|
+
|
|
264
|
+
```tsx
|
|
265
|
+
import { AdBanner, isInitialized } from 'shared-features';
|
|
266
|
+
|
|
267
|
+
function Footer() {
|
|
268
|
+
return (
|
|
269
|
+
<footer>
|
|
270
|
+
{isInitialized() && <AdBanner />}
|
|
271
|
+
<p>© 2026 Your Company</p>
|
|
272
|
+
</footer>
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Sidebar with Ads
|
|
278
|
+
|
|
279
|
+
```tsx
|
|
280
|
+
import { AdPanel, isInitialized } from 'shared-features';
|
|
281
|
+
|
|
282
|
+
function Sidebar() {
|
|
283
|
+
return (
|
|
284
|
+
<aside>
|
|
285
|
+
<nav>{/* Navigation */}</nav>
|
|
286
|
+
{isInitialized() && <AdPanel variant="small" />}
|
|
287
|
+
</aside>
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Firestore Collections (Reference)
|
|
293
|
+
|
|
294
|
+
| Collection | Purpose |
|
|
295
|
+
|------------|---------|
|
|
296
|
+
| `zaions_campaigns` | Ad campaigns data |
|
|
297
|
+
| `zaions_products` | Products being promoted |
|
|
298
|
+
| `zaions_impressions` | Ad impression analytics |
|
|
299
|
+
| `zaions_broadcasts` | Broadcast messages |
|
|
300
|
+
| `zaions_broadcast_events` | Broadcast analytics |
|
|
301
|
+
| `zaions_notification_templates` | Reusable templates |
|
|
302
|
+
|
|
303
|
+
## Troubleshooting
|
|
304
|
+
|
|
305
|
+
| Issue | Solution |
|
|
306
|
+
|-------|----------|
|
|
307
|
+
| Components not rendering | Check `isInitialized()` returns true |
|
|
308
|
+
| Firebase errors | Verify all 7 config fields are provided |
|
|
309
|
+
| No ads showing | Check projectId matches admin panel config |
|
|
310
|
+
| Styles missing | Ensure `@radix-ui/themes` is imported |
|
|
311
|
+
|
|
312
|
+
## Links
|
|
313
|
+
|
|
314
|
+
- [Full Documentation](./README.md)
|
|
315
|
+
- [Admin Panel](https://aoneahsan.com/admin)
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# shared-features
|
|
2
2
|
|
|
3
|
+
- **[AI Integration Guide](./AI-INTEGRATION-GUIDE.md)** - Quick reference for AI development agents (Claude, Cursor, Copilot)
|
|
4
|
+
|
|
3
5
|
Centralized common features for Zaions projects. Manage ads, notifications, contacts, and more from a single admin panel at [aoneahsan.com](https://aoneahsan.com).
|
|
4
6
|
|
|
5
7
|
---
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Support configuration for shared-features package
|
|
3
|
+
* Help keep this package free and improving
|
|
4
|
+
*/
|
|
5
|
+
export declare const SUPPORT_CONFIG: {
|
|
6
|
+
readonly url: "https://aoneahsan.com/payment?project-id=shared-features&project-identifier=shared-features";
|
|
7
|
+
readonly label: "Support the Project";
|
|
8
|
+
readonly description: "Help us keep shared-features free and improving";
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=support.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"support.d.ts","sourceRoot":"","sources":["../../src/config/support.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,cAAc;;;;CAIjB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shared-features",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "Shared features for Zaions projects - centralized ads, notifications, broadcasts, contacts, and more",
|
|
5
5
|
"author": "Ahsan Mahmood <aoneahsan@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -58,7 +58,8 @@
|
|
|
58
58
|
},
|
|
59
59
|
"files": [
|
|
60
60
|
"dist",
|
|
61
|
-
"README.md"
|
|
61
|
+
"README.md",
|
|
62
|
+
"AI-INTEGRATION-GUIDE.md"
|
|
62
63
|
],
|
|
63
64
|
"scripts": {
|
|
64
65
|
"build": "vite build && tsc --emitDeclarationOnly",
|
|
@@ -72,7 +73,7 @@
|
|
|
72
73
|
"@radix-ui/react-icons": ">=1.3.2",
|
|
73
74
|
"@radix-ui/themes": ">=3.2.1",
|
|
74
75
|
"firebase": ">=12.8.0",
|
|
75
|
-
"lucide-react": ">=0.
|
|
76
|
+
"lucide-react": ">=0.562.0",
|
|
76
77
|
"react": ">=19.2.3",
|
|
77
78
|
"react-dom": ">=19.2.3",
|
|
78
79
|
"zustand": ">=5.0.10"
|
|
@@ -86,9 +87,12 @@
|
|
|
86
87
|
"@capacitor/preferences": "^8.0.0",
|
|
87
88
|
"@radix-ui/react-icons": "^1.3.2",
|
|
88
89
|
"@radix-ui/themes": "^3.2.1",
|
|
89
|
-
"@types/react": "^19.2.
|
|
90
|
+
"@types/react": "^19.2.9",
|
|
90
91
|
"@types/react-dom": "^19.2.3",
|
|
92
|
+
"@typescript-eslint/eslint-plugin": "^8.53.1",
|
|
93
|
+
"@typescript-eslint/parser": "^8.53.1",
|
|
91
94
|
"@vitejs/plugin-react": "^5.1.2",
|
|
95
|
+
"eslint": "^9.39.2",
|
|
92
96
|
"firebase": "^12.8.0",
|
|
93
97
|
"lucide-react": "^0.562.0",
|
|
94
98
|
"typescript": "^5.9.3",
|