๐ฌ ์ํ๊ด ์์ ์๊ฐํ & ์๊ณ ํธ ๊ฐค๋ฌ๋ฆฌ
cinema-schedule-trailer-gallery
๋ฌธ์ ์ค๋ช
ํ๋ก์ ํธ ๊ฐ์
์ํ๊ด ์น์ฌ์ดํธ์ ํต์ฌ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ Laravel 13.x + Blade ํ๋ก์ ํธ์ ๋๋ค. ์ค์ ์ํ๊ด์ฒ๋ผ ํ์ฌ ์์ ์ค์ธ ์ํ ๋ชฉ๋ก, ์์ ์๊ฐํ, ์๊ณ ํธ ์์์ ํ๋์ ๋ณผ ์ ์๋ ์๋น์ค๋ฅผ ๋ง๋ญ๋๋ค. ๊ด๋ฆฌ์๊ฐ ์ํ ์ ๋ณด๋ฅผ ์ถ๊ฐํ๋ฉด ๋ฐฉ๋ฌธ์๋ ๊น๋ํ ์นด๋ UI๋ก ์ํ๋ฅผ ํ์ํ๊ณ , YouTube ์๊ณ ํธ์ ๋ฐ๋ก ์์ฒญํ ์ ์์ต๋๋ค.
ํ์ ๊ธฐ๋ฅ
- ์ํ ๋ชฉ๋ก ํ์ด์ง: ํ์ฌ ์์ ์ค์ธ ์ํ๋ฅผ ์นด๋ ๊ทธ๋ฆฌ๋ ํํ๋ก ํ์ (ํฌ์คํฐ ์ด๋ฏธ์ง, ์ ๋ชฉ, ์ฅ๋ฅด, ๋ฌ๋ํ์)
- ์ํ ์์ธ ํ์ด์ง: ์ค๊ฑฐ๋ฆฌ, ๊ฐ๋ , ์ถ์ฐ์ง, ๊ด๋๋ฑ๊ธ, YouTube ์๊ณ ํธ ์๋ฒ ๋ ์์ ํ์
- ์์ ์๊ฐํ: ์ํ๋ณ๋ก ์ค๋/๋ด์ผ/๋ชจ๋ ์์ ์๊ฐ ๋ชฉ๋ก (์: 10:30, 13:00, 15:30, 18:00, 20:30)
- ์ํ ๋ฑ๋ก ํผ: ๊ฐ๋จํ ๊ด๋ฆฌ์ ํ์ด์ง์์ ์ํ ์ ๋ณด ์ ๋ ฅ (์ ๋ชฉ, ํฌ์คํฐ URL, ์ฅ๋ฅด, ๋ฌ๋ํ์, ์ค๊ฑฐ๋ฆฌ, ์๊ณ ํธ YouTube URL, ์์ ์๊ฐ)
- ๋ฐ์ํ ๋์์ธ: Tailwind CSS๋ก ๋ชจ๋ฐ์ผ/ํ๋ธ๋ฆฟ/๋ฐ์คํฌํฑ ๋์
- SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค: movies ํ ์ด๋ธ๊ณผ showtimes ํ ์ด๋ธ (1:N ๊ด๊ณ)
๋ณด๋์ค ๊ธฐ๋ฅ
- ์ฅ๋ฅด๋ณ ํํฐ๋ง (์ก์ , ๋๋ผ๋ง, ์ฝ๋ฏธ๋, ๊ณตํฌ, SF ๋ฑ)
- ์์ ์๊ฐ ์์ฝ ๋ฒํผ (ํด๋ฆญ ์ ๊ฐ๋จํ ์์ฝ ์๋ฃ ๋ฉ์์ง)
- ์ํ ๊ฒ์ ๊ธฐ๋ฅ (์ ๋ชฉ์ผ๋ก ๊ฒ์)
- ๋ณ์ ํ์ (๋๋ฏธ ๋ฐ์ดํฐ๋ก ํ์ ์๊ฐํ)
- ๋คํฌ ๋ชจ๋ ํ ๊ธ
ํ์ต ๋ชฉํ
- Laravel 13.x ๋ผ์ฐํ , ์ปจํธ๋กค๋ฌ, Blade ํ ํ๋ฆฟ ๊ธฐ์ด
- Eloquent ORM์ผ๋ก ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ด๊ณ ์ค์ (hasMany, belongsTo)
- Blade ์ปดํฌ๋ํธ ์ฌ์ฌ์ฉ (์ํ ์นด๋, ์๊ฐํ ๋ฆฌ์คํธ)
- Tailwind CSS๋ก ๋น ๋ฅธ UI ๊ตฌ์ฑ
- YouTube iframe ์๋ฒ ๋ ๋ฐฉ๋ฒ
- ํผ ๊ฒ์ฆ (Form Request Validation)
๊ธฐ์ ์คํ
- Laravel 13.x
- Blade ํ ํ๋ฆฟ ์์ง
- Tailwind CSS 4.x
- SQLite
- Alpine.js (๊ฐ๋จํ ์ธํฐ๋์ ์ฉ)
์ ์ฝ ์กฐ๊ฑด
- โข Laravel 13.x ์ต์ ๋ฒ์ ์ฌ์ฉ (composer create-project laravel/laravel ๋ช ๋ น)
- โข Blade ํ ํ๋ฆฟ๋ง ์ฌ์ฉ (React, Vue ๋ฑ SPA ํ๋ ์์ํฌ ์ฌ์ฉ ๊ธ์ง)
- โข Tailwind CSS 4.x๋ก ์คํ์ผ๋ง (CDN ๋๋ Vite ๋น๋)
- โข SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ฉ (.env ํ์ผ์์ DB_CONNECTION=sqlite ์ค์ )
- โข YouTube ์๊ณ ํธ URL์ ์๋ฒ ๋ ๊ฐ๋ฅํ ํ์์ผ๋ก ์ ์ฅ (https://www.youtube.com/embed/VIDEO_ID)
- โข ๋ฐ์ํ ๋์์ธ ํ์ (๋ชจ๋ฐ์ผ ์ฐ์ ์ ๊ทผ)
- โข Blade ์ปดํฌ๋ํธ๋ก UI ์ฌ์ฌ์ฉ์ฑ ๋์ด๊ธฐ
- โข ์ค์ ์ํ ๋ฐ์ดํฐ ์์ 5๊ฐ ์ด์ ์๋ ๋ฐ์ดํฐ๋ก ์ ๊ณต
- โข ์์ ์๊ฐ์ showtimes ํ ์ด๋ธ์ ๋ณ๋ ์ ์ฅ (movie_id ์ธ๋ํค)
- โข ๊ด๋ฆฌ์ ์ธ์ฆ์ ๊ตฌํํ์ง ์์ (๊ฐ๋จํ /admin ๊ฒฝ๋ก๋ก ์ ๊ทผ)
ํ๋กฌํํธ ๋ ์ํผ
์๋ ํ๋กฌํํธ๋ฅผ ์์๋๋ก AI์๊ฒ ๋ณด๋ด๋ฉด ๋ฉ๋๋ค. ๋ณต์ฌ ๋ฒํผ์ ๋๋ฌ ๋ฐ๋ก ์ฌ์ฉํ์ธ์.
mkdir cinema-schedule-trailer-gallery && cd cinema-schedule-trailer-gallery
์ด ํด๋์์ Laravel 13.x ํ๋ก์ ํธ๋ฅผ ์์ํฉ๋๋ค.
# Laravel 13.x ํ๋ก์ ํธ ์์ฑ ๋ฐ ์ด๊ธฐ ์ค์
๋ค์ ์์
์ ์์๋๋ก ์งํํด์ฃผ์ธ์:
1. Laravel 13.x ํ๋ก์ ํธ ์์ฑ:
```bash
composer create-project laravel/laravel .
```
2. .env ํ์ผ ์์ (SQLite ์ฌ์ฉ):
```
DB_CONNECTION=sqlite
# DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD ์ฃผ์ ์ฒ๋ฆฌ
```
3. database/database.sqlite ํ์ผ ์์ฑ:
```bash
touch database/database.sqlite
```
4. Tailwind CSS ์ค์น ๋ฐ ์ค์ :
- `npm install -D tailwindcss postcss autoprefixer`
- `npx tailwindcss init -p`
- tailwind.config.js์์ content ๊ฒฝ๋ก ์ค์ :
```js
content: [
"./resources/**/*.blade.php",
"./resources/**/*.js",
],
```
- resources/css/app.css์ Tailwind ๋๋ ํฐ๋ธ ์ถ๊ฐ:
```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```
5. Vite ๋น๋ ๋ฐ ๊ฐ๋ฐ ์๋ฒ ์คํ:
```bash
npm install
npm run dev
```
6. ๋ณ๋ ํฐ๋ฏธ๋์์ Laravel ์๋ฒ ์คํ:
```bash
php artisan serve
```
๋ชจ๋ ์ค์ ์ด ์๋ฃ๋๋ฉด http://localhost:8000 ์์ Laravel ๊ธฐ๋ณธ ํ์ด์ง๊ฐ ๋ณด์ฌ์ผ ํฉ๋๋ค.
๊ธฐ๋ ๊ฒฐ๊ณผ: Laravel 13.x ํ๋ก์ ํธ๊ฐ ์์ฑ๋๊ณ , SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค์ ์๋ฃ, Tailwind CSS๊ฐ ํตํฉ๋์ด ๊ฐ๋ฐ ํ๊ฒฝ์ด ์ค๋น๋ฉ๋๋ค. npm run dev์ php artisan serve๊ฐ ๋์์ ์คํ ์ค์ด์ด์ผ ํฉ๋๋ค.
# ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ง์ด๊ทธ๋ ์ด์
๋ฐ ๋ชจ๋ธ ์์ฑ
์ํ ์ ๋ณด์ ์์ ์๊ฐํ๋ฅผ ์ ์ฅํ ํ
์ด๋ธ์ ๋ง๋ค์ด์ฃผ์ธ์.
## 1. Movie ๋ชจ๋ธ ๋ฐ ๋ง์ด๊ทธ๋ ์ด์
์์ฑ
```bash
php artisan make:model Movie -m
```
`database/migrations/xxxx_create_movies_table.php` ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ด ์์ :
```php
public function up()
{
Schema::create('movies', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('poster_url');
$table->string('genre');
$table->integer('runtime'); // ๋ถ ๋จ์
$table->text('synopsis');
$table->string('director');
$table->string('cast'); // ์ผํ๋ก ๊ตฌ๋ถ๋ ๋ฐฐ์ฐ ์ด๋ฆ
$table->string('rating'); // ์ ์ฒด๊ด๋๊ฐ, 12์ธ, 15์ธ, ์ฒญ๋ถ ๋ฑ
$table->string('trailer_url')->nullable(); // YouTube embed URL
$table->timestamps();
});
}
```
## 2. Showtime ๋ชจ๋ธ ๋ฐ ๋ง์ด๊ทธ๋ ์ด์
์์ฑ
```bash
php artisan make:model Showtime -m
```
`database/migrations/xxxx_create_showtimes_table.php` ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ด ์์ :
```php
public function up()
{
Schema::create('showtimes', function (Blueprint $table) {
$table->id();
$table->foreignId('movie_id')->constrained()->onDelete('cascade');
$table->date('show_date');
$table->time('show_time');
$table->timestamps();
});
}
```
## 3. ๋ชจ๋ธ ๊ด๊ณ ์ค์
`app/Models/Movie.php`์ ๊ด๊ณ ์ถ๊ฐ:
```php
public function showtimes()
{
return $this->hasMany(Showtime::class);
}
```
`app/Models/Showtime.php`์ ๊ด๊ณ ์ถ๊ฐ:
```php
public function movie()
{
return $this->belongsTo(Movie::class);
}
protected $casts = [
'show_date' => 'date',
'show_time' => 'datetime:H:i',
];
```
## 4. ๋ง์ด๊ทธ๋ ์ด์
์คํ
```bash
php artisan migrate
```
์๋ฃ๋๋ฉด SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค์ movies, showtimes ํ
์ด๋ธ์ด ์์ฑ๋ฉ๋๋ค.
๊ธฐ๋ ๊ฒฐ๊ณผ: movies์ showtimes ํ ์ด๋ธ์ด ์์ฑ๋๊ณ , Movie์ Showtime ๋ชจ๋ธ ๊ฐ 1:N ๊ด๊ณ๊ฐ ์ค์ ๋ฉ๋๋ค. php artisan migrate ์คํ ํ ์๋ฌ ์์ด ์๋ฃ๋์ด์ผ ํฉ๋๋ค.
# ์๋ ๋ฐ์ดํฐ ์์ฑ ๋ฐ ๋๋ฏธ ์ํ ์ถ๊ฐ
์ค์ ์ํ๊ด์ฒ๋ผ ๋ณด์ด๋๋ก 5๊ฐ ์ด์์ ์ํ ๋ฐ์ดํฐ์ ๊ฐ ์ํ๋ณ ์์ ์๊ฐํ๋ฅผ ์ถ๊ฐํด์ฃผ์ธ์.
## 1. Seeder ์์ฑ
```bash
php artisan make:seeder MovieSeeder
```
## 2. `database/seeders/MovieSeeder.php` ์์ฑ
```php
use App\Models\Movie;
use App\Models\Showtime;
use Carbon\Carbon;
public function run()
{
$movies = [
[
'title' => '์คํํ์ด๋จธ',
'poster_url' => 'https://image.tmdb.org/t/p/w500/8Gxv8gSFCU0XGDykEGv7zR1n2ua.jpg',
'genre' => '๋๋ผ๋ง',
'runtime' => 180,
'synopsis' => '์์ํญํ์ ์๋ฒ์ง ๋ก๋ฒํธ ์คํํ์ด๋จธ์ ์ถ๊ณผ ๋งจํดํผ ํ๋ก์ ํธ๋ฅผ ๋ค๋ฃฌ ๋์์ฌ์.',
'director' => 'ํฌ๋ฆฌ์คํ ํผ ๋๋',
'cast' => 'ํฌ๋ฆฌ์ธ ๋จธํผ, ์๋ฐ๋ฆฌ ๋ธ๋ฐํธ, ๋ก๋ฒํธ ๋ค์ฐ๋ ์ฃผ๋์ด',
'rating' => '15์ธ ๊ด๋๊ฐ',
'trailer_url' => 'https://www.youtube.com/embed/uYPbbksJxIg',
],
[
'title' => '๋: ํํธ 2',
'poster_url' => 'https://image.tmdb.org/t/p/w500/1pdfLvkbY9ohJlCjQH2CZjjYVvJ.jpg',
'genre' => 'SF',
'runtime' => 166,
'synopsis' => 'ํด ์ํธ๋ ์ด๋ฐ์ค๊ฐ ํ๋ ๋ฉ์กฑ๊ณผ ํจ๊ป ํฉ์ ์ ๋ง์ ์ธ์ฐ๋ ์ฅ๋ํ SF ๋์.',
'director' => '๋๋ ๋น๋๋ธ',
'cast' => 'ํฐ๋ชจ์ ์ฌ๋ผ๋ฉ, ์ ๋ฐ์ด์, ๋ ๋ฒ ์นด ํผ๊ฑฐ์จ',
'rating' => '12์ธ ๊ด๋๊ฐ',
'trailer_url' => 'https://www.youtube.com/embed/Way9Dexny3w',
],
[
'title' => 'ํ๋ฌ',
'poster_url' => 'https://image.tmdb.org/t/p/w500/7JsHbxT03xShsvRy4R4TmD5tBTy.jpg',
'genre' => '๊ณตํฌ',
'runtime' => 134,
'synopsis' => '๋ฏธ๊ตญ LA์์ ์๋ฌธ์ ๋ณ์ด ๋ฐ์ํ๊ณ , ๋ฌด์์ธ๋ค์ด ๊ธฐ์ดํ ์ฌ๊ฑด์ ์ค์ฒด๋ฅผ ํํค์น๋ ์ค์ปฌํธ ๋ฏธ์คํฐ๋ฆฌ.',
'director' => '์ฅ์ฌํ',
'cast' => '์ต๋ฏผ์, ๊น๊ณ ์, ์ ํด์ง, ์ด๋ํ',
'rating' => '15์ธ ๊ด๋๊ฐ',
'trailer_url' => 'https://www.youtube.com/embed/HFvPeDSWKTI',
],
[
'title' => '๋ฒ์ฃ๋์ 4',
'poster_url' => 'https://image.tmdb.org/t/p/w500/jRyGHNkHSe2vVEcTbNqNvbtHPmO.jpg',
'genre' => '์ก์
',
'runtime' => 109,
'synopsis' => '๋ง์๋์ ๊ด์๋๊ฐ IT ๊ธฐ๋ฐ ์ ์ข
๋ฒ์ฃ ์กฐ์ง๊ณผ ๋ง์๋ ํต์พํ ์ก์
๋ธ๋ก๋ฒ์คํฐ.',
'director' => 'ํ๋ช
ํ',
'cast' => '๋ง๋์, ๊น๋ฌด์ด, ๋ฐ์งํ',
'rating' => '15์ธ ๊ด๋๊ฐ',
'trailer_url' => 'https://www.youtube.com/embed/r6XI0xx1LIU',
],
[
'title' => '์์',
'poster_url' => 'https://image.tmdb.org/t/p/w500/AcoVfiv1rrWOmAdpnAMnM56ki19.jpg',
'genre' => '์ ๋๋ฉ์ด์
',
'runtime' => 95,
'synopsis' => '๋์ฆ๋ 100์ฃผ๋
๊ธฐ๋
์. ์์์ ์ด๋ฃจ์ด์ฃผ๋ ์๊ตญ์์ ํผ์ณ์ง๋ ๋ง๋ฒ ๊ฐ์ ๋ชจํ.',
'director' => 'ํฌ๋ฆฌ์ค ๋ฒ
, ํ์ด ๋น๋ผ์ํฐ์ฝ',
'cast' => '์๋ฆฌ์๋ ๋๋ณด์ฆ, ํฌ๋ฆฌ์ค ํ์ธ (๋ชฉ์๋ฆฌ ์ถ์ฐ)',
'rating' => '์ ์ฒด ๊ด๋๊ฐ',
'trailer_url' => 'https://www.youtube.com/embed/oyKWDB63gJM',
],
];
foreach ($movies as $movieData) {
$movie = Movie::create($movieData);
// ๊ฐ ์ํ๋ณ๋ก ์ค๋, ๋ด์ผ, ๋ชจ๋ ์์ ์๊ฐ ์์ฑ
$times = ['10:30', '13:00', '15:30', '18:00', '20:30'];
for ($day = 0; $day < 3; $day++) {
foreach ($times as $time) {
Showtime::create([
'movie_id' => $movie->id,
'show_date' => Carbon::today()->addDays($day),
'show_time' => $time,
]);
}
}
}
}
```
## 3. DatabaseSeeder์ ๋ฑ๋ก
`database/seeders/DatabaseSeeder.php`:
```php
public function run()
{
$this->call([
MovieSeeder::class,
]);
}
```
## 4. ์๋ ์คํ
```bash
php artisan db:seed
```
์๋ฃ๋๋ฉด 5๊ฐ ์ํ์ ๊ฐ๊ฐ 15๊ฐ์ ์์ ์๊ฐ(3์ผ ร 5ํ)์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ถ๊ฐ๋ฉ๋๋ค.
๊ธฐ๋ ๊ฒฐ๊ณผ: MovieSeeder๊ฐ ์คํ๋์ด 5๊ฐ์ ์ํ์ ์ด 75๊ฐ์ ์์ ์๊ฐ ๋ฐ์ดํฐ๊ฐ SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋ฉ๋๋ค. php artisan db:seed ์คํ ํ ์๋ฌ ์์ด ์๋ฃ๋์ด์ผ ํฉ๋๋ค.
# ์ํ ๋ชฉ๋ก ํ์ด์ง ๋ฐ ์์ธ ํ์ด์ง ๊ตฌํ
๋ฉ์ธ ํ์ด์ง์์ ์ํ ์นด๋ ๊ทธ๋ฆฌ๋๋ฅผ ๋ณด์ฌ์ฃผ๊ณ , ํด๋ฆญํ๋ฉด ์์ธ ํ์ด์ง๋ก ์ด๋ํ๋๋ก ๋ง๋ค์ด์ฃผ์ธ์.
## 1. ์ปจํธ๋กค๋ฌ ์์ฑ
```bash
php artisan make:controller MovieController
```
`app/Http/Controllers/MovieController.php`:
```php
namespace App\Http\Controllers;
use App\Models\Movie;
use Illuminate\Http\Request;
class MovieController extends Controller
{
public function index()
{
$movies = Movie::all();
return view('movies.index', compact('movies'));
}
public function show(Movie $movie)
{
$movie->load('showtimes');
return view('movies.show', compact('movie'));
}
}
```
## 2. ๋ผ์ฐํธ ์ค์
`routes/web.php`:
```php
use App\Http\Controllers\MovieController;
Route::get('/', [MovieController::class, 'index'])->name('movies.index');
Route::get('/movies/{movie}', [MovieController::class, 'show'])->name('movies.show');
```
## 3. ๋ ์ด์์ ํ
ํ๋ฆฟ ์์ฑ
`resources/views/layouts/app.blade.php`:
```blade
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@yield('title', '์ํ๊ด ์์ ์๊ฐํ')</title>
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body class="bg-gray-900 text-white">
<nav class="bg-gray-800 shadow-lg">
<div class="container mx-auto px-4 py-4">
<a href="{{ route('movies.index') }}" class="text-2xl font-bold text-red-500">๐ฌ Cinema</a>
</div>
</nav>
<main class="container mx-auto px-4 py-8">
@yield('content')
</main>
<footer class="bg-gray-800 mt-16 py-6 text-center text-gray-400">
<p>© 2024 Cinema. All rights reserved.</p>
</footer>
</body>
</html>
```
## 4. ์ํ ๋ชฉ๋ก ํ์ด์ง
`resources/views/movies/index.blade.php`:
```blade
@extends('layouts.app')
@section('title', 'ํ์ฌ ์์์ - Cinema')
@section('content')
<div class="mb-8">
<h1 class="text-4xl font-bold mb-2">ํ์ฌ ์์ ์ค</h1>
<p class="text-gray-400">์ง๊ธ ๊ทน์ฅ์์ ๋ง๋๋ณด์ธ์</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-5 gap-6">
@foreach($movies as $movie)
<a href="{{ route('movies.show', $movie) }}" class="group">
<div class="bg-gray-800 rounded-lg overflow-hidden shadow-lg hover:shadow-2xl transition-all duration-300 transform hover:-translate-y-2">
<img src="{{ $movie->poster_url }}" alt="{{ $movie->title }}" class="w-full h-96 object-cover">
<div class="p-4">
<h3 class="text-lg font-bold mb-2 group-hover:text-red-500 transition">{{ $movie->title }}</h3>
<div class="flex items-center justify-between text-sm text-gray-400">
<span class="bg-gray-700 px-2 py-1 rounded">{{ $movie->genre }}</span>
<span>{{ $movie->runtime }}๋ถ</span>
</div>
</div>
</div>
</a>
@endforeach
</div>
@endsection
```
## 5. ์ํ ์์ธ ํ์ด์ง
`resources/views/movies/show.blade.php`:
```blade
@extends('layouts.app')
@section('title', $movie->title . ' - Cinema')
@section('content')
<div class="max-w-6xl mx-auto">
<div class="grid md:grid-cols-3 gap-8">
<div class="md:col-span-1">
<img src="{{ $movie->poster_url }}" alt="{{ $movie->title }}" class="w-full rounded-lg shadow-2xl">
</div>
<div class="md:col-span-2">
<h1 class="text-4xl font-bold mb-4">{{ $movie->title }}</h1>
<div class="flex flex-wrap gap-4 mb-6 text-sm">
<span class="bg-red-600 px-3 py-1 rounded">{{ $movie->rating }}</span>
<span class="bg-gray-700 px-3 py-1 rounded">{{ $movie->genre }}</span>
<span class="bg-gray-700 px-3 py-1 rounded">{{ $movie->runtime }}๋ถ</span>
</div>
<p class="text-gray-300 mb-6 leading-relaxed">{{ $movie->synopsis }}</p>
<div class="mb-4">
<p class="text-gray-400"><span class="font-semibold text-white">๊ฐ๋
:</span> {{ $movie->director }}</p>
<p class="text-gray-400"><span class="font-semibold text-white">์ถ์ฐ:</span> {{ $movie->cast }}</p>
</div>
@if($movie->trailer_url)
<div class="mb-8">
<h2 class="text-2xl font-bold mb-4">์๊ณ ํธ</h2>
<div class="aspect-video">
<iframe src="{{ $movie->trailer_url }}" class="w-full h-full rounded-lg" allowfullscreen></iframe>
</div>
</div>
@endif
<div>
<h2 class="text-2xl font-bold mb-4">์์ ์๊ฐํ</h2>
@php
$groupedShowtimes = $movie->showtimes->groupBy(function($showtime) {
return $showtime->show_date->format('Y-m-d');
});
@endphp
@foreach($groupedShowtimes as $date => $times)
<div class="mb-4">
<h3 class="font-semibold mb-2">{{ \Carbon\Carbon::parse($date)->isoFormat('M์ D์ผ (ddd)') }}</h3>
<div class="flex flex-wrap gap-2">
@foreach($times as $showtime)
<button class="bg-gray-700 hover:bg-red-600 px-4 py-2 rounded transition">
{{ $showtime->show_time->format('H:i') }}
</button>
@endforeach
</div>
</div>
@endforeach
</div>
</div>
</div>
</div>
@endsection
```
์๋ฃ๋๋ฉด http://localhost:8000 ์์ ์ํ ๋ชฉ๋ก์ ๋ณผ ์ ์๊ณ , ๊ฐ ์ํ๋ฅผ ํด๋ฆญํ๋ฉด ์์ธ ํ์ด์ง๋ก ์ด๋ํฉ๋๋ค.
๊ธฐ๋ ๊ฒฐ๊ณผ: ์ํ ๋ชฉ๋ก ํ์ด์ง์ 5๊ฐ์ ์ํ๊ฐ ์นด๋ ํํ๋ก ํ์๋๊ณ , ํด๋ฆญํ๋ฉด ์์ธ ํ์ด์ง๋ก ์ด๋ํ์ฌ ํฌ์คํฐ, ์ค๊ฑฐ๋ฆฌ, ์๊ณ ํธ, ์์ ์๊ฐํ๊ฐ ๋ณด์ ๋๋ค. Tailwind CSS๋ก ์คํ์ผ๋ง๋ ๋ฐ์ํ UI๊ฐ ์์ฑ๋ฉ๋๋ค.
์ ์ถ๋ ์ํ (0)
๋ก๊ทธ์ธ ํ ์ ์ถ์์ง ์ ์ถ๋ ์ํ์ด ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ ๋์ ์๊ฐ ๋์ด๋ณด์ธ์!