feat: Add multi-language support (i18n)

Languages supported (8):
- English (en)
- 日本語 (ja)
- Deutsch (de)
- Français (fr)
- Español (es)
- 简体中文 (zh-CN)
- 繁體中文 (zh-TW)
- 한국어 (ko)

Changes:
- Add locale column to users table
- Add SetLocale middleware for automatic locale detection
- Add LocaleController for language switching
- Create language files with translations for all UI elements
- Add language selector to user profile page
- Update all Blade views to use translation strings
This commit is contained in:
2025-11-29 12:00:09 +09:00
parent ecfa21d56c
commit cdf0bf4bad
25 changed files with 1183 additions and 84 deletions

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Http\Controllers;
use App\Http\Middleware\SetLocale;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LocaleController extends Controller
{
/**
* Update the user's locale preference.
*/
public function update(Request $request)
{
$validated = $request->validate([
'locale' => ['required', 'string', 'in:' . implode(',', array_keys(SetLocale::SUPPORTED_LOCALES))],
]);
$locale = $validated['locale'];
// Save to user record
Auth::user()->update(['locale' => $locale]);
// Also save to session for immediate effect
$request->session()->put('locale', $locale);
return redirect()->route('profile.edit')->with('success', __('messages.settings.language_updated'));
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class SetLocale
{
/**
* Supported locales
*/
public const SUPPORTED_LOCALES = [
'en' => 'English',
'ja' => '日本語',
'de' => 'Deutsch',
'fr' => 'Français',
'es' => 'Español',
'zh-CN' => '简体中文',
'zh-TW' => '繁體中文',
'ko' => '한국어',
];
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
$locale = config('app.locale', 'en');
// Check authenticated user's preference
if (Auth::check() && Auth::user()->locale) {
$locale = Auth::user()->locale;
}
// Check session (for immediate effect after changing)
elseif ($request->session()->has('locale')) {
$locale = $request->session()->get('locale');
}
// Validate locale
if (!array_key_exists($locale, self::SUPPORTED_LOCALES)) {
$locale = 'en';
}
App::setLocale($locale);
return $next($request);
}
}

View File

@@ -22,6 +22,7 @@ class User extends Authenticatable
'email',
'password',
'is_admin',
'locale',
];
/**