index.vue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. <template>
  2. <v-expansion-panels>
  3. <v-row class="px-10 py-5" align="center">
  4. <v-text-field
  5. v-model="searchKey"
  6. append-outer-icon="mdi-magnify"
  7. class="pt-5"
  8. placeholder="Введите чтобы начать поиск"
  9. @click:append-outer="searchTrigger"
  10. @keyup.enter="searchTrigger"
  11. />
  12. </v-row>
  13. <v-expansion-panels class="admin-users" v-if="users">
  14. <v-expansion-panel v-for="user in users.users" :key="user.user_id">
  15. <v-expansion-panel-header @click="() => {}">
  16. <v-col cols="6">
  17. <div class="user-contacts">
  18. <span>
  19. <b>{{ user.first_name }}</b>
  20. </span>
  21. <span>
  22. {{ user.email }}
  23. </span>
  24. </div>
  25. </v-col>
  26. <v-col cols="6">
  27. <span> </span>
  28. <span> </span>
  29. <v-divider vertical></v-divider>
  30. <div class="user-info">
  31. <span>бан: {{ user.ban_status ? "да" : "нет" }}</span>
  32. <span>мут: {{ user.mut_status ? "да" : "нет" }}</span>
  33. <span>права: {{ user.user_permission_group_display_name }}</span>
  34. </div>
  35. </v-col>
  36. <v-col cols="2">
  37. <v-btn link tile color="success" @click="openEditor(user)">
  38. <v-icon center> mdi-pencil </v-icon>
  39. </v-btn>
  40. <v-btn tile color="error" @click="deleteUser(user)">
  41. <v-icon center> mdi-delete-outline </v-icon>
  42. </v-btn>
  43. </v-col>
  44. </v-expansion-panel-header>
  45. </v-expansion-panel>
  46. </v-expansion-panels>
  47. <v-pagination
  48. v-model="counter"
  49. :length="users ? users.total_pages : 0"
  50. ref="pagination"
  51. v-if="users.total_users"
  52. @input="onPageChanged"
  53. :next-icon="'Вперед'"
  54. :prev-icon="'Назад'"
  55. :next-aria-label="'next-text'"
  56. :prev-aria-label="'prev-text'"
  57. :page-aria-label="'page-text'"
  58. :current-page-aria-label="'current-page'"
  59. total-visible="10"
  60. color="gray"
  61. class="mt-5"
  62. ></v-pagination>
  63. <modal height="auto" name="user-editor" class="user-editor__modal">
  64. <h2>Редактирование данных</h2>
  65. <v-text-field
  66. :value="editingUser.first_name"
  67. v-model="editingUser.first_name"
  68. label="Никнейм"
  69. >Никнейм</v-text-field
  70. >
  71. <v-text-field
  72. label="Емейл"
  73. :value="editingUser.email"
  74. v-model="editingUser.email"
  75. >Емейл</v-text-field
  76. >
  77. <v-text-field
  78. label="Телефон"
  79. :value="editingUser.phone"
  80. v-model="editingUser.phone"
  81. >Телефон</v-text-field
  82. >
  83. <v-select
  84. class="user-editor__select"
  85. :items="permissionGroups"
  86. item-text="name"
  87. item-value="code"
  88. v-model="editingUser.user_permission_group"
  89. label="Права"
  90. ></v-select>
  91. <v-switch v-model="editingUser.mut_status" color="orange" inset label="Мут"></v-switch>
  92. <v-switch v-model="editingUser.ban_status" color="red" inset label="Бан"></v-switch>
  93. <v-btn
  94. class="user-editor__modal-button mr-4"
  95. color="primary"
  96. @click="editUser"
  97. >Сохранить</v-btn
  98. >
  99. <v-btn
  100. class="user-editor__modal-button"
  101. color="error"
  102. @click="$modal.hide('user-editor')"
  103. >Отмена</v-btn
  104. >
  105. </modal>
  106. </v-expansion-panels>
  107. </template>
  108. <script>
  109. export default {
  110. layout: "admin",
  111. data() {
  112. return {
  113. users: false,
  114. counter: 1,
  115. editingUser: false,
  116. searchKey: '',
  117. permissionGroups: [
  118. {
  119. code: 0,
  120. name: "Гость",
  121. },
  122. {
  123. code: 1,
  124. name: "Пользователь",
  125. },
  126. {
  127. code: 2,
  128. name: "Менеджер по рекламе",
  129. },
  130. {
  131. code: 3,
  132. name: "Репортер",
  133. },
  134. {
  135. code: 4,
  136. name: "Модератор",
  137. },
  138. {
  139. code: 5,
  140. name: "Администратор",
  141. },
  142. ],
  143. };
  144. },
  145. async mounted() {
  146. await this.loadUsers();
  147. },
  148. methods: {
  149. async onPageChanged() {
  150. window.scrollTo({ top: 0, behavior: "smooth" });
  151. await this.loadUsers();
  152. },
  153. async editUser() {
  154. const result = await this.$swal.fire({
  155. title: "Вы уверены, что хотите отредактировать пользователя?",
  156. showCancelButton: true,
  157. confirmButtonText: "Принять",
  158. icon: "question",
  159. cancelButtonText: `Отменить`,
  160. confirmButtonColor: `#1976d2`,
  161. denyButtonColor: `#2196f3`,
  162. });
  163. if (result.isDenied) {
  164. this.$swal.fire("Отмена редактирования", "", "info");
  165. return;
  166. }
  167. else if (result.isConfirmed) {
  168. await this.$axios.post("/authorized/admin/user/profile/update", {
  169. target_id: this.editingUser.user_id,
  170. first_name: this.editingUser.first_name,
  171. email: this.editingUser.email,
  172. phone:
  173. this.editingUser.phone.length >= 3
  174. ? this.editingUser.phone
  175. : "без номера",
  176. });
  177. await this.$axios.post("/authorized/admin/user/permission_group/update", {
  178. user_permission_group_id: this.editingUser.user_permission_group,
  179. user_id: this.editingUser.user_id,
  180. });
  181. await this.$axios.post("/authorized/admin/user/profile/ban_or_mute", {
  182. target_id: this.editingUser.user_id,
  183. ban_status: this.editingUser.ban_status,
  184. mut_status: this.editingUser.mut_status,
  185. });
  186. await this.loadUsers();
  187. this.$swal.fire("Готово!", "", "success");
  188. this.$modal.hide("user-editor");
  189. }
  190. },
  191. getPermission(num) {
  192. return this.permissionGroups.find((el) => el.code == num);
  193. },
  194. openEditor(user) {
  195. this.editingUser = Object.assign({}, user);
  196. this.$modal.show("user-editor");
  197. },
  198. async deleteUser(user) {
  199. const result = await this.$swal.fire({
  200. title: "Вы уверены, что хотите удалить пользователя?",
  201. showCancelButton: true,
  202. confirmButtonText: "Удалить",
  203. icon: "error",
  204. cancelButtonText: `Не удалять`,
  205. confirmButtonColor: `#ab003c`,
  206. denyButtonColor: `#2196f3`,
  207. });
  208. if (result.isConfirmed) {
  209. await this.$axios.get(
  210. `authorized/admin/user/profile/delete/${user.user_id}`
  211. );
  212. await this.loadUsers();
  213. this.$swal.fire("Удалено!", "", "error");
  214. }
  215. else if (result.isDenied) {
  216. this.$swal.fire("Отмена удаления", "", "info");
  217. }
  218. },
  219. async searchTrigger() {
  220. this.counter = 1;
  221. await this.loadUsers();
  222. },
  223. async loadUsers() {
  224. if(this.searchKey) {
  225. await this.searchUsers();
  226. return;
  227. }
  228. this.users = await this.$axios
  229. .get(`authorized/admin/user/profiles/list/page_${this.counter}`)
  230. .then((res) => res.data.data);
  231. },
  232. async searchUsers() {
  233. this.users = await this.$axios
  234. .get(`authorized/admin/user/profiles/search/${this.searchKey}/page_${this.counter}`)
  235. .then((res) => res.data.data);
  236. }
  237. },
  238. };
  239. </script>
  240. <style lang="scss">
  241. .v-expansion-panel--active,
  242. .v-item--active {
  243. margin: 0 !important;
  244. // border: none !important;
  245. }
  246. .v-expansion-panel {
  247. margin: 0 !important;
  248. }
  249. .v-expansion-panel--active:not(:first-child)::after,
  250. .v-expansion-panel--active + .v-expansion-panel::after {
  251. opacity: 1 !important;
  252. }
  253. .user-info,
  254. .user-contacts {
  255. display: flex;
  256. flex-direction: column;
  257. span {
  258. margin-bottom: 6px;
  259. }
  260. }
  261. .admin-users {
  262. margin: 0 auto;
  263. }
  264. .user-editor {
  265. &__modal {
  266. &-button {
  267. margin-top: 20px;
  268. }
  269. h2 {
  270. margin-bottom: 20px;
  271. }
  272. input {
  273. border: none;
  274. }
  275. .vm--modal {
  276. max-height: 100vh;
  277. min-height: 450px;
  278. padding: 30px;
  279. }
  280. }
  281. &__select {
  282. input {
  283. border: none;
  284. background: rgba(0, 0, 0, 0.06);
  285. z-index: -1;
  286. display: none;
  287. }
  288. }
  289. }
  290. .v-application--is-ltr .v-expansion-panel-header__icon {
  291. margin-left: auto;
  292. display: none;
  293. }
  294. </style>