8781d25808475013c191f47442dfb20e0b4513a0
[ndcode_site.git] / _lib / navbar.jst
1 let assert = require('assert')
2 let XDate = require('xdate')
3
4 return async (env, head, body, scripts) => {
5   //let cart = await _require('/online_store/cart.jst')
6   let globals = await env.site.get_json('/_config/globals.json')
7   //let icon_cart_small = await env.site.get_min_svg('/_svg/icon_cart_small.svg')
8   let icon_search_mono = await env.site.get_min_svg('/_svg/icon_search_mono.svg')
9   let logo_large = await env.site.get_min_svg('/_svg/logo_large.svg')
10   let menu = await env.site.get_menu('/_menu.json')
11   let page = await _require('/_lib/page.jst')
12   //let session = await _require('/session.jst')
13
14   // initialize env.sessions, env.session_key, env.session
15   //await session(env)
16
17   // initialize env.cart
18   //await cart(env)
19
20   await page(
21     env,
22     // head
23     async _out => {
24       // extract top-level directory name
25       assert(env.parsed_url.pathname.slice(0, 1) === '/')
26       let index = env.parsed_url.pathname.indexOf('/', 1)
27       let dir = index === -1 ? '' : env.parsed_url.pathname.slice(1, index)
28
29       title {
30         _out.push(
31           globals.site_title + ': ' + (
32             dir.length === 0 ?
33             'Home' :
34             menu.entries[menu.index[dir]].name
35           )
36         )
37       }
38
39       await head(_out)
40     },
41     // body
42     async _out => {
43       // extract top-level directory name
44       assert(env.parsed_url.pathname.slice(0, 1) === '/')
45       let index = env.parsed_url.pathname.indexOf('/', 1)
46       let dir = index === -1 ? '' : env.parsed_url.pathname.slice(1, index)
47
48       div.scrollbar-fix {
49         div.container {
50           div.row.align-items-center.py-3 {
51             div.col-sm-8 {
52               _out.push(logo_large)
53             }
54             div.'col-sm-4' {
55               //div {
56               //  let signed_in =
57               //    Object.prototype.hasOwnProperty.call(env.session, 'account')
58               //  span#signed-in-status {
59               //    if (signed_in)
60               //      `Signed in as ${env.session.account}.`
61               //    else
62               //      'Browsing as guest.'
63               //  }
64               //  ' '
65               //  if (signed_in)
66               //    a#sign-in(href="" hidden="") {'Sign in'}
67               //  else
68               //    a#sign-in(href="") {'Sign in'}
69               //  ' '
70               //  if (signed_in)
71               //    a#sign-out(href="") {'Sign out'}
72               //  else
73               //    a#sign-out(href="" hidden="") {'Sign out'}
74               //}
75               //p {}
76   
77               form/*.form-inline*/(action="/search/index.html") {
78                 div.input-group {
79                   input.form-control(name="query" type="text" placeholder="Search" aria-describedby="search-button") {}
80                   div.input-group-append {
81                     button.btn.btn-outline-secondary#search-button(type="submit") {
82                       _out.push(icon_search_mono)
83                     }
84                   }
85                 }
86               }
87             }
88   
89             //div.'col-sm-1'.vbottom {
90             //  // a nested div is used to avoid hover colour on the padding
91             //  div.nav-li-a(style="text-align: center;") {
92             //    a(href="/online_store/view_cart/index.html") {
93             //      div.cart-icon {
94             //        _out.push(icon_cart_small)
95             //      }
96             //      div.cart-number {
97             //        div.cart-circle {
98             //          `${(env.cart.items || []).length}`
99             //        }
100             //      }
101             //    }
102             //  }
103             //}
104           }
105         }
106       }
107       nav.navbar.navbar-expand-lg.navbar-dark.bg-primary.scrollbar-fix {
108         div.container {
109           //a.navbar-brand(href="#") {'Navbar'}
110           //' '
111           button.navbar-toggler(type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation") {
112             span.navbar-toggler-icon {}
113           }
114           div.collapse.navbar-collapse#navbarSupportedContent {
115             ul.navbar-nav.mr-auto {
116               if (dir.length === 0)
117                 li.nav-item.active {
118                   a.nav-link(href="/index.html") {
119                     'Home'
120                     span.sr-only {' (current)'}
121                   }
122                 }
123               else
124                 li.nav-item {
125                   a.nav-link(href="/index.html") {'Home'}
126                 }
127               let entries = menu.entries
128               for (let i = 0; i < entries.length; ++i)
129                 if (entries[i].navbar)
130                   if (entries[i].dir === dir)
131                     li.nav-item.active {
132                       a.nav-link(href=`/${entries[i].dir}/index.html`) {
133                         `${entries[i].name}`
134                         span.sr-only {' (current)'}
135                       }
136                     }
137                   else
138                     li.nav-item {
139                       a.nav-link(href=`/${entries[i].dir}/index.html`) {
140                         `${entries[i].name}`
141                       }
142                     }
143               //li.nav-item.dropdown {
144               //  a.nav-link.dropdown-toggle#navbarDropdown(href="#" role="button" data-toggle="dropdown" aria-expanded="false") {
145               //    'Dropdown'
146               //  }
147               //  div.dropdown-menu(aria-labelledby="navbarDropdown") {
148               //    a.dropdown-item(href="#") {
149               //      'Action'
150               //    }
151               //    ' '
152               //    a.dropdown-item(href="#") {
153               //      'Another action'
154               //    }
155               //    div.dropdown-divider {}
156               //    a.dropdown-item(href="#") {
157               //      'Something else here'
158               //    }
159               //  }
160               //}
161               //li.nav-item {
162               //  a.nav-link.disabled {
163               //    'Disabled'
164               //  }
165               //}
166             }
167             ul.navbar-nav.ml-auto {
168               li.nav-item {
169                 a.nav-link#give-feedback(href="") {'Give feedback'}
170               }
171             }
172           }
173         }
174       }
175       div.scrollbar-fix {
176         div.container {
177           await body(_out)
178         }
179       }
180       footer.scrollbar-fix {
181         div.container {
182           a(rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/") {
183             img(alt="Creative Commons License" style="border-width:0;" src="/images/by-sa_3.0_88x31.png") {}
184           }
185           p {
186             'This website is '
187             a(href="https://git.ndcode.org/public/ndcode_site.git") {
188               'open source'
189             }
190             ' and licensed under a '
191             a(rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/") {
192               'Creative Commons Attribution-ShareAlike 3.0 Unported License'
193             }
194             '.'
195           }
196
197           p {'Example code fragments embedded within the text are placed in the public domain unless otherwise noted.'}
198
199           p {`Copyright © ${new XDate().getUTCFullYear()} ${globals.copyright}.`}
200         }
201       }
202
203       // hidden part
204       //div#sign-in-modal.modal.fade(role="dialog") {
205       //  div.modal-dialog {
206       //    div.modal-content {
207       //      div.modal-header {
208       //        span.h4.modal-title {'Sign in'}
209       //      }
210       //      div.modal-body {
211       //        form#sign-in-form(method="post" action="/sign_in.json" role="form") {
212       //          div.row {
213       //            div.col-md-12 {
214       //              div.form-group {
215       //                label(for="sign-in-form-email") {'Email'}
216       //                input.form-control#sign-in-form-email(type="text" name="email" placeholder="Please enter your email address" required="required" data-error="Email address is required.") {}
217       //                div.help-block.with-errors {}
218       //              }
219       //            }
220       //          }
221       //          div.row {
222       //            div.col-md-12 {
223       //              div.form-group {
224       //                label(for="sign-in-form-password") {'Password'}
225       //                input.form-control#sign-in-form-password(type="password" name="password" required="required" placeholder="Please enter your password" data-error="Password is required.") {}
226       //                div.help-block.with-errors {}
227       //              }
228       //            }
229       //          }
230       //          input.btn.btn-success.btn-send(style="display: none;" type="submit" value="Sign in") {}
231       //        }
232
233       //        p {
234       //          'No account yet? '
235       //          a(href="/my_account/sign_up/index.html") {'Sign up'}
236       //        }
237
238       //        p {
239       //          'Forgot password? '
240       //          a(href="/my_account/password_reset/index.html") {'Password reset'}
241       //        }
242       //      }
243       //      div.modal-footer {
244       //        button.btn.btn-primary(type="submit" form="sign-in-form") {
245       //          'Sign in'
246       //        }
247       //        button.btn.btn-outline-secondary(type="button" data-dismiss="modal") {
248       //          'Cancel'
249       //        }
250       //      }
251       //    }
252       //  }
253       //}
254
255       div#feedback-modal.modal.fade(role="dialog") {
256         div.modal-dialog {
257           div.modal-content {
258             div.modal-header {
259               span.h4.modal-title {'Give feedback'}
260             }
261             div.modal-body {
262               p {
263                 'Did you notice something not quite right, or just want to share your impression of this page?'
264               }
265               form#feedback-form(method="post" action="/feedback.html" role="form") {
266                 div.row {
267                   div.col-md-12 {
268                     div.form-group {
269                       label(for="feedback-form-message") {'Message *'}
270                       textarea.form-control#feedback-form-message(name="message" placeholder="Please tell us your thoughts" rows="4" required="required" data-error="Please, leave us a message.") {}
271                       div.help-block.with-errors {}
272                     }
273                   }
274                 }
275                 p {} // fix this later
276                 div.row {
277                   div.col-md-12 {
278                     p.text-muted {
279                       strong {'*'}
280                       'These fields are required.'
281                       //'Contact form template by '
282                       //a(href="https://bootstrapious.com/p/how-to-build-a-working-bootstrap-feedback-form" target="_blank") {'Bootstrapious'}
283                       //'.'
284                     }
285                   }
286                 }
287                 input.btn.btn-success.btn-send(style="display: none;" type="submit" value="Send message") {}
288               }
289             }
290             div.modal-footer {
291               button.btn.btn-primary(type="submit" form="feedback-form") {
292                 'Submit'
293               }
294               button.btn.btn-outline-secondary(type="button" data-dismiss="modal") {
295                 'Cancel'
296               }
297             }
298           }
299         }
300       }
301
302       div#message-modal.modal.fade(role="dialog") {
303         div.modal-dialog {
304           div.modal-content {
305             div.modal-header {
306               span.h4.modal-title {'Message'}
307             }
308             div.modal-body {
309               p#message-modal-message {}
310             }
311             div.modal-footer {
312               button.btn.btn-outline-secondary(type="button" data-dismiss="modal") {
313                 'Close'
314               }
315             }
316           }
317         }
318       }
319     },
320     // scripts
321     async _out => {
322       //script(src="/js/sha256.js") {}
323
324       script {
325         //function get_cookie(name) {
326         //  let entries = document.cookie.split(';');
327         //  for (let i = 0; i < entries.length; ++i) {
328         //    let fields = entries[i].split('=');
329         //    if (fields[0].trim() === name)
330         //      return decodeURIComponent(fields[1]);
331         //  }
332         //  return undefined;
333         //}
334
335         //// this function can be overridden in a further script
336         //function sign_in_out(status) {
337         //}
338
339         $(document).ready(
340           () => {
341             //// sign in form
342             //$('#sign-in').click(
343             //  () => {
344             //    $('#sign-in-form-email').text('')
345             //    $('#sign-in-form-password').text('')
346             //    $('#sign-in-modal').modal('show')
347             //    return false
348             //  }
349             //)
350             //$('#sign-in-modal').on(
351             //  'shown.bs.modal',
352             //  () => {
353             //    $('#sign-in-form-email').focus()
354             //  }
355             //)
356             //// when sign in form is submitted, do not reload the page
357             //$(document).on(
358             //  'submit',
359             //  '#sign-in-form',
360             //  e => {
361             //    e.preventDefault()
362             //    $.ajax(
363             //      {
364             //        url: '/my_account/sign_in.json',
365             //        type: 'POST',
366             //        data: {
367             //          email: $('#sign-in-form-email').val(),
368             //          password: sha256(
369             //            get_cookie('session_key') +
370             //            $('#sign-in-form-password').val()
371             //          ).toString('hex')
372             //        },
373             //        success: (data, textStatus, jqXHR) => {
374             //          $('#sign-in-modal').modal('hide')
375             //          switch (data.result) {
376             //          case 1: // success
377             //            $('#signed-in-status').text(data.signed_in_status)
378             //            $('#sign-in').hide()
379             //            $('#sign-out').show()
380             //            sign_in_out(true) // notify navbar caller
381             //            break
382             //          case 2: // redirect
383             //            location.href = data.redirect_href
384             //            break
385             //          }
386             //          $('#message-modal-message').text(data.message)
387             //          $('#message-modal').modal('show')
388             //        },
389             //        error: (jqXHR, textStatus, errorThrown) => {
390             //          $('#sign-in-modal').modal('hide')
391             //          $('#message-modal-message').text(errorThrown)
392             //          $('#message-modal').modal('show')
393             //        }
394             //      }
395             //    )
396             //  }
397             //)
398
399             //// sign out button
400             //$('#sign-out').click(
401             //  () => {
402             //    $.ajax(
403             //      {
404             //        url: '/my_account/sign_out.json',
405             //        type: 'GET',
406             //        success: (data, textStatus, jqXHR) => {
407             //          if (data.result) {
408             //            $('#signed-in-status').text(data.signed_in_status)
409             //            $('#sign-in').show()
410             //            $('#sign-out').hide()
411             //            sign_in_out(false) // notify navbar caller
412             //          }
413             //          $('#message-modal-message').text(data.message)
414             //          $('#message-modal').modal('show')
415             //        },
416             //        error: (jqXHR, textStatus, errorThrown) => {
417             //          $('#message-modal-message').text(errorThrown)
418             //          $('#message-modal').modal('show')
419             //        }
420             //      }
421             //    )
422             //    return false
423             //  }
424             //)
425
426             // feedback form
427             $('#give-feedback').click(
428               () => {
429                 $('#feedback-form-message').text('')
430                 $('#feedback-modal').modal('show')
431                 return false
432               }
433             )
434             $('#feedback-modal').on(
435               'shown.bs.modal',
436               () => {
437                 $('#feedback-form-message').focus()
438               }
439             )
440             // when feedback form is submitted, do not reload the page
441             $(document).on(
442               'submit',
443               '#feedback-form',
444               e => {
445                 e.preventDefault()
446                 $.ajax(
447                   {
448                     url: '/feedback.html',
449                     type: 'POST',
450                     data: {
451                       page: window.location.href,
452                       message: $('#feedback-form-message').val()
453                     },
454                     success: (data, textStatus, jqXHR) => {
455                       $('#feedback-modal').modal('hide')
456                       $('#message-modal-message').text(data)
457                       $('#message-modal').modal('show')
458                     },
459                     error: (jqXHR, textStatus, errorThrown) => {
460                       $('#feedback-modal').modal('hide')
461                       $('#message-modal-message').text(errorThrown)
462                       $('#message-modal').modal('show')
463                     }
464                   }
465                 )
466               }
467             )
468           }
469         )
470       }
471
472       await scripts(_out)
473     }
474   )
475 }