Show.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <template>
  2. <div v-if="isUser">
  3. <metadata v-bind:title="`Profile | ${user.username}`" />
  4. <main-header />
  5. <div class="container">
  6. <img class="avatar" src="/assets/notes.png" />
  7. <h2 class="has-text-centered username">@{{ user.username }}</h2>
  8. <h5>A member since {{ user.createdAt }}</h5>
  9. <div
  10. v-if="role === 'admin' && userId !== user._id"
  11. class="admin-functionality"
  12. >
  13. <a
  14. v-if="user.role == 'default'"
  15. class="button is-small is-info is-outlined"
  16. @click="changeRank('admin')"
  17. >Promote to Admin</a
  18. >
  19. <a
  20. v-if="user.role == 'admin'"
  21. class="button is-small is-danger is-outlined"
  22. @click="changeRank('default')"
  23. >Demote to User</a
  24. >
  25. </div>
  26. <nav class="level">
  27. <div class="level-item has-text-centered">
  28. <p class="heading">
  29. Rank
  30. </p>
  31. <p class="title role">
  32. {{ user.role }}
  33. </p>
  34. </div>
  35. <div class="level-item has-text-centered">
  36. <p class="heading">
  37. Songs Requested
  38. </p>
  39. <p class="title">
  40. {{ user.statistics.songsRequested }}
  41. </p>
  42. </div>
  43. <div class="level-item has-text-centered">
  44. <p class="heading">
  45. Likes
  46. </p>
  47. <p class="title">
  48. {{ user.liked.length }}
  49. </p>
  50. </div>
  51. <div class="level-item has-text-centered">
  52. <p class="heading">
  53. Dislikes
  54. </p>
  55. <p class="title">
  56. {{ user.disliked.length }}
  57. </p>
  58. </div>
  59. </nav>
  60. </div>
  61. <main-footer />
  62. </div>
  63. </template>
  64. <script>
  65. import { mapState } from "vuex";
  66. import Toast from "toasters";
  67. import { format, parseISO } from "date-fns";
  68. import MainHeader from "../MainHeader.vue";
  69. import MainFooter from "../MainFooter.vue";
  70. import io from "../../io";
  71. export default {
  72. components: { MainHeader, MainFooter },
  73. data() {
  74. return {
  75. user: {},
  76. isUser: false
  77. };
  78. },
  79. computed: mapState({
  80. role: state => state.user.auth.role,
  81. userId: state => state.user.auth.userId
  82. }),
  83. mounted() {
  84. io.getSocket(socket => {
  85. this.socket = socket;
  86. this.socket.emit(
  87. "users.findByUsername",
  88. this.$route.params.username,
  89. res => {
  90. if (res.status === "error") this.$router.go("/404");
  91. else {
  92. this.user = res.data;
  93. this.user.createdAt = format(
  94. parseISO(this.user.createdAt),
  95. "MMMM do yyyy"
  96. );
  97. this.isUser = true;
  98. }
  99. }
  100. );
  101. });
  102. },
  103. methods: {
  104. changeRank(newRank) {
  105. this.socket.emit(
  106. "users.updateRole",
  107. this.user._id,
  108. newRank === "admin" ? "admin" : "default",
  109. res => {
  110. if (res.status === "error")
  111. new Toast({ content: res.message, timeout: 2000 });
  112. else this.user.role = newRank;
  113. new Toast({
  114. content: `User ${this.$route.params.username}'s rank has been changed to: ${newRank}`,
  115. timeout: 2000
  116. });
  117. }
  118. );
  119. }
  120. }
  121. };
  122. </script>
  123. <style lang="scss" scoped>
  124. @import "styles/global.scss";
  125. .container {
  126. padding: 25px;
  127. }
  128. .avatar {
  129. border-radius: 50%;
  130. width: 250px;
  131. display: block;
  132. margin: auto;
  133. }
  134. h5 {
  135. text-align: center;
  136. margin-bottom: 25px;
  137. font-size: 17px;
  138. }
  139. .role {
  140. text-transform: capitalize;
  141. }
  142. .level {
  143. margin-top: 40px;
  144. }
  145. .admin-functionality {
  146. text-align: center;
  147. margin: 0 auto;
  148. }
  149. @media (max-width: 350px) {
  150. .username {
  151. font-size: 2.9rem;
  152. word-wrap: break-all;
  153. }
  154. }
  155. </style>