AdminCategories.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. <template>
  2. <div class='admin_categories'>
  3. <modal-window v-model='showAddModal' :loading='loading'>
  4. <div slot='main'>
  5. <p>Add a category</p>
  6. <fancy-input v-model='add.name' placeholder='Category name'></fancy-input>
  7. <colour-picker v-model='add.color'></colour-picker>
  8. </div>
  9. <div slot='footer'>
  10. <button class='button button--modal button--green' @click='addCategory'>Add category</button>
  11. <button class='button button--modal' @click='toggleAddModal'>Cancel</button>
  12. </div>
  13. </modal-window>
  14. <modal-window v-model='showEditModal' :loading='loading'>
  15. <div slot='main'>
  16. <p>Edit this category</p>
  17. <fancy-input v-model='edit.name' placeholder='Category name'></fancy-input>
  18. <colour-picker v-model='edit.color'></colour-picker>
  19. </div>
  20. <div slot='footer'>
  21. <button class='button button--modal button--green' @click='editCategory'>Update category</button>
  22. <button class='button button--modal' @click='toggleEditModal(null)'>Cancel</button>
  23. </div>
  24. </modal-window>
  25. <div class='category_widget__box'>
  26. <div class='category_widget__text'>
  27. <div class='category_widget__text__title'>Categories</div>
  28. Hover to remove or edit a category. <br/>
  29. Removing a category will place any threads in that category into 'Other'
  30. </div>
  31. <transition-group name='slide'>
  32. <div
  33. class='admin_categories__category'
  34. v-for='(category, $index) in categories'
  35. :key='category.id'
  36. >
  37. <div class='admin_categories__category__actions_holder'>
  38. <div class='admin_categories__category__actions'>
  39. <div
  40. class='admin_categories__category__action'
  41. @click='removeCateogry(category.id, $index)'
  42. >Remove</div>
  43. <div
  44. class='admin_categories__category__action'
  45. @click='toggleEditModal(category, $index)'
  46. >Edit</div>
  47. </div>
  48. </div>
  49. <div
  50. class='admin_categories__category__color'
  51. :style='{ "background-color": category.color }'
  52. ></div>
  53. <div class='admin_categories__category__name'>{{category.name}}</div>
  54. </div>
  55. </transition-group>
  56. <div style="margin-top: 0.5rem;">
  57. <div class='admin_categories__category admin_categories__category--add' @click='toggleAddModal'>
  58. <div
  59. class='admin_categories__category__color fa fa-plus'
  60. >
  61. </div>
  62. <div class='admin_categories__category__name'>Add new category</div>
  63. </div>
  64. </div>
  65. </div>
  66. </div>
  67. </template>
  68. <script>
  69. import ModalWindow from './ModalWindow'
  70. import FancyInput from './FancyInput'
  71. import LoadingIcon from './LoadingIcon'
  72. import ColourPicker from './ColourPicker'
  73. import AjaxErrorHandler from '../assets/js/errorHandler'
  74. export default {
  75. name: 'AdminCategories',
  76. components: {
  77. ModalWindow,
  78. FancyInput,
  79. LoadingIcon,
  80. ColourPicker
  81. },
  82. data () {
  83. return {
  84. loading: false,
  85. showAddModal: false,
  86. showEditModal: false,
  87. add: {
  88. name: '',
  89. color: '#ffffff'
  90. },
  91. edit: {
  92. name: '',
  93. color: '#ffffff',
  94. id: null,
  95. index: null
  96. },
  97. categories: []
  98. }
  99. },
  100. methods: {
  101. toggleAddModal () {
  102. this.add.name = ''
  103. this.add.color = '#ffffff'
  104. this.showAddModal = !this.showAddModal
  105. },
  106. toggleEditModal (category, index) {
  107. if(category) {
  108. this.edit.name = category.name
  109. this.edit.color = category.color
  110. this.edit.id = category.id
  111. this.edit.index = index
  112. } else {
  113. this.edit.name = ''
  114. this.edit.color = '#ffffff'
  115. this.edit.id = null
  116. this.edit.index = null
  117. }
  118. this.showEditModal = !this.showEditModal
  119. },
  120. addCategory () {
  121. this.loading = true
  122. this.axios
  123. .post('/api/v1/category', { name: this.add.name, color: this.add.color })
  124. .then(res => {
  125. this.toggleAddModal()
  126. this.loading = false
  127. this.categories.push(res.data)
  128. this.$store.commit('addCategories', res.data)
  129. })
  130. .catch(AjaxErrorHandler(this.$store))
  131. },
  132. removeCateogry (id, index) {
  133. this.axios
  134. .delete('/api/v1/category/' + id)
  135. .then(res => {
  136. this.categories.splice(index, 1)
  137. this.$store.commit('removeCategory', id)
  138. if(res.data.otherCategoryCreated) {
  139. this.$store.commit('addCategories', res.data.otherCategoryCreated)
  140. }
  141. })
  142. .catch(AjaxErrorHandler(this.$store))
  143. },
  144. editCategory () {
  145. this.loading = true
  146. this.axios
  147. .put('/api/v1/category/' + this.edit.id ,{
  148. name: this.edit.name,
  149. color: this.edit.color
  150. })
  151. .then(res => {
  152. this.loading = false
  153. this.categories.splice(this.edit.index, 1, res.data)
  154. this.$store.commit('updateCategory', res.data)
  155. this.toggleEditModal()
  156. })
  157. .catch(AjaxErrorHandler(this.$store))
  158. }
  159. },
  160. mounted () {
  161. this.axios
  162. .get('/api/v1/category')
  163. .then(res => {
  164. this.categories = res.data.filter(c => c.name !== 'Other')
  165. })
  166. .catch(AjaxErrorHandler(this.$store))
  167. }
  168. }
  169. </script>
  170. <style lang='scss' scoped>
  171. @import '../assets/scss/variables.scss';
  172. .slide-enter-active, .slide-leave-active, .slice-move {
  173. transition: all 1s;
  174. }
  175. .slide-enter, .slide-leave-to {
  176. opacity: 0;
  177. }
  178. .admin_categories {
  179. @at-root #{&}__category {
  180. display: inline-flex;
  181. position: relative;
  182. align-items: center;
  183. background-color: rgba($color__lightgray--primary, 0.5);
  184. justify-content: center;
  185. border-radius: 5rem;
  186. padding: 0.25rem 0.5rem 0.25rem 0.5rem;
  187. border: thin solid $color__gray--darker;
  188. margin-right: 0.5rem;
  189. margin-bottom: 0.5rem;
  190. transition: all 0.2s;
  191. cursor: default;
  192. &:hover {
  193. background-color: $color__lightgray--primary;
  194. & .admin_categories__category__actions_holder {
  195. opacity: 1;
  196. margin-top: 0;
  197. pointer-events: all;
  198. }
  199. }
  200. @at-root #{&}--add {
  201. top: -0.25rem;
  202. cursor: pointer;
  203. }
  204. @at-root #{&}__actions_holder {
  205. position: absolute;
  206. top: -2.25rem;
  207. opacity: 0;
  208. pointer-events: none;
  209. margin-top: 1rem;
  210. padding-bottom: 1rem;
  211. transition: all 0.2s;
  212. }
  213. @at-root #{&}__actions {
  214. border-radius: 3rem;
  215. border: thin solid $color__gray--darker;
  216. overflow: hidden;
  217. display: flex;
  218. background-color: #fff;
  219. box-shadow: 0 0.2rem 3px 0px rgba(224, 224, 224, 0.4);
  220. }
  221. @at-root #{&}__action {
  222. padding: 0.25rem 0.5rem;
  223. cursor: pointer;
  224. transition: all 0.2s;
  225. &:first-of-type {
  226. border-right: 0.1rem solid $color__gray--primary;
  227. }
  228. &:hover {
  229. background-color: $color__lightgray--primary;
  230. }
  231. }
  232. @at-root #{&}__color {
  233. height: 1.25rem;
  234. width: 1.25rem;
  235. border-radius: 100%;
  236. margin-left: 0rem;
  237. margin-right: 0.25rem;
  238. display: flex;
  239. align-items: center;
  240. justify-content: center;
  241. }
  242. @at-root #{&}__name {
  243. position: relative;
  244. bottom: 0.1rem;
  245. }
  246. }
  247. }
  248. </style>