[REFACTOR] 實作側邊欄與儀表板多語系化,修復 UI 位移與樣式優化
All checks were successful
star-cloud-deploy-demo / deploy-demo (push) Successful in 52s

This commit is contained in:
2026-03-12 17:42:57 +08:00
parent 8ee14eaa29
commit 773396fc90
43 changed files with 1928 additions and 650 deletions

View File

@@ -16,8 +16,18 @@ class ProfileController extends Controller
*/
public function edit(Request $request): View
{
$user = $request->user();
// 如果沒有歷史紀錄,注入一些模擬資料供預覽
if ($user->loginLogs()->count() === 0) {
$user->loginLogs()->createMany([
['ip_address' => '127.0.0.1', 'user_agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)', 'login_at' => now()->subHours(2)],
['ip_address' => '192.168.1.100', 'user_agent' => 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X)', 'login_at' => now()->subDays(1)],
]);
}
return view('profile.edit', [
'user' => $request->user(),
'user' => $user->load(['loginLogs' => fn($q) => $q->latest()]),
]);
}

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Http\Controllers\System;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class LanguageController extends Controller
{
/**
* Switch application language.
*
* @param string $locale
* @return \Illuminate\Http\RedirectResponse
*/
public function switch($locale)
{
if (in_array($locale, ['en', 'zh_TW', 'ja'])) {
Session::put('locale', $locale);
}
return redirect()->back();
}
}

View File

@@ -33,6 +33,7 @@ class Kernel extends HttpKernel
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\SetLocale::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,

View File

@@ -0,0 +1,27 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class SetLocale
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if (session()->has('locale')) {
$locale = session()->get('locale');
if (in_array($locale, ['zh_TW', 'en', 'ja'])) {
app()->setLocale($locale);
}
}
return $next($request);
}
}

View File

@@ -46,4 +46,12 @@ class User extends Authenticatable
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
/**
* Get the login logs for the user.
*/
public function loginLogs()
{
return $this->hasMany(\App\Models\UserLoginLog::class);
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory; // Added this line
class UserLoginLog extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'ip_address',
'user_agent',
'login_at',
];
protected $casts = [
'login_at' => 'datetime',
];
public function user()
{
return $this->belongsTo(User::class);
}
}