๐ฏ ์จ๋ผ์ธ ํด์ฆ ๋ํ ์ฐธ๊ฐ ์ ์ฒญ ํ๋ซํผ
quiz-contest-registration-platform
๋ฌธ์ ์ค๋ช
๐ ํ๋ก์ ํธ ๊ฐ์
์จ๋ผ์ธ ํด์ฆ ๋ํ๋ฅผ ์ฃผ์ตํ๋ ๊ต์ก ๊ธฐ๊ด์ด๋ ๊ธฐ์ ์ ์ํ ์ฐธ๊ฐ ์ ์ฒญ ํ๋ซํผ์ ๋๋ค. ์ฐธ๊ฐ์๋ค์ด ๊ฐ์ธ ์ ๋ณด๋ฅผ ์ ๋ ฅํ๊ณ ์ํ๋ ํด์ฆ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ์ ํํ์ฌ ๋ํ์ ์ ์ฒญํ ์ ์์ต๋๋ค.
โจ ํ์ ๊ธฐ๋ฅ
- ๐ ์ฐธ๊ฐ ์ ์ฒญ ํผ: ์ด๋ฆ, ์ด๋ฉ์ผ, ์ ํ๋ฒํธ, ์ ํธ ์นดํ ๊ณ ๋ฆฌ ์ ํ
- ๐ ์ ์ฒญ์ ๋ชฉ๋ก ์กฐํ: ๊ด๋ฆฌ์๊ฐ ๋ฑ๋ก๋ ์ฐธ๊ฐ์ ํ์ธ (ํ์ด์ง๋ค์ด์ ํฌํจ)
- ๐จ ์นดํ ๊ณ ๋ฆฌ๋ณ ํํฐ๋ง: ๊ณผํ, ์ญ์ฌ, ์คํฌ์ธ , ์ํฐํ ์ธ๋จผํธ ๋ฑ ์นดํ ๊ณ ๋ฆฌ๋ณ ์ฐธ๊ฐ์ ํํฐ
- ๐ ์ฐธ๊ฐ์ ๊ฒ์: ์ด๋ฆ์ด๋ ์ด๋ฉ์ผ๋ก ๋น ๋ฅด๊ฒ ๊ฒ์
- โ ์ ์ฒญ ์๋ฃ ํ์ธ ํ์ด์ง: ์ ์ฒญ ํ ์ฐธ๊ฐ ๋ฒํธ ํ์
๐ ๋ณด๋์ค ๊ธฐ๋ฅ
- ๐ ์นดํ ๊ณ ๋ฆฌ๋ณ ํต๊ณ: ๊ฐ ์นดํ ๊ณ ๋ฆฌ๋ณ ์ ์ฒญ์ ์ ๋์๋ณด๋
- ๐ง ์๋ ํ์ธ ์ด๋ฉ์ผ: ์ ์ฒญ ์๋ฃ ์ ์ฐธ๊ฐ์์๊ฒ ์ด๋ฉ์ผ ๋ฐ์ก (Laravel Mail)
- ๐ซ ์ฐธ๊ฐ์ฆ ๋ค์ด๋ก๋: PDF ํํ์ ์ฐธ๊ฐ์ฆ ์์ฑ (Laravel DomPDF)
- ๐ ๋คํฌ๋ชจ๋ ํ ๊ธ: Tailwind CSS๋ก ๋คํฌ๋ชจ๋ ์ง์
- โฐ ์ ์ฒญ ๋ง๊ฐ ์นด์ดํธ๋ค์ด: JavaScript๋ก ์ค์๊ฐ ๋ง๊ฐ ์๊ฐ ํ์
๐ฏ ํ์ต ๋ชฉํ
- Laravel 13.x์ ๊ธฐ๋ณธ MVC ํจํด ์ดํด
- Blade ํ ํ๋ฆฟ ์์ง ํ์ฉ
- SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค CRUD ์กฐ์
- ๋ผ์ฐํ ๊ณผ ์ปจํธ๋กค๋ฌ ์ค๊ณ
- Tailwind CSS๋ก ๋ฐ์ํ UI ๊ตฌํ
- Form Validation๊ณผ ์๋ฌ ํธ๋ค๋ง
์ ์ฝ ์กฐ๊ฑด
- โข Laravel 13.x ์ฌ์ฉ (์ต์ ๋ฒ์ )
- โข Blade ํ ํ๋ฆฟ ์์ง ์ฌ์ฉ (React/Vue ๊ธ์ง)
- โข SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ฉ
- โข Tailwind CSS๋ก ์คํ์ผ๋ง
- โข ๋ฐ์ํ ๋์์ธ (๋ชจ๋ฐ์ผ/ํ๋ธ๋ฆฟ/๋ฐ์คํฌํฑ)
- โข Form Validation ํ์ ์ ์ฉ
- โข ํ์ด์ง๋ค์ด์ ๊ตฌํ (์ฐธ๊ฐ์ ๋ชฉ๋ก)
- โข CSRF ๋ณดํธ ํ์ฑํ
ํ๋กฌํํธ ๋ ์ํผ
์๋ ํ๋กฌํํธ๋ฅผ ์์๋๋ก AI์๊ฒ ๋ณด๋ด๋ฉด ๋ฉ๋๋ค. ๋ณต์ฌ ๋ฒํผ์ ๋๋ฌ ๋ฐ๋ก ์ฌ์ฉํ์ธ์.
mkdir quiz-contest-registration-platform && cd quiz-contest-registration-platform ์ด ํด๋์์ ํ๋ก์ ํธ๋ฅผ ์์ํฉ๋๋ค. Laravel 13.x ํ๋ก์ ํธ๋ฅผ ์์ฑํ๊ณ ๊ธฐ๋ณธ ์ค์ ์ ํด์ฃผ์ธ์. ์๊ตฌ์ฌํญ: 1. Laravel 13.x ์ต์ ๋ฒ์ ์ผ๋ก ํ๋ก์ ํธ ์์ฑ 2. SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค์ (.env ํ์ผ์์ DB_CONNECTION=sqlite) 3. database/database.sqlite ํ์ผ ์์ฑ 4. Tailwind CSS ์ค์น ๋ฐ ์ค์ (Laravel Breeze ์์ด ์์ Tailwind๋ง) 5. ๊ธฐ๋ณธ ๋ ์ด์์ Blade ํ์ผ ์์ฑ (resources/views/layouts/app.blade.php) - ํค๋: "๐ฏ ํด์ฆ ๋ํ ์ฐธ๊ฐ ์ ์ฒญ" - ๋ค๋น๊ฒ์ด์ : ํ, ์ ์ฒญํ๊ธฐ, ์ฐธ๊ฐ์ ๋ชฉ๋ก - Tailwind CSS CDN ๋๋ Vite ๋น๋ ์ค์ 6. ์ฐ์ปด ํ์ด์ง ์์ (resources/views/welcome.blade.php) - ๋ํ ์๊ฐ ๋ฌธ๊ตฌ - "์ง๊ธ ์ ์ฒญํ๊ธฐ" ๋ฒํผ (์ ์ฒญ ํ์ด์ง๋ก ์ด๋) - ์นดํ ๊ณ ๋ฆฌ ์๊ฐ ์น์ (๊ณผํ, ์ญ์ฌ, ์คํฌ์ธ , ์ํฐํ ์ธ๋จผํธ) ๋ผ์ฐํธ ์ค์ : - GET / : ์ฐ์ปด ํ์ด์ง - GET /register : ์ ์ฒญ ํผ ํ์ด์ง - GET /participants : ์ฐธ๊ฐ์ ๋ชฉ๋ก ํ์ด์ง ๋ชจ๋ ํ์ด์ง๋ app.blade.php ๋ ์ด์์์ ์์๋ฐ์์ผ ํฉ๋๋ค.
๊ธฐ๋ ๊ฒฐ๊ณผ: Laravel ํ๋ก์ ํธ๊ฐ ์์ฑ๋๊ณ , SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์ค์ ๋๋ฉฐ, Tailwind CSS๊ฐ ์ ์ฉ๋ ๊ธฐ๋ณธ ๋ ์ด์์๊ณผ ์ฐ์ปด ํ์ด์ง๊ฐ ์์ฑ๋ฉ๋๋ค. ๋ค๋น๊ฒ์ด์ ์ ํตํด ํ์ด์ง ๊ฐ ์ด๋์ด ๊ฐ๋ฅํด์ผ ํฉ๋๋ค.
์ฐธ๊ฐ์ ์ ๋ณด๋ฅผ ์ ์ฅํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ง์ด๊ทธ๋ ์ด์ ๊ณผ ๋ชจ๋ธ์ ์์ฑํด์ฃผ์ธ์. ์๊ตฌ์ฌํญ: 1. Participant ๋ชจ๋ธ ์์ฑ (app/Models/Participant.php) 2. participants ํ ์ด๋ธ ๋ง์ด๊ทธ๋ ์ด์ ์์ฑ - id (primary key) - name (string, ํ์) - email (string, ํ์, unique) - phone (string, ํ์) - category (string, ํ์) - ๊ณผํ/์ญ์ฌ/์คํฌ์ธ /์ํฐํ ์ธ๋จผํธ ์ค ํ๋ - participant_number (string, unique) - ์๋ ์์ฑ๋๋ ์ฐธ๊ฐ ๋ฒํธ (์: QC2024-0001) - timestamps (created_at, updated_at) 3. ๋ชจ๋ธ์ $fillable ์์ฑ ์ค์ 4. ๋ง์ด๊ทธ๋ ์ด์ ์คํ ์ถ๊ฐ ์๊ตฌ์ฌํญ: - category ํ๋๋ enum์ด๋ ์ ์ฝ์กฐ๊ฑด ์์ด string์ผ๋ก ์ค์ (Blade์์ select๋ก ์ ํ) - participant_number๋ nullable๋ก ์ค์ (์ปจํธ๋กค๋ฌ์์ ์๋ ์์ฑ)
๊ธฐ๋ ๊ฒฐ๊ณผ: Participant ๋ชจ๋ธ๊ณผ ๋ง์ด๊ทธ๋ ์ด์ ์ด ์์ฑ๋๊ณ , ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ์ด ์์ฑ๋ฉ๋๋ค. ์ฐธ๊ฐ์ ์ ๋ณด๋ฅผ ์ ์ฅํ ์ค๋น๊ฐ ์๋ฃ๋ฉ๋๋ค.
์ฐธ๊ฐ ์ ์ฒญ ํผ ํ์ด์ง์ ์ปจํธ๋กค๋ฌ๋ฅผ ๊ตฌํํด์ฃผ์ธ์.
์๊ตฌ์ฌํญ:
1. ParticipantController ์์ฑ
2. ๋ผ์ฐํธ ์ค์ :
- GET /register : create() ๋ฉ์๋ - ์ ์ฒญ ํผ ํ์
- POST /register : store() ๋ฉ์๋ - ์ ์ฒญ ์ ๋ณด ์ ์ฅ
3. resources/views/participants/create.blade.php ์์ฑ
- ํผ ํ๋:
* ์ด๋ฆ (text input, required)
* ์ด๋ฉ์ผ (email input, required)
* ์ ํ๋ฒํธ (tel input, required, placeholder: 010-1234-5678)
* ์ ํธ ์นดํ
๊ณ ๋ฆฌ (select dropdown, required)
- ๊ณผํ (Science)
- ์ญ์ฌ (History)
- ์คํฌ์ธ (Sports)
- ์ํฐํ
์ธ๋จผํธ (Entertainment)
- "์ ์ฒญํ๊ธฐ" ๋ฒํผ
- Tailwind CSS๋ก ์๋ฆ๋ค์ด ํผ ๋์์ธ (์นด๋ ํํ, ๊ทธ๋ฆผ์, ๋ฅ๊ทผ ๋ชจ์๋ฆฌ)
4. store() ๋ฉ์๋ ๊ตฌํ:
- Form Validation (name, email, phone, category ํ์, email ํ์ ๊ฒ์ฆ)
- participant_number ์๋ ์์ฑ (QC2024-0001 ํ์, ๊ธฐ์กด ์ฐธ๊ฐ์ ์ +1)
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ
- ์ฑ๊ณต ์ /confirmation/{id} ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธ
5. CSRF ํ ํฐ ํฌํจ
6. Validation ์๋ฌ ํ์ (@error ๋๋ ํฐ๋ธ ์ฌ์ฉ)
UI ๋์์ธ:
- ํผ์ ํ๋ฉด ์ค์์ ์ต๋ ๋๋น 600px ์นด๋๋ก ํ์
- ๊ฐ ์
๋ ฅ ํ๋๋ ๋ผ๋ฒจ๊ณผ ํจ๊ป ํ์
- ์๋ฌ ๋ฉ์์ง๋ ๋นจ๊ฐ์์ผ๋ก ์
๋ ฅ ํ๋ ์๋ ํ์
- ์ ์ถ ๋ฒํผ์ ํ๋์ ๋ฐฐ๊ฒฝ, ํธ๋ฒ ์ ์งํ ํ๋์
๊ธฐ๋ ๊ฒฐ๊ณผ: ์ฐธ๊ฐ ์ ์ฒญ ํผ ํ์ด์ง๊ฐ ์์ฑ๋๊ณ , ์ฌ์ฉ์๊ฐ ์ ๋ณด๋ฅผ ์ ๋ ฅํ์ฌ ์ ์ถํ๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋๋ฉฐ ํ์ธ ํ์ด์ง๋ก ์ด๋ํฉ๋๋ค. Validation ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด ํผ์ ์๋ฌ ๋ฉ์์ง๊ฐ ํ์๋ฉ๋๋ค.
์ ์ฒญ ์๋ฃ ํ์ธ ํ์ด์ง์ ์ฐธ๊ฐ์ ๋ชฉ๋ก ํ์ด์ง๋ฅผ ๊ตฌํํด์ฃผ์ธ์.
์๊ตฌ์ฌํญ:
1. ํ์ธ ํ์ด์ง (resources/views/participants/confirmation.blade.php)
- ๋ผ์ฐํธ: GET /confirmation/{participant}
- ์ปจํธ๋กค๋ฌ ๋ฉ์๋: show(Participant $participant)
- ํ์ ๋ด์ฉ:
* ์ถํ ๋ฉ์์ง "์ ์ฒญ์ด ์๋ฃ๋์์ต๋๋ค! ๐"
* ์ฐธ๊ฐ ๋ฒํธ (ํฌ๊ฒ ๊ฐ์กฐ)
* ์ด๋ฆ, ์ด๋ฉ์ผ, ์นดํ
๊ณ ๋ฆฌ ์ ๋ณด
* "์ฐธ๊ฐ์ ๋ชฉ๋ก ๋ณด๊ธฐ" ๋ฒํผ
- Tailwind CSS๋ก ์ฑ๊ณต ๋ฉ์์ง ์คํ์ผ (๋
น์ ๋ฐฐ๊ฒฝ, ํฐ ํ
์คํธ)
2. ์ฐธ๊ฐ์ ๋ชฉ๋ก ํ์ด์ง (resources/views/participants/index.blade.php)
- ๋ผ์ฐํธ: GET /participants
- ์ปจํธ๋กค๋ฌ ๋ฉ์๋: index()
- ๊ธฐ๋ฅ:
* ๋ชจ๋ ์ฐธ๊ฐ์ ๋ชฉ๋ก ํ์ (ํ
์ด๋ธ ํํ)
* ํ์ด์ง๋ค์ด์
(ํ์ด์ง๋น 10๋ช
)
* ์นดํ
๊ณ ๋ฆฌ๋ณ ํํฐ๋ง (์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ: ?category=Science)
* ๊ฒ์ ๊ธฐ๋ฅ (์ด๋ฆ ๋๋ ์ด๋ฉ์ผ, ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ: ?search=ํ๊ธธ๋)
- ํ
์ด๋ธ ์ปฌ๋ผ: ์ฐธ๊ฐ ๋ฒํธ, ์ด๋ฆ, ์ด๋ฉ์ผ, ์นดํ
๊ณ ๋ฆฌ, ์ ์ฒญ์ผ
- ํํฐ UI:
* ์นดํ
๊ณ ๋ฆฌ ๋ฒํผ ๊ทธ๋ฃน (์ ์ฒด/๊ณผํ/์ญ์ฌ/์คํฌ์ธ /์ํฐํ
์ธ๋จผํธ)
* ๊ฒ์ ์
๋ ฅ ํ๋
- Tailwind CSS๋ก ๋ฐ์ํ ํ
์ด๋ธ ๋์์ธ
3. ์ปจํธ๋กค๋ฌ ๋ก์ง:
- ์นดํ
๊ณ ๋ฆฌ ํํฐ๊ฐ ์์ผ๋ฉด ํด๋น ์นดํ
๊ณ ๋ฆฌ๋ง ์กฐํ
- ๊ฒ์์ด๊ฐ ์์ผ๋ฉด ์ด๋ฆ ๋๋ ์ด๋ฉ์ผ์์ ๊ฒ์ (LIKE ์ฟผ๋ฆฌ)
- ์ต์ ์ ์ฒญ์๋ถํฐ ํ์ (created_at DESC)
- paginate(10) ์ฌ์ฉ
4. ๋น ์ํ ์ฒ๋ฆฌ:
- ์ฐธ๊ฐ์๊ฐ ์์ ๋ "์์ง ์ ์ฒญ์๊ฐ ์์ต๋๋ค" ๋ฉ์์ง ํ์
๊ธฐ๋ ๊ฒฐ๊ณผ: ์ ์ฒญ ์๋ฃ ํ ์ฐธ๊ฐ ๋ฒํธ์ ์ ๋ณด๋ฅผ ํ์ธํ ์ ์๋ ํ์ด์ง๊ฐ ์์ฑ๋๊ณ , ์ฐธ๊ฐ์ ๋ชฉ๋ก ํ์ด์ง์์ ๋ชจ๋ ์ ์ฒญ์๋ฅผ ์กฐํํ๊ณ ํํฐ๋ง/๊ฒ์ํ ์ ์์ต๋๋ค. ํ์ด์ง๋ค์ด์ ์ด ์ ์ ์๋ํด์ผ ํฉ๋๋ค.
์ ์ถ๋ ์ํ (0)
๋ก๊ทธ์ธ ํ ์ ์ถ์์ง ์ ์ถ๋ ์ํ์ด ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ ๋์ ์๊ฐ ๋์ด๋ณด์ธ์!