1
0

add assigning of tests

This commit is contained in:
Rokas Puzonas 2023-11-25 20:25:21 +02:00
parent 8a9007561f
commit 8b1877d1aa
10 changed files with 368 additions and 48 deletions

View 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()
]));
}
}

View File

@ -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,
]);
}

View 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',
];
}

View 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
View 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;
}

View File

@ -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');
}
};

View File

@ -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');
}
};

View File

@ -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');
}
};

View File

@ -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>

View File

@ -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');