init language

This commit is contained in:
bayu 2025-12-31 13:49:49 +07:00
parent 2ab0549f02
commit 7b38c511ce
15 changed files with 182 additions and 23 deletions

View File

@ -0,0 +1,30 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Session;
class LocaleController extends Controller
{
/**
* Handle language switching request.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function switch(Request $request): JsonResponse
{
$locale = $request->input('locale');
// Validate locale
if (in_array($locale, ['en', 'id'])) {
App::setLocale($locale);
Session::put('locale', $locale);
}
return response()->json(['success' => true]);
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Session;
class SetLocale
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
// Check if locale is in request
if ($request->has('locale')) {
$locale = $request->get('locale');
// Validate locale
if (in_array($locale, ['en', 'id'])) {
App::setLocale($locale);
Session::put('locale', $locale);
}
}
// Check if locale is in session
elseif (Session::has('locale')) {
$locale = Session::get('locale');
if (in_array($locale, ['en', 'id'])) {
App::setLocale($locale);
}
}
return $next($request);
}
}

View File

@ -11,7 +11,9 @@ return Application::configure(basePath: dirname(__DIR__))
health: '/up',
)
->withMiddleware(function (Middleware $middleware): void {
//
$middleware->web(append: [
\App\Http\Middleware\SetLocale::class,
]);
})
->withExceptions(function (Exceptions $exceptions): void {
//

View File

@ -3,6 +3,6 @@
return [
'id' => 'Indonesia',
'en' => 'English'
'en' => 'English',
];

6
lang/en/new_arrivals.php Normal file
View File

@ -0,0 +1,6 @@
<?php
return [
'new_arrivals' => 'New Arrivals',
'meet_the_collection' => 'Meet the :app collection'
];

View File

@ -0,0 +1,9 @@
<?php
return [
'this_weeks_highlights' => 'This week\'s highlights',
'best_sellers' => 'Best sellers',
'new_arrivals' => 'New arrivals',
'sale_items' => 'Sale items',
'top_rated' => 'Top rated'
];

View File

@ -3,6 +3,6 @@
return [
'id' => 'Indonesia',
'en' => 'English'
'en' => 'English',
];

6
lang/id/new_arrivals.php Normal file
View File

@ -0,0 +1,6 @@
<?php
return [
'new_arrivals' => 'Kedatangan Baru',
'meet_the_collection' => 'Temukan koleksi :app'
];

View File

@ -0,0 +1,9 @@
<?php
return [
'this_weeks_highlights' => 'Highlight minggu ini',
'best_sellers' => 'Terlaris',
'new_arrivals' => 'Kedatangan baru',
'sale_items' => 'Item diskon',
'top_rated' => 'Peringkat tertinggi'
];

View File

@ -1,8 +1,8 @@
<!-- Special collection carousel -->
<section class="container pb-5 mb-2 mb-sm-3 mb-lg-4 mb-xl-5">
<div class="d-md-none text-center pb-3 mb-3">
<p class="mb-2">New arrivals</p>
<h2 class="mb-0">Meet the {{ config('app.name') }} collection</h2>
<p class="mb-2">{{ __('new_arrivals.new_arrivals') }}</p>
<h2 class="mb-0">{{ __('new_arrivals.meet_the_collection', ['app' => config('app.name')]) }}</h2>
</div>
<div class="row align-items-center pb-xxl-3">
@ -34,8 +34,8 @@
<!-- Products master slider -->
<div class="col-md-5 order-md-1 text-center">
<div class="d-none d-md-block pb-3 mb-2 mb-lg-3 mx-auto" style="max-width: 306px">
<p class="mb-2">New arrivals</p>
<h2 class="mb-0">Meet the Cartzilla collection</h2>
<p class="mb-2">{{ __('new_arrivals.new_arrivals') }}</p>
<h2 class="mb-0">{{ __('new_arrivals.meet_the_collection', ['app' => config('app.name')]) }}</h2>
</div>
<div class="d-flex align-items-center justify-content-center">

View File

@ -1,21 +1,21 @@
<section class="container pb-5 mb-2 mb-sm-3 mb-lg-4 mb-xl-5">
<h2 class="text-center pb-2 pb-sm-3">This week's highlights</h2>
<h2 class="text-center pb-2 pb-sm-3">{{ __('weeks_highlights.this_weeks_highlights') }}</h2>
<!-- Nav pills -->
<div class="row g-0 overflow-x-auto pb-2 pb-sm-3 mb-3">
<div class="col-auto pb-1 pb-sm-0 mx-auto">
<ul class="nav nav-pills flex-nowrap text-nowrap">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#!">Best sellers</a>
<a class="nav-link active" aria-current="page" href="#!">{{ __('weeks_highlights.best_sellers') }}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#!">New arrivals</a>
<a class="nav-link" href="#!">{{ __('weeks_highlights.new_arrivals') }}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#!">Sale items</a>
<a class="nav-link" href="#!">{{ __('weeks_highlights.sale_items') }}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#!">Top rated</a>
<a class="nav-link" href="#!">{{ __('weeks_highlights.top_rated') }}</a>
</li>
</ul>
</div>

View File

@ -1,22 +1,48 @@
<!-- Language selector for sidebar/offcanvas -->
<div class="dropdown nav">
<a class="nav-link dropdown-toggle py-1 px-0" href="#" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="{{ __('messages.Country select') }}: USA">
<a class="nav-link dropdown-toggle py-1 px-0" href="#" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="{{ __('languages.Country select') }}: {{ app()->getLocale() === 'en' ? 'USA' : 'Indonesia' }}">
<div class="ratio ratio-1x1" style="width: 20px">
<img src="/img/flags/en-us.png" alt="USA">
<img src="/img/flags/{{ app()->getLocale() === 'en' ? 'en-us' : 'id' }}.png" alt="{{ app()->getLocale() === 'en' ? 'USA' : 'Indonesia' }}">
</div>
</a>
<ul class="dropdown-menu fs-sm" style="--cz-dropdown-spacer: .5rem">
<li>
<a class="dropdown-item" href="#!">
<a class="dropdown-item {{ app()->getLocale() === 'en' ? 'active' : '' }}" href="#" onclick="switchLanguageSidebar('en')">
<img src="/img/flags/en-us.png" class="flex-shrink-0 me-2" width="20" alt="United States">
{{ __('languages.en') }}
</a>
</li>
<li>
<a class="dropdown-item" href="#!">
<a class="dropdown-item {{ app()->getLocale() === 'id' ? 'active' : '' }}" href="#" onclick="switchLanguageSidebar('id')">
<img src="/img/flags/id.png" class="flex-shrink-0 me-2" width="20" alt="Indonesia">
{{ __('languages.id') }}
</a>
</li>
</ul>
</div>
<script>
function switchLanguageSidebar(locale) {
// Store language in session via AJAX
fetch('/locale/switch', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
},
body: JSON.stringify({
locale: locale
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
// Reload page to reflect changes
window.location.reload();
}
})
.catch(error => console.error('Error switching language:', error));
}
</script>

View File

@ -1,20 +1,20 @@
<!-- Country selector visible on screens > 768px wide (md breakpoint) -->
<div class="dropdown d-none d-md-block nav">
<a class="nav-link dropdown-toggle py-1 px-0" href="#" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="{{ __('messages.Country select') }}: USA">
<a class="nav-link dropdown-toggle py-1 px-0" href="#" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="{{ __('messages.Country select') }}: {{ app()->getLocale() === 'en' ? 'USA' : 'Indonesia' }}">
<div class="ratio ratio-1x1" style="width: 20px">
<img src="/img/flags/en-us.png" alt="USA">
<img src="/img/flags/{{ session('locale') === 'en' ? 'en-us' : 'id' }}.png" alt="{{ session('locale') === 'en' ? 'USA' : 'Indonesia' }}">
</div>
</a>
<ul class="dropdown-menu fs-sm" style="--cz-dropdown-spacer: .5rem">
<li>
<a class="dropdown-item" href="#!">
<a class="dropdown-item {{ session('locale') === 'en' ? 'active' : '' }}" href="#" onclick="switchLanguage('en')">
<img src="/img/flags/en-us.png" class="flex-shrink-0 me-2" width="20" alt="United States">
{{ __('languages.en') }}
</a>
</li>
<li>
<a class="dropdown-item" href="#!">
<a class="dropdown-item {{ session('locale') === 'id' ? 'active' : '' }}" href="#" onclick="switchLanguage('id')">
<img src="/img/flags/id.png" class="flex-shrink-0 me-2" width="20" alt="Indonesia">
{{ __('languages.id') }}
</a>
@ -22,3 +22,27 @@
</ul>
</div>
<script>
function switchLanguage(locale) {
// Store language in session via AJAX
fetch('/locale/switch', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
},
body: JSON.stringify({
locale: locale
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
// Reload page to reflect changes
window.location.reload();
}
})
.catch(error => console.error('Error switching language:', error));
}
</script>

View File

@ -17,5 +17,5 @@
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="manifest" href="/manifest.json">
<link rel="icon" type="image/png" href="/app-icons/icon-32x32.png" sizes="32x32">
<link rel="apple-touch-icon" href="/app-icons/icon-180x180.png">
<link rel="icon" type="image/png" href="{{ asset('logo/logo-app.png') }}" sizes="32x32">
<link rel="apple-touch-icon" href="{{ asset('app-icons/icon-180x180.png') }}">

View File

@ -4,6 +4,7 @@ use App\Http\Controllers\HomeController;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\RoutingController;
use App\Http\Controllers\LocationController;
use App\Http\Controllers\LocaleController;
Route::group(['prefix' => '/dummy'], function () {
Route::get('', [RoutingController::class, 'index'])->name('root');
@ -16,4 +17,7 @@ Route::group(['prefix' => '/dummy'], function () {
// Location selection route
Route::post('/location/select', [LocationController::class, 'select'])->name('location.select');
// Language switching route
Route::post('/locale/switch', [LocaleController::class, 'switch'])->name('locale.switch');
Route::get('/', [HomeController::class, 'index'])->name('home');