@encorekit/web-sdk 0.1.1 → 0.1.7
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 +94 -9
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/umd/encore.min.js +1 -1
- package/dist/umd/encore.min.js.map +1 -1
- package/embed/README.md +409 -0
- package/embed/index.html +57 -0
- package/embed/styles.css +154 -0
- package/examples/README.md +149 -0
- package/examples/angular/README.md +210 -0
- package/examples/angular/angular.json +73 -0
- package/examples/angular/package.json +32 -0
- package/examples/angular/src/app/app.component.html +56 -0
- package/examples/angular/src/app/app.component.ts +114 -0
- package/examples/angular/src/app/encore.service.ts +83 -0
- package/examples/angular/src/index.html +13 -0
- package/examples/angular/src/main.ts +7 -0
- package/examples/angular/src/styles.css +225 -0
- package/examples/angular/tsconfig.json +33 -0
- package/examples/ios-webview/EncoreURLBuilder.swift +87 -0
- package/examples/ios-webview/EncoreWebViewBridge.swift +426 -0
- package/examples/ios-webview/ExampleViewController.swift +233 -0
- package/examples/ios-webview/README.md +416 -0
- package/examples/ios-webview/SimpleEncoreView.swift +94 -0
- package/examples/ios-webview/SimpleExample.swift +131 -0
- package/examples/react/README.md +186 -0
- package/examples/react/index.html +13 -0
- package/examples/react/package.json +24 -0
- package/examples/react/src/App.tsx +173 -0
- package/examples/react/src/index.css +227 -0
- package/examples/react/src/main.tsx +11 -0
- package/examples/react/src/vite-env.d.ts +2 -0
- package/examples/react/tsconfig.json +25 -0
- package/examples/react/vite.config.ts +8 -0
- package/examples/svelte/README.md +233 -0
- package/examples/svelte/index.html +13 -0
- package/examples/svelte/package.json +25 -0
- package/examples/svelte/src/App.svelte +164 -0
- package/examples/svelte/src/app.css +224 -0
- package/examples/svelte/src/main.ts +9 -0
- package/examples/svelte/src/vite-env.d.ts +3 -0
- package/examples/svelte/svelte.config.js +8 -0
- package/examples/svelte/tsconfig.json +16 -0
- package/examples/svelte/tsconfig.node.json +11 -0
- package/examples/svelte/vite.config.ts +8 -0
- package/examples/vanilla-js/README.md +271 -0
- package/examples/vanilla-js/index.html +421 -0
- package/examples/vue/README.md +212 -0
- package/examples/vue/index.html +13 -0
- package/examples/vue/package.json +22 -0
- package/examples/vue/src/App.vue +170 -0
- package/examples/vue/src/main.ts +6 -0
- package/examples/vue/src/style.css +224 -0
- package/examples/vue/src/vite-env.d.ts +2 -0
- package/examples/vue/tsconfig.json +25 -0
- package/examples/vue/vite.config.ts +8 -0
- package/package.json +22 -3
- package/types/analytics/AnalyticsClient.d.ts +14 -0
- package/types/analytics/AnalyticsClient.d.ts.map +1 -0
- package/types/analytics/events.d.ts +63 -0
- package/types/analytics/events.d.ts.map +1 -0
- package/types/analytics/models.d.ts +17 -0
- package/types/analytics/models.d.ts.map +1 -0
- package/types/api/APIClient.d.ts +44 -8
- package/types/api/APIClient.d.ts.map +1 -1
- package/types/api/endpoints.d.ts +11 -7
- package/types/api/endpoints.d.ts.map +1 -1
- package/types/api/models.d.ts +134 -68
- package/types/api/models.d.ts.map +1 -1
- package/types/core/Configuration.d.ts +4 -0
- package/types/core/Configuration.d.ts.map +1 -1
- package/types/core/Encore.d.ts +16 -12
- package/types/core/Encore.d.ts.map +1 -1
- package/types/core/EntitlementManager.d.ts +9 -0
- package/types/core/EntitlementManager.d.ts.map +1 -1
- package/types/core/OfferManager.d.ts +27 -7
- package/types/core/OfferManager.d.ts.map +1 -1
- package/types/types.d.ts +1 -1
- package/types/types.d.ts.map +1 -1
- package/types/ui/OfferCard.d.ts.map +1 -1
- package/types/ui/OfferCarousel.d.ts.map +1 -1
- package/types/ui/Tooltip.d.ts +22 -0
- package/types/ui/Tooltip.d.ts.map +1 -0
- package/types/ui/styles.d.ts.map +1 -1
- package/dist/cjs/index.js +0 -2
- package/dist/cjs/index.js.map +0 -1
- package/types/src/api/APIClient.d.ts +0 -63
- package/types/src/api/APIClient.d.ts.map +0 -1
- package/types/src/api/endpoints.d.ts +0 -35
- package/types/src/api/endpoints.d.ts.map +0 -1
- package/types/src/api/models.d.ts +0 -156
- package/types/src/api/models.d.ts.map +0 -1
- package/types/src/core/Configuration.d.ts +0 -42
- package/types/src/core/Configuration.d.ts.map +0 -1
- package/types/src/core/Encore.d.ts +0 -81
- package/types/src/core/Encore.d.ts.map +0 -1
- package/types/src/core/EntitlementManager.d.ts +0 -65
- package/types/src/core/EntitlementManager.d.ts.map +0 -1
- package/types/src/core/OfferManager.d.ts +0 -35
- package/types/src/core/OfferManager.d.ts.map +0 -1
- package/types/src/core/PlacementBuilder.d.ts +0 -27
- package/types/src/core/PlacementBuilder.d.ts.map +0 -1
- package/types/src/core/SignalManager.d.ts +0 -51
- package/types/src/core/SignalManager.d.ts.map +0 -1
- package/types/src/core/StorageManager.d.ts +0 -34
- package/types/src/core/StorageManager.d.ts.map +0 -1
- package/types/src/core/VerificationPoller.d.ts +0 -27
- package/types/src/core/VerificationPoller.d.ts.map +0 -1
- package/types/src/index.d.ts +0 -7
- package/types/src/index.d.ts.map +0 -1
- package/types/src/types.d.ts +0 -156
- package/types/src/types.d.ts.map +0 -1
- package/types/src/ui/OfferCard.d.ts +0 -29
- package/types/src/ui/OfferCard.d.ts.map +0 -1
- package/types/src/ui/OfferCarousel.d.ts +0 -55
- package/types/src/ui/OfferCarousel.d.ts.map +0 -1
- package/types/src/ui/OfferModal.d.ts +0 -41
- package/types/src/ui/OfferModal.d.ts.map +0 -1
- package/types/src/ui/SuccessScreen.d.ts +0 -33
- package/types/src/ui/SuccessScreen.d.ts.map +0 -1
- package/types/src/ui/styles.d.ts +0 -44
- package/types/src/ui/styles.d.ts.map +0 -1
- package/types/src/utils/eventEmitter.d.ts +0 -50
- package/types/src/utils/eventEmitter.d.ts.map +0 -1
- package/types/src/utils/focusDetection.d.ts +0 -21
- package/types/src/utils/focusDetection.d.ts.map +0 -1
- package/types/src/utils/logger.d.ts +0 -21
- package/types/src/utils/logger.d.ts.map +0 -1
- package/types/src/utils/network.d.ts +0 -57
- package/types/src/utils/network.d.ts.map +0 -1
- package/types/src/utils/uuid.d.ts +0 -10
- package/types/src/utils/uuid.d.ts.map +0 -1
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# Encore SDK - Vue Example
|
|
2
|
+
|
|
3
|
+
This example demonstrates how to integrate the Encore Web SDK into a Vue 3 application using Vite, TypeScript, and the Composition API.
|
|
4
|
+
|
|
5
|
+
## 🚀 Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install dependencies
|
|
9
|
+
npm install
|
|
10
|
+
|
|
11
|
+
# Start development server
|
|
12
|
+
npm run dev
|
|
13
|
+
|
|
14
|
+
# Build for production
|
|
15
|
+
npm run build
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The app will be available at `http://localhost:5173`
|
|
19
|
+
|
|
20
|
+
## 📁 Project Structure
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
vue/
|
|
24
|
+
├── src/
|
|
25
|
+
│ ├── App.vue # Main application component
|
|
26
|
+
│ ├── main.ts # Application entry point
|
|
27
|
+
│ ├── style.css # Global styles
|
|
28
|
+
│ └── vite-env.d.ts # Vite type definitions
|
|
29
|
+
├── index.html # HTML template
|
|
30
|
+
├── package.json # Dependencies and scripts
|
|
31
|
+
├── tsconfig.json # TypeScript configuration
|
|
32
|
+
└── vite.config.ts # Vite configuration
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## 🔑 Configuration
|
|
36
|
+
|
|
37
|
+
Before running the example, replace `'YOUR_API_KEY_HERE'` in `src/App.vue` with your actual Encore API key:
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
Encore.configure({
|
|
41
|
+
apiKey: 'YOUR_API_KEY_HERE', // Get this from dashboard.encorekit.com
|
|
42
|
+
environment: 'production',
|
|
43
|
+
logLevel: 'debug',
|
|
44
|
+
})
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 🎯 Features Demonstrated
|
|
48
|
+
|
|
49
|
+
### 1. SDK Initialization
|
|
50
|
+
The SDK is initialized when the component mounts using `onMounted`:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { onMounted } from 'vue'
|
|
54
|
+
import Encore from '@encorekit/web-sdk'
|
|
55
|
+
|
|
56
|
+
onMounted(() => {
|
|
57
|
+
Encore.configure({
|
|
58
|
+
apiKey: 'YOUR_API_KEY_HERE',
|
|
59
|
+
environment: 'production',
|
|
60
|
+
logLevel: 'debug',
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const currentUserId = Encore.getCurrentUserId()
|
|
64
|
+
userId.value = currentUserId || ''
|
|
65
|
+
isInitialized.value = true
|
|
66
|
+
})
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 2. Reactive State Management
|
|
70
|
+
Vue's reactivity system tracks SDK state:
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { ref } from 'vue'
|
|
74
|
+
|
|
75
|
+
const isInitialized = ref(false)
|
|
76
|
+
const userId = ref('')
|
|
77
|
+
const customUserId = ref('')
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 3. User Identification
|
|
81
|
+
Users can be identified with custom IDs and attributes:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
const handleIdentifyUser = () => {
|
|
85
|
+
Encore.identify(customUserId.value, {
|
|
86
|
+
email: 'user@example.com',
|
|
87
|
+
})
|
|
88
|
+
userId.value = customUserId.value
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 4. Presenting Offers
|
|
93
|
+
Display targeted offers to users:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
const handlePresentOffer = async () => {
|
|
97
|
+
const result = await Encore.presentOffer()
|
|
98
|
+
|
|
99
|
+
if (result.granted) {
|
|
100
|
+
console.log('Offer granted!')
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## 🏗️ Vue Patterns
|
|
106
|
+
|
|
107
|
+
This example uses Vue 3 best practices:
|
|
108
|
+
|
|
109
|
+
- **Composition API** - `<script setup>` for cleaner component logic
|
|
110
|
+
- **Reactivity** - `ref()` for reactive state management
|
|
111
|
+
- **Lifecycle Hooks** - `onMounted()` for initialization
|
|
112
|
+
- **TypeScript** - Full type safety with TypeScript
|
|
113
|
+
- **Template Syntax** - Vue's declarative template syntax
|
|
114
|
+
- **Event Handling** - `@click` for user interactions
|
|
115
|
+
|
|
116
|
+
## 📦 Dependencies
|
|
117
|
+
|
|
118
|
+
- `vue` ^3.4.21 - Vue 3 framework
|
|
119
|
+
- `@encorekit/web-sdk` ^0.2.0 - Encore Web SDK
|
|
120
|
+
- `vite` ^5.4.1 - Build tool and dev server
|
|
121
|
+
- `typescript` ^5.5.3 - TypeScript compiler
|
|
122
|
+
- `vue-tsc` ^2.0.6 - Vue TypeScript compiler
|
|
123
|
+
|
|
124
|
+
## 🔧 Available Scripts
|
|
125
|
+
|
|
126
|
+
- `npm run dev` - Start development server with hot reload
|
|
127
|
+
- `npm run build` - Build for production (with type checking)
|
|
128
|
+
- `npm run preview` - Preview production build locally
|
|
129
|
+
|
|
130
|
+
## 💡 Best Practices
|
|
131
|
+
|
|
132
|
+
1. **Initialize Once** - Initialize the SDK in `onMounted` hook
|
|
133
|
+
2. **Error Handling** - Always wrap SDK calls in try-catch blocks
|
|
134
|
+
3. **Reactive State** - Use `ref()` or `reactive()` for state management
|
|
135
|
+
4. **User Feedback** - Provide clear feedback for all SDK operations
|
|
136
|
+
5. **Environment Variables** - In production, use environment variables for the API key
|
|
137
|
+
6. **Type Safety** - Use TypeScript for better developer experience
|
|
138
|
+
|
|
139
|
+
## 🎨 Customization
|
|
140
|
+
|
|
141
|
+
### Using Environment Variables
|
|
142
|
+
|
|
143
|
+
Create a `.env` file:
|
|
144
|
+
|
|
145
|
+
```env
|
|
146
|
+
VITE_ENCORE_API_KEY=your-api-key-here
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Update `App.vue`:
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
Encore.configure({
|
|
153
|
+
apiKey: import.meta.env.VITE_ENCORE_API_KEY,
|
|
154
|
+
environment: 'production',
|
|
155
|
+
})
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Creating a Composable
|
|
159
|
+
|
|
160
|
+
For better reusability, create a composable function:
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
// composables/useEncore.ts
|
|
164
|
+
import { ref, onMounted } from 'vue'
|
|
165
|
+
import Encore from '@encorekit/web-sdk'
|
|
166
|
+
|
|
167
|
+
export function useEncore(apiKey: string) {
|
|
168
|
+
const isInitialized = ref(false)
|
|
169
|
+
const userId = ref('')
|
|
170
|
+
|
|
171
|
+
onMounted(() => {
|
|
172
|
+
Encore.configure({ apiKey })
|
|
173
|
+
userId.value = Encore.getCurrentUserId() || ''
|
|
174
|
+
isInitialized.value = true
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
const presentOffer = async () => {
|
|
178
|
+
return await Encore.presentOffer()
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const identify = (id: string, attributes?: Record<string, any>) => {
|
|
182
|
+
Encore.identify(id, attributes)
|
|
183
|
+
userId.value = id
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return { isInitialized, userId, presentOffer, identify }
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Usage in component:
|
|
191
|
+
|
|
192
|
+
```vue
|
|
193
|
+
<script setup lang="ts">
|
|
194
|
+
import { useEncore } from './composables/useEncore'
|
|
195
|
+
|
|
196
|
+
const { userId, isInitialized, presentOffer, identify } = useEncore('YOUR_API_KEY')
|
|
197
|
+
</script>
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## 📚 Learn More
|
|
201
|
+
|
|
202
|
+
- [Encore SDK Documentation](https://docs.encorekit.com)
|
|
203
|
+
- [Vue 3 Documentation](https://vuejs.org)
|
|
204
|
+
- [Vite Documentation](https://vitejs.dev)
|
|
205
|
+
- [TypeScript Documentation](https://www.typescriptlang.org)
|
|
206
|
+
|
|
207
|
+
## 🆘 Support
|
|
208
|
+
|
|
209
|
+
- 📧 Email: admin@encorekit.com
|
|
210
|
+
- 📖 Docs: https://docs.encorekit.com
|
|
211
|
+
|
|
212
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Encore SDK - Vue Example</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="app"></div>
|
|
10
|
+
<script type="module" src="/src/main.ts"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
13
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "encore-sdk-vue-example",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Vue example for Encore Web SDK",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "vue-tsc && vite build",
|
|
9
|
+
"preview": "vite preview"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@encorekit/web-sdk": "^0.1.1",
|
|
13
|
+
"vue": "^3.4.21"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@vitejs/plugin-vue": "^5.0.4",
|
|
17
|
+
"typescript": "^5.5.3",
|
|
18
|
+
"vite": "^5.4.1",
|
|
19
|
+
"vue-tsc": "^2.0.6"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref, onMounted } from 'vue'
|
|
3
|
+
import Encore from '@encorekit/web-sdk'
|
|
4
|
+
|
|
5
|
+
const isInitialized = ref(false)
|
|
6
|
+
const userId = ref('')
|
|
7
|
+
const customUserId = ref('')
|
|
8
|
+
const status = ref<{
|
|
9
|
+
message: string
|
|
10
|
+
type: 'info' | 'success' | 'error'
|
|
11
|
+
} | null>(null)
|
|
12
|
+
|
|
13
|
+
// Initialize SDK on mount
|
|
14
|
+
onMounted(() => {
|
|
15
|
+
try {
|
|
16
|
+
Encore.configure({
|
|
17
|
+
apiKey: 'ENCORE_PUBLIC_API_KEY', // Replace with your actual API key
|
|
18
|
+
userId: 'test-vue',
|
|
19
|
+
environment: 'production',
|
|
20
|
+
logLevel: 'debug',
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const currentUserId = Encore.getCurrentUserId()
|
|
24
|
+
userId.value = currentUserId || ''
|
|
25
|
+
isInitialized.value = true
|
|
26
|
+
status.value = {
|
|
27
|
+
message: 'Encore SDK initialized successfully!',
|
|
28
|
+
type: 'success',
|
|
29
|
+
}
|
|
30
|
+
} catch (error) {
|
|
31
|
+
status.value = {
|
|
32
|
+
message: `Failed to initialize SDK: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
33
|
+
type: 'error',
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
const handleIdentifyUser = () => {
|
|
39
|
+
if (!customUserId.value.trim()) {
|
|
40
|
+
status.value = {
|
|
41
|
+
message: 'Please enter a user ID',
|
|
42
|
+
type: 'error',
|
|
43
|
+
}
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
Encore.identify(customUserId.value, {
|
|
49
|
+
email: 'user@example.com',
|
|
50
|
+
})
|
|
51
|
+
userId.value = customUserId.value
|
|
52
|
+
status.value = {
|
|
53
|
+
message: `User identified as: ${customUserId.value}`,
|
|
54
|
+
type: 'success',
|
|
55
|
+
}
|
|
56
|
+
} catch (error) {
|
|
57
|
+
status.value = {
|
|
58
|
+
message: `Failed to identify user: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
59
|
+
type: 'error',
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const handlePresentOffer = async () => {
|
|
65
|
+
status.value = {
|
|
66
|
+
message: 'Presenting offer...',
|
|
67
|
+
type: 'info',
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
const result = await Encore.presentOffer()
|
|
72
|
+
|
|
73
|
+
if (result.granted) {
|
|
74
|
+
status.value = {
|
|
75
|
+
message: 'Offer granted successfully!',
|
|
76
|
+
type: 'success',
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
status.value = {
|
|
80
|
+
message: `Offer not granted: ${JSON.stringify(result.reason)}`,
|
|
81
|
+
type: 'info',
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
} catch (error) {
|
|
85
|
+
status.value = {
|
|
86
|
+
message: `Failed to present offer: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
87
|
+
type: 'error',
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
</script>
|
|
92
|
+
|
|
93
|
+
<template>
|
|
94
|
+
<div class="app">
|
|
95
|
+
<h1>🎯 Encore SDK</h1>
|
|
96
|
+
<p>Vue Example</p>
|
|
97
|
+
|
|
98
|
+
<div class="card">
|
|
99
|
+
<h2>SDK Status</h2>
|
|
100
|
+
<div class="user-info">
|
|
101
|
+
<strong>Status:</strong> {{ isInitialized ? '✓ Initialized' : '✗ Not Initialized' }}
|
|
102
|
+
<br />
|
|
103
|
+
<strong>User ID:</strong> {{ userId || 'Not set' }}
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
<div v-if="status" :class="['status', status.type]">
|
|
107
|
+
{{ status.message }}
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
<div class="card">
|
|
112
|
+
<h2>User Identification</h2>
|
|
113
|
+
<div class="input-group">
|
|
114
|
+
<label for="userId">Custom User ID:</label>
|
|
115
|
+
<input
|
|
116
|
+
id="userId"
|
|
117
|
+
v-model="customUserId"
|
|
118
|
+
type="text"
|
|
119
|
+
placeholder="Enter user ID (e.g., user-123)"
|
|
120
|
+
:disabled="!isInitialized"
|
|
121
|
+
/>
|
|
122
|
+
</div>
|
|
123
|
+
<button
|
|
124
|
+
@click="handleIdentifyUser"
|
|
125
|
+
:disabled="!isInitialized"
|
|
126
|
+
class="primary"
|
|
127
|
+
>
|
|
128
|
+
Identify User
|
|
129
|
+
</button>
|
|
130
|
+
</div>
|
|
131
|
+
|
|
132
|
+
<div class="card">
|
|
133
|
+
<h2>Present Offer</h2>
|
|
134
|
+
<p>Click the button below to display an offer to the user.</p>
|
|
135
|
+
<button
|
|
136
|
+
@click="handlePresentOffer"
|
|
137
|
+
:disabled="!isInitialized"
|
|
138
|
+
class="success"
|
|
139
|
+
>
|
|
140
|
+
🎁 Present Offer
|
|
141
|
+
</button>
|
|
142
|
+
</div>
|
|
143
|
+
|
|
144
|
+
<div class="card">
|
|
145
|
+
<h2>Code Example</h2>
|
|
146
|
+
<pre>{{ codeExample }}</pre>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
</template>
|
|
150
|
+
|
|
151
|
+
<script lang="ts">
|
|
152
|
+
const codeExample = `// Initialize SDK
|
|
153
|
+
Encore.configure({
|
|
154
|
+
apiKey: 'your-api-key',
|
|
155
|
+
userId: 'user-123',
|
|
156
|
+
environment: 'production',
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
// Identify user
|
|
160
|
+
Encore.identify('user-123', {
|
|
161
|
+
email: 'user@example.com'
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
// Present offer
|
|
165
|
+
const result = await Encore.presentOffer()
|
|
166
|
+
if (result.granted) {
|
|
167
|
+
console.log('Offer granted!')
|
|
168
|
+
}`
|
|
169
|
+
</script>
|
|
170
|
+
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
3
|
+
line-height: 1.5;
|
|
4
|
+
font-weight: 400;
|
|
5
|
+
|
|
6
|
+
color-scheme: light dark;
|
|
7
|
+
color: rgba(255, 255, 255, 0.87);
|
|
8
|
+
background-color: #242424;
|
|
9
|
+
|
|
10
|
+
font-synthesis: none;
|
|
11
|
+
text-rendering: optimizeLegibility;
|
|
12
|
+
-webkit-font-smoothing: antialiased;
|
|
13
|
+
-moz-osx-font-smoothing: grayscale;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
* {
|
|
17
|
+
margin: 0;
|
|
18
|
+
padding: 0;
|
|
19
|
+
box-sizing: border-box;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
body {
|
|
23
|
+
margin: 0;
|
|
24
|
+
display: flex;
|
|
25
|
+
place-items: center;
|
|
26
|
+
min-width: 320px;
|
|
27
|
+
min-height: 100vh;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
#app {
|
|
31
|
+
width: 100%;
|
|
32
|
+
max-width: 1280px;
|
|
33
|
+
margin: 0 auto;
|
|
34
|
+
padding: 2rem;
|
|
35
|
+
text-align: center;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
h1 {
|
|
39
|
+
font-size: 3.2em;
|
|
40
|
+
line-height: 1.1;
|
|
41
|
+
margin-bottom: 1rem;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
h2 {
|
|
45
|
+
font-size: 1.8em;
|
|
46
|
+
margin-top: 2rem;
|
|
47
|
+
margin-bottom: 1rem;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.card {
|
|
51
|
+
padding: 2em;
|
|
52
|
+
background-color: #1a1a1a;
|
|
53
|
+
border-radius: 8px;
|
|
54
|
+
margin-bottom: 2rem;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.user-info {
|
|
58
|
+
margin: 1.5rem 0;
|
|
59
|
+
padding: 1rem;
|
|
60
|
+
background-color: #2a2a2a;
|
|
61
|
+
border-radius: 4px;
|
|
62
|
+
font-family: monospace;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.user-info strong {
|
|
66
|
+
color: #42b883;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.button-group {
|
|
70
|
+
display: flex;
|
|
71
|
+
gap: 1rem;
|
|
72
|
+
justify-content: center;
|
|
73
|
+
flex-wrap: wrap;
|
|
74
|
+
margin: 1.5rem 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
button {
|
|
78
|
+
border-radius: 8px;
|
|
79
|
+
border: 1px solid transparent;
|
|
80
|
+
padding: 0.6em 1.2em;
|
|
81
|
+
font-size: 1em;
|
|
82
|
+
font-weight: 500;
|
|
83
|
+
font-family: inherit;
|
|
84
|
+
background-color: #1a1a1a;
|
|
85
|
+
cursor: pointer;
|
|
86
|
+
transition: border-color 0.25s;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
button:hover {
|
|
90
|
+
border-color: #42b883;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
button:focus,
|
|
94
|
+
button:focus-visible {
|
|
95
|
+
outline: 4px auto -webkit-focus-ring-color;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
button:disabled {
|
|
99
|
+
opacity: 0.5;
|
|
100
|
+
cursor: not-allowed;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
button:disabled:hover {
|
|
104
|
+
border-color: transparent;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.primary {
|
|
108
|
+
background-color: #42b883;
|
|
109
|
+
color: white;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.primary:hover {
|
|
113
|
+
background-color: #33a06f;
|
|
114
|
+
border-color: #33a06f;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.success {
|
|
118
|
+
background-color: #059669;
|
|
119
|
+
color: white;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.success:hover {
|
|
123
|
+
background-color: #047857;
|
|
124
|
+
border-color: #047857;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.status {
|
|
128
|
+
margin: 1rem 0;
|
|
129
|
+
padding: 0.8rem;
|
|
130
|
+
border-radius: 4px;
|
|
131
|
+
font-size: 0.9em;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.status.info {
|
|
135
|
+
background-color: #1e40af;
|
|
136
|
+
color: white;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.status.success {
|
|
140
|
+
background-color: #059669;
|
|
141
|
+
color: white;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.status.error {
|
|
145
|
+
background-color: #dc2626;
|
|
146
|
+
color: white;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.input-group {
|
|
150
|
+
margin: 1rem 0;
|
|
151
|
+
text-align: left;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.input-group label {
|
|
155
|
+
display: block;
|
|
156
|
+
margin-bottom: 0.5rem;
|
|
157
|
+
font-weight: 500;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.input-group input {
|
|
161
|
+
width: 100%;
|
|
162
|
+
padding: 0.6em;
|
|
163
|
+
border-radius: 4px;
|
|
164
|
+
border: 1px solid #444;
|
|
165
|
+
background-color: #1a1a1a;
|
|
166
|
+
color: inherit;
|
|
167
|
+
font-size: 1em;
|
|
168
|
+
font-family: inherit;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.input-group input:focus {
|
|
172
|
+
outline: 2px solid #42b883;
|
|
173
|
+
border-color: #42b883;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
code {
|
|
177
|
+
background-color: #2a2a2a;
|
|
178
|
+
padding: 0.2em 0.4em;
|
|
179
|
+
border-radius: 3px;
|
|
180
|
+
font-family: monospace;
|
|
181
|
+
font-size: 0.9em;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
pre {
|
|
185
|
+
text-align: left;
|
|
186
|
+
background-color: #1a1a1a;
|
|
187
|
+
padding: 1rem;
|
|
188
|
+
border-radius: 4px;
|
|
189
|
+
overflow-x: auto;
|
|
190
|
+
margin: 1rem 0;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
@media (prefers-color-scheme: light) {
|
|
194
|
+
:root {
|
|
195
|
+
color: #213547;
|
|
196
|
+
background-color: #ffffff;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
button {
|
|
200
|
+
background-color: #f9f9f9;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.card {
|
|
204
|
+
background-color: #f9f9f9;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.user-info {
|
|
208
|
+
background-color: #efefef;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.input-group input {
|
|
212
|
+
background-color: #ffffff;
|
|
213
|
+
border-color: #ccc;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
code {
|
|
217
|
+
background-color: #efefef;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
pre {
|
|
221
|
+
background-color: #f5f5f5;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
|
|
9
|
+
/* Bundler mode */
|
|
10
|
+
"moduleResolution": "bundler",
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
12
|
+
"isolatedModules": true,
|
|
13
|
+
"moduleDetection": "force",
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
"jsx": "preserve",
|
|
16
|
+
|
|
17
|
+
/* Linting */
|
|
18
|
+
"strict": true,
|
|
19
|
+
"noUnusedLocals": true,
|
|
20
|
+
"noUnusedParameters": true,
|
|
21
|
+
"noFallthroughCasesInSwitch": true
|
|
22
|
+
},
|
|
23
|
+
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
|
|
24
|
+
}
|
|
25
|
+
|