add assigning of tests
This commit is contained in:
parent
8a9007561f
commit
8b1877d1aa
93
app/Http/Controllers/AssignedTestsController.php
Normal file
93
app/Http/Controllers/AssignedTestsController.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\AssignedTests;
|
||||
use App\Models\MultipleChoiceAnswers;
|
||||
use App\Models\SingleChoiceAnswer;
|
||||
use App\Models\SingleQuestionAnswers;
|
||||
use App\Models\Test;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class AssignedTestsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
"test_id" => "required|integer",
|
||||
"student_id" => "required|integer"
|
||||
]);
|
||||
|
||||
AssignedTests::create($validated);
|
||||
|
||||
return redirect(route("tests.edit", [
|
||||
"test" => Test::where("id", $validated["test_id"])->first()
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show($assigned_student)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit($assigned_student)
|
||||
{
|
||||
$obj = AssignedTests::where("id", $assigned_student);
|
||||
$obj->update([
|
||||
"allowed" => "1"
|
||||
]);
|
||||
$test_id = $obj->first()->test_id;
|
||||
|
||||
return redirect(route("tests.edit", [
|
||||
"test" => Test::where("id", $test_id)->first()
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, AssignedTests $assigned_student)
|
||||
{
|
||||
// $test->update($validated);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy($assigned_student)
|
||||
{
|
||||
$obj = AssignedTests::where("id", $assigned_student);
|
||||
$test_id = $obj->first()->test_id;
|
||||
$obj->delete();
|
||||
|
||||
return redirect(route("tests.edit", [
|
||||
"test" => Test::where("id", $test_id)->first()
|
||||
]));
|
||||
}
|
||||
}
|
@ -2,10 +2,12 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\AssignedTests;
|
||||
use App\Models\MultipleChoiceAnswers;
|
||||
use App\Models\SingleChoiceAnswer;
|
||||
use App\Models\SingleQuestionAnswers;
|
||||
use App\Models\Test;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TestController extends Controller
|
||||
@ -83,9 +85,27 @@ class TestController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
$students = User::where("role", "student")->get()->toArray();
|
||||
|
||||
$assigned_students = [];
|
||||
foreach (AssignedTests::where("test_id", $test->id)->get() as $assigned_student) {
|
||||
$backing_student = User::where("id", $assigned_student->student_id)->first();
|
||||
$assigned_student->name = $backing_student->name;
|
||||
|
||||
foreach ($students as $idx => $student) {
|
||||
if ($student["id"] == $assigned_student->student_id) {
|
||||
unset($students[$idx]);
|
||||
}
|
||||
}
|
||||
|
||||
array_push($assigned_students, $assigned_student);
|
||||
}
|
||||
|
||||
return view("tests.edit", [
|
||||
"test" => $test,
|
||||
"questions" => $questions,
|
||||
"students" => $students,
|
||||
"assigned_students" => $assigned_students,
|
||||
]);
|
||||
}
|
||||
|
||||
|
16
app/Models/AssignedTests.php
Normal file
16
app/Models/AssignedTests.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class AssignedTests extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
"test_id",
|
||||
'student_id',
|
||||
];
|
||||
}
|
11
app/Models/TestQuestionResult.php
Normal file
11
app/Models/TestQuestionResult.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class TestQuestionResult extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
}
|
11
app/Models/TestResult.php
Normal file
11
app/Models/TestResult.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class TestResult extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('test_results', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId("student_id")->references("id")->on("users")->constrained()->cascadeOnDelete();
|
||||
$table->foreignId("test_id")->references("id")->on("tests")->constrained()->cascadeOnDelete();
|
||||
$table->float("points")->default(0);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('test_results');
|
||||
}
|
||||
};
|
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('test_question_results', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId("test_results_id")->references("id")->on("test_results")->constrained()->cascadeOnDelete();
|
||||
$table->foreignId("question_id")->references("id")->on("questions")->constrained()->cascadeOnDelete();
|
||||
$table->float("points")->default(0);
|
||||
$table->string("answer");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('test_question_results');
|
||||
}
|
||||
};
|
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('assigned_tests', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId("student_id")->references("id")->on("users")->constrained()->cascadeOnDelete();
|
||||
$table->foreignId("test_id")->references("id")->on("tests")->constrained()->cascadeOnDelete();
|
||||
$table->boolean("allowed")->default(true);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('assigned_tests');
|
||||
}
|
||||
};
|
@ -16,58 +16,132 @@
|
||||
</form>
|
||||
|
||||
<hr class="mt-6 mb-6">
|
||||
<div>
|
||||
<h2 class="text-center text-lg font-medium">{{ __("Questions") }}</h2>
|
||||
|
||||
<form method="POST" action="{{ route('questions.store') }}">
|
||||
@csrf
|
||||
<div class="flex flex-col gap-1">
|
||||
<x-question-fields
|
||||
:test_id="$test->id"
|
||||
/>
|
||||
</div>
|
||||
<form method="POST" action="{{ route('questions.store') }}">
|
||||
@csrf
|
||||
<div class="flex flex-col gap-1">
|
||||
<x-question-fields
|
||||
:test_id="$test->id"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 space-x-2">
|
||||
<x-primary-button>{{ __("Add question") }}</x-primary-button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="mt-4 space-x-2">
|
||||
<x-primary-button>{{ __("Add question") }}</x-primary-button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<table class="mt-6 border border-gray-300 w-full text-left">
|
||||
<tr>
|
||||
<th class="border border-gray-300 p-1">{{ __("Question") }}</th>
|
||||
<th class="border border-gray-300 p-1">{{ __("Answer") }}</th>
|
||||
<th class="border border-gray-300 p-1">{{ __("Points") }}</th>
|
||||
<th class="border border-gray-300 p-1"></th>
|
||||
</tr>
|
||||
<table class="mt-6 border border-gray-300 w-full text-left">
|
||||
<tr>
|
||||
<th class="border border-gray-300 p-1">{{ __("Question") }}</th>
|
||||
<th class="border border-gray-300 p-1">{{ __("Answer") }}</th>
|
||||
<th class="border border-gray-300 p-1">{{ __("Points") }}</th>
|
||||
<th class="border border-gray-300 p-1"></th>
|
||||
</tr>
|
||||
|
||||
@foreach ($questions as $question)
|
||||
<tr>
|
||||
<td class="border border-gray-300 p-1">{{ $question->question }}</td>
|
||||
<td class="border border-gray-300 p-1">{{ $question->answer }}</td>
|
||||
<td class="border border-gray-300 p-1">{{ $question->points }}</td>
|
||||
<td class="border border-gray-300 p-1">
|
||||
<x-dropdown>
|
||||
<x-slot name="trigger">
|
||||
<button>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-gray-400" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M6 10a2 2 0 11-4 0 2 2 0 014 0zM12 10a2 2 0 11-4 0 2 2 0 014 0zM16 12a2 2 0 100-4 2 2 0 000 4z" />
|
||||
</svg>
|
||||
</button>
|
||||
</x-slot>
|
||||
<x-slot name="content">
|
||||
<x-dropdown-link :href="route('questions.edit', $question)">
|
||||
{{ __("Edit") }}
|
||||
</x-dropdown-link>
|
||||
<form method="POST" action="{{ route("questions.destroy", $question) }}">
|
||||
@csrf
|
||||
@method("delete")
|
||||
<x-dropdown-link :href="route('questions.destroy', $question)" onclick="event.preventDefault(); this.closest('form').submit();">
|
||||
{{ __("Delete") }}
|
||||
@foreach ($questions as $question)
|
||||
<tr>
|
||||
<td class="border border-gray-300 p-1">{{ $question->question }}</td>
|
||||
<td class="border border-gray-300 p-1">{{ $question->answer }}</td>
|
||||
<td class="border border-gray-300 p-1">{{ $question->points }}</td>
|
||||
<td class="border border-gray-300 p-1">
|
||||
<x-dropdown>
|
||||
<x-slot name="trigger">
|
||||
<button>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-gray-400" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M6 10a2 2 0 11-4 0 2 2 0 014 0zM12 10a2 2 0 11-4 0 2 2 0 014 0zM16 12a2 2 0 100-4 2 2 0 000 4z" />
|
||||
</svg>
|
||||
</button>
|
||||
</x-slot>
|
||||
<x-slot name="content">
|
||||
<x-dropdown-link :href="route('questions.edit', $question)">
|
||||
{{ __("Edit") }}
|
||||
</x-dropdown-link>
|
||||
</form>
|
||||
</x-slot>
|
||||
</x-dropdown>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
<form method="POST" action="{{ route("questions.destroy", $question) }}">
|
||||
@csrf
|
||||
@method("delete")
|
||||
<x-dropdown-link :href="route('questions.destroy', $question)" onclick="event.preventDefault(); this.closest('form').submit();">
|
||||
{{ __("Delete") }}
|
||||
</x-dropdown-link>
|
||||
</form>
|
||||
</x-slot>
|
||||
</x-dropdown>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<hr class="mt-6 mb-6">
|
||||
<div>
|
||||
<h2 class="text-center text-lg font-medium">{{ __("Assigned students") }}</h2>
|
||||
|
||||
<form method="POST" action="{{ route('assigned_tests.store') }}">
|
||||
@csrf
|
||||
<div class="flex flex-col gap-1">
|
||||
<input type="hidden" value="{{ $test->id }}" name="test_id">
|
||||
|
||||
<x-input-label>{{ __("Student") }}</x-input-label>
|
||||
<x-select name="student_id" id="student_id">
|
||||
@if (sizeof($students) == 0)
|
||||
<option selected disabled hidden>{{ __("-- Empty --") }}</option>
|
||||
@endif
|
||||
@foreach ($students as $student)
|
||||
<option value="{{$student['id']}}" {{ old("student") == $student['id'] ? "selected" : "" }} >{{ $student['name'] }}</option>
|
||||
@endforeach
|
||||
</x-select>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 space-x-2">
|
||||
<x-primary-button :disabled="sizeof($students) == 0">{{ __("Add student") }}</x-primary-button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<table class="mt-6 border border-gray-300 w-full text-left">
|
||||
<tr>
|
||||
<th class="border border-gray-300 p-1">{{ __("Student") }}</th>
|
||||
<th class="border border-gray-300 p-1">{{ __("Can take test") }}</th>
|
||||
<th class="border border-gray-300 p-1"></th>
|
||||
</tr>
|
||||
|
||||
@foreach ($assigned_students as $student)
|
||||
<tr>
|
||||
<td class="border border-gray-300 p-1">{{ $student->name }}</td>
|
||||
<td class="border border-gray-300 p-1">{{ __($student->allowed ? "Yes" : "No") }}</td>
|
||||
<td class="border border-gray-300 p-1">
|
||||
<x-dropdown>
|
||||
<x-slot name="trigger">
|
||||
<button>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-gray-400" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M6 10a2 2 0 11-4 0 2 2 0 014 0zM12 10a2 2 0 11-4 0 2 2 0 014 0zM16 12a2 2 0 100-4 2 2 0 000 4z" />
|
||||
</svg>
|
||||
</button>
|
||||
</x-slot>
|
||||
<x-slot name="content">
|
||||
@if (!$student->allowed)
|
||||
<x-dropdown-link :href="route('assigned_tests.edit', $student)">
|
||||
{{ __("Allow to take test") }}
|
||||
</x-dropdown-link>
|
||||
@endif
|
||||
<form method="POST" action="{{ route("assigned_tests.destroy", $student) }}">
|
||||
@csrf
|
||||
@method("delete")
|
||||
<x-dropdown-link :href="route('assigned_tests.destroy', $student)" onclick="event.preventDefault(); this.closest('form').submit();">
|
||||
{{ __("Delete") }}
|
||||
</x-dropdown-link>
|
||||
</form>
|
||||
</x-slot>
|
||||
</x-dropdown>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<hr class="mt-6 mb-6">
|
||||
<div>
|
||||
<h2 class="text-center text-lg font-medium">{{ __("Test results") }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
</x-app-layout>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\AssignedTestsController;
|
||||
use App\Http\Controllers\ProfileController;
|
||||
use App\Http\Controllers\QuestionController;
|
||||
use App\Http\Controllers\TestController;
|
||||
@ -43,6 +44,10 @@ Route::resource("questions", QuestionController::class)
|
||||
->only(["index", "store", "edit", "update", "destroy"])
|
||||
->middleware(["auth", "verified"]);
|
||||
|
||||
Route::resource("assigned_tests", AssignedTestsController::class)
|
||||
->only(["index", "store", "edit", "update", "destroy"])
|
||||
->middleware(["auth", "verified"]);
|
||||
|
||||
Route::get('/take-tests', function () {
|
||||
return view('take-tests');
|
||||
})->middleware(['auth', 'verified'])->name('take-tests');
|
||||
|
Loading…
Reference in New Issue
Block a user