Feat: Добавлены show и edit шаблоны для вопросов
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
parent
89e72895c8
commit
54e13c7c96
|
|
@ -0,0 +1,128 @@
|
|||
@extends('layouts.app')
|
||||
@section('title', 'Редактировать вопрос')
|
||||
@section('content')
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<nav class="col-md-3 col-lg-2 d-md-block sidebar"><div class="position-sticky pt-3">@include('partials._sidebar')</div></nav>
|
||||
<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4 main-content">
|
||||
<div class="d-flex justify-content-between align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h1 class="h2">Редактировать вопрос</h1>
|
||||
<a href="{{ route('admin.tests.questions.index', $test) }}" class="btn btn-secondary btn-sm">Назад</a>
|
||||
</div>
|
||||
<form action="{{ route('admin.tests.questions.update', [$test, $question]) }}" method="POST" id="questionForm">
|
||||
@csrf @method('PUT')
|
||||
<input type="hidden" name="type" id="questionType" value="{{ $question->type }}">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="card shadow-sm mb-3">
|
||||
<div class="card-body">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Тип вопроса *</label>
|
||||
<select name="type_select" id="typeSelect" class="form-select" onchange="updateQuestionType()">
|
||||
<option value="single_choice" {{ $question->type == 'single_choice' ? 'selected' : '' }}>Один правильный ответ</option>
|
||||
<option value="multiple_choice" {{ $question->type == 'multiple_choice' ? 'selected' : '' }}>Несколько правильных ответов</option>
|
||||
<option value="input" {{ $question->type == 'input' ? 'selected' : '' }}>Ввод текста</option>
|
||||
<option value="matching" {{ $question->type == 'matching' ? 'selected' : '' }}>Соответствие</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Текст вопроса *</label>
|
||||
<textarea name="question_text" class="form-control" rows="3" required>{{ old('question_text', $question->question_text) }}</textarea>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Пояснение</label>
|
||||
<textarea name="explanation" class="form-control" rows="2">{{ old('explanation', $question->explanation) }}</textarea>
|
||||
<small class="text-muted">Отображается после ответа</small>
|
||||
</div>
|
||||
|
||||
<div id="answersSection" class="mb-3">
|
||||
<label class="form-label">Ответы</label>
|
||||
<div id="answersContainer">
|
||||
@foreach($question->answers as $answer)
|
||||
<div class="input-group mb-2">
|
||||
<input type="text" name="answers[{{ $loop->index }}][text]" class="form-control" value="{{ $answer->answer_text }}">
|
||||
<input type="hidden" name="answers[{{ $loop->index }}][is_correct]" value="{{ $answer->is_correct ? '1' : '0' }}">
|
||||
<button type="button" class="btn btn-outline-success" onclick="toggleCorrect(this)"><i class="bi {{ $answer->is_correct ? 'bi-check-circle-fill text-success' : 'bi-circle' }}"></i></button>
|
||||
<button type="button" class="btn btn-outline-danger" onclick="removeAnswer(this)"><i class="bi bi-trash"></i></button>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm btn-secondary" onclick="addAnswer()">+ Добавить ответ</button>
|
||||
</div>
|
||||
|
||||
<div id="matchingSection" class="mb-3" style="display:none;">
|
||||
<label class="form-label">Пары для соответствия</label>
|
||||
<div id="matchingContainer">
|
||||
@foreach($question->matchingPairs as $pair)
|
||||
<div class="input-group mb-2">
|
||||
<input type="text" name="matching_pairs[{{ $loop->index }}][left_text]" class="form-control" value="{{ $pair->left_text }}">
|
||||
<input type="text" name="matching_pairs[{{ $loop->index }}][right_text]" class="form-control" value="{{ $pair->right_text }}">
|
||||
<input type="number" name="matching_pairs[{{ $loop->index }}][match_score]" class="form-control" value="{{ $pair->match_score }}" style="width:80px">
|
||||
<button type="button" class="btn btn-outline-danger" onclick="this.parentElement.remove()"><i class="bi bi-trash"></i></button>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm btn-secondary" onclick="addMatchingPair()">+ Добавить пару</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card shadow-sm mb-3">
|
||||
<div class="card-body">
|
||||
<h5>Настройки</h5>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Баллы</label>
|
||||
<input type="number" name="score" class="form-control" value="{{ old('score', $question->score) }}" min="1">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Порядок</label>
|
||||
<input type="number" name="sort_order" class="form-control" value="{{ old('sort_order', $question->sort_order) }}">
|
||||
</div>
|
||||
<div class="form-check mb-3">
|
||||
<input type="checkbox" name="is_required" value="1" class="form-check-input" {{ old('is_required', $question->is_required) ? 'checked' : '' }}>
|
||||
<label class="form-check-label">Обязательный вопрос</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Сохранить</button>
|
||||
<a href="{{ route('admin.tests.questions.index', $test) }}" class="btn btn-secondary">Отмена</a>
|
||||
</form>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function updateQuestionType() {
|
||||
const type = document.getElementById('typeSelect').value;
|
||||
document.getElementById('questionType').value = type;
|
||||
const answersSection = document.getElementById('answersSection');
|
||||
const matchingSection = document.getElementById('matchingSection');
|
||||
answersSection.style.display = (type === 'single_choice' || type === 'multiple_choice') ? 'block' : 'none';
|
||||
matchingSection.style.display = (type === 'matching') ? 'block' : 'none';
|
||||
}
|
||||
function addAnswer() {
|
||||
const container = document.getElementById('answersContainer');
|
||||
const index = container.children.length;
|
||||
const div = document.createElement('div');
|
||||
div.className = 'input-group mb-2';
|
||||
div.innerHTML = `<input type="text" name="answers[${index}][text]" class="form-control" placeholder="Текст ответа"><input type="hidden" name="answers[${index}][is_correct]" value="0"><button type="button" class="btn btn-outline-success" onclick="toggleCorrect(this)"><i class="bi bi-circle"></i></button><button type="button" class="btn btn-outline-danger" onclick="removeAnswer(this)"><i class="bi bi-trash"></i></button>`;
|
||||
container.appendChild(div);
|
||||
}
|
||||
function removeAnswer(btn) { btn.parentElement.remove(); }
|
||||
function toggleCorrect(btn) {
|
||||
const hidden = btn.previousElementSibling;
|
||||
if (hidden.value === '0') { hidden.value = '1'; btn.innerHTML = '<i class="bi bi-check-circle-fill text-success"></i>'; }
|
||||
else { hidden.value = '0'; btn.innerHTML = '<i class="bi bi-circle"></i>'; }
|
||||
}
|
||||
function addMatchingPair() {
|
||||
const container = document.getElementById('matchingContainer');
|
||||
const index = container.children.length;
|
||||
const div = document.createElement('div');
|
||||
div.className = 'input-group mb-2';
|
||||
div.innerHTML = `<input type="text" name="matching_pairs[${index}][left_text]" class="form-control" placeholder="Левая часть"><input type="text" name="matching_pairs[${index}][right_text]" class="form-control" placeholder="Правая часть"><input type="number" name="matching_pairs[${index}][match_score]" class="form-control" value="1" style="width:80px"><button type="button" class="btn btn-outline-danger" onclick="this.parentElement.remove()"><i class="bi bi-trash"></i></button>`;
|
||||
container.appendChild(div);
|
||||
}
|
||||
</script>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
@extends('layouts.app')
|
||||
@section('title', $question->question_text)
|
||||
@section('content')
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<nav class="col-md-3 col-lg-2 d-md-block sidebar"><div class="position-sticky pt-3">@include('partials._sidebar')</div></nav>
|
||||
<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4 main-content">
|
||||
<div class="d-flex justify-content-between align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h1 class="h2">Вопрос #{{ $question->id }}</h1>
|
||||
<div>
|
||||
<a href="{{ route('admin.tests.questions.edit', [$test, $question]) }}" class="btn btn-warning btn-sm me-2">Редактировать</a>
|
||||
<a href="{{ route('admin.tests.questions.index', $test) }}" class="btn btn-secondary btn-sm">Назад</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8 mb-4">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header bg-primary text-white"><h5 class="mb-0">Информация</h5></div>
|
||||
<div class="card-body">
|
||||
<table class="table table-sm">
|
||||
<tr><th>Тип:</th><td><span class="badge bg-info">{{ $question->type }}</span></td></tr>
|
||||
<tr><th>Вопрос:</th><td>{{ $question->question_text }}</td></tr>
|
||||
<tr><th>Пояснение:</th><td>{{ $question->explanation ?? '—' }}</td></tr>
|
||||
<tr><th>Баллы:</th><td>{{ $question->score }}</td></tr>
|
||||
<tr><th>Порядок:</th><td>{{ $question->sort_order }}</td></tr>
|
||||
<tr><th>Обязательный:</th><td>@if($question->is_required)<span class="badge bg-warning">Да</span>@else<span class="badge bg-secondary">Нет</span>@endif</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 mb-4">
|
||||
<div class="card shadow-sm">
|
||||
@if($question->type === 'matching')
|
||||
<div class="card-header"><h5 class="mb-0">Пары</h5></div>
|
||||
<div class="card-body">
|
||||
@if($question->matchingPairs->count() > 0)
|
||||
<ul class="list-group list-group-flush">
|
||||
@foreach($question->matchingPairs as $pair)
|
||||
<li class="list-group-item"><strong>{{ $pair->left_text }}</strong> ↔ <strong>{{ $pair->right_text }}</strong> ({{ $pair->match_score }} балл.)</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@else
|
||||
<p class="text-muted mb-0">Нет пар</p>
|
||||
@endif
|
||||
</div>
|
||||
@else
|
||||
<div class="card-header"><h5 class="mb-0">Ответы</h5></div>
|
||||
<div class="card-body">
|
||||
@if($question->answers->count() > 0)
|
||||
<ul class="list-group list-group-flush">
|
||||
@foreach($question->answers as $answer)
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
{{ Str::limit($answer->answer_text, 50) }}
|
||||
@if($answer->is_correct)<span class="badge bg-success"><i class="bi bi-check"></i></span>@endif
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@else
|
||||
<p class="text-muted mb-0">Нет ответов</p>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
Loading…
Reference in New Issue