176 lines
5.6 KiB
Vue
Executable File
176 lines
5.6 KiB
Vue
Executable File
<template>
|
|
<meta-head title="Пользователи"></meta-head>
|
|
|
|
<div class="mt-16 container mx-auto px-2 md:px-6 2xl:px-28 buttons-filter-line">
|
|
<div class="mb-5">
|
|
<search-filter v-model="form.search" class="w-full max-w-3xl mr-4"
|
|
@reset="reset"
|
|
>
|
|
<label class="text-xs md:text-base block text-gray mb-2">Пол:</label>
|
|
<div class="flex space-x-6">
|
|
<div class="flex items-center">
|
|
<input id="user-sex-1" v-model="form.sex"
|
|
value="1" type="radio"
|
|
class="h-5 w-5 text-orange border-gray-light focus:ring-transparent focus:ring-offset-transparent cursor-pointer"
|
|
>
|
|
<label for="user-sex-1" class="cursor-pointer select-none ml-3 text-gray text-xs md:text-base">Женский</label>
|
|
</div>
|
|
<div class="flex items-center">
|
|
<input id="user-sex-2" v-model="form.sex"
|
|
value="2" type="radio"
|
|
class="h-5 w-5 text-orange border-gray-light focus:ring-transparent focus:ring-offset-transparent cursor-pointer"
|
|
>
|
|
<label for="user-sex-2" class="cursor-pointer select-none ml-3 text-gray text-xs md:text-base">Мужской</label>
|
|
</div>
|
|
</div>
|
|
</search-filter>
|
|
</div>
|
|
|
|
|
|
<div v-show="users.length" class="grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5 cards-block rounded-md bg-indigo-200 shadow-classic grid gap-2 lg:gap-4 grid-cards p-2 lg:p-5">
|
|
<InfinityScroll :node-element="lastNodeLement" :next-cursor="nextCursor"
|
|
@fromPagination="putFromPagination"
|
|
>
|
|
<div
|
|
v-for="user in userLists"
|
|
:key="user.id"
|
|
:ref="el => { if (el && user.id === lastElementID) lastNodeLement = el }"
|
|
class="user-card relative"
|
|
>
|
|
<div v-if="!user.private" class="absolute inset-x-0 top-4 z-10 flex justify-center">
|
|
<toggle
|
|
:user_id="user.id"
|
|
:enabled="user.is_sub"
|
|
textin="Подписаться"
|
|
textout="Отписаться" @clicked="susbscribe"
|
|
/>
|
|
</div>
|
|
<div class="absolute inset-x-0 bottom-4 z-10 flex justify-center">
|
|
<div class="flex flex-col items-center">
|
|
<inertia-link :href="route('profile.user', user.username)" class="block flex-shrink-0">
|
|
<user-avatar :user="user" size="small"
|
|
class="border border-white shadow-classic h-20 w-20 text-lg"
|
|
/>
|
|
</inertia-link>
|
|
<inertia-link :href="route('profile.user', user.username)" class="mt-2 block text-white text-sm text-center">
|
|
<p class="">
|
|
{{ user.name }}
|
|
</p>
|
|
<p class="text-xs">
|
|
{{ user.username }}
|
|
</p>
|
|
</inertia-link>
|
|
</div>
|
|
</div>
|
|
<div class="gradient-profile relative overflow-hidden">
|
|
<user-banner class="h-72 bg-indigo-300" :user="user"
|
|
size="banner"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</InfinityScroll>
|
|
</div>
|
|
|
|
<div v-show="users.length == 0">
|
|
<p class="text-center md:text-2xl text-gray-light">
|
|
Пользователи не найдены
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { ref } from 'vue'
|
|
import { Inertia } from '@inertiajs/inertia'
|
|
import throttle from 'lodash/throttle'
|
|
import pickBy from 'lodash/pickBy'
|
|
import mapValues from 'lodash/mapValues'
|
|
|
|
import Layout from '@/Shared/Layout.vue'
|
|
import MetaHead from '@/Shared/MetaHead.vue'
|
|
import Toggle from '@/Shared/Form/Toggle.vue'
|
|
import UserAvatar from '@/Shared/Misc/UserAvatar.vue'
|
|
import UserBanner from '@/Shared/Misc/UserBanner.vue'
|
|
import SearchFilter from '@/Shared/Form/SearchFilter.vue'
|
|
import InfinityScroll from '@/Shared/Misc/InfinityScroll.vue'
|
|
|
|
export default {
|
|
components: {
|
|
MetaHead,
|
|
UserAvatar,
|
|
UserBanner,
|
|
Toggle,
|
|
InfinityScroll,
|
|
SearchFilter,
|
|
},
|
|
layout: Layout,
|
|
props: {
|
|
nextCursor: String,
|
|
users: Array,
|
|
filters: Object,
|
|
per_page: Number,
|
|
},
|
|
|
|
setup() {
|
|
const containerRef = ref(null)
|
|
return {
|
|
lastNodeLement: containerRef,
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
userLists: [],
|
|
form: {
|
|
search: this.filters.search,
|
|
sex: this.filters.sex,
|
|
},
|
|
}
|
|
},
|
|
computed: {
|
|
lastElementID() {
|
|
return this.userLists[this.userLists.length - 1]?.id
|
|
},
|
|
},
|
|
watch: {
|
|
users() {
|
|
this.updateRequest()
|
|
},
|
|
form: {
|
|
deep: true,
|
|
handler: throttle(function () {
|
|
Inertia.get(this.route('users.index'), pickBy(this.form), {
|
|
preserveState: true,
|
|
})
|
|
}, 500),
|
|
},
|
|
},
|
|
|
|
mounted() {
|
|
this.updateRequest()
|
|
},
|
|
|
|
methods: {
|
|
putFromPagination(lists) {
|
|
for (let list of lists) {
|
|
this.userLists.push(list)
|
|
}
|
|
},
|
|
|
|
susbscribe(user_id) {
|
|
Inertia.post(
|
|
route('users.subs', user_id),
|
|
{},
|
|
{ preserveScroll: true, preserveState: true }
|
|
)
|
|
},
|
|
updateRequest() {
|
|
this.userLists = this.users
|
|
},
|
|
reset() {
|
|
this.form = mapValues(this.form, () => null)
|
|
},
|
|
},
|
|
|
|
}
|
|
</script>
|