You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
5.4 KiB
PHP

<?php
namespace App\Http\Controllers\Administracion;
use App\Http\Controllers\Controller;
use App\Models\Comunicado;
use App\Models\ComunicadoImagen;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Carbon\Carbon;
class ComunicadoController extends Controller
{
// Admin: lista paginada
public function index(Request $request)
{
$comunicados = Comunicado::with('imagenes')
->orderByDesc('created_at')
->paginate(10);
return response()->json($comunicados);
}
// Admin: crear comunicado
public function store(Request $request)
{
$request->validate([
'titulo' => 'required|string|max:255',
'fecha_inicio' => 'nullable|date',
'fecha_fin' => 'nullable|date|after_or_equal:fecha_inicio',
'url_accion' => 'nullable|url|max:500',
'texto_boton' => 'nullable|string|max:60',
'imagenes' => 'required|array|min:1',
'imagenes.*' => 'required|file|mimes:jpg,jpeg,png,webp|max:5120',
]);
$comunicado = Comunicado::create([
'titulo' => $request->titulo,
'activo' => false,
'fecha_inicio' => $request->fecha_inicio,
'fecha_fin' => $request->fecha_fin,
'url_accion' => $request->url_accion,
'texto_boton' => $request->texto_boton,
]);
foreach ($request->file('imagenes') as $orden => $imagen) {
$filename = uniqid() . '.' . $imagen->getClientOriginalExtension();
$path = "comunicados/{$comunicado->id}/{$filename}";
Storage::disk('public')->put($path, file_get_contents($imagen->getRealPath()));
ComunicadoImagen::create([
'comunicado_id' => $comunicado->id,
'imagen_path' => $path,
'orden' => $orden + 1,
]);
}
return response()->json($comunicado->load('imagenes'), 201);
}
// Admin: actualizar comunicado
public function update(Request $request, int $id)
{
$comunicado = Comunicado::findOrFail($id);
$request->validate([
'titulo' => 'sometimes|required|string|max:255',
'fecha_inicio' => 'nullable|date',
'fecha_fin' => 'nullable|date|after_or_equal:fecha_inicio',
'url_accion' => 'nullable|url|max:500',
'texto_boton' => 'nullable|string|max:60',
'imagenes' => 'sometimes|array|min:1',
'imagenes.*' => 'file|mimes:jpg,jpeg,png,webp|max:5120',
]);
$comunicado->update($request->only('titulo', 'fecha_inicio', 'fecha_fin', 'url_accion', 'texto_boton'));
// Si se enviaron nuevas imágenes, AGREGAR a las existentes (no reemplazar)
if ($request->hasFile('imagenes')) {
$maxOrden = $comunicado->imagenes()->max('orden') ?? 0;
foreach ($request->file('imagenes') as $idx => $imagen) {
$filename = uniqid() . '.' . $imagen->getClientOriginalExtension();
$path = "comunicados/{$comunicado->id}/{$filename}";
Storage::disk('public')->put($path, file_get_contents($imagen->getRealPath()));
ComunicadoImagen::create([
'comunicado_id' => $comunicado->id,
'imagen_path' => $path,
'orden' => $maxOrden + $idx + 1,
]);
}
}
return response()->json($comunicado->load('imagenes'));
}
// Admin: eliminar comunicado
public function destroy(int $id)
{
$comunicado = Comunicado::with('imagenes')->findOrFail($id);
foreach ($comunicado->imagenes as $img) {
Storage::disk('public')->delete($img->imagen_path);
}
$comunicado->delete();
return response()->json(['message' => 'Comunicado eliminado correctamente.']);
}
// Admin: activar/desactivar (uno activo a la vez)
public function toggleActivo(int $id)
{
$comunicado = Comunicado::findOrFail($id);
if ($comunicado->activo) {
// Si ya estaba activo, simplemente lo desactiva
$comunicado->update(['activo' => false]);
} else {
// Desactiva todos los demás y activa este
Comunicado::where('activo', true)->update(['activo' => false]);
$comunicado->update(['activo' => true]);
}
return response()->json($comunicado->load('imagenes'));
}
// Admin: eliminar una imagen individual
public function destroyImagen(int $imagenId)
{
$imagen = ComunicadoImagen::findOrFail($imagenId);
Storage::disk('public')->delete($imagen->imagen_path);
$imagen->delete();
return response()->json(['message' => 'Imagen eliminada correctamente.']);
}
// Público: devuelve el comunicado activo con sus imágenes (respeta vigencia)
public function activo()
{
$hoy = Carbon::today();
$comunicado = Comunicado::with('imagenes')
->where('activo', true)
->where(function ($q) use ($hoy) {
$q->whereNull('fecha_inicio')->orWhere('fecha_inicio', '<=', $hoy);
})
->where(function ($q) use ($hoy) {
$q->whereNull('fecha_fin')->orWhere('fecha_fin', '>=', $hoy);
})
->first();
return response()->json($comunicado);
}
}