@linktr.ee/linkapp 0.0.21 → 0.0.22
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/dev-server/classic/main.tsx +313 -29
- package/dev-server/classic.html +21 -35
- package/dev-server/components/SettingsPreview.tsx +330 -0
- package/dev-server/components/ui/dialog.tsx +6 -3
- package/dev-server/featured/main.tsx +313 -29
- package/dev-server/featured.html +21 -35
- package/dev-server/index.html +8 -1
- package/dev-server/lib/utils.ts +6 -0
- package/dev-server/package-lock.json +245 -287
- package/dev-server/package.json +5 -1
- package/dev-server/postcss.config.mjs +5 -0
- package/dev-server/preview/Preview.tsx +95 -69
- package/dev-server/preview/preview.css +20 -35
- package/dev-server/public/apple-touch-icon.png +0 -0
- package/dev-server/public/favicon-96x96.png +0 -0
- package/dev-server/public/favicon.ico +0 -0
- package/dev-server/public/favicon.svg +6 -0
- package/dev-server/public/site.webmanifest +21 -0
- package/dev-server/public/web-app-manifest-192x192.png +0 -0
- package/dev-server/public/web-app-manifest-512x512.png +0 -0
- package/dev-server/vite-env.d.ts +8 -0
- package/dev-server/vite.config.ts +5 -0
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +19 -17
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +110 -2
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/test-url-match-rules.js +1 -1
- package/dist/commands/test-url-match-rules.js.map +1 -1
- package/dist/components/index.d.ts +0 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +2 -1
- package/dist/components/index.js.map +1 -1
- package/dist/lib/auth/device-flow.d.ts +1 -6
- package/dist/lib/auth/device-flow.d.ts.map +1 -1
- package/dist/lib/auth/device-flow.js +3 -9
- package/dist/lib/auth/device-flow.js.map +1 -1
- package/dist/lib/auth/token-storage.d.ts +0 -5
- package/dist/lib/auth/token-storage.d.ts.map +1 -1
- package/dist/lib/auth/token-storage.js +16 -14
- package/dist/lib/auth/token-storage.js.map +1 -1
- package/dist/lib/deploy/generate-manifest-files.js +1 -1
- package/dist/lib/deploy/generate-manifest-files.js.map +1 -1
- package/dist/lib/deploy/pack-project.js +1 -1
- package/dist/lib/deploy/pack-project.js.map +1 -1
- package/dist/lib/deploy/test-url-match-rules.d.ts +2 -1
- package/dist/lib/deploy/test-url-match-rules.d.ts.map +1 -1
- package/dist/lib/deploy/test-url-match-rules.js +1 -1
- package/dist/lib/deploy/test-url-match-rules.js.map +1 -1
- package/dist/lib/deploy/upload.d.ts.map +1 -1
- package/dist/lib/deploy/upload.js +7 -3
- package/dist/lib/deploy/upload.js.map +1 -1
- package/dist/lib/utils/setup-runtime.d.ts.map +1 -1
- package/dist/lib/utils/setup-runtime.js +29 -2
- package/dist/lib/utils/setup-runtime.js.map +1 -1
- package/dist/lib/vite/config-factory.d.ts.map +1 -1
- package/dist/lib/vite/config-factory.js +3 -2
- package/dist/lib/vite/config-factory.js.map +1 -1
- package/dist/schema/config.schema.d.ts +104 -32
- package/dist/schema/config.schema.d.ts.map +1 -1
- package/dist/schema/config.schema.js +27 -17
- package/dist/schema/config.schema.js.map +1 -1
- package/dist/types.d.ts +6 -57
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -2
- package/runtime/index.html +19 -36
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { LinkAppSettings, SettingsElement } from "../../src/types";
|
|
2
|
+
|
|
3
|
+
interface SettingsPreviewProps {
|
|
4
|
+
settings: LinkAppSettings;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function SettingsPreview({ settings }: SettingsPreviewProps) {
|
|
8
|
+
return (
|
|
9
|
+
<div className="max-w-4xl mx-auto p-6 space-y-6">
|
|
10
|
+
{/* Header */}
|
|
11
|
+
<div className="space-y-2">
|
|
12
|
+
<h2 className="text-2xl font-bold">{settings.title}</h2>
|
|
13
|
+
{settings.overview && (
|
|
14
|
+
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4">
|
|
15
|
+
{settings.overview.title && (
|
|
16
|
+
<h3 className="font-semibold text-blue-900 mb-1">
|
|
17
|
+
{settings.overview.title}
|
|
18
|
+
</h3>
|
|
19
|
+
)}
|
|
20
|
+
<p className="text-blue-800 text-sm">
|
|
21
|
+
{settings.overview.description}
|
|
22
|
+
</p>
|
|
23
|
+
</div>
|
|
24
|
+
)}
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
{/* Metadata */}
|
|
28
|
+
<div className="grid grid-cols-2 gap-4 bg-gray-50 border border-gray-200 rounded-lg p-4">
|
|
29
|
+
<div>
|
|
30
|
+
<span className="text-sm font-medium text-gray-600">Uses URL:</span>
|
|
31
|
+
<span className="ml-2 text-sm">
|
|
32
|
+
{settings.uses_url || settings.has_url ? "Yes" : "No"}
|
|
33
|
+
</span>
|
|
34
|
+
</div>
|
|
35
|
+
<div>
|
|
36
|
+
<span className="text-sm font-medium text-gray-600">
|
|
37
|
+
Supports Featured Layout:
|
|
38
|
+
</span>
|
|
39
|
+
<span className="ml-2 text-sm">
|
|
40
|
+
{settings.supports_featured_layout ? "Yes" : "No"}
|
|
41
|
+
</span>
|
|
42
|
+
</div>
|
|
43
|
+
{settings.icon && (
|
|
44
|
+
<div>
|
|
45
|
+
<span className="text-sm font-medium text-gray-600">Icon:</span>
|
|
46
|
+
<span className="ml-2 text-sm">{settings.icon}</span>
|
|
47
|
+
</div>
|
|
48
|
+
)}
|
|
49
|
+
{settings.settings_tab_title && (
|
|
50
|
+
<div>
|
|
51
|
+
<span className="text-sm font-medium text-gray-600">
|
|
52
|
+
Settings Tab Title:
|
|
53
|
+
</span>
|
|
54
|
+
<span className="ml-2 text-sm">{settings.settings_tab_title}</span>
|
|
55
|
+
</div>
|
|
56
|
+
)}
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
{/* Setup Instructions */}
|
|
60
|
+
{settings.setup_instructions && (
|
|
61
|
+
<div className="bg-green-50 border border-green-200 rounded-lg p-4">
|
|
62
|
+
{settings.setup_instructions.title && (
|
|
63
|
+
<h3 className="font-semibold text-green-900 mb-1">
|
|
64
|
+
{settings.setup_instructions.title}
|
|
65
|
+
</h3>
|
|
66
|
+
)}
|
|
67
|
+
<p className="text-green-800 text-sm">
|
|
68
|
+
{settings.setup_instructions.description}
|
|
69
|
+
</p>
|
|
70
|
+
</div>
|
|
71
|
+
)}
|
|
72
|
+
|
|
73
|
+
{/* Settings Elements */}
|
|
74
|
+
<div className="space-y-4">
|
|
75
|
+
<h3 className="text-xl font-semibold">Settings Elements</h3>
|
|
76
|
+
{settings.elements.length === 0 ? (
|
|
77
|
+
<p className="text-gray-500 italic">No settings elements defined</p>
|
|
78
|
+
) : (
|
|
79
|
+
<div className="space-y-4">
|
|
80
|
+
{settings.elements.map((element, index) => (
|
|
81
|
+
<SettingsElementCard key={element.id} element={element} index={index} />
|
|
82
|
+
))}
|
|
83
|
+
</div>
|
|
84
|
+
)}
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
interface SettingsElementCardProps {
|
|
91
|
+
element: SettingsElement;
|
|
92
|
+
index: number;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function SettingsElementCard({ element, index }: SettingsElementCardProps) {
|
|
96
|
+
return (
|
|
97
|
+
<div className="border border-gray-300 rounded-lg p-4 bg-white shadow-sm">
|
|
98
|
+
<div className="flex items-start justify-between mb-3">
|
|
99
|
+
<div className="flex-1">
|
|
100
|
+
<div className="flex items-center gap-2">
|
|
101
|
+
<span className="text-xs font-mono bg-gray-100 px-2 py-1 rounded">
|
|
102
|
+
{index + 1}
|
|
103
|
+
</span>
|
|
104
|
+
<h4 className="font-semibold text-lg">{element.title || element.label}</h4>
|
|
105
|
+
</div>
|
|
106
|
+
<p className="text-sm text-gray-600 mt-1">
|
|
107
|
+
<span className="font-mono text-xs bg-blue-100 text-blue-800 px-1.5 py-0.5 rounded">
|
|
108
|
+
{element.id}
|
|
109
|
+
</span>
|
|
110
|
+
</p>
|
|
111
|
+
</div>
|
|
112
|
+
<span className="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium bg-purple-100 text-purple-800">
|
|
113
|
+
{element.inputType}
|
|
114
|
+
</span>
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
{element.description && (
|
|
118
|
+
<p className="text-sm text-gray-700 mb-3">{element.description}</p>
|
|
119
|
+
)}
|
|
120
|
+
|
|
121
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-3 text-sm">
|
|
122
|
+
{element.placeholder && (
|
|
123
|
+
<div>
|
|
124
|
+
<span className="font-medium text-gray-600">Placeholder:</span>
|
|
125
|
+
<span className="ml-2 text-gray-800">{element.placeholder}</span>
|
|
126
|
+
</div>
|
|
127
|
+
)}
|
|
128
|
+
|
|
129
|
+
{element.defaultValue !== undefined && (
|
|
130
|
+
<div>
|
|
131
|
+
<span className="font-medium text-gray-600">Default Value:</span>
|
|
132
|
+
<span className="ml-2 text-gray-800 font-mono text-xs">
|
|
133
|
+
{typeof element.defaultValue === "boolean"
|
|
134
|
+
? element.defaultValue.toString()
|
|
135
|
+
: Array.isArray(element.defaultValue)
|
|
136
|
+
? `[${element.defaultValue.join(", ")}]`
|
|
137
|
+
: element.defaultValue}
|
|
138
|
+
</span>
|
|
139
|
+
</div>
|
|
140
|
+
)}
|
|
141
|
+
|
|
142
|
+
{element.validation && (
|
|
143
|
+
<div className="col-span-2">
|
|
144
|
+
<span className="font-medium text-gray-600">Validation:</span>
|
|
145
|
+
<div className="ml-2 mt-1 space-y-1">
|
|
146
|
+
{element.validation.required && (
|
|
147
|
+
<div className="text-xs">
|
|
148
|
+
<span className="bg-red-100 text-red-800 px-2 py-0.5 rounded">
|
|
149
|
+
Required
|
|
150
|
+
</span>
|
|
151
|
+
</div>
|
|
152
|
+
)}
|
|
153
|
+
{element.validation.minLength !== undefined && (
|
|
154
|
+
<div className="text-xs text-gray-600">
|
|
155
|
+
Min Length: {element.validation.minLength}
|
|
156
|
+
</div>
|
|
157
|
+
)}
|
|
158
|
+
{element.validation.maxLength !== undefined && (
|
|
159
|
+
<div className="text-xs text-gray-600">
|
|
160
|
+
Max Length: {element.validation.maxLength}
|
|
161
|
+
</div>
|
|
162
|
+
)}
|
|
163
|
+
{element.validation.min !== undefined && (
|
|
164
|
+
<div className="text-xs text-gray-600">
|
|
165
|
+
Min: {element.validation.min}
|
|
166
|
+
</div>
|
|
167
|
+
)}
|
|
168
|
+
{element.validation.max !== undefined && (
|
|
169
|
+
<div className="text-xs text-gray-600">
|
|
170
|
+
Max: {element.validation.max}
|
|
171
|
+
</div>
|
|
172
|
+
)}
|
|
173
|
+
{element.validation.maxSize !== undefined && (
|
|
174
|
+
<div className="text-xs text-gray-600">
|
|
175
|
+
Max Size: {element.validation.maxSize}
|
|
176
|
+
</div>
|
|
177
|
+
)}
|
|
178
|
+
{element.validation.pattern && (
|
|
179
|
+
<div className="text-xs text-gray-600 font-mono">
|
|
180
|
+
Pattern: {element.validation.pattern}
|
|
181
|
+
</div>
|
|
182
|
+
)}
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
)}
|
|
186
|
+
|
|
187
|
+
{element.options && element.options.length > 0 && (
|
|
188
|
+
<div className="col-span-2">
|
|
189
|
+
<span className="font-medium text-gray-600">Options:</span>
|
|
190
|
+
<div className="ml-2 mt-1 space-y-1">
|
|
191
|
+
{element.options.map((option) => (
|
|
192
|
+
<div key={option.value} className="text-xs bg-gray-50 px-2 py-1 rounded">
|
|
193
|
+
<span className="font-mono text-blue-700">{option.value}</span>
|
|
194
|
+
<span className="mx-1 text-gray-400">→</span>
|
|
195
|
+
<span>{option.label}</span>
|
|
196
|
+
</div>
|
|
197
|
+
))}
|
|
198
|
+
</div>
|
|
199
|
+
</div>
|
|
200
|
+
)}
|
|
201
|
+
|
|
202
|
+
{element.linkBehaviorLabels && (
|
|
203
|
+
<div className="col-span-2">
|
|
204
|
+
<span className="font-medium text-gray-600">Link Behavior Labels:</span>
|
|
205
|
+
<div className="ml-2 mt-1 space-y-1">
|
|
206
|
+
<div className="text-xs">
|
|
207
|
+
<span className="font-medium">Embed:</span> {element.linkBehaviorLabels.embedLabel}
|
|
208
|
+
</div>
|
|
209
|
+
<div className="text-xs">
|
|
210
|
+
<span className="font-medium">Link Off:</span> {element.linkBehaviorLabels.linkOffLabel}
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
</div>
|
|
214
|
+
)}
|
|
215
|
+
|
|
216
|
+
{element.accept && element.accept.length > 0 && (
|
|
217
|
+
<div className="col-span-2">
|
|
218
|
+
<span className="font-medium text-gray-600">Accepted Files:</span>
|
|
219
|
+
<span className="ml-2 text-xs font-mono">
|
|
220
|
+
{element.accept.join(", ")}
|
|
221
|
+
</span>
|
|
222
|
+
</div>
|
|
223
|
+
)}
|
|
224
|
+
|
|
225
|
+
{element.multiple && (
|
|
226
|
+
<div>
|
|
227
|
+
<span className="bg-orange-100 text-orange-800 px-2 py-0.5 rounded text-xs">
|
|
228
|
+
Multiple values allowed
|
|
229
|
+
</span>
|
|
230
|
+
</div>
|
|
231
|
+
)}
|
|
232
|
+
|
|
233
|
+
{element.capability && (
|
|
234
|
+
<div>
|
|
235
|
+
<span className="font-medium text-gray-600">Integration Capability:</span>
|
|
236
|
+
<span className="ml-2 text-xs">{element.capability}</span>
|
|
237
|
+
</div>
|
|
238
|
+
)}
|
|
239
|
+
|
|
240
|
+
{element.vendor && (
|
|
241
|
+
<div>
|
|
242
|
+
<span className="font-medium text-gray-600">Vendor:</span>
|
|
243
|
+
<span className="ml-2 text-xs">{element.vendor}</span>
|
|
244
|
+
</div>
|
|
245
|
+
)}
|
|
246
|
+
|
|
247
|
+
{element.array_options && (
|
|
248
|
+
<div className="col-span-2">
|
|
249
|
+
<span className="font-medium text-gray-600">Array Options:</span>
|
|
250
|
+
<div className="ml-2 mt-1 space-y-1 text-xs">
|
|
251
|
+
{element.array_options.add_item_button_text && (
|
|
252
|
+
<div>Add Button: "{element.array_options.add_item_button_text}"</div>
|
|
253
|
+
)}
|
|
254
|
+
{element.array_options.add_item_title && (
|
|
255
|
+
<div>Add Title: "{element.array_options.add_item_title}"</div>
|
|
256
|
+
)}
|
|
257
|
+
{element.array_options.edit_item_title && (
|
|
258
|
+
<div>Edit Title: "{element.array_options.edit_item_title}"</div>
|
|
259
|
+
)}
|
|
260
|
+
{element.array_options.item_format && (
|
|
261
|
+
<div>Item Format: "{element.array_options.item_format}"</div>
|
|
262
|
+
)}
|
|
263
|
+
{element.array_options.min !== undefined && (
|
|
264
|
+
<div>Min Items: {element.array_options.min}</div>
|
|
265
|
+
)}
|
|
266
|
+
{element.array_options.max !== undefined && (
|
|
267
|
+
<div>Max Items: {element.array_options.max}</div>
|
|
268
|
+
)}
|
|
269
|
+
</div>
|
|
270
|
+
</div>
|
|
271
|
+
)}
|
|
272
|
+
|
|
273
|
+
{element.array_elements && element.array_elements.length > 0 && (
|
|
274
|
+
<div className="col-span-2">
|
|
275
|
+
<span className="font-medium text-gray-600">Array Elements:</span>
|
|
276
|
+
<div className="ml-2 mt-2 space-y-2">
|
|
277
|
+
{element.array_elements.map((arrayElement, arrayIndex) => (
|
|
278
|
+
<div key={arrayElement.id} className="bg-gray-50 border border-gray-200 rounded p-3">
|
|
279
|
+
<div className="text-xs font-mono text-blue-700 mb-1">
|
|
280
|
+
{arrayElement.id}
|
|
281
|
+
</div>
|
|
282
|
+
<div className="text-xs">
|
|
283
|
+
<span className="font-medium">Type:</span> {arrayElement.inputType}
|
|
284
|
+
</div>
|
|
285
|
+
{arrayElement.label && (
|
|
286
|
+
<div className="text-xs">
|
|
287
|
+
<span className="font-medium">Label:</span> {arrayElement.label}
|
|
288
|
+
</div>
|
|
289
|
+
)}
|
|
290
|
+
{arrayElement.placeholder && (
|
|
291
|
+
<div className="text-xs">
|
|
292
|
+
<span className="font-medium">Placeholder:</span> {arrayElement.placeholder}
|
|
293
|
+
</div>
|
|
294
|
+
)}
|
|
295
|
+
</div>
|
|
296
|
+
))}
|
|
297
|
+
</div>
|
|
298
|
+
</div>
|
|
299
|
+
)}
|
|
300
|
+
|
|
301
|
+
{element.conditionalDisplay && (
|
|
302
|
+
<div className="col-span-2">
|
|
303
|
+
<span className="font-medium text-gray-600">Conditional Display:</span>
|
|
304
|
+
<div className="ml-2 mt-1 text-xs bg-yellow-50 border border-yellow-200 rounded p-2">
|
|
305
|
+
Depends on <span className="font-mono">{element.conditionalDisplay.dependsOn}</span>
|
|
306
|
+
{" "}
|
|
307
|
+
{element.conditionalDisplay.operator || "equals"}
|
|
308
|
+
{" "}
|
|
309
|
+
<span className="font-mono">{String(element.conditionalDisplay.value)}</span>
|
|
310
|
+
</div>
|
|
311
|
+
</div>
|
|
312
|
+
)}
|
|
313
|
+
|
|
314
|
+
{element.action && (
|
|
315
|
+
<div className="col-span-2">
|
|
316
|
+
<span className="font-medium text-gray-600">Action:</span>
|
|
317
|
+
<div className="ml-2 mt-1 text-xs">
|
|
318
|
+
On {element.action.on}: {element.action.type}
|
|
319
|
+
{element.action.data && (
|
|
320
|
+
<div className="font-mono text-xs mt-1 bg-gray-50 p-1 rounded">
|
|
321
|
+
{JSON.stringify(element.action.data, null, 2)}
|
|
322
|
+
</div>
|
|
323
|
+
)}
|
|
324
|
+
</div>
|
|
325
|
+
</div>
|
|
326
|
+
)}
|
|
327
|
+
</div>
|
|
328
|
+
</div>
|
|
329
|
+
);
|
|
330
|
+
}
|
|
@@ -45,12 +45,15 @@ function DialogContent({
|
|
|
45
45
|
<DialogPrimitive.Content
|
|
46
46
|
data-slot="dialog-content"
|
|
47
47
|
className={cn(
|
|
48
|
-
'bg-background fixed top-[50%] left-[50%] z-50
|
|
48
|
+
'bg-background fixed top-[50%] left-[50%] z-50 w-full translate-x-[-50%] translate-y-[-50%] rounded-3xl duration-200',
|
|
49
49
|
className
|
|
50
50
|
)}
|
|
51
51
|
{...props}
|
|
52
52
|
>
|
|
53
|
-
|
|
53
|
+
<div className="flex h-full flex-col">
|
|
54
|
+
{children}
|
|
55
|
+
</div>
|
|
56
|
+
|
|
54
57
|
{showCloseButton && (
|
|
55
58
|
<DialogPrimitive.Close
|
|
56
59
|
data-slot="dialog-close"
|
|
@@ -69,7 +72,7 @@ function DialogHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
|
69
72
|
return (
|
|
70
73
|
<div
|
|
71
74
|
data-slot="dialog-header"
|
|
72
|
-
className={cn(
|
|
75
|
+
className={cn(className)}
|
|
73
76
|
{...props}
|
|
74
77
|
/>
|
|
75
78
|
)
|