@yoamigo.com/cli 0.1.23 → 0.1.25

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 CHANGED
@@ -1,11 +1,11 @@
1
- # @yoamigo/cli
1
+ # @yoamigo.com/cli
2
2
 
3
3
  CLI for creating and managing YoAmigo templates.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- npm install -g @yoamigo/cli
8
+ npm install -g @yoamigo.com/cli
9
9
  ```
10
10
 
11
11
  ## Quick Start
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yoamigo.com/cli",
3
- "version": "0.1.23",
3
+ "version": "0.1.25",
4
4
  "description": "CLI for creating and managing YoAmigo templates",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -14,7 +14,7 @@
14
14
  "@tiptap/pm": "^3.11.1",
15
15
  "@tiptap/react": "^3.11.1",
16
16
  "@tiptap/starter-kit": "^3.11.1",
17
- "@yoamigo.com/core": "^0.1.7",
17
+ "@yoamigo.com/core": "^0.1.10",
18
18
  "dompurify": "^3.2.3",
19
19
  "react": "^19.2.1",
20
20
  "react-dom": "^19.2.1"
@@ -2065,12 +2065,13 @@
2065
2065
  }
2066
2066
  },
2067
2067
  "node_modules/@yoamigo.com/core": {
2068
- "version": "0.1.7",
2069
- "resolved": "https://registry.npmjs.org/@yoamigo.com/core/-/core-0.1.7.tgz",
2070
- "integrity": "sha512-vGSDiLNkI4dC1bLGzGlTVGdbRJvDtbRNXhtptDYPkqBHGhdJ+vk6r9Nb85RqbPJWCH8PAdqkAVSfmqjiJxNcUA==",
2068
+ "version": "0.1.12",
2069
+ "resolved": "https://registry.npmjs.org/@yoamigo.com/core/-/core-0.1.12.tgz",
2070
+ "integrity": "sha512-f2ev6TaG6fSrC98JoaL+OjVK5IYb2N1lLlmDchF5k6C9AOH6rvJmBXL4CaQqg7KwUpltw3Z+Uiqs9MnikaqjXA==",
2071
2071
  "license": "SEE LICENSE IN LICENSE",
2072
2072
  "dependencies": {
2073
2073
  "clsx": "^2.1.1",
2074
+ "html2canvas-pro": "^1.6.1",
2074
2075
  "preact": "^10.27.2",
2075
2076
  "wouter": "^3.8.0"
2076
2077
  },
@@ -2136,6 +2137,15 @@
2136
2137
  "@babel/core": "^7.12.10"
2137
2138
  }
2138
2139
  },
2140
+ "node_modules/base64-arraybuffer": {
2141
+ "version": "1.0.2",
2142
+ "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
2143
+ "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
2144
+ "license": "MIT",
2145
+ "engines": {
2146
+ "node": ">= 0.6.0"
2147
+ }
2148
+ },
2139
2149
  "node_modules/baseline-browser-mapping": {
2140
2150
  "version": "2.9.7",
2141
2151
  "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz",
@@ -2225,6 +2235,15 @@
2225
2235
  "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
2226
2236
  "license": "MIT"
2227
2237
  },
2238
+ "node_modules/css-line-break": {
2239
+ "version": "2.1.0",
2240
+ "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
2241
+ "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
2242
+ "license": "MIT",
2243
+ "dependencies": {
2244
+ "utrie": "^1.0.2"
2245
+ }
2246
+ },
2228
2247
  "node_modules/css-select": {
2229
2248
  "version": "5.2.2",
2230
2249
  "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
@@ -2498,6 +2517,19 @@
2498
2517
  "he": "bin/he"
2499
2518
  }
2500
2519
  },
2520
+ "node_modules/html2canvas-pro": {
2521
+ "version": "1.6.1",
2522
+ "resolved": "https://registry.npmjs.org/html2canvas-pro/-/html2canvas-pro-1.6.1.tgz",
2523
+ "integrity": "sha512-TAwiVhNNmMGIqCax3cPirMaAqp7GbPTAAFAU95DO13diXZTWEI2Ih0hDez5yUplvmqirklZQkKVVXLTpEt2o9Q==",
2524
+ "license": "MIT",
2525
+ "dependencies": {
2526
+ "css-line-break": "^2.1.0",
2527
+ "text-segmentation": "^1.0.3"
2528
+ },
2529
+ "engines": {
2530
+ "node": ">=16.0.0"
2531
+ }
2532
+ },
2501
2533
  "node_modules/jiti": {
2502
2534
  "version": "2.6.1",
2503
2535
  "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
@@ -3332,6 +3364,15 @@
3332
3364
  "url": "https://opencollective.com/webpack"
3333
3365
  }
3334
3366
  },
3367
+ "node_modules/text-segmentation": {
3368
+ "version": "1.0.3",
3369
+ "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
3370
+ "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
3371
+ "license": "MIT",
3372
+ "dependencies": {
3373
+ "utrie": "^1.0.2"
3374
+ }
3375
+ },
3335
3376
  "node_modules/tinyglobby": {
3336
3377
  "version": "0.2.15",
3337
3378
  "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
@@ -3436,6 +3477,15 @@
3436
3477
  "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
3437
3478
  }
3438
3479
  },
3480
+ "node_modules/utrie": {
3481
+ "version": "1.0.2",
3482
+ "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
3483
+ "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
3484
+ "license": "MIT",
3485
+ "dependencies": {
3486
+ "base64-arraybuffer": "^1.0.2"
3487
+ }
3488
+ },
3439
3489
  "node_modules/vite": {
3440
3490
  "version": "7.3.0",
3441
3491
  "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz",
@@ -15,8 +15,9 @@
15
15
  "@tiptap/pm": "^3.11.1",
16
16
  "@tiptap/react": "^3.11.1",
17
17
  "@tiptap/starter-kit": "^3.11.1",
18
- "@yoamigo.com/core": "^0.1.10",
18
+ "@yoamigo.com/core": "^0.1.14",
19
19
  "dompurify": "^3.2.3",
20
+ "preact": "^10.27.2",
20
21
  "react": "^19.2.1",
21
22
  "react-dom": "^19.2.1"
22
23
  },
@@ -1,6 +1,6 @@
1
1
  import { StrictMode } from 'react'
2
2
  import { createRoot } from 'react-dom/client'
3
- import { ContentStoreProvider, registerContent } from '@yoamigo.com/core'
3
+ import { ContentStoreProvider, registerContent, setAssetResolver } from '@yoamigo.com/core'
4
4
  import App from './App'
5
5
  import content from './content'
6
6
  import './styles/globals.css'
@@ -8,6 +8,24 @@ import './styles/globals.css'
8
8
  // Register content for the content store
9
9
  registerContent(content)
10
10
 
11
+ // Configure asset resolver for builder preview
12
+ // - Builder: base=/session/{sessionId}/ → /session/{sessionId}/assets/...
13
+ // - Production: base=./ → ./assets/...
14
+ setAssetResolver((path) => {
15
+ if (!path || path.startsWith('http://') || path.startsWith('https://')) {
16
+ return path
17
+ }
18
+ const relativePath = path.startsWith('/') ? path.slice(1) : path
19
+ return `${import.meta.env.BASE_URL}${relativePath}`
20
+ })
21
+
22
+ // Initialize builder selection mode (dev only)
23
+ if (import.meta.env.DEV) {
24
+ import('@yoamigo.com/core').then(({ initBuilderSelection }) => {
25
+ initBuilderSelection()
26
+ })
27
+ }
28
+
11
29
  createRoot(document.getElementById('root')!).render(
12
30
  <StrictMode>
13
31
  <ContentStoreProvider initialContent={content}>
@@ -1,6 +1,35 @@
1
+ import { useState } from 'react'
1
2
  import { YaText } from '@yoamigo.com/core'
3
+ import { submitContactForm, type ContactFormData } from '@yoamigo.com/core/lib'
2
4
 
3
5
  export default function ContactPage() {
6
+ const [formData, setFormData] = useState({ name: '', email: '', message: '' })
7
+ const [isSubmitting, setIsSubmitting] = useState(false)
8
+ const [isSubmitted, setIsSubmitted] = useState(false)
9
+ const [error, setError] = useState<string | null>(null)
10
+
11
+ const handleSubmit = async (e: React.FormEvent) => {
12
+ e.preventDefault()
13
+ setIsSubmitting(true)
14
+ setError(null)
15
+
16
+ try {
17
+ const data: ContactFormData = {
18
+ name: formData.name,
19
+ email: formData.email,
20
+ message: formData.message,
21
+ }
22
+
23
+ await submitContactForm(data)
24
+ setIsSubmitted(true)
25
+ setFormData({ name: '', email: '', message: '' })
26
+ } catch (err) {
27
+ setError(err instanceof Error ? err.message : 'Failed to submit form')
28
+ } finally {
29
+ setIsSubmitting(false)
30
+ }
31
+ }
32
+
4
33
  return (
5
34
  <div>
6
35
  {/* Hero Section */}
@@ -21,70 +50,184 @@ export default function ContactPage() {
21
50
  </div>
22
51
  </section>
23
52
 
24
- {/* Contact Info Section */}
53
+ {/* Contact Form & Info Section */}
25
54
  <section className="py-16">
26
55
  <div className="container mx-auto px-4">
27
- <div className="max-w-2xl mx-auto">
28
- <div className="grid md:grid-cols-2 gap-8">
29
- {/* Email */}
30
- <div className="bg-white p-6 rounded-lg border border-gray-200">
31
- <div className="w-10 h-10 bg-blue-100 rounded-lg flex items-center justify-center mb-4">
32
- <svg className="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
33
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
34
- </svg>
35
- </div>
36
- <h3 className="text-lg font-semibold text-gray-900 mb-2">
37
- <YaText fieldId="contact.emailTitle" as="span">
38
- Email
56
+ <div className="max-w-4xl mx-auto">
57
+ <div className="grid md:grid-cols-2 gap-12">
58
+ {/* Contact Form */}
59
+ <div>
60
+ <h2 className="text-2xl font-bold text-gray-900 mb-6">
61
+ <YaText fieldId="contact.formTitle" as="span">
62
+ Send us a message
39
63
  </YaText>
40
- </h3>
41
- <p className="text-gray-600">
42
- <YaText fieldId="contact.emailValue" as="span">
43
- hello@example.com
44
- </YaText>
45
- </p>
64
+ </h2>
65
+
66
+ {isSubmitted ? (
67
+ <div className="bg-green-50 border border-green-200 rounded-lg p-6 text-center">
68
+ <div className="text-green-600 text-4xl mb-4">✓</div>
69
+ <h3 className="text-lg font-semibold text-green-800 mb-2">
70
+ <YaText fieldId="contact.successTitle" as="span">
71
+ Message Sent!
72
+ </YaText>
73
+ </h3>
74
+ <p className="text-green-700">
75
+ <YaText fieldId="contact.successMessage" as="span">
76
+ Thanks for reaching out. We'll get back to you soon.
77
+ </YaText>
78
+ </p>
79
+ <button
80
+ onClick={() => setIsSubmitted(false)}
81
+ className="mt-4 text-sm font-medium text-blue-600 hover:underline"
82
+ >
83
+ Send another message
84
+ </button>
85
+ </div>
86
+ ) : (
87
+ <form onSubmit={handleSubmit} className="space-y-6">
88
+ <div>
89
+ <label htmlFor="name" className="block text-sm font-medium text-gray-700 mb-2">
90
+ <YaText fieldId="contact.nameLabel" as="span">
91
+ Name
92
+ </YaText>
93
+ </label>
94
+ <input
95
+ type="text"
96
+ id="name"
97
+ name="name"
98
+ required
99
+ value={formData.name}
100
+ onChange={(e) => setFormData({ ...formData, name: e.target.value })}
101
+ className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
102
+ placeholder="Your name"
103
+ />
104
+ </div>
105
+
106
+ <div>
107
+ <label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-2">
108
+ <YaText fieldId="contact.emailLabel" as="span">
109
+ Email
110
+ </YaText>
111
+ </label>
112
+ <input
113
+ type="email"
114
+ id="email"
115
+ name="email"
116
+ required
117
+ value={formData.email}
118
+ onChange={(e) => setFormData({ ...formData, email: e.target.value })}
119
+ className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
120
+ placeholder="your@email.com"
121
+ />
122
+ </div>
123
+
124
+ <div>
125
+ <label htmlFor="message" className="block text-sm font-medium text-gray-700 mb-2">
126
+ <YaText fieldId="contact.messageLabel" as="span">
127
+ Message
128
+ </YaText>
129
+ </label>
130
+ <textarea
131
+ id="message"
132
+ name="message"
133
+ required
134
+ rows={5}
135
+ value={formData.message}
136
+ onChange={(e) => setFormData({ ...formData, message: e.target.value })}
137
+ className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
138
+ placeholder="How can we help you?"
139
+ />
140
+ </div>
141
+
142
+ {error && (
143
+ <div className="p-3 bg-red-50 border border-red-200 text-red-700 text-sm rounded-lg">
144
+ {error}
145
+ </div>
146
+ )}
147
+
148
+ <button
149
+ type="submit"
150
+ disabled={isSubmitting}
151
+ className="w-full bg-blue-600 text-white font-medium py-3 px-6 rounded-lg hover:bg-blue-700 transition-colors disabled:opacity-50"
152
+ >
153
+ {isSubmitting ? 'Sending...' : (
154
+ <YaText fieldId="contact.submitText" as="span">
155
+ Send Message
156
+ </YaText>
157
+ )}
158
+ </button>
159
+ </form>
160
+ )}
46
161
  </div>
47
162
 
48
- {/* Phone */}
49
- <div className="bg-white p-6 rounded-lg border border-gray-200">
50
- <div className="w-10 h-10 bg-blue-100 rounded-lg flex items-center justify-center mb-4">
51
- <svg className="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
52
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z" />
53
- </svg>
54
- </div>
55
- <h3 className="text-lg font-semibold text-gray-900 mb-2">
56
- <YaText fieldId="contact.phoneTitle" as="span">
57
- Phone
58
- </YaText>
59
- </h3>
60
- <p className="text-gray-600">
61
- <YaText fieldId="contact.phoneValue" as="span">
62
- (555) 123-4567
163
+ {/* Contact Info */}
164
+ <div className="space-y-6">
165
+ <h2 className="text-2xl font-bold text-gray-900 mb-6">
166
+ <YaText fieldId="contact.infoTitle" as="span">
167
+ Contact Information
63
168
  </YaText>
64
- </p>
65
- </div>
66
- </div>
169
+ </h2>
67
170
 
68
- {/* Address */}
69
- <div className="mt-8 bg-white p-6 rounded-lg border border-gray-200">
70
- <div className="w-10 h-10 bg-blue-100 rounded-lg flex items-center justify-center mb-4">
71
- <svg className="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
72
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
73
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
74
- </svg>
171
+ {/* Email */}
172
+ <div className="bg-white p-6 rounded-lg border border-gray-200">
173
+ <div className="w-10 h-10 bg-blue-100 rounded-lg flex items-center justify-center mb-4">
174
+ <svg className="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
175
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
176
+ </svg>
177
+ </div>
178
+ <h3 className="text-lg font-semibold text-gray-900 mb-2">
179
+ <YaText fieldId="contact.emailTitle" as="span">
180
+ Email
181
+ </YaText>
182
+ </h3>
183
+ <p className="text-gray-600">
184
+ <YaText fieldId="contact.emailValue" as="span">
185
+ hello@example.com
186
+ </YaText>
187
+ </p>
188
+ </div>
189
+
190
+ {/* Phone */}
191
+ <div className="bg-white p-6 rounded-lg border border-gray-200">
192
+ <div className="w-10 h-10 bg-blue-100 rounded-lg flex items-center justify-center mb-4">
193
+ <svg className="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
194
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z" />
195
+ </svg>
196
+ </div>
197
+ <h3 className="text-lg font-semibold text-gray-900 mb-2">
198
+ <YaText fieldId="contact.phoneTitle" as="span">
199
+ Phone
200
+ </YaText>
201
+ </h3>
202
+ <p className="text-gray-600">
203
+ <YaText fieldId="contact.phoneValue" as="span">
204
+ (555) 123-4567
205
+ </YaText>
206
+ </p>
207
+ </div>
208
+
209
+ {/* Address */}
210
+ <div className="bg-white p-6 rounded-lg border border-gray-200">
211
+ <div className="w-10 h-10 bg-blue-100 rounded-lg flex items-center justify-center mb-4">
212
+ <svg className="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
213
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
214
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
215
+ </svg>
216
+ </div>
217
+ <h3 className="text-lg font-semibold text-gray-900 mb-2">
218
+ <YaText fieldId="contact.addressTitle" as="span">
219
+ Address
220
+ </YaText>
221
+ </h3>
222
+ <p className="text-gray-600">
223
+ <YaText fieldId="contact.addressValue" as="span">
224
+ 123 Main Street, Suite 100
225
+ <br />
226
+ San Francisco, CA 94102
227
+ </YaText>
228
+ </p>
229
+ </div>
75
230
  </div>
76
- <h3 className="text-lg font-semibold text-gray-900 mb-2">
77
- <YaText fieldId="contact.addressTitle" as="span">
78
- Address
79
- </YaText>
80
- </h3>
81
- <p className="text-gray-600">
82
- <YaText fieldId="contact.addressValue" as="span">
83
- 123 Main Street, Suite 100
84
- <br />
85
- San Francisco, CA 94102
86
- </YaText>
87
- </p>
88
231
  </div>
89
232
  </div>
90
233
  </div>