Последняя версия с сервера прошлого разработчика

This commit is contained in:
2025-07-10 04:35:51 +00:00
commit c731570032
1174 changed files with 134314 additions and 0 deletions

416
resources/js/Pages/Music/Edit.vue Executable file
View 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>