From 1c48f0aa1a275c1625499f2d29c08f30c46f4d0a Mon Sep 17 00:00:00 2001 From: mohanmd Date: Sat, 13 Jun 2026 23:42:21 +0530 Subject: [PATCH] language api --- .../Controllers/Api/WorkerAuthController.php | 96 +++++++++++++++ public/swagger.json | 115 ++++++++++++++++++ routes/api.php | 1 + tests/Feature/WorkerJourneyApiTest.php | 85 +++++++++++++ 4 files changed, 297 insertions(+) diff --git a/app/Http/Controllers/Api/WorkerAuthController.php b/app/Http/Controllers/Api/WorkerAuthController.php index a11689a..6490cab 100644 --- a/app/Http/Controllers/Api/WorkerAuthController.php +++ b/app/Http/Controllers/Api/WorkerAuthController.php @@ -990,4 +990,100 @@ public function preferredLocationAreas(Request $request, $location = null) ], ], 200); } + + /** + * Get list of languages translated to requested language. + * Supports en, hindi (hi), sawahi (sw), taglo (tl), tamil (ta). + */ + public function languages(Request $request) + { + $lang = strtolower($request->input('lang') ?? $request->header('Accept-Language') ?? 'en'); + if (str_contains($lang, ',')) { + $lang = explode(',', $lang)[0]; + } + if (str_contains($lang, '-')) { + $lang = explode('-', $lang)[0]; + } + + $langMap = [ + 'hindi' => 'hi', + 'sawahi' => 'sw', + 'swahili' => 'sw', + 'taglo' => 'tl', + 'tagalog' => 'tl', + 'tamil' => 'ta', + ]; + + if (isset($langMap[$lang])) { + $lang = $langMap[$lang]; + } + + if (!in_array($lang, ['en', 'hi', 'sw', 'tl', 'ta'])) { + $lang = 'en'; + } + + $rawLanguages = [ + ['code' => 'en', 'name' => 'English', 'hi' => 'अंग्रेज़ी', 'sw' => 'Kiingereza', 'tl' => 'Ingles', 'ta' => 'ஆங்கிலம்'], + ['code' => 'ar', 'name' => 'Arabic', 'hi' => 'अरबी', 'sw' => 'Kiarabu', 'tl' => 'Arabe', 'ta' => 'அரபு'], + ['code' => 'hi', 'name' => 'Hindi', 'hi' => 'हिन्दी', 'sw' => 'Kihindi', 'tl' => 'Hindi', 'ta' => 'இந்தி'], + ['code' => 'tl', 'name' => 'Tagalog', 'hi' => 'तागालोग', 'sw' => 'Kitagalog', 'tl' => 'Tagalog', 'ta' => 'தகலாக்'], + ['code' => 'sw', 'name' => 'Swahili', 'hi' => 'स्वाहिली', 'sw' => 'Kiswahili', 'tl' => 'Swahili', 'ta' => 'சுவாஹிலி'], + ['code' => 'ta', 'name' => 'Tamil', 'hi' => 'तमिल', 'sw' => 'Kitamil', 'tl' => 'Tamil', 'ta' => 'தமிழ்'], + ['code' => 'ur', 'name' => 'Urdu', 'hi' => 'उर्दू', 'sw' => 'Kiurdu', 'tl' => 'Urdu', 'ta' => 'உருது'], + ['code' => 'bn', 'name' => 'Bengali', 'hi' => 'बंगाली', 'sw' => 'Kibengali', 'tl' => 'Bengali', 'ta' => 'பெங்காலி'], + ['code' => 'ml', 'name' => 'Malayalam', 'hi' => 'मलयालम', 'sw' => 'Kimalayalam', 'tl' => 'Malayalam', 'ta' => 'மலையாளம்'], + ['code' => 'ne', 'name' => 'Nepali', 'hi' => 'नेपाली', 'sw' => 'Kinepali', 'tl' => 'Nepali', 'ta' => 'நேபாளி'], + ['code' => 'si', 'name' => 'Sinhala', 'hi' => 'सिंहली', 'sw' => 'Kisinhala', 'tl' => 'Sinhala', 'ta' => 'சிங்களம்'], + ['code' => 'te', 'name' => 'Telugu', 'hi' => 'तेलुगु', 'sw' => 'Kitelugu', 'tl' => 'Telugu', 'ta' => 'தெலுங்கு'], + ['code' => 'pa', 'name' => 'Punjabi', 'hi' => 'पंजाबी', 'sw' => 'Kipunjabi', 'tl' => 'Punjabi', 'ta' => 'பஞ்சாபி'], + ['code' => 'ps', 'name' => 'Pashto', 'hi' => 'पश्तो', 'sw' => 'Kipashto', 'tl' => 'Pashto', 'ta' => 'பஷ்தூ'], + ['code' => 'kn', 'name' => 'Kannada', 'hi' => 'कन्नड़', 'sw' => 'Kikannada', 'tl' => 'Kannada', 'ta' => 'கன்னடம்'], + ['code' => 'mr', 'name' => 'Marathi', 'hi' => 'मराठी', 'sw' => 'Kimarathi', 'tl' => 'Marathi', 'ta' => 'மராத்தி'], + ['code' => 'gu', 'name' => 'Gujarati', 'hi' => 'गुजराती', 'sw' => 'Kigujarati', 'tl' => 'Gujarati', 'ta' => 'குஜராत्ति'], + ['code' => 'fr', 'name' => 'French', 'hi' => 'फ़्रांसीसी', 'sw' => 'Kifaransa', 'tl' => 'Pranses', 'ta' => 'பிரெஞ்சு'], + ['code' => 'es', 'name' => 'Spanish', 'hi' => 'स्पैनिश', 'sw' => 'Kihispania', 'tl' => 'Espanyol', 'ta' => 'ஸ்பானிஷ்'], + ['code' => 'zh', 'name' => 'Chinese', 'hi' => 'चीनी', 'sw' => 'Kichina', 'tl' => 'Intsik', 'ta' => 'சீனம்'], + ['code' => 'ru', 'name' => 'Russian', 'hi' => 'रूसी', 'sw' => 'Kirusi', 'tl' => 'Ruso', 'ta' => 'ரஷ்யன்'], + ['code' => 'id', 'name' => 'Indonesian', 'hi' => 'इंडोनेशियाई', 'sw' => 'Kiindonesia', 'tl' => 'Indonesian', 'ta' => 'இந்தோனேசியன்'], + ]; + + $list = []; + foreach ($rawLanguages as $item) { + $list[] = [ + 'code' => $item['code'], + 'name' => $item[$lang] ?? $item['name'], + ]; + } + + $search = strtolower($request->input('search') ?? $request->input('q') ?? ''); + if ($search !== '') { + $list = array_filter($list, function ($item) use ($search) { + return stripos($item['name'], $search) !== false || stripos($item['code'], $search) !== false; + }); + $list = array_values($list); + } + + // Apply Pagination + $page = (int) $request->input('page', 1); + $perPage = (int) $request->input('per_page', 500); + if ($perPage === 15) { + $perPage = 500; + } + $total = count($list); + $offset = ($page - 1) * $perPage; + $paginatedList = array_slice($list, $offset, $perPage); + + return response()->json([ + 'success' => true, + 'data' => [ + 'languages' => $paginatedList, + 'pagination' => [ + 'total' => $total, + 'per_page' => $perPage, + 'current_page' => $page, + 'last_page' => max(1, (int) ceil($total / $perPage)), + ] + ], + ], 200); + } } diff --git a/public/swagger.json b/public/swagger.json index b8fd2e1..cd099a8 100644 --- a/public/swagger.json +++ b/public/swagger.json @@ -859,6 +859,121 @@ } } }, + "/languages": { + "get": { + "tags": [ + "General" + ], + "summary": "Get Languages List", + "description": "Returns a list of supported languages translated to the requested language. Supports en, hindi (hi), sawahi (sw), taglo (tl), tamil (ta).", + "security": [], + "parameters": [ + { + "name": "lang", + "in": "query", + "schema": { + "type": "string", + "default": "en" + }, + "description": "Language locale code (e.g. 'en', 'hindi', 'sawahi', 'taglo', 'tamil')" + }, + { + "name": "Accept-Language", + "in": "header", + "schema": { + "type": "string" + }, + "description": "Fallback header locale (e.g. 'en', 'hi', 'sw', 'tl', 'ta')" + }, + { + "name": "search", + "in": "query", + "schema": { + "type": "string" + }, + "description": "Search keyword to filter languages by name or code" + }, + { + "name": "page", + "in": "query", + "schema": { + "type": "integer", + "default": 1 + }, + "description": "Page number for pagination" + }, + { + "name": "per_page", + "in": "query", + "schema": { + "type": "integer", + "default": 500 + }, + "description": "Number of languages to return per page." + } + ], + "responses": { + "200": { + "description": "Languages list retrieved successfully.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean", + "example": true + }, + "data": { + "type": "object", + "properties": { + "languages": { + "type": "array", + "items": { + "type": "object", + "properties": { + "code": { + "type": "string", + "example": "en" + }, + "name": { + "type": "string", + "example": "English" + } + } + } + }, + "pagination": { + "type": "object", + "properties": { + "total": { + "type": "integer", + "example": 22 + }, + "per_page": { + "type": "integer", + "example": 15 + }, + "current_page": { + "type": "integer", + "example": 1 + }, + "last_page": { + "type": "integer", + "example": 2 + } + } + } + } + } + } + } + } + } + } + } + } + }, "/preferred-locations": { "get": { "tags": [ diff --git a/routes/api.php b/routes/api.php index e587d9c..bd17922 100644 --- a/routes/api.php +++ b/routes/api.php @@ -31,6 +31,7 @@ Route::get('/preferred-locations', [WorkerAuthController::class, 'preferredLocations']); Route::get('/preferred-locations/areas', [WorkerAuthController::class, 'preferredLocationAreas']); Route::get('/preferred-locations/{location}/areas', [WorkerAuthController::class, 'preferredLocationAreas']); +Route::get('/languages', [WorkerAuthController::class, 'languages']); Route::post('/workers/send-otp', [WorkerAuthController::class, 'sendOtp']); Route::post('/workers/verify-otp', [WorkerAuthController::class, 'verifyOtp']); Route::post('/workers/setup-profile', [WorkerAuthController::class, 'setupProfile']); diff --git a/tests/Feature/WorkerJourneyApiTest.php b/tests/Feature/WorkerJourneyApiTest.php index 620fabd..792a8ff 100644 --- a/tests/Feature/WorkerJourneyApiTest.php +++ b/tests/Feature/WorkerJourneyApiTest.php @@ -588,6 +588,91 @@ public function test_nationalities_list_api() ]); } + /** + * Test languages list API with translations. + */ + public function test_languages_list_api() + { + // 1. Default (English) + $responseEn = $this->getJson('/api/languages?per_page=200'); + $responseEn->assertStatus(200) + ->assertJson([ + 'success' => true, + ]) + ->assertJsonFragment([ + 'code' => 'en', + 'name' => 'English', + ]) + ->assertJsonFragment([ + 'code' => 'hi', + 'name' => 'Hindi', + ]); + + // 2. Hindi + $responseHi = $this->getJson('/api/languages?lang=hindi&per_page=200'); + $responseHi->assertStatus(200) + ->assertJsonFragment([ + 'code' => 'hi', + 'name' => 'हिन्दी', + ]); + + // 3. Swahili via header + $responseSw = $this->withHeaders([ + 'Accept-Language' => 'sw', + ])->getJson('/api/languages?per_page=200'); + $responseSw->assertStatus(200) + ->assertJsonFragment([ + 'code' => 'sw', + 'name' => 'Kiswahili', + ]); + + // 4. Tagalog (taglo) + $responseTl = $this->getJson('/api/languages?lang=taglo&per_page=200'); + $responseTl->assertStatus(200) + ->assertJsonFragment([ + 'code' => 'tl', + 'name' => 'Tagalog', + ]); + + // 5. Tamil + $responseTa = $this->getJson('/api/languages?lang=tamil&per_page=200'); + $responseTa->assertStatus(200) + ->assertJsonFragment([ + 'code' => 'ta', + 'name' => 'தமிழ்', + ]); + + // 6. Test Pagination structure + $this->flushHeaders(); + $responsePaginated = $this->getJson('/api/languages?page=2&per_page=5'); + $responsePaginated->assertStatus(200) + ->assertJsonStructure([ + 'success', + 'data' => [ + 'languages', + 'pagination' => [ + 'total', + 'per_page', + 'current_page', + 'last_page' + ] + ] + ]); + + $this->assertCount(5, $responsePaginated->json('data.languages')); + $this->assertEquals(2, $responsePaginated->json('data.pagination.current_page')); + + // 7. Test Search functionality + $this->flushHeaders(); + $responseSearch = $this->getJson('/api/languages?search=Hindi'); + $responseSearch->assertStatus(200); + $this->assertGreaterThanOrEqual(1, count($responseSearch->json('data.languages'))); + $responseSearch->assertJsonFragment([ + 'code' => 'hi', + 'name' => 'Hindi' + ]); + } + /** * Test worker dashboard stats including employer_contacted and profile_viewed unique counts. */