diff --git a/.github/workflows/build_web_image.yml b/.github/workflows/build_web_image.yml index a1b2f24..c5e78ba 100644 --- a/.github/workflows/build_web_image.yml +++ b/.github/workflows/build_web_image.yml @@ -31,4 +31,4 @@ jobs: tag_with_latest: true path: ./sera-front/ build_file: ./prod.Dockerfile - extra_args: --build-arg port=80 --build-arg VITE_BACKEND_URL=https://sera-api.destcom.website --build-arg VITE_ENV_MODE=production + extra_args: --build-arg port=80 --build-arg VITE_BACKEND_URL=https://sera-api.stroyco.eu --build-arg VITE_ENV_MODE=production diff --git a/develop.docker-compose.yml b/develop.docker-compose.yml index 14c7ca7..719e78e 100644 --- a/develop.docker-compose.yml +++ b/develop.docker-compose.yml @@ -78,8 +78,8 @@ services: target: runner args: - port=${PORT_FRONT:-80} - - VITE_BACKEND_URL=${ENV_VARIABLE:-https://develop-sera-back.destcom.website} - - VITE_ENV_MODE=${VITE_ENV_MODE:-dev} + - VITE_BACKEND_URL=${ENV_VARIABLE:-https://develop-sera-back.stroyco.eu} + - VITE_ENV_MODE=${VITE_ENV_MODE:-development} networks: - monolith - hosted diff --git a/sera-back/.env.example b/sera-back/.env.example index 84afb4c..802ff32 100644 --- a/sera-back/.env.example +++ b/sera-back/.env.example @@ -48,9 +48,9 @@ AWS_SECRET_ACCESS_KEY=${MINIO_ROOT_PASSWORD} AWS_DEFAULT_REGION=us-east-1 AWS_BUCKET=sera AWS_USE_PATH_STYLE_ENDPOINT=true -AWS_ENDPOINT_URL=http://minio:9000 -AWS_URL=http://minio:9000 -AWS_ENDPOINT=http://minio:9000 +AWS_ENDPOINT_URL=http://localhost:9000 +AWS_URL=http://localhost:9000 +AWS_ENDPOINT=http://localhost:9000 # PUSHER_APP_ID= PUSHER_APP_KEY= diff --git a/sera-back/app/Http/Controllers/NotificationController.php b/sera-back/app/Http/Controllers/NotificationController.php new file mode 100644 index 0000000..fc82817 --- /dev/null +++ b/sera-back/app/Http/Controllers/NotificationController.php @@ -0,0 +1,86 @@ +id)->get(); + + return response()->json($notifications, 201); + } + + public function store(Request $request) + { + $validated = $request->validate([ + 'title' => 'required|string', + 'description' => 'required|string', + 'is_urgent' => 'required|boolean', + ]); + + $notification = new Notification(); + $notification->title = $$validated['title']; + $notification->description = $validated['description']; + $notification->is_read = false; + $notification->is_deleted = false; + $notification->user_id = Auth::user()->id; + $notification->is_urgent = $validated['is_urgent']; + $notification->save(); + + return response()->json($notification, 201); + } + + public function show($id) + { + $notification = Notification::find($id); + return response()->json($notification); + } + + public function update(Request $request) + { + $validated = $request->validate([ + 'title' => 'string', + 'description' => 'string', + 'is_urgent' => 'boolean', + 'is_read' => 'boolean' + ]); + + $notification = Notification::find($request->id); + + if ($notification == null) { + return response()->json(['error' => 'Notification not found.'], 404); + } + + if ($request->filled('title')) { + $notification->title = $validated['title']; + } + if ($request->filled('description')) { + $notification->description = $validated['description']; + } + if ($request->filled('is_urgent')) { + $notification->is_urgent = $validated['is_urgent']; + } + + $notification->save(); + return response()->json($notification, 201); + } + + public function destroy($id) + { + $notification = Notification::find($id); + + if ($notification == null) { + return response()->json(['error' => 'Notification not found.'], 404); + } + + $notification->delete(); + + return response()->json('Notification deleted successfully', 201); + } +} diff --git a/sera-back/app/Http/Controllers/TranscriptionController.php b/sera-back/app/Http/Controllers/TranscriptionController.php index df831c7..9698276 100644 --- a/sera-back/app/Http/Controllers/TranscriptionController.php +++ b/sera-back/app/Http/Controllers/TranscriptionController.php @@ -7,6 +7,8 @@ use Illuminate\Http\Request; use App\Models\Transcription; use Illuminate\Support\Facades\Storage; +use \Done\Subtitles\Subtitles; + class TranscriptionController extends Controller { @@ -35,6 +37,16 @@ class TranscriptionController extends Controller * type="integer" * ) * ), + * @OA\Parameter( + * name="file_type", + * description="Transcription file type", + * required=false, + * in="query", + * @OA\Schema( + * type="string", + * enum={"srt", "vtt"} + * ) + * ), * @OA\Response( * response=200, * description="successful operation", @@ -84,7 +96,8 @@ class TranscriptionController extends Controller public function index(Request $request,$projectId) { $request->validate([ - 'version' => 'integer' + 'version' => 'integer', + 'file_type' => 'string|in:srt,vtt' ]); $project = Project::find($projectId); @@ -95,19 +108,23 @@ public function index(Request $request,$projectId) ], 404); } + $transcriptions = $project->transcriptions(); + if ($request->has('version')) { - $transcriptions = $project->transcriptions()->where('version', $request->version)->get(); - } else { - $transcriptions = $project->transcriptions()->get(); + $transcriptions = $transcriptions->where('version', $request->version); + } + + if ($request->has('file_type')) { + $transcriptions = $transcriptions->where('file_type', $request->file_type); } return response()->json([ - 'data' => $transcriptions + 'data' => $transcriptions->get() ], 200); } /** - * @OA\Post( + * @OA\Post( * path="/api/projects/{projectId}/transcriptions", * operationId="storeTranscription", * tags={"Transcriptions"}, @@ -128,8 +145,14 @@ public function index(Request $request,$projectId) * mediaType="multipart/form-data", * @OA\Schema( * @OA\Property( - * property="file", - * description="File", + * property="srt", + * description="Srt file", + * type="file", + * format="file" + * ), + * @OA\Property( + * property="vtt", + * description="Vtt file", * type="file", * format="file" * ) @@ -142,30 +165,32 @@ public function index(Request $request,$projectId) * @OA\JsonContent( * @OA\Property( * property="data", - * type="object", - * @OA\Property( - * property="id", - * type="integer" - * ), - * @OA\Property( - * property="ressource_id", - * type="integer" - * ), - * @OA\Property( - * property="project_id", - * type="integer" - * ), - * @OA\Property( - * property="version", - * type="integer" - * ), - * @OA\Property( - * property="created_at", - * type="string" - * ), - * @OA\Property( - * property="updated_at", - * type="string" + * type="array", + * @OA\Items( + * @OA\Property( + * property="id", + * type="integer" + * ), + * @OA\Property( + * property="ressource_id", + * type="integer" + * ), + * @OA\Property( + * property="project_id", + * type="integer" + * ), + * @OA\Property( + * property="version", + * type="integer" + * ), + * @OA\Property( + * property="created_at", + * type="string" + * ), + * @OA\Property( + * property="updated_at", + * type="string" + * ) * ) * ) * ) @@ -183,13 +208,13 @@ public function index(Request $request,$projectId) public function store(Request $request, $projectId){ $request->validate([ - 'file' => 'required|file', + 'srt' => 'file', + 'vtt' => 'file' ]); - // le file doit être de type srt - if ($request->file('file')->getClientOriginalExtension() != 'srt') { + if (!$request->has('srt') && !$request->has('vtt')) { return response()->json([ - 'message' => 'The file must be a srt file. The extension is ' . $request->file('file')->getClientOriginalExtension() + 'message' => 'You must provide a srt or vtt file' ], 400); } @@ -201,43 +226,155 @@ public function store(Request $request, $projectId){ ], 404); } - // on cherche la dernière version de la transcription. Si elle n'existe pas, on crée la version 1 $lastVersion = $project->transcriptions()->max('version'); if (!$lastVersion) { $lastVersion = 0; } + // si le fichier est un fichier srt + if($request->file('srt')){ + if ($request->file('srt')->getClientOriginalExtension() != 'srt') { + return response()->json([ + 'message' => 'The file must be a srt file. The extension is ' . $request->file('srt')->getClientOriginalExtension() + ], 400); + } - $transcriptionName = 'transcription_' . $projectId . '_version_' . ($lastVersion + 1) . '.srt'; - // on stocke le fichier dans le s3 - $path = $request->file('file')->storeAs( - 'ressources/' . $projectId . '/transcriptions', - $transcriptionName, - 's3' - ); + $transcriptionName = 'transcription_' . $projectId . '_version_' . ($lastVersion + 1) . '.srt'; + + $path = $request->file('srt')->storeAs( + 'ressources/' . $projectId . '/transcriptions/' . ($lastVersion + 1), + $transcriptionName, + 's3' + ); + + if (!$path) { + return response()->json([ + 'message' => 'Error while storing the file' + ], 500); + } + + $ressource = new Ressource(); + $ressource->name = $transcriptionName; + $ressource->type = 'transcription'; + $ressource->url = $path; + $ressource->project_id = $projectId; + $ressource->save(); + + + $transcriptionSRT = $project->transcriptions()->create([ + 'version' => $lastVersion + 1, + 'ressource_id' => $ressource->id, + 'project_id' => $projectId, + 'file_type' => 'srt' + ]); - if (!$path) { - return response()->json([ - 'message' => 'Error while storing the file' - ], 500); } - $ressource = new Ressource(); - $ressource->name = $transcriptionName; - $ressource->type = 'transcription'; - $ressource->url = $path; - $ressource->project_id = $projectId; - $ressource->save(); - - $transcription = $project->transcriptions()->create([ - 'version' => $lastVersion + 1, - 'ressource_id' => $ressource->id, - 'project_id' => $projectId - ]); + // si le fichier est un fichier vtt + if($request->file('vtt')){ + + if ($request->file('vtt')->getClientOriginalExtension() != 'vtt') { + return response()->json([ + 'message' => 'The file must be a vtt file. The extension is ' . $request->file('vtt')->getClientOriginalExtension() + ], 400); + } + + $transcriptionName = 'transcription_' . $projectId . '_version_' . ($lastVersion + 1) . '.vtt'; + + $path = $request->file('vtt')->storeAs( + 'ressources/' . $projectId . '/transcriptions/' . ($lastVersion + 1), + $transcriptionName, + 's3' + ); + + if (!$path) { + return response()->json([ + 'message' => 'Error while storing the file' + ], 500); + } + + $ressource = new Ressource(); + $ressource->name = $transcriptionName; + $ressource->type = 'transcription'; + $ressource->url = $path; + $ressource->project_id = $projectId; + $ressource->save(); + + + $transcriptionVTT = $project->transcriptions()->create([ + 'version' => $lastVersion + 1, + 'ressource_id' => $ressource->id, + 'project_id' => $projectId, + 'file_type' => 'vtt' + ]); + + } + + + // en fonction de transcriptionsSRT ou transcriptionsVTT, on va créer un fichier vtt ou srt + if (isset($transcriptionSRT) && !isset($transcriptionVTT)) { + $subtitles = Subtitles::convert($request->file('srt')->getRealPath(), 'vtt'); + + $path = $request->file('srt')->storeAs( + 'ressources/' . $projectId . '/transcriptions/' . ($lastVersion + 1), + 'transcription_' . $projectId . '_version_' . ($lastVersion + 1) . '.vtt', + 's3' + ); + + if (!$path) { + return response()->json([ + 'message' => 'Error while storing the file' + ], 500); + } + + $newRessource = new Ressource(); + $newRessource->name = 'transcription_' . $projectId . '_version_' . ($lastVersion + 1) . '.vtt'; + $newRessource->type = 'transcription'; + $newRessource->url = $path; + $newRessource->project_id = $projectId; + $newRessource->save(); + + $transcriptionVTT = $project->transcriptions()->create([ + 'version' => $lastVersion + 1, + 'ressource_id' => $newRessource->id, + 'project_id' => $projectId, + 'file_type' => 'vtt' + ]); + } + + if (isset($transcriptionVTT) && !isset($transcriptionSRT)) { + $subtitles = Subtitles::convert($request->file('vtt')->getRealPath(), 'srt'); + + $path = $request->file('vtt')->storeAs( + 'ressources/' . $projectId . '/transcriptions/' . ($lastVersion + 1), + 'transcription_' . $projectId . '_version_' . ($lastVersion + 1) . '.srt', + 's3' + ); + + $newRessource = new Ressource(); + $newRessource->name = 'transcription_' . $projectId . '_version_' . ($lastVersion + 1) . '.srt'; + $newRessource->type = 'transcription'; + $newRessource->url = $path; + $newRessource->project_id = $projectId; + $newRessource->save(); + + $transcriptionSRT = $project->transcriptions()->create([ + 'version' => $lastVersion + 1, + 'ressource_id' => $newRessource->id, + 'project_id' => $projectId, + 'file_type' => 'srt' + ]); + } + + // return srt and vtt files return response()->json([ - 'data' => $transcription + 'data' => [ + 'srt' => $transcriptionSRT ?? null, + 'vtt' => $transcriptionVTT ?? null + ] ], 201); + } /** @@ -298,23 +435,25 @@ public function destroy(Request $request, $projectId){ ], 404); } - $transcription = $project->transcriptions()->where('version', $request->version)->first(); + $transcriptions = $project->transcriptions()->where('version', $request->version)->get(); // $transcription->ressource_id is not set, return error - if (!$transcription) { + if (!$transcriptions) { return response()->json([ 'message' => 'Transcription not found.' ], 404); } - $ressource = Ressource::find($transcription->ressource_id); + foreach ($transcriptions as $transcription) { + $ressource = Ressource::find($transcription->ressource_id); - Storage::disk('s3')->delete($ressource->url); + Storage::disk('s3')->delete($ressource->url); - $ressource->delete(); + $ressource->delete(); - $transcription->delete(); + $transcription->delete(); + } return response()->json([ 'message' => 'Transcription deleted' diff --git a/sera-back/app/Models/Ressource.php b/sera-back/app/Models/Ressource.php index c30afba..ea3b6c9 100644 --- a/sera-back/app/Models/Ressource.php +++ b/sera-back/app/Models/Ressource.php @@ -2,8 +2,9 @@ namespace App\Models; -use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Facades\Storage; +use Illuminate\Database\Eloquent\Factories\HasFactory; class Ressource extends Model { @@ -23,4 +24,16 @@ public function project() { return $this->belongsTo(Project::class); } + + public function getUrlAttribute($value) + { + $disk = Storage::disk('s3'); + + $temporaryUrl = $disk->temporaryUrl( + $value, + now()->addHours(24) + ); + + return $temporaryUrl; + } } diff --git a/sera-back/app/Models/Transcription.php b/sera-back/app/Models/Transcription.php index c8d6c13..8e34727 100644 --- a/sera-back/app/Models/Transcription.php +++ b/sera-back/app/Models/Transcription.php @@ -13,6 +13,7 @@ class Transcription extends Model 'ressource_id', 'project_id', 'version', + 'file_type', ]; public function ressource() diff --git a/sera-back/composer.json b/sera-back/composer.json index 3703d39..51b6a9a 100644 --- a/sera-back/composer.json +++ b/sera-back/composer.json @@ -11,7 +11,8 @@ "laravel/framework": "^10.10", "laravel/sanctum": "^3.2", "laravel/tinker": "^2.8", - "league/flysystem-aws-s3-v3": "^3.15" + "league/flysystem-aws-s3-v3": "^3.15", + "mantas-done/subtitles": "^1.0" }, "require-dev": { "fakerphp/faker": "^1.9.1", diff --git a/sera-back/composer.lock b/sera-back/composer.lock index 7c3c219..e17bf5a 100644 --- a/sera-back/composer.lock +++ b/sera-back/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "648df8551320b7de480aab4e99dd5758", + "content-hash": "136d3765644618b5bf41dcee9f0e7aa5", "packages": [ { "name": "aws/aws-crt-php", @@ -2130,6 +2130,40 @@ ], "time": "2022-04-17T13:12:02+00:00" }, + { + "name": "mantas-done/subtitles", + "version": "v1.0.17", + "source": { + "type": "git", + "url": "https://github.com/mantas-done/subtitles.git", + "reference": "748a82c99e645ffef7f007c8f903e021a8dd5a52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mantas-done/subtitles/zipball/748a82c99e645ffef7f007c8f903e021a8dd5a52", + "reference": "748a82c99e645ffef7f007c8f903e021a8dd5a52", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Done\\Subtitles\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "description": "Subtitle converter and generator for PHP", + "support": { + "issues": "https://github.com/mantas-done/subtitles/issues", + "source": "https://github.com/mantas-done/subtitles/tree/v1.0.17" + }, + "time": "2023-08-31T06:57:03+00:00" + }, { "name": "monolog/monolog", "version": "3.3.1", @@ -8627,5 +8661,5 @@ "php": "^8.1" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/sera-back/config/roles.php b/sera-back/config/roles.php index 2d07ce2..f771ac3 100644 --- a/sera-back/config/roles.php +++ b/sera-back/config/roles.php @@ -12,6 +12,7 @@ "video-reviews" => ["getReviewsByProjectId","store","destroy","addAComment"], "ressources" => ["show", "index", "store", "update", "destroy"], "transcriptions" => ["index", "store", "destroy"], + "notifications" => ["index", "store", "show", "update", "destroy"] ], "project_manager" => [ "projects-requests" => ["show", "index", "update"], @@ -22,6 +23,7 @@ "video-reviews" => ["getReviewsByProjectId","store","destroy","addAComment"], "ressources" => ["show", "index", "store", "update", "destroy"], "transcriptions" => ["index", "store", "destroy"], + "notifications" => ["index", "store", "show", "update", "destroy"] ], "professor" => [ "users" => ["show", "index", "roles", "image", "password","reservations"], @@ -30,6 +32,7 @@ "rooms" => ["show", "index","available","showByProject"], "video-reviews" => ["getReviewsByProjectId","addAComment"], "ressources" => ["show", "index", "store", "update", "destroy"], + "notifications" => ["index", "store", "show", "update", "destroy"] ], "video_team" => [ "users" => ["show", "index", "roles", "image", "password","reservations"], @@ -38,6 +41,7 @@ "rooms" => ["show", "index","available","showByProject"], "video-reviews" => ["getReviewsByProjectId","addAComment"], "ressources" => ["show", "index", "store", "update", "destroy"], + "notifications" => ["index", "store", "show", "update", "destroy"] ], "video_editor" => [ "users" => ["show", "index", "roles", "image", "password","reservations"], @@ -46,6 +50,7 @@ "rooms" => ["show", "index","available","showByProject"], "video-reviews" => ["getReviewsByProjectId","store","destroy","addAComment"], "ressources" => ["show", "index", "store", "update", "destroy"], + "notifications" => ["index", "store", "show", "update", "destroy"] ], "transcription_team" => [ "users" => ["show", "index", "roles", "image", "password","reservations"], @@ -55,6 +60,7 @@ "video-reviews" => ["addAComment"], "ressources" => ["show", "index", "store", "update", "destroy"], "transcriptions" => ["index", "store", "destroy"], + "notifications" => ["index", "store", "show", "update", "destroy"] ], "traduction_team" => [ "users" => ["show", "index", "roles", "image", "password","reservations"], @@ -63,6 +69,7 @@ "rooms" => ["show", "index","available","showByProject"], "video-reviews" => ["addAComment"], "ressources" => ["show", "index", "store", "update", "destroy"], + "notifications" => ["index", "store", "show", "update", "destroy"] ], "editorial_team" => [ "users" => ["show", "index", "roles", "image", "password","reservations"], @@ -71,5 +78,6 @@ "rooms" => ["show", "index","available","showByProject"], "video-reviews" => ["addAComment"], "ressources" => ["show", "index", "store", "update", "destroy"], + "notifications" => ["index", "store", "show", "update", "destroy"] ], ]; diff --git a/sera-back/database/factories/NotificationFactory.php b/sera-back/database/factories/NotificationFactory.php index 6a7d39b..a1ae9f5 100644 --- a/sera-back/database/factories/NotificationFactory.php +++ b/sera-back/database/factories/NotificationFactory.php @@ -20,7 +20,6 @@ public function definition(): array "title" => $this->faker->realText(50), "description" => $this->faker->realText(200), "is_read" => $this->faker->boolean(), - "is_deleted" => $this->faker->boolean(), "is_urgent" => $this->faker->boolean(), ]; } diff --git a/sera-back/database/migrations/2023_09_04_205848_create_notifications_table.php b/sera-back/database/migrations/2023_09_04_205848_create_notifications_table.php index b5b5fa4..245d6d6 100644 --- a/sera-back/database/migrations/2023_09_04_205848_create_notifications_table.php +++ b/sera-back/database/migrations/2023_09_04_205848_create_notifications_table.php @@ -16,7 +16,6 @@ public function up(): void $table->string('title'); $table->text('description'); $table->boolean('is_read')->default(false); - $table->boolean('is_deleted')->default(false); $table->foreignId('user_id')->constrained('users')->onDelete('cascade'); $table->boolean('is_urgent')->default(false); $table->timestamps(); diff --git a/sera-back/database/migrations/2023_09_05_092423_create_transcriptions_table.php b/sera-back/database/migrations/2023_09_05_092423_create_transcriptions_table.php index 5d66e08..ef73ad4 100644 --- a/sera-back/database/migrations/2023_09_05_092423_create_transcriptions_table.php +++ b/sera-back/database/migrations/2023_09_05_092423_create_transcriptions_table.php @@ -16,6 +16,7 @@ public function up(): void $table->foreignId('ressource_id')->constrained('ressources')->cascadeOnDelete()->cascadeOnUpdate(); $table->foreignId('project_id')->constrained('projects')->cascadeOnDelete()->cascadeOnUpdate(); $table->integer('version')->nullable(false); + $table->string('file_type')->nullable(false); $table->timestamps(); }); } diff --git a/sera-back/myminio/sera/topfreddy.mp4 b/sera-back/myminio/sera/topfreddy.mp4 new file mode 100644 index 0000000..17d8021 Binary files /dev/null and b/sera-back/myminio/sera/topfreddy.mp4 differ diff --git a/sera-back/public/vtt b/sera-back/public/vtt new file mode 100644 index 0000000..f8a3d9d --- /dev/null +++ b/sera-back/public/vtt @@ -0,0 +1,22 @@ +WEBVTT + +00:00:00.000 --> 00:00:05.090 +It'll gaze at least of top think of Freddy Fazbear numero Cinco. + +00:00:11.800 --> 00:00:14.290 +Numero cuatro, + +00:00:14.300 --> 00:00:23.190 +30000. + +00:00:23.200 --> 00:00:27.390 +Hello, middle Trace meaning of Freddy Fazbear. + +00:00:35.700 --> 00:00:38.290 +Uma dose Freddy Fazbear. + +00:00:39.500 --> 00:00:41.290 +Is it Freddy? + +00:00:41.300 --> 00:00:54.890 +Fazbear Freddy Fazbear. \ No newline at end of file diff --git a/sera-back/routes/api.php b/sera-back/routes/api.php index e97eb23..ea18ef9 100644 --- a/sera-back/routes/api.php +++ b/sera-back/routes/api.php @@ -94,13 +94,9 @@ /************************/ - /***** Ressource *****/ + /***** Notification *****/ - Route::get('projects/{projectId}/ressources', 'App\Http\Controllers\SharedRessourceController@index')->name('ressources.index'); - Route::get('ressources/{ressourceId}', 'App\Http\Controllers\SharedRessourceController@show')->name('ressources.show'); - Route::post('projects/{projectId}/ressources', 'App\Http\Controllers\SharedRessourceController@store')->name('ressources.store'); - Route::post('ressources/{ressourceId}/update', 'App\Http\Controllers\SharedRessourceController@update')->name('ressources.update'); - Route::delete('ressources/{ressourceId}', 'App\Http\Controllers\SharedRessourceController@destroy')->name('ressources.destroy'); + Route::resource('notifications', 'App\Http\Controllers\NotificationController'); /************************/ diff --git a/sera-back/storage/api-docs/api-docs.json b/sera-back/storage/api-docs/api-docs.json index adb2150..6ba4eb3 100644 --- a/sera-back/storage/api-docs/api-docs.json +++ b/sera-back/storage/api-docs/api-docs.json @@ -3178,6 +3178,19 @@ "schema": { "type": "integer" } + }, + { + "name": "file_type", + "in": "query", + "description": "Transcription file type", + "required": false, + "schema": { + "type": "string", + "enum": [ + "srt", + "vtt" + ] + } } ], "responses": { @@ -3251,8 +3264,13 @@ "multipart/form-data": { "schema": { "properties": { - "file": { - "description": "File", + "srt": { + "description": "Srt file", + "type": "file", + "format": "file" + }, + "vtt": { + "description": "Vtt file", "type": "file", "format": "file" } @@ -3270,27 +3288,30 @@ "schema": { "properties": { "data": { - "properties": { - "id": { - "type": "integer" - }, - "ressource_id": { - "type": "integer" - }, - "project_id": { - "type": "integer" - }, - "version": { - "type": "integer" - }, - "created_at": { - "type": "string" + "type": "array", + "items": { + "properties": { + "id": { + "type": "integer" + }, + "ressource_id": { + "type": "integer" + }, + "project_id": { + "type": "integer" + }, + "version": { + "type": "integer" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + } }, - "updated_at": { - "type": "string" - } - }, - "type": "object" + "type": "object" + } } }, "type": "object" diff --git a/sera-front/src/components/app/navigation/HeaderTitle.tsx b/sera-front/src/components/app/navigation/HeaderTitle.tsx index a2e2c30..109e8a7 100644 --- a/sera-front/src/components/app/navigation/HeaderTitle.tsx +++ b/sera-front/src/components/app/navigation/HeaderTitle.tsx @@ -2,15 +2,19 @@ import { ChevronLeft, ChevronRight } from "lucide-react"; import { Link } from "react-router-dom"; import { Button } from "@/components/ui/button"; +import { Badge } from "@/components/ui/badge"; +import clsx from "clsx"; interface HeaderTitleProps { title?: string; + porjectStatus?: string; linkPath?: string | number; previousTitle?: string; } export const HeaderTitle = ({ title, + porjectStatus, linkPath = -1, previousTitle, }: HeaderTitleProps) => { @@ -36,6 +40,21 @@ export const HeaderTitle = ({ )}

{title}

+ + {porjectStatus} + + + {porjectStatus + ? porjectStatus.charAt(0).toUpperCase() + porjectStatus.slice(1) + : ""} + ); }; diff --git a/sera-front/src/pages/Project.tsx b/sera-front/src/pages/Project.tsx index fbcb6ce..cb392bf 100644 --- a/sera-front/src/pages/Project.tsx +++ b/sera-front/src/pages/Project.tsx @@ -48,6 +48,7 @@ export const Project = () => { <>
diff --git a/sera-front/src/pages/Tickets.tsx b/sera-front/src/pages/Tickets.tsx index b0399e0..f46ace7 100644 --- a/sera-front/src/pages/Tickets.tsx +++ b/sera-front/src/pages/Tickets.tsx @@ -1,4 +1,5 @@ import { useMutation, useQuery } from "@tanstack/react-query"; +import clsx from "clsx"; import { useEffect, useState } from "react"; import React from "react"; import { @@ -20,6 +21,7 @@ import { AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; +import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Dialog, @@ -47,8 +49,6 @@ import { import { axios } from "@/lib/axios"; import { TicketsEntity } from "@/lib/types/types"; import { formatDate } from "@/lib/utils"; -import clsx from "clsx"; -import { Badge } from "@/components/ui/badge"; export const Tickets = () => { const ticketStatus = "pending";