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