Compare commits
4 Commits
74e0463393
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 7c77d0942c | |||
| 6c81e7a4c5 | |||
| c55b28f1b8 | |||
| cc8804672c |
@@ -44,13 +44,39 @@ class SongController extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @return void
|
* @param int $id
|
||||||
* @param mixed $id
|
|
||||||
*/
|
*/
|
||||||
public function update(Request $request, $id):void
|
public function update(Request $request, $id)
|
||||||
{
|
{
|
||||||
// Update specified song
|
// Actualizar cancion
|
||||||
|
$song = Song::find($id);
|
||||||
|
$this->authorize("update", $song);
|
||||||
|
|
||||||
|
$validated = $request->validate([
|
||||||
|
'title' => 'required|string',
|
||||||
|
'artist' => 'required|string',
|
||||||
|
'cover' => 'nullable|image|max:2048',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($request->hasFile('cover')){
|
||||||
|
if ($song->cover){
|
||||||
|
$coverfile = "covers/". $song->cover;
|
||||||
|
Storage::delete($coverfile);
|
||||||
}
|
}
|
||||||
|
$request->cover->store('covers');
|
||||||
|
$song->cover = "covers/" . $request->cover->getClientOriginalName();
|
||||||
|
}
|
||||||
|
|
||||||
|
$song->title = $validated['title'];
|
||||||
|
$song->artist = $validated['artist'];
|
||||||
|
|
||||||
|
$song->save();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'data' => 'Updated successfully'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $id
|
* @param int $id
|
||||||
*/
|
*/
|
||||||
@@ -71,6 +97,16 @@ class SongController extends Controller
|
|||||||
}
|
}
|
||||||
return response()->noContent(200);
|
return response()->noContent(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function viewcover($id){
|
||||||
|
$song = Song::find($id);
|
||||||
|
|
||||||
|
$this->authorize('view', $song);
|
||||||
|
if ($song && Storage::exists($song->cover)){
|
||||||
|
return response()->file(Storage::path($song->cover));
|
||||||
|
}
|
||||||
|
abort(404, 'Cover no encontrado');
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @param int $id
|
* @param int $id
|
||||||
*/
|
*/
|
||||||
|
|||||||
56
resources/js/Components/ModalEditarCancion.tsx
Normal file
56
resources/js/Components/ModalEditarCancion.tsx
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { Cancion } from '@/types/types';
|
||||||
|
import { Input } from '@headlessui/react';
|
||||||
|
import { FormEvent } from 'react';
|
||||||
|
import InputLabel from './InputLabel';
|
||||||
|
import Modal from './Modal';
|
||||||
|
import PrimaryButton from './PrimaryButton';
|
||||||
|
|
||||||
|
export default function ModalEditarCancion({
|
||||||
|
showEditModal,
|
||||||
|
UpdateCallback,
|
||||||
|
setShowEditModal,
|
||||||
|
song,
|
||||||
|
}: {
|
||||||
|
song: Cancion;
|
||||||
|
showEditModal: boolean;
|
||||||
|
UpdateCallback: (event: FormEvent<HTMLFormElement>) => void;
|
||||||
|
setShowEditModal: (arg0: boolean) => void;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
show={showEditModal}
|
||||||
|
onClose={() => setShowEditModal(false)}
|
||||||
|
closeable={true}
|
||||||
|
maxWidth="md"
|
||||||
|
>
|
||||||
|
<form onSubmit={UpdateCallback} className="p-6">
|
||||||
|
<h2 className="mb-2 text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||||
|
Editando Datos Cancion
|
||||||
|
</h2>
|
||||||
|
<hr />
|
||||||
|
<div className="mt-2">
|
||||||
|
<InputLabel>Titulo</InputLabel>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
name="title"
|
||||||
|
defaultValue={song.title}
|
||||||
|
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm hover:bg-gray-700 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300"
|
||||||
|
/>
|
||||||
|
<InputLabel>Artista</InputLabel>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
name="artist"
|
||||||
|
defaultValue={song.artist}
|
||||||
|
className="mt-1 block w-full rounded-md border-gray-300 shadow-sm hover:bg-gray-700 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300"
|
||||||
|
/>
|
||||||
|
<hr className="mt-2" />
|
||||||
|
<div className="flex place-content-center">
|
||||||
|
<PrimaryButton className="mt-2" type="submit">
|
||||||
|
Subir Cambios
|
||||||
|
</PrimaryButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,15 +1,17 @@
|
|||||||
import BotonAdd from '@/Components/BotonAdd';
|
import BotonAdd from '@/Components/BotonAdd';
|
||||||
import ModalAñadirCancion from '@/Components/ModalAñadirCancion';
|
import ModalAñadirCancion from '@/Components/ModalAñadirCancion';
|
||||||
|
import ModalEditarCancion from '@/Components/ModalEditarCancion';
|
||||||
import ModalRemoveCancion from '@/Components/ModalRemoveCancion';
|
import ModalRemoveCancion from '@/Components/ModalRemoveCancion';
|
||||||
import Authenticated from '@/Layouts/AuthenticatedLayout';
|
import Authenticated from '@/Layouts/AuthenticatedLayout';
|
||||||
import { Cancion } from '@/types/types';
|
import { Cancion } from '@/types/types';
|
||||||
import { Head } from '@inertiajs/react';
|
import { Head, router } from '@inertiajs/react';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { FormEvent, useEffect, useState } from 'react';
|
import { FormEvent, useEffect, useState } from 'react';
|
||||||
|
|
||||||
export default function Index({ songs }: { songs: Cancion[] }) {
|
export default function Index({ songs }: { songs: Cancion[] }) {
|
||||||
const [showaddmodal, setshowmodal] = useState(false);
|
const [showaddmodal, setshowmodal] = useState(false);
|
||||||
const [showRemove, setRemove] = useState(false);
|
const [showRemove, setRemove] = useState(false);
|
||||||
|
const [showEdit, setEdit] = useState(false);
|
||||||
const [selcan, setcan] = useState<Cancion>({} as Cancion);
|
const [selcan, setcan] = useState<Cancion>({} as Cancion);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -40,7 +42,8 @@ export default function Index({ songs }: { songs: Cancion[] }) {
|
|||||||
})
|
})
|
||||||
.then((response: { data: string }) => {
|
.then((response: { data: string }) => {
|
||||||
console.log('Song added successfully', response.data);
|
console.log('Song added successfully', response.data);
|
||||||
window.location.reload();
|
router.reload();
|
||||||
|
setshowmodal(false);
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
setshowmodal(false);
|
setshowmodal(false);
|
||||||
@@ -54,7 +57,7 @@ export default function Index({ songs }: { songs: Cancion[] }) {
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
setcan({} as Cancion);
|
setcan({} as Cancion);
|
||||||
setRemove(false);
|
setRemove(false);
|
||||||
window.location.reload();
|
router.reload();
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Error removing song:', error);
|
console.error('Error removing song:', error);
|
||||||
@@ -62,6 +65,27 @@ export default function Index({ songs }: { songs: Cancion[] }) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleUpdate(event: FormEvent<HTMLFormElement>) {
|
||||||
|
event.preventDefault();
|
||||||
|
const formData = new FormData(event.currentTarget);
|
||||||
|
const title = formData.get('title');
|
||||||
|
const artist = formData.get('artist');
|
||||||
|
|
||||||
|
axios
|
||||||
|
.put(`/canciones/${selcan.id}`, {
|
||||||
|
title: title,
|
||||||
|
artist: artist,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
setEdit(false);
|
||||||
|
router.reload();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error actualizando datos de la cancion', error);
|
||||||
|
setEdit(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Authenticated
|
<Authenticated
|
||||||
header={
|
header={
|
||||||
@@ -106,7 +130,13 @@ export default function Index({ songs }: { songs: Cancion[] }) {
|
|||||||
{song.path}
|
{song.path}
|
||||||
</td>
|
</td>
|
||||||
<td className="whitespace-nowrap px-6 py-4 text-sm">
|
<td className="whitespace-nowrap px-6 py-4 text-sm">
|
||||||
<button className="mr-2 rounded-md bg-indigo-600 px-4 py-2 text-sm font-medium text-white hover:bg-indigo-700">
|
<button
|
||||||
|
className="mr-2 rounded-md bg-indigo-600 px-4 py-2 text-sm font-medium text-white hover:bg-indigo-700"
|
||||||
|
onClick={() => {
|
||||||
|
setcan(song);
|
||||||
|
setEdit(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
Editar
|
Editar
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
@@ -137,6 +167,12 @@ export default function Index({ songs }: { songs: Cancion[] }) {
|
|||||||
cancion={selcan}
|
cancion={selcan}
|
||||||
remove={handleRemove}
|
remove={handleRemove}
|
||||||
/>
|
/>
|
||||||
|
<ModalEditarCancion
|
||||||
|
song={selcan}
|
||||||
|
showEditModal={showEdit}
|
||||||
|
setShowEditModal={setEdit}
|
||||||
|
UpdateCallback={handleUpdate}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Authenticated>
|
</Authenticated>
|
||||||
);
|
);
|
||||||
|
|||||||
2
resources/js/types/types.d.ts
vendored
2
resources/js/types/types.d.ts
vendored
@@ -1,7 +1,7 @@
|
|||||||
export type Cancion = {
|
export type Cancion = {
|
||||||
id: number;
|
id: number;
|
||||||
title: string;
|
title: string;
|
||||||
artist: string | null;
|
artist: string;
|
||||||
path: string;
|
path: string;
|
||||||
cover: string | null;
|
cover: string | null;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -31,5 +31,6 @@ Route::get('/canciones/stream/{id}', [SongController::class, 'stream']);
|
|||||||
Route::post('/canciones', [SongController::class, 'store']);
|
Route::post('/canciones', [SongController::class, 'store']);
|
||||||
Route::put('/canciones/{id}', [SongController::class, 'update']);
|
Route::put('/canciones/{id}', [SongController::class, 'update']);
|
||||||
Route::delete('/canciones/{id}', [SongController::class, 'destroy'])->middleware(['auth', 'verified']);
|
Route::delete('/canciones/{id}', [SongController::class, 'destroy'])->middleware(['auth', 'verified']);
|
||||||
|
Route::get('/canciones/cover/{id}', [SongController::class], 'viewcover')
|
||||||
|
|
||||||
require __DIR__.'/auth.php';
|
require __DIR__.'/auth.php';
|
||||||
|
|||||||
Reference in New Issue
Block a user