ViewReport.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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>Category:</strong>
  43. {{ report.category }}
  44. </span>
  45. <br />
  46. <span>
  47. <strong>Info:</strong>
  48. {{ report.info }}
  49. </span>
  50. </div>
  51. </article>
  52. </template>
  53. <template #footer v-if="report && report._id">
  54. <a class="button is-primary" href="#" @click="resolve(report._id)">
  55. <span>Resolve</span>
  56. </a>
  57. <a
  58. class="button is-primary"
  59. :href="`/admin/songs?songId=${report.song._id}`"
  60. target="_blank"
  61. >
  62. <span>Go to song</span>
  63. </a>
  64. </template>
  65. </modal>
  66. </template>
  67. <script>
  68. import { mapActions, mapGetters, mapState } from "vuex";
  69. import { formatDistance } from "date-fns";
  70. import Toast from "toasters";
  71. import UserIdToUsername from "../UserIdToUsername.vue";
  72. import Modal from "../Modal.vue";
  73. export default {
  74. components: { Modal, UserIdToUsername },
  75. props: {
  76. reportId: { type: String, default: "" },
  77. sector: { type: String, default: "admin" }
  78. },
  79. computed: {
  80. ...mapState("modals/viewReport", {
  81. report: state => state.report
  82. }),
  83. ...mapGetters({
  84. socket: "websockets/getSocket"
  85. })
  86. },
  87. mounted() {
  88. if (this.$route.query.returnToSong) {
  89. this.closeModal("editSong");
  90. }
  91. this.socket.dispatch(`reports.findOne`, this.reportId, res => {
  92. if (res.status === "success") {
  93. const { report } = res.data;
  94. this.viewReport(report);
  95. } else {
  96. new Toast("Report with that ID not found");
  97. this.closeModal("viewReport");
  98. }
  99. });
  100. },
  101. methods: {
  102. formatDistance,
  103. resolve(reportId) {
  104. return this.resolveReport(reportId)
  105. .then(res => {
  106. if (res.status === "success") this.closeModal("viewReport");
  107. })
  108. .catch(err => new Toast(err.message));
  109. },
  110. ...mapActions("modals/viewReport", ["viewReport", "resolveReport"]),
  111. ...mapActions("modalVisibility", ["closeModal"])
  112. }
  113. };
  114. </script>
  115. <style lang="scss" scoped>
  116. .night-mode {
  117. .message,
  118. .table {
  119. color: var(--light-grey-2);
  120. background-color: var(--dark-grey-3);
  121. }
  122. .table tr:hover {
  123. filter: brightness(95%);
  124. }
  125. }
  126. .back-to-song {
  127. display: flex;
  128. margin-bottom: 20px;
  129. }
  130. </style>