@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.
Files changed (134) hide show
  1. package/README.md +94 -9
  2. package/dist/cjs/index.cjs +1 -1
  3. package/dist/cjs/index.cjs.map +1 -1
  4. package/dist/esm/index.js +1 -1
  5. package/dist/esm/index.js.map +1 -1
  6. package/dist/umd/encore.min.js +1 -1
  7. package/dist/umd/encore.min.js.map +1 -1
  8. package/embed/README.md +409 -0
  9. package/embed/index.html +57 -0
  10. package/embed/styles.css +154 -0
  11. package/examples/README.md +149 -0
  12. package/examples/angular/README.md +210 -0
  13. package/examples/angular/angular.json +73 -0
  14. package/examples/angular/package.json +32 -0
  15. package/examples/angular/src/app/app.component.html +56 -0
  16. package/examples/angular/src/app/app.component.ts +114 -0
  17. package/examples/angular/src/app/encore.service.ts +83 -0
  18. package/examples/angular/src/index.html +13 -0
  19. package/examples/angular/src/main.ts +7 -0
  20. package/examples/angular/src/styles.css +225 -0
  21. package/examples/angular/tsconfig.json +33 -0
  22. package/examples/ios-webview/EncoreURLBuilder.swift +87 -0
  23. package/examples/ios-webview/EncoreWebViewBridge.swift +426 -0
  24. package/examples/ios-webview/ExampleViewController.swift +233 -0
  25. package/examples/ios-webview/README.md +416 -0
  26. package/examples/ios-webview/SimpleEncoreView.swift +94 -0
  27. package/examples/ios-webview/SimpleExample.swift +131 -0
  28. package/examples/react/README.md +186 -0
  29. package/examples/react/index.html +13 -0
  30. package/examples/react/package.json +24 -0
  31. package/examples/react/src/App.tsx +173 -0
  32. package/examples/react/src/index.css +227 -0
  33. package/examples/react/src/main.tsx +11 -0
  34. package/examples/react/src/vite-env.d.ts +2 -0
  35. package/examples/react/tsconfig.json +25 -0
  36. package/examples/react/vite.config.ts +8 -0
  37. package/examples/svelte/README.md +233 -0
  38. package/examples/svelte/index.html +13 -0
  39. package/examples/svelte/package.json +25 -0
  40. package/examples/svelte/src/App.svelte +164 -0
  41. package/examples/svelte/src/app.css +224 -0
  42. package/examples/svelte/src/main.ts +9 -0
  43. package/examples/svelte/src/vite-env.d.ts +3 -0
  44. package/examples/svelte/svelte.config.js +8 -0
  45. package/examples/svelte/tsconfig.json +16 -0
  46. package/examples/svelte/tsconfig.node.json +11 -0
  47. package/examples/svelte/vite.config.ts +8 -0
  48. package/examples/vanilla-js/README.md +271 -0
  49. package/examples/vanilla-js/index.html +421 -0
  50. package/examples/vue/README.md +212 -0
  51. package/examples/vue/index.html +13 -0
  52. package/examples/vue/package.json +22 -0
  53. package/examples/vue/src/App.vue +170 -0
  54. package/examples/vue/src/main.ts +6 -0
  55. package/examples/vue/src/style.css +224 -0
  56. package/examples/vue/src/vite-env.d.ts +2 -0
  57. package/examples/vue/tsconfig.json +25 -0
  58. package/examples/vue/vite.config.ts +8 -0
  59. package/package.json +22 -3
  60. package/types/analytics/AnalyticsClient.d.ts +14 -0
  61. package/types/analytics/AnalyticsClient.d.ts.map +1 -0
  62. package/types/analytics/events.d.ts +63 -0
  63. package/types/analytics/events.d.ts.map +1 -0
  64. package/types/analytics/models.d.ts +17 -0
  65. package/types/analytics/models.d.ts.map +1 -0
  66. package/types/api/APIClient.d.ts +44 -8
  67. package/types/api/APIClient.d.ts.map +1 -1
  68. package/types/api/endpoints.d.ts +11 -7
  69. package/types/api/endpoints.d.ts.map +1 -1
  70. package/types/api/models.d.ts +134 -68
  71. package/types/api/models.d.ts.map +1 -1
  72. package/types/core/Configuration.d.ts +4 -0
  73. package/types/core/Configuration.d.ts.map +1 -1
  74. package/types/core/Encore.d.ts +16 -12
  75. package/types/core/Encore.d.ts.map +1 -1
  76. package/types/core/EntitlementManager.d.ts +9 -0
  77. package/types/core/EntitlementManager.d.ts.map +1 -1
  78. package/types/core/OfferManager.d.ts +27 -7
  79. package/types/core/OfferManager.d.ts.map +1 -1
  80. package/types/types.d.ts +1 -1
  81. package/types/types.d.ts.map +1 -1
  82. package/types/ui/OfferCard.d.ts.map +1 -1
  83. package/types/ui/OfferCarousel.d.ts.map +1 -1
  84. package/types/ui/Tooltip.d.ts +22 -0
  85. package/types/ui/Tooltip.d.ts.map +1 -0
  86. package/types/ui/styles.d.ts.map +1 -1
  87. package/dist/cjs/index.js +0 -2
  88. package/dist/cjs/index.js.map +0 -1
  89. package/types/src/api/APIClient.d.ts +0 -63
  90. package/types/src/api/APIClient.d.ts.map +0 -1
  91. package/types/src/api/endpoints.d.ts +0 -35
  92. package/types/src/api/endpoints.d.ts.map +0 -1
  93. package/types/src/api/models.d.ts +0 -156
  94. package/types/src/api/models.d.ts.map +0 -1
  95. package/types/src/core/Configuration.d.ts +0 -42
  96. package/types/src/core/Configuration.d.ts.map +0 -1
  97. package/types/src/core/Encore.d.ts +0 -81
  98. package/types/src/core/Encore.d.ts.map +0 -1
  99. package/types/src/core/EntitlementManager.d.ts +0 -65
  100. package/types/src/core/EntitlementManager.d.ts.map +0 -1
  101. package/types/src/core/OfferManager.d.ts +0 -35
  102. package/types/src/core/OfferManager.d.ts.map +0 -1
  103. package/types/src/core/PlacementBuilder.d.ts +0 -27
  104. package/types/src/core/PlacementBuilder.d.ts.map +0 -1
  105. package/types/src/core/SignalManager.d.ts +0 -51
  106. package/types/src/core/SignalManager.d.ts.map +0 -1
  107. package/types/src/core/StorageManager.d.ts +0 -34
  108. package/types/src/core/StorageManager.d.ts.map +0 -1
  109. package/types/src/core/VerificationPoller.d.ts +0 -27
  110. package/types/src/core/VerificationPoller.d.ts.map +0 -1
  111. package/types/src/index.d.ts +0 -7
  112. package/types/src/index.d.ts.map +0 -1
  113. package/types/src/types.d.ts +0 -156
  114. package/types/src/types.d.ts.map +0 -1
  115. package/types/src/ui/OfferCard.d.ts +0 -29
  116. package/types/src/ui/OfferCard.d.ts.map +0 -1
  117. package/types/src/ui/OfferCarousel.d.ts +0 -55
  118. package/types/src/ui/OfferCarousel.d.ts.map +0 -1
  119. package/types/src/ui/OfferModal.d.ts +0 -41
  120. package/types/src/ui/OfferModal.d.ts.map +0 -1
  121. package/types/src/ui/SuccessScreen.d.ts +0 -33
  122. package/types/src/ui/SuccessScreen.d.ts.map +0 -1
  123. package/types/src/ui/styles.d.ts +0 -44
  124. package/types/src/ui/styles.d.ts.map +0 -1
  125. package/types/src/utils/eventEmitter.d.ts +0 -50
  126. package/types/src/utils/eventEmitter.d.ts.map +0 -1
  127. package/types/src/utils/focusDetection.d.ts +0 -21
  128. package/types/src/utils/focusDetection.d.ts.map +0 -1
  129. package/types/src/utils/logger.d.ts +0 -21
  130. package/types/src/utils/logger.d.ts.map +0 -1
  131. package/types/src/utils/network.d.ts +0 -57
  132. package/types/src/utils/network.d.ts.map +0 -1
  133. package/types/src/utils/uuid.d.ts +0 -10
  134. 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,6 @@
1
+ import { createApp } from 'vue'
2
+ import './style.css'
3
+ import App from './App.vue'
4
+
5
+ createApp(App).mount('#app')
6
+
@@ -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,2 @@
1
+ /// <reference types="vite/client" />
2
+
@@ -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
+
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from 'vite'
2
+ import vue from '@vitejs/plugin-vue'
3
+
4
+ // https://vitejs.dev/config/
5
+ export default defineConfig({
6
+ plugins: [vue()],
7
+ })
8
+