init
This commit is contained in:
105
frontend/src/components/tracks/UploadTrack.vue
Normal file
105
frontend/src/components/tracks/UploadTrack.vue
Normal file
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<form @submit.prevent="handleUpload" class="upload-form">
|
||||
<div class="form-group">
|
||||
<label>MP3 файл (макс. 10MB)</label>
|
||||
<input
|
||||
type="file"
|
||||
accept="audio/mpeg,audio/mp3"
|
||||
@change="handleFileSelect"
|
||||
required
|
||||
ref="fileInput"
|
||||
/>
|
||||
<small class="hint">Название и исполнитель будут взяты из тегов файла</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Название <span class="optional">(необязательно)</span></label>
|
||||
<input type="text" v-model="title" placeholder="Оставьте пустым для автоопределения" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Исполнитель <span class="optional">(необязательно)</span></label>
|
||||
<input type="text" v-model="artist" placeholder="Оставьте пустым для автоопределения" />
|
||||
</div>
|
||||
<p v-if="error" class="error-message">{{ error }}</p>
|
||||
<button type="submit" class="btn-primary" :disabled="uploading">
|
||||
{{ uploading ? 'Загрузка...' : 'Загрузить' }}
|
||||
</button>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { useTracksStore } from '../../stores/tracks'
|
||||
|
||||
const emit = defineEmits(['uploaded'])
|
||||
|
||||
const tracksStore = useTracksStore()
|
||||
|
||||
const title = ref('')
|
||||
const artist = ref('')
|
||||
const file = ref(null)
|
||||
const fileInput = ref(null)
|
||||
const error = ref('')
|
||||
const uploading = ref(false)
|
||||
|
||||
function handleFileSelect(e) {
|
||||
const selectedFile = e.target.files[0]
|
||||
if (!selectedFile) return
|
||||
|
||||
// Check file size (10MB)
|
||||
if (selectedFile.size > 10 * 1024 * 1024) {
|
||||
error.value = 'Файл слишком большой (макс. 10MB)'
|
||||
fileInput.value.value = ''
|
||||
return
|
||||
}
|
||||
|
||||
file.value = selectedFile
|
||||
error.value = ''
|
||||
}
|
||||
|
||||
async function handleUpload() {
|
||||
if (!file.value) {
|
||||
error.value = 'Выберите файл'
|
||||
return
|
||||
}
|
||||
|
||||
uploading.value = true
|
||||
error.value = ''
|
||||
|
||||
try {
|
||||
await tracksStore.uploadTrack(file.value, title.value, artist.value)
|
||||
title.value = ''
|
||||
artist.value = ''
|
||||
file.value = null
|
||||
fileInput.value.value = ''
|
||||
emit('uploaded')
|
||||
} catch (e) {
|
||||
error.value = e.response?.data?.detail || 'Ошибка загрузки'
|
||||
} finally {
|
||||
uploading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.upload-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.upload-form input[type="file"] {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.hint {
|
||||
color: #888;
|
||||
font-size: 12px;
|
||||
margin-top: 4px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.optional {
|
||||
color: #666;
|
||||
font-weight: normal;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user