@explorer02/cfm-survey-sdk 0.2.2 → 0.2.4

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 (113) hide show
  1. package/dist/cli/index.js +140 -33
  2. package/dist/cli/index.mjs +140 -33
  3. package/dist/index.js +1 -1
  4. package/dist/index.mjs +1 -1
  5. package/package.json +8 -1
  6. package/postinstall.js +8 -5
  7. package/templates/AGENT.md +62 -17
  8. package/templates/deploy-wizard-to-s3.sh +52 -0
  9. package/templates/docs/00-integration/agent-execution-flow.md +281 -0
  10. package/templates/docs/00-integration/agent-operating-contract.md +260 -0
  11. package/templates/docs/00-integration/analytics-events-catalog.md +54 -0
  12. package/templates/docs/00-integration/apply-ui-config.md +365 -0
  13. package/templates/docs/00-integration/canonical-survey-fixtures.md +94 -0
  14. package/templates/docs/00-integration/client-integration-guide.md +10 -8
  15. package/templates/docs/00-integration/client-lib-folder.md +115 -0
  16. package/templates/docs/00-integration/component-checklist.md +90 -54
  17. package/templates/docs/00-integration/constraints.md +13 -5
  18. package/templates/docs/00-integration/custom-field-logic-and-navigation.md +56 -0
  19. package/templates/docs/00-integration/display-logic-and-navigation.md +16 -1
  20. package/templates/docs/00-integration/file-upload-aws.md +116 -0
  21. package/templates/docs/00-integration/logic-fields-catalog.md +105 -0
  22. package/templates/docs/00-integration/partial-save-and-recovery.md +24 -0
  23. package/templates/docs/00-integration/progress.md +4 -2
  24. package/templates/docs/00-integration/question-type-sdk-matrix.md +11 -9
  25. package/templates/docs/00-integration/setup.md +15 -3
  26. package/templates/docs/00-integration/skip-logic-and-navigation.md +1 -1
  27. package/templates/docs/00-integration/survey-lifecycle-analytics.md +1 -1
  28. package/templates/docs/00-integration/ui-customization-wizard.md +144 -0
  29. package/templates/docs/00-integration/useSurveySDK.md +35 -1
  30. package/templates/docs/00-integration/wizard-api.md +134 -0
  31. package/templates/docs/00-integration/wizard-config-handoff.md +246 -0
  32. package/templates/docs/00-integration/wizard-preview-build-guide.md +400 -0
  33. package/templates/docs/00-integration/wizard-question-type-styling.md +195 -0
  34. package/templates/docs/01-components/01-survey-page.md +18 -8
  35. package/templates/docs/01-components/02-question.md +2 -2
  36. package/templates/docs/01-components/03-rating-scale.md +12 -18
  37. package/templates/docs/01-components/05-csat-matrix-scale.md +18 -26
  38. package/templates/docs/01-components/06-likert-matrix-scale.md +19 -38
  39. package/templates/docs/01-components/07-slider-matrix-scale.md +48 -33
  40. package/templates/docs/01-components/08-file-upload-scale.md +15 -52
  41. package/templates/docs/01-components/09-custom-slider-track.md +15 -25
  42. package/templates/docs/01-components/10-header-footer.md +23 -4
  43. package/templates/docs/01-components/11-progress-bar.md +14 -6
  44. package/templates/docs/01-components/13-matrix-dropdown.md +28 -33
  45. package/templates/docs/01-components/17-heatmap-scale.md +4 -4
  46. package/templates/docs/01-components/18-rank-order-scale.md +24 -31
  47. package/templates/docs/01-components/19-survey-sticky-chrome.md +79 -0
  48. package/templates/docs/01-components/README.md +2 -2
  49. package/templates/docs/02-reference/question-types/10-slider-matrix.md +38 -26
  50. package/templates/docs/02-reference/question-types/11-file-upload.md +36 -21
  51. package/templates/docs/02-reference/question-types/README.md +11 -1
  52. package/templates/docs/02-reference/routing-table.md +1 -0
  53. package/templates/docs/02-reference/value-derivation.md +1 -1
  54. package/templates/docs/03-ui-specs/00-question-shell.md +10 -0
  55. package/templates/docs/03-ui-specs/01-rating.md +28 -2
  56. package/templates/docs/03-ui-specs/02-radio.md +94 -24
  57. package/templates/docs/03-ui-specs/03-text.md +12 -1
  58. package/templates/docs/03-ui-specs/04-csat.md +90 -26
  59. package/templates/docs/03-ui-specs/06-slider.md +3 -1
  60. package/templates/docs/03-ui-specs/07-matrix-cfm.md +74 -35
  61. package/templates/docs/03-ui-specs/08-matrix-csat-rating.md +50 -16
  62. package/templates/docs/03-ui-specs/09-slider-matrix.md +70 -26
  63. package/templates/docs/03-ui-specs/10-file-upload.md +52 -20
  64. package/templates/docs/03-ui-specs/11-text-and-media.md +4 -0
  65. package/templates/docs/03-ui-specs/12-survey-chrome.md +92 -5
  66. package/templates/docs/03-ui-specs/13-heatmap.md +21 -3
  67. package/templates/docs/03-ui-specs/14-rank-order.md +108 -28
  68. package/templates/docs/03-ui-specs/README.md +11 -7
  69. package/templates/docs/03-ui-specs/shared/custom-slider-track.md +28 -35
  70. package/templates/docs/03-ui-specs/shared/matrix-dropdown.md +1 -1
  71. package/templates/docs/MANIFEST.json +187 -6
  72. package/templates/docs/index.md +116 -116
  73. package/templates/docs/templates/CsatMatrixScale.tsx +637 -0
  74. package/templates/docs/templates/CustomSliderTrack.tsx +144 -0
  75. package/templates/docs/templates/FileUploadScale.tsx +262 -0
  76. package/templates/docs/templates/HeatmapScale.tsx +114 -0
  77. package/templates/docs/templates/LikertMatrixScale.tsx +414 -0
  78. package/templates/docs/templates/MatrixDropdown.tsx +216 -0
  79. package/templates/docs/templates/Question.tsx +3 -0
  80. package/templates/docs/templates/RankOrderScale.tsx +353 -0
  81. package/templates/docs/templates/RatingScale.tsx +129 -0
  82. package/templates/docs/templates/SliderMatrixScale.tsx +248 -0
  83. package/templates/docs/templates/SurveyStickyChrome.tsx +24 -0
  84. package/templates/docs/templates/customFieldValues.ts +36 -0
  85. package/templates/docs/templates/implementation_plan.md +75 -8
  86. package/templates/docs/templates/labelStyles.ts +33 -0
  87. package/templates/docs/templates/selectionStyles.ts +100 -0
  88. package/templates/docs/templates/survey-inventory.schema.json +28 -23
  89. package/templates/docs/templates/surveyUiIcons.tsx +63 -0
  90. package/templates/docs/templates/surveyUiScaleUtils.ts +51 -0
  91. package/templates/docs/templates/verify-agent-build.sh +151 -0
  92. package/templates/preview-harness/preview-bridge.inline.js +201 -0
  93. package/templates/preview-harness/previewPages.js +108 -0
  94. package/templates/preview-harness/previewPages.ts +298 -0
  95. package/templates/preview-harness/vite-app/src/PreviewConfigContext.tsx +67 -0
  96. package/templates/preview-harness/vite-app/src/QuestionPreview.tsx +122 -0
  97. package/templates/preview-harness/vite-app/src/SurveyPagePreview.tsx +75 -0
  98. package/templates/preview-harness/vite-app/src/fixtures/questions.ts +311 -0
  99. package/templates/preview-harness/vite-app/src/globals.css +16 -0
  100. package/templates/preview-harness/vite-app/src/mount.tsx +9 -0
  101. package/templates/preview-harness/vite-app/src/preview-live-overrides.css +101 -0
  102. package/templates/preview-harness/vite-app/stubs/next-dynamic.tsx +25 -0
  103. package/templates/preview-harness/vite-app/stubs/next-image.tsx +29 -0
  104. package/templates/previewBridge.ts +153 -0
  105. package/templates/survey-theme.css +295 -0
  106. package/templates/survey-ui-config.schema.json +213 -0
  107. package/templates/wizard-dist/assets/PreviewMock-DgHfrVeb.js +1 -0
  108. package/templates/wizard-dist/assets/TypePanel-CFVC3Ptn.js +1 -0
  109. package/templates/wizard-dist/assets/index-BhWM50Yu.css +1 -0
  110. package/templates/wizard-dist/assets/index-DYK3X1e5.js +34 -0
  111. package/templates/wizard-dist/assets/vendor-BwkXDkd3.js +17 -0
  112. package/templates/wizard-dist/index.html +20 -0
  113. package/templates/wizard.html +13 -1129
@@ -1,1139 +1,23 @@
1
1
  <!DOCTYPE html>
2
- <html lang="en" class="h-full bg-slate-950 text-slate-100">
2
+ <html lang="en">
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>CFM Survey SDK — Setup Wizard</title>
7
- <!-- Google Fonts -->
8
- <link rel="preconnect" href="https://fonts.googleapis.com">
9
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Outfit:wght@400;500;600;700;800&display=swap" rel="stylesheet">
11
- <!-- Tailwind CSS CDN -->
12
- <script src="https://cdn.tailwindcss.com"></script>
13
- <script>
14
- tailwind.config = {
15
- theme: {
16
- extend: {
17
- fontFamily: {
18
- sans: ['Inter', 'sans-serif'],
19
- display: ['Outfit', 'sans-serif'],
20
- },
21
- },
22
- },
23
- }
24
- </script>
6
+ <title>CFM Survey SDK — Wizard Moved</title>
25
7
  <style>
26
- /* Glassmorphism custom helpers */
27
- .glass-panel {
28
- background: rgba(15, 23, 42, 0.45);
29
- backdrop-filter: blur(16px);
30
- -webkit-backdrop-filter: blur(16px);
31
- border: 1px solid rgba(255, 255, 255, 0.08);
32
- }
33
- .glass-card {
34
- background: rgba(30, 41, 59, 0.4);
35
- border: 1px solid rgba(255, 255, 255, 0.05);
36
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
37
- }
38
- .glass-card:hover {
39
- background: rgba(30, 41, 59, 0.65);
40
- border-color: rgba(99, 102, 241, 0.4);
41
- box-shadow: 0 10px 30px -10px rgba(99, 102, 241, 0.15);
42
- }
43
- .glass-card.active {
44
- background: rgba(99, 102, 241, 0.15);
45
- border-color: rgba(99, 102, 241, 0.8);
46
- box-shadow: 0 0 20px rgba(99, 102, 241, 0.2);
47
- }
48
- /* Custom scrollbar */
49
- ::-webkit-scrollbar {
50
- width: 6px;
51
- height: 6px;
52
- }
53
- ::-webkit-scrollbar-track {
54
- background: rgba(15, 23, 42, 0.3);
55
- }
56
- ::-webkit-scrollbar-thumb {
57
- background: rgba(255, 255, 255, 0.1);
58
- border-radius: 999px;
59
- }
60
- ::-webkit-scrollbar-thumb:hover {
61
- background: rgba(255, 255, 255, 0.2);
62
- }
8
+ body { font-family: system-ui, sans-serif; background: #0f172a; color: #e2e8f0; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; padding: 2rem; }
9
+ .card { max-width: 480px; text-align: center; background: rgba(30,41,59,0.6); border: 1px solid rgba(255,255,255,0.08); border-radius: 1rem; padding: 2.5rem; }
10
+ h1 { font-size: 1.5rem; margin-bottom: 0.5rem; }
11
+ p { color: #94a3b8; font-size: 0.9rem; line-height: 1.6; }
12
+ code { background: #1e293b; padding: 0.15rem 0.4rem; border-radius: 0.25rem; color: #818cf8; }
63
13
  </style>
64
14
  </head>
65
- <body class="h-full font-sans flex overflow-hidden selection:bg-indigo-500 selection:text-white">
66
-
67
- <!-- BACKGROUND DECORATIONS -->
68
- <div class="absolute inset-0 -z-10 bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-indigo-950/30 via-slate-950 to-slate-950"></div>
69
- <div class="absolute top-0 left-1/4 w-[500px] h-[500px] bg-indigo-500/10 rounded-full blur-[120px] -z-10 animate-pulse"></div>
70
- <div class="absolute bottom-0 right-1/4 w-[600px] h-[600px] bg-cyan-500/5 rounded-full blur-[150px] -z-10"></div>
71
-
72
- <!-- MAIN CONTAINER -->
73
- <div class="flex-1 flex overflow-hidden glass-panel m-4 md:m-6 lg:m-8 rounded-3xl shadow-2xl shadow-slate-950/50">
74
-
75
- <!-- LEFT SIDEBAR: STEPS -->
76
- <aside class="w-80 border-r border-white/5 flex flex-col justify-between p-8 bg-slate-950/20 backdrop-blur-md hidden md:flex">
77
- <div>
78
- <div class="flex items-center gap-3 mb-10">
79
- <div class="h-10 w-10 rounded-xl bg-gradient-to-tr from-indigo-500 to-cyan-500 flex items-center justify-center shadow-lg shadow-indigo-500/20">
80
- <svg class="w-6 h-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
81
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M13 10V3L4 14h7v7l9-11h-7z"/>
82
- </svg>
83
- </div>
84
- <div>
85
- <h1 class="font-display font-bold text-lg leading-tight bg-gradient-to-r from-white to-slate-300 bg-clip-text text-transparent">CFM Survey SDK</h1>
86
- <span class="text-xs text-indigo-400 font-semibold tracking-wider uppercase">Setup Wizard</span>
87
- </div>
88
- </div>
89
-
90
- <nav class="space-y-1">
91
- <div data-step="0" class="step-tab flex items-center gap-4 px-4 py-3 rounded-xl transition-all cursor-pointer bg-white/5 text-white font-medium border-l-4 border-indigo-500">
92
- <span class="w-6 h-6 rounded-full bg-indigo-500 text-white font-bold text-xs flex items-center justify-center shadow-md shadow-indigo-500/30">0</span>
93
- <span class="text-sm">Mockup Setup</span>
94
- </div>
95
- <div data-step="1" class="step-tab flex items-center gap-4 px-4 py-3 rounded-xl transition-all cursor-pointer text-slate-400 hover:text-slate-200">
96
- <span class="w-6 h-6 rounded-full bg-slate-800 text-slate-400 font-bold text-xs flex items-center justify-center border border-white/5">1</span>
97
- <span class="text-sm">Survey Identity</span>
98
- </div>
99
- <div data-step="2" class="step-tab flex items-center gap-4 px-4 py-3 rounded-xl transition-all cursor-pointer text-slate-400 hover:text-slate-200">
100
- <span class="w-6 h-6 rounded-full bg-slate-800 text-slate-400 font-bold text-xs flex items-center justify-center border border-white/5">2</span>
101
- <span class="text-sm">Logo Setup</span>
102
- </div>
103
- <div data-step="3" class="step-tab flex items-center gap-4 px-4 py-3 rounded-xl transition-all cursor-pointer text-slate-400 hover:text-slate-200">
104
- <span class="w-6 h-6 rounded-full bg-slate-800 text-slate-400 font-bold text-xs flex items-center justify-center border border-white/5">3</span>
105
- <span class="text-sm">UI Layout</span>
106
- </div>
107
- <div data-step="4" class="step-tab flex items-center gap-4 px-4 py-3 rounded-xl transition-all cursor-pointer text-slate-400 hover:text-slate-200">
108
- <span class="w-6 h-6 rounded-full bg-slate-800 text-slate-400 font-bold text-xs flex items-center justify-center border border-white/5">4</span>
109
- <span class="text-sm">Color Branding</span>
110
- </div>
111
- <div data-step="5" class="step-tab flex items-center gap-4 px-4 py-3 rounded-xl transition-all cursor-pointer text-slate-400 hover:text-slate-200">
112
- <span class="w-6 h-6 rounded-full bg-slate-800 text-slate-400 font-bold text-xs flex items-center justify-center border border-white/5">5</span>
113
- <span class="text-sm">Config & Mode</span>
114
- </div>
115
- <div data-step="6" class="step-tab flex items-center gap-4 px-4 py-3 rounded-xl transition-all cursor-pointer text-slate-400 hover:text-slate-200">
116
- <span class="w-6 h-6 rounded-full bg-slate-800 text-slate-400 font-bold text-xs flex items-center justify-center border border-white/5">6</span>
117
- <span class="text-sm">Ready to Build</span>
118
- </div>
119
- </nav>
120
- </div>
121
-
122
- <div class="pt-6 border-t border-white/5">
123
- <button id="btn-skip-all" type="button" class="w-full text-center py-2 px-4 rounded-xl border border-white/10 text-xs font-medium text-slate-400 hover:text-white hover:bg-white/5 hover:border-white/20 transition-all">
124
- Skip All Remaining & Finish
125
- </button>
126
- </div>
127
- </aside>
128
-
129
- <!-- CENTER & RIGHT: MAIN WORK AREA -->
130
- <div class="flex-1 flex flex-col justify-between overflow-hidden">
131
- <!-- HEADER -->
132
- <header class="h-20 border-b border-white/5 flex items-center justify-between px-8 bg-slate-900/10">
133
- <div class="flex items-center gap-2">
134
- <span class="h-2.5 w-2.5 rounded-full bg-emerald-500 animate-pulse"></span>
135
- <span class="text-xs text-slate-400 font-medium tracking-wide">Local Configuration Server is active</span>
136
- </div>
137
- <div>
138
- <button id="btn-quit" type="button" class="text-xs text-slate-400 hover:text-red-400 transition-all py-1.5 px-3 rounded-lg hover:bg-red-500/10 border border-transparent hover:border-red-500/10">
139
- Quit Setup
140
- </button>
141
- </div>
142
- </header>
143
-
144
- <!-- CONTENT BODY (SPLIT FORM & LIVE PREVIEW) -->
145
- <main class="flex-1 flex overflow-hidden">
146
-
147
- <!-- LEFT: SCROLLABLE FORM -->
148
- <div class="flex-1 overflow-y-auto p-8 md:p-10 lg:p-12 space-y-8 min-w-[320px]">
149
-
150
- <form id="wizard-form" onsubmit="event.preventDefault();" class="h-full flex flex-col justify-between">
151
- <div class="space-y-6">
152
-
153
- <!-- STEP 0: MOCKUP SETUP -->
154
- <section id="step-panel-0" class="step-panel space-y-6">
155
- <div class="space-y-2">
156
- <span class="text-indigo-400 text-xs font-semibold uppercase tracking-wider">Phase 0 of 7</span>
157
- <h2 class="font-display font-bold text-2xl lg:text-3xl text-white">Mockup Detection</h2>
158
- <p class="text-sm text-slate-400">If you shared mockup images with the AI agent in the IDE chat, the agent can analyze them to match the visual layout and styles.</p>
159
- </div>
160
-
161
- <div class="space-y-4">
162
- <label class="block text-sm font-medium text-slate-300">Did you provide UI mockup screenshots in the chat?</label>
163
- <div class="grid grid-cols-2 gap-4">
164
- <button type="button" data-val="true" data-field="hasMockup" class="toggle-card glass-card p-6 rounded-2xl text-center focus:outline-none flex flex-col items-center gap-2">
165
- <span class="text-lg font-bold text-white">Yes</span>
166
- <span class="text-xs text-slate-400">Agent will replicate screens</span>
167
- </button>
168
- <button type="button" data-val="false" data-field="hasMockup" class="toggle-card glass-card p-6 rounded-2xl text-center focus:outline-none flex flex-col items-center gap-2 active">
169
- <span class="text-lg font-bold text-white">No</span>
170
- <span class="text-xs text-slate-400">Design a standard visual UI</span>
171
- </button>
172
- </div>
173
- </div>
174
- </section>
175
-
176
- <!-- STEP 1: SURVEY IDENTITY -->
177
- <section id="step-panel-1" class="step-panel space-y-6 hidden">
178
- <div class="space-y-2">
179
- <span class="text-indigo-400 text-xs font-semibold uppercase tracking-wider">Phase 1 of 7</span>
180
- <h2 class="font-display font-bold text-2xl lg:text-3xl text-white">Survey Identity</h2>
181
- <p class="text-sm text-slate-400">Configure corporate branding and headings displayed to users.</p>
182
- </div>
183
-
184
- <div class="space-y-4">
185
- <div class="space-y-1">
186
- <label for="input-surveyTitle" class="block text-xs font-medium text-slate-400 uppercase tracking-wider">Survey Title</label>
187
- <input type="text" id="input-surveyTitle" placeholder="Customer Feedback Survey" class="w-full bg-slate-900 border border-white/10 rounded-xl px-4 py-3 text-sm text-white focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-all">
188
- </div>
189
- <div class="space-y-1">
190
- <label for="input-companyName" class="block text-xs font-medium text-slate-400 uppercase tracking-wider">Company Name</label>
191
- <input type="text" id="input-companyName" placeholder="Sprinklr" class="w-full bg-slate-900 border border-white/10 rounded-xl px-4 py-3 text-sm text-white focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-all">
192
- </div>
193
- <div class="space-y-1">
194
- <label for="input-browserTabTitle" class="block text-xs font-medium text-slate-400 uppercase tracking-wider">Browser Tab Title</label>
195
- <input type="text" id="input-browserTabTitle" placeholder="Customer Feedback Survey" class="w-full bg-slate-900 border border-white/10 rounded-xl px-4 py-3 text-sm text-white focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-all">
196
- </div>
197
- <div class="space-y-1">
198
- <label for="input-thankYouMessage" class="block text-xs font-medium text-slate-400 uppercase tracking-wider">Thank-You Message</label>
199
- <input type="text" id="input-thankYouMessage" placeholder="Thank you for your valuable feedback!" class="w-full bg-slate-900 border border-white/10 rounded-xl px-4 py-3 text-sm text-white focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-all">
200
- </div>
201
- </div>
202
- </section>
203
-
204
- <!-- STEP 2: LOGO SETUP -->
205
- <section id="step-panel-2" class="step-panel space-y-6 hidden">
206
- <div class="space-y-2">
207
- <span class="text-indigo-400 text-xs font-semibold uppercase tracking-wider">Phase 2 of 7</span>
208
- <h2 class="font-display font-bold text-2xl lg:text-3xl text-white">Logo Setup</h2>
209
- <p class="text-sm text-slate-400">Drag and drop your brand logo here. It will be saved automatically to your project's <code>public/</code> folder.</p>
210
- </div>
211
-
212
- <div class="space-y-4">
213
- <div id="logo-dropzone" class="border-2 border-dashed border-white/10 hover:border-indigo-500/50 transition-all rounded-3xl p-8 text-center cursor-pointer flex flex-col items-center justify-center gap-3 bg-slate-900/40">
214
- <svg class="w-10 h-10 text-slate-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
215
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/>
216
- </svg>
217
- <div>
218
- <p class="text-sm text-slate-200 font-medium">Click to upload or drag logo here</p>
219
- <p class="text-xs text-slate-400 mt-1">Supports PNG, JPG, SVG. Leaves blank to use default Sprinklr logo.</p>
220
- </div>
221
- <input type="file" id="input-logoFile" class="hidden" accept="image/*">
222
- </div>
223
-
224
- <div id="logo-preview-container" class="hidden glass-card p-4 rounded-2xl flex items-center justify-between gap-4">
225
- <div class="flex items-center gap-3">
226
- <img id="logo-preview-img" src="" class="max-h-12 w-auto object-contain rounded bg-slate-950 p-1 border border-white/5">
227
- <div>
228
- <p id="logo-preview-name" class="text-xs text-white font-medium max-w-[200px] truncate"></p>
229
- <p class="text-[10px] text-emerald-400 flex items-center gap-1 font-semibold">
230
- <span class="h-1.5 w-1.5 rounded-full bg-emerald-400"></span> Uploaded & Ready
231
- </p>
232
- </div>
233
- </div>
234
- <button id="btn-remove-logo" type="button" class="text-xs text-slate-400 hover:text-red-400 transition-all">Remove</button>
235
- </div>
236
- </div>
237
- </section>
238
-
239
- <!-- STEP 3: UI LAYOUT -->
240
- <section id="step-panel-3" class="step-panel space-y-6 hidden">
241
- <div class="space-y-2">
242
- <span class="text-indigo-400 text-xs font-semibold uppercase tracking-wider">Phase 3 of 7</span>
243
- <h2 class="font-display font-bold text-2xl lg:text-3xl text-white">UI Layout</h2>
244
- <p class="text-sm text-slate-400">Adjust the core components and structure of your survey UI.</p>
245
- </div>
246
-
247
- <div class="space-y-5">
248
- <div class="flex items-center justify-between border-b border-white/5 pb-3">
249
- <div>
250
- <h4 class="text-sm font-medium text-white">Show Header Bar</h4>
251
- <p class="text-xs text-slate-400">Render logo and company name at the top</p>
252
- </div>
253
- <button type="button" data-field="showHeader" class="toggle-btn w-12 h-6 rounded-full bg-indigo-500 p-0.5 transition-all flex items-center justify-end focus:outline-none"><span class="w-5 h-5 rounded-full bg-white shadow-md"></span></button>
254
- </div>
255
-
256
- <div class="flex items-center justify-between border-b border-white/5 pb-3">
257
- <div>
258
- <h4 class="text-sm font-medium text-white">Show Footer</h4>
259
- <p class="text-xs text-slate-400">Render copyright and default footer links</p>
260
- </div>
261
- <button type="button" data-field="showFooter" class="toggle-btn w-12 h-6 rounded-full bg-indigo-500 p-0.5 transition-all flex items-center justify-end focus:outline-none"><span class="w-5 h-5 rounded-full bg-white shadow-md"></span></button>
262
- </div>
263
-
264
- <div class="flex items-center justify-between border-b border-white/5 pb-3">
265
- <div>
266
- <h4 class="text-sm font-medium text-white">Show Progress Bar</h4>
267
- <p class="text-xs text-slate-400">Displays survey completion status</p>
268
- </div>
269
- <button type="button" data-field="showProgressBar" class="toggle-btn w-12 h-6 rounded-full bg-indigo-500 p-0.5 transition-all flex items-center justify-end focus:outline-none"><span class="w-5 h-5 rounded-full bg-white shadow-md"></span></button>
270
- </div>
271
-
272
- <div class="flex items-center justify-between border-b border-white/5 pb-3">
273
- <div>
274
- <h4 class="text-sm font-medium text-white">Language Switcher</h4>
275
- <p class="text-xs text-slate-400">Include language selection dropdown</p>
276
- </div>
277
- <button type="button" data-field="showLanguageSwitcher" class="toggle-btn w-12 h-6 rounded-full bg-slate-800 p-0.5 transition-all flex items-center justify-start focus:outline-none"><span class="w-5 h-5 rounded-full bg-slate-400 shadow-md"></span></button>
278
- </div>
279
-
280
- <div class="flex items-center justify-between border-b border-white/5 pb-3">
281
- <div>
282
- <h4 class="text-sm font-medium text-white">Show "Next" Button</h4>
283
- <p class="text-xs text-slate-400">Allows moving forward in multi-page surveys</p>
284
- </div>
285
- <button type="button" data-field="showNextButton" class="toggle-btn w-12 h-6 rounded-full bg-indigo-500 p-0.5 transition-all flex items-center justify-end focus:outline-none"><span class="w-5 h-5 rounded-full bg-white shadow-md"></span></button>
286
- </div>
287
-
288
- <div id="next-label-container" class="space-y-1 pl-4 border-l border-white/10">
289
- <label for="input-nextButtonText" class="block text-[10px] font-medium text-slate-400 uppercase tracking-wider">Next Button Label</label>
290
- <input type="text" id="input-nextButtonText" placeholder="Next" class="w-full bg-slate-900 border border-white/10 rounded-xl px-4 py-2 text-xs text-white focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-all">
291
- </div>
292
-
293
- <div class="flex items-center justify-between border-b border-white/5 pb-3">
294
- <div>
295
- <h4 class="text-sm font-medium text-white">Show "Back" Button</h4>
296
- <p class="text-xs text-slate-400">Allows navigating back to prior pages</p>
297
- </div>
298
- <button type="button" data-field="showBackButton" class="toggle-btn w-12 h-6 rounded-full bg-indigo-500 p-0.5 transition-all flex items-center justify-end focus:outline-none"><span class="w-5 h-5 rounded-full bg-white shadow-md"></span></button>
299
- </div>
300
-
301
- <div id="back-label-container" class="space-y-1 pl-4 border-l border-white/10">
302
- <label for="input-backButtonText" class="block text-[10px] font-medium text-slate-400 uppercase tracking-wider">Back Button Label</label>
303
- <input type="text" id="input-backButtonText" placeholder="Back" class="w-full bg-slate-900 border border-white/10 rounded-xl px-4 py-2 text-xs text-white focus:outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 transition-all">
304
- </div>
305
-
306
- <div class="flex items-center justify-between border-b border-white/5 pb-3">
307
- <div>
308
- <h4 class="text-sm font-medium text-white">Question Numbers</h4>
309
- <p class="text-xs text-slate-400">Prefix labels with Q1, Q2, etc.</p>
310
- </div>
311
- <button type="button" data-field="showQuestionNumbers" class="toggle-btn w-12 h-6 rounded-full bg-indigo-500 p-0.5 transition-all flex items-center justify-end focus:outline-none"><span class="w-5 h-5 rounded-full bg-white shadow-md"></span></button>
312
- </div>
313
-
314
- <div class="flex items-center justify-between border-b border-white/5 pb-3">
315
- <div>
316
- <h4 class="text-sm font-medium text-white">Required Indicator</h4>
317
- <p class="text-xs text-slate-400">Append asterisk (*) to required fields</p>
318
- </div>
319
- <button type="button" data-field="showRequiredAsterisk" class="toggle-btn w-12 h-6 rounded-full bg-indigo-500 p-0.5 transition-all flex items-center justify-end focus:outline-none"><span class="w-5 h-5 rounded-full bg-white shadow-md"></span></button>
320
- </div>
321
-
322
- <div class="flex items-center justify-between border-b border-white/5 pb-3">
323
- <div>
324
- <h4 class="text-sm font-medium text-white">Animations</h4>
325
- <p class="text-xs text-slate-400">Enable transitions between steps</p>
326
- </div>
327
- <button type="button" data-field="animationsEnabled" class="toggle-btn w-12 h-6 rounded-full bg-indigo-500 p-0.5 transition-all flex items-center justify-end focus:outline-none"><span class="w-5 h-5 rounded-full bg-white shadow-md"></span></button>
328
- </div>
329
-
330
- <div class="grid grid-cols-3 gap-3">
331
- <div class="space-y-1">
332
- <label for="select-width" class="block text-[10px] font-medium text-slate-400 uppercase tracking-wider">Width</label>
333
- <select id="select-width" class="w-full bg-slate-900 border border-white/10 rounded-xl px-3 py-2 text-xs text-white focus:outline-none transition-all">
334
- <option value="narrow">Narrow (xl)</option>
335
- <option value="standard" selected>Standard (3xl)</option>
336
- <option value="wide">Wide (5xl)</option>
337
- </select>
338
- </div>
339
- <div class="space-y-1">
340
- <label for="select-borderStyle" class="block text-[10px] font-medium text-slate-400 uppercase tracking-wider">Corners</label>
341
- <select id="select-borderStyle" class="w-full bg-slate-900 border border-white/10 rounded-xl px-3 py-2 text-xs text-white focus:outline-none transition-all">
342
- <option value="sharp">Sharp</option>
343
- <option value="rounded" selected>Rounded</option>
344
- <option value="pill">Pill</option>
345
- </select>
346
- </div>
347
- <div class="space-y-1">
348
- <label for="select-fontStyle" class="block text-[10px] font-medium text-slate-400 uppercase tracking-wider">Font</label>
349
- <select id="select-fontStyle" class="w-full bg-slate-900 border border-white/10 rounded-xl px-3 py-2 text-xs text-white focus:outline-none transition-all">
350
- <option value="system">System</option>
351
- <option value="modern" selected>Modern Inter</option>
352
- <option value="serif">Classic Serif</option>
353
- </select>
354
- </div>
355
- </div>
356
- </div>
357
- </section>
358
-
359
- <!-- STEP 4: COLOR BRANDING -->
360
- <section id="step-panel-4" class="step-panel space-y-6 hidden">
361
- <div class="space-y-2">
362
- <span class="text-indigo-400 text-xs font-semibold uppercase tracking-wider">Phase 4 of 7</span>
363
- <h2 class="font-display font-bold text-2xl lg:text-3xl text-white">Color Branding</h2>
364
- <p class="text-sm text-slate-400">Establish the survey theme palette.</p>
365
- </div>
366
-
367
- <div class="space-y-4">
368
- <div class="space-y-2">
369
- <label class="block text-xs font-medium text-slate-400 uppercase tracking-wider">Theme Source</label>
370
- <div class="grid grid-cols-2 gap-2">
371
- <button type="button" data-val="auto" data-field="colorSource" class="theme-source-card glass-card p-3 rounded-xl text-xs text-center font-medium text-white active">Agent Auto Pick</button>
372
- <button type="button" data-val="logo" data-field="colorSource" class="theme-source-card glass-card p-3 rounded-xl text-xs text-center font-medium text-white">Derive from Logo</button>
373
- <button type="button" data-val="mockup" id="btn-theme-mockup" data-field="colorSource" class="theme-source-card glass-card p-3 rounded-xl text-xs text-center font-medium text-white opacity-40 cursor-not-allowed" disabled>Extract Mockup</button>
374
- <button type="button" data-val="custom" data-field="colorSource" class="theme-source-card glass-card p-3 rounded-xl text-xs text-center font-medium text-white">Custom Scheme</button>
375
- </div>
376
- </div>
377
-
378
- <!-- CUSTOM SCHEME CONFIGURATION -->
379
- <div id="custom-theme-container" class="hidden space-y-4 pt-4 border-t border-white/5">
380
- <div class="space-y-2">
381
- <label class="block text-xs font-medium text-slate-400 uppercase tracking-wider">Custom Setup Mode</label>
382
- <div class="grid grid-cols-2 gap-2">
383
- <button type="button" id="btn-pick-presets" class="glass-card p-3 rounded-xl text-xs text-center font-semibold text-white active">Curated Presets</button>
384
- <button type="button" id="btn-pick-hex" class="glass-card p-3 rounded-xl text-xs text-center font-semibold text-white">Custom Hex Codes</button>
385
- </div>
386
- </div>
387
-
388
- <!-- PRESETS SELECTION -->
389
- <div id="presets-panel" class="space-y-2">
390
- <label class="block text-xs font-medium text-slate-400">Choose Curated Scheme</label>
391
- <div class="space-y-2" id="presets-list">
392
- <!-- Filled in JS -->
393
- </div>
394
- </div>
395
-
396
- <!-- HEX INPUTS -->
397
- <div id="hex-panel" class="hidden space-y-3">
398
- <label class="block text-xs font-medium text-slate-400">Configure Color Swatches</label>
399
- <div class="grid grid-cols-2 gap-3">
400
- <div class="space-y-1">
401
- <label class="text-[10px] text-slate-400 font-medium">Primary (Main)</label>
402
- <div class="flex items-center gap-1.5">
403
- <input type="color" id="hex-primary" value="#1A1F36" class="w-6 h-6 rounded-md bg-transparent border-0 cursor-pointer p-0">
404
- <input type="text" id="text-primary" value="#1A1F36" class="bg-slate-900 border border-white/10 rounded-lg px-2 py-1 text-xs text-white w-20">
405
- </div>
406
- </div>
407
- <div class="space-y-1">
408
- <label class="text-[10px] text-slate-400 font-medium">Secondary (Light bg)</label>
409
- <div class="flex items-center gap-1.5">
410
- <input type="color" id="hex-secondary" value="#E8F5FD" class="w-6 h-6 rounded-md bg-transparent border-0 cursor-pointer p-0">
411
- <input type="text" id="text-secondary" value="#E8F5FD" class="bg-slate-900 border border-white/10 rounded-lg px-2 py-1 text-xs text-white w-20">
412
- </div>
413
- </div>
414
- <div class="space-y-1">
415
- <label class="text-[10px] text-slate-400 font-medium">Accent (Details)</label>
416
- <div class="flex items-center gap-1.5">
417
- <input type="color" id="hex-accent" value="#00B5AD" class="w-6 h-6 rounded-md bg-transparent border-0 cursor-pointer p-0">
418
- <input type="text" id="text-accent" value="#00B5AD" class="bg-slate-900 border border-white/10 rounded-lg px-2 py-1 text-xs text-white w-20">
419
- </div>
420
- </div>
421
- <div class="space-y-1">
422
- <label class="text-[10px] text-slate-400 font-medium">Background</label>
423
- <div class="flex items-center gap-1.5">
424
- <input type="color" id="hex-background" value="#FFFFFF" class="w-6 h-6 rounded-md bg-transparent border-0 cursor-pointer p-0">
425
- <input type="text" id="text-background" value="#FFFFFF" class="bg-slate-900 border border-white/10 rounded-lg px-2 py-1 text-xs text-white w-20">
426
- </div>
427
- </div>
428
- <div class="space-y-1 col-span-2">
429
- <label class="text-[10px] text-slate-400 font-medium">Text Color</label>
430
- <div class="flex items-center gap-1.5">
431
- <input type="color" id="hex-text" value="#1A1F36" class="w-6 h-6 rounded-md bg-transparent border-0 cursor-pointer p-0">
432
- <input type="text" id="text-text" value="#1A1F36" class="bg-slate-900 border border-white/10 rounded-lg px-2 py-1 text-xs text-white w-20">
433
- </div>
434
- </div>
435
- </div>
436
- </div>
437
- </div>
438
- </div>
439
- </section>
440
-
441
- <!-- STEP 5: CONFIG & MODE -->
442
- <section id="step-panel-5" class="step-panel space-y-6 hidden">
443
- <div class="space-y-2">
444
- <span class="text-indigo-400 text-xs font-semibold uppercase tracking-wider">Phase 5 of 7</span>
445
- <h2 class="font-display font-bold text-2xl lg:text-3xl text-white">Variables & Mode</h2>
446
- <p class="text-sm text-slate-400">Configure query placeholder mappings and environment settings.</p>
447
- </div>
448
-
449
- <div class="space-y-4">
450
- <div class="grid grid-cols-2 gap-4">
451
- <div class="space-y-1">
452
- <label for="input-firstName" class="block text-[10px] font-medium text-slate-400 uppercase tracking-wider">Test First Name</label>
453
- <input type="text" id="input-firstName" placeholder="Unnat" class="w-full bg-slate-900 border border-white/10 rounded-xl px-4 py-2.5 text-xs text-white focus:outline-none focus:border-indigo-500 transition-all">
454
- </div>
455
- <div class="space-y-1">
456
- <label for="input-lastName" class="block text-[10px] font-medium text-slate-400 uppercase tracking-wider">Test Last Name</label>
457
- <input type="text" id="input-lastName" placeholder="Agrawal" class="w-full bg-slate-900 border border-white/10 rounded-xl px-4 py-2.5 text-xs text-white focus:outline-none focus:border-indigo-500 transition-all">
458
- </div>
459
- </div>
460
-
461
- <div class="space-y-1">
462
- <label for="input-email" class="block text-[10px] font-medium text-slate-400 uppercase tracking-wider">Test Email Address</label>
463
- <input type="email" id="input-email" placeholder="unnat.agrawal@sprinklr.com" class="w-full bg-slate-900 border border-white/10 rounded-xl px-4 py-2.5 text-xs text-white focus:outline-none focus:border-indigo-500 transition-all">
464
- </div>
465
-
466
- <div class="flex items-center justify-between border-t border-white/5 pt-4">
467
- <div>
468
- <h4 class="text-sm font-medium text-white">Debug / Test Mode</h4>
469
- <p class="text-xs text-slate-400">Outputs debug telemetry in browser console</p>
470
- </div>
471
- <button type="button" data-field="debug" class="toggle-btn w-12 h-6 rounded-full bg-indigo-500 p-0.5 transition-all flex items-center justify-end focus:outline-none"><span class="w-5 h-5 rounded-full bg-white shadow-md"></span></button>
472
- </div>
473
- </div>
474
- </section>
475
-
476
- <!-- STEP 6: READY TO BUILD -->
477
- <section id="step-panel-6" class="step-panel space-y-6 hidden">
478
- <div class="space-y-2">
479
- <span class="text-indigo-400 text-xs font-semibold uppercase tracking-wider">Phase 6 of 7</span>
480
- <h2 class="font-display font-bold text-2xl lg:text-3xl text-white">Deploy & Complete</h2>
481
- <p class="text-sm text-slate-400">Configure auto-deployment preferences before saving the config.</p>
482
- </div>
483
-
484
- <div class="space-y-5">
485
- <div class="flex items-center justify-between">
486
- <div>
487
- <h4 class="text-sm font-medium text-white">Auto-Deploy to Vercel</h4>
488
- <p class="text-xs text-slate-400">Runs deployment script automatically upon compile success</p>
489
- </div>
490
- <button type="button" data-field="deployToVercel" class="toggle-btn w-12 h-6 rounded-full bg-indigo-500 p-0.5 transition-all flex items-center justify-end focus:outline-none"><span class="w-5 h-5 rounded-full bg-white shadow-md"></span></button>
491
- </div>
492
-
493
- <div class="glass-card p-6 rounded-2xl border border-indigo-500/20 bg-indigo-500/5 mt-6 space-y-3">
494
- <h4 class="text-sm font-bold text-indigo-300 flex items-center gap-2">
495
- <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
496
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
497
- </svg>
498
- Setup Complete!
499
- </h4>
500
- <p class="text-xs text-slate-300 leading-relaxed">Click <strong>Complete Setup</strong> below to save your configuration file. The IDE agent will read it instantly and proceed to build your survey interface.</p>
501
- </div>
502
- </div>
503
- </section>
504
-
505
- </div>
506
-
507
- <!-- BUTTONS NAVIGATION -->
508
- <div class="flex items-center justify-between border-t border-white/5 pt-6 mt-8">
509
- <button id="btn-prev" type="button" class="px-5 py-2.5 rounded-xl border border-white/10 text-sm font-medium text-slate-300 hover:text-white hover:bg-white/5 hover:border-white/20 transition-all opacity-0 pointer-events-none">
510
- Previous
511
- </button>
512
- <div class="flex gap-3">
513
- <button id="btn-skip" type="button" class="px-5 py-2.5 rounded-xl text-sm font-medium text-slate-400 hover:text-white transition-all">
514
- Skip
515
- </button>
516
- <button id="btn-next" type="button" class="px-6 py-2.5 rounded-xl bg-indigo-600 hover:bg-indigo-500 text-sm font-semibold text-white shadow-lg shadow-indigo-600/20 hover:shadow-indigo-500/30 transition-all">
517
- Next
518
- </button>
519
- <button id="btn-finish" type="button" class="hidden px-6 py-2.5 rounded-xl bg-gradient-to-r from-indigo-500 to-cyan-500 hover:from-indigo-400 hover:to-cyan-400 text-sm font-bold text-white shadow-lg shadow-indigo-500/20 transition-all">
520
- Complete Setup
521
- </button>
522
- </div>
523
- </div>
524
- </form>
525
-
526
- </div>
527
-
528
- <!-- RIGHT: SURVEY THEME PREVIEW PANEL -->
529
- <div class="w-[420px] border-l border-white/5 bg-slate-950/40 p-8 flex flex-col justify-between hidden lg:flex select-none">
530
- <div class="space-y-4">
531
- <h3 class="font-display font-bold text-sm text-slate-400 uppercase tracking-wider">Real-time Preview</h3>
532
-
533
- <!-- SAMPLE SURVEY CARD PREVIEW -->
534
- <div id="preview-survey-card" class="rounded-2xl shadow-xl overflow-hidden border border-slate-800 transition-all duration-300 bg-white text-slate-900">
535
-
536
- <!-- HEADER -->
537
- <div id="preview-header" class="px-5 py-4 border-b flex items-center gap-3 transition-all duration-300">
538
- <img id="preview-logo" src="https://www.aprimo.com/wp-content/uploads/2024/03/Sprinklr_Logo-1.png" class="max-h-6 w-auto object-contain" alt="Logo">
539
- <span id="preview-companyName" class="text-xs font-semibold tracking-wider text-slate-800">Sprinklr</span>
540
- </div>
541
-
542
- <!-- CONTENT -->
543
- <div class="p-6 space-y-6">
544
- <!-- PROGRESS -->
545
- <div id="preview-progress-container" class="space-y-1.5">
546
- <div class="flex justify-between text-[10px] text-slate-400 font-semibold">
547
- <span>Progress</span>
548
- <span>35%</span>
549
- </div>
550
- <div class="w-full h-1.5 bg-slate-100 rounded-full overflow-hidden">
551
- <div id="preview-progress-bar" class="w-[35%] h-full bg-[#00B5AD] rounded-full transition-all duration-300"></div>
552
- </div>
553
- </div>
554
-
555
- <!-- QUESTION -->
556
- <div class="space-y-3">
557
- <h4 class="text-sm font-bold leading-snug flex gap-1.5 items-start">
558
- <span id="preview-q-num" class="text-slate-400 font-medium">Q1.</span>
559
- <span id="preview-surveyTitle">Customer Feedback Survey</span>
560
- <span id="preview-asterisk" class="text-red-500">*</span>
561
- </h4>
562
- <p class="text-[11px] text-slate-400">How would you rate your overall branding and configuration setup experience?</p>
563
-
564
- <!-- RATING ROW -->
565
- <div class="grid grid-cols-5 gap-2">
566
- <button type="button" class="preview-badge h-9 rounded-lg border text-xs font-semibold flex items-center justify-center transition-all bg-[#E8F5FD] border-indigo-500/20 text-[#1A1F36]">1</button>
567
- <button type="button" class="preview-badge h-9 rounded-lg border text-xs font-semibold flex items-center justify-center transition-all bg-slate-50 border-slate-200 hover:bg-slate-100 text-slate-700">2</button>
568
- <button type="button" class="preview-badge h-9 rounded-lg border text-xs font-semibold flex items-center justify-center transition-all bg-slate-50 border-slate-200 hover:bg-slate-100 text-slate-700">3</button>
569
- <button type="button" class="preview-badge h-9 rounded-lg border text-xs font-semibold flex items-center justify-center transition-all bg-slate-50 border-slate-200 hover:bg-slate-100 text-slate-700">4</button>
570
- <button type="button" class="preview-badge h-9 rounded-lg border text-xs font-semibold flex items-center justify-center transition-all bg-slate-50 border-slate-200 hover:bg-slate-100 text-slate-700">5</button>
571
- </div>
572
- </div>
573
- </div>
574
-
575
- <!-- FOOTER & BUTTONS -->
576
- <div class="px-6 py-4 border-t bg-slate-50/50 flex items-center justify-between">
577
- <button type="button" id="preview-btn-back" class="text-[10px] font-semibold text-slate-500 px-3 py-1.5 rounded-lg border border-slate-200 bg-white">Back</button>
578
- <button type="button" id="preview-btn-next" class="text-[10px] font-bold text-white px-4 py-1.5 rounded-lg bg-[#1A1F36] shadow-sm">Next</button>
579
- </div>
580
-
581
- </div>
582
- </div>
583
-
584
- <!-- FOOTER / HINT -->
585
- <div class="text-[10px] text-slate-500 leading-normal bg-slate-900/10 p-4 rounded-xl border border-white/5">
586
- This card represents a live visualization of the generated colors and components configured in your survey config.
587
- </div>
588
- </div>
589
-
590
- </main>
591
- </div>
592
-
15
+ <body>
16
+ <div class="card">
17
+ <h1>UI Customization Wizard</h1>
18
+ <p>This wizard has moved to a React app. After building your survey and starting the dev server, run:</p>
19
+ <p><code>npx cfm-sdk customize</code></p>
20
+ <p style="margin-top:1rem;font-size:0.8rem;">Build the wizard first: <code>npm run build:wizard</code> in packages/sdk</p>
593
21
  </div>
594
-
595
- <!-- JS CONTROLS -->
596
- <script>
597
- // State Variables
598
- let currentStep = 0;
599
- const totalSteps = 7;
600
-
601
- const config = {
602
- hasMockup: false,
603
- surveyTitle: "Customer Feedback Survey",
604
- companyName: "Sprinklr",
605
- browserTabTitle: "Customer Feedback Survey",
606
- thankYouMessage: "Thank you for your valuable feedback!",
607
- logo: {
608
- fileName: null,
609
- defaultUrl: "https://www.aprimo.com/wp-content/uploads/2024/03/Sprinklr_Logo-1.png"
610
- },
611
- layout: {
612
- showHeader: true,
613
- showFooter: true,
614
- showProgressBar: true,
615
- showLanguageSwitcher: false,
616
- showNextButton: true,
617
- showBackButton: true,
618
- width: "standard",
619
- borderStyle: "rounded",
620
- fontStyle: "modern",
621
- showQuestionNumbers: true,
622
- showRequiredAsterisk: true,
623
- animationsEnabled: true,
624
- },
625
- buttons: {
626
- submit: "Submit",
627
- next: "Next",
628
- back: "Back",
629
- },
630
- colorSource: "auto",
631
- colorScheme: {
632
- primary: "#1A1F36",
633
- secondary: "#E8F5FD",
634
- accent: "#00B5AD",
635
- background: "#FFFFFF",
636
- text: "#1A1F36",
637
- buttonText: "#FFFFFF",
638
- },
639
- placeholders: {
640
- firstName: "Unnat",
641
- lastName: "Agrawal",
642
- email: "unnat.agrawal@sprinklr.com",
643
- },
644
- debug: true,
645
- deployToVercel: true
646
- };
647
-
648
- const COLOR_SCHEMES_PRESETS = [
649
- { name: 'Indigo + Amber', primary: '#4F46E5', secondary: '#E0E7FF', accent: '#F59E0B', bg: '#FFFFFF', text: '#111827' },
650
- { name: 'Slate + Teal', primary: '#334155', secondary: '#F1F5F9', accent: '#0D9488', bg: '#FFFFFF', text: '#0F172A' },
651
- { name: 'Amber + Brown', primary: '#B45309', secondary: '#FEF3C7', accent: '#D97706', bg: '#FFFBEB', text: '#1C1917' },
652
- { name: 'Violet + Green', primary: '#7C3AED', secondary: '#EDE9FE', accent: '#10B981', bg: '#FFFFFF', text: '#111827' },
653
- { name: 'Navy + Sky', primary: '#1E3A5F', secondary: '#DBEAFE', accent: '#0284C7', bg: '#FFFFFF', text: '#1E293B' },
654
- ];
655
-
656
- // Curated Presets builder
657
- const presetsList = document.getElementById('presets-list');
658
- COLOR_SCHEMES_PRESETS.forEach((s, idx) => {
659
- const btn = document.createElement('button');
660
- btn.type = 'button';
661
- btn.className = `w-full text-left p-3 rounded-xl border border-white/5 bg-slate-900/50 hover:bg-slate-900/80 transition-all flex items-center justify-between text-xs focus:outline-none ${idx === 0 ? 'border-indigo-500/40 bg-slate-900/80' : ''}`;
662
- btn.onclick = () => {
663
- // Remove active border
664
- Array.from(presetsList.children).forEach(c => c.classList.remove('border-indigo-500/40', 'bg-slate-900/80'));
665
- btn.classList.add('border-indigo-500/40', 'bg-slate-900/80');
666
-
667
- config.colorScheme = {
668
- primary: s.primary,
669
- secondary: s.secondary,
670
- accent: s.accent,
671
- background: s.bg,
672
- text: s.text,
673
- buttonText: '#FFFFFF'
674
- };
675
- updatePreview();
676
- };
677
- btn.innerHTML = `
678
- <span class="font-medium text-slate-200">${s.name}</span>
679
- <div class="flex gap-1.5">
680
- <span class="w-3 h-3 rounded-full border border-white/10" style="background:${s.primary}"></span>
681
- <span class="w-3 h-3 rounded-full border border-white/10" style="background:${s.secondary}"></span>
682
- <span class="w-3 h-3 rounded-full border border-white/10" style="background:${s.accent}"></span>
683
- </div>
684
- `;
685
- presetsList.appendChild(btn);
686
- });
687
-
688
- // Step navigation controller
689
- function showStep(stepIndex) {
690
- document.querySelectorAll('.step-panel').forEach(p => p.classList.add('hidden'));
691
- document.getElementById(`step-panel-${stepIndex}`).classList.remove('hidden');
692
-
693
- // Update sidebar
694
- document.querySelectorAll('.step-tab').forEach((tab, idx) => {
695
- if (idx === stepIndex) {
696
- tab.className = "step-tab flex items-center gap-4 px-4 py-3 rounded-xl transition-all cursor-pointer bg-white/5 text-white font-medium border-l-4 border-indigo-500";
697
- tab.querySelector('span').className = "w-6 h-6 rounded-full bg-indigo-500 text-white font-bold text-xs flex items-center justify-center shadow-md shadow-indigo-500/30";
698
- } else if (idx < stepIndex) {
699
- // Completed
700
- tab.className = "step-tab flex items-center gap-4 px-4 py-3 rounded-xl transition-all cursor-pointer text-slate-300 font-medium";
701
- tab.querySelector('span').className = "w-6 h-6 rounded-full bg-indigo-500/10 text-indigo-400 font-bold text-xs flex items-center justify-center border border-indigo-500/30";
702
- } else {
703
- // Future
704
- tab.className = "step-tab flex items-center gap-4 px-4 py-3 rounded-xl transition-all cursor-pointer text-slate-400 hover:text-slate-200";
705
- tab.querySelector('span').className = "w-6 h-6 rounded-full bg-slate-800 text-slate-400 font-bold text-xs flex items-center justify-center border border-white/5";
706
- }
707
- });
708
-
709
- // Show/Hide back button
710
- if (stepIndex > 0) {
711
- document.getElementById('btn-prev').classList.remove('opacity-0', 'pointer-events-none');
712
- } else {
713
- document.getElementById('btn-prev').classList.add('opacity-0', 'pointer-events-none');
714
- }
715
-
716
- // Toggle next vs complete button
717
- if (stepIndex === totalSteps - 1) {
718
- document.getElementById('btn-next').classList.add('hidden');
719
- document.getElementById('btn-finish').classList.remove('hidden');
720
- } else {
721
- document.getElementById('btn-next').classList.remove('hidden');
722
- document.getElementById('btn-finish').classList.add('hidden');
723
- }
724
-
725
- currentStep = stepIndex;
726
- updatePreview();
727
- }
728
-
729
- // Toggle yes/no cards (mockup setup)
730
- document.querySelectorAll('.toggle-card').forEach(btn => {
731
- btn.onclick = () => {
732
- const field = btn.getAttribute('data-field');
733
- const val = btn.getAttribute('data-val') === 'true';
734
-
735
- // Remove active state
736
- document.querySelectorAll(`[data-field="${field}"]`).forEach(b => b.classList.remove('active'));
737
- btn.classList.add('active');
738
-
739
- config[field] = val;
740
-
741
- // Mockup specific: toggle options
742
- if (field === 'hasMockup') {
743
- const mockupBtn = document.getElementById('btn-theme-mockup');
744
- if (val) {
745
- mockupBtn.classList.remove('opacity-40', 'cursor-not-allowed');
746
- mockupBtn.removeAttribute('disabled');
747
- } else {
748
- mockupBtn.classList.add('opacity-40', 'cursor-not-allowed');
749
- mockupBtn.setAttribute('disabled', 'true');
750
- if (config.colorSource === 'mockup') {
751
- selectThemeSource('auto');
752
- }
753
- }
754
- }
755
- updatePreview();
756
- };
757
- });
758
-
759
- // Toggle slide-buttons (show/hide options)
760
- document.querySelectorAll('.toggle-btn').forEach(btn => {
761
- btn.onclick = () => {
762
- const field = btn.getAttribute('data-field');
763
- const isEnabled = btn.classList.contains('bg-indigo-500');
764
-
765
- if (isEnabled) {
766
- // Disable
767
- btn.className = "toggle-btn w-12 h-6 rounded-full bg-slate-800 p-0.5 transition-all flex items-center justify-start focus:outline-none";
768
- btn.querySelector('span').className = "w-5 h-5 rounded-full bg-slate-400 shadow-md";
769
- config.layout[field] = false;
770
- if (field === 'debug') config.debug = false;
771
- if (field === 'deployToVercel') config.deployToVercel = false;
772
- } else {
773
- // Enable
774
- btn.className = "toggle-btn w-12 h-6 rounded-full bg-indigo-500 p-0.5 transition-all flex items-center justify-end focus:outline-none";
775
- btn.querySelector('span').className = "w-5 h-5 rounded-full bg-white shadow-md";
776
- config.layout[field] = true;
777
- if (field === 'debug') config.debug = true;
778
- if (field === 'deployToVercel') config.deployToVercel = true;
779
- }
780
-
781
- // Show/hide sub inputs
782
- if (field === 'showNextButton') {
783
- document.getElementById('next-label-container').style.display = config.layout.showNextButton ? 'block' : 'none';
784
- }
785
- if (field === 'showBackButton') {
786
- document.getElementById('back-label-container').style.display = config.layout.showBackButton ? 'block' : 'none';
787
- }
788
-
789
- updatePreview();
790
- };
791
- });
792
-
793
- // Theme Source Card Selectors
794
- function selectThemeSource(val) {
795
- document.querySelectorAll(`[data-field="colorSource"]`).forEach(b => b.classList.remove('active'));
796
- const activeBtn = document.querySelector(`[data-field="colorSource"][data-val="${val}"]`);
797
- if (activeBtn) activeBtn.classList.add('active');
798
-
799
- config.colorSource = val;
800
-
801
- const customContainer = document.getElementById('custom-theme-container');
802
- if (val === 'custom') {
803
- customContainer.classList.remove('hidden');
804
- } else {
805
- customContainer.classList.add('hidden');
806
- }
807
-
808
- // Apply predefined colorScheme states for auto/logo modes
809
- if (val === 'auto' || val === 'logo' || val === 'mockup') {
810
- config.colorScheme = {
811
- primary: "#1A1F36",
812
- secondary: "#E8F5FD",
813
- accent: "#00B5AD",
814
- background: "#FFFFFF",
815
- text: "#1A1F36",
816
- buttonText: "#FFFFFF",
817
- };
818
- }
819
- updatePreview();
820
- }
821
-
822
- document.querySelectorAll('.theme-source-card').forEach(btn => {
823
- btn.onclick = () => {
824
- if (btn.hasAttribute('disabled')) return;
825
- selectThemeSource(btn.getAttribute('data-val'));
826
- };
827
- });
828
-
829
- // Custom Customizer mode toggles
830
- document.getElementById('btn-pick-presets').onclick = () => {
831
- document.getElementById('btn-pick-presets').classList.add('active');
832
- document.getElementById('btn-pick-hex').classList.remove('active');
833
- document.getElementById('presets-panel').classList.remove('hidden');
834
- document.getElementById('hex-panel').classList.add('hidden');
835
- };
836
-
837
- document.getElementById('btn-pick-hex').onclick = () => {
838
- document.getElementById('btn-pick-presets').classList.remove('active');
839
- document.getElementById('btn-pick-hex').classList.add('active');
840
- document.getElementById('presets-panel').classList.add('hidden');
841
- document.getElementById('hex-panel').classList.remove('hidden');
842
- };
843
-
844
- // Hex Color inputs bindings
845
- ['primary', 'secondary', 'accent', 'background', 'text'].forEach(type => {
846
- const picker = document.getElementById(`hex-${type}`);
847
- const text = document.getElementById(`text-${type}`);
848
-
849
- picker.oninput = () => {
850
- text.value = picker.value.toUpperCase();
851
- config.colorScheme[type] = picker.value;
852
- updatePreview();
853
- };
854
-
855
- text.oninput = () => {
856
- let val = text.value;
857
- if (!val.startsWith('#')) val = '#' + val;
858
- if (/^#[0-9A-Fa-f]{6}$/.test(val)) {
859
- picker.value = val;
860
- config.colorScheme[type] = val;
861
- updatePreview();
862
- }
863
- };
864
- });
865
-
866
- // Logo Upload Logic
867
- const dropzone = document.getElementById('logo-dropzone');
868
- const fileInput = document.getElementById('input-logoFile');
869
-
870
- dropzone.onclick = () => fileInput.click();
871
-
872
- dropzone.ondragover = (e) => {
873
- e.preventDefault();
874
- dropzone.classList.add('border-indigo-500', 'bg-slate-900/60');
875
- };
876
-
877
- dropzone.ondragleave = () => {
878
- dropzone.classList.remove('border-indigo-500', 'bg-slate-900/60');
879
- };
880
-
881
- dropzone.ondrop = (e) => {
882
- e.preventDefault();
883
- dropzone.classList.remove('border-indigo-500', 'bg-slate-900/60');
884
- if (e.dataTransfer.files.length) {
885
- handleLogoFile(e.dataTransfer.files[0]);
886
- }
887
- };
888
-
889
- fileInput.onchange = () => {
890
- if (fileInput.files.length) {
891
- handleLogoFile(fileInput.files[0]);
892
- }
893
- };
894
-
895
- function handleLogoFile(file) {
896
- const reader = new FileReader();
897
- reader.onload = () => {
898
- const base64 = reader.result;
899
- // Post logo to server
900
- fetch('/api/upload-logo', {
901
- method: 'POST',
902
- headers: { 'Content-Type': 'application/json' },
903
- body: JSON.stringify({
904
- filename: file.name,
905
- base64: base64
906
- })
907
- })
908
- .then(res => res.json())
909
- .then(data => {
910
- if (data.fileName) {
911
- config.logo.fileName = data.fileName;
912
- config.logo.defaultUrl = null;
913
-
914
- // Show preview box
915
- document.getElementById('logo-dropzone').classList.add('hidden');
916
- const preview = document.getElementById('logo-preview-container');
917
- preview.classList.remove('hidden');
918
- document.getElementById('logo-preview-img').src = base64;
919
- document.getElementById('logo-preview-name').innerText = file.name;
920
-
921
- updatePreview();
922
- }
923
- })
924
- .catch(err => {
925
- alert('Failed to upload logo: ' + err.message);
926
- });
927
- };
928
- reader.readAsDataURL(file);
929
- }
930
-
931
- // Remove Logo
932
- document.getElementById('btn-remove-logo').onclick = () => {
933
- config.logo.fileName = null;
934
- config.logo.defaultUrl = "https://www.aprimo.com/wp-content/uploads/2024/03/Sprinklr_Logo-1.png";
935
-
936
- document.getElementById('logo-preview-container').classList.add('hidden');
937
- document.getElementById('logo-dropzone').classList.remove('hidden');
938
- fileInput.value = '';
939
-
940
- updatePreview();
941
- };
942
-
943
- // Real-time Visualizer Sync
944
- function updatePreview() {
945
- // Inputs read
946
- config.surveyTitle = document.getElementById('input-surveyTitle').value || "Customer Feedback Survey";
947
- config.companyName = document.getElementById('input-companyName').value || "Sprinklr";
948
- config.browserTabTitle = document.getElementById('input-browserTabTitle').value || config.surveyTitle;
949
- config.thankYouMessage = document.getElementById('input-thankYouMessage').value || "Thank you for your valuable feedback!";
950
-
951
- config.placeholders.firstName = document.getElementById('input-firstName').value || "Unnat";
952
- config.placeholders.lastName = document.getElementById('input-lastName').value || "Agrawal";
953
- config.placeholders.email = document.getElementById('input-email').value || "unnat.agrawal@sprinklr.com";
954
-
955
- config.layout.width = document.getElementById('select-width').value;
956
- config.layout.borderStyle = document.getElementById('select-borderStyle').value;
957
- config.layout.fontStyle = document.getElementById('select-fontStyle').value;
958
-
959
- config.buttons.next = document.getElementById('input-nextButtonText').value || "Next";
960
- config.buttons.back = document.getElementById('input-backButtonText').value || "Back";
961
-
962
- // Sync preview nodes
963
- document.getElementById('preview-surveyTitle').innerText = config.surveyTitle;
964
- document.getElementById('preview-companyName').innerText = config.companyName;
965
-
966
- // Logo url preview
967
- const previewLogo = document.getElementById('preview-logo');
968
- if (config.logo.fileName) {
969
- previewLogo.src = document.getElementById('logo-preview-img').src;
970
- previewLogo.classList.remove('hidden');
971
- } else if (config.logo.defaultUrl) {
972
- previewLogo.src = config.logo.defaultUrl;
973
- previewLogo.classList.remove('hidden');
974
- } else {
975
- previewLogo.classList.add('hidden');
976
- }
977
-
978
- // Render showHeader
979
- document.getElementById('preview-header').style.display = config.layout.showHeader ? 'flex' : 'none';
980
-
981
- // Render showProgressBar
982
- document.getElementById('preview-progress-container').style.display = config.layout.showProgressBar ? 'block' : 'none';
983
-
984
- // Required indicator
985
- document.getElementById('preview-asterisk').style.display = config.layout.showRequiredAsterisk ? 'inline' : 'none';
986
-
987
- // Question numbers
988
- document.getElementById('preview-q-num').style.display = config.layout.showQuestionNumbers ? 'inline' : 'none';
989
-
990
- // Width classes
991
- const card = document.getElementById('preview-survey-card');
992
- card.className = "rounded-2xl shadow-xl overflow-hidden border transition-all duration-300";
993
-
994
- // Border styles
995
- if (config.layout.borderStyle === 'sharp') {
996
- card.classList.add('rounded-none');
997
- document.querySelectorAll('.preview-badge').forEach(b => b.classList.add('rounded-none'));
998
- document.getElementById('preview-btn-back').className = "text-[10px] font-semibold text-slate-500 px-3 py-1.5 rounded-none border border-slate-200 bg-white";
999
- document.getElementById('preview-btn-next').className = "text-[10px] font-bold text-white px-4 py-1.5 rounded-none";
1000
- } else if (config.layout.borderStyle === 'pill') {
1001
- card.classList.add('rounded-[32px]');
1002
- document.querySelectorAll('.preview-badge').forEach(b => b.classList.add('rounded-full'));
1003
- document.getElementById('preview-btn-back').className = "text-[10px] font-semibold text-slate-500 px-4 py-1.5 rounded-full border border-slate-200 bg-white";
1004
- document.getElementById('preview-btn-next').className = "text-[10px] font-bold text-white px-5 py-1.5 rounded-full";
1005
- } else {
1006
- card.classList.add('rounded-2xl');
1007
- document.querySelectorAll('.preview-badge').forEach(b => b.classList.add('rounded-lg'));
1008
- document.getElementById('preview-btn-back').className = "text-[10px] font-semibold text-slate-500 px-3 py-1.5 rounded-lg border border-slate-200 bg-white";
1009
- document.getElementById('preview-btn-next').className = "text-[10px] font-bold text-white px-4 py-1.5 rounded-lg";
1010
- }
1011
-
1012
- // Font styles
1013
- if (config.layout.fontStyle === 'serif') {
1014
- card.style.fontFamily = "Georgia, serif";
1015
- } else if (config.layout.fontStyle === 'system') {
1016
- card.style.fontFamily = "system-ui, sans-serif";
1017
- } else {
1018
- card.style.fontFamily = "'Inter', sans-serif";
1019
- }
1020
-
1021
- // Button labels
1022
- document.getElementById('preview-btn-next').innerText = config.buttons.next;
1023
- document.getElementById('preview-btn-back').innerText = config.buttons.back;
1024
-
1025
- // Show/hide buttons
1026
- document.getElementById('preview-btn-next').style.display = config.layout.showNextButton ? 'block' : 'none';
1027
- document.getElementById('preview-btn-back').style.display = config.layout.showBackButton ? 'block' : 'none';
1028
-
1029
- // Colors sync
1030
- const colors = config.colorScheme;
1031
- card.style.backgroundColor = colors.background;
1032
- card.style.color = colors.text;
1033
- card.style.borderColor = colors.secondary;
1034
-
1035
- document.getElementById('preview-header').style.borderColor = colors.secondary;
1036
- document.getElementById('preview-progress-bar').style.backgroundColor = colors.accent;
1037
-
1038
- const primaryBtn = document.getElementById('preview-btn-next');
1039
- primaryBtn.style.backgroundColor = colors.primary;
1040
- primaryBtn.style.color = colors.buttonText || '#FFFFFF';
1041
-
1042
- // Ratings options colors sync
1043
- document.querySelectorAll('.preview-badge').forEach((badge, idx) => {
1044
- if (idx === 0) {
1045
- badge.style.backgroundColor = colors.secondary;
1046
- badge.style.borderColor = colors.primary;
1047
- badge.style.color = colors.primary;
1048
- } else {
1049
- badge.style.backgroundColor = colors.background;
1050
- badge.style.borderColor = colors.secondary;
1051
- badge.style.color = colors.text;
1052
- }
1053
- });
1054
- }
1055
-
1056
- // Step Nav Button Hooks
1057
- document.getElementById('btn-next').onclick = () => {
1058
- if (currentStep < totalSteps - 1) showStep(currentStep + 1);
1059
- };
1060
-
1061
- document.getElementById('btn-prev').onclick = () => {
1062
- if (currentStep > 0) showStep(currentStep - 1);
1063
- };
1064
-
1065
- document.getElementById('btn-skip').onclick = () => {
1066
- // Skipping accepts defaults for this step and advances
1067
- if (currentStep < totalSteps - 1) showStep(currentStep + 1);
1068
- };
1069
-
1070
- // Sidebar tab clicks
1071
- document.querySelectorAll('.step-tab').forEach(tab => {
1072
- tab.onclick = () => {
1073
- const target = parseInt(tab.getAttribute('data-step'), 10);
1074
- showStep(target);
1075
- };
1076
- });
1077
-
1078
- // Save and submit
1079
- function submitSetup() {
1080
- // Sync one final time
1081
- updatePreview();
1082
-
1083
- // Save configuration
1084
- fetch('/api/save-config', {
1085
- method: 'POST',
1086
- headers: { 'Content-Type': 'application/json' },
1087
- body: JSON.stringify(config)
1088
- })
1089
- .then(res => {
1090
- if (res.ok) {
1091
- // Render gorgeous complete overlay
1092
- document.body.innerHTML = `
1093
- <div class="h-full flex items-center justify-center p-6 text-center select-none bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-indigo-950/40 via-slate-950 to-slate-950">
1094
- <div class="glass-panel p-10 md:p-12 rounded-3xl max-w-md border border-indigo-500/20 shadow-2xl space-y-6">
1095
- <div class="h-16 w-16 mx-auto rounded-2xl bg-gradient-to-tr from-indigo-500 to-cyan-500 flex items-center justify-center shadow-lg shadow-indigo-500/30">
1096
- <svg class="w-10 h-10 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1097
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M5 13l4 4L19 7"/>
1098
- </svg>
1099
- </div>
1100
- <div class="space-y-2">
1101
- <h1 class="font-display font-bold text-2xl text-white">Branding Setup Saved!</h1>
1102
- <p class="text-sm text-slate-400">Your configuration was saved to <code>survey-config.json</code>. You can close this browser window. The IDE Agent will now resume building your survey UI.</p>
1103
- </div>
1104
- <div class="text-[11px] text-slate-500 bg-slate-950/50 p-3 rounded-xl border border-white/5">
1105
- Process exited. Ready to proceed.
1106
- </div>
1107
- </div>
1108
- </div>
1109
- `;
1110
- // Close browser window after 3 seconds
1111
- setTimeout(() => window.close(), 3000);
1112
- } else {
1113
- alert('Failed to save survey config.');
1114
- }
1115
- })
1116
- .catch(err => {
1117
- alert('Error completing setup: ' + err.message);
1118
- });
1119
- }
1120
-
1121
- document.getElementById('btn-finish').onclick = submitSetup;
1122
- document.getElementById('btn-skip-all').onclick = submitSetup;
1123
-
1124
- // Quit setup
1125
- document.getElementById('btn-quit').onclick = () => {
1126
- if (confirm('Are you sure you want to exit? Your changes will not be saved.')) {
1127
- fetch('/api/save-config', {
1128
- method: 'POST',
1129
- headers: { 'Content-Type': 'application/json' },
1130
- body: JSON.stringify({}) // empty config -> triggers cancellation/defaults
1131
- }).then(() => window.close());
1132
- }
1133
- };
1134
-
1135
- // Load initial panel
1136
- showStep(0);
1137
- </script>
1138
22
  </body>
1139
23
  </html>