Последняя версия с сервера прошлого разработчика
This commit is contained in:
243
resources/js/Pages/Music/Create.vue
Executable file
243
resources/js/Pages/Music/Create.vue
Executable file
@@ -0,0 +1,243 @@
|
||||
<template>
|
||||
<meta-head title="Загрузить музыку"></meta-head>
|
||||
<div class="mt-16 container mx-auto px-2 md:px-6 2xl:px-28 buttons-filter-line">
|
||||
<form class=" bg-indigo-200 shadow-classic rounded-md p-5" @submit.prevent="submit">
|
||||
<div class="mb-4 flex items-center text-gray-light text-lg font-medium">
|
||||
<link-back class="default block hover:underline">
|
||||
Вернуться
|
||||
</link-back>
|
||||
<span class="px-3">/</span>
|
||||
<h1 class="text-gray">
|
||||
Загрузка музыки
|
||||
</h1>
|
||||
</div>
|
||||
<div class="space-y-5">
|
||||
<div class="flex flex-col">
|
||||
<text-input v-model="form.title" :error="form.errors.title"
|
||||
type="text" class="focus:ring-4 focus:ring-offset-1 focus:ring-orange focus:ring-opacity-20 focus:ring-offset-orange focus:border-transparent text-gray border border-indigo-300 bg-indigo-200 rounded-md placeholder-gray-light"
|
||||
label="Название"
|
||||
/>
|
||||
<warning-text />
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<textarea-input v-model="form.body" :error="form.errors.body"
|
||||
class="focus:ring-4 focus:ring-offset-1 focus:ring-orange focus:ring-opacity-20 focus:ring-offset-orange focus:border-transparent text-gray border border-indigo-300 bg-indigo-200 rounded-md" cols="30"
|
||||
rows="4" label="Описание"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<file-input
|
||||
v-model="form.preview"
|
||||
accept="image/png, image/jpeg, image/jpg"
|
||||
:error="form.errors.preview"
|
||||
label="Загрузить превью"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<file-input-multiple-decode
|
||||
v-model="form.musics"
|
||||
accept=".mp3"
|
||||
:error="form.errors.musics"
|
||||
label="Выбрать музыку"
|
||||
@fileTime="saveTimeFile"
|
||||
@loadFileStart="incrementLoadFile"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="text-gray-light">
|
||||
<TagInput v-model="form.tags" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="text-gray-light text-lg mb-2">
|
||||
Тип контента
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-4">
|
||||
<div class="flex items-center">
|
||||
<input id="feed-paid-1" v-model="form.is_paid"
|
||||
value="0" type="radio"
|
||||
class="h-5 w-5 text-orange border-gray-light focus:ring-transparent focus:ring-offset-transparent"
|
||||
>
|
||||
<label for="feed-paid-1" class="select-none ml-3 text-gray">Бесплатный</label>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<input id="feed-paid-2" v-model="form.is_paid"
|
||||
value="1" type="radio"
|
||||
class="h-5 w-5 text-orange border-gray-light focus:ring-transparent focus:ring-offset-transparent"
|
||||
>
|
||||
<label for="feed-paid-2" class="select-none ml-3 text-gray">Эксклюзивный</label>
|
||||
</div>
|
||||
<div v-if="authUser.private" class="flex items-center">
|
||||
<input id="feed-paid-3" v-model="form.is_paid"
|
||||
value="2" type="radio"
|
||||
class="h-5 w-5 text-orange border-gray-light focus:ring-transparent focus:ring-offset-transparent"
|
||||
>
|
||||
<label for="feed-paid-3" class="select-none ml-3 text-gray">Доступен по личной подписке</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="flex items-center">
|
||||
<input id="is_adult_feed" v-model="form.is_adult"
|
||||
type="checkbox"
|
||||
class="h-5 w-5 text-orange border-gray-light focus:ring-transparent focus:ring-offset-transparent"
|
||||
>
|
||||
<label for="is_adult_feed" class="select-none ml-3 text-gray">Контент для взрослых</label>
|
||||
</div> -->
|
||||
|
||||
<div v-if="form.is_paid == 1" class="space-y-5">
|
||||
<div class="flex flex-col">
|
||||
<text-input v-model="form.price" :error="form.errors.price"
|
||||
type="number" class="focus:ring-4 focus:ring-offset-1 focus:ring-orange focus:ring-opacity-20 focus:ring-offset-orange focus:border-transparent text-gray border border-indigo-300 bg-indigo-200 rounded-md placeholder-gray-light"
|
||||
label="Цена"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<file-input-multiple-decode
|
||||
v-model="form.musics_paid"
|
||||
accept=".mp3"
|
||||
:error="form.errors.musics_paid"
|
||||
label="Выбрать музыку"
|
||||
@fileTime="savePaidTimeFile"
|
||||
@loadFileStart="incrementLoadFile"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-12 flex flex-wrap -my-1 -mx-3">
|
||||
<progress
|
||||
v-if="form.progress"
|
||||
class="mx-3 my-1 w-full"
|
||||
:value="form.progress.percentage"
|
||||
max="100"
|
||||
>
|
||||
{{ form.progress.percentage }}%
|
||||
</progress>
|
||||
|
||||
<div v-if="!is_disabled_create">
|
||||
<loading-button :loading="form.processing" class="mx-3 my-1 transition shadow-none hover:shadow-classic2 inline-flex items-center px-8 py-3 justify-center text-base rounded-md text-white bg-orange focus:outline-none"
|
||||
type="submit"
|
||||
>
|
||||
Создать
|
||||
</loading-button>
|
||||
<link-back class="mx-3 my-1 transition shadow-none hover:shadow-classic inline-flex items-center px-8 py-3 justify-center text-base rounded-md text-white bg-indigo-300 focus:outline-none">
|
||||
Отменить
|
||||
</link-back>
|
||||
</div>
|
||||
<div v-else>
|
||||
<button type="button" class="mx-3 my-1 transition shadow-none hover:shadow-classic2 inline-flex items-center px-8 py-3 justify-center text-base rounded-md text-white bg-orange focus:outline-none ease-in-out duration-150 cursor-not-allowed"
|
||||
disabled
|
||||
>
|
||||
<svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none" viewBox="0 0 24 24"
|
||||
><circle class="opacity-25" cx="12"
|
||||
cy="12" r="10"
|
||||
stroke="currentColor" stroke-width="4"
|
||||
></circle><path class="opacity-75" fill="currentColor"
|
||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
||||
></path></svg>
|
||||
Обработка
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { useForm, usePage } from '@inertiajs/inertia-vue3'
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
import Layout from '@/Shared/Layout.vue'
|
||||
import MetaHead from '@/Shared/MetaHead.vue'
|
||||
import TextInput from '@/Shared/Form/TextInput.vue'
|
||||
import FileInputMultipleDecode from '@/Shared/Form/FileInputMultipleDecode.vue'
|
||||
import FileInput from '@/Shared/Form/FileInput.vue'
|
||||
import TextareaInput from '@/Shared/Form/TextareaInput.vue'
|
||||
import LoadingButton from '@/Shared/Form/LoadingButton.vue'
|
||||
import TagInput from '@/Shared/Form/TagInput.vue'
|
||||
import WarningText from '@/Shared/Misc/WarningText.vue'
|
||||
import LinkBack from '@/Shared/Misc/LinkBack.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MetaHead,
|
||||
TextInput,
|
||||
FileInput,
|
||||
FileInputMultipleDecode,
|
||||
LoadingButton,
|
||||
TextareaInput,
|
||||
TagInput,
|
||||
WarningText,
|
||||
LinkBack,
|
||||
},
|
||||
layout: Layout,
|
||||
|
||||
setup() {
|
||||
let is_disabled_create = ref(0)
|
||||
let countFiles = ref(0)
|
||||
let countFilesLoaded = ref(0)
|
||||
|
||||
// let isFeedPaid = ref(0)
|
||||
// let openPaidBlock = ref(0)
|
||||
|
||||
const form = useForm({
|
||||
title: null,
|
||||
body: null,
|
||||
preview: null,
|
||||
musics: null,
|
||||
musics_paid: null,
|
||||
price: null,
|
||||
is_paid: 0,
|
||||
times: [],
|
||||
times_paid: [],
|
||||
tags: [],
|
||||
})
|
||||
|
||||
// watch(isFeedPaid, (value) => {
|
||||
// openPaidBlock.value = value
|
||||
// form.is_paid = value
|
||||
// })
|
||||
|
||||
const submit = () => {
|
||||
form.post(route('musics.store'))
|
||||
}
|
||||
|
||||
const saveTimeFile = (time) => {
|
||||
form.times.push(time)
|
||||
countFilesLoaded.value++
|
||||
if (countFilesLoaded.value === countFiles.value) {
|
||||
is_disabled_create.value = 0
|
||||
}
|
||||
}
|
||||
const savePaidTimeFile = (time) => {
|
||||
form.times_paid.push(time)
|
||||
countFilesLoaded.value++
|
||||
if (countFilesLoaded.value === countFiles.value) {
|
||||
is_disabled_create.value = 0
|
||||
}
|
||||
}
|
||||
const incrementLoadFile = () => {
|
||||
countFiles.value++
|
||||
is_disabled_create.value = 1
|
||||
}
|
||||
const authUser = computed(() => usePage().props.value.auth.user)
|
||||
|
||||
|
||||
|
||||
return {
|
||||
form,
|
||||
submit,
|
||||
saveTimeFile,
|
||||
savePaidTimeFile,
|
||||
incrementLoadFile,
|
||||
is_disabled_create,
|
||||
authUser,
|
||||
// isFeedPaid,
|
||||
// openPaidBlock,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
416
resources/js/Pages/Music/Edit.vue
Executable file
416
resources/js/Pages/Music/Edit.vue
Executable file
@@ -0,0 +1,416 @@
|
||||
<template>
|
||||
<meta-head title="Обновить музыку"></meta-head>
|
||||
|
||||
<modal-warning
|
||||
:feed_id="feed.id"
|
||||
:open="modalShow"
|
||||
@action="deleteActionModal"
|
||||
/>
|
||||
|
||||
<div class="mt-16 container mx-auto px-2 md:px-6 2xl:px-28 buttons-filter-line">
|
||||
<div v-if="feed.status != 1" class="bg-indigo-200 shadow-classic rounded-md p-5 mb-10">
|
||||
<p class="text-lg font-medium text-gray">
|
||||
Контент запрещен к публикации, причина:
|
||||
</p>
|
||||
<p v-if="feed.status_note " class="text-gray-light">
|
||||
<ul>
|
||||
<li v-for="textBreak in textsBreak" :key="textBreak">
|
||||
{{ textBreak }}
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
<p v-else class="text-gray-light">
|
||||
модерация созданного\обновленного контента
|
||||
</p>
|
||||
<p v-if="feed.status == 3" class="pt-3 text-green">
|
||||
Обновления отправлены, ожидайте!
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
<form class="bg-indigo-200 shadow-classic rounded-md p-5" @submit.prevent="submit">
|
||||
<div class="mb-4 flex items-center text-gray-light text-lg font-medium">
|
||||
<link-back class="default block hover:underline">
|
||||
Вернуться
|
||||
</link-back>
|
||||
<span class="px-3">/</span>
|
||||
<h1 class="text-gray">
|
||||
Редактирование музыки
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="space-y-5">
|
||||
<div class="flex flex-col">
|
||||
<text-input v-model="form.title" :error="form.errors.title"
|
||||
type="text" class="focus:ring-4 focus:ring-offset-1 focus:ring-orange focus:ring-opacity-20 focus:ring-offset-orange focus:border-transparent text-gray border border-indigo-300 bg-indigo-200 rounded-md placeholder-gray-light"
|
||||
label="Название"
|
||||
/>
|
||||
<warning-text />
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<textarea-input v-model="form.body" :error="form.errors.body"
|
||||
class="focus:ring-4 focus:ring-offset-1 focus:ring-orange focus:ring-opacity-20 focus:ring-offset-orange focus:border-transparent text-gray border border-indigo-300 bg-indigo-200 rounded-md" cols="30"
|
||||
rows="4" label="Описание"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<file-input
|
||||
v-model="form.preview"
|
||||
accept="image/png, image/jpeg, image/jpg"
|
||||
:error="form.errors.preview"
|
||||
:label="textPreview()"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div v-if="mediaPreview" class="border border-indigo-300 p-4 rounded-md">
|
||||
<button type="button"
|
||||
class="flex-shrink-0 px-6 py-2 bg-pink focus:ring-4 focus:ring-offset-1 focus:ring-orange focus:ring-opacity-20 focus:ring-offset-orange focus:outline-none focus:border-transparent rounded-sm text-sm text-white" @click="removePreview(mediaPreview.id)"
|
||||
>
|
||||
Удалить старое превью
|
||||
</button>
|
||||
<div class="mt-4 flex-shrink-0 self-start overflow-hidden">
|
||||
<img class="object-contain h-48" :src="mediaPreview.url"
|
||||
alt=""
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="border border-indigo-300 flex flex-col p-4 rounded-md">
|
||||
<file-input-multiple-decode
|
||||
v-model="form.musics"
|
||||
accept=".mp3"
|
||||
:error="form.errors.musics"
|
||||
label="Загрузить новую музыку"
|
||||
@fileTime="saveTimeFile"
|
||||
@loadFileStart="incrementLoadFile"
|
||||
/>
|
||||
|
||||
<div>
|
||||
<h2 class="mt-3 mb-2 text-lg text-gray-light select-none">
|
||||
Загруженная музыка:
|
||||
</h2>
|
||||
<div class="grid gap-2 grid-cols-2 sm:grid-cols-3 lg:grid-cols-4">
|
||||
<created-media-item
|
||||
v-for="mediaCommon in mediasCommon"
|
||||
:key="mediaCommon.id" :type="feed.type"
|
||||
:media="mediaCommon"
|
||||
@addRemoveId="stateToggle"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-gray-light">
|
||||
<TagInput v-model="form.tags" />
|
||||
</div>
|
||||
<div v-if="isFreeFeed">
|
||||
<div class="text-gray-light text-lg mb-2">
|
||||
Тип контента
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-4">
|
||||
<div class="flex items-center">
|
||||
<input id="feed-paid-1" v-model="form.is_paid"
|
||||
value="0" type="radio"
|
||||
class="h-5 w-5 text-orange border-gray-light focus:ring-transparent focus:ring-offset-transparent"
|
||||
>
|
||||
<label for="feed-paid-1" class="select-none ml-3 text-gray">Бесплатный</label>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<input id="feed-paid-2" v-model="form.is_paid"
|
||||
value="1" type="radio"
|
||||
class="h-5 w-5 text-orange border-gray-light focus:ring-transparent focus:ring-offset-transparent"
|
||||
>
|
||||
<label for="feed-paid-2" class="select-none ml-3 text-gray">Эксклюзивный</label>
|
||||
</div>
|
||||
<div v-if="authUser.private" class="flex items-center">
|
||||
<input id="feed-paid-3" v-model="form.is_paid"
|
||||
value="2" type="radio"
|
||||
class="h-5 w-5 text-orange border-gray-light focus:ring-transparent focus:ring-offset-transparent"
|
||||
>
|
||||
<label for="feed-paid-3" class="select-none ml-3 text-gray">Доступен по личной подписке</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="flex items-center">
|
||||
<input id="is_adult_feed" v-model="form.is_adult"
|
||||
type="checkbox"
|
||||
class="h-5 w-5 text-orange border-gray-light focus:ring-transparent focus:ring-offset-transparent"
|
||||
>
|
||||
<label for="is_adult_feed" class="select-none ml-3 text-gray">Контент для взрослых</label>
|
||||
</div> -->
|
||||
<div v-if="form.is_paid == 1" class="space-y-5">
|
||||
<div class="flex flex-col">
|
||||
<text-input v-model="form.price" :error="form.errors.price"
|
||||
type="number" class="focus:ring-4 focus:ring-offset-1 focus:ring-orange focus:ring-opacity-20 focus:ring-offset-orange focus:border-transparent text-gray border border-indigo-300 bg-indigo-200 rounded-md placeholder-gray-light"
|
||||
label="Цена"
|
||||
/>
|
||||
</div>
|
||||
<div class="border border-indigo-300 flex flex-col p-4 rounded-md space-y-3">
|
||||
<div v-if="isFreeFeed">
|
||||
<file-input-multiple-decode
|
||||
v-model="form.musics_paid"
|
||||
accept=".mp3"
|
||||
:error="form.errors.musics_paid"
|
||||
label="Выбрать музыку"
|
||||
@fileTime="savePaidTimeFile"
|
||||
@loadFileStart="incrementLoadFile"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="mediasPaid.length">
|
||||
<h2 class="mb-2 text-lg text-gray-light select-none">
|
||||
Загруженная платная музыка:
|
||||
</h2>
|
||||
<div class="grid gap-2 grid-cols-2 sm:grid-cols-3 lg:grid-cols-4">
|
||||
<created-media-item
|
||||
v-for="mediaPaid in mediasPaid" :key="mediaPaid.id"
|
||||
:edit="false"
|
||||
:type="feed.type"
|
||||
:media="mediaPaid"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-12 flex flex-wrap -my-1 -mx-3">
|
||||
<progress
|
||||
v-if="form.progress"
|
||||
class="mx-3 my-1 w-full"
|
||||
:value="form.progress.percentage"
|
||||
max="100"
|
||||
>
|
||||
{{ form.progress.percentage }}%
|
||||
</progress>
|
||||
|
||||
<div v-if="!is_disabled_create">
|
||||
<loading-button :loading="form.processing" class="mx-3 my-1 transition shadow-none hover:shadow-classic2 inline-flex items-center px-8 py-3 justify-center text-base rounded-md text-white bg-orange focus:outline-none"
|
||||
type="submit"
|
||||
>
|
||||
Обновить
|
||||
</loading-button>
|
||||
<link-back class="mx-3 my-1 transition shadow-none hover:shadow-classic inline-flex items-center px-8 py-3 justify-center text-base rounded-md text-white bg-indigo-300 focus:outline-none">
|
||||
Отменить
|
||||
</link-back>
|
||||
<button type="button" class="mx-3 my-1 default text-lg text-pink"
|
||||
@click="openModal"
|
||||
>
|
||||
Удалить
|
||||
</button>
|
||||
</div>
|
||||
<div v-else>
|
||||
<button type="button" class="mx-3 my-1 transition shadow-none hover:shadow-classic2 inline-flex items-center px-8 py-3 justify-center text-base rounded-md text-white bg-orange focus:outline-none ease-in-out duration-150 cursor-not-allowed"
|
||||
disabled
|
||||
>
|
||||
<svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none" viewBox="0 0 24 24"
|
||||
><circle class="opacity-25" cx="12"
|
||||
cy="12" r="10"
|
||||
stroke="currentColor" stroke-width="4"
|
||||
></circle><path class="opacity-75" fill="currentColor"
|
||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
||||
></path></svg>
|
||||
Обработка
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { toRefs, watch, ref, computed } from 'vue'
|
||||
import { useForm, usePage } from '@inertiajs/inertia-vue3'
|
||||
import { Inertia } from '@inertiajs/inertia'
|
||||
import { useStore } from 'vuex'
|
||||
import find from 'lodash/find'
|
||||
|
||||
import Layout from '@/Shared/Layout.vue'
|
||||
import MetaHead from '@/Shared/MetaHead.vue'
|
||||
import FileInput from '@/Shared/Form/FileInput.vue'
|
||||
import TextInput from '@/Shared/Form/TextInput.vue'
|
||||
import FileInputMultipleDecode from '@/Shared/Form/FileInputMultipleDecode.vue'
|
||||
import TextareaInput from '@/Shared/Form/TextareaInput.vue'
|
||||
import TagInput from '@/Shared/Form/TagInput.vue'
|
||||
import LoadingButton from '@/Shared/Form/LoadingButton.vue'
|
||||
import LinkBack from '@/Shared/Misc/LinkBack.vue'
|
||||
import WarningText from '@/Shared/Misc/WarningText.vue'
|
||||
import CreatedMediaItem from '@/Shared/Edit/CreatedMediaItem.vue'
|
||||
import ModalWarning from '@/Shared/Overlay/ModalWarning.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MetaHead,
|
||||
CreatedMediaItem,
|
||||
TextInput,
|
||||
FileInput,
|
||||
FileInputMultipleDecode,
|
||||
LoadingButton,
|
||||
WarningText,
|
||||
TextareaInput,
|
||||
LinkBack,
|
||||
TagInput,
|
||||
ModalWarning,
|
||||
},
|
||||
layout: Layout,
|
||||
props: {
|
||||
feed: Object,
|
||||
tags: Array,
|
||||
mediasCommon: Array,
|
||||
mediasPaid: Array,
|
||||
mediasCount: Number,
|
||||
mediaPreview: Object,
|
||||
},
|
||||
|
||||
setup(props) {
|
||||
const store = useStore()
|
||||
const { feed, tags, mediasCount, mediaPreview } = toRefs(props)
|
||||
|
||||
const textsBreak = computed(() => feed.value.status_note.split('\n'))
|
||||
|
||||
const modalShow = ref(false)
|
||||
|
||||
let is_disabled_create = ref(0)
|
||||
let countFiles = ref(0)
|
||||
let countFilesLoaded = ref(0)
|
||||
|
||||
// let isFeedPaid, openPaidBlock
|
||||
|
||||
let form_fields = {
|
||||
id: feed.value.id,
|
||||
title: feed.value.title,
|
||||
body: feed.value.body,
|
||||
price: feed.value.price,
|
||||
tags: tags.value,
|
||||
is_paid: feed.value.is_paid,
|
||||
|
||||
|
||||
preview: null,
|
||||
musics: null,
|
||||
musics_paid: null,
|
||||
|
||||
times: [],
|
||||
times_paid: [],
|
||||
removedItems: [],
|
||||
totalItems: mediasCount,
|
||||
}
|
||||
|
||||
if (feed.value.is_paid) {
|
||||
// isFeedPaid = ref(1)
|
||||
// openPaidBlock = ref(1)
|
||||
delete form_fields.musics_paid
|
||||
}
|
||||
// else {
|
||||
// isFeedPaid = ref(0)
|
||||
// openPaidBlock = ref(0)
|
||||
// }
|
||||
|
||||
const form = useForm(form_fields)
|
||||
|
||||
// watch(isFeedPaid, (value) => {
|
||||
// openPaidBlock.value = value
|
||||
// form.is_paid = value
|
||||
// })
|
||||
|
||||
const submit = () => {
|
||||
form.post(route('musics.update', feed.value.id), {
|
||||
onSuccess: () => {
|
||||
form.reset('musics')
|
||||
form.reset('musics_paid')
|
||||
form.reset('preview')
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const stateToggle = (id) => {
|
||||
let existID = find(form.removedItems, (itemID) => itemID === id)
|
||||
if (existID) {
|
||||
const index = form.removedItems.indexOf(existID)
|
||||
if (index > -1) {
|
||||
form.removedItems.splice(index, 1)
|
||||
}
|
||||
} else {
|
||||
form.removedItems.push(id)
|
||||
}
|
||||
}
|
||||
|
||||
const resetPlaylist = () => {
|
||||
store.dispatch('defaultPlaylistReset')
|
||||
}
|
||||
|
||||
const deleteActionModal = (remove) => {
|
||||
if (remove) {
|
||||
resetPlaylist()
|
||||
Inertia.delete(route('feed.destroy', feed.value.id), {
|
||||
preserveScroll: true,
|
||||
preserveState: true,
|
||||
})
|
||||
}
|
||||
modalShow.value = false
|
||||
}
|
||||
|
||||
const openModal = () => (modalShow.value = true)
|
||||
|
||||
const authUser = computed(() => usePage().props.value.auth.user)
|
||||
|
||||
const isFreeFeed = computed(() => feed.value.is_paid === 0)
|
||||
const textPreview = () => {
|
||||
if (mediaPreview.value) {
|
||||
return 'Обновить превью'
|
||||
}
|
||||
return 'Загрузить превью'
|
||||
}
|
||||
|
||||
const saveTimeFile = (time) => {
|
||||
form.times.push(time)
|
||||
countFilesLoaded.value++
|
||||
if (countFilesLoaded.value === countFiles.value) {
|
||||
is_disabled_create.value = 0
|
||||
}
|
||||
}
|
||||
const savePaidTimeFile = (time) => {
|
||||
form.times_paid.push(time)
|
||||
countFilesLoaded.value++
|
||||
if (countFilesLoaded.value === countFiles.value) {
|
||||
is_disabled_create.value = 0
|
||||
}
|
||||
}
|
||||
|
||||
const incrementLoadFile = () => {
|
||||
countFiles.value++
|
||||
is_disabled_create.value = 1
|
||||
}
|
||||
|
||||
const removePreview = (id) => {
|
||||
Inertia.delete(route('feed.preview.destroy', id))
|
||||
}
|
||||
|
||||
return {
|
||||
form,
|
||||
submit,
|
||||
saveTimeFile,
|
||||
savePaidTimeFile,
|
||||
incrementLoadFile,
|
||||
stateToggle,
|
||||
authUser,
|
||||
// isFeedPaid,
|
||||
// openPaidBlock,
|
||||
isFreeFeed,
|
||||
modalShow,
|
||||
deleteActionModal,
|
||||
openModal,
|
||||
textPreview,
|
||||
is_disabled_create,
|
||||
removePreview,
|
||||
textsBreak
|
||||
}
|
||||
},
|
||||
|
||||
updated() {
|
||||
if (this.feed.is_paid) {
|
||||
delete this.form.musics_paid
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
139
resources/js/Pages/Music/Feed.vue
Executable file
139
resources/js/Pages/Music/Feed.vue
Executable file
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<meta-head title="Музыка"></meta-head>
|
||||
|
||||
<div class="mb-6 py-3 banner relative bg-center bg-no-repeat bg-cover"
|
||||
style="background-image: url('/image/bg-home.jpg');">
|
||||
<div class="h-52 flex justify-center items-center text-center">
|
||||
<div class="max-w-4xl text-gray px-3">
|
||||
<h1
|
||||
class=" text-xl md:text-2xl lg:text-3xl xl:text-5xl text-white font-semibold xl:leading-relaxed">
|
||||
Музыка</h1>
|
||||
|
||||
<h2 v-if="tag" class="text-lg md:text-3xl text-gray-light">
|
||||
#{{tag.name}}
|
||||
</h2>
|
||||
|
||||
<inertia-link :href="route('musics.create')"
|
||||
class="mt-8 inline-flex tracking-wide items-center px-8 md:px-12 py-3 border border-white text-sm lg:text-lg text-white rounded-full bg-transparent hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2">
|
||||
Загрузить
|
||||
</inertia-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="xl:container xl:mx-auto px-2 md:px-3 buttons-filter-line">
|
||||
|
||||
<div class=" relative mb-5">
|
||||
<div class="absolute inset-y-0 left-3 flex items-center z-[1]">
|
||||
<svg class="flex-shrink-0 h-5 w-5 text-gray-light" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24" fill="currentColor">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M11 4a7 7 0 100 14 7 7 0 000-14zm-9 7a9 9 0 1118 0 9 9 0 01-18 0z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M15.943 15.943a1 1 0 011.414 0l4.35 4.35a1 1 0 01-1.414 1.414l-4.35-4.35a1 1 0 010-1.414z" />
|
||||
</svg>
|
||||
</div>
|
||||
<input
|
||||
v-model="form.search"
|
||||
class="relative w-full focus:ring-4 focus:ring-offset-1 focus:ring-orange focus:ring-opacity-20 focus:ring-offset-orange focus:border-transparent text-gray border border-indigo-300 bg-indigo-200 rounded-md placeholder-gray-light !pl-10 h-14" placeholder="Поиск"
|
||||
type="search">
|
||||
</div>
|
||||
|
||||
<div class="grid gap-2 md:gap-5 grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6">
|
||||
|
||||
<inertia-link :href="local_route"
|
||||
:class="[active_filter == 'new' ? 'bg-orange shadow-classic2' : 'shadow-classic bg-indigo-200 hover:bg-orange' , 'transition inline-flex items-center px-3 py-3 lg:px-6 lg:py-6 xl:px-10 text-sm lg:text-lg justify-center rounded-md text-white focus:outline-none']">
|
||||
Новинки
|
||||
</inertia-link >
|
||||
|
||||
<inertia-link :href="local_route"
|
||||
:data="{ filter: 'hot' }"
|
||||
:class="[active_filter == 'hot' ? 'bg-orange shadow-classic2' : 'shadow-classic bg-indigo-200 hover:bg-orange' , 'transition inline-flex items-center px-3 py-3 lg:px-6 lg:py-6 xl:px-10 text-sm lg:text-lg justify-center shadow-classic rounded-md text-white focus:outline-none']">
|
||||
<svg class="-ml-1 mr-2 h-4 w-4 md:h-5 md:w-5 flex-shrink-0" fill="currentColor"
|
||||
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
||||
<path
|
||||
d="M14.422 6.243c-3.57-2.172-1.895-5.238-1.824-5.365A.586.586 0 0012.09 0c-1.837 0-3.276.522-4.276 1.552-1.71 1.76-1.63 4.498-1.597 5.667.004.13.007.242.007.325 0 .868.14 1.67.263 2.377.079.456.147.85.16 1.159.012.331-.048.407-.05.41-.01.01-.081.049-.276.049a.657.657 0 01-.53-.235c-.565-.634-.604-2.365-.496-3.307a.586.586 0 00-.582-.654c-1.521 0-2.658 2.488-2.658 4.712 0 1.046.21 2.07.625 3.045a8.081 8.081 0 001.7 2.527C5.894 19.157 7.89 20 10 20c2.119 0 4.114-.83 5.618-2.34a7.892 7.892 0 002.327-5.605c0-2.692-2.107-4.95-3.523-5.812zM10 18.828c-3.671 0-6.773-3.101-6.773-6.773 0-.893.213-1.83.585-2.571.086-.173.175-.322.263-.447.01.967.163 2.284.841 3.046.366.41.852.627 1.405.627.518 0 .912-.156 1.172-.466.486-.578.337-1.436.148-2.524-.115-.66-.245-1.409-.245-2.176 0-.1-.003-.22-.007-.359-.032-1.107-.099-3.412 1.265-4.817.613-.63 1.467-1.014 2.55-1.145-.123.406-.228.92-.232 1.497-.01 1.27.476 3.085 2.841 4.524 1.145.696 2.96 2.618 2.96 4.811A6.78 6.78 0 0110 18.828z" />
|
||||
</svg>
|
||||
Популярные
|
||||
</inertia-link >
|
||||
</div>
|
||||
|
||||
<div v-if="tag" class="mt-4 grid gap-2 md:gap-5 grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6">
|
||||
<feed-tags-buttons :slug='tag.slug' />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="xl:container xl:mx-auto px-2 md:px-3 my-6">
|
||||
<button @click="resetFilter" class="button-default text-gray text-lg">Очистить фильтры</button>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="xl:container xl:mx-auto px-2 md:px-3">
|
||||
<div v-if="feeds.length" class="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">
|
||||
<feed
|
||||
:nextCursor="nextCursor"
|
||||
:feeds="feeds"
|
||||
/>
|
||||
</div>
|
||||
<div v-else class="font-bold text-xl lg:text-3xl text-gray text-center">Записи не найдены</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Inertia } from "@inertiajs/inertia";
|
||||
import throttle from "lodash/throttle";
|
||||
import pickBy from "lodash/pickBy";
|
||||
|
||||
import Feed from "@/Shared/Feed/Feed.vue";
|
||||
import Layout from "@/Shared/Layout.vue";
|
||||
import MetaHead from "@/Shared/MetaHead.vue";
|
||||
import FeedTagsButtons from "@/Shared/Misc/FeedTagsButtons.vue";
|
||||
|
||||
export default {
|
||||
layout: Layout,
|
||||
components: {
|
||||
MetaHead,
|
||||
FeedTagsButtons,
|
||||
Feed,
|
||||
},
|
||||
props: {
|
||||
feeds: Array,
|
||||
local_route: String,
|
||||
active_filter: String,
|
||||
tag: { type: [Object, Boolean], default: false },
|
||||
searchFilters: Object,
|
||||
nextCursor: String,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
search: this.searchFilters.search,
|
||||
},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
form: {
|
||||
deep: true,
|
||||
handler: throttle(function () {
|
||||
Inertia.get(this.local_route, pickBy(this.form), {
|
||||
preserveScroll: true, preserveState: true
|
||||
});
|
||||
}, 500),
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
methods: {
|
||||
resetFilter() {
|
||||
Inertia.get(
|
||||
this.local_route,
|
||||
{},
|
||||
{
|
||||
preserveScroll: true,
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
78
resources/js/Pages/Music/Show.vue
Executable file
78
resources/js/Pages/Music/Show.vue
Executable file
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
|
||||
<Head>
|
||||
<title>{{feed.entity.title}}</title>
|
||||
<meta name="description" :content="feed.entity.body">
|
||||
<meta property="og:url" :content="route(`${feed.entity.type}.show`, feed.entity.slug)">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" :content="feed.entity.title">
|
||||
<meta property="og:description" :content="feed.entity.body">
|
||||
<meta property="og:image" :content="feed.entity.preview">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
|
||||
<!-- <meta name="twitter:title" :content="feed.entity.title">
|
||||
<meta name="twitter:description" :content="feed.entity.body">
|
||||
<meta name="twitter:image" :content="feed.entity.preview">
|
||||
<meta name="twitter:card" content="summary_large_image"> -->
|
||||
|
||||
</Head>
|
||||
|
||||
<header-auth v-if="!$page.props.auth.user" />
|
||||
|
||||
<modal-share :entity='feed.entity' ref="shareModalNode" />
|
||||
<div class="mt-16 container mx-auto px-2 md:px-6 2xl:px-28 md:grid grid-cols-12 ">
|
||||
<modal-feed-media
|
||||
:type='feed.type'
|
||||
:feed_id='feed.id'
|
||||
:title='feed.entity.title'
|
||||
:preview='feed.entity.preview'
|
||||
:medias='feed.entity.collection_medias'
|
||||
class="border-l border-r md:border-r-0 border-t border-b border-indigo-100"
|
||||
/>
|
||||
|
||||
<modal-feed-body
|
||||
@openShare='showShareModal'
|
||||
:user='user'
|
||||
:feed_id='feed.id'
|
||||
:entity='feed.entity'
|
||||
class="border-r md:border-t border-b border-indigo-100"
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Head } from "@inertiajs/inertia-vue3";
|
||||
import Layout from "@/Shared/Layout.vue";
|
||||
import HeaderAuth from "@/Shared/LayoutParts/HeaderAuth.vue";
|
||||
import ModalFeedMedia from "@/Shared/Overlay/ModalFeedMedia.vue";
|
||||
import ModalFeedBody from "@/Shared/Overlay/ModalFeedBody.vue";
|
||||
import ModalShare from "@/Shared/Overlay/ModalShare.vue";
|
||||
|
||||
export default {
|
||||
layout: Layout,
|
||||
components: {
|
||||
Head,
|
||||
ModalShare,
|
||||
ModalFeedMedia,
|
||||
ModalFeedBody,
|
||||
HeaderAuth
|
||||
},
|
||||
props: {
|
||||
feed: Object,
|
||||
user: Object,
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
is_exist_menu: false
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
showShareModal() {
|
||||
this.$refs.shareModalNode.openModal();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
Reference in New Issue
Block a user