AdminModerationBannedUsers.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. <template>
  2. <div class='admin_moderation'>
  3. <div class='admin_moderation__header'>
  4. <moderation-header selected-tab='bans'></moderation-header>
  5. <button class='button button--blue' @click='toggleShowAddNewBanModal'>Add new ban</button>
  6. </div>
  7. <transition name='fade' mode='out-in'>
  8. <loading-message v-if='!bans' key='loading'></loading-message>
  9. <table class='admin_moderation__table' v-else-if='bans.length' key='bans'>
  10. <tr>
  11. <th>User</th>
  12. <th>Ban type</th>
  13. <th>Date banned</th>
  14. <th>Message</th>
  15. <th>Action</th>
  16. </tr>
  17. <tr v-for='(ban, $index) in bans'>
  18. <td>{{ban.User.username}}</td>
  19. <td>{{ban.type}}</td>
  20. <td>{{ban.createdAt | formatDate}}</td>
  21. <td>
  22. <template v-if='ban.message'>{{ban.message}}</template>
  23. <i v-else>No message given</i>
  24. </td>
  25. <td>
  26. <button
  27. class='button button--red'
  28. @click='deleteBan(ban, $index)'
  29. >
  30. Delete ban
  31. </button>
  32. </td>
  33. </tr>
  34. </table>
  35. <div class='overlay_message' v-else key='no bans'>
  36. <span class='fa fa-thumbs-up'></span>
  37. No banned users
  38. </div>
  39. </transition>
  40. <modal-window v-model='$store.state.moderation.showAddNewBanModal' width='30rem'>
  41. <div class='admin_moderation__add_new_ban_modal'>
  42. <div
  43. class='admin_moderation__add_new_ban_modal__overlay'
  44. :class='{ "admin_moderation__add_new_ban_modal__overlay--show": loading }'
  45. >
  46. <loading-icon></loading-icon>
  47. </div>
  48. <h2>Ban or block a user</h2>
  49. <p>Search for the user to ban, then select the relevant ban type for the user</p>
  50. <div>
  51. <fancy-input
  52. placeholder='Username to ban'
  53. v-model='$store.state.moderation.username'
  54. width='15rem'
  55. :large='true'
  56. ></fancy-input>
  57. </div>
  58. <div>
  59. <fancy-input
  60. placeholder='Message to user (optional)'
  61. v-model='$store.state.moderation.message'
  62. width='15rem'
  63. :large='true'
  64. ></fancy-input>
  65. </div>
  66. <div>
  67. <select-button
  68. :options='$store.state.moderation.options'
  69. name='test'
  70. v-model='$store.state.moderation.selectedOption'
  71. >
  72. </select-button>
  73. </div>
  74. <div>
  75. <button class='button button--modal button--borderless' @click='toggleShowAddNewBanModal'>Cancel</button>
  76. <button class='button button--modal button--green' @click='addBan'>Add ban</button>
  77. </div>
  78. </div>
  79. </modal-window>
  80. </div>
  81. </template>
  82. <script>
  83. import TabView from '../TabView'
  84. import ModalWindow from '../ModalWindow'
  85. import FancyInput from '../FancyInput'
  86. import SelectButton from '../SelectButton'
  87. import MenuButton from '../MenuButton'
  88. import AvatarIcon from '../AvatarIcon'
  89. import ConfirmModal from '../ConfirmModal'
  90. import ModerationHeader from '../ModerationHeader'
  91. import LoadingIcon from '../LoadingIcon'
  92. import LoadingMessage from '../LoadingMessage'
  93. import AjaxErrorHandler from '../../assets/js/errorHandler'
  94. export default {
  95. name: 'AdminDashboard',
  96. components: {
  97. TabView,
  98. ModalWindow,
  99. FancyInput,
  100. SelectButton,
  101. MenuButton,
  102. AvatarIcon,
  103. ConfirmModal,
  104. ModerationHeader,
  105. LoadingIcon,
  106. LoadingMessage
  107. },
  108. data () {
  109. return {
  110. loading: false,
  111. bans_: null
  112. }
  113. },
  114. computed: {
  115. bans () {
  116. if(!this.bans_) return null
  117. return this.bans_.map(ban => {
  118. if(ban.ipBanned) {
  119. ban.type = 'IP banned'
  120. } else if (ban.canCreateThreads && !ban.canCreatePosts) {
  121. ban.type = 'Posting replies'
  122. } else if(ban.canCreatePosts && !ban.canCreateThreads) {
  123. ban.type = 'Creating threads'
  124. } else {
  125. ban.type = 'Posting replies and creating threads'
  126. }
  127. return ban
  128. })
  129. }
  130. },
  131. methods: {
  132. toggleShowAddNewBanModal () {
  133. this.$store.commit(
  134. 'moderation/setModal',
  135. !this.$store.state.moderation.showAddNewBanModal
  136. )
  137. this.$store.dispatch('moderation/clearModal')
  138. },
  139. addBan () {
  140. let store = this.$store.state.moderation
  141. let obj = { username: store.username }
  142. if(store.message.trim().length) {
  143. obj.message = store.message
  144. }
  145. if(store.selectedOption === 'both') {
  146. obj.canCreatePosts = false
  147. obj.canCreateThreads = false
  148. } else if(store.selectedOption === 'thread') {
  149. obj.canCreateThreads = false
  150. } else if(store.selectedOption === 'post') {
  151. obj.canCreatePosts = false
  152. } else {
  153. obj.ipBanned = true
  154. }
  155. this.loading = true
  156. this.axios
  157. .post('/api/v1/ban', obj)
  158. .then(res => {
  159. this.loading = false
  160. this.bans_.push(res.data)
  161. this.toggleShowAddNewBanModal()
  162. this.$store.dispatch('moderation/clearModal')
  163. })
  164. .catch(e => {
  165. this.loading = false
  166. AjaxErrorHandler(this.$store)(e)
  167. })
  168. },
  169. deleteBan (ban, index) {
  170. this.axios
  171. .delete('/api/v1/ban/' + ban.id)
  172. .then(res => {
  173. this.bans_.splice(index, 1)
  174. })
  175. .catch(AjaxErrorHandler(this.$store))
  176. }
  177. },
  178. mounted () {
  179. this.$store.dispatch('setTitle', 'admin | moderation')
  180. this.axios
  181. .get('/api/v1/ban')
  182. .then(res => {
  183. this.bans_ = res.data
  184. })
  185. .catch(AjaxErrorHandler(this.$store))
  186. }
  187. }
  188. </script>
  189. <style lang='scss' scoped>
  190. @import '../../assets/scss/variables.scss';
  191. .admin_moderation {
  192. padding: 2rem;
  193. padding-top: 1rem;
  194. @at-root #{&}__header {
  195. display: flex;
  196. justify-content: space-between;
  197. align-items: flex-end;
  198. button {
  199. margin-bottom: 1.2rem;
  200. }
  201. }
  202. @at-root #{&}__add_new_ban_modal {
  203. padding: 1rem;
  204. @at-root #{&}__overlay {
  205. margin-left: -1rem;
  206. @include loading-overlay(rgba(0, 0, 0, 0.3), 0.125rem);
  207. }
  208. h2 {
  209. padding: 0;
  210. margin: 0;
  211. margin-bottom: -0.5rem;
  212. }
  213. }
  214. @at-root #{&}__table {
  215. width: calc(100%);
  216. overflow: hidden;
  217. margin-top: 1rem;
  218. padding: 0.5rem;
  219. background-color: #fff;
  220. border-radius: 0.25rem;
  221. border-collapse: collapse;
  222. @extend .shadow_border;
  223. td, th {
  224. padding: 0.5rem;
  225. }
  226. th {
  227. text-align: left;
  228. }
  229. tr:nth-child(even) {
  230. background-color: $color__lightgray--darker;
  231. }
  232. }
  233. }
  234. </style>