2 let breadcrumbs = await _require('/_lib/breadcrumbs.jst')
3 let get_session = await _require('/_lib/get_session.jst')
4 let icon_cross = await env.site.get_min_svg('/_svg/icon_cross.svg')
5 let icon_tick = await env.site.get_min_svg('/_svg/icon_tick.svg')
6 let navbar = await _require('/_lib/navbar.jst')
8 // preload draft details if any
9 let transaction = await env.site.database.Transaction()
12 let root = await transaction.get({})
13 let session = await get_session(env, root)
14 sign_up_draft = await session.get_json('sign_up_draft')
15 if (sign_up_draft === undefined || env.now >= sign_up_draft.expires)
19 transaction.rollback()
28 await breadcrumbs(env, _out)
30 p {'Signing up allows you to leave comments on our blog and receive communications from us.'}
32 p {'Your given names are visible to other users if you comment on our blog. Your email and family name remain private. If your name is one word or does not fit given names/family name pattern, then please enter given names only.'}
34 div.accordion#accordion(role="tablist" aria-multiselectable="true") {
36 div.card-header#card-1-heading(role="tab") {
37 span#card-1-tick(style="display: none;") {
38 span.icon-color.pr-3 {_out.push(icon_tick)}
40 span#card-1-cross(style="display: none;") {
41 span.icon-color.pr-3 {_out.push(icon_cross)}
43 //span#card-1-spinner(style="display: none;") {
44 // span.icon-color.pr-3 {
45 // div.spinner-border(role="status") {
46 // span.sr-only {'Loading...'}
50 a.h5(data-toggle="collapse" data-parent="#accordion" href="#card-1-collapse" aria-expanded="true" aria-controls="card-1-collapse") {
54 div#card-1-collapse.collapse.show(role="tabpanel" aria-labelledby="card-1-heading" data-parent="#accordion") {
60 label.form-label(for="given-names") {'Given names *'}
61 input.form-control#given-names(type="text" value=sign_up_draft.given_names || '' placeholder="Miley" required maxlength=256) {}
62 div.invalid-feedback {'Please enter a name we can address you by.'}
67 label.form-label(for="family-name") {'Family name'}
68 input.form-control#family-name(type="text" value=sign_up_draft.family_name || '' placeholder="Chapman" maxlength=256) {}
75 label.form-label(for="email") {'Email *'}
76 input.form-control#email(type="email" value=sign_up_draft.email || '' placeholder="mileychapman@email.com" required maxlength=256) {}
77 div.invalid-feedback {'Please enter an email address we can contact you on.'}
82 label.form-label(for="password") {'Password *'}
83 input.form-control#password(type="password" placeholder="Choose" required minlength=8 maxlength=256) {}
84 div.invalid-feedback {'Please choose a secure password of at least 8 characters.'}
90 div.custom-control.custom-checkbox {
91 if (sign_up_draft === undefined || sign_up_draft.contact_me)
92 input.custom-control-input#contact-me(type="checkbox" checked) {}
94 input.custom-control-input#contact-me(type="checkbox") {}
96 label.custom-control-label(for="contact-me") {
97 'Contact me by email with updates and special offers'
102 div.row.align-items-center {
105 label.form-label(for="verification-code") {'Verification code *'}
106 input.form-control#verification-code(type="text" placeholder="ad7jb3" required minlength=6 maxlength=6) {}
107 div.invalid-feedback {'Please enter the 6 characters from the verification image to right or below. We need this to protect us from spam and bots.'}
110 div.'col-md-6'.my-3 {
111 img#verification-image(src="/api/verification_image.png?seq=0" width=300 height=150) {}
116 button.btn.btn-outline-secondary#'card-1-new-code'(type="button") {'New code'}
117 button.btn.btn-success.ml-3#card-1-create-account(type="button") {'Create account'}
119 p.'mt-3'.mb-0#card-1-message(style="display: none;") {}
124 div.card-header#card-2-heading(role="tab") {
125 span#card-2-tick(style="display: none;") {
126 span.icon-color.pr-3 {_out.push(icon_tick)}
128 span#card-2-cross(style="display: none;") {
129 span.icon-color.pr-3 {_out.push(icon_cross)}
131 span#card-2-spinner(style="display: none;") {
132 span.icon-color.pr-3 {
133 div.spinner-border(role="status") {
134 span.sr-only {'Loading...'}
138 a.h5.collapsed(data-toggle="collapse" data-parent="#accordion" href="#card-2-collapse" aria-expanded="false" aria-controls="card-2-collapse") {
139 'Send email verification link'
142 div#card-2-collapse.collapse(role="tabpanel" aria-labelledby="card-2-heading" data-parent="#accordion") {
144 button.btn.btn-outline-secondary#card-2-back(type="button") {'Back'}
145 button.btn.btn-outline-secondary.ml-3#card-2-resend-email(type="button") {'Re-send email'}
147 p.'mt-3'.mb-0#card-2-message(style="display: none;") {}
153 p.mt-3 {'* These fields are required.'}
157 //script(src="/js/api_call.js") {}
160 let draft_timeout_running = false
161 let draft_timeout_handler = async () => {
162 draft_timeout_running = false
164 '/api/account/sign_up/set_draft.json',
166 email: document.getElementById('email').value.slice(0, 256).toLowerCase(),
167 given_names: document.getElementById('given-names').value.slice(0, 256),
168 family_name: document.getElementById('family-name').value.slice(0, 256),
169 contact_me: document.getElementById('contact-me').checked ? true : false
172 //console.log('draft', await api_call('/api/account/sign_up/get_draft.json'))
174 let draft_change_handler = () => {
175 if (!draft_timeout_running) {
176 draft_timeout_running = true
177 setTimeout(draft_timeout_handler, 5000)
182 let card_1 = async () => {
183 if (!document.getElementById('form').checkValidity()) {
184 document.getElementById('form').classList.add('was-validated');
185 $('#card-1-tick').hide()
186 $('#card-1-cross').show()
187 //$('#card-1-spinner').hide()
190 document.getElementById('form').classList.remove('was-validated');
193 email: document.getElementById('email').value.slice(0, 256).toLowerCase(),
194 given_names: document.getElementById('given-names').value.slice(0, 256),
195 family_name: document.getElementById('family-name').value.slice(0, 256),
196 password: document.getElementById('password').value.slice(0, 256),
197 contact_me: document.getElementById('contact-me').checked ? true : false
202 '/api/account/sign_up/create_account.json',
203 document.getElementById('verification-code').value.slice(0, 6).toLowerCase(),
208 let problem = Problem.from(error)
210 $('#card-1-tick').hide()
211 $('#card-1-cross').show()
212 $('#card-1-spinner').hide()
214 document.getElementById('card-1-message').textContent = problem.detail
215 //document.getElementById('card-1-message').classList.remove('text-success')
216 document.getElementById('card-1-message').classList.add('text-danger')
217 $('#card-1-message').show()
219 $('#card-1-collapse').collapse('show')
222 $('#card-1-tick').show()
223 $('#card-1-cross').hide()
224 $('#card-1-spinner').hide()
225 document.getElementById('card-1-message').textContent = `Your account with email "${details.email}" has been created.`
226 //document.getElementById('card-1-message').classList.add('text-success')
227 document.getElementById('card-1-message').classList.remove('text-danger')
228 $('#card-1-message').show()
232 let card_2 = async () => {
233 $('#card-2-tick').hide()
234 $('#card-2-cross').hide()
235 $('#card-2-spinner').show()
236 document.getElementById('card-2').scrollIntoView()
240 '/api/account/sign_up/send_email_verification_link.json',
245 let problem = Problem.from(error)
247 $('#card-2-tick').hide()
248 $('#card-2-cross').show()
249 $('#card-2-spinner').hide()
251 document.getElementById('card-2-message').textContent = problem.detail
252 //document.getElementById('card-2-message').classList.remove('text-success')
253 document.getElementById('card-2-message').classList.add('text-danger')
254 $('#card-2-message').show()
256 $('#card-2-collapse').collapse('show')
259 $('#card-2-tick').show()
260 $('#card-2-cross').hide()
261 $('#card-2-spinner').hide()
263 document.getElementById('card-2-message').textContent = `Email verification link has been sent to "${details.email}". Please check your email for next steps.`
264 //document.getElementById('card-2-message').classList.add('text-success')
265 document.getElementById('card-2-message').classList.remove('text-danger')
266 $('#card-2-message').show()
270 document.addEventListener(
273 document.getElementById('given-names').addEventListener(
277 document.getElementById('family-name').addEventListener(
281 document.getElementById('email').addEventListener(
285 document.getElementById('password').addEventListener(
289 document.getElementById('contact-me').addEventListener(
295 document.getElementById('card-1-new-code').addEventListener(
298 document.getElementById('verification-image').src = `/api/verification_image.png?seq=${image_seq}`
303 document.getElementById('card-1-create-account').addEventListener(
306 if (await card_1() && await card_2())
307 $('#card-2-collapse').collapse('show')
311 document.getElementById('card-2-back').addEventListener(
313 () => {$('#card-1-collapse').collapse('show')}
316 document.getElementById('card-2-resend-email').addEventListener(
320 $('#card-2-collapse').collapse('show')