ViewReport.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. <template>
  2. <modal title="View Report">
  3. <template #body v-if="report && report._id">
  4. <router-link
  5. v-if="$route.query.returnToSong"
  6. class="button is-dark back-to-song"
  7. :to="{
  8. path: '/admin/songs',
  9. query: { id: report.youtubeId }
  10. }"
  11. >
  12. <i class="material-icons">keyboard_return</i> &nbsp; Edit Song
  13. </router-link>
  14. <article class="message">
  15. <div class="message-body">
  16. <strong>Song ID:</strong>
  17. {{ report.song.youtubeId }} / {{ report.song._id }}
  18. <br />
  19. <strong>Author:</strong>
  20. <user-id-to-username
  21. :user-id="report.createdBy"
  22. :alt="report.createdBy"
  23. />
  24. <br />
  25. <strong>Time of report:</strong>
  26. <span
  27. :content="report.createdAt"
  28. v-tippy="{ theme: 'info' }"
  29. >
  30. {{
  31. formatDistance(
  32. new Date(report.createdAt),
  33. new Date(),
  34. {
  35. addSuffix: true
  36. }
  37. )
  38. }}
  39. </span>
  40. <br />
  41. <span>
  42. <strong>Issues:</strong>
  43. <ul id="issues">
  44. <li
  45. v-for="(issue, index) in report.issues"
  46. :key="index"
  47. >
  48. <strong> {{ issue.category }}:</strong>
  49. {{ issue.info }}
  50. </li>
  51. </ul>
  52. </span>
  53. </div>
  54. </article>
  55. </template>
  56. <template #footer v-if="report && report._id">
  57. <a class="button is-primary" href="#" @click="resolve(report._id)">
  58. <span>Resolve</span>
  59. </a>
  60. <a
  61. class="button is-primary"
  62. :href="`/admin/songs?songId=${report.song._id}`"
  63. target="_blank"
  64. >
  65. <span>Go to song</span>
  66. </a>
  67. </template>
  68. </modal>
  69. </template>
  70. <script>
  71. import { mapActions, mapGetters, mapState } from "vuex";
  72. import { formatDistance } from "date-fns";
  73. import Toast from "toasters";
  74. import UserIdToUsername from "../UserIdToUsername.vue";
  75. import Modal from "../Modal.vue";
  76. export default {
  77. components: { Modal, UserIdToUsername },
  78. props: {
  79. reportId: { type: String, default: "" },
  80. sector: { type: String, default: "admin" }
  81. },
  82. computed: {
  83. ...mapState("modals/viewReport", {
  84. report: state => state.report
  85. }),
  86. ...mapGetters({
  87. socket: "websockets/getSocket"
  88. })
  89. },
  90. mounted() {
  91. if (this.$route.query.returnToSong) {
  92. this.closeModal("editSong");
  93. }
  94. this.socket.dispatch(`reports.findOne`, this.reportId, res => {
  95. if (res.status === "success") {
  96. const { report } = res.data;
  97. this.viewReport(report);
  98. } else {
  99. new Toast("Report with that ID not found");
  100. this.closeModal("viewReport");
  101. }
  102. });
  103. },
  104. methods: {
  105. formatDistance,
  106. resolve(reportId) {
  107. return this.resolveReport(reportId)
  108. .then(res => {
  109. if (res.status === "success") this.closeModal("viewReport");
  110. })
  111. .catch(err => new Toast(err.message));
  112. },
  113. ...mapActions("modals/viewReport", ["viewReport", "resolveReport"]),
  114. ...mapActions("modalVisibility", ["closeModal"])
  115. }
  116. };
  117. </script>
  118. <style lang="scss" scoped>
  119. .night-mode {
  120. .message,
  121. .table {
  122. color: var(--light-grey-2);
  123. background-color: var(--dark-grey-3);
  124. }
  125. .table tr:hover {
  126. filter: brightness(95%);
  127. }
  128. }
  129. .back-to-song {
  130. display: flex;
  131. margin-bottom: 20px;
  132. }
  133. #issues {
  134. list-style: inside;
  135. }
  136. </style>