Update /my_account/verify_email/index.html.jst to latest way, no accordion
[ndcode_site.git] / my_account / verify_email / index.html.jst
1 return async env => {
2   let breadcrumbs = await _require('/_lib/breadcrumbs.jst')
3   let fa_user_check = await env.site.get_min_svg('/_svg/fa_user-check.svg')
4   let get_placeholder = await _require('/_lib/get_placeholder.jst')
5   let get_session = await _require('/_lib/get_session.jst')
6   let icon_cross = await env.site.get_min_svg('/_svg/icon_cross.svg')
7   let icon_tick = await env.site.get_min_svg('/_svg/icon_tick.svg')
8   let navbar = await _require('/_lib/navbar.jst')
9
10   // preload placeholder
11   let transaction = await env.site.database.Transaction()
12   let placeholder
13   try {
14     let root = await transaction.get({})
15     let session = await get_session(env, root)
16     placeholder = await get_placeholder(env, session)
17     transaction.commit()
18   }
19   catch (error) {
20     transaction.rollback()
21     throw error
22   }
23
24   // preload URL details if any
25   let email =
26     Object.prototype.hasOwnProperty.call(
27       env.parsed_url.query,
28       'email'
29     ) ?
30       decodeURIComponent(env.parsed_url.query.email) :
31       ''
32   let link_code =
33     Object.prototype.hasOwnProperty.call(
34       env.parsed_url.query,
35       'link_code'
36     ) ?
37       decodeURIComponent(env.parsed_url.query.link_code) :
38       ''
39
40    await navbar(
41     env,
42     // head
43     async _out => {},
44     // body
45     async _out => {
46       await breadcrumbs(env, _out)
47
48       p {'You will need to verify your email address via an emailed link before you can sign in to your account.'}
49
50       form#form {
51         div.row {
52           div.col-md-6 {
53             div.form-group {
54              label.form-label(for="email") {'Email *'}
55               input.form-control#email(type="email" value=email placeholder=placeholder.email required="required" maxlength=256) {}
56               div.invalid-feedback {'Please enter your account\'s email address.'}
57             }
58           }
59           div.col-md-6 {
60             div.form-group {
61               label.form-label(for="link-code") {'Link code *'}
62               input.form-control#link-code(type="text" value=link_code placeholder="00000000000000000000000000000000" required="required" minlength=32 maxlength=32) {}
63               div.invalid-feedback {'Please enter the 32-character code from the link we have emailed to you.'}
64             }
65           }
66         }
67       }
68
69       if (email.length || details.length)
70         button.btn.btn-success#verify-email(type="button") {
71           div.icon24-outer.mr-2#icon {
72             div.icon24-inner {_out.push(fa_user_check)}
73           }
74           div.icon24-outer.mr-2#tick(hidden) {
75             div.icon24-inner {_out.push(icon_tick)}
76           }
77           div.icon24-outer.mr-2#cross(hidden) {
78             div.icon24-inner {_out.push(icon_cross)}
79           }
80           div.icon24-outer.mr-2#spinner(hidden) {
81             div.icon24-inner {
82               div.spinner-border.spinner-border-sm(role="status") {}
83             }
84           }
85           'Verify email'
86         }
87       else
88         button.btn.btn-success#verify-email(type="button" disabled) {
89           div.icon24-outer.mr-2#icon {
90             div.icon24-inner {_out.push(fa_user_check)}
91           }
92           div.icon24-outer.mr-2#tick(hidden) {
93             div.icon24-inner {_out.push(icon_tick)}
94           }
95           div.icon24-outer.mr-2#cross(hidden) {
96             div.icon24-inner {_out.push(icon_cross)}
97           }
98           div.icon24-outer.mr-2#spinner(hidden) {
99             div.icon24-inner {
100               div.spinner-border.spinner-border-sm(role="status") {}
101             }
102           }
103           'Verify email'
104         }
105
106       p.'mt-3'.mb-0#message(hidden) {}
107
108       p.text-muted.mt-3 {'* These fields are required.'}
109     },
110     // scripts
111     async _out => {
112       //script(src="/js/utils.js") {}
113
114       script {
115         document.addEventListener(
116           'DOMContentLoaded',
117           () => {
118             let id_cross = document.getElementById('cross')
119             let id_email = document.getElementById('email')
120             let id_form = document.getElementById('form')
121             let id_icon = document.getElementById('icon')
122             let id_link_code = document.getElementById('link-code')
123             let id_message = document.getElementById('message')
124             let id_spinner = document.getElementById('spinner')
125             let id_tick = document.getElementById('tick')
126             let id_verify_email = document.getElementById('verify-email')
127
128             let edited = () => {
129               id_verify_email.disabled =
130                 id_email.value.length === 0 &&
131                   id_link_code.value.length === 0
132               id_icon.hidden = false
133               id_tick.hidden = true
134               id_cross.hidden = true
135               id_spinner.hidden = true
136               id_message.hidden = true
137             }
138
139             id_email.addEventListener('input', edited)
140             id_link_code.addEventListener('input', edited)
141
142             id_verify_email.addEventListener(
143               'click',
144               async () => {
145                 id_icon.hidden = false
146                 id_tick.hidden = true
147                 id_cross.hidden = true
148                 id_spinner.hidden = true
149                 // the below causes an ugly flicker, so just keep the message
150                 //id_message.hidden = true
151
152                 if (!id_form.checkValidity()) {
153                   id_form.classList.add('was-validated');
154
155                   id_icon.hidden = true
156                   id_cross.hidden = false
157                   return
158                 }
159                 id_form.classList.remove('was-validated');
160
161                 let email = id_email.value.slice(0, 256).toLowerCase()
162                 let link_code = id_link_code.value.slice(0, 32)
163
164                 id_icon.hidden = true
165                 id_spinner.hidden = false
166                 try {
167                   await api_call(
168                     '/api/account/verify_email.json',
169                     email,
170                     link_code
171                   )
172                 }
173                 catch (error) {
174                   let problem = Problem.from(error)
175
176                   id_cross.hidden = false
177                   id_spinner.hidden = true
178
179                   id_message.textContent = problem.detail
180                   //id_message.classList.remove('text-success')
181                   id_message.classList.add('text-danger')
182                   id_message.hidden = false
183                   return
184                 }
185                 id_tick.hidden = false
186                 id_spinner.hidden = true
187                 id_message.textContent = `Your email "${email}" has been verified. You can now sign in.`
188                 //id_message.classList.add('text-success')
189                 id_message.classList.remove('text-danger')
190                 id_message.hidden = false
191               }
192             )
193           }
194         )
195       }
196     }
197   )
198 }