plicación Web CRUD de Películas con Laravel
- Obtener vínculo
- X
- Correo electrónico
- Otras apps
plicación Web CRUD de Películas con Laravel
Para Principiantes - Sin Resumen, Paso a Paso
📋 TABLA DE CONTENIDO
1. PRERREQUISITOS E INSTALACIÓN
1.1 Instalar Composer (si no lo tienes)
Descarga de: https://getcomposer.org/
En Windows, usa el instalador .exe
En Linux/Mac:
bashphp -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" php composer-setup.php php -r "unlink('composer-setup.php');" sudo mv composer.phar /usr/local/bin/composer
1.2 Instalar Laravel
bash
# Instalar globalmente el instalador de Laravel
composer global require laravel/installer
# Crear nuevo proyecto (llamémoslo 'peliculas-app')
laravel new peliculas-app
# O alternativamente
composer create-project laravel/laravel peliculas-app1.3 Entrar al directorio del proyecto
bash
cd peliculas-app1.4 Instalar dependencias adicionales (opcional pero recomendado)
bash
composer require laravel/ui2. CONFIGURACIÓN DEL PROYECTO
2.1 Configurar variables de entorno
Abre el archivo .env y configura:
env
APP_NAME=PeliculasApp
APP_ENV=local
APP_KEY=base64:...
APP_DEBUG=true
APP_URL=http://localhost
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=peliculas_db
DB_USERNAME=root
DB_PASSWORD=
# Configuración de correo (puedes dejarlo así por ahora)
MAIL_MAILER=smtp
MAIL_HOST=mailpit
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null2.2 Generar clave de aplicación
bash
php artisan key:generate2.3 Servir la aplicación localmente
bash
# En una terminal ejecuta:
php artisan serveAbre tu navegador en: http://localhost:8000
3. CONFIGURACIÓN DE BASE DE DATOS
3.1 Crear la base de datos en MySQL
sql
-- Abre MySQL desde terminal o phpMyAdmin
CREATE DATABASE peliculas_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;3.2 Verificar conexión
bash
php artisan migrate:status4. MODELO, MIGRACIÓN Y SEEDER
4.1 Crear Modelo con Migración
bash
php artisan make:model Movie -m4.2 Editar la migración
Abre database/migrations/xxxx_xx_xx_xxxxxx_create_movies_table.php:
php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('movies', function (Blueprint $table) {
$table->id();
$table->string('title', 200);
$table->text('description')->nullable();
$table->integer('year');
$table->integer('duration')->comment('Duración en minutos');
$table->string('director', 100);
$table->string('genre', 100);
$table->decimal('rating', 3, 1)->default(0.0);
$table->string('poster_url')->nullable();
$table->boolean('available')->default(true);
$table->timestamps(); // created_at y updated_at automáticos
});
}
public function down(): void
{
Schema::dropIfExists('movies');
}
};4.3 Ejecutar migración
bash
php artisan migrate4.4 Crear Seeder
bash
php artisan make:seeder MovieSeeder4.5 Editar el Seeder
Abre database/seeders/MovieSeeder.php:
php
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\Movie;
use Illuminate\Support\Facades\DB;
class MovieSeeder extends Seeder
{
public function run(): void
{
// Limpiar tabla primero
DB::table('movies')->truncate();
$movies = [
[
'title' => 'El Padrino',
'description' => 'La saga de la familia Corleone, una poderosa familia mafiosa de Nueva York.',
'year' => 1972,
'duration' => 175,
'director' => 'Francis Ford Coppola',
'genre' => 'Crimen, Drama',
'rating' => 9.2,
'poster_url' => 'https://image.tmdb.org/t/p/w500/rSPw7tgCH9c6NqICZef4kZjFOQ5.jpg',
'available' => true,
],
[
'title' => 'Pulp Fiction',
'description' => 'Las vidas de dos matones, un boxeador y una pareja de atracadores se entrelazan.',
'year' => 1994,
'duration' => 154,
'director' => 'Quentin Tarantino',
'genre' => 'Crimen, Drama',
'rating' => 8.9,
'poster_url' => 'https://image.tmdb.org/t/p/w500/d5iIlFn5s0ImszYzBPb8JPIfbXD.jpg',
'available' => true,
],
[
'title' => 'El Señor de los Anillos: El Retorno del Rey',
'description' => 'Gandalf y Aragorn lideran el mundo de los hombres contra Sauron.',
'year' => 2003,
'duration' => 201,
'director' => 'Peter Jackson',
'genre' => 'Aventura, Fantasía',
'rating' => 9.0,
'poster_url' => 'https://image.tmdb.org/t/p/w500/rCzpDGLbOoPwLjy3OAm5NUPOTrC.jpg',
'available' => true,
],
[
'title' => 'Origen',
'description' => 'Un ladrón que roba secretos mediante el uso de tecnología para compartir sueños.',
'year' => 2010,
'duration' => 148,
'director' => 'Christopher Nolan',
'genre' => 'Ciencia Ficción, Acción',
'rating' => 8.8,
'poster_url' => 'https://image.tmdb.org/t/p/w500/9gk7adHYeDvHkCSEqAvQNLV5Uge.jpg',
'available' => false,
],
[
'title' => 'Parásitos',
'description' => 'Una familia pobre que se infiltra en una familia adinerada.',
'year' => 2019,
'duration' => 132,
'director' => 'Bong Joon Ho',
'genre' => 'Comedia, Drama, Thriller',
'rating' => 8.6,
'poster_url' => 'https://image.tmdb.org/t/p/w500/7IiTTgloJzvGI1TAYymCfbfl3vT.jpg',
'available' => true,
],
];
foreach ($movies as $movie) {
Movie::create($movie);
}
$this->command->info('¡Películas insertadas correctamente!');
}
}4.6 Actualizar DatabaseSeeder
Abre database/seeders/DatabaseSeeder.php:
php
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run(): void
{
$this->call([
MovieSeeder::class,
]);
}
}4.7 Ejecutar el Seeder
bash
php artisan db:seed
# O para refrescar todo
php artisan migrate:fresh --seed4.8 Editar el Modelo
Abre app/Models/Movie.php:
php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Movie extends Model
{
use HasFactory;
// Campos que se pueden llenar masivamente
protected $fillable = [
'title',
'description',
'year',
'duration',
'director',
'genre',
'rating',
'poster_url',
'available'
];
// Campos que deben ser convertidos a tipos específicos
protected $casts = [
'rating' => 'float',
'available' => 'boolean',
'year' => 'integer',
'duration' => 'integer'
];
// Validación de datos (opcional pero útil)
public static $rules = [
'title' => 'required|string|max:200',
'description' => 'nullable|string',
'year' => 'required|integer|min:1888|max:' . (date('Y') + 5),
'duration' => 'required|integer|min:1|max:500',
'director' => 'required|string|max:100',
'genre' => 'required|string|max:100',
'rating' => 'numeric|min:0|max:10',
'poster_url' => 'nullable|url',
'available' => 'boolean'
];
}5. RUTAS Y CONTROLADORES
5.1 Crear Controlador de Películas
bash
php artisan make:controller MovieController --resource5.2 Editar el Controlador
Abre app/Http/Controllers/MovieController.php:
php
<?php
namespace App\Http\Controllers;
use App\Models\Movie;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
class MovieController extends Controller
{
/**
* Mostrar lista de todas las películas
*/
public function index()
{
$movies = Movie::orderBy('title')->get();
return view('movies.index', compact('movies'));
}
/**
* Mostrar formulario para crear nueva película
*/
public function create()
{
return view('movies.create');
}
/**
* Guardar nueva película en la base de datos
*/
public function store(Request $request)
{
// Validar datos
$validator = Validator::make($request->all(), Movie::$rules);
if ($validator->fails()) {
return redirect()->back()
->withErrors($validator)
->withInput();
}
// Crear película
Movie::create($request->all());
return redirect()->route('movies.index')
->with('success', 'Película creada exitosamente!');
}
/**
* Mostrar detalles de una película específica
*/
public function show($id)
{
$movie = Movie::findOrFail($id);
return view('movies.show', compact('movie'));
}
/**
* Mostrar formulario para editar una película
*/
public function edit($id)
{
$movie = Movie::findOrFail($id);
return view('movies.edit', compact('movie'));
}
/**
* Actualizar película en la base de datos
*/
public function update(Request $request, $id)
{
// Validar datos
$validator = Validator::make($request->all(), Movie::$rules);
if ($validator->fails()) {
return redirect()->back()
->withErrors($validator)
->withInput();
}
// Actualizar película
$movie = Movie::findOrFail($id);
$movie->update($request->all());
return redirect()->route('movies.show', $id)
->with('success', 'Película actualizada exitosamente!');
}
/**
* Eliminar una película
*/
public function destroy($id)
{
$movie = Movie::findOrFail($id);
$movie->delete();
return redirect()->route('movies.index')
->with('success', 'Película eliminada exitosamente!');
}
}5.3 Configurar las Rutas
Abre routes/web.php:
php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\MovieController;
// Ruta principal - redirige a lista de películas
Route::get('/', function () {
return redirect()->route('movies.index');
});
// Rutas CRUD para películas
Route::resource('movies', MovieController::class);
// Ruta adicional para buscar películas
Route::get('/search', [MovieController::class, 'search'])->name('movies.search');
// Ruta para información sobre la aplicación
Route::get('/about', function () {
return view('about');
})->name('about');5.4 Crear Ruta para Búsqueda
Agrega este método al MovieController:
php
/**
* Buscar películas
*/
public function search(Request $request)
{
$search = $request->input('search');
$movies = Movie::where('title', 'like', "%$search%")
->orWhere('director', 'like', "%$search%")
->orWhere('genre', 'like', "%$search%")
->orWhere('description', 'like', "%$search%")
->orderBy('title')
->get();
return view('movies.index', compact('movies', 'search'));
}6. LAYOUTS Y VISTAS
6.1 Crear Layout Principal
Crea el archivo resources/views/layouts/app.blade.php:
html
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@yield('title') - Películas App</title>
<!-- Bootstrap 5 CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- CSS Personalizado -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
@stack('styles')
</head>
<body>
<!-- Barra de Navegación -->
<nav class="navbar navbar-expand-lg navbar-dark bg-primary shadow">
<div class="container">
<a class="navbar-brand" href="{{ route('movies.index') }}">
<i class="fas fa-film"></i> Películas App
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link {{ request()->routeIs('movies.index') ? 'active' : '' }}"
href="{{ route('movies.index') }}">
<i class="fas fa-home"></i> Inicio
</a>
</li>
<li class="nav-item">
<a class="nav-link {{ request()->routeIs('movies.create') ? 'active' : '' }}"
href="{{ route('movies.create') }}">
<i class="fas fa-plus-circle"></i> Nueva Película
</a>
</li>
<li class="nav-item">
<a class="nav-link {{ request()->routeIs('about') ? 'active' : '' }}"
href="{{ route('about') }}">
<i class="fas fa-info-circle"></i> Acerca de
</a>
</li>
</ul>
<!-- Buscador -->
<form class="d-flex ms-3" action="{{ route('movies.search') }}" method="GET">
<div class="input-group">
<input type="text" class="form-control" name="search"
placeholder="Buscar películas..." value="{{ request('search') ?? '' }}">
<button class="btn btn-light" type="submit">
<i class="fas fa-search"></i>
</button>
</div>
</form>
</div>
</div>
</nav>
<!-- Contenido Principal -->
<main class="py-4">
<div class="container">
<!-- Mensajes Flash -->
@if(session('success'))
<div class="alert alert-success alert-dismissible fade show" role="alert">
{{ session('success') }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
@endif
@if(session('error'))
<div class="alert alert-danger alert-dismissible fade show" role="alert">
{{ session('error') }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
@endif
@if($errors->any())
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<ul class="mb-0">
@foreach($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
@endif
<!-- Contenido de la Página -->
@yield('content')
</div>
</main>
<!-- Footer -->
<footer class="bg-dark text-white py-4 mt-5">
<div class="container">
<div class="row">
<div class="col-md-6">
<h5><i class="fas fa-film"></i> Películas App</h5>
<p>Gestiona tu colección de películas favoritas</p>
</div>
<div class="col-md-6 text-md-end">
<p class="mb-0">
© {{ date('Y') }} Películas App. Todos los derechos reservados.
</p>
<p class="mb-0">
Desarrollado con Laravel <i class="fas fa-heart text-danger"></i>
</p>
</div>
</div>
</div>
</footer>
<!-- Bootstrap JS y Dependencias -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
<!-- Scripts Personalizados -->
<script src="{{ asset('js/app.js') }}"></script>
@stack('scripts')
</body>
</html>6.2 Crear Vista de Página Principal
Crea resources/views/home.blade.php:
html
@extends('layouts.app')
@section('title', 'Inicio')
@section('content')
<div class="row mb-4">
<div class="col-12">
<div class="jumbotron bg-light p-5 rounded">
<h1 class="display-4"><i class="fas fa-film text-primary"></i> Bienvenido a Películas App</h1>
<p class="lead">Gestiona tu colección de películas favoritas de manera sencilla y eficiente.</p>
<hr class="my-4">
<p>Desde aquí puedes ver todas las películas, agregar nuevas, editar existentes y mucho más.</p>
<a class="btn btn-primary btn-lg" href="{{ route('movies.index') }}">
<i class="fas fa-play-circle"></i> Ver Películas
</a>
<a class="btn btn-success btn-lg" href="{{ route('movies.create') }}">
<i class="fas fa-plus"></i> Agregar Nueva
</a>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4 mb-4">
<div class="card h-100 text-center">
<div class="card-body">
<i class="fas fa-list fa-3x text-primary mb-3"></i>
<h4 class="card-title">Ver Todas</h4>
<p class="card-text">Consulta el listado completo de películas en tu colección.</p>
</div>
<div class="card-footer bg-transparent">
<a href="{{ route('movies.index') }}" class="btn btn-outline-primary">Ir al Listado</a>
</div>
</div>
</div>
<div class="col-md-4 mb-4">
<div class="card h-100 text-center">
<div class="card-body">
<i class="fas fa-plus-circle fa-3x text-success mb-3"></i>
<h4 class="card-title">Agregar Nueva</h4>
<p class="card-text">Añade nuevas películas a tu colección con todos sus detalles.</p>
</div>
<div class="card-footer bg-transparent">
<a href="{{ route('movies.create') }}" class="btn btn-outline-success">Crear Película</a>
</div>
</div>
</div>
<div class="col-md-4 mb-4">
<div class="card h-100 text-center">
<div class="card-body">
<i class="fas fa-search fa-3x text-info mb-3"></i>
<h4 class="card-title">Buscar</h4>
<p class="card-text">Encuentra películas por título, director, género o descripción.</p>
</div>
<div class="card-footer bg-transparent">
<form action="{{ route('movies.search') }}" method="GET" class="input-group">
<input type="text" class="form-control" name="search" placeholder="Buscar...">
<button class="btn btn-outline-info" type="submit">
<i class="fas fa-search"></i>
</button>
</form>
</div>
</div>
</div>
</div>
<div class="row mt-5">
<div class="col-12">
<div class="card">
<div class="card-header bg-info text-white">
<h5 class="mb-0"><i class="fas fa-chart-line"></i> Estadísticas Rápidas</h5>
</div>
<div class="card-body">
<div class="row text-center">
<div class="col-md-3">
<h3 class="text-primary">{{ \App\Models\Movie::count() }}</h3>
<p class="text-muted">Películas Totales</p>
</div>
<div class="col-md-3">
<h3 class="text-success">{{ \App\Models\Movie::where('available', true)->count() }}</h3>
<p class="text-muted">Disponibles</p>
</div>
<div class="col-md-3">
<h3 class="text-warning">{{ \App\Models\Movie::avg('rating') ? number_format(\App\Models\Movie::avg('rating'), 1) : '0.0' }}</h3>
<p class="text-muted">Rating Promedio</p>
</div>
<div class="col-md-3">
<h3 class="text-danger">{{ \App\Models\Movie::max('year') }}</h3>
<p class="text-muted">Año Más Reciente</p>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection6.3 Crear Vista About
Crea resources/views/about.blade.php:
html
@extends('layouts.app')
@section('title', 'Acerca de')
@section('content')
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header bg-primary text-white">
<h4 class="mb-0"><i class="fas fa-info-circle"></i> Acerca de Películas App</h4>
</div>
<div class="card-body">
<h5 class="card-title">¿Qué es Películas App?</h5>
<p class="card-text">
Películas App es una aplicación web desarrollada con Laravel que te permite
gestionar tu colección personal de películas. Con esta aplicación puedes:
</p>
<ul class="list-group list-group-flush mb-4">
<li class="list-group-item">
<i class="fas fa-check text-success"></i> Ver todas tus películas en un listado organizado
</li>
<li class="list-group-item">
<i class="fas fa-check text-success"></i> Agregar nuevas películas con información detallada
</li>
<li class="list-group-item">
<i class="fas fa-check text-success"></i> Editar información de películas existentes
</li>
<li class="list-group-item">
<i class="fas fa-check text-success"></i> Eliminar películas de tu colección
</li>
<li class="list-group-item">
<i class="fas fa-check text-success"></i> Buscar películas por diferentes criterios
</li>
<li class="list-group-item">
<i class="fas fa-check text-success"></i> Ver detalles completos de cada película
</li>
</ul>
<h5 class="card-title">Características Técnicas</h5>
<div class="row mt-3">
<div class="col-md-6">
<div class="card bg-light mb-3">
<div class="card-body">
<h6><i class="fas fa-code text-primary"></i> Tecnologías Utilizadas</h6>
<ul class="mb-0">
<li>Laravel 10.x - Framework PHP</li>
<li>Bootstrap 5 - Framework CSS</li>
<li>MySQL - Base de Datos</li>
<li>Blade - Motor de Plantillas</li>
</ul>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card bg-light mb-3">
<div class="card-body">
<h6><i class="fas fa-cogs text-primary"></i> Características</h6>
<ul class="mb-0">
<li>CRUD Completo</li>
<li>Validación de Datos</li>
<li>Diseño Responsivo</li>
<li>Mensajes de Confirmación</li>
</ul>
</div>
</div>
</div>
</div>
<div class="alert alert-info mt-4">
<h6><i class="fas fa-lightbulb"></i> Para Principiantes</h6>
<p class="mb-0">
Esta aplicación está diseñada para ser un ejemplo educativo para quienes
están comenzando con Laravel. Incluye todas las funcionalidades básicas
de una aplicación web CRUD completa.
</p>
</div>
<div class="text-center mt-4">
<a href="{{ route('movies.index') }}" class="btn btn-primary">
<i class="fas fa-play"></i> Comenzar a Usar la App
</a>
<a href="{{ route('movies.create') }}" class="btn btn-success">
<i class="fas fa-plus"></i> Agregar Tu Primera Película
</a>
</div>
</div>
<div class="card-footer text-muted text-center">
Versión 1.0.0 | Desarrollado con <i class="fas fa-heart text-danger"></i> para la comunidad Laravel
</div>
</div>
</div>
</div>
@endsection7. VISTAS CRUD
7.1 Vista Index (Listado de Películas)
Crea resources/views/movies/index.blade.php:
html
@extends('layouts.app')
@section('title', 'Lista de Películas')
@section('content')
<div class="d-flex justify-content-between align-items-center mb-4">
<h1><i class="fas fa-film text-primary"></i> Lista de Películas</h1>
<a href="{{ route('movies.create') }}" class="btn btn-success">
<i class="fas fa-plus-circle"></i> Nueva Película
</a>
</div>
@if($movies->isEmpty())
<div class="alert alert-info">
<h4 class="alert-heading"><i class="fas fa-info-circle"></i> No hay películas registradas</h4>
<p>Parece que aún no has agregado ninguna película a tu colección.</p>
<hr>
<a href="{{ route('movies.create') }}" class="btn btn-primary">
<i class="fas fa-plus"></i> Agregar Mi Primera Película
</a>
</div>
@else
<!-- Filtros -->
<div class="card mb-4">
<div class="card-body">
<form action="{{ route('movies.search') }}" method="GET" class="row g-3">
<div class="col-md-6">
<input type="text" class="form-control" name="search"
placeholder="Buscar por título, director, género..."
value="{{ request('search') ?? '' }}">
</div>
<div class="col-md-2">
<select class="form-select" name="genre">
<option value="">Todos los géneros</option>
@foreach($movies->pluck('genre')->unique() as $genre)
<option value="{{ $genre }}" {{ request('genre') == $genre ? 'selected' : '' }}>
{{ $genre }}
</option>
@endforeach
</select>
</div>
<div class="col-md-2">
<select class="form-select" name="available">
<option value="">Disponibilidad</option>
<option value="1" {{ request('available') == '1' ? 'selected' : '' }}>Disponible</option>
<option value="0" {{ request('available') == '0' ? 'selected' : '' }}>No Disponible</option>
</select>
</div>
<div class="col-md-2">
<button type="submit" class="btn btn-primary w-100">
<i class="fas fa-search"></i> Filtrar
</button>
</div>
</form>
@if(request()->has('search') || request()->has('genre') || request()->has('available'))
<div class="mt-3">
<a href="{{ route('movies.index') }}" class="btn btn-sm btn-outline-secondary">
<i class="fas fa-times"></i> Limpiar Filtros
</a>
</div>
@endif
</div>
</div>
<!-- Tarjetas de Películas -->
<div class="row">
@foreach($movies as $movie)
<div class="col-md-4 mb-4">
<div class="card h-100 shadow-sm">
<!-- Badge de Disponibilidad -->
<div class="position-absolute top-0 end-0 m-2">
@if($movie->available)
<span class="badge bg-success">
<i class="fas fa-check-circle"></i> Disponible
</span>
@else
<span class="badge bg-danger">
<i class="fas fa-times-circle"></i> No Disponible
</span>
@endif
</div>
<!-- Poster -->
<div class="text-center p-3">
@if($movie->poster_url)
<img src="{{ $movie->poster_url }}"
alt="{{ $movie->title }}"
class="img-fluid rounded"
style="max-height: 300px;">
@else
<div class="bg-light rounded d-flex align-items-center justify-content-center"
style="height: 300px;">
<i class="fas fa-film fa-5x text-muted"></i>
</div>
@endif
</div>
<div class="card-body">
<h5 class="card-title">{{ $movie->title }}</h5>
<h6 class="card-subtitle mb-2 text-muted">
<i class="fas fa-user"></i> {{ $movie->director }} |
<i class="fas fa-calendar"></i> {{ $movie->year }}
</h6>
<p class="card-text">
@if(strlen($movie->description) > 100)
{{ substr($movie->description, 0, 100) }}...
@else
{{ $movie->description }}
@endif
</p>
<div class="mb-3">
<span class="badge bg-info">
<i class="fas fa-tag"></i> {{ $movie->genre }}
</span>
<span class="badge bg-warning text-dark">
<i class="fas fa-clock"></i> {{ $movie->duration }} min
</span>
<span class="badge bg-primary">
<i class="fas fa-star"></i> {{ $movie->rating }}/10
</span>
</div>
</div>
<div class="card-footer bg-transparent">
<div class="d-flex justify-content-between">
<a href="{{ route('movies.show', $movie->id) }}"
class="btn btn-sm btn-outline-primary">
<i class="fas fa-eye"></i> Ver
</a>
<a href="{{ route('movies.edit', $movie->id) }}"
class="btn btn-sm btn-outline-warning">
<i class="fas fa-edit"></i> Editar
</a>
<form action="{{ route('movies.destroy', $movie->id) }}"
method="POST"
class="d-inline"
onsubmit="return confirm('¿Estás seguro de eliminar esta película?');">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-sm btn-outline-danger">
<i class="fas fa-trash"></i> Eliminar
</button>
</form>
</div>
</div>
</div>
</div>
@endforeach
</div>
<!-- Paginación -->
@if($movies->hasPages())
<div class="d-flex justify-content-center mt-4">
{{ $movies->links() }}
</div>- Obtener vínculo
- X
- Correo electrónico
- Otras apps
Comentarios
Publicar un comentario