notify-me-wl 1.4.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -9
- package/build/notify-me-wl.js +667 -0
- package/build/notify-me-wl.min.js +1 -0
- package/package.json +17 -3
- package/CLAUDE.md +0 -199
- package/index.html +0 -21
- package/index.js +0 -553
package/index.js
DELETED
|
@@ -1,553 +0,0 @@
|
|
|
1
|
-
// Access token for the API
|
|
2
|
-
const ACCESS_TOKEN =
|
|
3
|
-
'Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJRWlJkS3JabXJmMEk3WkhXRUtqNWRLTEhQanFubWJFeV9iNmpSbHdya1drIn0.eyJleHAiOjE3MjMwMzI3NzIsImlhdCI6MTcyMzAyOTE3MiwianRpIjoiNDJiNGYwM2QtMDNiNS00NmZlLTk5YmItZDQ2NTdhNjk5NGNiIiwiaXNzIjoiaHR0cHM6Ly9hdXRoLmF1LWF3cy50aGV3aXNobGlzdC5pby9hdXRoL3JlYWxtcy90d2NNYWluIiwiYXVkIjoiYWNjb3VudCIsInN1YiI6IjI2YTIyNTAyLWRhNzQtNDhkMC1iZWFiLTgzY2E0YTlmMDdlOSIsInR5cCI6IkJlYXJlciIsImF6cCI6InR3Yy1wb3MtY2xpZW50Iiwic2Vzc2lvbl9zdGF0ZSI6IjQxYWQwMDc4LWVmYTItNGVjMi1hM2I2LTIzYjBkNDM3YjEzOCIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cHM6Ly9sb2NhbGhvc3QiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbInR3Yy1wb3MtdXNlciIsIm9mZmxpbmVfYWNjZXNzIiwidHdjLXN0b3JlLW93bmVyIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6InRlbmFudGlkIHN0b3JlIHByb2ZpbGUgZW1haWwiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInRlbmFudGlkIjoidmlrdG9yaWEtd29vZHMiLCJuYW1lIjoiTWF0dCBIYW1wc2hpcmUiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJtYXR0QHRoZXdpc2hsaXN0LmlvIiwic3RvcmUiOiIyMDUiLCJnaXZlbl9uYW1lIjoiTWF0dCIsImZhbWlseV9uYW1lIjoiSGFtcHNoaXJlIiwiZW1haWwiOiJtYXR0QHRoZXdpc2hsaXN0LmlvIn0.iZkMgwH74njjXUWvImkJomHYr91Lr8ZGrZGwslEGcV3vbNuoNc5CocvNWW476o-LoSh-LsKf-MLiYN1XvOuPDF3fGoGCEbMh6_M0RJcrhVWogkj81fx4ukvDPCFIjgoDCV9WIuehV9dsSWa7E0irZeE6MUVhLwRIaTzKtxgzUUKrAqBtI_HKpyo8TUGQBiYlrc85QFUyuoKbKg-QaRn_SObRLDB8ooIBJvIlgklXQt1ZYBM2HUOc5L1bAQwfzcrWEvl6eYiQHXCSPqS0rPGoaGC6v5ydBo9VMxtVHGladDHLrO3Gt2BnIGMBoYrKTAmt7j0KABwPyB3CmAIwj_pOBQ'; // Replace `ACCESS_TOKEN` with your actual access token to authenticate API requests.
|
|
4
|
-
const TENANT_ID = 'victoria-woods'; // Replace `TENANT_ID` with your actual tenant ID.
|
|
5
|
-
|
|
6
|
-
// Session-cached access token obtained from the Shopify App Proxy (proxy auth mode).
|
|
7
|
-
let cachedProxyToken = null;
|
|
8
|
-
|
|
9
|
-
// Fetch a tenant-scoped access token from the Shopify App Proxy.
|
|
10
|
-
// The path is relative/same-origin, so Shopify's App Proxy layer appends and
|
|
11
|
-
// signs `shop`, `logged_in_customer_id`, `timestamp`, and `signature`.
|
|
12
|
-
// Returns the access token string, or null on failure (e.g. customer not logged in).
|
|
13
|
-
async function getProxyAccessToken() {
|
|
14
|
-
if (cachedProxyToken) return cachedProxyToken;
|
|
15
|
-
try {
|
|
16
|
-
const response = await fetch('/apps/twc-sdk/auth/token', {
|
|
17
|
-
method: 'GET',
|
|
18
|
-
headers: { Accept: 'application/json' },
|
|
19
|
-
});
|
|
20
|
-
const body = await response.json().catch(() => null);
|
|
21
|
-
if (
|
|
22
|
-
response.ok &&
|
|
23
|
-
body &&
|
|
24
|
-
body.success &&
|
|
25
|
-
body.data &&
|
|
26
|
-
body.data.access_token
|
|
27
|
-
) {
|
|
28
|
-
cachedProxyToken = body.data.access_token;
|
|
29
|
-
return cachedProxyToken;
|
|
30
|
-
}
|
|
31
|
-
return null;
|
|
32
|
-
} catch (error) {
|
|
33
|
-
console.error('Error fetching proxy access token:', error);
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const COUNTRY_CODES = [
|
|
39
|
-
{ code: 'AF', name: 'Afghanistan' }, { code: 'AX', name: 'Åland Islands' },
|
|
40
|
-
{ code: 'AL', name: 'Albania' }, { code: 'DZ', name: 'Algeria' },
|
|
41
|
-
{ code: 'AS', name: 'American Samoa' }, { code: 'AD', name: 'Andorra' },
|
|
42
|
-
{ code: 'AO', name: 'Angola' }, { code: 'AI', name: 'Anguilla' },
|
|
43
|
-
{ code: 'AG', name: 'Antigua and Barbuda' }, { code: 'AR', name: 'Argentina' },
|
|
44
|
-
{ code: 'AM', name: 'Armenia' }, { code: 'AW', name: 'Aruba' },
|
|
45
|
-
{ code: 'AU', name: 'Australia' }, { code: 'AT', name: 'Austria' },
|
|
46
|
-
{ code: 'AZ', name: 'Azerbaijan' }, { code: 'BS', name: 'Bahamas' },
|
|
47
|
-
{ code: 'BH', name: 'Bahrain' }, { code: 'BD', name: 'Bangladesh' },
|
|
48
|
-
{ code: 'BB', name: 'Barbados' }, { code: 'BY', name: 'Belarus' },
|
|
49
|
-
{ code: 'BE', name: 'Belgium' }, { code: 'BZ', name: 'Belize' },
|
|
50
|
-
{ code: 'BJ', name: 'Benin' }, { code: 'BM', name: 'Bermuda' },
|
|
51
|
-
{ code: 'BT', name: 'Bhutan' }, { code: 'BO', name: 'Bolivia' },
|
|
52
|
-
{ code: 'BA', name: 'Bosnia and Herzegovina' }, { code: 'BW', name: 'Botswana' },
|
|
53
|
-
{ code: 'BR', name: 'Brazil' }, { code: 'BN', name: 'Brunei' },
|
|
54
|
-
{ code: 'BG', name: 'Bulgaria' }, { code: 'BF', name: 'Burkina Faso' },
|
|
55
|
-
{ code: 'BI', name: 'Burundi' }, { code: 'CV', name: 'Cabo Verde' },
|
|
56
|
-
{ code: 'KH', name: 'Cambodia' }, { code: 'CM', name: 'Cameroon' },
|
|
57
|
-
{ code: 'CA', name: 'Canada' }, { code: 'KY', name: 'Cayman Islands' },
|
|
58
|
-
{ code: 'CF', name: 'Central African Republic' }, { code: 'TD', name: 'Chad' },
|
|
59
|
-
{ code: 'CL', name: 'Chile' }, { code: 'CN', name: 'China' },
|
|
60
|
-
{ code: 'CO', name: 'Colombia' }, { code: 'KM', name: 'Comoros' },
|
|
61
|
-
{ code: 'CG', name: 'Congo' }, { code: 'CD', name: 'Congo, DR' },
|
|
62
|
-
{ code: 'CK', name: 'Cook Islands' }, { code: 'CR', name: 'Costa Rica' },
|
|
63
|
-
{ code: 'HR', name: 'Croatia' }, { code: 'CU', name: 'Cuba' },
|
|
64
|
-
{ code: 'CW', name: 'Curaçao' }, { code: 'CY', name: 'Cyprus' },
|
|
65
|
-
{ code: 'CZ', name: 'Czech Republic' }, { code: 'DK', name: 'Denmark' },
|
|
66
|
-
{ code: 'DJ', name: 'Djibouti' }, { code: 'DM', name: 'Dominica' },
|
|
67
|
-
{ code: 'DO', name: 'Dominican Republic' }, { code: 'EC', name: 'Ecuador' },
|
|
68
|
-
{ code: 'EG', name: 'Egypt' }, { code: 'SV', name: 'El Salvador' },
|
|
69
|
-
{ code: 'GQ', name: 'Equatorial Guinea' }, { code: 'ER', name: 'Eritrea' },
|
|
70
|
-
{ code: 'EE', name: 'Estonia' }, { code: 'SZ', name: 'Eswatini' },
|
|
71
|
-
{ code: 'ET', name: 'Ethiopia' }, { code: 'FO', name: 'Faroe Islands' },
|
|
72
|
-
{ code: 'FJ', name: 'Fiji' }, { code: 'FI', name: 'Finland' },
|
|
73
|
-
{ code: 'FR', name: 'France' }, { code: 'GF', name: 'French Guiana' },
|
|
74
|
-
{ code: 'PF', name: 'French Polynesia' }, { code: 'GA', name: 'Gabon' },
|
|
75
|
-
{ code: 'GM', name: 'Gambia' }, { code: 'GE', name: 'Georgia' },
|
|
76
|
-
{ code: 'DE', name: 'Germany' }, { code: 'GH', name: 'Ghana' },
|
|
77
|
-
{ code: 'GI', name: 'Gibraltar' }, { code: 'GR', name: 'Greece' },
|
|
78
|
-
{ code: 'GL', name: 'Greenland' }, { code: 'GD', name: 'Grenada' },
|
|
79
|
-
{ code: 'GP', name: 'Guadeloupe' }, { code: 'GU', name: 'Guam' },
|
|
80
|
-
{ code: 'GT', name: 'Guatemala' }, { code: 'GN', name: 'Guinea' },
|
|
81
|
-
{ code: 'GW', name: 'Guinea-Bissau' }, { code: 'GY', name: 'Guyana' },
|
|
82
|
-
{ code: 'HT', name: 'Haiti' }, { code: 'HN', name: 'Honduras' },
|
|
83
|
-
{ code: 'HK', name: 'Hong Kong' }, { code: 'HU', name: 'Hungary' },
|
|
84
|
-
{ code: 'IS', name: 'Iceland' }, { code: 'IN', name: 'India' },
|
|
85
|
-
{ code: 'ID', name: 'Indonesia' }, { code: 'IR', name: 'Iran' },
|
|
86
|
-
{ code: 'IQ', name: 'Iraq' }, { code: 'IE', name: 'Ireland' },
|
|
87
|
-
{ code: 'IM', name: 'Isle of Man' }, { code: 'IL', name: 'Israel' },
|
|
88
|
-
{ code: 'IT', name: 'Italy' }, { code: 'JM', name: 'Jamaica' },
|
|
89
|
-
{ code: 'JP', name: 'Japan' }, { code: 'JE', name: 'Jersey' },
|
|
90
|
-
{ code: 'JO', name: 'Jordan' }, { code: 'KZ', name: 'Kazakhstan' },
|
|
91
|
-
{ code: 'KE', name: 'Kenya' }, { code: 'KI', name: 'Kiribati' },
|
|
92
|
-
{ code: 'KR', name: 'Korea, South' }, { code: 'XK', name: 'Kosovo' },
|
|
93
|
-
{ code: 'KW', name: 'Kuwait' }, { code: 'KG', name: 'Kyrgyzstan' },
|
|
94
|
-
{ code: 'LA', name: 'Laos' }, { code: 'LV', name: 'Latvia' },
|
|
95
|
-
{ code: 'LB', name: 'Lebanon' }, { code: 'LS', name: 'Lesotho' },
|
|
96
|
-
{ code: 'LR', name: 'Liberia' }, { code: 'LY', name: 'Libya' },
|
|
97
|
-
{ code: 'LI', name: 'Liechtenstein' }, { code: 'LT', name: 'Lithuania' },
|
|
98
|
-
{ code: 'LU', name: 'Luxembourg' }, { code: 'MO', name: 'Macao' },
|
|
99
|
-
{ code: 'MG', name: 'Madagascar' }, { code: 'MW', name: 'Malawi' },
|
|
100
|
-
{ code: 'MY', name: 'Malaysia' }, { code: 'MV', name: 'Maldives' },
|
|
101
|
-
{ code: 'ML', name: 'Mali' }, { code: 'MT', name: 'Malta' },
|
|
102
|
-
{ code: 'MH', name: 'Marshall Islands' }, { code: 'MQ', name: 'Martinique' },
|
|
103
|
-
{ code: 'MR', name: 'Mauritania' }, { code: 'MU', name: 'Mauritius' },
|
|
104
|
-
{ code: 'MX', name: 'Mexico' }, { code: 'FM', name: 'Micronesia' },
|
|
105
|
-
{ code: 'MD', name: 'Moldova' }, { code: 'MC', name: 'Monaco' },
|
|
106
|
-
{ code: 'MN', name: 'Mongolia' }, { code: 'ME', name: 'Montenegro' },
|
|
107
|
-
{ code: 'MS', name: 'Montserrat' }, { code: 'MA', name: 'Morocco' },
|
|
108
|
-
{ code: 'MZ', name: 'Mozambique' }, { code: 'MM', name: 'Myanmar' },
|
|
109
|
-
{ code: 'NA', name: 'Namibia' }, { code: 'NR', name: 'Nauru' },
|
|
110
|
-
{ code: 'NP', name: 'Nepal' }, { code: 'NL', name: 'Netherlands' },
|
|
111
|
-
{ code: 'NC', name: 'New Caledonia' }, { code: 'NZ', name: 'New Zealand' },
|
|
112
|
-
{ code: 'NI', name: 'Nicaragua' }, { code: 'NE', name: 'Niger' },
|
|
113
|
-
{ code: 'NG', name: 'Nigeria' }, { code: 'NU', name: 'Niue' },
|
|
114
|
-
{ code: 'MK', name: 'North Macedonia' }, { code: 'NO', name: 'Norway' },
|
|
115
|
-
{ code: 'OM', name: 'Oman' }, { code: 'PK', name: 'Pakistan' },
|
|
116
|
-
{ code: 'PW', name: 'Palau' }, { code: 'PS', name: 'Palestine' },
|
|
117
|
-
{ code: 'PA', name: 'Panama' }, { code: 'PG', name: 'Papua New Guinea' },
|
|
118
|
-
{ code: 'PY', name: 'Paraguay' }, { code: 'PE', name: 'Peru' },
|
|
119
|
-
{ code: 'PH', name: 'Philippines' }, { code: 'PL', name: 'Poland' },
|
|
120
|
-
{ code: 'PT', name: 'Portugal' }, { code: 'PR', name: 'Puerto Rico' },
|
|
121
|
-
{ code: 'QA', name: 'Qatar' }, { code: 'RE', name: 'Réunion' },
|
|
122
|
-
{ code: 'RO', name: 'Romania' },
|
|
123
|
-
{ code: 'RW', name: 'Rwanda' }, { code: 'KN', name: 'Saint Kitts and Nevis' },
|
|
124
|
-
{ code: 'LC', name: 'Saint Lucia' }, { code: 'VC', name: 'Saint Vincent and the Grenadines' },
|
|
125
|
-
{ code: 'WS', name: 'Samoa' }, { code: 'SM', name: 'San Marino' },
|
|
126
|
-
{ code: 'SA', name: 'Saudi Arabia' }, { code: 'SN', name: 'Senegal' },
|
|
127
|
-
{ code: 'RS', name: 'Serbia' }, { code: 'SC', name: 'Seychelles' },
|
|
128
|
-
{ code: 'SL', name: 'Sierra Leone' }, { code: 'SG', name: 'Singapore' },
|
|
129
|
-
{ code: 'SK', name: 'Slovakia' }, { code: 'SI', name: 'Slovenia' },
|
|
130
|
-
{ code: 'SB', name: 'Solomon Islands' }, { code: 'SO', name: 'Somalia' },
|
|
131
|
-
{ code: 'ZA', name: 'South Africa' }, { code: 'SS', name: 'South Sudan' },
|
|
132
|
-
{ code: 'ES', name: 'Spain' }, { code: 'LK', name: 'Sri Lanka' },
|
|
133
|
-
{ code: 'SD', name: 'Sudan' }, { code: 'SR', name: 'Suriname' },
|
|
134
|
-
{ code: 'SE', name: 'Sweden' }, { code: 'CH', name: 'Switzerland' },
|
|
135
|
-
{ code: 'SY', name: 'Syria' }, { code: 'TW', name: 'Taiwan' },
|
|
136
|
-
{ code: 'TJ', name: 'Tajikistan' }, { code: 'TZ', name: 'Tanzania' },
|
|
137
|
-
{ code: 'TH', name: 'Thailand' }, { code: 'TL', name: 'Timor-Leste' },
|
|
138
|
-
{ code: 'TG', name: 'Togo' }, { code: 'TO', name: 'Tonga' },
|
|
139
|
-
{ code: 'TT', name: 'Trinidad and Tobago' }, { code: 'TN', name: 'Tunisia' },
|
|
140
|
-
{ code: 'TR', name: 'Turkey' }, { code: 'TM', name: 'Turkmenistan' },
|
|
141
|
-
{ code: 'TC', name: 'Turks and Caicos Islands' }, { code: 'TV', name: 'Tuvalu' },
|
|
142
|
-
{ code: 'UG', name: 'Uganda' }, { code: 'UA', name: 'Ukraine' },
|
|
143
|
-
{ code: 'AE', name: 'United Arab Emirates' }, { code: 'GB', name: 'United Kingdom' },
|
|
144
|
-
{ code: 'US', name: 'United States' }, { code: 'UY', name: 'Uruguay' },
|
|
145
|
-
{ code: 'UZ', name: 'Uzbekistan' }, { code: 'VU', name: 'Vanuatu' },
|
|
146
|
-
{ code: 'VE', name: 'Venezuela' }, { code: 'VN', name: 'Vietnam' },
|
|
147
|
-
{ code: 'VG', name: 'Virgin Islands, British' }, { code: 'VI', name: 'Virgin Islands, U.S.' },
|
|
148
|
-
{ code: 'YE', name: 'Yemen' }, { code: 'ZM', name: 'Zambia' },
|
|
149
|
-
{ code: 'ZW', name: 'Zimbabwe' },
|
|
150
|
-
];
|
|
151
|
-
|
|
152
|
-
// Detect country/province/market context using priority fallback chain
|
|
153
|
-
function detectCountryContext() {
|
|
154
|
-
const ctx = { countryCode: null, provinceCode: null, marketId: null };
|
|
155
|
-
|
|
156
|
-
// Priority 1: Shopify localization/country context
|
|
157
|
-
const shopify = window.Shopify;
|
|
158
|
-
if (shopify) {
|
|
159
|
-
if (typeof shopify.country === 'string') ctx.countryCode = shopify.country;
|
|
160
|
-
const mkt = shopify.markets?.currentMarket;
|
|
161
|
-
if (mkt) {
|
|
162
|
-
if (mkt.countryCode) ctx.countryCode = mkt.countryCode;
|
|
163
|
-
if (mkt.id != null) ctx.marketId = String(mkt.id);
|
|
164
|
-
}
|
|
165
|
-
if (!ctx.countryCode && typeof shopify.locale === 'string') {
|
|
166
|
-
const parts = shopify.locale.split('-');
|
|
167
|
-
if (parts.length > 1) ctx.countryCode = parts[parts.length - 1].toUpperCase();
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Priority 2: Existing customer shipping country
|
|
172
|
-
if (!ctx.countryCode || !ctx.provinceCode) {
|
|
173
|
-
const addr = window.customer?.default_address;
|
|
174
|
-
if (addr) {
|
|
175
|
-
if (!ctx.countryCode && addr.country_code) ctx.countryCode = addr.country_code;
|
|
176
|
-
if (!ctx.provinceCode && addr.province_code) ctx.provinceCode = addr.province_code;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Priority 3: Browser locale fallback
|
|
181
|
-
if (!ctx.countryCode) {
|
|
182
|
-
const parts = (navigator.language || '').split('-');
|
|
183
|
-
if (parts.length > 1) ctx.countryCode = parts[parts.length - 1].toUpperCase();
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
return ctx;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
document.addEventListener('DOMContentLoaded', function () {
|
|
190
|
-
const wrapper = document.getElementById('notification-widget');
|
|
191
|
-
if (!wrapper) return;
|
|
192
|
-
|
|
193
|
-
// Define and apply styles for the popup and button
|
|
194
|
-
const styles = `
|
|
195
|
-
.notification-btn {
|
|
196
|
-
background-color: #fff;
|
|
197
|
-
border: 1px solid black;
|
|
198
|
-
color: black;
|
|
199
|
-
padding: 12px 24px;
|
|
200
|
-
text-align: center;
|
|
201
|
-
width: 100%;
|
|
202
|
-
cursor: pointer;
|
|
203
|
-
text-transform: uppercase;
|
|
204
|
-
}
|
|
205
|
-
#popup-body.overlay {
|
|
206
|
-
position: fixed;
|
|
207
|
-
z-index: 9998;
|
|
208
|
-
top: 0;
|
|
209
|
-
bottom: 0;
|
|
210
|
-
left: 0;
|
|
211
|
-
right: 0;
|
|
212
|
-
background: rgba(0, 0, 0, 0.7);
|
|
213
|
-
transition: opacity 200ms;
|
|
214
|
-
visibility: hidden;
|
|
215
|
-
opacity: 0;
|
|
216
|
-
}
|
|
217
|
-
#popup-wrapper {
|
|
218
|
-
margin: 70px auto;
|
|
219
|
-
z-index: 9999;
|
|
220
|
-
padding: 15px;
|
|
221
|
-
background: #fff;
|
|
222
|
-
border-radius: 5px;
|
|
223
|
-
max-width: 360px;
|
|
224
|
-
position: relative;
|
|
225
|
-
}
|
|
226
|
-
#popup-close {
|
|
227
|
-
position: absolute;
|
|
228
|
-
top: 5px;
|
|
229
|
-
right: 15px;
|
|
230
|
-
transition: all 200ms;
|
|
231
|
-
font-size: 30px;
|
|
232
|
-
font-weight: bold;
|
|
233
|
-
text-decoration: none;
|
|
234
|
-
color: #333;
|
|
235
|
-
cursor: pointer;
|
|
236
|
-
}
|
|
237
|
-
#popup-close:hover {
|
|
238
|
-
color: #d80606;
|
|
239
|
-
}
|
|
240
|
-
#popup-title {
|
|
241
|
-
margin: 0;
|
|
242
|
-
font-size: 20px;
|
|
243
|
-
max-width: 350px;
|
|
244
|
-
text-transform: uppercase;
|
|
245
|
-
}
|
|
246
|
-
#popup-text {
|
|
247
|
-
margin: 10px 0;
|
|
248
|
-
font-size: 14px;
|
|
249
|
-
}
|
|
250
|
-
#popup-form {
|
|
251
|
-
display: flex;
|
|
252
|
-
flex-direction: column;
|
|
253
|
-
gap: 10px;
|
|
254
|
-
}
|
|
255
|
-
#popup-form input {
|
|
256
|
-
padding: 0.475em 1em;
|
|
257
|
-
border: 1px solid #caced1;
|
|
258
|
-
border-radius: 0.25rem;
|
|
259
|
-
font-size: 1.15rem;
|
|
260
|
-
max-width: 100%;
|
|
261
|
-
}
|
|
262
|
-
#popup-form input::placeholder {
|
|
263
|
-
font-size: 1rem;
|
|
264
|
-
}
|
|
265
|
-
#popup-form button {
|
|
266
|
-
font-size: 0.85rem;
|
|
267
|
-
padding: 0.975em 1em;
|
|
268
|
-
font-weight: 600;
|
|
269
|
-
border: none;
|
|
270
|
-
text-transform: uppercase;
|
|
271
|
-
background: #aca475;
|
|
272
|
-
color: #fff;
|
|
273
|
-
cursor: pointer;
|
|
274
|
-
}
|
|
275
|
-
.checkbox-item {
|
|
276
|
-
display: flex;
|
|
277
|
-
align-items: center;
|
|
278
|
-
gap: 8px;
|
|
279
|
-
}
|
|
280
|
-
.checkbox-item input[type="checkbox"] {
|
|
281
|
-
width: auto;
|
|
282
|
-
margin: 0;
|
|
283
|
-
}
|
|
284
|
-
.custom-select {
|
|
285
|
-
position: relative;
|
|
286
|
-
}
|
|
287
|
-
.custom-select select {
|
|
288
|
-
appearance: none;
|
|
289
|
-
width: 100%;
|
|
290
|
-
font-size: 1.15rem;
|
|
291
|
-
padding: 0.475em 1em;
|
|
292
|
-
background-color: #fff;
|
|
293
|
-
border: 1px solid #caced1;
|
|
294
|
-
border-radius: 0.25rem;
|
|
295
|
-
color: #000;
|
|
296
|
-
cursor: pointer;
|
|
297
|
-
}
|
|
298
|
-
.custom-select::before,
|
|
299
|
-
.custom-select::after {
|
|
300
|
-
--size: 0.3rem;
|
|
301
|
-
content: "";
|
|
302
|
-
position: absolute;
|
|
303
|
-
right: 1rem;
|
|
304
|
-
pointer-events: none;
|
|
305
|
-
}
|
|
306
|
-
.custom-select::before {
|
|
307
|
-
border-left: var(--size) solid transparent;
|
|
308
|
-
border-right: var(--size) solid transparent;
|
|
309
|
-
border-bottom: var(--size) solid black;
|
|
310
|
-
top: 40%;
|
|
311
|
-
}
|
|
312
|
-
.custom-select::after {
|
|
313
|
-
border-left: var(--size) solid transparent;
|
|
314
|
-
border-right: var(--size) solid transparent;
|
|
315
|
-
border-top: var(--size) solid black;
|
|
316
|
-
top: 55%;
|
|
317
|
-
}
|
|
318
|
-
`;
|
|
319
|
-
|
|
320
|
-
const styleSheet = document.createElement('style');
|
|
321
|
-
styleSheet.type = 'text/css';
|
|
322
|
-
styleSheet.innerText = styles;
|
|
323
|
-
document.head.appendChild(styleSheet);
|
|
324
|
-
|
|
325
|
-
// Create and append the overlay for the popup
|
|
326
|
-
const overlay = document.createElement('div');
|
|
327
|
-
overlay.innerHTML = `
|
|
328
|
-
<div id="popup-body" class="overlay">
|
|
329
|
-
<div id="popup-wrapper">
|
|
330
|
-
<h3 id="popup-title"></h3>
|
|
331
|
-
<span id="popup-close">×</span>
|
|
332
|
-
<div id="popup-text"></div>
|
|
333
|
-
<div id="popup-login-msg" style="display:none; color:#d80606; font-size:14px; margin:10px 0;">Please log in to your account to continue.</div>
|
|
334
|
-
<form id="popup-form">
|
|
335
|
-
<div class="custom-select">
|
|
336
|
-
<select name="select-size" required>
|
|
337
|
-
</select>
|
|
338
|
-
</div>
|
|
339
|
-
<input name="email" placeholder="Email" type="email" required />
|
|
340
|
-
</form>
|
|
341
|
-
</div>
|
|
342
|
-
</div>
|
|
343
|
-
`;
|
|
344
|
-
|
|
345
|
-
wrapper.appendChild(overlay);
|
|
346
|
-
|
|
347
|
-
const popupBody = document.getElementById('popup-body');
|
|
348
|
-
const popupClose = document.getElementById('popup-close');
|
|
349
|
-
const popupOpenButton = document.getElementById('popup-open');
|
|
350
|
-
const popupTitle = document.getElementById('popup-title');
|
|
351
|
-
const popupText = document.getElementById('popup-text');
|
|
352
|
-
const loginMsg = document.getElementById('popup-login-msg');
|
|
353
|
-
const sizeSelect = document.querySelector("select[name='select-size']");
|
|
354
|
-
const form = overlay.querySelector('#popup-form');
|
|
355
|
-
|
|
356
|
-
if (
|
|
357
|
-
!popupBody ||
|
|
358
|
-
!popupClose ||
|
|
359
|
-
!popupOpenButton ||
|
|
360
|
-
!popupTitle ||
|
|
361
|
-
!sizeSelect
|
|
362
|
-
)
|
|
363
|
-
return;
|
|
364
|
-
|
|
365
|
-
// Parse fields and type to be included in the form from data attribute
|
|
366
|
-
const fields = JSON.parse(
|
|
367
|
-
popupOpenButton.getAttribute('data-fields') || '["email"]',
|
|
368
|
-
);
|
|
369
|
-
const type = popupOpenButton.getAttribute('data-type') || 'notify-me';
|
|
370
|
-
// Auth mode: 'token' (default, hardcoded ACCESS_TOKEN) or 'proxy' (Shopify App Proxy).
|
|
371
|
-
const authMode = popupOpenButton.getAttribute('data-auth') || 'token';
|
|
372
|
-
// Tenant for X-Twc-Tenant header; used in both auth modes.
|
|
373
|
-
const tenant = popupOpenButton.getAttribute('data-tenant') || TENANT_ID;
|
|
374
|
-
const typeConfig = {
|
|
375
|
-
'notify-me': {
|
|
376
|
-
text: 'Register to receive a notification as soon as this item is back in stock',
|
|
377
|
-
buttonText: 'Notify me',
|
|
378
|
-
},
|
|
379
|
-
'coming-soon': {
|
|
380
|
-
text: 'Register your interest to hear more about this item',
|
|
381
|
-
buttonText: 'Register Interest',
|
|
382
|
-
},
|
|
383
|
-
};
|
|
384
|
-
|
|
385
|
-
// Get product data from Shopify's global variable
|
|
386
|
-
const productData = window?.currentProduct;
|
|
387
|
-
|
|
388
|
-
const countryCtx = detectCountryContext();
|
|
389
|
-
const resolvedMarketId =
|
|
390
|
-
popupOpenButton.getAttribute('data-market-id') || countryCtx.marketId;
|
|
391
|
-
|
|
392
|
-
// Map for form fields
|
|
393
|
-
popupText.innerText = typeConfig[type].text;
|
|
394
|
-
|
|
395
|
-
const countryOptions = COUNTRY_CODES.map(
|
|
396
|
-
(c) =>
|
|
397
|
-
`<option value="${c.code}"${c.code === countryCtx.countryCode ? ' selected' : ''}>${c.name}</option>`,
|
|
398
|
-
).join('');
|
|
399
|
-
|
|
400
|
-
const fieldMap = {
|
|
401
|
-
email: `<input name="email" placeholder="Email" type="email" required />`,
|
|
402
|
-
mobile: `<input name="mobile" placeholder="Mobile" type="tel" required />`,
|
|
403
|
-
firstName: `<input name="firstName" placeholder="First name" type="text" required />`,
|
|
404
|
-
lastName: `<input name="lastName" placeholder="Last name" type="text" required />`,
|
|
405
|
-
countryCode: `<div class="custom-select"><select name="countryCode"><option value="">Select country</option>${countryOptions}</select></div>`,
|
|
406
|
-
provinceCode: `<input name="provinceCode" placeholder="State / Province code" type="text" value="${countryCtx.provinceCode || ''}" />`,
|
|
407
|
-
};
|
|
408
|
-
|
|
409
|
-
// Add fields to the form based on the parsed fields
|
|
410
|
-
fields.forEach((field) => {
|
|
411
|
-
if (fieldMap[field]) {
|
|
412
|
-
form.insertAdjacentHTML('beforeend', fieldMap[field]);
|
|
413
|
-
}
|
|
414
|
-
});
|
|
415
|
-
|
|
416
|
-
form.insertAdjacentHTML('beforeend', `<div id="checkbox-wrapper"></div>`);
|
|
417
|
-
const checkboxWrapper = document.getElementById('checkbox-wrapper');
|
|
418
|
-
checkboxWrapper.insertAdjacentHTML(
|
|
419
|
-
'beforeend',
|
|
420
|
-
`<div class="checkbox-item"><input type="checkbox" name="mailList" id="mailList" /><label for="mailList">Subscribe to our mailing list</label></div>`,
|
|
421
|
-
);
|
|
422
|
-
checkboxWrapper.insertAdjacentHTML(
|
|
423
|
-
'beforeend',
|
|
424
|
-
`<div class="checkbox-item"><input type="checkbox" name="mailListSms" id="mailListSms" /><label for="mailListSms">Subscribe to our mailing list via SMS</label></div>`,
|
|
425
|
-
);
|
|
426
|
-
form.insertAdjacentHTML(
|
|
427
|
-
'beforeend',
|
|
428
|
-
`<button type="submit">${typeConfig[type].buttonText}</button>`,
|
|
429
|
-
);
|
|
430
|
-
|
|
431
|
-
// Show/hide the popup
|
|
432
|
-
function showPopup() {
|
|
433
|
-
if (!productData) {
|
|
434
|
-
alert('Product data not found');
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
// Set the popup title and populate the size dropdown
|
|
438
|
-
popupTitle.innerHTML = productData.title;
|
|
439
|
-
productData.variants.forEach((variant) => {
|
|
440
|
-
const option = document.createElement('option');
|
|
441
|
-
option.value = variant.title;
|
|
442
|
-
option.textContent = variant.title;
|
|
443
|
-
sizeSelect.appendChild(option);
|
|
444
|
-
});
|
|
445
|
-
popupBody.style.visibility = 'visible';
|
|
446
|
-
popupBody.style.opacity = 1;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
function hidePopup() {
|
|
450
|
-
popupBody.style.visibility = 'hidden';
|
|
451
|
-
popupBody.style.opacity = 0;
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
popupOpenButton.addEventListener('click', showPopup);
|
|
455
|
-
popupClose.addEventListener('click', hidePopup);
|
|
456
|
-
|
|
457
|
-
// Form submission handler
|
|
458
|
-
if (form) {
|
|
459
|
-
form.addEventListener('submit', async function (event) {
|
|
460
|
-
event.preventDefault();
|
|
461
|
-
|
|
462
|
-
const selectedSize = sizeSelect.value;
|
|
463
|
-
const selectedVariant = productData.variants.find(
|
|
464
|
-
(variant) => variant.title === selectedSize,
|
|
465
|
-
);
|
|
466
|
-
|
|
467
|
-
if (selectedVariant) {
|
|
468
|
-
const formData = {
|
|
469
|
-
variantRef: selectedVariant.id,
|
|
470
|
-
email: form.querySelector("input[name='email']").value,
|
|
471
|
-
subscribe: form.querySelector("input[name='mailList']").checked,
|
|
472
|
-
subscribeSms: form.querySelector("input[name='mailListSms']").checked,
|
|
473
|
-
};
|
|
474
|
-
|
|
475
|
-
if (type === 'coming-soon') {
|
|
476
|
-
formData.comingSoon = true;
|
|
477
|
-
// formData.productRef = productData.id;
|
|
478
|
-
} else {
|
|
479
|
-
formData.notifyMe = true;
|
|
480
|
-
}
|
|
481
|
-
if (fields.includes('firstName')) {
|
|
482
|
-
formData.firstName = form.querySelector(
|
|
483
|
-
"input[name='firstName']",
|
|
484
|
-
).value;
|
|
485
|
-
}
|
|
486
|
-
if (fields.includes('lastName')) {
|
|
487
|
-
formData.lastName = form.querySelector(
|
|
488
|
-
"input[name='lastName']",
|
|
489
|
-
).value;
|
|
490
|
-
}
|
|
491
|
-
if (fields.includes('mobile')) {
|
|
492
|
-
formData.mobile = form.querySelector("input[name='mobile']").value;
|
|
493
|
-
// formData.phone = form.querySelector("input[name='mobile']").value;
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
// Country / province / market — manual fields take precedence over auto-detected values
|
|
497
|
-
if (fields.includes('countryCode')) {
|
|
498
|
-
const selected = form.querySelector("select[name='countryCode']").value;
|
|
499
|
-
if (selected) formData.countryCode = selected;
|
|
500
|
-
} else if (countryCtx.countryCode) {
|
|
501
|
-
formData.countryCode = countryCtx.countryCode;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
if (fields.includes('provinceCode')) {
|
|
505
|
-
const val = form.querySelector("input[name='provinceCode']").value;
|
|
506
|
-
if (val) formData.provinceCode = val;
|
|
507
|
-
} else if (countryCtx.provinceCode) {
|
|
508
|
-
formData.provinceCode = countryCtx.provinceCode;
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
if (resolvedMarketId) formData.marketId = resolvedMarketId;
|
|
512
|
-
|
|
513
|
-
// Resolve the Authorization token based on auth mode.
|
|
514
|
-
let authToken = ACCESS_TOKEN;
|
|
515
|
-
if (authMode === 'proxy') {
|
|
516
|
-
const proxyToken = await getProxyAccessToken();
|
|
517
|
-
if (!proxyToken) {
|
|
518
|
-
loginMsg.style.display = 'block';
|
|
519
|
-
return;
|
|
520
|
-
}
|
|
521
|
-
loginMsg.style.display = 'none';
|
|
522
|
-
authToken = `Bearer ${proxyToken}`;
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
let url = `https://api.au-sandbox.thewishlist.io/services/wsservice/api/wishlist/items/customerInterest`;
|
|
526
|
-
|
|
527
|
-
fetch(url, {
|
|
528
|
-
method: 'POST',
|
|
529
|
-
headers: {
|
|
530
|
-
'Content-Type': 'application/json',
|
|
531
|
-
Authorization: authToken,
|
|
532
|
-
'X-Twc-Tenant': tenant,
|
|
533
|
-
},
|
|
534
|
-
body: JSON.stringify(formData),
|
|
535
|
-
})
|
|
536
|
-
.then((response) => {
|
|
537
|
-
if (response.ok) {
|
|
538
|
-
alert('Form submitted');
|
|
539
|
-
hidePopup();
|
|
540
|
-
} else {
|
|
541
|
-
alert('Form submission failed');
|
|
542
|
-
}
|
|
543
|
-
})
|
|
544
|
-
.catch((error) => {
|
|
545
|
-
console.error('Error submitting form:', error);
|
|
546
|
-
alert('Form submission failed');
|
|
547
|
-
});
|
|
548
|
-
} else {
|
|
549
|
-
alert('Selected variant not found');
|
|
550
|
-
}
|
|
551
|
-
});
|
|
552
|
-
}
|
|
553
|
-
});
|