App.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <!--
  2. Copyright 2019 Hackware SpA <human@hackware.cl>
  3. This file is part of "Hackware Userland" and licensed under the terms
  4. of the GNU Affero General Public License version 3, or (at your option)
  5. a later version. You should have received a copy of this license along
  6. with the software. If not, see <https://www.gnu.org/licenses/>.
  7. -->
  8. <template>
  9. <div id="app">
  10. <button
  11. v-if="$auth.isLoggedIn()"
  12. id="toggle_sidebar"
  13. :class="{ 'show-sidebar': showSidebar }"
  14. @click="toggleSidebar"
  15. >
  16. <i class="fas fa-bars" />
  17. </button>
  18. <nav
  19. v-if="$auth.isLoggedIn()"
  20. id="sidebar"
  21. :class="{ 'show-sidebar': showSidebar }"
  22. >
  23. <div id="user_info">
  24. <img
  25. alt="User avatar"
  26. src="@/assets/avatar.png"
  27. >
  28. <h5>{{ $auth.user.display_name || $auth.user.email }}</h5>
  29. </div>
  30. <ul id="nav_menu">
  31. <li>
  32. <router-link :to="{ name: 'wallet' }">
  33. Mi billetera
  34. <i class="fas fa-wallet" />
  35. </router-link>
  36. </li>
  37. <li>
  38. <router-link :to="{ name: 'transactions' }">
  39. Mis transacciones
  40. <i class="fas fa-history" />
  41. </router-link>
  42. </li>
  43. <li>
  44. <router-link :to="{ name: 'add-funds-payment' }">
  45. Añadir fondos
  46. <i class="fas fa-plus-square" />
  47. </router-link>
  48. </li>
  49. </ul>
  50. <div class="flex-spacer" />
  51. <ul id="sub_menu">
  52. <li>
  53. <a
  54. id="userland_sourcecode"
  55. href="https://git.hackware.cl/userland"
  56. target="_blank"
  57. title="¡Hackware Userland es software libre!"
  58. >
  59. <i class="fas fa-code" />
  60. </a>
  61. </li>
  62. <li>
  63. <form @submit.prevent="submitLogout">
  64. <button
  65. id="btnLogout"
  66. type="submit"
  67. title="Salir"
  68. >
  69. <i class="fas fa-sign-out-alt" />
  70. </button>
  71. </form>
  72. </li>
  73. </ul>
  74. </nav>
  75. <main :class="{ 'show-sidebar': showSidebar }">
  76. <router-view
  77. class="container-fluid"
  78. @login="initSidebar"
  79. />
  80. </main>
  81. </div>
  82. </template>
  83. <script>
  84. export default {
  85. data() {
  86. return {
  87. showSidebar: false,
  88. };
  89. },
  90. mounted() {
  91. this.initSidebar();
  92. },
  93. methods: {
  94. initSidebar() {
  95. setTimeout(() => { // FIXME: Should trigger after all components have been loaded
  96. if (!this.isSmallScreen() && this.$auth.isLoggedIn()) {
  97. this.showSidebar = true;
  98. } else {
  99. this.showSidebar = false;
  100. }
  101. }, 500);
  102. },
  103. isSmallScreen() {
  104. const minWidth = getComputedStyle(document.body)
  105. .getPropertyValue('--breakpoint-sm')
  106. .match(/\d+/)[0];
  107. return window.screen.width < minWidth;
  108. },
  109. toggleSidebar() {
  110. this.showSidebar = !this.showSidebar;
  111. },
  112. submitLogout() {
  113. this.showSidebar = false;
  114. this.$fetcher.hawesePost('/auth/logout')
  115. .then(() => {
  116. this.$auth.logout();
  117. this.$router.push({ name: 'login-by-password' });
  118. });
  119. },
  120. },
  121. };
  122. </script>
  123. <style lang="scss">
  124. @import "assets/bootstrap/custom";
  125. $sidebar-width: 18rem;
  126. nav#sidebar {
  127. &.show-sidebar {
  128. transform: translateX($sidebar-width);
  129. }
  130. position: fixed;
  131. display: flex;
  132. flex-direction: column;
  133. transition: all 300ms ease;
  134. left: -$sidebar-width;
  135. height: 100%;
  136. overflow: hidden auto;
  137. width: $sidebar-width;
  138. background-color: var(--dark);
  139. color: var(--light);
  140. text-align: right;
  141. > #user_info {
  142. @extend .p-3;
  143. @extend .pt-5;
  144. color: var(--light);
  145. > img {
  146. @extend .mb-2;
  147. object-fit: cover;
  148. width: 100px;
  149. }
  150. }
  151. > ul#nav_menu {
  152. @extend .nav;
  153. @extend .flex-column;
  154. &:hover > li > a.router-link-active {
  155. background-color: transparent;
  156. }
  157. > li {
  158. @extend .nav-item;
  159. > a {
  160. @extend .nav-link;
  161. transition: all 300ms ease;
  162. color: var(--gray);
  163. padding: ($spacer * 0.75) $spacer;
  164. > i.fas, > i.fab {
  165. margin-left: map-get($spacers, 2);
  166. }
  167. &:hover, &.router-link-active, &.router-link-active:hover {
  168. background-color: $black;
  169. color: var(--light);
  170. }
  171. }
  172. }
  173. }
  174. > .flex-spacer {
  175. flex-grow: 1;
  176. }
  177. > ul#sub_menu {
  178. @extend .nav;
  179. @extend .justify-content-center;
  180. > li {
  181. @extend .nav-item;
  182. > a, > form > button#btnLogout {
  183. @extend .nav-link;
  184. color: var(--gray);
  185. &:hover {
  186. color: var(--light);
  187. }
  188. }
  189. }
  190. button#btnLogout {
  191. @extend .btn;
  192. @extend .btn-link;
  193. }
  194. }
  195. }
  196. button#toggle_sidebar {
  197. @extend .btn;
  198. @extend .btn-sm;
  199. @extend .btn-dark;
  200. color: var(--light);
  201. width: 30px;
  202. left: 0;
  203. position: absolute;
  204. opacity: .2;
  205. transition: all 300ms ease;
  206. z-index: 100;
  207. &:hover {
  208. opacity: 1;
  209. }
  210. &.show-sidebar {
  211. left: $sidebar-width;
  212. }
  213. }
  214. main {
  215. transition: all 300ms ease;
  216. @include media-breakpoint-down(xs) {
  217. min-width: 100%;
  218. }
  219. &.show-sidebar {
  220. margin-left: $sidebar-width;
  221. }
  222. }
  223. </style>