๐ŸŽฏ ์˜ค๋Š˜์˜ ํ•œ์ž ํ•™์Šต ์นด๋“œ - ๋งค์ผ ํ•œ ๊ธ€์ž์”ฉ ์ตํžˆ๊ธฐ - ๋ฐ”์ด๋ธŒ์ฝ”๋”ฉ ๋ ˆ์‹œํ”ผ
์ค‘๊ธ‰ PHP g5se AI: Claude

๐ŸŽฏ ์˜ค๋Š˜์˜ ํ•œ์ž ํ•™์Šต ์นด๋“œ - ๋งค์ผ ํ•œ ๊ธ€์ž์”ฉ ์ตํžˆ๊ธฐ

๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ช… daily-hanja-learning-card
์กฐํšŒ์ˆ˜ 89 0๊ฑด ์ œ์ถœ

๋ฌธ์ œ ์„ค๋ช…

๐Ÿ“š ํ”„๋กœ์ ํŠธ ๊ฐœ์š”

๋งค์ผ ํ•œ ๊ธ€์ž์”ฉ ํ•œ์ž๋ฅผ ํ•™์Šตํ•˜๊ณ  ๋ณต์Šตํ•  ์ˆ˜ ์žˆ๋Š” ํ•œ์ž ํ•™์Šต ์นด๋“œ ํ”Œ๋žซํผ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ˆ„๋ณด๋“œ5 SE ์œ„์—์„œ ๋™์ž‘ํ•˜๋ฉฐ, ์‚ฌ์šฉ์ž๊ฐ€ ์˜ค๋Š˜์˜ ํ•œ์ž๋ฅผ ํ™•์ธํ•˜๊ณ  ํ€ด์ฆˆ๋กœ ๋ณต์Šตํ•˜๋ฉฐ ํ•™์Šต ์ง„ํ–‰๋ฅ ์„ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โœจ ํ•ต์‹ฌ ๊ธฐ๋Šฅ

ํ•„์ˆ˜ ๊ธฐ๋Šฅ:

  • ๐Ÿ“… ์˜ค๋Š˜์˜ ํ•œ์ž ์นด๋“œ: ๋งค์ผ ํ•˜๋‚˜์”ฉ ์ƒˆ๋กœ์šด ํ•œ์ž๋ฅผ ์†Œ๊ฐœ (ํ›ˆ์Œ, ํš์ˆ˜, ๋ถ€์ˆ˜, ๋œป, ์˜ˆ๋ฌธ ํฌํ•จ)
  • ๐Ÿ“– ํ•™์Šต ์•„์นด์ด๋ธŒ: ์ง€๊ธˆ๊นŒ์ง€ ํ•™์Šตํ•œ ํ•œ์ž ๋ชฉ๋ก ๋ณด๊ธฐ (๋‚ ์งœ๋ณ„ ์ •๋ ฌ)
  • โœ… ๋ณต์Šต ํ€ด์ฆˆ: ๋žœ๋ค์œผ๋กœ ํ•™์Šตํ•œ ํ•œ์ž ์ค‘ 5๊ฐœ๋ฅผ ๊ณจ๋ผ ํ›ˆ์Œ ๋งž์ถ”๊ธฐ ํ€ด์ฆˆ
  • ๐Ÿ“Š ํ•™์Šต ํ†ต๊ณ„: ์ด ํ•™์Šต ์ผ์ˆ˜, ์—ฐ์† ํ•™์Šต ์ผ์ˆ˜, ํ€ด์ฆˆ ์ •๋‹ต๋ฅ  ํ‘œ์‹œ
  • ๐ŸŽจ ์นด๋“œ ํ”Œ๋ฆฝ ์• ๋‹ˆ๋ฉ”์ด์…˜: ํ•œ์ž ์นด๋“œ๋ฅผ ํด๋ฆญํ•˜๋ฉด ๋’ท๋ฉด(์ƒ์„ธ ์ •๋ณด)์œผ๋กœ ๋’ค์ง‘ํžˆ๋Š” ์ธํ„ฐ๋ž™์…˜

๋ณด๋„ˆ์Šค ๊ธฐ๋Šฅ:

  • ๐Ÿ”– ๋ถ๋งˆํฌ ๊ธฐ๋Šฅ: ์–ด๋ ค์šด ํ•œ์ž๋ฅผ ์ฆ๊ฒจ์ฐพ๊ธฐ๋กœ ์ €์žฅ
  • ๐Ÿ† ํ•™์Šต ๋ฑƒ์ง€: ์—ฐ์† 7์ผ, 30์ผ, 100์ผ ํ•™์Šต ์‹œ ๋ฑƒ์ง€ ํš๋“
  • ๐Ÿ” ํ•œ์ž ๊ฒ€์ƒ‰: ํ›ˆ์Œ์ด๋‚˜ ํ•œ์ž๋กœ ๊ฒ€์ƒ‰ํ•˜์—ฌ ๊ณผ๊ฑฐ ํ•™์Šต ๋‚ด์šฉ ์ฐพ๊ธฐ
  • ๐Ÿ“ฑ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ: ๋ชจ๋ฐ”์ผ์—์„œ๋„ ์พŒ์ ํ•œ ํ•™์Šต ๊ฒฝํ—˜

๐ŸŽฏ ํ•™์Šต ๋ชฉํ‘œ

  • g5se์˜ modern shell์„ ํ™œ์šฉํ•œ ์ผ๊ด€๋œ UI ๊ตฌํ˜„
  • ํด๋” ๊ธฐ๋ฐ˜ ์ž๋™ ๋ผ์šฐํŒ… ์ดํ•ด
  • SQLite๋ฅผ ํ™œ์šฉํ•œ ๋ชจ๋“ˆ ๋…๋ฆฝ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ
  • CSS ๋ณ€์ˆ˜๋ฅผ ํ™œ์šฉํ•œ ๋‹คํฌ๋ชจ๋“œ ๋Œ€์‘
  • ๋ฐ”๋‹๋ผ JavaScript๋กœ ์นด๋“œ ํ”Œ๋ฆฝ, ํ€ด์ฆˆ ๋กœ์ง ๊ตฌํ˜„
  • prepared statement๋กœ SQL ์ธ์ ์…˜ ๋ฐฉ์ง€

๐Ÿ›  ๊ธฐ์ˆ  ์Šคํƒ

  • ๋ฐฑ์—”๋“œ: PHP (g5se ์ปจ๋ฒค์…˜)
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค: SQLite (๋ชจ๋“ˆ ์ „์šฉ DB)
  • ํ”„๋ก ํŠธ์—”๋“œ: HTML5, CSS3 (๋””์ž์ธ ํ† ํฐ), Vanilla JavaScript
  • UI ํ”„๋ ˆ์ž„์›Œํฌ: g5se modern shell

๐Ÿ“‚ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

app/modules/hanja/
โ”œโ”€โ”€ index.php          # ๋ฉ”์ธ ํŽ˜์ด์ง€ (์˜ค๋Š˜์˜ ํ•œ์ž)
โ”œโ”€โ”€ archive.php        # ํ•™์Šต ์•„์นด์ด๋ธŒ
โ””โ”€โ”€ quiz.php           # ๋ณต์Šต ํ€ด์ฆˆ

data/modules/
โ””โ”€โ”€ hanja.sqlite       # ํ•œ์ž ํ•™์Šต ๋ฐ์ดํ„ฐ

์ œ์•ฝ ์กฐ๊ฑด

  • โ€ข g5se ์„ค์น˜๋ณธ ์œ„์—์„œ ์ž‘์—… (https://github.com/gnuboard/g5se main ๋ธŒ๋žœ์น˜)
  • โ€ข ํด๋” ๊ธฐ๋ฐ˜ ์ž๋™ ๋ผ์šฐํŒ… ์‚ฌ์šฉ (app/modules/hanja/index.php โ†’ /hanja)
  • โ€ข modern shell ํ•„์ˆ˜ ์ ์šฉ (_head.inc.php + m-shell + _nav.inc.php + m-container + _footer.inc.php)
  • โ€ข ๋””์ž์ธ ํ† ํฐ(CSS ๋ณ€์ˆ˜) ์‚ฌ์šฉ์œผ๋กœ ๋‹คํฌ๋ชจ๋“œ ์ž๋™ ๋Œ€์‘
  • โ€ข ๋ชจ๋“ˆ ์ „์šฉ SQLite ํŒŒ์ผ ์‚ฌ์šฉ (G5_DATA_PATH.'/modules/hanja.sqlite')
  • โ€ข prepared statement๋กœ SQL ์ธ์ ์…˜ ๋ฐฉ์ง€
  • โ€ข ์™ธ๋ถ€ ๋นŒ๋“œ ๋„๊ตฌ(npm/vite) ์‚ฌ์šฉ ๊ธˆ์ง€
  • โ€ข CDN ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ตœ์†Œํ™”, ์ˆœ์ˆ˜ HTML/CSS/JS ๊ถŒ์žฅ
  • โ€ข ๋ชจ๋“  ์‚ฌ์šฉ์ž ์ž…๋ ฅ์€ htmlspecialchars()๋กœ ์ด์Šค์ผ€์ดํ”„

ํ”„๋กฌํ”„ํŠธ ๋ ˆ์‹œํ”ผ

์•„๋ž˜ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ AI์—๊ฒŒ ๋ณด๋‚ด๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋ณต์‚ฌ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ๋ฐ”๋กœ ์‚ฌ์šฉํ•˜์„ธ์š”.

1
Step 1
g5se๊ฐ€ ์„ค์น˜๋œ ๋””๋ ‰ํ„ฐ๋ฆฌ(๋ฃจํŠธ์— `index.php`ยท`app/`์ด ์žˆ๋Š” ๊ณณ)์—์„œ ์ž‘์—…์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. (g5se ์„ค์น˜๋Š” https://github.com/gnuboard/g5se ์ฐธ๊ณ )

## Step 1: ํ”„๋กœ์ ํŠธ ๊ธฐ๋ณธ ๊ตฌ์กฐ ์ƒ์„ฑ

### 1) ๋ชจ๋“ˆ ํด๋” ์ƒ์„ฑ

```bash
mkdir -p app/modules/hanja
```

### 2) ๋ฉ”์ธ ํŽ˜์ด์ง€ ์ƒ์„ฑ (app/modules/hanja/index.php)

๋‹ค์Œ ๋‚ด์šฉ์œผ๋กœ ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜์„ธ์š”:

```php
<?php
include_once('./_common.php');

// ๋ชจ๋“ˆ DB ์ดˆ๊ธฐํ™”
@mkdir(G5_DATA_PATH.'/modules', 0707, true);
$db = new PDO('sqlite:'.G5_DATA_PATH.'/modules/hanja.sqlite');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// ํ…Œ์ด๋ธ” ์ƒ์„ฑ (์ตœ์ดˆ ์‹คํ–‰ ์‹œ)
$db->exec("
    CREATE TABLE IF NOT EXISTS hanja_cards (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        hanja TEXT NOT NULL,
        reading TEXT NOT NULL,
        meaning TEXT NOT NULL,
        strokes INTEGER,
        radical TEXT,
        examples TEXT,
        learned_date DATE,
        is_bookmarked INTEGER DEFAULT 0,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP
    )
");

$db->exec("
    CREATE TABLE IF NOT EXISTS hanja_stats (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        total_days INTEGER DEFAULT 0,
        streak_days INTEGER DEFAULT 0,
        quiz_attempts INTEGER DEFAULT 0,
        quiz_correct INTEGER DEFAULT 0,
        last_study_date DATE
    )
");

// ํ†ต๊ณ„ ๋ ˆ์ฝ”๋“œ ์ดˆ๊ธฐํ™”
$statsCheck = $db->query("SELECT COUNT(*) FROM hanja_stats")->fetchColumn();
if ($statsCheck == 0) {
    $db->exec("INSERT INTO hanja_stats (total_days, streak_days) VALUES (0, 0)");
}

// ์ƒ˜ํ”Œ ํ•œ์ž ๋ฐ์ดํ„ฐ ์‚ฝ์ž… (์ตœ์ดˆ ์‹คํ–‰ ์‹œ)
$count = $db->query("SELECT COUNT(*) FROM hanja_cards")->fetchColumn();
if ($count == 0) {
    $sampleData = [
        ['ๅคง', 'ํฐ ๋Œ€', 'ํฌ๋‹ค, ์œ„๋Œ€ํ•˜๋‹ค', 3, 'ๅคง', 'ๅคงๅญธ(๋Œ€ํ•™), ๅคง้Ÿ“ๆฐ‘ๅœ‹(๋Œ€ํ•œ๋ฏผ๊ตญ)'],
        ['ๅฐ', '์ž‘์„ ์†Œ', '์ž‘๋‹ค', 3, 'ๅฐ', 'ๅฐๅญธๆ ก(์†Œํ•™๊ต), ๅคงๅฐ(๋Œ€์†Œ)'],
        ['ไธญ', '๊ฐ€์šด๋ฐ ์ค‘', '๊ฐ€์šด๋ฐ, ์•ˆ', 4, 'ไธจ', 'ไธญๅญธๆ ก(์ค‘ํ•™๊ต), ไธญๅคฎ(์ค‘์•™)'],
        ['ไบบ', '์‚ฌ๋žŒ ์ธ', '์‚ฌ๋žŒ', 2, 'ไบบ', 'ไบบ้–“(์ธ๊ฐ„), ไบบ็”Ÿ(์ธ์ƒ)'],
        ['ๆ—ฅ', '๋‚  ์ผ', 'ํ•ด, ๋‚ ', 4, 'ๆ—ฅ', 'ๆ—ฅๆœฌ(์ผ๋ณธ), ๆฏๆ—ฅ(๋งค์ผ)'],
    ];
    
    $stmt = $db->prepare("
        INSERT INTO hanja_cards (hanja, reading, meaning, strokes, radical, examples)
        VALUES (?, ?, ?, ?, ?, ?)
    ");
    
    foreach ($sampleData as $data) {
        $stmt->execute($data);
    }
}

// ์˜ค๋Š˜์˜ ํ•œ์ž ๊ฐ€์ ธ์˜ค๊ธฐ (์•„์ง ํ•™์Šตํ•˜์ง€ ์•Š์€ ์ฒซ ๋ฒˆ์งธ ํ•œ์ž)
$todayHanja = $db->query("
    SELECT * FROM hanja_cards 
    WHERE learned_date IS NULL 
    ORDER BY id ASC 
    LIMIT 1
")->fetch(PDO::FETCH_ASSOC);

// ํ†ต๊ณ„ ๊ฐ€์ ธ์˜ค๊ธฐ
$stats = $db->query("SELECT * FROM hanja_stats LIMIT 1")->fetch(PDO::FETCH_ASSOC);

require_once(G5_THEME_PATH.'/modern/_head.inc.php');
include_once('./head.sub.php');
?>
<style>
.hanja-card {
    perspective: 1000px;
    margin: 32px auto;
    max-width: 400px;
    height: 500px;
    cursor: pointer;
}

.hanja-card-inner {
    position: relative;
    width: 100%;
    height: 100%;
    transition: transform 0.6s;
    transform-style: preserve-3d;
}

.hanja-card.flipped .hanja-card-inner {
    transform: rotateY(180deg);
}

.hanja-card-front,
.hanja-card-back {
    position: absolute;
    width: 100%;
    height: 100%;
    backface-visibility: hidden;
    border-radius: var(--m-radius-lg);
    background: var(--m-surface);
    box-shadow: var(--m-shadow);
    padding: 40px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

.hanja-card-back {
    transform: rotateY(180deg);
}

.hanja-display {
    font-size: 120px;
    font-weight: bold;
    color: var(--m-primary);
    margin-bottom: 16px;
}

.hanja-reading {
    font-size: 24px;
    color: var(--m-text);
    margin-bottom: 8px;
}

.hanja-meaning {
    font-size: 18px;
    color: var(--m-text-muted);
    margin-bottom: 24px;
}

.hanja-details {
    width: 100%;
    text-align: left;
}

.hanja-detail-row {
    display: flex;
    justify-content: space-between;
    padding: 12px 0;
    border-bottom: 1px solid var(--m-text-muted);
    opacity: 0.3;
}

.hanja-detail-label {
    font-weight: bold;
    color: var(--m-text);
}

.hanja-detail-value {
    color: var(--m-text-muted);
}

.stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 16px;
    margin-top: 32px;
}

.stat-card {
    background: var(--m-surface);
    padding: 20px;
    border-radius: var(--m-radius-lg);
    box-shadow: var(--m-shadow);
    text-align: center;
}

.stat-value {
    font-size: 32px;
    font-weight: bold;
    color: var(--m-primary);
}

.stat-label {
    font-size: 14px;
    color: var(--m-text-muted);
    margin-top: 8px;
}

.action-buttons {
    display: flex;
    gap: 12px;
    margin-top: 32px;
}

.btn {
    padding: 12px 24px;
    border-radius: var(--m-radius-lg);
    border: none;
    font-size: 16px;
    cursor: pointer;
    transition: opacity 0.2s;
}

.btn:hover {
    opacity: 0.8;
}

.btn-primary {
    background: var(--m-primary);
    color: white;
}

.btn-secondary {
    background: var(--m-surface);
    color: var(--m-text);
    box-shadow: var(--m-shadow);
}

.flip-hint {
    text-align: center;
    color: var(--m-text-muted);
    font-size: 14px;
    margin-top: 16px;
}
</style>

<div class="m-shell">
    <?php require G5_THEME_PATH.'/modern/_nav.inc.php'; ?>
    <main class="m-container" style="padding: 32px 20px 48px;">
        <h1 style="text-align: center; color: var(--m-text); margin-bottom: 8px;">๐ŸŽฏ ์˜ค๋Š˜์˜ ํ•œ์ž</h1>
        <p style="text-align: center; color: var(--m-text-muted); margin-bottom: 32px;">๋งค์ผ ํ•œ ๊ธ€์ž์”ฉ ์ตํ˜€๊ฐ€๋Š” ํ•œ์ž ํ•™์Šต</p>

        <?php if ($todayHanja): ?>
            <div class="hanja-card" id="hanjaCard">
                <div class="hanja-card-inner">
                    <div class="hanja-card-front">
                        <div class="hanja-display"><?php echo htmlspecialchars($todayHanja['hanja']); ?></div>
                        <div class="hanja-reading"><?php echo htmlspecialchars($todayHanja['reading']); ?></div>
                        <div class="hanja-meaning"><?php echo htmlspecialchars($todayHanja['meaning']); ?></div>
                        <p style="color: var(--m-text-muted); font-size: 14px;">์นด๋“œ๋ฅผ ํด๋ฆญํ•˜์—ฌ ๋’ค์ง‘์–ด๋ณด์„ธ์š”</p>
                    </div>
                    <div class="hanja-card-back">
                        <h3 style="color: var(--m-text); margin-bottom: 24px;">์ƒ์„ธ ์ •๋ณด</h3>
                        <div class="hanja-details">
                            <div class="hanja-detail-row">
                                <span class="hanja-detail-label">ํš์ˆ˜</span>
                                <span class="hanja-detail-value"><?php echo htmlspecialchars($todayHanja['strokes']); ?>ํš</span>
                            </div>
                            <div class="hanja-detail-row">
                                <span class="hanja-detail-label">๋ถ€์ˆ˜</span>
                                <span class="hanja-detail-value"><?php echo htmlspecialchars($todayHanja['radical']); ?></span>
                            </div>
                            <div class="hanja-detail-row">
                                <span class="hanja-detail-label">์˜ˆ๋ฌธ</span>
                                <span class="hanja-detail-value"><?php echo htmlspecialchars($todayHanja['examples']); ?></span>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <p class="flip-hint">๐Ÿ’ก Tip: ์นด๋“œ๋ฅผ ํด๋ฆญํ•˜๋ฉด ์•ž๋’ค๋กœ ๋’ค์ง‘์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค</p>

            <div class="action-buttons" style="justify-content: center;">
                <button class="btn btn-primary" onclick="markAsLearned(<?php echo $todayHanja['id']; ?>)">โœ… ํ•™์Šต ์™„๋ฃŒ</button>
                <a href="/hanja/archive" class="btn btn-secondary">๐Ÿ“– ํ•™์Šต ์•„์นด์ด๋ธŒ</a>
            </div>
        <?php else: ?>
            <div style="text-align: center; padding: 60px 20px;">
                <p style="font-size: 48px; margin-bottom: 16px;">๐ŸŽ‰</p>
                <h2 style="color: var(--m-text); margin-bottom: 8px;">๋ชจ๋“  ํ•œ์ž๋ฅผ ํ•™์Šตํ–ˆ์Šต๋‹ˆ๋‹ค!</h2>
                <p style="color: var(--m-text-muted);">๋ณต์Šต ํ€ด์ฆˆ๋กœ ์‹ค๋ ฅ์„ ํ™•์ธํ•ด๋ณด์„ธ์š”</p>
                <div class="action-buttons" style="justify-content: center; margin-top: 24px;">
                    <a href="/hanja/quiz" class="btn btn-primary">ํ€ด์ฆˆ ํ’€๊ธฐ</a>
                    <a href="/hanja/archive" class="btn btn-secondary">ํ•™์Šต ๊ธฐ๋ก ๋ณด๊ธฐ</a>
                </div>
            </div>
        <?php endif; ?>

        <div class="stats-grid">
            <div class="stat-card">
                <div class="stat-value"><?php echo $stats['total_days']; ?></div>
                <div class="stat-label">์ด ํ•™์Šต ์ผ์ˆ˜</div>
            </div>
            <div class="stat-card">
                <div class="stat-value"><?php echo $stats['streak_days']; ?></div>
                <div class="stat-label">์—ฐ์† ํ•™์Šต ์ผ์ˆ˜</div>
            </div>
            <div class="stat-card">
                <div class="stat-value">
                    <?php 
                    if ($stats['quiz_attempts'] > 0) {
                        echo round(($stats['quiz_correct'] / $stats['quiz_attempts']) * 100);
                    } else {
                        echo 0;
                    }
                    ?>%
                </div>
                <div class="stat-label">ํ€ด์ฆˆ ์ •๋‹ต๋ฅ </div>
            </div>
        </div>
    </main>
    <?php require G5_THEME_PATH.'/modern/_footer.inc.php'; ?>
</div>

<script>
// ์นด๋“œ ํ”Œ๋ฆฝ ์• ๋‹ˆ๋ฉ”์ด์…˜
document.getElementById('hanjaCard')?.addEventListener('click', function() {
    this.classList.toggle('flipped');
});

// ํ•™์Šต ์™„๋ฃŒ ์ฒ˜๋ฆฌ
function markAsLearned(id) {
    if (!confirm('์ด ํ•œ์ž๋ฅผ ํ•™์Šต ์™„๋ฃŒ๋กœ ํ‘œ์‹œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?')) return;
    
    fetch('/hanja/index.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: 'action=mark_learned&id=' + id
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            alert('ํ•™์Šต ์™„๋ฃŒ! ๋‹ค์Œ ํ•œ์ž๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.');
            location.reload();
        } else {
            alert('์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.');
        }
    });
}
</script>

<?php include_once('./tail.sub.php'); ?>
```

### 3) AJAX ์ฒ˜๋ฆฌ ์ถ”๊ฐ€

์œ„ ํŒŒ์ผ์˜ ๋งจ ์œ„(`include_once('./_common.php');` ๋ฐ”๋กœ ์•„๋ž˜)์— ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”:

```php
// AJAX ์š”์ฒญ ์ฒ˜๋ฆฌ
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
    @mkdir(G5_DATA_PATH.'/modules', 0707, true);
    $db = new PDO('sqlite:'.G5_DATA_PATH.'/modules/hanja.sqlite');
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    if ($_POST['action'] === 'mark_learned') {
        $id = intval($_POST['id']);
        $today = date('Y-m-d');
        
        // ํ•œ์ž๋ฅผ ํ•™์Šต ์™„๋ฃŒ๋กœ ํ‘œ์‹œ
        $stmt = $db->prepare("UPDATE hanja_cards SET learned_date = ? WHERE id = ?");
        $stmt->execute([$today, $id]);
        
        // ํ†ต๊ณ„ ์—…๋ฐ์ดํŠธ
        $stats = $db->query("SELECT * FROM hanja_stats LIMIT 1")->fetch(PDO::FETCH_ASSOC);
        $lastStudyDate = $stats['last_study_date'];
        $newStreakDays = $stats['streak_days'];
        
        if ($lastStudyDate === null || $lastStudyDate !== $today) {
            $newTotalDays = $stats['total_days'] + 1;
            
            // ์—ฐ์† ์ผ์ˆ˜ ๊ณ„์‚ฐ
            if ($lastStudyDate === date('Y-m-d', strtotime('-1 day'))) {
                $newStreakDays = $stats['streak_days'] + 1;
            } else {
                $newStreakDays = 1;
            }
            
            $stmt = $db->prepare("
                UPDATE hanja_stats 
                SET total_days = ?, streak_days = ?, last_study_date = ?
            ");
            $stmt->execute([$newTotalDays, $newStreakDays, $today]);
        }
        
        header('Content-Type: application/json');
        echo json_encode(['success' => true]);
        exit;
    }
}
```

์ด์ œ ๋ธŒ๋ผ์šฐ์ €์—์„œ `/hanja`๋กœ ์ ‘์†ํ•˜๋ฉด ์˜ค๋Š˜์˜ ํ•œ์ž ํ•™์Šต ํŽ˜์ด์ง€๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

๊ธฐ๋Œ€ ๊ฒฐ๊ณผ: - `/hanja` URL๋กœ ์ ‘์† ๊ฐ€๋Šฅํ•œ ๋ฉ”์ธ ํŽ˜์ด์ง€ ์ƒ์„ฑ - modern shell์ด ์ ์šฉ๋˜์–ด ์‚ฌ์ดํŠธ nav/footer๊ฐ€ ํ‘œ์‹œ๋จ - SQLite DB๊ฐ€ ์ž๋™ ์ƒ์„ฑ๋˜๊ณ  ์ƒ˜ํ”Œ ํ•œ์ž ๋ฐ์ดํ„ฐ ์‚ฝ์ž…๋จ - ์˜ค๋Š˜์˜ ํ•œ์ž๊ฐ€ ํฐ ์นด๋“œ๋กœ ํ‘œ์‹œ๋˜๊ณ , ํด๋ฆญ ์‹œ ์•ž๋’ค๋กœ ํ”Œ๋ฆฝ๋˜๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋™์ž‘ - ํ•™์Šต ์™„๋ฃŒ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ AJAX๋กœ DB ์—…๋ฐ์ดํŠธ ํ›„ ํŽ˜์ด์ง€ ์ƒˆ๋กœ๊ณ ์นจ - ํ•™์Šต ํ†ต๊ณ„(์ด ํ•™์Šต ์ผ์ˆ˜, ์—ฐ์† ์ผ์ˆ˜, ํ€ด์ฆˆ ์ •๋‹ต๋ฅ )๊ฐ€ ํ•˜๋‹จ์— ํ‘œ์‹œ๋จ - ๋‹คํฌ๋ชจ๋“œ ์ „ํ™˜ ์‹œ ์ƒ‰์ƒ์ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ณ€๊ฒฝ๋จ

2
Step 2
## Step 2: ํ•™์Šต ์•„์นด์ด๋ธŒ ํŽ˜์ด์ง€ ๊ตฌํ˜„

์ง€๊ธˆ๊นŒ์ง€ ํ•™์Šตํ•œ ํ•œ์ž ๋ชฉ๋ก์„ ๋‚ ์งœ๋ณ„๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ์•„์นด์ด๋ธŒ ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

### 1) ์•„์นด์ด๋ธŒ ํŽ˜์ด์ง€ ์ƒ์„ฑ (app/modules/hanja/archive.php)

๋‹ค์Œ ๋‚ด์šฉ์œผ๋กœ ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜์„ธ์š”:

```php
<?php
include_once('./_common.php');

// ๋ชจ๋“ˆ DB ์—ฐ๊ฒฐ
@mkdir(G5_DATA_PATH.'/modules', 0707, true);
$db = new PDO('sqlite:'.G5_DATA_PATH.'/modules/hanja.sqlite');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// ๊ฒ€์ƒ‰ ํŒŒ๋ผ๋ฏธํ„ฐ
$search = isset($_GET['search']) ? trim($_GET['search']) : '';
$filterBookmarked = isset($_GET['bookmarked']) ? true : false;

// ํ•™์Šตํ•œ ํ•œ์ž ๋ชฉ๋ก ๊ฐ€์ ธ์˜ค๊ธฐ
$query = "SELECT * FROM hanja_cards WHERE learned_date IS NOT NULL";
$params = [];

if ($search !== '') {
    $query .= " AND (hanja LIKE ? OR reading LIKE ? OR meaning LIKE ?)";
    $params[] = "%$search%";
    $params[] = "%$search%";
    $params[] = "%$search%";
}

if ($filterBookmarked) {
    $query .= " AND is_bookmarked = 1";
}

$query .= " ORDER BY learned_date DESC";

$stmt = $db->prepare($query);
$stmt->execute($params);
$learnedCards = $stmt->fetchAll(PDO::FETCH_ASSOC);

// ๋ถ๋งˆํฌ ํ† ๊ธ€ ์ฒ˜๋ฆฌ
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'toggle_bookmark') {
    $id = intval($_POST['id']);
    $stmt = $db->prepare("UPDATE hanja_cards SET is_bookmarked = NOT is_bookmarked WHERE id = ?");
    $stmt->execute([$id]);
    
    header('Content-Type: application/json');
    echo json_encode(['success' => true]);
    exit;
}

require_once(G5_THEME_PATH.'/modern/_head.inc.php');
include_once('./head.sub.php');
?>
<style>
.search-bar {
    display: flex;
    gap: 12px;
    margin-bottom: 24px;
    flex-wrap: wrap;
}

.search-input {
    flex: 1;
    min-width: 200px;
    padding: 12px 16px;
    border: 1px solid var(--m-text-muted);
    border-radius: var(--m-radius-lg);
    background: var(--m-surface);
    color: var(--m-text);
    font-size: 16px;
}

.search-input::placeholder {
    color: var(--m-text-muted);
}

.filter-checkbox {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
    background: var(--m-surface);
    border-radius: var(--m-radius-lg);
    cursor: pointer;
}

.hanja-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 20px;
    margin-top: 24px;
}

.hanja-card-mini {
    background: var(--m-surface);
    border-radius: var(--m-radius-lg);
    box-shadow: var(--m-shadow);
    padding: 24px;
    position: relative;
    transition: transform 0.2s, box-shadow 0.2s;
}

.hanja-card-mini:hover {
    transform: translateY(-4px);
    box-shadow: 0 8px 16px rgba(0,0,0,0.15);
}

.hanja-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 16px;
}

.hanja-char {
    font-size: 48px;
    font-weight: bold;
    color: var(--m-primary);
}

.bookmark-btn {
    background: none;
    border: none;
    font-size: 24px;
    cursor: pointer;
    transition: transform 0.2s;
}

.bookmark-btn:hover {
    transform: scale(1.2);
}

.hanja-info {
    margin-bottom: 12px;
}

.hanja-reading-mini {
    font-size: 18px;
    font-weight: bold;
    color: var(--m-text);
    margin-bottom: 4px;
}

.hanja-meaning-mini {
    font-size: 14px;
    color: var(--m-text-muted);
    margin-bottom: 8px;
}

.hanja-meta {
    display: flex;
    gap: 12px;
    font-size: 12px;
    color: var(--m-text-muted);
}

.hanja-date {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--m-text-muted);
    opacity: 0.3;
    font-size: 12px;
    color: var(--m-text-muted);
}

.empty-state {
    text-align: center;
    padding: 60px 20px;
}

.empty-state-icon {
    font-size: 64px;
    margin-bottom: 16px;
}

.btn {
    padding: 12px 24px;
    border-radius: var(--m-radius-lg);
    border: none;
    font-size: 16px;
    cursor: pointer;
    transition: opacity 0.2s;
    text-decoration: none;
    display: inline-block;
}

.btn:hover {
    opacity: 0.8;
}

.btn-primary {
    background: var(--m-primary);
    color: white;
}
</style>

<div class="m-shell">
    <?php require G5_THEME_PATH.'/modern/_nav.inc.php'; ?>
    <main class="m-container" style="padding: 32px 20px 48px;">
        <h1 style="color: var(--m-text); margin-bottom: 8px;">๐Ÿ“– ํ•™์Šต ์•„์นด์ด๋ธŒ</h1>
        <p style="color: var(--m-text-muted); margin-bottom: 32px;">์ง€๊ธˆ๊นŒ์ง€ ํ•™์Šตํ•œ ํ•œ์ž๋ฅผ ํ™•์ธํ•˜์„ธ์š”</p>

        <form method="GET" class="search-bar">
            <input 
                type="text" 
                name="search" 
                class="search-input" 
                placeholder="ํ•œ์ž, ํ›ˆ์Œ, ๋œป์œผ๋กœ ๊ฒ€์ƒ‰..." 
                value="<?php echo htmlspecialchars($search); ?>"
            >
            <label class="filter-checkbox">
                <input type="checkbox" name="bookmarked" <?php echo $filterBookmarked ? 'checked' : ''; ?> onchange="this.form.submit()">
                <span style="color: var(--m-text);">๐Ÿ”– ๋ถ๋งˆํฌ๋งŒ ๋ณด๊ธฐ</span>
            </label>
            <button type="submit" class="btn btn-primary">๊ฒ€์ƒ‰</button>
        </form>

        <?php if (count($learnedCards) > 0): ?>
            <div class="hanja-grid">
                <?php foreach ($learnedCards as $card): ?>
                    <div class="hanja-card-mini">
                        <div class="hanja-header">
                            <div class="hanja-char"><?php echo htmlspecialchars($card['hanja']); ?></div>
                            <button 
                                class="bookmark-btn" 
                                onclick="toggleBookmark(<?php echo $card['id']; ?>, this)"
                                title="๋ถ๋งˆํฌ"
                            >
                                <?php echo $card['is_bookmarked'] ? 'โญ' : 'โ˜†'; ?>
                            </button>
                        </div>
                        <div class="hanja-info">
                            <div class="hanja-reading-mini"><?php echo htmlspecialchars($card['reading']); ?></div>
                            <div class="hanja-meaning-mini"><?php echo htmlspecialchars($card['meaning']); ?></div>
                            <div class="hanja-meta">
                                <span>ํš์ˆ˜: <?php echo htmlspecialchars($card['strokes']); ?>ํš</span>
                                <span>๋ถ€์ˆ˜: <?php echo htmlspecialchars($card['radical']); ?></span>
                            </div>
                        </div>
                        <div class="hanja-date">
                            ํ•™์Šต์ผ: <?php echo htmlspecialchars($card['learned_date']); ?>
                        </div>
                    </div>
                <?php endforeach; ?>
            </div>
        <?php else: ?>
            <div class="empty-state">
                <div class="empty-state-icon">๐Ÿ“š</div>
                <h2 style="color: var(--m-text); margin-bottom: 8px;">
                    <?php echo $search !== '' || $filterBookmarked ? '๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค' : '์•„์ง ํ•™์Šตํ•œ ํ•œ์ž๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค'; ?>
                </h2>
                <p style="color: var(--m-text-muted); margin-bottom: 24px;">
                    <?php echo $search !== '' || $filterBookmarked ? '๋‹ค๋ฅธ ๊ฒ€์ƒ‰์–ด๋กœ ์‹œ๋„ํ•ด๋ณด์„ธ์š”' : '์˜ค๋Š˜์˜ ํ•œ์ž๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด๋ณด์„ธ์š”!'; ?>
                </p>
                <a href="/hanja" class="btn btn-primary">์˜ค๋Š˜์˜ ํ•œ์ž ๋ณด๊ธฐ</a>
            </div>
        <?php endif; ?>

        <div style="margin-top: 32px; text-align: center;">
            <a href="/hanja" class="btn btn-primary">โ† ๋ฉ”์ธ์œผ๋กœ</a>
            <a href="/hanja/quiz" class="btn btn-primary" style="margin-left: 12px;">ํ€ด์ฆˆ ํ’€๊ธฐ โ†’</a>
        </div>
    </main>
    <?php require G5_THEME_PATH.'/modern/_footer.inc.php'; ?>
</div>

<script>
function toggleBookmark(id, btn) {
    fetch('/hanja/archive', {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: 'action=toggle_bookmark&id=' + id
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            // ๋ถ๋งˆํฌ ์•„์ด์ฝ˜ ํ† ๊ธ€
            btn.textContent = btn.textContent === 'โญ' ? 'โ˜†' : 'โญ';
        }
    });
}
</script>

<?php include_once('./tail.sub.php'); ?>
```

์ด์ œ `/hanja/archive`๋กœ ์ ‘์†ํ•˜๋ฉด ํ•™์Šตํ•œ ํ•œ์ž ๋ชฉ๋ก์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋Œ€ ๊ฒฐ๊ณผ: - `/hanja/archive` URL๋กœ ํ•™์Šต ์•„์นด์ด๋ธŒ ํŽ˜์ด์ง€ ์ ‘์† ๊ฐ€๋Šฅ - ํ•™์Šต ์™„๋ฃŒํ•œ ํ•œ์ž๊ฐ€ ๊ทธ๋ฆฌ๋“œ ํ˜•ํƒœ๋กœ ์นด๋“œ๋กœ ํ‘œ์‹œ๋จ - ๊ฒ€์ƒ‰์ฐฝ์—์„œ ํ•œ์ž/ํ›ˆ์Œ/๋œป์œผ๋กœ ๊ฒ€์ƒ‰ ๊ฐ€๋Šฅ - ๋ถ๋งˆํฌ ํ•„ํ„ฐ ์ฒดํฌ๋ฐ•์Šค๋กœ ๋ถ๋งˆํฌํ•œ ํ•œ์ž๋งŒ ํ•„ํ„ฐ๋ง ๊ฐ€๋Šฅ - ๊ฐ ์นด๋“œ์˜ ๋ถ๋งˆํฌ ๋ฒ„ํŠผ(โ˜†/โญ) ํด๋ฆญ ์‹œ AJAX๋กœ ํ† ๊ธ€๋˜๊ณ  ์ฆ‰์‹œ ์•„์ด์ฝ˜ ๋ณ€๊ฒฝ - ํ˜ธ๋ฒ„ ์‹œ ์นด๋“œ๊ฐ€ ์œ„๋กœ ์‚ด์ง ์˜ฌ๋ผ๊ฐ€๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜ - ํ•™์Šตํ•œ ํ•œ์ž๊ฐ€ ์—†์„ ๊ฒฝ์šฐ ๋นˆ ์ƒํƒœ ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ - ๋‹คํฌ๋ชจ๋“œ์—์„œ๋„ ์ž์—ฐ์Šค๋Ÿฌ์šด ์ƒ‰์ƒ ์ „ํ™˜

3
Step 3
## Step 3: ๋ณต์Šต ํ€ด์ฆˆ ํŽ˜์ด์ง€ ๊ตฌํ˜„

ํ•™์Šตํ•œ ํ•œ์ž ์ค‘ ๋žœ๋ค์œผ๋กœ 5๊ฐœ๋ฅผ ์„ ํƒํ•˜์—ฌ ํ›ˆ์Œ ๋งž์ถ”๊ธฐ ํ€ด์ฆˆ๋ฅผ ์ œ๊ณตํ•˜๋Š” ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

### 1) ํ€ด์ฆˆ ํŽ˜์ด์ง€ ์ƒ์„ฑ (app/modules/hanja/quiz.php)

๋‹ค์Œ ๋‚ด์šฉ์œผ๋กœ ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜์„ธ์š”:

```php
<?php
include_once('./_common.php');

// ๋ชจ๋“ˆ DB ์—ฐ๊ฒฐ
@mkdir(G5_DATA_PATH.'/modules', 0707, true);
$db = new PDO('sqlite:'.G5_DATA_PATH.'/modules/hanja.sqlite');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// ํ€ด์ฆˆ ์ œ์ถœ ์ฒ˜๋ฆฌ
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'submit_quiz') {
    $answers = json_decode($_POST['answers'], true);
    $correctCount = 0;
    
    foreach ($answers as $answer) {
        $stmt = $db->prepare("SELECT reading FROM hanja_cards WHERE id = ?");
        $stmt->execute([$answer['id']]);
        $correct = $stmt->fetchColumn();
        
        if (strtolower(trim($answer['answer'])) === strtolower(trim($correct))) {
            $correctCount++;
        }
    }
    
    // ํ†ต๊ณ„ ์—…๋ฐ์ดํŠธ
    $stmt = $db->prepare("
        UPDATE hanja_stats 
        SET quiz_attempts = quiz_attempts + ?, quiz_correct = quiz_correct + ?
    ");
    $stmt->execute([count($answers), $correctCount]);
    
    header('Content-Type: application/json');
    echo json_encode([
        'success' => true,
        'correct' => $correctCount,
        'total' => count($answers)
    ]);
    exit;
}

// ํ•™์Šตํ•œ ํ•œ์ž ์ค‘ ๋žœ๋ค 5๊ฐœ ์„ ํƒ
$quizCards = $db->query("
    SELECT * FROM hanja_cards 
    WHERE learned_date IS NOT NULL 
    ORDER BY RANDOM() 
    LIMIT 5
")->fetchAll(PDO::FETCH_ASSOC);

require_once(G5_THEME_PATH.'/modern/_head.inc.php');
include_once('./head.sub.php');
?>
<style>
.quiz-container {
    max-width: 600px;
    margin: 0 auto;
}

.quiz-progress {
    display: flex;
    gap: 8px;
    margin-bottom: 32px;
    justify-content: center;
}

.progress-dot {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--m-text-muted);
    opacity: 0.3;
    transition: all 0.3s;
}

.progress-dot.active {
    background: var(--m-primary);
    opacity: 1;
    transform: scale(1.3);
}

.progress-dot.correct {
    background: #22c55e;
    opacity: 1;
}

.progress-dot.wrong {
    background: #ef4444;
    opacity: 1;
}

.quiz-card {
    background: var(--m-surface);
    border-radius: var(--m-radius-lg);
    box-shadow: var(--m-shadow);
    padding: 48px 32px;
    text-align: center;
    margin-bottom: 24px;
}

.quiz-number {
    color: var(--m-text-muted);
    font-size: 14px;
    margin-bottom: 16px;
}

.quiz-hanja {
    font-size: 96px;
    font-weight: bold;
    color: var(--m-primary);
    margin-bottom: 32px;
}

.quiz-input {
    width: 100%;
    max-width: 400px;
    padding: 16px 20px;
    font-size: 18px;
    border: 2px solid var(--m-text-muted);
    border-radius: var(--m-radius-lg);
    background: var(--m-surface);
    color: var(--m-text);
    text-align: center;
    transition: border-color 0.2s;
}

.quiz-input:focus {
    outline: none;
    border-color: var(--m-primary);
}

.quiz-input::placeholder {
    color: var(--m-text-muted);
}

.quiz-hint {
    margin-top: 16px;
    font-size: 14px;
    color: var(--m-text-muted);
}

.quiz-buttons {
    display: flex;
    gap: 12px;
    justify-content: center;
    margin-top: 24px;
}

.btn {
    padding: 12px 32px;
    border-radius: var(--m-radius-lg);
    border: none;
    font-size: 16px;
    cursor: pointer;
    transition: opacity 0.2s;
}

.btn:hover {
    opacity: 0.8;
}

.btn-primary {
    background: var(--m-primary);
    color: white;
}

.btn-secondary {
    background: var(--m-surface);
    color: var(--m-text);
    box-shadow: var(--m-shadow);
}

.result-card {
    background: var(--m-surface);
    border-radius: var(--m-radius-lg);
    box-shadow: var(--m-shadow);
    padding: 48px 32px;
    text-align: center;
}

.result-score {
    font-size: 72px;
    font-weight: bold;
    color: var(--m-primary);
    margin-bottom: 16px;
}

.result-message {
    font-size: 24px;
    color: var(--m-text);
    margin-bottom: 32px;
}

.result-details {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 16px;
    margin-top: 32px;
}

.result-stat {
    padding: 16px;
    background: var(--m-surface);
    border-radius: var(--m-radius-lg);
    box-shadow: var(--m-shadow);
}

.result-stat-value {
    font-size: 32px;
    font-weight: bold;
    color: var(--m-primary);
}

.result-stat-label {
    font-size: 14px;
    color: var(--m-text-muted);
    margin-top: 4px;
}
</style>

<div class="m-shell">
    <?php require G5_THEME_PATH.'/modern/_nav.inc.php'; ?>
    <main class="m-container" style="padding: 32px 20px 48px;">
        <h1 style="text-align: center; color: var(--m-text); margin-bottom: 8px;">โœ๏ธ ๋ณต์Šต ํ€ด์ฆˆ</h1>
        <p style="text-align: center; color: var(--m-text-muted); margin-bottom: 32px;">ํ•œ์ž๋ฅผ ๋ณด๊ณ  ํ›ˆ์Œ์„ ์ž…๋ ฅํ•˜์„ธ์š”</p>

        <?php if (count($quizCards) < 5): ?>
            <div class="result-card">
                <div style="font-size: 64px; margin-bottom: 16px;">๐Ÿ“š</div>
                <h2 style="color: var(--m-text); margin-bottom: 8px;">ํ€ด์ฆˆ๋ฅผ ์‹œ์ž‘ํ•˜๋ ค๋ฉด ์ตœ์†Œ 5๊ฐœ์˜ ํ•œ์ž๋ฅผ ํ•™์Šตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค</h2>
                <p style="color: var(--m-text-muted); margin-bottom: 24px;">ํ˜„์žฌ <?php echo count($quizCards); ?>๊ฐœ ํ•™์Šต ์™„๋ฃŒ</p>
                <a href="/hanja" class="btn btn-primary">ํ•™์Šตํ•˜๋Ÿฌ ๊ฐ€๊ธฐ</a>
            </div>
        <?php else: ?>
            <div class="quiz-container">
                <div class="quiz-progress" id="quizProgress">
                    <?php for ($i = 0; $i < 5; $i++): ?>
                        <div class="progress-dot <?php echo $i === 0 ? 'active' : ''; ?>"></div>
                    <?php endfor; ?>
                </div>

                <div id="quizArea">
                    <div class="quiz-card">
                        <div class="quiz-number">๋ฌธ์ œ <span id="currentNumber">1</span> / 5</div>
                        <div class="quiz-hanja" id="quizHanja"><?php echo htmlspecialchars($quizCards[0]['hanja']); ?></div>
                        <input 
                            type="text" 
                            class="quiz-input" 
                            id="quizInput" 
                            placeholder="ํ›ˆ์Œ์„ ์ž…๋ ฅํ•˜์„ธ์š” (์˜ˆ: ํฐ ๋Œ€)"
                            autocomplete="off"
                        >
                        <div class="quiz-hint">๐Ÿ’ก Tip: ๋„์–ด์“ฐ๊ธฐ์™€ ๋Œ€์†Œ๋ฌธ์ž๋Š” ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค</div>
                    </div>

                    <div class="quiz-buttons">
                        <button class="btn btn-secondary" onclick="skipQuestion()">๊ฑด๋„ˆ๋›ฐ๊ธฐ</button>
                        <button class="btn btn-primary" onclick="submitAnswer()">๋‹ค์Œ</button>
                    </div>
                </div>

                <div id="resultArea" style="display: none;">
                    <div class="result-card">
                        <div class="result-score" id="resultScore"></div>
                        <div class="result-message" id="resultMessage"></div>
                        <div class="result-details">
                            <div class="result-stat">
                                <div class="result-stat-value" id="correctCount"></div>
                                <div class="result-stat-label">์ •๋‹ต</div>
                            </div>
                            <div class="result-stat">
                                <div class="result-stat-value" id="wrongCount"></div>
                                <div class="result-stat-label">์˜ค๋‹ต</div>
                            </div>
                        </div>
                        <div style="margin-top: 32px;">
                            <a href="/hanja/quiz" class="btn btn-primary">๋‹ค์‹œ ํ’€๊ธฐ</a>
                            <a href="/hanja" class="btn btn-secondary" style="margin-left: 12px;">๋ฉ”์ธ์œผ๋กœ</a>
                        </div>
                    </div>
                </div>
            </div>
        <?php endif; ?>
    </main>
    <?php require G5_THEME_PATH.'/modern/_footer.inc.php'; ?>
</div>

<script>
const quizData = <?php echo json_encode($quizCards); ?>;
let currentIndex = 0;
let answers = [];

const quizInput = document.getElementById('quizInput');
const quizHanja = document.getElementById('quizHanja');
const currentNumber = document.getElementById('currentNumber');
const progressDots = document.querySelectorAll('.progress-dot');

// Enter ํ‚ค๋กœ ์ œ์ถœ
quizInput?.addEventListener('keypress', function(e) {
    if (e.key === 'Enter') {
        submitAnswer();
    }
});

function submitAnswer() {
    const answer = quizInput.value.trim();
    
    if (answer === '') {
        alert('๋‹ต์„ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”!');
        return;
    }
    
    // ๋‹ต์•ˆ ์ €์žฅ
    answers.push({
        id: quizData[currentIndex].id,
        answer: answer
    });
    
    // ๋‹ค์Œ ๋ฌธ์ œ๋กœ
    nextQuestion();
}

function skipQuestion() {
    answers.push({
        id: quizData[currentIndex].id,
        answer: ''
    });
    
    nextQuestion();
}

function nextQuestion() {
    currentIndex++;
    
    if (currentIndex < quizData.length) {
        // ๋‹ค์Œ ๋ฌธ์ œ ํ‘œ์‹œ
        quizHanja.textContent = quizData[currentIndex].hanja;
        quizInput.value = '';
        quizInput.focus();
        currentNumber.textContent = currentIndex + 1;
        
        // ์ง„ํ–‰๋ฅ  ์—…๋ฐ์ดํŠธ
        progressDots.forEach((dot, index) => {
            dot.classList.remove('active');
            if (index === currentIndex) {
                dot.classList.add('active');
            }
        });
    } else {
        // ํ€ด์ฆˆ ์™„๋ฃŒ
        finishQuiz();
    }
}

function finishQuiz() {
    // ์„œ๋ฒ„์— ๋‹ต์•ˆ ์ œ์ถœ
    fetch('/hanja/quiz', {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: 'action=submit_quiz&answers=' + encodeURIComponent(JSON.stringify(answers))
    })
    .then(response => response.json())
    .then(data => {
        showResult(data.correct, data.total);
    });
}

function showResult(correct, total) {
    const score = Math.round((correct / total) * 100);
    const wrong = total - correct;
    
    document.getElementById('quizArea').style.display = 'none';
    document.getElementById('resultArea').style.display = 'block';
    
    document.getElementById('resultScore').textContent = score + '์ ';
    document.getElementById('correctCount').textContent = correct;
    document.getElementById('wrongCount').textContent = wrong;
    
    let message = '';
    if (score === 100) {
        message = '๐ŸŽ‰ ์™„๋ฒฝํ•ฉ๋‹ˆ๋‹ค!';
    } else if (score >= 80) {
        message = '๐Ÿ‘ ํ›Œ๋ฅญํ•ด์š”!';
    } else if (score >= 60) {
        message = '๐Ÿ‘ ์ž˜ํ–ˆ์–ด์š”!';
    } else {
        message = '๐Ÿ’ช ์กฐ๊ธˆ๋งŒ ๋” ํž˜๋‚ด์„ธ์š”!';
    }
    document.getElementById('resultMessage').textContent = message;
    
    // ์ง„ํ–‰๋ฅ  ์  ์—…๋ฐ์ดํŠธ
    progressDots.forEach((dot, index) => {
        dot.classList.remove('active');
        if (index < correct) {
            dot.classList.add('correct');
        } else {
            dot.classList.add('wrong');
        }
    });
}
</script>

<?php include_once('./tail.sub.php'); ?>
```

์ด์ œ `/hanja/quiz`๋กœ ์ ‘์†ํ•˜๋ฉด ๋ณต์Šต ํ€ด์ฆˆ๋ฅผ ํ’€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋Œ€ ๊ฒฐ๊ณผ: - `/hanja/quiz` URL๋กœ ํ€ด์ฆˆ ํŽ˜์ด์ง€ ์ ‘์† ๊ฐ€๋Šฅ - ํ•™์Šตํ•œ ํ•œ์ž๊ฐ€ 5๊ฐœ ๋ฏธ๋งŒ์ด๋ฉด ์•ˆ๋‚ด ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ - 5๊ฐœ ์ด์ƒ์ด๋ฉด ๋žœ๋ค์œผ๋กœ 5๋ฌธ์ œ ์ถœ์ œ - ์ƒ๋‹จ์— ์ง„ํ–‰๋ฅ  ์ (dot) 5๊ฐœ๊ฐ€ ํ‘œ์‹œ๋˜๊ณ  ํ˜„์žฌ ๋ฌธ์ œ๊ฐ€ ๊ฐ•์กฐ๋จ - ํ•œ์ž๊ฐ€ ํฌ๊ฒŒ ํ‘œ์‹œ๋˜๊ณ  ์ž…๋ ฅ์ฐฝ์— ํ›ˆ์Œ ์ž…๋ ฅ ๊ฐ€๋Šฅ - Enter ํ‚ค ๋˜๋Š” '๋‹ค์Œ' ๋ฒ„ํŠผ์œผ๋กœ ์ œ์ถœ - '๊ฑด๋„ˆ๋›ฐ๊ธฐ' ๋ฒ„ํŠผ์œผ๋กœ ๋นˆ ๋‹ต์•ˆ ์ œ์ถœ ๊ฐ€๋Šฅ - 5๋ฌธ์ œ ์™„๋ฃŒ ํ›„ ๊ฒฐ๊ณผ ํ™”๋ฉด์œผ๋กœ ์ „ํ™˜ (์ ์ˆ˜, ์ •๋‹ต/์˜ค๋‹ต ์ˆ˜, ๋ฉ”์‹œ์ง€) - ์ง„ํ–‰๋ฅ  ์ ์ด ์ •๋‹ต์€ ์ดˆ๋ก์ƒ‰, ์˜ค๋‹ต์€ ๋นจ๊ฐ„์ƒ‰์œผ๋กœ ๋ณ€๊ฒฝ - ํ†ต๊ณ„ DB์— ํ€ด์ฆˆ ์‹œ๋„ ํšŸ์ˆ˜์™€ ์ •๋‹ต ์ˆ˜๊ฐ€ ๋ˆ„์ ๋จ - ๋‹คํฌ๋ชจ๋“œ์—์„œ๋„ ์ž์—ฐ์Šค๋Ÿฌ์šด UI

4
Step 4
## Step 4: ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ๊ฐœ์„  ๋ฐ ๋งˆ๋ฌด๋ฆฌ

๋งˆ์ง€๋ง‰์œผ๋กœ ์ „์ฒด์ ์ธ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๊ฐœ์„ ํ•˜๊ณ  ์„ธ๋ถ€ ๊ธฐ๋Šฅ์„ ๋ณด๊ฐ•ํ•ฉ๋‹ˆ๋‹ค.

### 1) ๋ฉ”์ธ ํŽ˜์ด์ง€ ๊ฐœ์„  (app/modules/hanja/index.php ์ˆ˜์ •)

๊ธฐ์กด ๋ฉ”์ธ ํŽ˜์ด์ง€์˜ `<main>` ์„น์…˜ ์ƒ๋‹จ์— ๋‹ค์Œ ์•ˆ๋‚ด ๋ฐฐ๋„ˆ๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š” (`<h1>` ํƒœ๊ทธ ๋ฐ”๋กœ ์œ„):

```php
<?php
// ํ•™์Šต ๊ฐ€๋Šฅํ•œ ํ•œ์ž ์ˆ˜ ํ™•์ธ
$remainingCount = $db->query("SELECT COUNT(*) FROM hanja_cards WHERE learned_date IS NULL")->fetchColumn();
?>

<?php if ($remainingCount > 0): ?>
    <div style="background: linear-gradient(135deg, var(--m-primary) 0%, #6366f1 100%); color: white; padding: 20px 24px; border-radius: var(--m-radius-lg); margin-bottom: 24px; box-shadow: var(--m-shadow);">
        <div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px;">
            <div>
                <div style="font-size: 14px; opacity: 0.9; margin-bottom: 4px;">ํ•™์Šต ์ง„ํ–‰๋ฅ </div>
                <div style="font-size: 24px; font-weight: bold;">
                    <?php 
                    $totalCount = $db->query("SELECT COUNT(*) FROM hanja_cards")->fetchColumn();
                    $learnedCount = $totalCount - $remainingCount;
                    echo "$learnedCount / $totalCount";
                    ?>
                </div>
            </div>
            <div style="font-size: 14px; opacity: 0.9;">
                <?php echo round(($learnedCount / $totalCount) * 100); ?>% ์™„๋ฃŒ
            </div>
        </div>
        <div style="background: rgba(255,255,255,0.2); height: 8px; border-radius: 4px; margin-top: 12px; overflow: hidden;">
            <div style="background: white; height: 100%; width: <?php echo round(($learnedCount / $totalCount) * 100); ?>%; transition: width 0.3s;"></div>
        </div>
    </div>
<?php endif; ?>
```

### 2) ์•„์นด์ด๋ธŒ ํŽ˜์ด์ง€์— ํ†ต๊ณ„ ์š”์•ฝ ์ถ”๊ฐ€ (app/modules/hanja/archive.php ์ˆ˜์ •)

๊ฒ€์ƒ‰ ๋ฐ” ์œ„์— ๋‹ค์Œ ํ†ต๊ณ„ ์„น์…˜์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”:

```php
<?php
// ํ†ต๊ณ„ ๊ณ„์‚ฐ
$totalLearned = count($learnedCards);
$bookmarkedCount = $db->query("SELECT COUNT(*) FROM hanja_cards WHERE is_bookmarked = 1")->fetchColumn();
$thisWeekCount = $db->query("
    SELECT COUNT(*) FROM hanja_cards 
    WHERE learned_date >= date('now', '-7 days')
")->fetchColumn();
?>

<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; margin-bottom: 32px;">
    <div style="background: var(--m-surface); padding: 20px; border-radius: var(--m-radius-lg); box-shadow: var(--m-shadow); text-align: center;">
        <div style="font-size: 36px; font-weight: bold; color: var(--m-primary);"><?php echo $totalLearned; ?></div>
        <div style="font-size: 14px; color: var(--m-text-muted); margin-top: 4px;">์ด ํ•™์Šต ํ•œ์ž</div>
    </div>
    <div style="background: var(--m-surface); padding: 20px; border-radius: var(--m-radius-lg); box-shadow: var(--m-shadow); text-align: center;">
        <div style="font-size: 36px; font-weight: bold; color: #f59e0b;"><?php echo $bookmarkedCount; ?></div>
        <div style="font-size: 14px; color: var(--m-text-muted); margin-top: 4px;">๋ถ๋งˆํฌ</div>
    </div>
    <div style="background: var(--m-surface); padding: 20px; border-radius: var(--m-radius-lg); box-shadow: var(--m-shadow); text-align: center;">
        <div style="font-size: 36px; font-weight: bold; color: #22c55e;"><?php echo $thisWeekCount; ?></div>
        <div style="font-size: 14px; color: var(--m-text-muted); margin-top: 4px;">์ด๋ฒˆ ์ฃผ ํ•™์Šต</div>
    </div>
</div>
```

### 3) ํ€ด์ฆˆ ํŽ˜์ด์ง€์— ํžŒํŠธ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ (app/modules/hanja/quiz.php ์ˆ˜์ •)

ํ€ด์ฆˆ ์นด๋“œ ์•ˆ์˜ ์ž…๋ ฅ์ฐฝ ์•„๋ž˜์— ํžŒํŠธ ๋ฒ„ํŠผ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”:

```html
<!-- ๊ธฐ์กด quiz-hint div ์•„๋ž˜์— ์ถ”๊ฐ€ -->
<button class="btn btn-secondary" onclick="showHint()" id="hintBtn" style="margin-top: 16px;">
    ๐Ÿ’ก ํžŒํŠธ ๋ณด๊ธฐ
</button>
<div id="hintText" style="display: none; margin-top: 12px; padding: 12px; background: rgba(99, 102, 241, 0.1); border-radius: 8px; color: var(--m-text);">
    ํš์ˆ˜: <span id="hintStrokes"></span>ํš | 
    ๋ถ€์ˆ˜: <span id="hintRadical"></span>
</div>
```

๊ทธ๋ฆฌ๊ณ  `<script>` ์„น์…˜์— ๋‹ค์Œ ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”:

```javascript
function showHint() {
    const current = quizData[currentIndex];
    document.getElementById('hintStrokes').textContent = current.strokes;
    document.getElementById('hintRadical').textContent = current.radical;
    document.getElementById('hintText').style.display = 'block';
    document.getElementById('hintBtn').style.display = 'none';
}

// nextQuestion ํ•จ์ˆ˜ ์•ˆ์— ํžŒํŠธ ์ดˆ๊ธฐํ™” ์ฝ”๋“œ ์ถ”๊ฐ€
function nextQuestion() {
    currentIndex++;
    
    if (currentIndex < quizData.length) {
        // ... ๊ธฐ์กด ์ฝ”๋“œ ...
        
        // ํžŒํŠธ ์ดˆ๊ธฐํ™”
        document.getElementById('hintText').style.display = 'none';
        document.getElementById('hintBtn').style.display = 'inline-block';
    } else {
        finishQuiz();
    }
}
```

### 4) ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ฐœ์„ 

๋ชจ๋“  ํŽ˜์ด์ง€์˜ `<style>` ์„น์…˜ ๋์— ๋‹ค์Œ ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•˜์„ธ์š”:

```css
@media (max-width: 640px) {
    .hanja-display {
        font-size: 80px;
    }
    
    .quiz-hanja {
        font-size: 72px;
    }
    
    .hanja-grid {
        grid-template-columns: 1fr;
    }
    
    .stats-grid {
        grid-template-columns: 1fr;
    }
    
    .action-buttons {
        flex-direction: column;
    }
    
    .btn {
        width: 100%;
    }
}
```

### 5) ์ตœ์ข… ํ…Œ์ŠคํŠธ

๋‹ค์Œ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ํ…Œ์ŠคํŠธํ•˜์„ธ์š”:

1. **๋ฉ”์ธ ํŽ˜์ด์ง€**
   - `/hanja` ์ ‘์†
   - ํ•™์Šต ์ง„ํ–‰๋ฅ  ๋ฐฐ๋„ˆ ํ™•์ธ
   - ํ•œ์ž ์นด๋“œ ํด๋ฆญํ•˜์—ฌ ํ”Œ๋ฆฝ ์• ๋‹ˆ๋ฉ”์ด์…˜ ํ™•์ธ
   - ํ•™์Šต ์™„๋ฃŒ ๋ฒ„ํŠผ ํด๋ฆญ ํ›„ ํ†ต๊ณ„ ์—…๋ฐ์ดํŠธ ํ™•์ธ

2. **์•„์นด์ด๋ธŒ ํŽ˜์ด์ง€**
   - `/hanja/archive` ์ ‘์†
   - ํ†ต๊ณ„ ์š”์•ฝ ํ™•์ธ
   - ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ
   - ๋ถ๋งˆํฌ ํ† ๊ธ€ ํ…Œ์ŠคํŠธ
   - ๋ถ๋งˆํฌ ํ•„ํ„ฐ ํ…Œ์ŠคํŠธ

3. **ํ€ด์ฆˆ ํŽ˜์ด์ง€**
   - `/hanja/quiz` ์ ‘์†
   - 5๋ฌธ์ œ ํ’€์ด (์ •๋‹ต/์˜ค๋‹ต ์„ž์–ด์„œ)
   - ํžŒํŠธ ๊ธฐ๋Šฅ ์‚ฌ์šฉ
   - ๊ฑด๋„ˆ๋›ฐ๊ธฐ ๊ธฐ๋Šฅ ์‚ฌ์šฉ
   - ๊ฒฐ๊ณผ ํ™”๋ฉด ํ™•์ธ
   - ํ†ต๊ณ„ ์—…๋ฐ์ดํŠธ ํ™•์ธ

4. **๋‹คํฌ๋ชจ๋“œ**
   - nav์˜ ๋‹คํฌ๋ชจ๋“œ ํ† ๊ธ€ ๋ฒ„ํŠผ ํด๋ฆญ
   - ๋ชจ๋“  ํŽ˜์ด์ง€์—์„œ ์ƒ‰์ƒ ์ „ํ™˜ ํ™•์ธ

5. **๋ฐ˜์‘ํ˜•**
   - ๋ธŒ๋ผ์šฐ์ € ์ฐฝ ํฌ๊ธฐ ์กฐ์ ˆ
   - ๋ชจ๋ฐ”์ผ ํ™”๋ฉด์—์„œ ๋ ˆ์ด์•„์›ƒ ํ™•์ธ

๋ชจ๋“  ๊ธฐ๋Šฅ์ด ์ •์ƒ ๋™์ž‘ํ•˜๋ฉด ์™„์„ฑ์ž…๋‹ˆ๋‹ค! ๐ŸŽ‰

๊ธฐ๋Œ€ ๊ฒฐ๊ณผ: - ๋ฉ”์ธ ํŽ˜์ด์ง€์— ํ•™์Šต ์ง„ํ–‰๋ฅ  ๋ฐฐ๋„ˆ๊ฐ€ ํ‘œ์‹œ๋˜๊ณ  ํ”„๋กœ๊ทธ๋ ˆ์Šค ๋ฐ”๊ฐ€ ์• ๋‹ˆ๋ฉ”์ด์…˜์œผ๋กœ ์ฑ„์›Œ์ง - ์•„์นด์ด๋ธŒ ํŽ˜์ด์ง€์— ์ด ํ•™์Šต ํ•œ์ž ์ˆ˜, ๋ถ๋งˆํฌ ์ˆ˜, ์ด๋ฒˆ ์ฃผ ํ•™์Šต ์ˆ˜ ํ†ต๊ณ„ ์นด๋“œ๊ฐ€ ํ‘œ์‹œ๋จ - ํ€ด์ฆˆ ํŽ˜์ด์ง€์— ํžŒํŠธ ๋ฒ„ํŠผ์ด ์ถ”๊ฐ€๋˜๊ณ  ํด๋ฆญ ์‹œ ํš์ˆ˜์™€ ๋ถ€์ˆ˜ ์ •๋ณด ํ‘œ์‹œ - ๋ชจ๋“  ํŽ˜์ด์ง€๊ฐ€ ๋ชจ๋ฐ”์ผ ํ™”๋ฉด์—์„œ 1์—ด ๊ทธ๋ฆฌ๋“œ๋กœ ์ „ํ™˜๋˜๊ณ  ๋ฒ„ํŠผ์ด ์ „์ฒด ๋„ˆ๋น„๋กœ ํ™•์žฅ๋จ - ๋‹คํฌ๋ชจ๋“œ ์ „ํ™˜ ์‹œ ๋ชจ๋“  ์š”์†Œ์˜ ์ƒ‰์ƒ์ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ณ€๊ฒฝ๋จ - ๋ชจ๋“  ์ธํ„ฐ๋ž™์…˜(์นด๋“œ ํ”Œ๋ฆฝ, ๋ถ๋งˆํฌ ํ† ๊ธ€, ํ€ด์ฆˆ ์ œ์ถœ)์ด ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ๋™์ž‘ - SQLite DB์— ๋ฐ์ดํ„ฐ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ €์žฅ๋˜๊ณ  ์กฐํšŒ๋จ - ์ „์ฒด์ ์œผ๋กœ ์™„์„ฑ๋„ ๋†’์€ ํ•œ์ž ํ•™์Šต ํ”Œ๋žซํผ์ด ๊ตฌํ˜„๋จ

์ œ์ถœ๋œ ์ž‘ํ’ˆ (0)

๋กœ๊ทธ์ธ ํ›„ ์ œ์ถœ

์•„์ง ์ œ์ถœ๋œ ์ž‘ํ’ˆ์ด ์—†์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋„์ „์ž๊ฐ€ ๋˜์–ด๋ณด์„ธ์š”!

๋Œ“๊ธ€ (0)

๋กœ๊ทธ์ธ ํ›„ ๋Œ“๊ธ€์„ ๋‚จ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์•„์ง ๋Œ“๊ธ€์ด ์—†์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋Œ“๊ธ€์„ ๋‚จ๊ฒจ๋ณด์„ธ์š”!