Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

274 be refactor model binding student languages endpoint #286

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class StudentLanguagesDetailAnnotation
{
/**
* @OA\Get(
* path="/student/{studentId}/resume/languages",
* path="/student/{student}/resume/languages",
* operationId="getStudentResumeLanguages",
* tags={"Student -> Resume"},
* summary="Gets the languages spoken by a student",
Expand All @@ -19,7 +19,7 @@ class StudentLanguagesDetailAnnotation
It returns a list of languages along with any other relevant information, such as the proficiency level in each language.",
*
* @OA\Parameter(
* name="studentId",
* name="student",
* description="Student ID",
* required=true,
* in="path",
Expand All @@ -39,19 +39,19 @@ class StudentLanguagesDetailAnnotation
* @OA\Items(
* type="object",
* @OA\Property(
* property="language_id",
* property="id",
* type="string",
* description="Language UUID",
* example="e6b4432b-d2f8-4e06-b727-6ecaf40e6e0e"
* ),
* @OA\Property(
* property="language_name",
* property="name",
* type="string",
* description="Language name",
* example="Anglès"
* ),
* @OA\Property(
* property="language_level",
* property="level",
* type="string",
* description="The student's proficiency level in the language",
* example="Bàsic"
Expand All @@ -65,8 +65,7 @@ class StudentLanguagesDetailAnnotation
* description="Student or Resume not found",
* @OA\JsonContent(
* type="object",
* @OA\Property(property="message", type="string", example="No s'ha trobat cap estudiant amb aquest ID {studentId}"),
* @OA\Property(property="message2", type="string", example="No s'ha trobat cap currículum per a l'estudiant amb id: {studentId}")
* @OA\Property(property="message", type="string", example="No query results for model [App\Models\Student] {studentId}"),
* )
* ),
* @OA\Response(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ class UpdateStudentLanguagesAnnotation
* @OA\JsonContent(
* type="object",
* @OA\Property(
* property="language_name",
* property="name",
* type="string",
* example="Català"
* ),
* @OA\Property(
* property="language_level",
* property="level",
* type="string",
* enum={"Bàsic", "Intermedi", "Avançat", "Natiu"},
* example="Intermedi"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,18 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers\api\Student;

use Exception;
use App\Http\Controllers\Controller;
use App\Service\Student\StudentLanguageDetailService;
use App\Exceptions\StudentNotFoundException;
use App\Exceptions\ResumeNotFoundException;
use App\Http\Resources\LanguageCollection;
use App\Models\Student;
use Illuminate\Http\JsonResponse;

class StudentLanguagesDetailController extends Controller
{
private StudentLanguageDetailService $studentLanguageDetailService;

public function __construct(StudentLanguageDetailService $studentLanguageDetailService)
{
$this->studentLanguageDetailService = $studentLanguageDetailService;
}

public function __invoke(string $studentId): JsonResponse
public function __invoke(Student $student): JsonResponse
{
try {
$service = $this->studentLanguageDetailService->execute($studentId);
return response()->json(['languages' => $service]);
} catch (StudentNotFoundException | ResumeNotFoundException $e) {
return response()->json(['message' => $e->getMessage()], $e->getCode());
} catch (Exception $e) {
return response()->json(['message' => $e->getMessage()], $e->getCode() ?: 500);
}
$languages = $student->resume?->languages ?? collect();
return response()->json(new LanguageCollection($languages));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public function __invoke(string $studentId, UpdateStudentLanguagesRequest $reque

$resume = $this->updateStudentLanguagesService->findStudentResume($student);

if ($this->updateStudentLanguagesService->updateStudentLanguage($resume, $data['language_name'], $data['language_level'])) {
if ($this->updateStudentLanguagesService->updateStudentLanguage($resume, $data['name'], $data['level'])) {
return response()->json(['message' => 'Language updated successfully']);
} else {
return response()->json(['message' => 'Language not found for this student'], 404);
Expand Down
4 changes: 2 additions & 2 deletions app/Http/Requests/UpdateStudentLanguagesRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ class UpdateStudentLanguagesRequest extends FormRequest
public function rules(): array
{
return [
'language_name' => 'required|exists:languages,language_name',
'language_level' => 'required|in:Bàsic,Intermedi,Avançat,Natiu'
'name' => 'required|exists:languages,name',
'level' => 'required|in:Bàsic,Intermedi,Avançat,Natiu'
];
}
}
28 changes: 28 additions & 0 deletions app/Http/Resources/LanguageCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\ResourceCollection;

class LanguageCollection extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*
* @return array<int|string, mixed>
*/
public function toArray(Request $request): array
{
return [
'languages' => $this->collection->map(function ($language): array {
return [
'id' => $language->id,
'name' => $language->name,
'level' => $language->level
];
})
];
}
}
45 changes: 0 additions & 45 deletions app/Service/Student/StudentLanguageDetailService.php

This file was deleted.

8 changes: 4 additions & 4 deletions app/Service/Student/UpdateStudentLanguagesService.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ public function getResumeLanguages($resume)
public function findLanguageByNameAndLevel(string $languageName, string $languageLevel): Language
{
try {
$language = Language::where('language_name', $languageName)
->where('language_level', $languageLevel)
$language = Language::where('name', $languageName)
->where('level', $languageLevel)
->firstOrFail();
return $language;
} catch (ModelNotFoundException $e) {
Log::error('Language not found', ['language_name' => $languageName, 'language_level' => $languageLevel, 'error' => $e->getMessage()]);
Log::error('Language not found', ['name' => $languageName, 'level' => $languageLevel, 'error' => $e->getMessage()]);
throw new ModelNotFoundException('Language not found');
}
}
Expand All @@ -64,7 +64,7 @@ public function updateStudentLanguage($resume, $languageName, $languageLevel): b
$languagesToUpdate = $this->getResumeLanguages($resume);

foreach ($languagesToUpdate as $languageToUpdate) {
if ($languageToUpdate->language_name === $languageName) {
if ($languageToUpdate->name === $languageName) {
$resume->languages()->updateExistingPivot($languageToUpdate->id, ['language_id' => $newLanguage->id]);
return true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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::table('languages', function (Blueprint $table) {
$table->renameColumn(from: 'language_name', to: 'name');
$table->renameColumn(from: 'language_level', to: 'level');
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('languages', function (Blueprint $table) {
$table->renameColumn(from: 'name', to: 'language_name');
$table->renameColumn(from: 'level', to: 'language_level');
});
}
};
4 changes: 2 additions & 2 deletions database/seeders/LanguageSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ public function run(): void
foreach ($levels as $level) {
DB::table('languages')->insert([
'id' => (string) Str::uuid(),
'language_name' => $language,
'language_level' => $level,
'name' => $language,
'level' => $level,
]);
}
}
Expand Down
2 changes: 1 addition & 1 deletion database/seeders/ResumeLanguageSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ private function attachSecondLanguage($resume, $languageIds, $selectedLanguage):
$selectedLanguageModel = Language::find($selectedLanguage);
$additionalLanguageModel = Language::find($additionalLanguage);
} while ($additionalLanguage === $selectedLanguage ||
$additionalLanguageModel->language_name === $selectedLanguageModel->language_name);
$additionalLanguageModel->name === $selectedLanguageModel->name);
$this->attachLanguage($resume, $additionalLanguage);
}
}
Expand Down
3 changes: 2 additions & 1 deletion routes/api/v1.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@

Route::get('student/resume/list', StudentListController::class)->name('students.list');

Route::get('student/{student}/resume/languages', StudentLanguagesDetailController::class)->name('student.languages');

Route::get('student/{student}/resume/detail', StudentDetailController::class)->name('student.details');
Route::put('student/{student}/resume/profile', UpdateStudentProfileController::class)->name('student.updateProfile');
Route::get('student/{student}/resume/bootcamp', StudentBootcampDetailController::class)->name('student.bootcamp');
Expand All @@ -56,7 +58,6 @@

Route::prefix('student/{studentId}/resume')->group(function () {
Route::get('collaborations', StudentCollaborationDetailController::class)->name('student.collaborations');
Route::get('languages', StudentLanguagesDetailController::class)->name('student.languages');
Route::put('languages', UpdateStudentLanguagesController::class)->name('student.languages.update');
Route::get('modality', StudentModalityController::class)->name('student.modality');
Route::get('photo', GetStudentImageController::class)->middleware('auth:api', EnsureStudentOwner::class)->name('student.photo.get');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ describe('LanguagesCard component', () => {
const studentUUID = '123'; // You can replace this with a sample UUID
const setStudentUUID = () => { }
const languagesData = [
{ language_id: 1, language_name: 'Spanish' },
{ language_id: 2, language_name: 'English' },
{ language_id: 1, name: 'Spanish' },
{ language_id: 2, name: 'English' },
];

test('renders languages correctly', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,16 @@ describe("StudentLanguagesTest reducer", () => {
type: "getStudentLanguagesThunk/fulfilled",
payload: {
language_id: "string",
language_name: "string",
language_level: "string",
name: "string",
level: "string",
}
})).toEqual({
isLoadingLanguages: false,
isErrorLanguages: false,
languagesData: {
language_id: "string",
language_name: "string",
language_level: "string",
name: "string",
level: "string",
}
})
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const LanguagesCard: React.FC = () => {
{languagesData.map((language) => (
<ul key={language.language_id} className="flex flex-col">
<li className="text-sm font-semibold text-black-2">
{language.language_name}
{language.name}
</li>
</ul>
))}
Expand Down
4 changes: 2 additions & 2 deletions src/interfaces/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ export type TProject = {

export type TLanguage = {
language_id: string
language_name: string
language_level: string
name: string
level: string
}

export type TAbout = {
Expand Down
Loading
Loading