f0ee4cf553ce7a10626769d5323e77132c13cda9
[ndcode_site.git] / my_account / password_reset / index.html.jst
1 let logjson = (await import('@ndcode/logjson')).default
2
3 return async env => {
4   let breadcrumbs = await _require('/_lib/breadcrumbs.jst')
5   let icon_cross = await env.site.get_min_svg('/_svg/icon_cross.svg')
6   let icon_tick = await env.site.get_min_svg('/_svg/icon_tick.svg')
7   let navbar = await _require('/_lib/navbar.jst')
8
9   // preload draft details if any
10   let details = {}
11   if (Object.prototype.hasOwnProperty.call(env.parsed_url.query, 'email'))
12     details.email = decodeURIComponent(env.parsed_url.query.email)
13   console.log('details', JSON.stringify(details))
14
15   await navbar(
16     env,
17     // head
18     async _out => {},
19     // body
20     async _out => {
21       await breadcrumbs(env, _out)
22
23       p {'To reset your password, please enter new details below and we will send you a password reset link.'}
24
25       div.accordion#accordion.mb-5(role="tablist" aria-multiselectable="true") {
26         div.card#step-1 {
27           div.card-header#step-1-heading(role="tab") {
28             span#step-1-tick(style="display: none;") {
29               span.icon-color.pr-3 {_out.push(icon_tick)}
30             }
31             span#step-1-cross(style="display: none;") {
32               span.icon-color.pr-3 {_out.push(icon_cross)}
33             }
34             //span#step-1-spinner(style="display: none;") {
35             //  span.icon-color.pr-3 {
36             //    div.spinner-border(role="status") {
37             //      span.sr-only {'Loading...'}
38             //    }
39             //  }
40             //}
41             a.h5(data-toggle="collapse" data-parent="#accordion" href="#step-1-collapse" aria-expanded="true" aria-controls="step-1-collapse") {
42               'Account details'
43             }
44           }
45           div#step-1-collapse.collapse.show(role="tabpanel" aria-labelledby="step-1-heading" data-parent="#accordion") {
46             div.card-body {
47               div.row {
48                 div.col-md-6 {
49                   div.form-group {
50                    label.form-label(for="email") {'Email *'}
51                     input.form-control#email(type="email" value=details.email || '' placeholder="Account email address" required="required" maxlength=256) {}
52                   }
53                 }
54                 div.col-md-6 {
55                   div.form-group {
56                    label.form-label(for="password") {'Password *'}
57                     input.form-control#password(type="password" placeholder="New password" required="required" minlength=8 maxlength=256) {}
58                   }
59                 }
60               }
61
62               button.btn.btn-success#step-1-continue(type="button") {'Continue'}
63               p.'mt-3'.mb-0 {'* This field is required.'}
64             }
65           }
66         }
67         div.card#step-2 {
68           div.card-header#step-2-heading(role="tab") {
69             span#step-2-tick(style="display: none;") {
70               span.icon-color.pr-3 {_out.push(icon_tick)}
71             }
72             span#step-2-cross(style="display: none;") {
73               span.icon-color.pr-3 {_out.push(icon_cross)}
74             }
75             span#step-2-spinner(style="display: none;") {
76               span.icon-color.pr-3 {
77                 div.spinner-border(role="status") {
78                   span.sr-only {'Loading...'}
79                 }
80               }
81             }
82             a.h5.collapsed(data-toggle="collapse" data-parent="#accordion" href="#step-2-collapse" aria-expanded="false" aria-controls="step-2-collapse") {
83               'Send password reset link'
84             }
85           }
86           div#step-2-collapse.collapse(role="tabpanel" aria-labelledby="step-2-heading" data-parent="#accordion") {
87             div.card-body {
88               p#step-2-message {'Please enter account details first.'}
89
90               button.btn.btn-outline-secondary#step-2-back(type="button") {'Back'}
91               button.btn.btn-outline-secondary.ml-3#step-2-resend-email(type="button") {'Re-send email'}
92             }
93           }
94         }
95       }
96     },
97     // scripts
98     async _out => {
99       //script(src="/js/utils.js") {}
100
101       script {
102         let step_1 = async () => {
103           if (
104             !document.getElementById('email').reportValidity() ||
105               !document.getElementById('password').reportValidity()
106           ) {
107             $('#step-1-tick').hide()
108             $('#step-1-cross').show()
109             //$('#step-1-spinner').hide()
110             return false
111           }
112           $('#step-1-tick').show()
113           $('#step-1-cross').hide()
114           //$('#step-1-spinner').hide()
115           return true
116         }
117
118         let step_2 = async () => {
119           $('#step-2-tick').hide()
120           $('#step-2-cross').hide()
121           $('#step-2-spinner').show()
122           document.getElementById('step-1').scrollIntoView()
123
124           let email
125           try {
126             email = document.getElementById('email').value.slice(0, 256).toLowerCase()
127             await api_call(
128               '/api/account/password_reset.json',
129               email,
130               document.getElementById('password').value.slice(0, 256)
131             )
132           }
133           catch (error) {
134             let problem = Problem.from(error)
135
136             $('#step-2-tick').hide()
137             $('#step-2-cross').show()
138             $('#step-2-spinner').hide()
139
140             document.getElementById('step-2-message').textContent = problem.detail
141             $('#step-2-collapse').collapse('show')
142             return false
143           }
144           $('#step-2-tick').show()
145           $('#step-2-cross').hide()
146           $('#step-2-spinner').hide()
147
148           document.getElementById('step-2-message').textContent = `Password reset link has been sent to "${email}". Please check your email for next steps.`
149           return true
150         }
151
152         document.addEventListener(
153           'DOMContentLoaded',
154           () => {
155             document.getElementById('step-1-continue').addEventListener(
156               'click',
157               async () => {
158                 if (await step_1() && await step_2())
159                   $('#step-2-collapse').collapse('show')
160               }
161             )
162
163             document.getElementById('step-2-back').addEventListener(
164               'click',
165               () => {$('#step-1-collapse').collapse('show')}
166             )
167
168             document.getElementById('step-2-resend-email').addEventListener(
169               'click',
170               async () => {
171                 if (await step_2())
172                   $('#step-3-collapse').collapse('show')
173               }
174             )
175           }
176         )
177       }
178     }
179   )
180 }