From: Nick Downing Date: Fri, 14 Jan 2022 12:31:47 +0000 (+1100) Subject: Add sign up draft facility (avoids having to re-enter data if you refresh page) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?p=ndcode_site.git;a=commitdiff_plain;h=8a171faf80e7188b9cd60fdeca4c6254481b2071 Add sign up draft facility (avoids having to re-enter data if you refresh page) --- diff --git a/_lib/post_request.jst b/_lib/post_request.jst index a20e797..7d7f2ba 100644 --- a/_lib/post_request.jst +++ b/_lib/post_request.jst @@ -24,12 +24,12 @@ return async (env, api, func) => { ) env.request.pipe(write_stream) let arguments = JSON.parse((await data).toString()) - console.log('api', api, 'arguments', arguments) + console.log('api', api, 'arguments', JSON.stringify(arguments)) result = await func(...arguments) if (result === undefined) result = null - console.log('api', api, 'result', result) + console.log('api', api, 'result', JSON.stringify(result)) } catch (error) { let problem = diff --git a/api/sign_up/get_draft.json.jst b/api/sign_up/get_draft.json.jst new file mode 100644 index 0000000..1f80c00 --- /dev/null +++ b/api/sign_up/get_draft.json.jst @@ -0,0 +1,30 @@ +let logjson = (await import('@ndcode/logjson')).default +let XDate = require('xdate') + +return async env => { + let post_request = await _require('/_lib/post_request.jst') + let session_cookie = await _require('/_lib/session_cookie.jst') + let Problem = await _require('/_lib/Problem.jst') + + post_request( + // env + env, + // api + '/api/sign_up/get_draft', + // func + async () => { + let transaction = await env.site.database.Transaction() + try { + // initialize env.session_key, set cookie in env.response + let session = await session_cookie(env, transaction) + + return await logjson.logjson_to_json( + await session.get('sign_up_draft', {}) + ) + } + finally { + transaction.rollback() + } + } + ) +} diff --git a/api/sign_up/set_draft.json.jst b/api/sign_up/set_draft.json.jst new file mode 100644 index 0000000..79c4de3 --- /dev/null +++ b/api/sign_up/set_draft.json.jst @@ -0,0 +1,38 @@ +let XDate = require('xdate') + +return async env => { + let post_request = await _require('/_lib/post_request.jst') + let session_cookie = await _require('/_lib/session_cookie.jst') + let Problem = await _require('/_lib/Problem.jst') + + post_request( + // env + env, + // api + '/api/sign_up/set_draft', + // func + async details => { + // coerce and/or validate + details = { + email: details.email.slice(0, 256).toLowerCase(), + given_names: details.given_names.slice(0, 256), + family_name: details.family_name.slice(0, 256), + password: details.password.slice(0, 256), + contact_me: details.contact_me ? true : false + } + + let transaction = await env.site.database.Transaction() + try { + // initialize env.session_key, set cookie in env.response + let session = await session_cookie(env, transaction) + + session.set('sign_up_draft', transaction.json_to_logjson(details)) + await transaction.commit() + } + catch (error) { + transaction.rollback() + throw error + } + } + ) +} diff --git a/my_account/sign_up/index.html.jst b/my_account/sign_up/index.html.jst index 8eaff34..0bbf5b8 100644 --- a/my_account/sign_up/index.html.jst +++ b/my_account/sign_up/index.html.jst @@ -1,8 +1,26 @@ +let logjson = (await import('@ndcode/logjson')).default + return async env => { let breadcrumbs = await _require('/_lib/breadcrumbs.jst') let icon_cross = await env.site.get_min_svg('/_svg/icon_cross.svg') let icon_tick = await env.site.get_min_svg('/_svg/icon_tick.svg') let navbar = await _require('/_lib/navbar.jst') + let session_cookie = await _require('/_lib/session_cookie.jst') + + // preload draft details if any + let transaction = await env.site.database.Transaction(), details + try { + // initialize env.session_key, set cookie in env.response + let session = await session_cookie(env, transaction) + + details = await logjson.logjson_to_json( + await session.get('sign_up_draft', {}) + ) + } + finally { + transaction.rollback() + } + console.log('details', JSON.stringify(details)) await navbar( env, @@ -40,13 +58,13 @@ return async env => { div.col-md-6 { div.form-group { label.form-label(for="given-names") {'Given names *'} - input.form-control#given-names(type="text" placeholder="Your given names" required="required" maxlength=256) {} + input.form-control#given-names(type="text" value=details.given_names || '' placeholder="Your given names" required="required" maxlength=256) {} } } div.col-md-6 { div.form-group { label.form-label(for="family-name") {'Family name'} - input.form-control#family-name(type="text" placeholder="Your family name" maxlength=256) {} + input.form-control#family-name(type="text" value=details.family_name || '' placeholder="Your family name" maxlength=256) {} } } } @@ -54,20 +72,23 @@ return async env => { div.col-md-6 { div.form-group { label.form-label(for="email") {'Email *'} - input.form-control#email(type="email" placeholder="Your email address" required="required" maxlength=256) {} + input.form-control#email(type="email" value=details.email || '' placeholder="Your email address" required="required" maxlength=256) {} } } div.col-md-6 { div.form-group { label.form-label(for="password") {'Password *'} - input.form-control#password(type="password" placeholder="New password" required="required" minlength=8 maxlength=256) {} + input.form-control#password(type="password" value=details.password || '' placeholder="New password" required="required" minlength=8 maxlength=256) {} } } } div.row { div.col-md-12 { div.custom-control.custom-checkbox { - input.custom-control-input#contact-me(type="checkbox" checked="checked") {} + if (details.contact_me === undefined || details.contact_me) + input.custom-control-input#contact-me(type="checkbox" checked="checked") {} + else + input.custom-control-input#contact-me(type="checkbox") {} ' ' label.custom-control-label(for="contact-me") { 'Contact me by email with updates and special offers' @@ -162,10 +183,64 @@ return async env => { '/api/sign_up/create_account.json', ...arguments ) + //let sign_up_get_draft = async (...arguments) => api_call( + // '/api/sign_up/get_draft.json', + // ...arguments + //) + let sign_up_set_draft = async (...arguments) => api_call( + '/api/sign_up/set_draft.json', + ...arguments + ) - $(document).ready( + let details = () => { + return { + email: document.getElementById('email').value.slice(0, 256).toLowerCase(), + given_names: document.getElementById('given-names').value.slice(0, 256), + family_name: document.getElementById('family-name').value.slice(0, 256), + password: document.getElementById('password').value.slice(0, 256), + contact_me: document.getElementById('contact-me').checked ? true : false + } + } + + let draft_timeout_running = false + let draft_timeout_handler = async () => { + draft_timeout_running = false + await sign_up_set_draft(details()) + //console.log('draft', await sign_up_get_draft()) + } + let draft_change_handler = () => { + if (!draft_timeout_running) { + draft_timeout_running = true + setTimeout(draft_timeout_handler, 5000) + } + } + + document.addEventListener( + 'DOMContentLoaded', () => { - $('#step-1-continue').click( + document.getElementById('given-names').addEventListener( + 'change', + draft_change_handler + ) + document.getElementById('family-name').addEventListener( + 'change', + draft_change_handler + ) + document.getElementById('email').addEventListener( + 'change', + draft_change_handler + ) + document.getElementById('password').addEventListener( + 'change', + draft_change_handler + ) + document.getElementById('contact-me').addEventListener( + 'change', + draft_change_handler + ) + + document.getElementById('step-1-continue').addEventListener( + 'click', async () => { if ( !document.getElementById('given-names').reportValidity() || @@ -189,15 +264,9 @@ return async env => { try { await sign_up_create_account( // verification_code - document.getElementById('verification-code').value, + document.getElementById('verification-code').value.slice(0, 6).toLowerCase(), // details - { - email: document.getElementById('email').value, - given_names: document.getElementById('given-names').value, - family_name: document.getElementById('family-name').value, - password: document.getElementById('password').value, - contact_me: document.getElementById('contact-me').value - } + details() ) } catch (e) { @@ -205,7 +274,7 @@ return async env => { $('#step-2-cross').show() $('#step-2-spinner').hide() - $('#step-2-message').text(e.message) + document.getElementById('step-2-message').textContent = e.message $('#step-2-collapse').collapse('show') return } @@ -213,7 +282,7 @@ return async env => { $('#step-2-cross').hide() $('#step-2-spinner').hide() - $('#step-2-message').text(`Your account with email "${document.getElementById('email').value}" has been created.`) + document.getElementById('step-2-message').textContent = `Your account with email "${document.getElementById('email').value}" has been created.` $('#step-2-collapse').collapse('show') } )