@drttix/drt-sdk 0.9.7 → 0.9.9
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/demo/test.html +1554 -674
- package/dist/bundle/drt-sdk.js +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/src/definitions/portal.d.ts +2 -0
- package/dist/cjs/src/definitions/portal.js +2 -0
- package/dist/cjs/src/generated/portal/core/OpenAPI.js +1 -1
- package/dist/cjs/src/generated/portal/index.d.ts +3 -0
- package/dist/cjs/src/generated/portal/index.js +3 -1
- package/dist/cjs/src/generated/portal/models/SupportTicketResponseDto.d.ts +26 -0
- package/dist/cjs/src/generated/portal/models/SupportTicketResponseDto.js +2 -0
- package/dist/cjs/src/generated/portal/models/SupportTicketStatusResponseDto.d.ts +4 -0
- package/dist/cjs/src/generated/portal/models/SupportTicketStatusResponseDto.js +2 -0
- package/dist/cjs/src/generated/portal/services/SuperUserSupportTicketsService.d.ts +21 -0
- package/dist/cjs/src/generated/portal/services/SuperUserSupportTicketsService.js +40 -0
- package/dist/cjs/src/generated/portal/types.d.ts +2 -0
- package/dist/cjs/src/generated/shopper/services/AccountService.d.ts +4 -16
- package/dist/cjs/src/generated/shopper/services/AccountService.js +4 -36
- package/dist/cjs/src/generated/shopper/services/CartService.d.ts +2 -8
- package/dist/cjs/src/generated/shopper/services/CartService.js +2 -18
- package/dist/cjs/src/generated/shopper/services/CheckoutService.d.ts +5 -20
- package/dist/cjs/src/generated/shopper/services/CheckoutService.js +5 -45
- package/dist/cjs/src/generated/shopper/services/CodeService.d.ts +5 -20
- package/dist/cjs/src/generated/shopper/services/CodeService.js +5 -45
- package/dist/cjs/src/generated/shopper/services/DonationService.d.ts +2 -8
- package/dist/cjs/src/generated/shopper/services/DonationService.js +2 -16
- package/dist/cjs/src/generated/shopper/services/EventService.d.ts +4 -16
- package/dist/cjs/src/generated/shopper/services/EventService.js +4 -36
- package/dist/cjs/src/generated/shopper/services/GiftCardService.d.ts +5 -20
- package/dist/cjs/src/generated/shopper/services/GiftCardService.js +5 -45
- package/dist/cjs/src/generated/shopper/services/OrderService.d.ts +14 -56
- package/dist/cjs/src/generated/shopper/services/OrderService.js +14 -126
- package/dist/cjs/src/generated/shopper/services/PaymentService.d.ts +3 -12
- package/dist/cjs/src/generated/shopper/services/PaymentService.js +3 -27
- package/dist/cjs/src/generated/shopper/services/ProductService.d.ts +3 -12
- package/dist/cjs/src/generated/shopper/services/ProductService.js +3 -27
- package/dist/cjs/src/generated/shopper/services/SeatService.d.ts +6 -24
- package/dist/cjs/src/generated/shopper/services/SeatService.js +6 -54
- package/dist/cjs/src/generated/shopper/services/SessionService.d.ts +2 -8
- package/dist/cjs/src/generated/shopper/services/SessionService.js +2 -18
- package/dist/cjs/src/scripts/build-all.js +46 -2
- package/dist/cjs/src/staging/wrapService.js +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/src/definitions/portal.d.ts +2 -0
- package/dist/esm/src/definitions/portal.js +2 -0
- package/dist/esm/src/generated/portal/core/OpenAPI.js +1 -1
- package/dist/esm/src/generated/portal/index.d.ts +3 -0
- package/dist/esm/src/generated/portal/index.js +1 -0
- package/dist/esm/src/generated/portal/models/SupportTicketResponseDto.d.ts +26 -0
- package/dist/esm/src/generated/portal/models/SupportTicketResponseDto.js +1 -0
- package/dist/esm/src/generated/portal/models/SupportTicketStatusResponseDto.d.ts +4 -0
- package/dist/esm/src/generated/portal/models/SupportTicketStatusResponseDto.js +1 -0
- package/dist/esm/src/generated/portal/services/SuperUserSupportTicketsService.d.ts +21 -0
- package/dist/esm/src/generated/portal/services/SuperUserSupportTicketsService.js +36 -0
- package/dist/esm/src/generated/portal/types.d.ts +2 -0
- package/dist/esm/src/generated/shopper/services/AccountService.d.ts +4 -16
- package/dist/esm/src/generated/shopper/services/AccountService.js +4 -36
- package/dist/esm/src/generated/shopper/services/CartService.d.ts +2 -8
- package/dist/esm/src/generated/shopper/services/CartService.js +2 -18
- package/dist/esm/src/generated/shopper/services/CheckoutService.d.ts +5 -20
- package/dist/esm/src/generated/shopper/services/CheckoutService.js +5 -45
- package/dist/esm/src/generated/shopper/services/CodeService.d.ts +5 -20
- package/dist/esm/src/generated/shopper/services/CodeService.js +5 -45
- package/dist/esm/src/generated/shopper/services/DonationService.d.ts +2 -8
- package/dist/esm/src/generated/shopper/services/DonationService.js +2 -16
- package/dist/esm/src/generated/shopper/services/EventService.d.ts +4 -16
- package/dist/esm/src/generated/shopper/services/EventService.js +4 -36
- package/dist/esm/src/generated/shopper/services/GiftCardService.d.ts +5 -20
- package/dist/esm/src/generated/shopper/services/GiftCardService.js +5 -45
- package/dist/esm/src/generated/shopper/services/OrderService.d.ts +14 -56
- package/dist/esm/src/generated/shopper/services/OrderService.js +14 -126
- package/dist/esm/src/generated/shopper/services/PaymentService.d.ts +3 -12
- package/dist/esm/src/generated/shopper/services/PaymentService.js +3 -27
- package/dist/esm/src/generated/shopper/services/ProductService.d.ts +3 -12
- package/dist/esm/src/generated/shopper/services/ProductService.js +3 -27
- package/dist/esm/src/generated/shopper/services/SeatService.d.ts +6 -24
- package/dist/esm/src/generated/shopper/services/SeatService.js +6 -54
- package/dist/esm/src/generated/shopper/services/SessionService.d.ts +2 -8
- package/dist/esm/src/generated/shopper/services/SessionService.js +2 -18
- package/dist/esm/src/scripts/build-all.js +46 -2
- package/dist/esm/src/staging/wrapService.js +1 -1
- package/drt-api-specs-staging.json +14 -0
- package/package.json +38 -38
- package/public/sdk/latest/drt-sdk.js +1 -1
- package/src/definitions/portal.ts +2 -0
- package/src/generated/portal/core/OpenAPI.ts +1 -1
- package/src/generated/portal/index.ts +3 -0
- package/src/generated/portal/models/SupportTicketResponseDto.ts +31 -0
- package/src/generated/portal/models/SupportTicketStatusResponseDto.ts +9 -0
- package/src/generated/portal/services/SuperUserSupportTicketsService.ts +46 -0
- package/src/generated/portal/types.ts +2 -0
- package/src/generated/shopper/services/AccountService.ts +0 -44
- package/src/generated/shopper/services/CartService.ts +0 -22
- package/src/generated/shopper/services/CheckoutService.ts +0 -55
- package/src/generated/shopper/services/CodeService.ts +0 -55
- package/src/generated/shopper/services/DonationService.ts +0 -20
- package/src/generated/shopper/services/EventService.ts +0 -44
- package/src/generated/shopper/services/GiftCardService.ts +0 -55
- package/src/generated/shopper/services/OrderService.ts +0 -154
- package/src/generated/shopper/services/PaymentService.ts +0 -33
- package/src/generated/shopper/services/ProductService.ts +0 -33
- package/src/generated/shopper/services/SeatService.ts +0 -66
- package/src/generated/shopper/services/SessionService.ts +0 -22
- package/src/scripts/build-all.ts +59 -2
- package/src/staging/wrapService.ts +1 -1
package/demo/test.html
CHANGED
|
@@ -1,676 +1,1406 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
|
-
<html>
|
|
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" />
|
|
6
|
+
<title>DRT SDK — Test Console</title>
|
|
6
7
|
<link rel="icon" href="data:," />
|
|
7
8
|
<style>
|
|
9
|
+
:root {
|
|
10
|
+
--primary: #4f46e5;
|
|
11
|
+
--primary-hover: #4338ca;
|
|
12
|
+
--primary-light: #eef2ff;
|
|
13
|
+
--danger: #dc2626;
|
|
14
|
+
--danger-hover: #b91c1c;
|
|
15
|
+
--success: #059669;
|
|
16
|
+
--success-light: #d1fae5;
|
|
17
|
+
--warning: #d97706;
|
|
18
|
+
--warning-light: #fef3c7;
|
|
19
|
+
--info: #0284c7;
|
|
20
|
+
--info-light: #e0f2fe;
|
|
21
|
+
--text: #111827;
|
|
22
|
+
--text-muted: #6b7280;
|
|
23
|
+
--border: #e5e7eb;
|
|
24
|
+
--surface: #ffffff;
|
|
25
|
+
--surface-alt: #f9fafb;
|
|
26
|
+
--code-bg: #1e1e2e;
|
|
27
|
+
--code-text: #e4e4e7;
|
|
28
|
+
}
|
|
8
29
|
* {
|
|
9
30
|
box-sizing: border-box;
|
|
10
31
|
}
|
|
32
|
+
html,
|
|
11
33
|
body {
|
|
12
|
-
font-family: system-ui, sans-serif;
|
|
13
34
|
margin: 0;
|
|
14
35
|
padding: 0;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
36
|
+
height: 100%;
|
|
37
|
+
font-family:
|
|
38
|
+
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
|
39
|
+
'Helvetica Neue', sans-serif;
|
|
40
|
+
color: var(--text);
|
|
41
|
+
background: var(--surface-alt);
|
|
42
|
+
font-size: 14px;
|
|
43
|
+
line-height: 1.5;
|
|
18
44
|
}
|
|
19
|
-
.
|
|
45
|
+
.app {
|
|
20
46
|
display: flex;
|
|
21
|
-
width: 100%;
|
|
22
47
|
height: 100vh;
|
|
23
|
-
|
|
48
|
+
overflow: hidden;
|
|
24
49
|
}
|
|
25
50
|
.left-panel {
|
|
26
51
|
width: 50%;
|
|
27
52
|
min-width: 50%;
|
|
28
53
|
max-width: 50%;
|
|
29
54
|
overflow-y: auto;
|
|
30
|
-
padding:
|
|
55
|
+
padding: 1.25rem 1.5rem 2rem;
|
|
56
|
+
background: var(--surface-alt);
|
|
31
57
|
}
|
|
32
58
|
.right-panel {
|
|
33
59
|
width: 50%;
|
|
34
60
|
min-width: 50%;
|
|
35
61
|
max-width: 50%;
|
|
36
|
-
background:
|
|
37
|
-
color:
|
|
62
|
+
background: var(--code-bg);
|
|
63
|
+
color: var(--code-text);
|
|
38
64
|
display: flex;
|
|
39
65
|
flex-direction: column;
|
|
40
|
-
border-left: 1px solid
|
|
41
|
-
position: sticky;
|
|
42
|
-
top: 0;
|
|
66
|
+
border-left: 1px solid var(--border);
|
|
43
67
|
height: 100vh;
|
|
44
68
|
}
|
|
45
|
-
.right-panel h2 {
|
|
46
|
-
color: #fff;
|
|
47
|
-
margin: 0;
|
|
48
|
-
padding: 1rem;
|
|
49
|
-
background: #2d2d2d;
|
|
50
|
-
border-bottom: 1px solid #444;
|
|
51
|
-
font-size: 1rem;
|
|
52
|
-
}
|
|
53
69
|
h1 {
|
|
54
|
-
|
|
55
|
-
|
|
70
|
+
font-size: 1.5rem;
|
|
71
|
+
font-weight: 700;
|
|
72
|
+
margin: 0 0 0.25rem;
|
|
73
|
+
color: var(--text);
|
|
74
|
+
display: flex;
|
|
75
|
+
align-items: center;
|
|
76
|
+
gap: 0.5rem;
|
|
77
|
+
}
|
|
78
|
+
h1 .badge-version {
|
|
79
|
+
font-size: 0.7rem;
|
|
80
|
+
background: var(--primary-light);
|
|
81
|
+
color: var(--primary);
|
|
82
|
+
padding: 0.15rem 0.5rem;
|
|
83
|
+
border-radius: 999px;
|
|
84
|
+
font-weight: 600;
|
|
56
85
|
}
|
|
57
|
-
|
|
58
|
-
color:
|
|
59
|
-
margin
|
|
60
|
-
|
|
61
|
-
padding-bottom: 0.5rem;
|
|
86
|
+
.subtitle {
|
|
87
|
+
color: var(--text-muted);
|
|
88
|
+
margin: 0 0 1.25rem;
|
|
89
|
+
font-size: 0.875rem;
|
|
62
90
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
91
|
+
h2.section-title {
|
|
92
|
+
font-size: 0.75rem;
|
|
93
|
+
font-weight: 700;
|
|
94
|
+
text-transform: uppercase;
|
|
95
|
+
letter-spacing: 0.05em;
|
|
96
|
+
color: var(--text-muted);
|
|
97
|
+
margin: 1.5rem 0 0.5rem;
|
|
98
|
+
padding: 0;
|
|
99
|
+
border: none;
|
|
66
100
|
}
|
|
67
101
|
button {
|
|
68
|
-
padding: 0.
|
|
69
|
-
font-size: 0.
|
|
102
|
+
padding: 0.4rem 0.85rem;
|
|
103
|
+
font-size: 0.85rem;
|
|
104
|
+
font-weight: 500;
|
|
70
105
|
cursor: pointer;
|
|
71
|
-
|
|
72
|
-
border:
|
|
73
|
-
|
|
74
|
-
|
|
106
|
+
border: 1px solid var(--border);
|
|
107
|
+
border-radius: 6px;
|
|
108
|
+
background: var(--surface);
|
|
109
|
+
color: var(--text);
|
|
110
|
+
transition: all 0.15s;
|
|
75
111
|
}
|
|
76
|
-
button:hover {
|
|
77
|
-
background:
|
|
112
|
+
button:hover:not(:disabled) {
|
|
113
|
+
background: var(--surface-alt);
|
|
114
|
+
border-color: #d1d5db;
|
|
78
115
|
}
|
|
79
116
|
button:disabled {
|
|
80
117
|
opacity: 0.5;
|
|
81
118
|
cursor: not-allowed;
|
|
82
119
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
min-width: 0;
|
|
88
|
-
max-width: 100%;
|
|
120
|
+
button.primary {
|
|
121
|
+
background: var(--primary);
|
|
122
|
+
color: white;
|
|
123
|
+
border-color: var(--primary);
|
|
89
124
|
}
|
|
90
|
-
|
|
91
|
-
background:
|
|
92
|
-
|
|
93
|
-
white-space: pre-wrap;
|
|
94
|
-
word-wrap: break-word;
|
|
95
|
-
overflow-wrap: break-word;
|
|
96
|
-
font-size: 0.85rem;
|
|
97
|
-
font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
|
|
125
|
+
button.primary:hover:not(:disabled) {
|
|
126
|
+
background: var(--primary-hover);
|
|
127
|
+
border-color: var(--primary-hover);
|
|
98
128
|
}
|
|
99
|
-
.
|
|
100
|
-
|
|
129
|
+
button.danger {
|
|
130
|
+
background: var(--surface);
|
|
131
|
+
color: var(--danger);
|
|
132
|
+
border-color: #fecaca;
|
|
101
133
|
}
|
|
102
|
-
.
|
|
103
|
-
|
|
134
|
+
button.danger:hover:not(:disabled) {
|
|
135
|
+
background: #fef2f2;
|
|
104
136
|
}
|
|
105
|
-
|
|
106
|
-
padding: 0.
|
|
107
|
-
font-
|
|
108
|
-
background: #252526;
|
|
109
|
-
border-bottom: 1px solid #444;
|
|
137
|
+
button.small {
|
|
138
|
+
padding: 0.25rem 0.6rem;
|
|
139
|
+
font-size: 0.75rem;
|
|
110
140
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
padding:
|
|
141
|
+
input,
|
|
142
|
+
select {
|
|
143
|
+
padding: 0.4rem 0.6rem;
|
|
144
|
+
font-size: 0.85rem;
|
|
145
|
+
border: 1px solid var(--border);
|
|
146
|
+
border-radius: 6px;
|
|
147
|
+
background: var(--surface);
|
|
148
|
+
color: var(--text);
|
|
149
|
+
font-family: inherit;
|
|
150
|
+
}
|
|
151
|
+
input:focus,
|
|
152
|
+
select:focus {
|
|
153
|
+
outline: none;
|
|
154
|
+
border-color: var(--primary);
|
|
155
|
+
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
|
|
156
|
+
}
|
|
157
|
+
code {
|
|
158
|
+
background: #eef1f5;
|
|
159
|
+
color: #374151;
|
|
160
|
+
padding: 0.1rem 0.35rem;
|
|
114
161
|
border-radius: 4px;
|
|
162
|
+
font-size: 0.78rem;
|
|
163
|
+
font-family:
|
|
164
|
+
ui-monospace, 'SF Mono', Monaco, 'Cascadia Code', monospace;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/* Config card */
|
|
168
|
+
.card {
|
|
169
|
+
background: var(--surface);
|
|
170
|
+
border: 1px solid var(--border);
|
|
171
|
+
border-radius: 10px;
|
|
172
|
+
padding: 1rem;
|
|
115
173
|
margin-bottom: 1rem;
|
|
116
174
|
}
|
|
117
|
-
.
|
|
175
|
+
.card-title {
|
|
176
|
+
font-size: 0.9rem;
|
|
177
|
+
font-weight: 600;
|
|
178
|
+
margin: 0 0 0.5rem;
|
|
179
|
+
display: flex;
|
|
180
|
+
align-items: center;
|
|
181
|
+
gap: 0.5rem;
|
|
182
|
+
}
|
|
183
|
+
.card-title .step {
|
|
184
|
+
display: inline-flex;
|
|
185
|
+
align-items: center;
|
|
186
|
+
justify-content: center;
|
|
187
|
+
width: 1.5rem;
|
|
188
|
+
height: 1.5rem;
|
|
189
|
+
background: var(--primary);
|
|
190
|
+
color: white;
|
|
191
|
+
border-radius: 50%;
|
|
192
|
+
font-size: 0.75rem;
|
|
193
|
+
font-weight: 700;
|
|
194
|
+
}
|
|
195
|
+
.quick-start {
|
|
196
|
+
background: var(--primary-light);
|
|
197
|
+
border: 1px solid #c7d2fe;
|
|
198
|
+
padding: 0.75rem;
|
|
199
|
+
border-radius: 8px;
|
|
200
|
+
margin-bottom: 0.75rem;
|
|
201
|
+
}
|
|
202
|
+
.field {
|
|
118
203
|
display: block;
|
|
119
|
-
|
|
204
|
+
font-size: 0.8rem;
|
|
120
205
|
font-weight: 500;
|
|
206
|
+
color: var(--text-muted);
|
|
207
|
+
margin: 0.6rem 0 0.25rem;
|
|
121
208
|
}
|
|
122
|
-
.
|
|
209
|
+
.field + input {
|
|
123
210
|
width: 100%;
|
|
124
|
-
padding: 0.5rem;
|
|
125
|
-
font-size: 1rem;
|
|
126
|
-
box-sizing: border-box;
|
|
127
|
-
border: 1px solid #ccc;
|
|
128
|
-
border-radius: 4px;
|
|
129
211
|
}
|
|
130
|
-
.
|
|
131
|
-
display: flex;
|
|
132
|
-
flex-wrap: wrap;
|
|
133
|
-
gap: 0.5rem;
|
|
134
|
-
margin: 0.5rem 0;
|
|
135
|
-
}
|
|
136
|
-
.input-row {
|
|
212
|
+
.inline-row {
|
|
137
213
|
display: flex;
|
|
138
214
|
gap: 0.5rem;
|
|
139
215
|
align-items: center;
|
|
140
|
-
|
|
216
|
+
flex-wrap: wrap;
|
|
141
217
|
}
|
|
142
|
-
.
|
|
218
|
+
.inline-row label {
|
|
219
|
+
font-size: 0.8rem;
|
|
220
|
+
font-weight: 500;
|
|
221
|
+
color: var(--text-muted);
|
|
222
|
+
}
|
|
223
|
+
.inline-row input,
|
|
224
|
+
.inline-row select {
|
|
143
225
|
flex: 1;
|
|
144
|
-
|
|
145
|
-
font-size: 0.9rem;
|
|
226
|
+
min-width: 0;
|
|
146
227
|
}
|
|
147
|
-
.
|
|
148
|
-
|
|
149
|
-
|
|
228
|
+
.btn-row {
|
|
229
|
+
display: flex;
|
|
230
|
+
gap: 0.5rem;
|
|
231
|
+
flex-wrap: wrap;
|
|
232
|
+
margin-top: 0.5rem;
|
|
150
233
|
}
|
|
151
|
-
|
|
152
|
-
|
|
234
|
+
|
|
235
|
+
/* Tabs for API */
|
|
236
|
+
.api-tabs {
|
|
237
|
+
display: flex;
|
|
238
|
+
gap: 0.25rem;
|
|
239
|
+
border-bottom: 1px solid var(--border);
|
|
153
240
|
margin-bottom: 1rem;
|
|
154
241
|
}
|
|
155
|
-
.tab {
|
|
156
|
-
padding: 0.5rem
|
|
242
|
+
.api-tab {
|
|
243
|
+
padding: 0.5rem 0.9rem;
|
|
157
244
|
border: none;
|
|
158
245
|
background: none;
|
|
159
246
|
cursor: pointer;
|
|
160
|
-
font-size:
|
|
247
|
+
font-size: 0.875rem;
|
|
248
|
+
font-weight: 500;
|
|
249
|
+
color: var(--text-muted);
|
|
250
|
+
border-bottom: 2px solid transparent;
|
|
251
|
+
margin-bottom: -1px;
|
|
252
|
+
border-radius: 0;
|
|
253
|
+
}
|
|
254
|
+
.api-tab:hover {
|
|
255
|
+
color: var(--text);
|
|
256
|
+
background: none;
|
|
161
257
|
}
|
|
162
|
-
.tab.active {
|
|
163
|
-
|
|
164
|
-
color:
|
|
165
|
-
margin-bottom: -2px;
|
|
258
|
+
.api-tab.active {
|
|
259
|
+
color: var(--primary);
|
|
260
|
+
border-bottom-color: var(--primary);
|
|
166
261
|
}
|
|
167
|
-
.
|
|
262
|
+
.api-content {
|
|
168
263
|
display: none;
|
|
169
264
|
}
|
|
170
|
-
.
|
|
265
|
+
.api-content.active {
|
|
171
266
|
display: block;
|
|
172
267
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
padding: 0.2rem 0.4rem;
|
|
176
|
-
border-radius: 3px;
|
|
177
|
-
font-size: 0.85rem;
|
|
178
|
-
}
|
|
268
|
+
|
|
269
|
+
/* Collapsible sections */
|
|
179
270
|
details.api-section {
|
|
180
|
-
border: 1px solid
|
|
181
|
-
border-radius:
|
|
182
|
-
margin-bottom: 0.
|
|
183
|
-
background:
|
|
271
|
+
border: 1px solid var(--border);
|
|
272
|
+
border-radius: 8px;
|
|
273
|
+
margin-bottom: 0.5rem;
|
|
274
|
+
background: var(--surface);
|
|
275
|
+
overflow: hidden;
|
|
184
276
|
}
|
|
185
277
|
details.api-section > summary {
|
|
186
|
-
padding: 0.
|
|
278
|
+
padding: 0.65rem 0.9rem;
|
|
187
279
|
font-weight: 600;
|
|
188
|
-
font-size: 0.
|
|
280
|
+
font-size: 0.9rem;
|
|
189
281
|
cursor: pointer;
|
|
190
|
-
background: #f7f7f7;
|
|
191
|
-
border-radius: 6px;
|
|
192
282
|
user-select: none;
|
|
193
283
|
list-style: none;
|
|
194
284
|
display: flex;
|
|
195
285
|
align-items: center;
|
|
196
286
|
gap: 0.5rem;
|
|
287
|
+
transition: background 0.15s;
|
|
288
|
+
}
|
|
289
|
+
details.api-section > summary:hover {
|
|
290
|
+
background: var(--surface-alt);
|
|
197
291
|
}
|
|
198
292
|
details.api-section > summary::-webkit-details-marker {
|
|
199
293
|
display: none;
|
|
200
294
|
}
|
|
201
295
|
details.api-section > summary::before {
|
|
202
|
-
content: '\
|
|
296
|
+
content: '\25B8';
|
|
203
297
|
font-size: 0.7rem;
|
|
298
|
+
color: #9ca3af;
|
|
204
299
|
transition: transform 0.15s;
|
|
205
|
-
|
|
300
|
+
flex-shrink: 0;
|
|
206
301
|
}
|
|
207
302
|
details.api-section[open] > summary::before {
|
|
208
303
|
transform: rotate(90deg);
|
|
209
304
|
}
|
|
210
305
|
details.api-section > .section-body {
|
|
211
|
-
padding: 0.
|
|
212
|
-
border-top: 1px solid
|
|
213
|
-
|
|
214
|
-
details.api-section[open] > summary {
|
|
215
|
-
border-radius: 6px 6px 0 0;
|
|
306
|
+
padding: 0.75rem 0.9rem 0.9rem;
|
|
307
|
+
border-top: 1px solid var(--border);
|
|
308
|
+
background: var(--surface-alt);
|
|
216
309
|
}
|
|
217
310
|
details.api-section.hidden-section {
|
|
218
311
|
display: none;
|
|
219
312
|
}
|
|
220
313
|
.section-badge {
|
|
221
314
|
font-size: 0.7rem;
|
|
222
|
-
padding: 0.
|
|
223
|
-
border-radius:
|
|
224
|
-
font-weight:
|
|
315
|
+
padding: 0.1rem 0.45rem;
|
|
316
|
+
border-radius: 999px;
|
|
317
|
+
font-weight: 600;
|
|
225
318
|
margin-left: auto;
|
|
319
|
+
background: #f3f4f6;
|
|
320
|
+
color: var(--text-muted);
|
|
226
321
|
}
|
|
227
322
|
.badge-ga {
|
|
228
|
-
background:
|
|
229
|
-
color:
|
|
323
|
+
background: var(--success-light);
|
|
324
|
+
color: var(--success);
|
|
230
325
|
}
|
|
231
326
|
.badge-reserved {
|
|
232
|
-
background:
|
|
233
|
-
color:
|
|
327
|
+
background: var(--info-light);
|
|
328
|
+
color: var(--info);
|
|
234
329
|
}
|
|
235
330
|
.badge-ready {
|
|
236
|
-
background:
|
|
237
|
-
color:
|
|
331
|
+
background: var(--success-light);
|
|
332
|
+
color: var(--success);
|
|
333
|
+
}
|
|
334
|
+
.badge-count {
|
|
335
|
+
background: var(--primary-light);
|
|
336
|
+
color: var(--primary);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/* Info banners */
|
|
340
|
+
.info-banner {
|
|
341
|
+
padding: 0.5rem 0.75rem;
|
|
342
|
+
border-radius: 6px;
|
|
343
|
+
font-size: 0.825rem;
|
|
344
|
+
margin-bottom: 0.5rem;
|
|
345
|
+
display: flex;
|
|
346
|
+
align-items: center;
|
|
347
|
+
gap: 0.5rem;
|
|
348
|
+
}
|
|
349
|
+
.info-banner.ga {
|
|
350
|
+
background: var(--success-light);
|
|
351
|
+
color: var(--success);
|
|
352
|
+
}
|
|
353
|
+
.info-banner.reserved {
|
|
354
|
+
background: var(--info-light);
|
|
355
|
+
color: var(--info);
|
|
356
|
+
}
|
|
357
|
+
.info-banner.warn {
|
|
358
|
+
background: var(--warning-light);
|
|
359
|
+
color: var(--warning);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/* Cart items */
|
|
363
|
+
.cart-items {
|
|
364
|
+
display: flex;
|
|
365
|
+
flex-direction: column;
|
|
366
|
+
gap: 0.4rem;
|
|
367
|
+
margin-top: 0.5rem;
|
|
368
|
+
}
|
|
369
|
+
.cart-item {
|
|
370
|
+
display: flex;
|
|
371
|
+
align-items: center;
|
|
372
|
+
gap: 0.75rem;
|
|
373
|
+
padding: 0.6rem 0.75rem;
|
|
374
|
+
background: var(--surface);
|
|
375
|
+
border: 1px solid var(--border);
|
|
376
|
+
border-radius: 6px;
|
|
377
|
+
}
|
|
378
|
+
.cart-item-icon {
|
|
379
|
+
width: 2rem;
|
|
380
|
+
height: 2rem;
|
|
381
|
+
border-radius: 6px;
|
|
382
|
+
display: flex;
|
|
383
|
+
align-items: center;
|
|
384
|
+
justify-content: center;
|
|
385
|
+
font-size: 1rem;
|
|
386
|
+
flex-shrink: 0;
|
|
387
|
+
}
|
|
388
|
+
.cart-item-icon.seat {
|
|
389
|
+
background: var(--info-light);
|
|
390
|
+
color: var(--info);
|
|
391
|
+
}
|
|
392
|
+
.cart-item-icon.product {
|
|
393
|
+
background: var(--warning-light);
|
|
394
|
+
color: var(--warning);
|
|
395
|
+
}
|
|
396
|
+
.cart-item-icon.donation {
|
|
397
|
+
background: var(--success-light);
|
|
398
|
+
color: var(--success);
|
|
399
|
+
}
|
|
400
|
+
.cart-item-body {
|
|
401
|
+
flex: 1;
|
|
402
|
+
min-width: 0;
|
|
403
|
+
}
|
|
404
|
+
.cart-item-title {
|
|
405
|
+
font-weight: 600;
|
|
406
|
+
font-size: 0.875rem;
|
|
407
|
+
color: var(--text);
|
|
408
|
+
}
|
|
409
|
+
.cart-item-subtitle {
|
|
410
|
+
font-size: 0.75rem;
|
|
411
|
+
color: var(--text-muted);
|
|
412
|
+
margin-top: 0.1rem;
|
|
413
|
+
}
|
|
414
|
+
.cart-item-price {
|
|
415
|
+
font-weight: 600;
|
|
416
|
+
font-size: 0.875rem;
|
|
417
|
+
color: var(--text);
|
|
418
|
+
margin-right: 0.5rem;
|
|
419
|
+
white-space: nowrap;
|
|
420
|
+
}
|
|
421
|
+
.cart-summary {
|
|
422
|
+
background: var(--primary-light);
|
|
423
|
+
border: 1px solid #c7d2fe;
|
|
424
|
+
border-radius: 6px;
|
|
425
|
+
padding: 0.6rem 0.75rem;
|
|
426
|
+
margin-top: 0.75rem;
|
|
427
|
+
display: flex;
|
|
428
|
+
justify-content: space-between;
|
|
429
|
+
align-items: center;
|
|
430
|
+
font-weight: 600;
|
|
431
|
+
font-size: 0.9rem;
|
|
432
|
+
}
|
|
433
|
+
.empty-cart {
|
|
434
|
+
text-align: center;
|
|
435
|
+
padding: 1.5rem 0.5rem;
|
|
436
|
+
color: var(--text-muted);
|
|
437
|
+
font-size: 0.875rem;
|
|
438
|
+
font-style: italic;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/* Right panel output */
|
|
442
|
+
.panel-tabs {
|
|
443
|
+
display: flex;
|
|
444
|
+
background: #181825;
|
|
445
|
+
border-bottom: 1px solid #313244;
|
|
446
|
+
padding: 0 0.5rem;
|
|
447
|
+
}
|
|
448
|
+
.panel-tab {
|
|
449
|
+
padding: 0.75rem 1rem;
|
|
450
|
+
border: none;
|
|
451
|
+
background: none;
|
|
452
|
+
cursor: pointer;
|
|
453
|
+
font-size: 0.85rem;
|
|
454
|
+
font-weight: 500;
|
|
455
|
+
color: #a1a1aa;
|
|
456
|
+
border-bottom: 2px solid transparent;
|
|
457
|
+
margin-bottom: -1px;
|
|
458
|
+
border-radius: 0;
|
|
459
|
+
font-family: inherit;
|
|
460
|
+
}
|
|
461
|
+
.panel-tab:hover {
|
|
462
|
+
background: none;
|
|
463
|
+
color: var(--code-text);
|
|
464
|
+
}
|
|
465
|
+
.panel-tab.active {
|
|
466
|
+
color: #a5b4fc;
|
|
467
|
+
border-bottom-color: #a5b4fc;
|
|
468
|
+
}
|
|
469
|
+
.panel-content {
|
|
470
|
+
flex: 1;
|
|
471
|
+
display: none;
|
|
472
|
+
flex-direction: column;
|
|
473
|
+
min-height: 0;
|
|
474
|
+
}
|
|
475
|
+
.panel-content.active {
|
|
476
|
+
display: flex;
|
|
477
|
+
}
|
|
478
|
+
#status {
|
|
479
|
+
padding: 0.5rem 1rem;
|
|
480
|
+
font-weight: 600;
|
|
481
|
+
background: #181825;
|
|
482
|
+
border-bottom: 1px solid #313244;
|
|
483
|
+
font-size: 0.8rem;
|
|
484
|
+
display: flex;
|
|
485
|
+
align-items: center;
|
|
486
|
+
gap: 0.5rem;
|
|
487
|
+
}
|
|
488
|
+
#status.success {
|
|
489
|
+
color: #a6e3a1;
|
|
490
|
+
}
|
|
491
|
+
#status.error {
|
|
492
|
+
color: #f38ba8;
|
|
493
|
+
}
|
|
494
|
+
#status::before {
|
|
495
|
+
content: '';
|
|
496
|
+
width: 8px;
|
|
497
|
+
height: 8px;
|
|
498
|
+
border-radius: 50%;
|
|
499
|
+
background: currentColor;
|
|
500
|
+
flex-shrink: 0;
|
|
501
|
+
}
|
|
502
|
+
#output-container {
|
|
503
|
+
flex: 1;
|
|
504
|
+
overflow: auto;
|
|
505
|
+
padding: 1rem;
|
|
506
|
+
min-width: 0;
|
|
507
|
+
}
|
|
508
|
+
pre {
|
|
509
|
+
background: transparent;
|
|
510
|
+
margin: 0;
|
|
511
|
+
white-space: pre-wrap;
|
|
512
|
+
word-wrap: break-word;
|
|
513
|
+
overflow-wrap: break-word;
|
|
514
|
+
font-size: 0.8rem;
|
|
515
|
+
font-family:
|
|
516
|
+
ui-monospace, 'SF Mono', Monaco, 'Cascadia Code', monospace;
|
|
517
|
+
color: var(--code-text);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/* Implementation panel */
|
|
521
|
+
#impl-panel {
|
|
522
|
+
padding: 1.25rem;
|
|
523
|
+
overflow-y: auto;
|
|
524
|
+
flex: 1;
|
|
525
|
+
background: #181825;
|
|
238
526
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
527
|
+
#impl-panel h3 {
|
|
528
|
+
color: #cdd6f4;
|
|
529
|
+
margin: 1.25rem 0 0.5rem;
|
|
530
|
+
font-size: 0.95rem;
|
|
531
|
+
font-weight: 600;
|
|
532
|
+
}
|
|
533
|
+
#impl-panel h3:first-child {
|
|
534
|
+
margin-top: 0;
|
|
535
|
+
}
|
|
536
|
+
#impl-panel p {
|
|
537
|
+
color: #bac2de;
|
|
538
|
+
font-size: 0.85rem;
|
|
539
|
+
margin: 0.25rem 0 0.5rem;
|
|
540
|
+
}
|
|
541
|
+
.code-block {
|
|
542
|
+
position: relative;
|
|
543
|
+
background: #11111b;
|
|
544
|
+
border: 1px solid #313244;
|
|
545
|
+
border-radius: 8px;
|
|
546
|
+
padding: 0.8rem 0.9rem;
|
|
547
|
+
margin: 0.5rem 0;
|
|
548
|
+
}
|
|
549
|
+
.code-block pre {
|
|
550
|
+
font-size: 0.78rem;
|
|
551
|
+
line-height: 1.55;
|
|
552
|
+
color: #cdd6f4;
|
|
553
|
+
}
|
|
554
|
+
.code-block .copy-btn {
|
|
555
|
+
position: absolute;
|
|
556
|
+
top: 0.5rem;
|
|
557
|
+
right: 0.5rem;
|
|
558
|
+
padding: 0.2rem 0.5rem;
|
|
559
|
+
font-size: 0.7rem;
|
|
560
|
+
background: #313244;
|
|
561
|
+
color: #cdd6f4;
|
|
562
|
+
border: 1px solid #45475a;
|
|
563
|
+
border-radius: 4px;
|
|
564
|
+
cursor: pointer;
|
|
565
|
+
opacity: 0;
|
|
566
|
+
transition: opacity 0.15s;
|
|
567
|
+
}
|
|
568
|
+
.code-block:hover .copy-btn {
|
|
569
|
+
opacity: 1;
|
|
570
|
+
}
|
|
571
|
+
.code-block .copy-btn:hover {
|
|
572
|
+
background: #45475a;
|
|
573
|
+
}
|
|
574
|
+
.code-block .copy-btn.copied {
|
|
575
|
+
background: #a6e3a1;
|
|
576
|
+
color: #11111b;
|
|
577
|
+
}
|
|
578
|
+
.impl-note {
|
|
579
|
+
background: #181e2e;
|
|
580
|
+
border-left: 3px solid #89b4fa;
|
|
581
|
+
padding: 0.6rem 0.85rem;
|
|
582
|
+
margin: 0.75rem 0;
|
|
583
|
+
border-radius: 0 6px 6px 0;
|
|
584
|
+
font-size: 0.82rem;
|
|
585
|
+
color: #bac2de;
|
|
586
|
+
}
|
|
587
|
+
.kw {
|
|
588
|
+
color: #cba6f7;
|
|
589
|
+
}
|
|
590
|
+
.str {
|
|
591
|
+
color: #a6e3a1;
|
|
592
|
+
}
|
|
593
|
+
.com {
|
|
594
|
+
color: #6c7086;
|
|
595
|
+
font-style: italic;
|
|
596
|
+
}
|
|
597
|
+
.fn {
|
|
598
|
+
color: #89b4fa;
|
|
599
|
+
}
|
|
600
|
+
.num {
|
|
601
|
+
color: #fab387;
|
|
242
602
|
}
|
|
243
603
|
</style>
|
|
244
604
|
</head>
|
|
245
605
|
<body>
|
|
246
|
-
<div class="
|
|
606
|
+
<div class="app">
|
|
607
|
+
<!-- LEFT PANEL: Controls -->
|
|
247
608
|
<div class="left-panel">
|
|
248
|
-
<h1>
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
<div
|
|
253
|
-
style="
|
|
254
|
-
background: #e8f5e9;
|
|
255
|
-
padding: 0.75rem;
|
|
256
|
-
border-radius: 4px;
|
|
257
|
-
margin-bottom: 1rem;
|
|
258
|
-
"
|
|
609
|
+
<h1>
|
|
610
|
+
DRT SDK Test Console
|
|
611
|
+
<span id="sdkVersionBadge" class="badge-version"
|
|
612
|
+
>v0.9.7</span
|
|
259
613
|
>
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
614
|
+
</h1>
|
|
615
|
+
<p class="subtitle">
|
|
616
|
+
Interactive playground for the
|
|
617
|
+
<code>@drttix/drt-sdk</code> shopper & scanner APIs.
|
|
618
|
+
</p>
|
|
619
|
+
|
|
620
|
+
<!-- Step 1 -->
|
|
621
|
+
<div class="card">
|
|
622
|
+
<div class="card-title">
|
|
623
|
+
<span class="step">1</span> Connect SDK
|
|
624
|
+
</div>
|
|
625
|
+
|
|
626
|
+
<div class="quick-start">
|
|
627
|
+
<strong style="font-size: 0.85rem"
|
|
628
|
+
>Quick Start — Create a new shopper
|
|
629
|
+
session</strong
|
|
630
|
+
>
|
|
631
|
+
<div
|
|
632
|
+
class="inline-row"
|
|
633
|
+
style="margin-top: 0.5rem; gap: 0.4rem"
|
|
634
|
+
>
|
|
264
635
|
<input
|
|
265
636
|
type="number"
|
|
266
637
|
id="createStudioId"
|
|
267
|
-
placeholder="
|
|
268
|
-
style="
|
|
638
|
+
placeholder="Studio ID"
|
|
639
|
+
style="max-width: 110px"
|
|
269
640
|
/>
|
|
270
|
-
<label>API Key:</label>
|
|
271
641
|
<input
|
|
272
642
|
type="text"
|
|
273
643
|
id="createApiKey"
|
|
274
|
-
placeholder="API
|
|
275
|
-
style="flex: 1"
|
|
644
|
+
placeholder="API Key"
|
|
276
645
|
/>
|
|
277
|
-
<button id="btn-create-shopper">
|
|
278
|
-
Create
|
|
646
|
+
<button id="btn-create-shopper" class="primary">
|
|
647
|
+
Create
|
|
279
648
|
</button>
|
|
280
649
|
</div>
|
|
281
650
|
</div>
|
|
282
651
|
|
|
283
|
-
<label for="shopperGuid">Shopper GUID
|
|
652
|
+
<label class="field" for="shopperGuid">Shopper GUID</label>
|
|
284
653
|
<input
|
|
285
654
|
type="text"
|
|
286
655
|
id="shopperGuid"
|
|
287
|
-
placeholder="e.g., F1199DCD-BB45-4BD0
|
|
656
|
+
placeholder="e.g., F1199DCD-BB45-4BD0-..."
|
|
288
657
|
/>
|
|
289
658
|
|
|
290
|
-
<label for="accountId">Account ID
|
|
659
|
+
<label class="field" for="accountId">Account ID</label>
|
|
291
660
|
<input type="text" id="accountId" placeholder="e.g., 508" />
|
|
292
661
|
|
|
293
|
-
<label for="apiKey">API Key
|
|
294
|
-
<input
|
|
295
|
-
type="text"
|
|
296
|
-
id="apiKey"
|
|
297
|
-
placeholder="e.g., your-api-key"
|
|
298
|
-
/>
|
|
662
|
+
<label class="field" for="apiKey">API Key</label>
|
|
663
|
+
<input type="text" id="apiKey" placeholder="your-api-key" />
|
|
299
664
|
|
|
300
|
-
<div
|
|
301
|
-
<button id="btn-init"
|
|
302
|
-
|
|
303
|
-
|
|
665
|
+
<div class="btn-row">
|
|
666
|
+
<button id="btn-init" class="primary">
|
|
667
|
+
Initialize SDK
|
|
668
|
+
</button>
|
|
669
|
+
<button id="btn-check-sdk">Check Status</button>
|
|
670
|
+
<button id="btn-reset" class="danger">Reset</button>
|
|
304
671
|
</div>
|
|
305
672
|
</div>
|
|
306
673
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
</button>
|
|
313
|
-
<button class="tab" data-tab="scanner">Scanner API</button>
|
|
314
|
-
</div>
|
|
674
|
+
<!-- Step 2 -->
|
|
675
|
+
<div class="card">
|
|
676
|
+
<div class="card-title">
|
|
677
|
+
<span class="step">2</span> Explore APIs
|
|
678
|
+
</div>
|
|
315
679
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
<button id="btn-theme">Get Theme</button>
|
|
325
|
-
<button id="btn-disposition">
|
|
326
|
-
Get Disposition
|
|
327
|
-
</button>
|
|
328
|
-
<button id="btn-root">Get Root Config</button>
|
|
329
|
-
<button id="btn-landing">
|
|
330
|
-
Get Landing Page
|
|
331
|
-
</button>
|
|
332
|
-
</div>
|
|
333
|
-
</div>
|
|
334
|
-
</details>
|
|
680
|
+
<div class="api-tabs">
|
|
681
|
+
<button class="api-tab active" data-tab="shopper">
|
|
682
|
+
Shopper
|
|
683
|
+
</button>
|
|
684
|
+
<button class="api-tab" data-tab="scanner">
|
|
685
|
+
Scanner
|
|
686
|
+
</button>
|
|
687
|
+
</div>
|
|
335
688
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
<
|
|
339
|
-
<
|
|
340
|
-
<
|
|
689
|
+
<!-- SHOPPER -->
|
|
690
|
+
<div id="tab-shopper" class="api-content active">
|
|
691
|
+
<details class="api-section" open>
|
|
692
|
+
<summary>
|
|
693
|
+
Account <code>DRT.shopper.account</code>
|
|
694
|
+
</summary>
|
|
695
|
+
<div class="section-body">
|
|
696
|
+
<div class="btn-row">
|
|
697
|
+
<button id="btn-theme">Theme</button>
|
|
698
|
+
<button id="btn-disposition">
|
|
699
|
+
Disposition
|
|
700
|
+
</button>
|
|
701
|
+
<button id="btn-root">Root Config</button>
|
|
702
|
+
<button id="btn-landing">
|
|
703
|
+
Landing Page
|
|
704
|
+
</button>
|
|
705
|
+
</div>
|
|
341
706
|
</div>
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
707
|
+
</details>
|
|
708
|
+
|
|
709
|
+
<details class="api-section" open>
|
|
710
|
+
<summary>
|
|
711
|
+
Events <code>DRT.shopper.event</code>
|
|
712
|
+
</summary>
|
|
713
|
+
<div class="section-body">
|
|
714
|
+
<div class="btn-row">
|
|
715
|
+
<button id="btn-events" class="primary">
|
|
716
|
+
Get All Events
|
|
717
|
+
</button>
|
|
718
|
+
</div>
|
|
719
|
+
<div
|
|
720
|
+
class="inline-row"
|
|
721
|
+
style="margin-top: 0.5rem"
|
|
347
722
|
>
|
|
348
|
-
<
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
723
|
+
<select id="eventSelect" style="flex: 1">
|
|
724
|
+
<option value="">
|
|
725
|
+
— Click "Get All Events" first
|
|
726
|
+
—
|
|
727
|
+
</option>
|
|
728
|
+
</select>
|
|
729
|
+
<button id="btn-event-details">
|
|
730
|
+
Get Details
|
|
731
|
+
</button>
|
|
732
|
+
</div>
|
|
355
733
|
</div>
|
|
356
|
-
</
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
734
|
+
</details>
|
|
735
|
+
|
|
736
|
+
<details
|
|
737
|
+
id="section-seats"
|
|
738
|
+
class="api-section hidden-section"
|
|
739
|
+
>
|
|
740
|
+
<summary>
|
|
741
|
+
Seats
|
|
742
|
+
<code>DRT.shopper.seat</code>
|
|
743
|
+
<span
|
|
744
|
+
id="seat-badge"
|
|
745
|
+
class="section-badge"
|
|
746
|
+
></span>
|
|
747
|
+
</summary>
|
|
748
|
+
<div class="section-body">
|
|
749
|
+
<div id="seat-type-info" class="info-banner">
|
|
750
|
+
Loading…
|
|
751
|
+
</div>
|
|
752
|
+
<div
|
|
753
|
+
id="seat-ga-controls"
|
|
754
|
+
style="display: none"
|
|
755
|
+
>
|
|
756
|
+
<div class="inline-row">
|
|
757
|
+
<label>Tier</label>
|
|
758
|
+
<select
|
|
759
|
+
id="tierSelect"
|
|
760
|
+
style="flex: 2"
|
|
761
|
+
></select>
|
|
762
|
+
<label>Qty</label>
|
|
763
|
+
<input
|
|
764
|
+
type="number"
|
|
765
|
+
id="gaQty"
|
|
766
|
+
value="1"
|
|
767
|
+
style="max-width: 70px"
|
|
768
|
+
/>
|
|
769
|
+
<button
|
|
770
|
+
id="btn-hold-ga"
|
|
771
|
+
class="primary"
|
|
772
|
+
>
|
|
773
|
+
Hold
|
|
774
|
+
</button>
|
|
775
|
+
</div>
|
|
776
|
+
</div>
|
|
777
|
+
<div
|
|
778
|
+
id="seat-ba-controls"
|
|
779
|
+
style="display: none"
|
|
780
|
+
>
|
|
781
|
+
<div class="inline-row">
|
|
782
|
+
<label>Seat #</label>
|
|
783
|
+
<input
|
|
784
|
+
type="number"
|
|
785
|
+
id="reservedSeatNum"
|
|
786
|
+
placeholder="e.g., 1"
|
|
787
|
+
style="flex: 1"
|
|
788
|
+
/>
|
|
789
|
+
<button
|
|
790
|
+
id="btn-hold-reserved"
|
|
791
|
+
class="primary"
|
|
792
|
+
>
|
|
793
|
+
Hold Reserved Seat
|
|
794
|
+
</button>
|
|
795
|
+
</div>
|
|
796
|
+
<p
|
|
797
|
+
style="
|
|
798
|
+
margin: 0.35rem 0 0;
|
|
799
|
+
font-size: 0.75rem;
|
|
800
|
+
color: var(--text-muted);
|
|
801
|
+
"
|
|
802
|
+
>
|
|
803
|
+
Use section rules from event details to
|
|
804
|
+
find valid seat numbers.
|
|
805
|
+
</p>
|
|
806
|
+
</div>
|
|
381
807
|
</div>
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
808
|
+
</details>
|
|
809
|
+
|
|
810
|
+
<details
|
|
811
|
+
id="section-update-tier"
|
|
812
|
+
class="api-section hidden-section"
|
|
813
|
+
>
|
|
814
|
+
<summary>
|
|
815
|
+
Update Tier
|
|
816
|
+
<code>DRT.shopper.seat.updateTier</code>
|
|
817
|
+
<span
|
|
818
|
+
id="tier-badge"
|
|
819
|
+
class="section-badge"
|
|
820
|
+
></span>
|
|
821
|
+
</summary>
|
|
822
|
+
<div class="section-body">
|
|
823
|
+
<p
|
|
824
|
+
style="
|
|
825
|
+
margin: 0 0 0.5rem;
|
|
826
|
+
color: var(--text-muted);
|
|
827
|
+
font-size: 0.8rem;
|
|
828
|
+
"
|
|
829
|
+
>
|
|
830
|
+
Change the pricing tier for a held seat.
|
|
831
|
+
</p>
|
|
832
|
+
<div class="inline-row">
|
|
833
|
+
<label>Seat #</label>
|
|
834
|
+
<input
|
|
835
|
+
type="number"
|
|
836
|
+
id="updateTierSeatNum"
|
|
837
|
+
placeholder="seat"
|
|
838
|
+
style="max-width: 90px"
|
|
839
|
+
/>
|
|
840
|
+
<label>Tier</label>
|
|
385
841
|
<select
|
|
386
|
-
id="
|
|
387
|
-
style="
|
|
842
|
+
id="updateTierSelect"
|
|
843
|
+
style="flex: 2"
|
|
388
844
|
></select>
|
|
389
|
-
<
|
|
845
|
+
<button id="btn-update-tier">Update</button>
|
|
846
|
+
</div>
|
|
847
|
+
</div>
|
|
848
|
+
</details>
|
|
849
|
+
|
|
850
|
+
<details
|
|
851
|
+
id="section-products"
|
|
852
|
+
class="api-section hidden-section"
|
|
853
|
+
>
|
|
854
|
+
<summary>
|
|
855
|
+
Products
|
|
856
|
+
<code>DRT.shopper.product</code>
|
|
857
|
+
<span
|
|
858
|
+
id="product-badge"
|
|
859
|
+
class="section-badge"
|
|
860
|
+
></span>
|
|
861
|
+
</summary>
|
|
862
|
+
<div class="section-body">
|
|
863
|
+
<div class="btn-row">
|
|
864
|
+
<button id="btn-get-products">
|
|
865
|
+
Get Products
|
|
866
|
+
</button>
|
|
867
|
+
</div>
|
|
868
|
+
<div
|
|
869
|
+
class="inline-row"
|
|
870
|
+
style="margin-top: 0.5rem; gap: 0.4rem"
|
|
871
|
+
>
|
|
872
|
+
<input
|
|
873
|
+
type="number"
|
|
874
|
+
id="productId"
|
|
875
|
+
placeholder="ID"
|
|
876
|
+
style="max-width: 70px"
|
|
877
|
+
/>
|
|
878
|
+
<input
|
|
879
|
+
type="text"
|
|
880
|
+
id="productHash"
|
|
881
|
+
placeholder="hash"
|
|
882
|
+
style="max-width: 120px"
|
|
883
|
+
/>
|
|
884
|
+
<input
|
|
885
|
+
type="number"
|
|
886
|
+
id="productVariant"
|
|
887
|
+
placeholder="Variant"
|
|
888
|
+
value="0"
|
|
889
|
+
style="max-width: 75px"
|
|
890
|
+
/>
|
|
390
891
|
<input
|
|
391
892
|
type="number"
|
|
392
|
-
id="
|
|
393
|
-
placeholder="
|
|
893
|
+
id="productQty"
|
|
894
|
+
placeholder="Qty"
|
|
394
895
|
value="1"
|
|
395
|
-
style="width: 60px"
|
|
896
|
+
style="max-width: 60px"
|
|
396
897
|
/>
|
|
397
|
-
<button
|
|
398
|
-
|
|
898
|
+
<button
|
|
899
|
+
id="btn-add-product"
|
|
900
|
+
class="primary"
|
|
901
|
+
>
|
|
902
|
+
Add
|
|
903
|
+
</button>
|
|
904
|
+
</div>
|
|
905
|
+
</div>
|
|
906
|
+
</details>
|
|
907
|
+
|
|
908
|
+
<details class="api-section" open>
|
|
909
|
+
<summary>
|
|
910
|
+
Cart
|
|
911
|
+
<code>DRT.shopper.cart</code>
|
|
912
|
+
<span
|
|
913
|
+
id="cart-badge"
|
|
914
|
+
class="section-badge"
|
|
915
|
+
></span>
|
|
916
|
+
</summary>
|
|
917
|
+
<div class="section-body">
|
|
918
|
+
<div class="btn-row">
|
|
919
|
+
<button id="btn-cart" class="primary">
|
|
920
|
+
Get Cart
|
|
921
|
+
</button>
|
|
922
|
+
<button id="btn-delete-cart" class="danger">
|
|
923
|
+
Delete Cart
|
|
399
924
|
</button>
|
|
400
925
|
</div>
|
|
926
|
+
<div id="cart-display" class="cart-items"></div>
|
|
401
927
|
</div>
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
928
|
+
</details>
|
|
929
|
+
|
|
930
|
+
<details class="api-section">
|
|
931
|
+
<summary>
|
|
932
|
+
Orders <code>DRT.shopper.order</code>
|
|
933
|
+
</summary>
|
|
934
|
+
<div class="section-body">
|
|
935
|
+
<div class="inline-row">
|
|
936
|
+
<label>Order GUID</label>
|
|
405
937
|
<input
|
|
406
|
-
type="
|
|
407
|
-
id="
|
|
408
|
-
placeholder="
|
|
409
|
-
|
|
938
|
+
type="text"
|
|
939
|
+
id="orderGuid"
|
|
940
|
+
placeholder="ABC123-..."
|
|
941
|
+
/>
|
|
942
|
+
<button id="btn-receipt">Receipt</button>
|
|
943
|
+
</div>
|
|
944
|
+
</div>
|
|
945
|
+
</details>
|
|
946
|
+
|
|
947
|
+
<details class="api-section">
|
|
948
|
+
<summary>
|
|
949
|
+
Codes / Discounts
|
|
950
|
+
<code>DRT.shopper.code</code>
|
|
951
|
+
</summary>
|
|
952
|
+
<div class="section-body">
|
|
953
|
+
<div class="inline-row">
|
|
954
|
+
<label>Code</label>
|
|
955
|
+
<input
|
|
956
|
+
type="text"
|
|
957
|
+
id="promoCode"
|
|
958
|
+
placeholder="SAVE10"
|
|
959
|
+
/>
|
|
960
|
+
<button id="btn-validate-code">
|
|
961
|
+
Validate
|
|
962
|
+
</button>
|
|
963
|
+
</div>
|
|
964
|
+
</div>
|
|
965
|
+
</details>
|
|
966
|
+
|
|
967
|
+
<details class="api-section">
|
|
968
|
+
<summary>
|
|
969
|
+
Gift Cards
|
|
970
|
+
<code>DRT.shopper.giftCard</code>
|
|
971
|
+
</summary>
|
|
972
|
+
<div class="section-body">
|
|
973
|
+
<div class="inline-row">
|
|
974
|
+
<label>Card #</label>
|
|
975
|
+
<input
|
|
976
|
+
type="text"
|
|
977
|
+
id="giftCardNumber"
|
|
978
|
+
placeholder="Gift card number"
|
|
979
|
+
/>
|
|
980
|
+
<button id="btn-gift-balance">
|
|
981
|
+
Check Balance
|
|
982
|
+
</button>
|
|
983
|
+
</div>
|
|
984
|
+
</div>
|
|
985
|
+
</details>
|
|
986
|
+
</div>
|
|
987
|
+
|
|
988
|
+
<!-- SCANNER -->
|
|
989
|
+
<div id="tab-scanner" class="api-content">
|
|
990
|
+
<details class="api-section" open>
|
|
991
|
+
<summary>
|
|
992
|
+
Scanning
|
|
993
|
+
<code>DRT.scanner.scanning</code>
|
|
994
|
+
</summary>
|
|
995
|
+
<div class="section-body">
|
|
996
|
+
<div class="btn-row">
|
|
997
|
+
<button id="btn-strings">
|
|
998
|
+
Get App Strings
|
|
999
|
+
<span
|
|
1000
|
+
class="section-badge"
|
|
1001
|
+
style="margin-left: 0.35rem"
|
|
1002
|
+
>no auth</span
|
|
1003
|
+
>
|
|
1004
|
+
</button>
|
|
1005
|
+
</div>
|
|
1006
|
+
</div>
|
|
1007
|
+
</details>
|
|
1008
|
+
|
|
1009
|
+
<details class="api-section" open>
|
|
1010
|
+
<summary>
|
|
1011
|
+
Database
|
|
1012
|
+
<code>DRT.scanner.database</code>
|
|
1013
|
+
</summary>
|
|
1014
|
+
<div class="section-body">
|
|
1015
|
+
<div class="inline-row">
|
|
1016
|
+
<label>Show Code</label>
|
|
1017
|
+
<input
|
|
1018
|
+
type="text"
|
|
1019
|
+
id="scannerShowCode"
|
|
1020
|
+
placeholder="e.g., ABC123"
|
|
1021
|
+
/>
|
|
1022
|
+
</div>
|
|
1023
|
+
<div
|
|
1024
|
+
class="inline-row"
|
|
1025
|
+
style="margin-top: 0.4rem"
|
|
1026
|
+
>
|
|
1027
|
+
<label>Device</label>
|
|
1028
|
+
<input
|
|
1029
|
+
type="text"
|
|
1030
|
+
id="scannerDevice"
|
|
1031
|
+
value="test-device"
|
|
1032
|
+
/>
|
|
1033
|
+
<label>User</label>
|
|
1034
|
+
<input
|
|
1035
|
+
type="text"
|
|
1036
|
+
id="scannerUser"
|
|
1037
|
+
value="test-user"
|
|
410
1038
|
/>
|
|
411
|
-
|
|
412
|
-
|
|
1039
|
+
</div>
|
|
1040
|
+
<div class="btn-row">
|
|
1041
|
+
<button id="btn-scanner-db">
|
|
1042
|
+
Download Database
|
|
1043
|
+
</button>
|
|
1044
|
+
<button id="btn-scanner-query">
|
|
1045
|
+
Query Sections
|
|
1046
|
+
</button>
|
|
1047
|
+
</div>
|
|
1048
|
+
</div>
|
|
1049
|
+
</details>
|
|
1050
|
+
|
|
1051
|
+
<details class="api-section">
|
|
1052
|
+
<summary>
|
|
1053
|
+
Orders
|
|
1054
|
+
<code>DRT.scanner.orders</code>
|
|
1055
|
+
</summary>
|
|
1056
|
+
<div class="section-body">
|
|
1057
|
+
<div class="inline-row">
|
|
1058
|
+
<label>Phone</label>
|
|
1059
|
+
<input
|
|
1060
|
+
type="text"
|
|
1061
|
+
id="scannerPhone"
|
|
1062
|
+
placeholder="Phone number"
|
|
1063
|
+
/>
|
|
1064
|
+
<button id="btn-scanner-by-phone">
|
|
1065
|
+
Search
|
|
413
1066
|
</button>
|
|
414
1067
|
</div>
|
|
415
1068
|
<div
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
font-size: 0.8rem;
|
|
419
|
-
color: #888;
|
|
420
|
-
"
|
|
1069
|
+
class="inline-row"
|
|
1070
|
+
style="margin-top: 0.4rem"
|
|
421
1071
|
>
|
|
422
|
-
|
|
423
|
-
|
|
1072
|
+
<label>Name</label>
|
|
1073
|
+
<input
|
|
1074
|
+
type="text"
|
|
1075
|
+
id="scannerName"
|
|
1076
|
+
placeholder="Buyer name"
|
|
1077
|
+
/>
|
|
1078
|
+
<button id="btn-scanner-by-name">
|
|
1079
|
+
Search
|
|
1080
|
+
</button>
|
|
424
1081
|
</div>
|
|
425
1082
|
</div>
|
|
1083
|
+
</details>
|
|
1084
|
+
</div>
|
|
1085
|
+
</div>
|
|
1086
|
+
</div>
|
|
1087
|
+
|
|
1088
|
+
<!-- RIGHT PANEL: Output + Implementation tabs -->
|
|
1089
|
+
<div class="right-panel">
|
|
1090
|
+
<div class="panel-tabs">
|
|
1091
|
+
<button class="panel-tab active" data-panel="output">
|
|
1092
|
+
Output
|
|
1093
|
+
</button>
|
|
1094
|
+
<button class="panel-tab" data-panel="impl">
|
|
1095
|
+
Implementation
|
|
1096
|
+
</button>
|
|
1097
|
+
</div>
|
|
1098
|
+
|
|
1099
|
+
<div id="panel-output" class="panel-content active">
|
|
1100
|
+
<div id="status" class="success">
|
|
1101
|
+
SDK loaded — initialize with your credentials
|
|
1102
|
+
</div>
|
|
1103
|
+
<div id="output-container">
|
|
1104
|
+
<pre id="output">
|
|
1105
|
+
// Initialize the SDK, then click a button to test...
|
|
1106
|
+
|
|
1107
|
+
// Tip: window.DRT is available in the browser console.</pre
|
|
1108
|
+
>
|
|
1109
|
+
</div>
|
|
1110
|
+
</div>
|
|
1111
|
+
|
|
1112
|
+
<div id="panel-impl" class="panel-content">
|
|
1113
|
+
<div id="impl-panel">
|
|
1114
|
+
<h3>Install</h3>
|
|
1115
|
+
<p>
|
|
1116
|
+
The SDK is distributed on npm and works in browsers,
|
|
1117
|
+
Node, and bundlers.
|
|
1118
|
+
</p>
|
|
1119
|
+
<div class="code-block">
|
|
1120
|
+
<button class="copy-btn" data-copy="npm-install">
|
|
1121
|
+
Copy
|
|
1122
|
+
</button>
|
|
1123
|
+
<pre
|
|
1124
|
+
id="npm-install"
|
|
1125
|
+
><span class="com"># With npm</span>
|
|
1126
|
+
npm install @drttix/drt-sdk
|
|
1127
|
+
|
|
1128
|
+
<span class="com"># With yarn</span>
|
|
1129
|
+
yarn add @drttix/drt-sdk
|
|
1130
|
+
|
|
1131
|
+
<span class="com"># With pnpm</span>
|
|
1132
|
+
pnpm add @drttix/drt-sdk</pre>
|
|
426
1133
|
</div>
|
|
427
|
-
</details>
|
|
428
1134
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
<
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
id="updateTierSeatNum"
|
|
453
|
-
placeholder="seat number"
|
|
454
|
-
style="width: 80px"
|
|
455
|
-
/>
|
|
456
|
-
<label>New Tier:</label>
|
|
457
|
-
<select
|
|
458
|
-
id="updateTierSelect"
|
|
459
|
-
style="width: 200px"
|
|
460
|
-
></select>
|
|
461
|
-
<button id="btn-update-tier">
|
|
462
|
-
Update Tier
|
|
463
|
-
</button>
|
|
464
|
-
</div>
|
|
1135
|
+
<h3>Browser (ES Modules)</h3>
|
|
1136
|
+
<p>
|
|
1137
|
+
Use the prebuilt bundle directly from a CDN or
|
|
1138
|
+
static host:
|
|
1139
|
+
</p>
|
|
1140
|
+
<div class="code-block">
|
|
1141
|
+
<button class="copy-btn" data-copy="browser-script">
|
|
1142
|
+
Copy
|
|
1143
|
+
</button>
|
|
1144
|
+
<pre
|
|
1145
|
+
id="browser-script"
|
|
1146
|
+
><span class="kw"><script</span> <span class="fn">type</span>=<span class="str">"module"</span><span class="kw">></span>
|
|
1147
|
+
<span class="kw">import</span> { DRT } <span class="kw">from</span> <span class="str">'https://df71w65i8efr5.cloudfront.net/public/sdk/latest/drt-sdk.js'</span>;
|
|
1148
|
+
|
|
1149
|
+
DRT.<span class="fn">init</span>({
|
|
1150
|
+
shopperGuid: <span class="str">'YOUR_SHOPPER_GUID'</span>,
|
|
1151
|
+
accountId: <span class="str">'YOUR_ACCOUNT_ID'</span>,
|
|
1152
|
+
apiKey: <span class="str">'YOUR_API_KEY'</span>,
|
|
1153
|
+
});
|
|
1154
|
+
|
|
1155
|
+
<span class="kw">const</span> events = <span class="kw">await</span> DRT.shopper.event.<span class="fn">getEvents</span>();
|
|
1156
|
+
<span class="fn">console</span>.log(events);
|
|
1157
|
+
<span class="kw"></script></span></pre>
|
|
465
1158
|
</div>
|
|
466
|
-
</details>
|
|
467
1159
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
<span
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
<input
|
|
489
|
-
type="number"
|
|
490
|
-
id="productId"
|
|
491
|
-
placeholder="id"
|
|
492
|
-
style="width: 70px"
|
|
493
|
-
/>
|
|
494
|
-
<label>Hash:</label>
|
|
495
|
-
<input
|
|
496
|
-
type="text"
|
|
497
|
-
id="productHash"
|
|
498
|
-
placeholder="hash"
|
|
499
|
-
style="width: 100px"
|
|
500
|
-
/>
|
|
501
|
-
<label>Variant:</label>
|
|
502
|
-
<input
|
|
503
|
-
type="number"
|
|
504
|
-
id="productVariant"
|
|
505
|
-
placeholder="0"
|
|
506
|
-
value="0"
|
|
507
|
-
style="width: 60px"
|
|
508
|
-
/>
|
|
509
|
-
<label>Qty:</label>
|
|
510
|
-
<input
|
|
511
|
-
type="number"
|
|
512
|
-
id="productQty"
|
|
513
|
-
placeholder="1"
|
|
514
|
-
value="1"
|
|
515
|
-
style="width: 60px"
|
|
516
|
-
/>
|
|
517
|
-
<button id="btn-add-product">
|
|
518
|
-
Add Product
|
|
519
|
-
</button>
|
|
520
|
-
</div>
|
|
1160
|
+
<h3>JavaScript / TypeScript</h3>
|
|
1161
|
+
<div class="code-block">
|
|
1162
|
+
<button class="copy-btn" data-copy="js-usage">
|
|
1163
|
+
Copy
|
|
1164
|
+
</button>
|
|
1165
|
+
<pre
|
|
1166
|
+
id="js-usage"
|
|
1167
|
+
><span class="kw">import</span> { DRT } <span class="kw">from</span> <span class="str">'@drttix/drt-sdk'</span>;
|
|
1168
|
+
|
|
1169
|
+
<span class="com">// 1. Initialize once at app startup</span>
|
|
1170
|
+
DRT.<span class="fn">init</span>({
|
|
1171
|
+
shopperGuid: <span class="str">'F1199DCD-BB45-4BD0-...'</span>,
|
|
1172
|
+
accountId: <span class="str">'508'</span>,
|
|
1173
|
+
apiKey: <span class="str">'your-api-key'</span>,
|
|
1174
|
+
});
|
|
1175
|
+
|
|
1176
|
+
<span class="com">// 2. Call any service — credentials are injected automatically</span>
|
|
1177
|
+
<span class="kw">const</span> events = <span class="kw">await</span> DRT.shopper.event.<span class="fn">getEvents</span>();
|
|
1178
|
+
<span class="kw">const</span> details = <span class="kw">await</span> DRT.shopper.event.<span class="fn">getEventById</span>(<span class="num">42075</span>);
|
|
1179
|
+
<span class="kw">const</span> cart = <span class="kw">await</span> DRT.shopper.cart.<span class="fn">getCart</span>();</pre>
|
|
521
1180
|
</div>
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
1181
|
+
|
|
1182
|
+
<h3>Creating a Shopper Session</h3>
|
|
1183
|
+
<p>
|
|
1184
|
+
If you don't have a shopperGuid yet, create one
|
|
1185
|
+
first:
|
|
1186
|
+
</p>
|
|
1187
|
+
<div class="code-block">
|
|
1188
|
+
<button class="copy-btn" data-copy="create-session">
|
|
1189
|
+
Copy
|
|
1190
|
+
</button>
|
|
1191
|
+
<pre
|
|
1192
|
+
id="create-session"
|
|
1193
|
+
><span class="kw">const</span> session = <span class="kw">await</span> DRT.shopper.session.<span class="fn">createSession</span>({
|
|
1194
|
+
studioId: <span class="num">508</span>,
|
|
1195
|
+
});
|
|
1196
|
+
|
|
1197
|
+
DRT.<span class="fn">init</span>({
|
|
1198
|
+
shopperGuid: session.shopperGuid,
|
|
1199
|
+
accountId: <span class="fn">String</span>(session.studioId),
|
|
1200
|
+
apiKey: <span class="str">'your-api-key'</span>,
|
|
1201
|
+
});</pre>
|
|
533
1202
|
</div>
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
1203
|
+
|
|
1204
|
+
<h3>Holding Seats</h3>
|
|
1205
|
+
<div class="code-block">
|
|
1206
|
+
<button class="copy-btn" data-copy="hold-seats">
|
|
1207
|
+
Copy
|
|
1208
|
+
</button>
|
|
1209
|
+
<pre
|
|
1210
|
+
id="hold-seats"
|
|
1211
|
+
><span class="com">// Reserved seat</span>
|
|
1212
|
+
<span class="kw">await</span> DRT.shopper.seat.<span class="fn">holdReservedSeat</span>({
|
|
1213
|
+
eventId: <span class="num">42075</span>,
|
|
1214
|
+
seatNum: <span class="num">101</span>,
|
|
1215
|
+
});
|
|
1216
|
+
|
|
1217
|
+
<span class="com">// General admission</span>
|
|
1218
|
+
<span class="kw">await</span> DRT.shopper.seat.<span class="fn">holdGaSeat</span>({
|
|
1219
|
+
eventId: <span class="num">42075</span>,
|
|
1220
|
+
tierId: <span class="num">1</span>,
|
|
1221
|
+
qty: <span class="num">2</span>,
|
|
1222
|
+
allOrNone: <span class="kw">true</span>,
|
|
1223
|
+
});
|
|
1224
|
+
|
|
1225
|
+
<span class="com">// Release a reserved seat</span>
|
|
1226
|
+
<span class="kw">await</span> DRT.shopper.seat.<span class="fn">releaseReservedSeat</span>({
|
|
1227
|
+
eventId: <span class="num">42075</span>,
|
|
1228
|
+
seatNum: <span class="num">101</span>,
|
|
1229
|
+
});
|
|
1230
|
+
|
|
1231
|
+
<span class="com">// Release GA seat</span>
|
|
1232
|
+
<span class="kw">await</span> DRT.shopper.seat.<span class="fn">releaseGaSeat</span>({
|
|
1233
|
+
eventId: <span class="num">42075</span>,
|
|
1234
|
+
tierId: <span class="num">1</span>,
|
|
1235
|
+
qty: <span class="num">1</span>,
|
|
1236
|
+
});</pre>
|
|
548
1237
|
</div>
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
</div>
|
|
1238
|
+
|
|
1239
|
+
<h3>Cart Management</h3>
|
|
1240
|
+
<div class="code-block">
|
|
1241
|
+
<button class="copy-btn" data-copy="cart-ex">
|
|
1242
|
+
Copy
|
|
1243
|
+
</button>
|
|
1244
|
+
<pre
|
|
1245
|
+
id="cart-ex"
|
|
1246
|
+
><span class="kw">const</span> { cart } = <span class="kw">await</span> DRT.shopper.cart.<span class="fn">getCart</span>();
|
|
1247
|
+
|
|
1248
|
+
<span class="com">// cart.seats, cart.products, cart.donations</span>
|
|
1249
|
+
<span class="kw">for</span> (<span class="kw">const</span> seat <span class="kw">of</span> cart.seats) {
|
|
1250
|
+
<span class="fn">console</span>.log(seat.tierName, seat.displayPrice);
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
<span class="com">// Clear entire cart</span>
|
|
1254
|
+
<span class="kw">await</span> DRT.shopper.cart.<span class="fn">deleteCart</span>();</pre>
|
|
567
1255
|
</div>
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
/>
|
|
582
|
-
<button id="btn-gift-balance">
|
|
583
|
-
Check Balance
|
|
584
|
-
</button>
|
|
585
|
-
</div>
|
|
1256
|
+
|
|
1257
|
+
<h3>Error Handling</h3>
|
|
1258
|
+
<div class="code-block">
|
|
1259
|
+
<button class="copy-btn" data-copy="err-handling">
|
|
1260
|
+
Copy
|
|
1261
|
+
</button>
|
|
1262
|
+
<pre id="err-handling"><span class="kw">try</span> {
|
|
1263
|
+
<span class="kw">const</span> events = <span class="kw">await</span> DRT.shopper.event.<span class="fn">getEvents</span>();
|
|
1264
|
+
} <span class="kw">catch</span> (err) {
|
|
1265
|
+
<span class="com">// err.status = HTTP status (400, 404, 500, ...)</span>
|
|
1266
|
+
<span class="com">// err.body = API error payload (errorCode, message)</span>
|
|
1267
|
+
<span class="fn">console</span>.error(err.status, err.body);
|
|
1268
|
+
}</pre>
|
|
586
1269
|
</div>
|
|
587
|
-
</details>
|
|
588
|
-
</div>
|
|
589
1270
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
Scanner app strings and utilities.
|
|
595
|
-
<code>DRT.scanner.scanning</code>
|
|
596
|
-
</p>
|
|
597
|
-
<div class="btn-group">
|
|
598
|
-
<button id="btn-strings">
|
|
599
|
-
Get App Strings (no auth)
|
|
600
|
-
</button>
|
|
601
|
-
</div>
|
|
1271
|
+
<h3>Available Services</h3>
|
|
1272
|
+
<div class="code-block">
|
|
1273
|
+
<pre><span class="kw">DRT</span>.shopper.{ account, event, seat, cart, product,
|
|
1274
|
+
order, code, giftCard, session, ... }
|
|
602
1275
|
|
|
603
|
-
|
|
604
|
-
<p>
|
|
605
|
-
Scanner database operations.
|
|
606
|
-
<code>DRT.scanner.database</code>
|
|
607
|
-
</p>
|
|
608
|
-
<div class="input-row">
|
|
609
|
-
<label>Show Code:</label>
|
|
610
|
-
<input
|
|
611
|
-
type="text"
|
|
612
|
-
id="scannerShowCode"
|
|
613
|
-
placeholder="e.g., ABC123"
|
|
614
|
-
/>
|
|
615
|
-
</div>
|
|
616
|
-
<div class="input-row">
|
|
617
|
-
<label>Device:</label>
|
|
618
|
-
<input
|
|
619
|
-
type="text"
|
|
620
|
-
id="scannerDevice"
|
|
621
|
-
placeholder="device name"
|
|
622
|
-
value="test-device"
|
|
623
|
-
/>
|
|
624
|
-
<label>User:</label>
|
|
625
|
-
<input
|
|
626
|
-
type="text"
|
|
627
|
-
id="scannerUser"
|
|
628
|
-
placeholder="username"
|
|
629
|
-
value="test-user"
|
|
630
|
-
/>
|
|
631
|
-
</div>
|
|
632
|
-
<div class="btn-group">
|
|
633
|
-
<button id="btn-scanner-db">Download Database</button>
|
|
634
|
-
<button id="btn-scanner-query">Query Sections</button>
|
|
635
|
-
</div>
|
|
1276
|
+
<span class="kw">DRT</span>.scanner.{ scanning, database, orders }
|
|
636
1277
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
Order lookup for scanning.
|
|
640
|
-
<code>DRT.scanner.orders</code>
|
|
641
|
-
</p>
|
|
642
|
-
<div class="input-row">
|
|
643
|
-
<label>Phone:</label>
|
|
644
|
-
<input
|
|
645
|
-
type="text"
|
|
646
|
-
id="scannerPhone"
|
|
647
|
-
placeholder="Phone number"
|
|
648
|
-
/>
|
|
649
|
-
<button id="btn-scanner-by-phone">
|
|
650
|
-
Search by Phone
|
|
651
|
-
</button>
|
|
652
|
-
</div>
|
|
653
|
-
<div class="input-row">
|
|
654
|
-
<label>Name:</label>
|
|
655
|
-
<input
|
|
656
|
-
type="text"
|
|
657
|
-
id="scannerName"
|
|
658
|
-
placeholder="Buyer name"
|
|
659
|
-
/>
|
|
660
|
-
<button id="btn-scanner-by-name">Search by Name</button>
|
|
661
|
-
</div>
|
|
662
|
-
</div>
|
|
663
|
-
</div>
|
|
1278
|
+
<span class="kw">DRT</span>.portal .{ ... admin-only services }</pre>
|
|
1279
|
+
</div>
|
|
664
1280
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
1281
|
+
<h3>API Documentation (Swagger)</h3>
|
|
1282
|
+
<p>
|
|
1283
|
+
Interactive API docs for each service — open
|
|
1284
|
+
directly in the browser:
|
|
1285
|
+
</p>
|
|
1286
|
+
<div
|
|
1287
|
+
style="
|
|
1288
|
+
display: flex;
|
|
1289
|
+
flex-direction: column;
|
|
1290
|
+
gap: 0.4rem;
|
|
1291
|
+
margin: 0.5rem 0;
|
|
1292
|
+
"
|
|
1293
|
+
>
|
|
1294
|
+
<a
|
|
1295
|
+
href="https://api.drttix.com/shopper/docs"
|
|
1296
|
+
target="_blank"
|
|
1297
|
+
rel="noopener"
|
|
1298
|
+
style="
|
|
1299
|
+
display: flex;
|
|
1300
|
+
align-items: center;
|
|
1301
|
+
gap: 0.6rem;
|
|
1302
|
+
padding: 0.55rem 0.8rem;
|
|
1303
|
+
background: #11111b;
|
|
1304
|
+
border: 1px solid #313244;
|
|
1305
|
+
border-radius: 6px;
|
|
1306
|
+
color: #89b4fa;
|
|
1307
|
+
text-decoration: none;
|
|
1308
|
+
font-size: 0.85rem;
|
|
1309
|
+
font-family: inherit;
|
|
1310
|
+
"
|
|
1311
|
+
>
|
|
1312
|
+
<span style="font-size: 1rem">🛒</span>
|
|
1313
|
+
<span
|
|
1314
|
+
><strong>Shopper API</strong> —
|
|
1315
|
+
events, seats, cart, products,
|
|
1316
|
+
checkout</span
|
|
1317
|
+
>
|
|
1318
|
+
<span
|
|
1319
|
+
style="
|
|
1320
|
+
margin-left: auto;
|
|
1321
|
+
font-size: 0.7rem;
|
|
1322
|
+
color: #6c7086;
|
|
1323
|
+
"
|
|
1324
|
+
>api.drttix.com/shopper/docs</span
|
|
1325
|
+
>
|
|
1326
|
+
</a>
|
|
1327
|
+
<a
|
|
1328
|
+
href="https://api.drttix.com/scanner-v3/docs"
|
|
1329
|
+
target="_blank"
|
|
1330
|
+
rel="noopener"
|
|
1331
|
+
style="
|
|
1332
|
+
display: flex;
|
|
1333
|
+
align-items: center;
|
|
1334
|
+
gap: 0.6rem;
|
|
1335
|
+
padding: 0.55rem 0.8rem;
|
|
1336
|
+
background: #11111b;
|
|
1337
|
+
border: 1px solid #313244;
|
|
1338
|
+
border-radius: 6px;
|
|
1339
|
+
color: #89b4fa;
|
|
1340
|
+
text-decoration: none;
|
|
1341
|
+
font-size: 0.85rem;
|
|
1342
|
+
font-family: inherit;
|
|
1343
|
+
"
|
|
1344
|
+
>
|
|
1345
|
+
<span style="font-size: 1rem">📷</span>
|
|
1346
|
+
<span
|
|
1347
|
+
><strong>Scanner API</strong> —
|
|
1348
|
+
scanning, database, orders</span
|
|
1349
|
+
>
|
|
1350
|
+
<span
|
|
1351
|
+
style="
|
|
1352
|
+
margin-left: auto;
|
|
1353
|
+
font-size: 0.7rem;
|
|
1354
|
+
color: #6c7086;
|
|
1355
|
+
"
|
|
1356
|
+
>api.drttix.com/scanner-v3/docs</span
|
|
1357
|
+
>
|
|
1358
|
+
</a>
|
|
1359
|
+
<a
|
|
1360
|
+
href="https://api.drttix.com/admin-portal/docs"
|
|
1361
|
+
target="_blank"
|
|
1362
|
+
rel="noopener"
|
|
1363
|
+
style="
|
|
1364
|
+
display: flex;
|
|
1365
|
+
align-items: center;
|
|
1366
|
+
gap: 0.6rem;
|
|
1367
|
+
padding: 0.55rem 0.8rem;
|
|
1368
|
+
background: #11111b;
|
|
1369
|
+
border: 1px solid #313244;
|
|
1370
|
+
border-radius: 6px;
|
|
1371
|
+
color: #89b4fa;
|
|
1372
|
+
text-decoration: none;
|
|
1373
|
+
font-size: 0.85rem;
|
|
1374
|
+
font-family: inherit;
|
|
1375
|
+
"
|
|
1376
|
+
>
|
|
1377
|
+
<span style="font-size: 1rem"
|
|
1378
|
+
>⚙️</span
|
|
1379
|
+
>
|
|
1380
|
+
<span
|
|
1381
|
+
><strong>Portal API</strong> —
|
|
1382
|
+
admin-only services</span
|
|
1383
|
+
>
|
|
1384
|
+
<span
|
|
1385
|
+
style="
|
|
1386
|
+
margin-left: auto;
|
|
1387
|
+
font-size: 0.7rem;
|
|
1388
|
+
color: #6c7086;
|
|
1389
|
+
"
|
|
1390
|
+
>api.drttix.com/admin-portal/docs</span
|
|
1391
|
+
>
|
|
1392
|
+
</a>
|
|
1393
|
+
</div>
|
|
1394
|
+
|
|
1395
|
+
<div class="impl-note">
|
|
1396
|
+
<strong>Note:</strong> Once
|
|
1397
|
+
<code>DRT.init()</code> is called, the
|
|
1398
|
+
<code>shopperguid</code>, <code>accountid</code>,
|
|
1399
|
+
and <code>apikey</code> headers are automatically
|
|
1400
|
+
attached to every request — you don't need to
|
|
1401
|
+
pass them as function arguments.
|
|
1402
|
+
</div>
|
|
1403
|
+
</div>
|
|
674
1404
|
</div>
|
|
675
1405
|
</div>
|
|
676
1406
|
</div>
|
|
@@ -684,6 +1414,12 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
684
1414
|
// Expose DRT globally for console testing
|
|
685
1415
|
window.DRT = DRT;
|
|
686
1416
|
|
|
1417
|
+
// Display the real SDK version if available
|
|
1418
|
+
if (DRT.version) {
|
|
1419
|
+
document.getElementById('sdkVersionBadge').textContent =
|
|
1420
|
+
'v' + DRT.version;
|
|
1421
|
+
}
|
|
1422
|
+
|
|
687
1423
|
function setStatus(msg, isError = false) {
|
|
688
1424
|
status.textContent = msg;
|
|
689
1425
|
status.className = isError ? 'error' : 'success';
|
|
@@ -693,13 +1429,13 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
693
1429
|
out.textContent =
|
|
694
1430
|
typeof data === 'string'
|
|
695
1431
|
? data
|
|
696
|
-
: JSON.stringify(data, null,
|
|
1432
|
+
: JSON.stringify(data, null, 2);
|
|
697
1433
|
}
|
|
698
1434
|
|
|
699
1435
|
function requireInit() {
|
|
700
1436
|
if (!DRT.isReady()) {
|
|
701
1437
|
setStatus(
|
|
702
|
-
'SDK not initialized!
|
|
1438
|
+
'SDK not initialized! Fill credentials and click Initialize.',
|
|
703
1439
|
true,
|
|
704
1440
|
);
|
|
705
1441
|
return false;
|
|
@@ -711,26 +1447,65 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
711
1447
|
setStatus(`Fetching ${description}...`, false);
|
|
712
1448
|
try {
|
|
713
1449
|
const result = await fn();
|
|
714
|
-
setStatus(
|
|
1450
|
+
setStatus(`Success - ${description}`, false);
|
|
715
1451
|
setOutput(result);
|
|
1452
|
+
return result;
|
|
716
1453
|
} catch (err) {
|
|
717
1454
|
setStatus(`Error: ${err.message}`, true);
|
|
718
1455
|
setOutput({
|
|
719
1456
|
error: err.message,
|
|
1457
|
+
status: err.status,
|
|
720
1458
|
details: err.body || err.toString(),
|
|
721
1459
|
});
|
|
722
1460
|
console.error(err);
|
|
1461
|
+
return null;
|
|
723
1462
|
}
|
|
724
1463
|
}
|
|
725
1464
|
|
|
726
|
-
|
|
727
|
-
document.querySelectorAll('.tab').forEach((tab) => {
|
|
1465
|
+
/* ============ Right-panel tabs (Output / Implementation) ============ */
|
|
1466
|
+
document.querySelectorAll('.panel-tab').forEach((tab) => {
|
|
1467
|
+
tab.addEventListener('click', () => {
|
|
1468
|
+
document
|
|
1469
|
+
.querySelectorAll('.panel-tab')
|
|
1470
|
+
.forEach((t) => t.classList.remove('active'));
|
|
1471
|
+
document
|
|
1472
|
+
.querySelectorAll('.panel-content')
|
|
1473
|
+
.forEach((c) => c.classList.remove('active'));
|
|
1474
|
+
tab.classList.add('active');
|
|
1475
|
+
document
|
|
1476
|
+
.getElementById(`panel-${tab.dataset.panel}`)
|
|
1477
|
+
.classList.add('active');
|
|
1478
|
+
});
|
|
1479
|
+
});
|
|
1480
|
+
|
|
1481
|
+
/* ============ Copy-to-clipboard for impl code blocks ============ */
|
|
1482
|
+
document.querySelectorAll('.copy-btn').forEach((btn) => {
|
|
1483
|
+
btn.addEventListener('click', async () => {
|
|
1484
|
+
const id = btn.dataset.copy;
|
|
1485
|
+
const el = document.getElementById(id);
|
|
1486
|
+
if (!el) return;
|
|
1487
|
+
try {
|
|
1488
|
+
await navigator.clipboard.writeText(el.innerText);
|
|
1489
|
+
btn.textContent = 'Copied!';
|
|
1490
|
+
btn.classList.add('copied');
|
|
1491
|
+
setTimeout(() => {
|
|
1492
|
+
btn.textContent = 'Copy';
|
|
1493
|
+
btn.classList.remove('copied');
|
|
1494
|
+
}, 1500);
|
|
1495
|
+
} catch (e) {
|
|
1496
|
+
console.error(e);
|
|
1497
|
+
}
|
|
1498
|
+
});
|
|
1499
|
+
});
|
|
1500
|
+
|
|
1501
|
+
/* ============ API left-panel tabs (Shopper / Scanner) ============ */
|
|
1502
|
+
document.querySelectorAll('.api-tab').forEach((tab) => {
|
|
728
1503
|
tab.addEventListener('click', () => {
|
|
729
1504
|
document
|
|
730
|
-
.querySelectorAll('.tab')
|
|
1505
|
+
.querySelectorAll('.api-tab')
|
|
731
1506
|
.forEach((t) => t.classList.remove('active'));
|
|
732
1507
|
document
|
|
733
|
-
.querySelectorAll('.
|
|
1508
|
+
.querySelectorAll('.api-content')
|
|
734
1509
|
.forEach((c) => c.classList.remove('active'));
|
|
735
1510
|
tab.classList.add('active');
|
|
736
1511
|
document
|
|
@@ -739,7 +1514,7 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
739
1514
|
});
|
|
740
1515
|
});
|
|
741
1516
|
|
|
742
|
-
|
|
1517
|
+
/* ============ SDK Init / Reset ============ */
|
|
743
1518
|
document
|
|
744
1519
|
.getElementById('btn-init')
|
|
745
1520
|
.addEventListener('click', () => {
|
|
@@ -760,9 +1535,9 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
760
1535
|
|
|
761
1536
|
try {
|
|
762
1537
|
DRT.init({ shopperGuid, accountId, apiKey });
|
|
763
|
-
setStatus('SDK
|
|
1538
|
+
setStatus('SDK initialized successfully', false);
|
|
764
1539
|
setOutput({
|
|
765
|
-
message: 'SDK initialized
|
|
1540
|
+
message: 'SDK initialized',
|
|
766
1541
|
config: { shopperGuid, accountId, apiKey: '***' },
|
|
767
1542
|
});
|
|
768
1543
|
} catch (err) {
|
|
@@ -771,7 +1546,6 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
771
1546
|
}
|
|
772
1547
|
});
|
|
773
1548
|
|
|
774
|
-
// Check SDK status
|
|
775
1549
|
document
|
|
776
1550
|
.getElementById('btn-check-sdk')
|
|
777
1551
|
.addEventListener('click', () => {
|
|
@@ -789,23 +1563,22 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
789
1563
|
availableServices: {
|
|
790
1564
|
shopper: Object.keys(DRT.shopper),
|
|
791
1565
|
scanner: Object.keys(DRT.scanner),
|
|
792
|
-
portal: Object.keys(DRT.portal),
|
|
1566
|
+
portal: Object.keys(DRT.portal || {}),
|
|
793
1567
|
},
|
|
794
1568
|
});
|
|
795
1569
|
});
|
|
796
1570
|
|
|
797
|
-
// Reset SDK
|
|
798
1571
|
document
|
|
799
1572
|
.getElementById('btn-reset')
|
|
800
1573
|
.addEventListener('click', () => {
|
|
801
1574
|
DRT.reset();
|
|
802
|
-
setStatus('SDK
|
|
1575
|
+
setStatus('SDK has been reset', false);
|
|
803
1576
|
setOutput({
|
|
804
1577
|
message: 'SDK has been reset. Initialize again to use.',
|
|
805
1578
|
});
|
|
806
1579
|
});
|
|
807
1580
|
|
|
808
|
-
|
|
1581
|
+
/* ============ Create Shopper Session ============ */
|
|
809
1582
|
document
|
|
810
1583
|
.getElementById('btn-create-shopper')
|
|
811
1584
|
.addEventListener('click', async () => {
|
|
@@ -815,32 +1588,26 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
815
1588
|
const apiKey = document
|
|
816
1589
|
.getElementById('createApiKey')
|
|
817
1590
|
.value.trim();
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
if (!apiKey) {
|
|
824
|
-
setStatus('Please enter an API Key', true);
|
|
1591
|
+
if (!studioId || !apiKey) {
|
|
1592
|
+
setStatus(
|
|
1593
|
+
'Please enter both Studio ID and API Key',
|
|
1594
|
+
true,
|
|
1595
|
+
);
|
|
825
1596
|
return;
|
|
826
1597
|
}
|
|
827
|
-
|
|
828
1598
|
setStatus('Creating shopper session...', false);
|
|
829
1599
|
try {
|
|
830
1600
|
const result = await DRT.shopper.session.createSession({
|
|
831
1601
|
studioId,
|
|
832
1602
|
});
|
|
833
|
-
setStatus('Shopper created!', false);
|
|
834
1603
|
setOutput(result);
|
|
835
1604
|
|
|
836
|
-
// Populate
|
|
1605
|
+
// Populate credential fields and auto-init
|
|
837
1606
|
document.getElementById('shopperGuid').value =
|
|
838
1607
|
result.shopperGuid;
|
|
839
1608
|
document.getElementById('accountId').value =
|
|
840
1609
|
result.studioId;
|
|
841
1610
|
document.getElementById('apiKey').value = apiKey;
|
|
842
|
-
|
|
843
|
-
// Auto-initialize
|
|
844
1611
|
DRT.init({
|
|
845
1612
|
shopperGuid: result.shopperGuid,
|
|
846
1613
|
accountId: String(result.studioId),
|
|
@@ -859,16 +1626,13 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
859
1626
|
}
|
|
860
1627
|
});
|
|
861
1628
|
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
// Account
|
|
1629
|
+
/* ============ SHOPPER - Account ============ */
|
|
865
1630
|
document
|
|
866
1631
|
.getElementById('btn-theme')
|
|
867
1632
|
.addEventListener('click', () => {
|
|
868
1633
|
if (!requireInit()) return;
|
|
869
1634
|
callApi(() => DRT.shopper.account.getTheme(), 'theme');
|
|
870
1635
|
});
|
|
871
|
-
|
|
872
1636
|
document
|
|
873
1637
|
.getElementById('btn-disposition')
|
|
874
1638
|
.addEventListener('click', () => {
|
|
@@ -878,14 +1642,12 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
878
1642
|
'disposition',
|
|
879
1643
|
);
|
|
880
1644
|
});
|
|
881
|
-
|
|
882
1645
|
document
|
|
883
1646
|
.getElementById('btn-root')
|
|
884
1647
|
.addEventListener('click', () => {
|
|
885
1648
|
if (!requireInit()) return;
|
|
886
1649
|
callApi(() => DRT.shopper.account.getRoot(), 'root config');
|
|
887
1650
|
});
|
|
888
|
-
|
|
889
1651
|
document
|
|
890
1652
|
.getElementById('btn-landing')
|
|
891
1653
|
.addEventListener('click', () => {
|
|
@@ -896,7 +1658,7 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
896
1658
|
);
|
|
897
1659
|
});
|
|
898
1660
|
|
|
899
|
-
|
|
1661
|
+
/* ============ SHOPPER - Events ============ */
|
|
900
1662
|
document
|
|
901
1663
|
.getElementById('btn-events')
|
|
902
1664
|
.addEventListener('click', async () => {
|
|
@@ -904,20 +1666,16 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
904
1666
|
setStatus('Fetching events...', false);
|
|
905
1667
|
try {
|
|
906
1668
|
const result = await DRT.shopper.event.getEvents();
|
|
907
|
-
|
|
908
|
-
// Populate the dropdown
|
|
909
1669
|
const select = document.getElementById('eventSelect');
|
|
910
1670
|
select.innerHTML =
|
|
911
1671
|
'<option value="">-- Select an event --</option>';
|
|
912
1672
|
const events = result.events || result || [];
|
|
913
|
-
events.forEach((
|
|
1673
|
+
events.forEach((ev) => {
|
|
914
1674
|
const opt = document.createElement('option');
|
|
915
|
-
opt.value =
|
|
916
|
-
opt.textContent = `${
|
|
1675
|
+
opt.value = ev.eventId || ev.id;
|
|
1676
|
+
opt.textContent = `${ev.eventId || ev.id}: ${ev.eventName || ev.name || 'Unnamed'}`;
|
|
917
1677
|
select.appendChild(opt);
|
|
918
1678
|
});
|
|
919
|
-
|
|
920
|
-
// Show a compact summary instead of the full response
|
|
921
1679
|
const summary = events.map((e) => ({
|
|
922
1680
|
id: e.eventId || e.id,
|
|
923
1681
|
name: e.eventName || e.name || 'Unnamed',
|
|
@@ -946,24 +1704,17 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
946
1704
|
document.getElementById('eventSelect').value,
|
|
947
1705
|
);
|
|
948
1706
|
if (!id) {
|
|
949
|
-
setStatus(
|
|
950
|
-
'Please select an event from the dropdown',
|
|
951
|
-
true,
|
|
952
|
-
);
|
|
1707
|
+
setStatus('Please select an event', true);
|
|
953
1708
|
return;
|
|
954
1709
|
}
|
|
955
1710
|
setStatus(`Fetching event ${id} details...`, false);
|
|
956
1711
|
try {
|
|
957
1712
|
const result = await DRT.shopper.event.getEventById(id);
|
|
958
|
-
setStatus('Success!', false);
|
|
959
|
-
|
|
960
|
-
// Determine seating type from sections
|
|
961
1713
|
const sections = result.sections || [];
|
|
962
1714
|
const tiers = result.tiers || [];
|
|
963
1715
|
const isGA =
|
|
964
1716
|
result.event && result.event.isGeneralSeating === 1;
|
|
965
1717
|
|
|
966
|
-
// Show the seats section
|
|
967
1718
|
const seatSection =
|
|
968
1719
|
document.getElementById('section-seats');
|
|
969
1720
|
seatSection.classList.remove('hidden-section');
|
|
@@ -978,25 +1729,24 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
978
1729
|
const seatBadge = document.getElementById('seat-badge');
|
|
979
1730
|
|
|
980
1731
|
if (isGA) {
|
|
981
|
-
infoEl.
|
|
982
|
-
infoEl.
|
|
1732
|
+
infoEl.textContent = `General Admission - ${tiers.length} tier(s), ${sections.length} section(s)`;
|
|
1733
|
+
infoEl.className = 'info-banner ga';
|
|
983
1734
|
gaControls.style.display = 'block';
|
|
984
1735
|
baControls.style.display = 'none';
|
|
985
1736
|
seatBadge.textContent = 'GA';
|
|
986
1737
|
seatBadge.className = 'section-badge badge-ga';
|
|
987
|
-
// Populate tier dropdown
|
|
988
1738
|
const tierSel =
|
|
989
1739
|
document.getElementById('tierSelect');
|
|
990
1740
|
tierSel.innerHTML = '';
|
|
991
1741
|
tiers.forEach((t) => {
|
|
992
1742
|
const opt = document.createElement('option');
|
|
993
1743
|
opt.value = t.id;
|
|
994
|
-
opt.textContent = `${t.name}
|
|
1744
|
+
opt.textContent = `${t.name} - $${t.price} (id: ${t.id})`;
|
|
995
1745
|
tierSel.appendChild(opt);
|
|
996
1746
|
});
|
|
997
1747
|
} else {
|
|
998
|
-
infoEl.
|
|
999
|
-
infoEl.
|
|
1748
|
+
infoEl.textContent = `Reserved Seating - ${sections.length} section(s), ${tiers.length} tier(s)`;
|
|
1749
|
+
infoEl.className = 'info-banner reserved';
|
|
1000
1750
|
gaControls.style.display = 'none';
|
|
1001
1751
|
baControls.style.display = 'block';
|
|
1002
1752
|
seatBadge.textContent = 'Reserved';
|
|
@@ -1004,30 +1754,27 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1004
1754
|
'section-badge badge-reserved';
|
|
1005
1755
|
}
|
|
1006
1756
|
|
|
1007
|
-
// Show Update Tier section if there are tiers
|
|
1008
1757
|
const tierSection = document.getElementById(
|
|
1009
1758
|
'section-update-tier',
|
|
1010
1759
|
);
|
|
1011
1760
|
if (tiers.length > 0) {
|
|
1012
1761
|
tierSection.classList.remove('hidden-section');
|
|
1013
|
-
const
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
const updateTierSel =
|
|
1762
|
+
const tb = document.getElementById('tier-badge');
|
|
1763
|
+
tb.textContent = `${tiers.length} tier(s)`;
|
|
1764
|
+
tb.className = 'section-badge badge-count';
|
|
1765
|
+
const sel =
|
|
1018
1766
|
document.getElementById('updateTierSelect');
|
|
1019
|
-
|
|
1767
|
+
sel.innerHTML = '';
|
|
1020
1768
|
tiers.forEach((t) => {
|
|
1021
1769
|
const opt = document.createElement('option');
|
|
1022
1770
|
opt.value = t.id;
|
|
1023
|
-
opt.textContent = `${t.name}
|
|
1024
|
-
|
|
1771
|
+
opt.textContent = `${t.name} - $${t.price} (id: ${t.id})`;
|
|
1772
|
+
sel.appendChild(opt);
|
|
1025
1773
|
});
|
|
1026
1774
|
} else {
|
|
1027
1775
|
tierSection.classList.add('hidden-section');
|
|
1028
1776
|
}
|
|
1029
1777
|
|
|
1030
|
-
// Show Products section
|
|
1031
1778
|
document
|
|
1032
1779
|
.getElementById('section-products')
|
|
1033
1780
|
.classList.remove('hidden-section');
|
|
@@ -1036,8 +1783,8 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1036
1783
|
document.getElementById('product-badge').className =
|
|
1037
1784
|
'section-badge badge-ready';
|
|
1038
1785
|
|
|
1039
|
-
// Show compact summary in output
|
|
1040
1786
|
const sectionRules = result.sectionRules || [];
|
|
1787
|
+
setStatus('Success', false);
|
|
1041
1788
|
setOutput({
|
|
1042
1789
|
event: {
|
|
1043
1790
|
id: result.event?.id,
|
|
@@ -1077,84 +1824,61 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1077
1824
|
}
|
|
1078
1825
|
});
|
|
1079
1826
|
|
|
1080
|
-
|
|
1827
|
+
/* ============ SHOPPER - Seats ============ */
|
|
1081
1828
|
document
|
|
1082
1829
|
.getElementById('btn-hold-ga')
|
|
1083
|
-
.addEventListener('click', () => {
|
|
1830
|
+
.addEventListener('click', async () => {
|
|
1084
1831
|
if (!requireInit()) return;
|
|
1085
1832
|
const eventId = parseInt(
|
|
1086
1833
|
document.getElementById('eventSelect').value,
|
|
1087
1834
|
);
|
|
1088
|
-
if (!eventId) {
|
|
1089
|
-
setStatus('Please select an event first', true);
|
|
1090
|
-
return;
|
|
1091
|
-
}
|
|
1092
1835
|
const tierId = parseInt(
|
|
1093
1836
|
document.getElementById('tierSelect').value,
|
|
1094
1837
|
);
|
|
1095
|
-
if (!tierId) {
|
|
1096
|
-
setStatus(
|
|
1097
|
-
'Please load event details first to populate tiers',
|
|
1098
|
-
true,
|
|
1099
|
-
);
|
|
1100
|
-
return;
|
|
1101
|
-
}
|
|
1102
1838
|
const qty =
|
|
1103
1839
|
parseInt(document.getElementById('gaQty').value) || 1;
|
|
1104
|
-
|
|
1840
|
+
if (!eventId || !tierId) {
|
|
1841
|
+
setStatus('Select event + tier first', true);
|
|
1842
|
+
return;
|
|
1843
|
+
}
|
|
1844
|
+
const result = await callApi(
|
|
1105
1845
|
() =>
|
|
1106
|
-
DRT.shopper.seat.holdGaSeat(
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
allOrNone: true,
|
|
1113
|
-
tierId,
|
|
1114
|
-
qty,
|
|
1115
|
-
},
|
|
1116
|
-
),
|
|
1846
|
+
DRT.shopper.seat.holdGaSeat({
|
|
1847
|
+
eventId,
|
|
1848
|
+
allOrNone: true,
|
|
1849
|
+
tierId,
|
|
1850
|
+
qty,
|
|
1851
|
+
}),
|
|
1117
1852
|
`hold ${qty} GA seat(s) for event ${eventId}`,
|
|
1118
1853
|
);
|
|
1854
|
+
if (result) silentRefreshCart();
|
|
1119
1855
|
});
|
|
1120
1856
|
|
|
1121
1857
|
document
|
|
1122
1858
|
.getElementById('btn-hold-reserved')
|
|
1123
|
-
.addEventListener('click', () => {
|
|
1859
|
+
.addEventListener('click', async () => {
|
|
1124
1860
|
if (!requireInit()) return;
|
|
1125
1861
|
const eventId = parseInt(
|
|
1126
1862
|
document.getElementById('eventSelect').value,
|
|
1127
1863
|
);
|
|
1128
|
-
if (!eventId) {
|
|
1129
|
-
setStatus('Please select an event first', true);
|
|
1130
|
-
return;
|
|
1131
|
-
}
|
|
1132
1864
|
const seatNum = parseInt(
|
|
1133
1865
|
document.getElementById('reservedSeatNum').value,
|
|
1134
1866
|
);
|
|
1135
|
-
if (!seatNum) {
|
|
1136
|
-
setStatus(
|
|
1137
|
-
'Please enter a seat number (check section rules in event details)',
|
|
1138
|
-
true,
|
|
1139
|
-
);
|
|
1867
|
+
if (!eventId || !seatNum) {
|
|
1868
|
+
setStatus('Select event + enter seat number', true);
|
|
1140
1869
|
return;
|
|
1141
1870
|
}
|
|
1142
|
-
callApi(
|
|
1871
|
+
const result = await callApi(
|
|
1143
1872
|
() =>
|
|
1144
|
-
DRT.shopper.seat.holdReservedSeat(
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
eventId,
|
|
1150
|
-
seatNum,
|
|
1151
|
-
},
|
|
1152
|
-
),
|
|
1153
|
-
`hold reserved seat #${seatNum} for event ${eventId}`,
|
|
1873
|
+
DRT.shopper.seat.holdReservedSeat({
|
|
1874
|
+
eventId,
|
|
1875
|
+
seatNum,
|
|
1876
|
+
}),
|
|
1877
|
+
`hold reserved seat #${seatNum}`,
|
|
1154
1878
|
);
|
|
1879
|
+
if (result) silentRefreshCart();
|
|
1155
1880
|
});
|
|
1156
1881
|
|
|
1157
|
-
// Update Tier
|
|
1158
1882
|
document
|
|
1159
1883
|
.getElementById('btn-update-tier')
|
|
1160
1884
|
.addEventListener('click', () => {
|
|
@@ -1162,41 +1886,28 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1162
1886
|
const eventId = parseInt(
|
|
1163
1887
|
document.getElementById('eventSelect').value,
|
|
1164
1888
|
);
|
|
1165
|
-
if (!eventId) {
|
|
1166
|
-
setStatus('Please select an event first', true);
|
|
1167
|
-
return;
|
|
1168
|
-
}
|
|
1169
1889
|
const seatNum = parseInt(
|
|
1170
1890
|
document.getElementById('updateTierSeatNum').value,
|
|
1171
1891
|
);
|
|
1172
|
-
if (!seatNum) {
|
|
1173
|
-
setStatus('Please enter a seat number', true);
|
|
1174
|
-
return;
|
|
1175
|
-
}
|
|
1176
1892
|
const tierId = parseInt(
|
|
1177
1893
|
document.getElementById('updateTierSelect').value,
|
|
1178
1894
|
);
|
|
1179
|
-
if (!tierId) {
|
|
1180
|
-
setStatus('
|
|
1895
|
+
if (!eventId || !seatNum || !tierId) {
|
|
1896
|
+
setStatus('Missing fields for tier update', true);
|
|
1181
1897
|
return;
|
|
1182
1898
|
}
|
|
1183
1899
|
callApi(
|
|
1184
1900
|
() =>
|
|
1185
|
-
DRT.shopper.seat.updateTier(
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
eventId,
|
|
1191
|
-
seatNum,
|
|
1192
|
-
tierId,
|
|
1193
|
-
},
|
|
1194
|
-
),
|
|
1901
|
+
DRT.shopper.seat.updateTier({
|
|
1902
|
+
eventId,
|
|
1903
|
+
seatNum,
|
|
1904
|
+
tierId,
|
|
1905
|
+
}),
|
|
1195
1906
|
`update seat #${seatNum} to tier ${tierId}`,
|
|
1196
|
-
);
|
|
1907
|
+
).then((r) => r && silentRefreshCart());
|
|
1197
1908
|
});
|
|
1198
1909
|
|
|
1199
|
-
|
|
1910
|
+
/* ============ SHOPPER - Products ============ */
|
|
1200
1911
|
document
|
|
1201
1912
|
.getElementById('btn-get-products')
|
|
1202
1913
|
.addEventListener('click', () => {
|
|
@@ -1209,7 +1920,7 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1209
1920
|
|
|
1210
1921
|
document
|
|
1211
1922
|
.getElementById('btn-add-product')
|
|
1212
|
-
.addEventListener('click', () => {
|
|
1923
|
+
.addEventListener('click', async () => {
|
|
1213
1924
|
if (!requireInit()) return;
|
|
1214
1925
|
const id = parseInt(
|
|
1215
1926
|
document.getElementById('productId').value,
|
|
@@ -1226,45 +1937,218 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1226
1937
|
1;
|
|
1227
1938
|
if (!id || !hash) {
|
|
1228
1939
|
setStatus(
|
|
1229
|
-
'
|
|
1940
|
+
'Enter Product ID and Hash (from Get Products)',
|
|
1230
1941
|
true,
|
|
1231
1942
|
);
|
|
1232
1943
|
return;
|
|
1233
1944
|
}
|
|
1234
|
-
callApi(
|
|
1945
|
+
const result = await callApi(
|
|
1235
1946
|
() =>
|
|
1236
|
-
DRT.shopper.product.addProduct(
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
text: '',
|
|
1244
|
-
quantity,
|
|
1245
|
-
variantId,
|
|
1246
|
-
},
|
|
1247
|
-
),
|
|
1947
|
+
DRT.shopper.product.addProduct({
|
|
1948
|
+
id,
|
|
1949
|
+
hash,
|
|
1950
|
+
text: '',
|
|
1951
|
+
quantity,
|
|
1952
|
+
variantId,
|
|
1953
|
+
}),
|
|
1248
1954
|
`add product ${id}`,
|
|
1249
1955
|
);
|
|
1956
|
+
if (result) silentRefreshCart();
|
|
1250
1957
|
});
|
|
1251
1958
|
|
|
1252
|
-
|
|
1959
|
+
/* ============ SHOPPER - Cart (with per-item remove) ============ */
|
|
1960
|
+
async function refreshCart() {
|
|
1961
|
+
if (!DRT.isReady()) return;
|
|
1962
|
+
try {
|
|
1963
|
+
const result = await DRT.shopper.cart.getCart();
|
|
1964
|
+
renderCart(result);
|
|
1965
|
+
setOutput(result);
|
|
1966
|
+
setStatus('Cart refreshed', false);
|
|
1967
|
+
} catch (err) {
|
|
1968
|
+
setStatus(`Error: ${err.message}`, true);
|
|
1969
|
+
setOutput({
|
|
1970
|
+
error: err.message,
|
|
1971
|
+
details: err.body || err.toString(),
|
|
1972
|
+
});
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1976
|
+
// Silently update only the cart widget without touching the output panel.
|
|
1977
|
+
// Used after hold/add/remove so the action result stays visible.
|
|
1978
|
+
async function silentRefreshCart(delayMs = 300) {
|
|
1979
|
+
if (!DRT.isReady()) return;
|
|
1980
|
+
await new Promise((r) => setTimeout(r, delayMs));
|
|
1981
|
+
try {
|
|
1982
|
+
const result = await DRT.shopper.cart.getCart();
|
|
1983
|
+
renderCart(result);
|
|
1984
|
+
} catch (_) {
|
|
1985
|
+
// silent — don't overwrite current output on background refresh failure
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1989
|
+
function renderCart(cartResponse) {
|
|
1990
|
+
const container = document.getElementById('cart-display');
|
|
1991
|
+
const cart = cartResponse?.cart || cartResponse || {};
|
|
1992
|
+
const seats = cart.seats || [];
|
|
1993
|
+
const products = cart.products || [];
|
|
1994
|
+
const donations = cart.donations || [];
|
|
1995
|
+
container.innerHTML = '';
|
|
1996
|
+
|
|
1997
|
+
const totalItems =
|
|
1998
|
+
seats.length + products.length + donations.length;
|
|
1999
|
+
const cartBadge = document.getElementById('cart-badge');
|
|
2000
|
+
if (totalItems === 0) {
|
|
2001
|
+
cartBadge.textContent = 'empty';
|
|
2002
|
+
cartBadge.className = 'section-badge';
|
|
2003
|
+
container.innerHTML =
|
|
2004
|
+
'<div class="empty-cart">Cart is empty</div>';
|
|
2005
|
+
return;
|
|
2006
|
+
}
|
|
2007
|
+
cartBadge.textContent = `${totalItems} item${totalItems !== 1 ? 's' : ''}`;
|
|
2008
|
+
cartBadge.className = 'section-badge badge-count';
|
|
2009
|
+
|
|
2010
|
+
let total = 0;
|
|
2011
|
+
|
|
2012
|
+
seats.forEach((s, idx) => {
|
|
2013
|
+
total += s.displayPrice || s.price || 0;
|
|
2014
|
+
const row = document.createElement('div');
|
|
2015
|
+
row.className = 'cart-item';
|
|
2016
|
+
const seatLabel = s.isGeneralSeating
|
|
2017
|
+
? `GA - ${s.tierName || 'General'}`
|
|
2018
|
+
: `${s.section || ''} ${s.row ? 'Row ' + s.row : ''} Seat ${s.seat || s.num}`;
|
|
2019
|
+
row.innerHTML = `
|
|
2020
|
+
<div class="cart-item-icon seat">${s.isGeneralSeating ? 'GA' : 'S'}</div>
|
|
2021
|
+
<div class="cart-item-body">
|
|
2022
|
+
<div class="cart-item-title">${escapeHtml(s.shortName || 'Event')}</div>
|
|
2023
|
+
<div class="cart-item-subtitle">${escapeHtml(seatLabel)}${s.tierName ? ' - ' + escapeHtml(s.tierName) : ''}</div>
|
|
2024
|
+
</div>
|
|
2025
|
+
<div class="cart-item-price">$${(s.displayPrice ?? s.price ?? 0).toFixed(2)}</div>
|
|
2026
|
+
<button class="small danger" data-remove-seat="${idx}">Remove</button>
|
|
2027
|
+
`;
|
|
2028
|
+
row.querySelector('[data-remove-seat]').addEventListener(
|
|
2029
|
+
'click',
|
|
2030
|
+
() => removeSeatFromCart(s),
|
|
2031
|
+
);
|
|
2032
|
+
container.appendChild(row);
|
|
2033
|
+
});
|
|
2034
|
+
|
|
2035
|
+
products.forEach((p) => {
|
|
2036
|
+
total += (p.price || 0) * (p.qty || 1);
|
|
2037
|
+
const row = document.createElement('div');
|
|
2038
|
+
row.className = 'cart-item';
|
|
2039
|
+
row.innerHTML = `
|
|
2040
|
+
<div class="cart-item-icon product">P</div>
|
|
2041
|
+
<div class="cart-item-body">
|
|
2042
|
+
<div class="cart-item-title">${escapeHtml(p.name || 'Product')}${p.variantName ? ' - ' + escapeHtml(p.variantName) : ''}</div>
|
|
2043
|
+
<div class="cart-item-subtitle">Qty: ${p.qty} - id: ${p.productId}</div>
|
|
2044
|
+
</div>
|
|
2045
|
+
<div class="cart-item-price">$${((p.price || 0) * (p.qty || 1)).toFixed(2)}</div>
|
|
2046
|
+
<button class="small danger" data-remove-product>Remove</button>
|
|
2047
|
+
`;
|
|
2048
|
+
row.querySelector('[data-remove-product]').addEventListener(
|
|
2049
|
+
'click',
|
|
2050
|
+
() => removeProductFromCart(p),
|
|
2051
|
+
);
|
|
2052
|
+
container.appendChild(row);
|
|
2053
|
+
});
|
|
2054
|
+
|
|
2055
|
+
donations.forEach((d) => {
|
|
2056
|
+
total += d.amount || 0;
|
|
2057
|
+
const row = document.createElement('div');
|
|
2058
|
+
row.className = 'cart-item';
|
|
2059
|
+
row.innerHTML = `
|
|
2060
|
+
<div class="cart-item-icon donation">D</div>
|
|
2061
|
+
<div class="cart-item-body">
|
|
2062
|
+
<div class="cart-item-title">${escapeHtml(d.name || 'Donation')}</div>
|
|
2063
|
+
<div class="cart-item-subtitle">Fund id: ${d.id}</div>
|
|
2064
|
+
</div>
|
|
2065
|
+
<div class="cart-item-price">$${(d.amount || 0).toFixed(2)}</div>
|
|
2066
|
+
`;
|
|
2067
|
+
container.appendChild(row);
|
|
2068
|
+
});
|
|
2069
|
+
|
|
2070
|
+
const sum = document.createElement('div');
|
|
2071
|
+
sum.className = 'cart-summary';
|
|
2072
|
+
sum.innerHTML = `<span>Subtotal</span><span>$${total.toFixed(2)}</span>`;
|
|
2073
|
+
container.appendChild(sum);
|
|
2074
|
+
}
|
|
2075
|
+
|
|
2076
|
+
function escapeHtml(s) {
|
|
2077
|
+
return String(s ?? '').replace(
|
|
2078
|
+
/[&<>"']/g,
|
|
2079
|
+
(c) =>
|
|
2080
|
+
({
|
|
2081
|
+
'&': '&',
|
|
2082
|
+
'<': '<',
|
|
2083
|
+
'>': '>',
|
|
2084
|
+
'"': '"',
|
|
2085
|
+
"'": ''',
|
|
2086
|
+
})[c],
|
|
2087
|
+
);
|
|
2088
|
+
}
|
|
2089
|
+
|
|
2090
|
+
async function removeSeatFromCart(seat) {
|
|
2091
|
+
if (!requireInit()) return;
|
|
2092
|
+
const eventId = seat.showId;
|
|
2093
|
+
if (seat.isGeneralSeating) {
|
|
2094
|
+
const qty = 1;
|
|
2095
|
+
const tierId = seat.tierId;
|
|
2096
|
+
const ok = await callApi(
|
|
2097
|
+
() =>
|
|
2098
|
+
DRT.shopper.seat.releaseGaSeat({
|
|
2099
|
+
eventId,
|
|
2100
|
+
tierId,
|
|
2101
|
+
qty,
|
|
2102
|
+
}),
|
|
2103
|
+
`release GA seat (tier ${tierId})`,
|
|
2104
|
+
);
|
|
2105
|
+
if (ok !== null) silentRefreshCart();
|
|
2106
|
+
} else {
|
|
2107
|
+
const seatNum = seat.num;
|
|
2108
|
+
const ok = await callApi(
|
|
2109
|
+
() =>
|
|
2110
|
+
DRT.shopper.seat.releaseReservedSeat({
|
|
2111
|
+
eventId,
|
|
2112
|
+
seatNum,
|
|
2113
|
+
}),
|
|
2114
|
+
`release reserved seat #${seatNum}`,
|
|
2115
|
+
);
|
|
2116
|
+
if (ok !== null) silentRefreshCart();
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
|
|
2120
|
+
async function removeProductFromCart(product) {
|
|
2121
|
+
if (!requireInit()) return;
|
|
2122
|
+
const ok = await callApi(
|
|
2123
|
+
() =>
|
|
2124
|
+
DRT.shopper.product.deleteProduct({
|
|
2125
|
+
id: product.productId,
|
|
2126
|
+
hash: product.guid || '',
|
|
2127
|
+
text: product.text || '',
|
|
2128
|
+
variantId: product.variantId || 0,
|
|
2129
|
+
}),
|
|
2130
|
+
`remove product ${product.productId}`,
|
|
2131
|
+
);
|
|
2132
|
+
if (ok !== null) silentRefreshCart();
|
|
2133
|
+
}
|
|
2134
|
+
|
|
1253
2135
|
document
|
|
1254
2136
|
.getElementById('btn-cart')
|
|
1255
|
-
.addEventListener('click',
|
|
1256
|
-
if (!requireInit()) return;
|
|
1257
|
-
callApi(() => DRT.shopper.cart.getCart(), 'cart');
|
|
1258
|
-
});
|
|
2137
|
+
.addEventListener('click', refreshCart);
|
|
1259
2138
|
|
|
1260
2139
|
document
|
|
1261
2140
|
.getElementById('btn-delete-cart')
|
|
1262
|
-
.addEventListener('click', () => {
|
|
2141
|
+
.addEventListener('click', async () => {
|
|
1263
2142
|
if (!requireInit()) return;
|
|
1264
|
-
|
|
2143
|
+
if (!confirm('Delete the entire cart?')) return;
|
|
2144
|
+
await callApi(
|
|
2145
|
+
() => DRT.shopper.cart.deleteCart(),
|
|
2146
|
+
'delete cart',
|
|
2147
|
+
);
|
|
2148
|
+
refreshCart();
|
|
1265
2149
|
});
|
|
1266
2150
|
|
|
1267
|
-
|
|
2151
|
+
/* ============ SHOPPER - Orders / Codes / Gift Cards ============ */
|
|
1268
2152
|
document
|
|
1269
2153
|
.getElementById('btn-receipt')
|
|
1270
2154
|
.addEventListener('click', () => {
|
|
@@ -1273,7 +2157,7 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1273
2157
|
.getElementById('orderGuid')
|
|
1274
2158
|
.value.trim();
|
|
1275
2159
|
if (!guid) {
|
|
1276
|
-
setStatus('
|
|
2160
|
+
setStatus('Enter an Order GUID', true);
|
|
1277
2161
|
return;
|
|
1278
2162
|
}
|
|
1279
2163
|
callApi(
|
|
@@ -1282,7 +2166,6 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1282
2166
|
);
|
|
1283
2167
|
});
|
|
1284
2168
|
|
|
1285
|
-
// Codes
|
|
1286
2169
|
document
|
|
1287
2170
|
.getElementById('btn-validate-code')
|
|
1288
2171
|
.addEventListener('click', () => {
|
|
@@ -1291,7 +2174,7 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1291
2174
|
.getElementById('promoCode')
|
|
1292
2175
|
.value.trim();
|
|
1293
2176
|
if (!code) {
|
|
1294
|
-
setStatus('
|
|
2177
|
+
setStatus('Enter a code', true);
|
|
1295
2178
|
return;
|
|
1296
2179
|
}
|
|
1297
2180
|
callApi(
|
|
@@ -1300,7 +2183,6 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1300
2183
|
);
|
|
1301
2184
|
});
|
|
1302
2185
|
|
|
1303
|
-
// Gift Cards
|
|
1304
2186
|
document
|
|
1305
2187
|
.getElementById('btn-gift-balance')
|
|
1306
2188
|
.addEventListener('click', () => {
|
|
@@ -1309,7 +2191,7 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1309
2191
|
.getElementById('giftCardNumber')
|
|
1310
2192
|
.value.trim();
|
|
1311
2193
|
if (!num) {
|
|
1312
|
-
setStatus('
|
|
2194
|
+
setStatus('Enter a gift card number', true);
|
|
1313
2195
|
return;
|
|
1314
2196
|
}
|
|
1315
2197
|
callApi(
|
|
@@ -1318,8 +2200,7 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1318
2200
|
);
|
|
1319
2201
|
});
|
|
1320
2202
|
|
|
1321
|
-
|
|
1322
|
-
|
|
2203
|
+
/* ============ SCANNER API ============ */
|
|
1323
2204
|
document
|
|
1324
2205
|
.getElementById('btn-strings')
|
|
1325
2206
|
.addEventListener('click', () => {
|
|
@@ -1342,7 +2223,7 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1342
2223
|
.getElementById('scannerUser')
|
|
1343
2224
|
.value.trim();
|
|
1344
2225
|
if (!showCode) {
|
|
1345
|
-
setStatus('
|
|
2226
|
+
setStatus('Enter a Show Code', true);
|
|
1346
2227
|
return;
|
|
1347
2228
|
}
|
|
1348
2229
|
callApi(
|
|
@@ -1353,7 +2234,7 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1353
2234
|
user,
|
|
1354
2235
|
'en',
|
|
1355
2236
|
),
|
|
1356
|
-
|
|
2237
|
+
'scanner database',
|
|
1357
2238
|
);
|
|
1358
2239
|
});
|
|
1359
2240
|
|
|
@@ -1364,12 +2245,12 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1364
2245
|
.getElementById('scannerShowCode')
|
|
1365
2246
|
.value.trim();
|
|
1366
2247
|
if (!showCode) {
|
|
1367
|
-
setStatus('
|
|
2248
|
+
setStatus('Enter a Show Code', true);
|
|
1368
2249
|
return;
|
|
1369
2250
|
}
|
|
1370
2251
|
callApi(
|
|
1371
2252
|
() => DRT.scanner.database.query(showCode, 'sections'),
|
|
1372
|
-
|
|
2253
|
+
'sections query',
|
|
1373
2254
|
);
|
|
1374
2255
|
});
|
|
1375
2256
|
|
|
@@ -1383,7 +2264,7 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1383
2264
|
.getElementById('scannerPhone')
|
|
1384
2265
|
.value.trim();
|
|
1385
2266
|
if (!showCode || !phone) {
|
|
1386
|
-
setStatus('
|
|
2267
|
+
setStatus('Enter Show Code and Phone', true);
|
|
1387
2268
|
return;
|
|
1388
2269
|
}
|
|
1389
2270
|
callApi(
|
|
@@ -1392,7 +2273,7 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1392
2273
|
showCode,
|
|
1393
2274
|
phone,
|
|
1394
2275
|
),
|
|
1395
|
-
|
|
2276
|
+
'orders by phone',
|
|
1396
2277
|
);
|
|
1397
2278
|
});
|
|
1398
2279
|
|
|
@@ -1406,7 +2287,7 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1406
2287
|
.getElementById('scannerName')
|
|
1407
2288
|
.value.trim();
|
|
1408
2289
|
if (!showCode || !name) {
|
|
1409
|
-
setStatus('
|
|
2290
|
+
setStatus('Enter Show Code and Name', true);
|
|
1410
2291
|
return;
|
|
1411
2292
|
}
|
|
1412
2293
|
callApi(
|
|
@@ -1415,11 +2296,10 @@ Initialize the SDK, then click a button to test...</pre
|
|
|
1415
2296
|
showCode,
|
|
1416
2297
|
name,
|
|
1417
2298
|
),
|
|
1418
|
-
|
|
2299
|
+
'orders by name',
|
|
1419
2300
|
);
|
|
1420
2301
|
});
|
|
1421
2302
|
|
|
1422
|
-
// Auto-check on load
|
|
1423
2303
|
console.log('DRT SDK available at window.DRT for console testing');
|
|
1424
2304
|
</script>
|
|
1425
2305
|
</body>
|