ThreadNew.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. <template>
  2. <div class='route_container thread_new'>
  3. <div class='h1'>Post new thread</div>
  4. <div class='thread_meta_info'>
  5. <div class='thread_meta_info__text'>Enter the thread title and the category to post it in</div>
  6. <select-button v-model='selectedCategory' :options='categories'></select-button>
  7. <fancy-input
  8. placeholder='Thread title'
  9. v-model='name'
  10. style='margin-left: 0.5rem; display: inline-block;'
  11. large='true'
  12. width='15rem'
  13. ></fancy-input>
  14. </div>
  15. <div class='editor' :class='{"editor--focus": focusInput}'>
  16. <div class='editor__input'>
  17. <div class='editor__format_bar'>
  18. editor
  19. </div>
  20. <input-editor-core
  21. v-model='editor'
  22. :error='errors.content'
  23. @focus='setFocusInput(true)'
  24. @blur='setFocusInput(false)'
  25. ></input-editor-core>
  26. </div>
  27. <div class='editor__preview'>
  28. <div class='editor__format_bar editor__format_bar--preview'>
  29. preview
  30. </div>
  31. <input-editor-preview :value='editor'></input-editor-preview>
  32. </div>
  33. </div>
  34. <loading-button class='button--green submit' :loading='loading' @click='postThread'>Post thread</loading-button>
  35. </div>
  36. </template>
  37. <script>
  38. import InputEditorCore from '../InputEditorCore'
  39. import InputEditorPreview from '../InputEditorPreview'
  40. import FancyInput from '../FancyInput'
  41. import SelectButton from '../SelectButton'
  42. import LoadingButton from '../LoadingButton'
  43. import AjaxErrorHandler from '../../assets/js/errorHandler'
  44. export default {
  45. name: 'ThreadNew',
  46. components: {
  47. InputEditorCore,
  48. InputEditorPreview,
  49. SelectButton,
  50. FancyInput,
  51. LoadingButton
  52. },
  53. data () {
  54. return {
  55. selectedCategory: this.$store.state.category.selectedCategory,
  56. editor: '',
  57. name: '',
  58. loading: false,
  59. focusInput: false,
  60. errors: {
  61. content: '',
  62. name: ''
  63. }
  64. }
  65. },
  66. computed: {
  67. categories () {
  68. return this.$store.getters.categoriesWithoutAll
  69. }
  70. },
  71. methods: {
  72. postThread () {
  73. if(!this.editor.trim().length) {
  74. this.errors.content = 'Cannot be blank'
  75. return;
  76. }
  77. this.errors.content = ''
  78. this.errors.name = ''
  79. this.loading = true
  80. this.axios.post('/api/v1/thread', {
  81. name: this.name,
  82. category: this.selectedCategory
  83. }).then(res => {
  84. return this.axios.post('/api/v1/post', {
  85. threadId: res.data.id,
  86. content: this.editor
  87. })
  88. }).then(res => {
  89. this.loading = false
  90. this.$router.push(`/thread/${res.data.Thread.slug}/${res.data.Thread.id}`)
  91. }).catch(e => {
  92. this.loading = false
  93. AjaxErrorHandler(this.$store)(e, (error, errors) => {
  94. let param = error.parameter
  95. if(this.errors[param] !== undefined) {
  96. this.error[param] = error.message
  97. } else {
  98. errors.push(error.message)
  99. }
  100. })
  101. })
  102. },
  103. setFocusInput (val) {
  104. this.focusInput = val
  105. }
  106. },
  107. watch: {
  108. '$store.state.username' (username) {
  109. if(!username) {
  110. this.$router.push('/')
  111. }
  112. }
  113. },
  114. beforeRouteEnter (to, from, next) {
  115. next(vm => {
  116. if(!vm.$store.state.username) {
  117. vm.$store.commit('setAccountModalState', true);
  118. next('/')
  119. }
  120. })
  121. }
  122. }
  123. </script>
  124. <style lang='scss'>
  125. @import '../../assets/scss/variables.scss';
  126. .thread_new {
  127. margin-top: 1rem;
  128. }
  129. .thread_meta_info {
  130. background-color: #fff;
  131. @extend .shadow_border;
  132. border-radius: 0.25rem;
  133. padding: 1rem;
  134. margin: 1rem 0;
  135. @at-root #{&}__text {
  136. margin-bottom: 0.5rem;
  137. }
  138. }
  139. .submit {
  140. margin-top: 1rem;
  141. }
  142. .editor {
  143. display: flex;
  144. background-color: #fff;
  145. border-radius: 0.25rem;
  146. border: 0.125rem solid $color__gray--darker;
  147. transition: color 0.2s;
  148. @at-root #{&}--focus {
  149. border-color: $color__gray--darkest;
  150. }
  151. @at-root #{&}__format_bar {
  152. height: 2.5rem;
  153. background-color: $color__gray--primary;
  154. display: flex;
  155. padding-right: 1rem;
  156. padding-bottom: 0.25rem;
  157. justify-content: flex-end;
  158. align-items: center;
  159. font-variant: small-caps;
  160. }
  161. @at-root #{&}__input {
  162. width: 50%;
  163. position: relative;
  164. .input_editor_core__format_bar {
  165. left: 0rem;
  166. }
  167. textarea {
  168. height: 14rem;
  169. }
  170. }
  171. @at-root #{&}__preview {
  172. border-left: 0.125rem solid $color__gray--darker;
  173. width: 50%;
  174. .input_editor_preview__markdownHTML {
  175. height: 14.2rem;
  176. }
  177. }
  178. }
  179. </style>