You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

base.html 9.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. <!--
  2. # @name: base.html
  3. # @version: 0.1
  4. # @creation_date: 2021-10-20
  5. # @license: The MIT License <https://opensource.org/licenses/MIT>
  6. # @author: Simon Bowie <ad7588@coventry.ac.uk>
  7. # @purpose: Basic layout for all pages
  8. # @acknowledgements:
  9. # https://www.digitalocean.com/community/tutorials/how-to-make-a-web-application-using-flask-in-python-3
  10. # Bootstrap 5.1.3: https://getbootstrap.com/
  11. # Flask-Moment: https://flask-moment.readthedocs.io/en/latest/
  12. # Boostrap select: https://stackoverflow.com/questions/67942546/bootstrap-5-select-dropdown-with-the-multiple-attribute-collapsed
  13. -->
  14. {% macro popup_link(title,url) %}
  15. <a href="{{ url }}" class="nav-link">
  16. {{ title }}
  17. </a>
  18. {% endmacro %}
  19. {% macro resource_lead(type, title, leadtext, url, year, thumbnail='', large_title=false) %}
  20. <div class="relative cell h-full">
  21. <a
  22. class="block cursor-pointer"
  23. href="{{ url }}"
  24. hx-target="#modal-content"
  25. hx-select="main"
  26. hx-swap="innerHTML"
  27. @click="openModal()"
  28. >
  29. {% if large_title %}
  30. <h2 class="">{{ title }}</h2>
  31. {% else %}
  32. <h3 class="">{{ title }}</h3>
  33. {% endif %}
  34. {% if year %}
  35. <div class="">{{ year }}</div>
  36. {% endif %}
  37. {% if type == 'book' and thumbnail %}
  38. <img class="w-40 h-40 object-contain float-right m-16 grayscale rotate-[15deg]" src={{ book['thumbnail'] }} alt="cover for {{ title }}">
  39. {% endif %}
  40. <div class="">
  41. {{ leadtext | truncate(100) }}
  42. </div>
  43. </a>
  44. {% if current_user.is_authenticated %}
  45. <div class="">
  46. {% if resource['type'] == 'tool' %}
  47. <a href="{{ url_for('tool.edit_tool', tool_id=resource['id']) }}">
  48. <span class="absolute top-0 left-0 text-xs">Edit</span>
  49. </a>
  50. {% elif resource['type'] == 'practice' %}
  51. <a href="{{ url_for('practice.edit_practice', practice_id=resource['id']) }}">
  52. <span class="absolute top-0 left-0 text-xs">Edit</span>
  53. </a>
  54. {% elif resource['type'] == 'book' %}
  55. <a href="{{ url_for('book.edit_book', book_id=resource['id']) }}">
  56. <span class="absolute top-0 left-0 text-xs">Edit</span>
  57. </a>
  58. {% endif %}
  59. </div>
  60. {% endif %}
  61. </div>
  62. {% endmacro %}
  63. {% macro resource_small(resource) %}
  64. {% if resource['type'] == 'tool' %}
  65. {{
  66. resource_lead(
  67. resource['type'],
  68. resource['name'],
  69. resource['description'],
  70. url_for('tool.show_tool',
  71. tool_id=resource['id']),
  72. null,
  73. '',
  74. true
  75. )
  76. }}
  77. {% elif resource['type'] == 'practice' %}
  78. {{
  79. resource_lead(
  80. resource['type'],
  81. resource['name'],
  82. resource['description'],
  83. url_for('practice.show_practice',
  84. practice_id=resource['id']),
  85. null
  86. )
  87. }}
  88. {% elif resource['type'] == 'book' %}
  89. {{
  90. resource_lead(
  91. resource['type'],
  92. resource['name'],
  93. resource['author'],
  94. url_for('book.show_book',
  95. book_id=resource['id']),
  96. null,
  97. resource['thumbnail'],
  98. true
  99. )
  100. }}
  101. {% endif %}
  102. {% endmacro %}
  103. <!DOCTYPE html>
  104. <html>
  105. <head>
  106. {{ moment.include_moment() }}
  107. <meta charset="utf-8">
  108. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  109. <meta name="viewport" content="width=device-width, initial-scale=1">
  110. <script src="https://unpkg.com/htmx.org@1.8.6"></script>
  111. <script src="//unpkg.com/alpinejs" defer></script>
  112. <title>ExPub Compendium</title>
  113. <link href="{{ url_for('static',filename='styles/main.css') }}" rel="stylesheet">
  114. </head>
  115. <script>
  116. // htmx.on('htmx:beforeRequest', e=> {
  117. // console.log(e)
  118. // })
  119. // htmx.logAll()
  120. function base() {
  121. return {
  122. menuOpen: false,
  123. modalOpen: false,
  124. showRelated: false,
  125. home: '/',
  126. hideIfBase() {
  127. let str = document.location.toString();
  128. str = str.replace('http://', '');
  129. str = str.replace('https://', '');
  130. let l = str.split('/').length-1;
  131. if(l<2) {
  132. this.modalOpen = false;
  133. }
  134. return l;
  135. },
  136. init() {
  137. this.$watch('document.location', (value, oldValue) => {
  138. console.log('new url', value);
  139. });
  140. window.addEventListener('popstate', e => {
  141. this.hideIfBase();
  142. });
  143. },
  144. hideOverlay() {
  145. this.modalOpen = false;
  146. // window.history.pushState({}, '', this.home);
  147. },
  148. openModal() {
  149. // this.$refs.modal.innerHTML = '';
  150. this.modalOpen = true;
  151. let mc = document.querySelector('#modal-content');
  152. mc.scrollTo(0,0);
  153. }
  154. }
  155. }
  156. </script>
  157. <body
  158. class="text-base overflow-y-scroll"
  159. x-data="base()"
  160. hx-boost="true"
  161. hx-select="#all"
  162. hx-target="#all"
  163. hx-swap="outerHTML"
  164. hx-indicator="body"
  165. >
  166. <div id="loading" class="loading">
  167. <div class="pointer-events-none fixed top-0 left-0 w-full h-screen z-50 flex justify-center items-center p-4">
  168. <div class="rounded-full bg-black text-white p-4 ">
  169. Loading...
  170. </div>
  171. </div>
  172. </div>
  173. <div id="all">
  174. <header class="sticky top-0 z-10 bg-white std-padding border-b-[3px] border-black">
  175. <nav class="">
  176. <div class="lg:flex gap-2 mb-2">
  177. <a class="link leading-tight" href="{{ url_for('main.index') }}">ExPub<br>Compendium</a>
  178. <a href="{{ url_for('main.about') }}" class="{{ 'active' if request.path == url_for('main.about') }} ml-auto link">
  179. About
  180. </a>
  181. {% if current_user.is_authenticated %}
  182. <a href="{{ url_for('create.create_resource') }}" class="link">
  183. Add resource
  184. </a>
  185. {% endif %}
  186. {% if current_user.is_authenticated %}
  187. <a href="{{ url_for('main.profile') }}" class="link">
  188. Profile
  189. </a>
  190. {% endif %}
  191. {% if not current_user.is_authenticated %}
  192. <a href="{{ url_for('auth.login') }}" class="link">
  193. Login
  194. </a>
  195. <a href="{{ url_for('auth.signup') }}" class="link">
  196. Sign Up
  197. </a>
  198. {% endif %}
  199. {% if current_user.is_authenticated %}
  200. <a href="{{ url_for('auth.logout') }}" class="link">
  201. Logout
  202. </a>
  203. {% endif %}
  204. </div>
  205. <h2 class="flex gap-4 ">
  206. <a href="{{ url_for('tool.get_tools') }}" class=" link align-bottom">
  207. Tools
  208. </a>
  209. <a href="{{ url_for('practice.get_practices') }}" class="link">
  210. Practices
  211. </a>
  212. <a href="{{ url_for('book.get_books') }}" class="link">
  213. Books
  214. </a>
  215. <input class="ml-auto text-base border-2 border-black p-1 " type="text" placeholder="Search">
  216. </h2>
  217. </nav>
  218. </header>
  219. <!-- Begin page content -->
  220. <main>
  221. {% with messages = get_flashed_messages() %}
  222. {% if messages %}
  223. <div class="alert alert-danger">
  224. {{ messages[0] }}
  225. </div>
  226. {% endif %}
  227. {% endwith %}
  228. {% block content %}
  229. {% endblock %}
  230. </main>
  231. </div>
  232. <div id="modal" x-show="modalOpen" class="modal h-screen w-full fixed top-0 z-20 p-8 bg-black/20 overscroll-none">
  233. <div class="cross cursor-pointer absolute top-10 right-10 w-10 h-10" @click="hideOverlay()">
  234. <svg width="100%" height="100%" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
  235. <path d="M2 2L18 18M18 2L2 18" stroke="black" stroke-width="1"></path>
  236. </svg>
  237. </div>
  238. <div id="modal-content" @click.outside="hideOverlay()" x-ref="modal" class="content w-full overflow-y-scroll h-full bg-white " style="box-shadow:0 0 4rem rgba(0,0,0,0.3)">
  239. </div>
  240. </div>
  241. <!-- Sticky footer-->
  242. <footer class="std-margin mt-20 text-sm">
  243. <div class="container">
  244. <span class="">© 2022–{{ moment().format('YYYY') }} <a href="https://copim.ac.uk/">COPIM</a> and licensed under a <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License (CC BY 4.0)</a>.</span>
  245. </div>
  246. </footer>
  247. <!-- JavaScript -->
  248. <!-- jQuery first, then Popper JS, then Bootstrap JS -->
  249. <script src="{{ url_for('static',filename='js/main.js') }}"></script>
  250. </body>
  251. </html>