diff --git a/app/Http/Controllers/Admin/CompanyController.php b/app/Http/Controllers/Admin/CompanyController.php index 1e89316..a8bf5b8 100644 --- a/app/Http/Controllers/Admin/CompanyController.php +++ b/app/Http/Controllers/Admin/CompanyController.php @@ -6,9 +6,11 @@ use App\Http\Controllers\Controller; use App\Models\System\Company; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; +use App\Traits\ImageHandler; class CompanyController extends Controller { + use ImageHandler; /** * Display a listing of the resource. */ @@ -38,7 +40,10 @@ class CompanyController extends Controller ->where('name', '!=', 'super-admin') ->get(); - return view('admin.companies.index', compact('companies', 'template_roles')); + // 取得發生驗證錯誤的公司資訊 (用於維持 Modal 開啟) + $error_company = session('error_company_id') ? Company::find(session('error_company_id')) : null; + + return view('admin.companies.index', compact('companies', 'template_roles', 'error_company')); } /** @@ -230,11 +235,33 @@ class CompanyController extends Controller ->with('success', __('System settings updated successfully.')); } + /** + * 顯示客製化品牌樣式設定頁面 + */ + public function editBranding(Company $company) + { + $settings = $company->settings ?? []; + $enableCustomBranding = filter_var($settings['enable_custom_branding'] ?? false, FILTER_VALIDATE_BOOLEAN); + + if (!$enableCustomBranding) { + return redirect()->route('admin.permission.companies.index') + ->with('error', __('Custom branding function is not enabled for this company.')); + } + + return view('admin.companies.branding', compact('company')); + } + /** * 更新公司品牌客製化樣式設定 (自訂 Logo 與歡迎詞) */ public function updateBranding(Request $request, Company $company) { + \Log::info('updateBranding payload:', [ + 'company_id' => $company->id, + 'request_all' => $request->all(), + 'files' => array_keys($request->allFiles()) + ]); + $settings = $company->settings ?? []; // 1. 安全檢驗:如果未授權此功能,則拒絕操作 @@ -244,41 +271,82 @@ class CompanyController extends Controller } // 2. 欄位驗證 - $request->validate([ - 'logo_file' => 'nullable|image|mimes:jpeg,png,jpg,svg|max:2048', // 限制最大 2MB + $validator = \Illuminate\Support\Facades\Validator::make($request->all(), [ + 'logo_file' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,webp|max:10240', // 限制最大 10MB + 'login_bg_file' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,webp|max:10240', // 限制最大 10MB + 'login_card_bg_file' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,webp|max:10240', // 限制最大 10MB 'login_title' => 'nullable|string|max:100', + 'login_main_title' => 'nullable|string|max:100', + 'login_sub_title' => 'nullable|string|max:100', 'clear_logo' => 'nullable|boolean', // 用於提供清除 Logo 功能 + 'clear_login_bg' => 'nullable|boolean', // 清除大背景 + 'clear_login_card_bg' => 'nullable|boolean', // 清除卡片背景 ]); - $logoPath = $settings['logo_path'] ?? null; + if ($validator->fails()) { + return redirect()->back() + ->withErrors($validator) + ->withInput() + ->with('error', __('Validation failed. Please check the styling configurations.')); + } - // 3. 處理清除 Logo 的需求 + $logoPath = $settings['logo_path'] ?? null; + $loginBgPath = $settings['login_bg_path'] ?? null; + $loginCardBgPath = $settings['login_card_bg_path'] ?? null; + + // 3. 處理清除圖片的需求 if ($request->boolean('clear_logo')) { if ($logoPath) { \Illuminate\Support\Facades\Storage::disk('public')->delete($logoPath); $logoPath = null; } } + if ($request->boolean('clear_login_bg')) { + if ($loginBgPath) { + \Illuminate\Support\Facades\Storage::disk('public')->delete($loginBgPath); + $loginBgPath = null; + } + } + if ($request->boolean('clear_login_card_bg')) { + if ($loginCardBgPath) { + \Illuminate\Support\Facades\Storage::disk('public')->delete($loginCardBgPath); + $loginCardBgPath = null; + } + } - // 4. 處理 Logo 檔案上傳 + // 4. 處理圖片檔案上傳 (轉為高品質 webp) if ($request->hasFile('logo_file')) { - // 如果原本有 Logo,先刪除舊檔案 if ($logoPath) { \Illuminate\Support\Facades\Storage::disk('public')->delete($logoPath); } - // 儲存新檔案到 public/company_logos - $logoPath = $request->file('logo_file')->store('company_logos', 'public'); + $logoPath = $this->storeAsWebp($request->file('logo_file'), 'company_logos', 80); + } + if ($request->hasFile('login_bg_file')) { + if ($loginBgPath) { + \Illuminate\Support\Facades\Storage::disk('public')->delete($loginBgPath); + } + $loginBgPath = $this->storeAsWebp($request->file('login_bg_file'), 'company_backgrounds', 85); + } + if ($request->hasFile('login_card_bg_file')) { + if ($loginCardBgPath) { + \Illuminate\Support\Facades\Storage::disk('public')->delete($loginCardBgPath); + } + $loginCardBgPath = $this->storeAsWebp($request->file('login_card_bg_file'), 'company_backgrounds', 85); } // 5. 合併寫入 settings JSON 中,防止覆寫其他功能開關 $company->settings = array_merge($settings, [ 'logo_path' => $logoPath, + 'login_bg_path' => $loginBgPath, + 'login_card_bg_path' => $loginCardBgPath, 'login_title' => $request->input('login_title'), + 'login_main_title' => $request->input('login_main_title'), + 'login_sub_title' => $request->input('login_sub_title'), ]); $company->save(); - return redirect()->to(route('admin.permission.companies.index') . '?tab=branding') + return redirect()->route('admin.permission.companies.branding.edit', $company->id) ->with('success', __('Brand styling updated successfully.')); } diff --git a/app/Http/Controllers/Auth/TenantLoginController.php b/app/Http/Controllers/Auth/TenantLoginController.php index 62c55fc..d9e6f14 100644 --- a/app/Http/Controllers/Auth/TenantLoginController.php +++ b/app/Http/Controllers/Auth/TenantLoginController.php @@ -64,8 +64,8 @@ class TenantLoginController extends Controller $user = User::where('username', $request->username)->first(); // 4. 【關鍵安全防錯】驗證此使用者是否確實屬於該公司 - if (!$user || $user->company_id !== $company->id) { - Log::warning("Tenant login security violation: User [{$request->username}] attempted login at company [{$company_code}] portal."); + if (!$user || (int)$user->company_id !== (int)$company->id) { + Log::warning("Tenant login security violation: User [{$request->username}] attempted login at company [{$company_code}] portal. User Company ID: " . var_export($user ? $user->company_id : null, true) . ", Target Company ID: {$company->id}"); return back()->withErrors([ 'username' => __('This account does not belong to this company.'), @@ -94,4 +94,51 @@ class TenantLoginController extends Controller return redirect()->intended(route('admin.dashboard')); } + + /** + * 預覽專屬客戶的客製化登入頁面 (不受 guest 中間件阻擋,供後台預覽用) + */ + public function preview($company_code) + { + // 1. 查詢啟用的公司 + $company = Company::active()->where('code', $company_code)->first(); + + // 2. 若公司不存在,重導向至主登入頁 + if (!$company) { + return redirect()->route('login'); + } + + $settings = $company->settings ?? []; + $enableCustomBranding = filter_var($settings['enable_custom_branding'] ?? false, FILTER_VALIDATE_BOOLEAN); + + if (!$enableCustomBranding) { + return redirect()->route('login'); + } + + $isPreview = true; + + // 3. 渲染共用的 login Blade,並傳入預覽標記 + return view('auth.login', compact('company', 'isPreview')); + } + + /** + * 處理打 /c/{company_code} 的跳轉邏輯 + */ + public function indexRedirect($company_code) + { + // 1. 查詢啟用的公司 + $company = Company::active()->where('code', $company_code)->first(); + + if (!$company) { + return redirect()->route('login'); + } + + // 2. 已登入則去 dashboard,未登入則去專屬登入頁 + if (auth()->check()) { + return redirect()->route('admin.dashboard'); + } + + return redirect()->route('tenant.login', $company_code); + } } + diff --git a/lang/en.json b/lang/en.json index 40e204d..208040d 100644 --- a/lang/en.json +++ b/lang/en.json @@ -1,6 +1,7 @@ { "10s": "10s", "15 Seconds": "15 Seconds", + "1920x1080 (Max 10MB)": "1920x1080 (Max 10MB)", "30 Seconds": "30 Seconds", "30s": "30s", "60 Seconds": "60 Seconds", @@ -182,6 +183,7 @@ "Are you sure you want to send this command?": "Are you sure you want to send this command?", "Are you sure you want to start delivery?": "Are you sure you want to start delivery?", "Are you sure?": "Are you sure?", + "Aspect Ratio 3:4 (Max 10MB)": "Aspect Ratio 3:4 (Max 10MB)", "Assign": "Assign", "Assign Advertisement": "Assign Advertisement", "Assign Machines": "Assign Machines", @@ -238,6 +240,7 @@ "Branch Warehouses": "Branch Warehouses", "Brand Styling": "Brand Styling", "Brand styling updated successfully.": "Brand styling updated successfully.", + "Branding Images & Backgrounds": "Branding Images & Backgrounds", "Business Type": "Business Type", "Buyout": "Buyout", "CASH": "CASH", @@ -265,6 +268,7 @@ "Card Reader Reboot": "Card Reader Reboot", "Card Reader Restart": "Card Reader Restart", "Card Reader Seconds": "Card Reader Seconds", + "Card Side Background": "Card Side Background", "Card System": "Card System", "Card Terminal": "Card Terminal", "Card Terminal System": "Card Terminal System", @@ -291,7 +295,11 @@ "Check": "Check", "Checkout Time 1": "Checkout Time 1", "Checkout Time 2": "Checkout Time 2", + "Choose": "Choose", "Choose Date": "Choose Date", + "Choose File": "Choose File", + "Choose Logo": "Choose Logo", + "Choose Overall BG": "Choose Overall BG", "Clear": "Clear", "Clear Abnormal Status": "Clear Abnormal Status", "Clear Filter": "Clear Filter", @@ -431,11 +439,14 @@ "Custom": "Custom", "Custom Alert Types": "Custom Alert Types", "Custom Background Image": "Custom Background Image", + "Custom Branding": "Custom Branding", "Custom Date": "Custom Date", "Custom Date Set": "Custom Date Set", "Custom Disabled (Mute Alert)": "Custom Disabled (Mute Alert)", "Custom Enabled": "Custom Enabled", "Custom Expiry": "Custom Expiry", + "Custom Left Main Title": "Custom Left Main Title", + "Custom Left Subtitle": "Custom Left Subtitle", "Custom Lower Limit (°C)": "Custom Lower Limit (°C)", "Custom Upper Limit (°C)": "Custom Upper Limit (°C)", "Custom Welcome Subtitle": "Custom Welcome Subtitle", @@ -452,6 +463,7 @@ "Customer updated successfully.": "Customer updated successfully.", "Customize Brand": "Customize Brand", "Customize Brand & Style": "Customize Brand & Style", + "Customize left-side main title, subtitle and right-side welcome description.": "Customize left-side main title, subtitle and right-side welcome description.", "Cycle Efficiency": "Cycle Efficiency", "Daily Revenue": "Daily Revenue", "Daily operational variance curve for selected timeframe": "Daily operational variance curve for selected timeframe", @@ -465,6 +477,8 @@ "Date Range": "Date Range", "Day Before": "Day Before", "Days": "Days", + "Default BG": "Default BG", + "Default Card BG": "Default Card BG", "Default Donate": "Default Donate", "Default Not Donate": "Default Not Donate", "Default Temp Alert Limits": "Default Temp Alert Limits", @@ -548,6 +562,9 @@ "Dispensing in progress": "Dispensing in progress", "Display Material Code": "Display Material Code", "Displayed below \"Welcome Back\" on the login portal.": "Displayed below \"Welcome Back\" on the login portal.", + "Displayed below 'Welcome Back' on the login portal.": "Displayed below 'Welcome Back' on the login portal.", + "Displayed below Logo on the left (defaults to customer name).": "Displayed below Logo on the left (defaults to customer name).", + "Displayed below main title on the left.": "Displayed below main title on the left.", "Displaying": "Displaying", "Done": "Done", "Door Closed": "Door Closed", @@ -597,6 +614,7 @@ "Edit Slot": "Edit Slot", "Edit Staff Card": "Edit Staff Card", "Edit Sub Account Role": "Edit Sub Account Role", + "Edit System Settings": "Edit System Settings", "Edit Warehouse": "Edit Warehouse", "Edit Welcome Gift": "Edit Welcome Gift", "Effective Alert Types": "Effective Alert Types", @@ -631,7 +649,9 @@ "Enable Material Code": "Enable Material Code", "Enable Points": "Enable Points", "Enable Points Mechanism": "Enable Points Mechanism", + "Enable Status": "Enable Status", "Enable and paste Webhook URL": "Enable and paste Webhook URL", + "Enable first": "Enable first", "Enabled": "Enabled", "Enabled Features": "Enabled Features", "Enabled/Disabled": "Enabled/Disabled", @@ -826,6 +846,7 @@ "Global roles accessible by all administrators.": "Global roles accessible by all administrators.", "Go Authorize": "Go Authorize", "Go Back": "Go Back", + "Go Enable": "Go Enable", "Go to E-Invoice": "Go to E-Invoice", "Goods & System Settings": "Goods & System Settings", "Got it": "Got it", @@ -1088,6 +1109,7 @@ "Material Name": "Material Name", "Material Type": "Material Type", "Max": "Max", + "Max 10MB": "Max 10MB", "Max 24 Hours": "Max 24 Hours", "Max 3": "Max 3", "Max 50MB": "Max 50MB", @@ -1356,6 +1378,7 @@ "Out of Stock": "Out of Stock", "Out of stock.": "Out of stock.", "Output Count": "Output Count", + "Overall Background Image": "Overall Background Image", "Overall Capacity": "Overall Capacity", "Owner": "Owner", "PARTNER_KEY": "PARTNER_KEY", @@ -1484,6 +1507,9 @@ "Prepared By": "Prepared By", "Preparing": "Preparing", "Preview": "Preview", + "Preview Login Page": "Preview Login Page", + "Preview Mode - Interactive Vending Portal Mockup": "Preview Mode - Interactive Vending Portal Mockup", + "Preview Mode: Login functionality is disabled.": "Preview Mode: Login functionality is disabled.", "Previous": "Previous", "Price / Member": "Price / Member", "Pricing Information": "Pricing Information", @@ -1919,6 +1945,8 @@ "Superseded by new command (Timeout)": "Superseded by new command (Timeout)", "Support rod push error": "Support rod push error", "Support rod return error": "Support rod return error", + "Supports JPEG, PNG, GIF, SVG, WebP (Max 10MB). Ideal proportion: Horizontal or Square.": "Supports JPEG, PNG, GIF, SVG, WebP (Max 10MB). Ideal proportion: Horizontal or Square.", + "Supports JPEG, PNG, GIF, SVG, WebP (Max 5MB). Ideal proportion: Horizontal or Square.": "Supports JPEG, PNG, GIF, SVG, WebP (Max 5MB). Ideal proportion: Horizontal or Square.", "Supports JPEG, PNG, SVG (Max 2MB). Ideal proportion: Horizontal or Square.": "Supports JPEG, PNG, SVG (Max 2MB). Ideal proportion: Horizontal or Square.", "Survey Analysis": "Survey Analysis", "Sync Ads": "Sync Ads", @@ -1979,6 +2007,7 @@ "Test Connection": "Test Connection", "Test notification sent successfully.": "Test notification sent successfully.", "Testing": "Testing", + "Text Titles Configuration": "Text Titles Configuration", "The Super Admin role cannot be deleted.": "The Super Admin role cannot be deleted.", "The Super Admin role is immutable.": "The Super Admin role is immutable.", "The Super Admin role name cannot be modified.": "The Super Admin role name cannot be modified.", @@ -2111,6 +2140,7 @@ "Upload New Images": "Upload New Images", "Upload Time": "Upload Time", "Upload Video": "Upload Video", + "Upload corporate logo, login portal overall background and card left side image.": "Upload corporate logo, login portal overall background and card left side image.", "Upload failed, please try again": "Upload failed, please try again", "Upload file or provide URL": "Upload file or provide URL", "Uploading new images will replace all existing images.": "Uploading new images will replace all existing images.", @@ -2137,6 +2167,7 @@ "Valid Ticket": "Valid Ticket", "Valid Until": "Valid Until", "Validation Error": "Validation Error", + "Validation failed. Please check the styling configurations.": "Validation failed. Please check the styling configurations.", "Validity Period": "Validity Period", "Validity Period (Days)": "Validity Period (Days)", "Validity Period (Hours)": "Validity Period (Hours)", @@ -2276,9 +2307,12 @@ "disabled": "disabled", "e.g. 500ml / 300g": "e.g. 500ml / 300g", "e.g. 8.5 for 85折, 8 for 8折": "e.g. 8.5 for 85折, 8 for 8折", + "e.g. AIoT Intelligent Management Platform": "e.g. AIoT Intelligent Management Platform", "e.g. John Doe": "e.g. John Doe", "e.g. Main Warehouse": "e.g. Main Warehouse", "e.g. New Guest 15% Off Discount": "e.g. New Guest 15% Off Discount", + "e.g. Please enter your account and password to enter the admin dashboard.": "e.g. Please enter your account and password to enter the admin dashboard.", + "e.g. SMART DEVICE MANAGEMENT HUB": "e.g. SMART DEVICE MANAGEMENT HUB", "e.g. TWSTAR": "e.g. TWSTAR", "e.g. Taiwan Star": "e.g. Taiwan Star", "e.g. Test Code for Maintenance": "e.g. Test Code for Maintenance", @@ -2428,6 +2462,5 @@ "video": "Video", "visit_gift": "Visit Gift", "vs Yesterday": "vs Yesterday", - "warehouses": "Warehouse Management", "warning": "warning" } diff --git a/lang/ja.json b/lang/ja.json index 5856093..7e86a92 100644 --- a/lang/ja.json +++ b/lang/ja.json @@ -1,6 +1,7 @@ { "10s": "10秒", "15 Seconds": "15秒", + "1920x1080 (Max 10MB)": "1920x1080 (最大10MB)", "30 Seconds": "30秒", "30s": "30秒", "60 Seconds": "60秒", @@ -182,6 +183,7 @@ "Are you sure you want to send this command?": "このコマンドを送信してもよろしいですか?", "Are you sure you want to start delivery?": "配送を開始してもよろしいですか?", "Are you sure?": "よろしいですか?", + "Aspect Ratio 3:4 (Max 10MB)": "比率 3:4 (最大10MB)", "Assign": "割り当て", "Assign Advertisement": "広告配信", "Assign Machines": "機器割り当て", @@ -238,6 +240,7 @@ "Branch Warehouses": "分庫数", "Brand Styling": "ブランドデザイン", "Brand styling updated successfully.": "ブランドデザインが正常に更新されました。", + "Branding Images & Backgrounds": "ブランド画像と背景設定", "Business Type": "業務タイプ", "Buyout": "買い取り", "CASH": "現金", @@ -265,6 +268,7 @@ "Card Reader Reboot": "カードリーダー再起動", "Card Reader Restart": "カードリーダー再起動", "Card Reader Seconds": "カードリーダー秒数", + "Card Side Background": "カード側背景画像", "Card System": "カードシステム", "Card Terminal": "カード端末", "Card Terminal System": "カードリーダーシステム", @@ -291,7 +295,11 @@ "Check": "確認", "Checkout Time 1": "カード決済締め時間1", "Checkout Time 2": "カード決済締め時間2", + "Choose": "選択", "Choose Date": "日付を選択", + "Choose File": "ファイルを選択", + "Choose Logo": "ロゴを選択", + "Choose Overall BG": "全体背景画像を選択", "Clear": "クリア", "Clear Abnormal Status": "異常状態のクリア", "Clear Filter": "フィルターをクリア", @@ -431,11 +439,14 @@ "Custom": "カスタム", "Custom Alert Types": "カスタムアラート種別", "Custom Background Image": "カスタム背景画像", + "Custom Branding": "ブランドカスタマイズ", "Custom Date": "カスタム日付", "Custom Date Set": "カスタム日付設定済み", "Custom Disabled (Mute Alert)": "カスタム無効(アラート消音)", "Custom Enabled": "カスタム有効", "Custom Expiry": "カスタム期限", + "Custom Left Main Title": "ログインページ左側メインタイトル", + "Custom Left Subtitle": "ログインページ左側サブタイトル", "Custom Lower Limit (°C)": "カスタム下限温度 (°C)", "Custom Upper Limit (°C)": "カスタム上限温度 (°C)", "Custom Welcome Subtitle": "カスタムウェルカムサブタイトル", @@ -452,6 +463,7 @@ "Customer updated successfully.": "顧客が正常に更新されました。", "Customize Brand": "ブランド設定", "Customize Brand & Style": "ブランド&デザインのカスタマイズ", + "Customize left-side main title, subtitle and right-side welcome description.": "ログインページの左側メインタイトル、サブタイトル、および右側ウェルカム説明をカスタマイズします。", "Cycle Efficiency": "サイクル効率", "Daily Revenue": "本日の収益", "Daily operational variance curve for selected timeframe": "選択期間における日次運営変動曲線", @@ -465,6 +477,8 @@ "Date Range": "日付範囲", "Day Before": "一昨日", "Days": "日", + "Default BG": "デフォルト背景", + "Default Card BG": "デフォルトカード背景", "Default Donate": "デフォルトで寄付する", "Default Not Donate": "デフォルトで寄付しない", "Default Temp Alert Limits": "デフォルト温度アラート範囲", @@ -548,6 +562,9 @@ "Dispensing in progress": "搬送中", "Display Material Code": "品目コードを表示", "Displayed below \"Welcome Back\" on the login portal.": "ログイン画面の「おかえりなさい」の下に表示されます。", + "Displayed below 'Welcome Back' on the login portal.": "ログイン画面の「おかえりなさい」の下に表示されます。", + "Displayed below Logo on the left (defaults to customer name).": "左側のロゴの下に表示されるメインタイトル(未設定の場合はデフォルトで顧客名になります)。", + "Displayed below main title on the left.": "左側のメインタイトルの下に表示されるサブタイトル。", "Displaying": "表示中", "Done": "完了", "Door Closed": "扉が閉まりました", @@ -597,6 +614,7 @@ "Edit Slot": "スロット編集", "Edit Staff Card": "スタッフカード編集", "Edit Sub Account Role": "サブアカウントロール編集", + "Edit System Settings": "システム設定の編集", "Edit Warehouse": "倉庫編集", "Edit Welcome Gift": "ウェルカムギフトを編集", "Effective Alert Types": "有効なアラート種別", @@ -631,7 +649,9 @@ "Enable Material Code": "資材コードを有効化", "Enable Points": "ポイントルールを有効化", "Enable Points Mechanism": "ポイント還元を有効化", + "Enable Status": "有効化ステータス", "Enable and paste Webhook URL": "Webhook URLを有効にして貼り付けます", + "Enable first": "まず有効にしてください", "Enabled": "有効済み", "Enabled Features": "有効な機能", "Enabled/Disabled": "有効/無効", @@ -826,6 +846,7 @@ "Global roles accessible by all administrators.": "全管理者がアクセス可能なグローバルロール。", "Go Authorize": "先に授権する", "Go Back": "戻る", + "Go Enable": "有効化へ進む", "Go to E-Invoice": "電子領収書へ移動", "Goods & System Settings": "商品・システム設定", "Got it": "了解しました", @@ -1088,6 +1109,7 @@ "Material Name": "素材名", "Material Type": "素材タイプ", "Max": "最大", + "Max 10MB": "最大10MB", "Max 24 Hours": "最長 24時間", "Max 3": "最大 3枚", "Max 50MB": "最大 50MB", @@ -1356,6 +1378,7 @@ "Out of Stock": "欠品", "Out of stock.": "在庫不足です。", "Output Count": "出庫回数", + "Overall Background Image": "全体背景画像", "Overall Capacity": "総在庫容量", "Owner": "所有者", "PARTNER_KEY": "PARTNER_KEY", @@ -1484,6 +1507,9 @@ "Prepared By": "起票者", "Preparing": "準備中", "Preview": "プレビュー", + "Preview Login Page": "ログインページをプレビュー", + "Preview Mode - Interactive Vending Portal Mockup": "プレビューモード - カスタムブランドログインページのモックアップ", + "Preview Mode: Login functionality is disabled.": "プレビューモード:ログイン機能は無効です。", "Previous": "前へ", "Price / Member": "価格 / 会員価格", "Pricing Information": "価格情報", @@ -1919,6 +1945,8 @@ "Superseded by new command (Timeout)": "新しいコマンドにより上書きされました (タイムアウト)", "Support rod push error": "サポートロッド押し出しエラー", "Support rod return error": "サポートロッド復帰エラー", + "Supports JPEG, PNG, GIF, SVG, WebP (Max 10MB). Ideal proportion: Horizontal or Square.": "JPEG、PNG、GIF、SVG、WebP形式に対応(最大10MB)。推奨比率:横長または正方形。", + "Supports JPEG, PNG, GIF, SVG, WebP (Max 5MB). Ideal proportion: Horizontal or Square.": "JPEG、PNG、GIF、SVG、WebP形式に対応(最大5MB)。推奨比率:横長または正方形。", "Supports JPEG, PNG, SVG (Max 2MB). Ideal proportion: Horizontal or Square.": "JPEG、PNG、SVGをサポート(最大2MB)。推奨比率:横長または正方形。", "Survey Analysis": "アンケート分析", "Sync Ads": "広告を同期", @@ -1979,6 +2007,7 @@ "Test Connection": "接続テスト", "Test notification sent successfully.": "テスト通知が正常に送信されました。", "Testing": "テスト", + "Text Titles Configuration": "ログインページタイトル設定", "The Super Admin role cannot be deleted.": "特権管理者ロールは削除できません。", "The Super Admin role is immutable.": "特権管理者ロールは変更できません。", "The Super Admin role name cannot be modified.": "特権管理者ロールの名前は変更できません。", @@ -2111,6 +2140,7 @@ "Upload New Images": "新しい写真をアップロード", "Upload Time": "アップロード時間", "Upload Video": "動画をアップロード", + "Upload corporate logo, login portal overall background and card left side image.": "コーポレートロゴ、ログインポータルの全体背景、およびカードの左側背景画像をアップロードします。", "Upload failed, please try again": "アップロードに失敗しました、再試行してください", "Upload file or provide URL": "Upload file or provide URL", "Uploading new images will replace all existing images.": "新しい写真をアップロードすると、既存のすべての写真が置き換えられます。", @@ -2137,6 +2167,7 @@ "Valid Ticket": "有効なチケット", "Valid Until": "有効期限", "Validation Error": "検証エラー", + "Validation failed. Please check the styling configurations.": "検証に失敗しました。ブランドカスタム設定を確認してください。", "Validity Period": "有効期間", "Validity Period (Days)": "有効期間 (日)", "Validity Period (Hours)": "有効期間 (時間)", @@ -2276,9 +2307,12 @@ "disabled": "無効", "e.g. 500ml / 300g": "例:500ml / 300g", "e.g. 8.5 for 85折, 8 for 8折": "例:8.5は85%、8は80%", + "e.g. AIoT Intelligent Management Platform": "例:AIoT自動化設備スマート運営プラットフォーム", "e.g. John Doe": "例:山田太郎", "e.g. Main Warehouse": "例:第一倉庫", "e.g. New Guest 15% Off Discount": "例:新規顧客向け15%割引", + "e.g. Please enter your account and password to enter the admin dashboard.": "例:管理ダッシュボードに入るためにアカウントとパスワードを入力してください。", + "e.g. SMART DEVICE MANAGEMENT HUB": "例:SMART DEVICE MANAGEMENT HUB", "e.g. TWSTAR": "例:TWSTAR", "e.g. Taiwan Star": "例:台湾星", "e.g. Test Code for Maintenance": "例:メンテナンステスト用コード", @@ -2428,6 +2462,5 @@ "video": "動画", "visit_gift": "来店ギフト", "vs Yesterday": "昨日比", - "warehouses": "倉庫管理", "warning": "警告" } diff --git a/lang/zh_TW.json b/lang/zh_TW.json index e025f01..a1b4627 100644 --- a/lang/zh_TW.json +++ b/lang/zh_TW.json @@ -1,6 +1,7 @@ { "10s": "10秒", "15 Seconds": "15 秒", + "1920x1080 (Max 10MB)": "1920x1080 (最大 10MB)", "30 Seconds": "30 秒", "30s": "30秒", "60 Seconds": "60 秒", @@ -182,6 +183,7 @@ "Are you sure you want to send this command?": "確定要發送此指令嗎?", "Are you sure you want to start delivery?": "確定要開始配送嗎?", "Are you sure?": "您確定嗎?", + "Aspect Ratio 3:4 (Max 10MB)": "比例 3:4 (最大 10MB)", "Assign": "分配所屬機台", "Assign Advertisement": "投放廣告", "Assign Machines": "分配機台", @@ -237,7 +239,8 @@ "Branch": "分倉", "Branch Warehouses": "分倉數量", "Brand Styling": "品牌樣式", - "Brand styling updated successfully.": "品牌樣式更新成功。", + "Brand styling updated successfully.": "客製化品牌樣式已更新成功。", + "Branding Images & Backgrounds": "品牌圖片與背景自訂", "Business Type": "業務類型", "Buyout": "買斷", "CASH": "CASH", @@ -265,6 +268,7 @@ "Card Reader Reboot": "刷卡機重啟", "Card Reader Restart": "卡機重啟", "Card Reader Seconds": "刷卡機秒數", + "Card Side Background": "左側卡片背景圖", "Card System": "刷卡機系統", "Card Terminal": "刷卡機端", "Card Terminal System": "刷卡機系統", @@ -291,7 +295,11 @@ "Check": "核對", "Checkout Time 1": "卡機結帳時間1", "Checkout Time 2": "卡機結帳時間2", + "Choose": "選擇", "Choose Date": "選擇日期", + "Choose File": "選擇檔案", + "Choose Logo": "選擇公司 Logo", + "Choose Overall BG": "選擇大背景圖", "Clear": "清除", "Clear Abnormal Status": "清除異常狀態", "Clear Filter": "清除篩選", @@ -431,15 +439,18 @@ "Custom": "自訂", "Custom Alert Types": "自訂告警類型", "Custom Background Image": "自訂背景圖", + "Custom Branding": "品牌自訂", "Custom Date": "自定義日期", "Custom Date Set": "已設定自定義日期", "Custom Disabled (Mute Alert)": "自訂停用(靜音告警)", "Custom Enabled": "自訂啟用", "Custom Expiry": "自訂效期", + "Custom Left Main Title": "登入頁左側主標題", + "Custom Left Subtitle": "登入頁左側副標題", "Custom Lower Limit (°C)": "自訂下限溫度 (°C)", "Custom Upper Limit (°C)": "自訂上限溫度 (°C)", "Custom Welcome Subtitle": "自訂歡迎副標題", - "Custom branding function is not enabled for this company.": "此公司尚未啟用品牌自訂功能授權。", + "Custom branding function is not enabled for this company.": "此客戶尚未啟用自訂品牌功能。", "Customer Details": "客戶詳情", "Customer Info": "客戶資訊", "Customer List": "客戶列表", @@ -450,8 +461,9 @@ "Customer deleted successfully.": "客戶已成功刪除。", "Customer enabled successfully.": "客戶已成功啟用。", "Customer updated successfully.": "客戶更新成功。", - "Customize Brand": "客製化品牌", + "Customize Brand": "自訂品牌樣式", "Customize Brand & Style": "客製化品牌樣式", + "Customize left-side main title, subtitle and right-side welcome description.": "自訂登入頁左側主副標題與右側歡迎語副標題。", "Cycle Efficiency": "週期效率", "Daily Revenue": "當日營收", "Daily operational variance curve for selected timeframe": "所選統計區間之每日營運變動曲線", @@ -465,6 +477,8 @@ "Date Range": "日期區間", "Day Before": "前日", "Days": "天", + "Default BG": "預設大背景", + "Default Card BG": "預設卡片背景", "Default Donate": "預設捐贈", "Default Not Donate": "預設不捐贈", "Default Temp Alert Limits": "預設溫度告警範圍", @@ -518,7 +532,7 @@ "Disable Pass Code": "停用通行碼", "Disable Product Confirmation": "停用商品確認", "Disable Warehouse": "停用倉庫", - "Disabled": "已停用", + "Disabled": "未啟用", "Disabled ambient temperature monitoring": "已停用環境溫度監測", "Disabling this customer will also disable all accounts under this customer. Are you sure you want to continue?": "停用此客戶將會連帶停用該客戶下的所有帳號,確定要繼續嗎?", "Discord Notifications": "Discord通知", @@ -548,6 +562,9 @@ "Dispensing in progress": "正在出貨中", "Display Material Code": "顯示物料代碼", "Displayed below \"Welcome Back\" on the login portal.": "顯示於登入入口「歡迎回來」下方。", + "Displayed below 'Welcome Back' on the login portal.": "顯示於登入入口「歡迎回來」下方。", + "Displayed below Logo on the left (defaults to customer name).": "顯示於左側 Logo 下方的主標題(未設定則預設帶入客戶名稱)。", + "Displayed below main title on the left.": "顯示於左側主標題下方的副標題/英文名稱。", "Displaying": "目前顯示", "Done": "已完成", "Door Closed": "機門已關閉", @@ -597,6 +614,7 @@ "Edit Slot": "編輯貨道", "Edit Staff Card": "編輯員工識別卡", "Edit Sub Account Role": "編輯子帳號角色", + "Edit System Settings": "編輯系統設定", "Edit Warehouse": "編輯倉庫", "Edit Welcome Gift": "編輯來店禮", "Effective Alert Types": "目前生效的告警類型", @@ -631,7 +649,9 @@ "Enable Material Code": "啟用物料編號", "Enable Points": "啟用點數規則", "Enable Points Mechanism": "啟用點數機制", + "Enable Status": "啟用狀態", "Enable and paste Webhook URL": "啟用並貼上 Webhook 網址", + "Enable first": "請先啟用", "Enabled": "已啟用", "Enabled Features": "啟用功能", "Enabled/Disabled": "啟用/停用", @@ -826,6 +846,7 @@ "Global roles accessible by all administrators.": "適用於所有管理者的全域角色。", "Go Authorize": "前往授權", "Go Back": "返回", + "Go Enable": "前往啟用", "Go to E-Invoice": "前往電子發票", "Goods & System Settings": "商品與系統設定", "Got it": "知道了", @@ -1088,6 +1109,7 @@ "Material Name": "素材名稱", "Material Type": "素材類型", "Max": "最大", + "Max 10MB": "最大 10MB", "Max 24 Hours": "最長 24 小時", "Max 3": "最多 3 張", "Max 50MB": "最大 50MB", @@ -1356,6 +1378,7 @@ "Out of Stock": "缺貨", "Out of stock.": "庫存不足。", "Output Count": "出貨次數", + "Overall Background Image": "登入頁大背景圖", "Overall Capacity": "總庫存量", "Owner": "公司名稱", "PARTNER_KEY": "PARTNER_KEY", @@ -1484,6 +1507,9 @@ "Prepared By": "經辦人", "Preparing": "備貨中", "Preview": "預覽", + "Preview Login Page": "預覽登入頁面", + "Preview Mode - Interactive Vending Portal Mockup": "預覽模式 - 客製化品牌登入頁面模擬", + "Preview Mode: Login functionality is disabled.": "預覽模式:不提供帳號登入功能。", "Previous": "上一頁", "Price / Member": "售價 / 會員價", "Pricing Information": "價格資訊", @@ -1919,7 +1945,9 @@ "Superseded by new command (Timeout)": "指令逾時 (1 分鐘未回報),已被新指令覆蓋。", "Support rod push error": "撐桿推出錯誤", "Support rod return error": "撐桿回位錯誤", - "Supports JPEG, PNG, SVG (Max 2MB). Ideal proportion: Horizontal or Square.": "支援 JPEG, PNG, SVG (最大 2MB)。建議比例:橫式或正方形。", + "Supports JPEG, PNG, GIF, SVG, WebP (Max 10MB). Ideal proportion: Horizontal or Square.": "支援 JPEG、PNG、GIF、SVG、WebP 格式(最大 10MB)。建議比例:橫向或正方形。", + "Supports JPEG, PNG, GIF, SVG, WebP (Max 5MB). Ideal proportion: Horizontal or Square.": "支援 JPEG、PNG、GIF、SVG、WebP 格式(最大 5MB)。建議比例:橫向或正方形。", + "Supports JPEG, PNG, SVG (Max 2MB). Ideal proportion: Horizontal or Square.": "支援 JPEG、PNG、SVG (最大 2MB)。建議比例:橫式或正方形。", "Survey Analysis": "問卷分析", "Sync Ads": "同步廣告", "Sync Products": "同步商品資料", @@ -1979,6 +2007,7 @@ "Test Connection": "測試連線", "Test notification sent successfully.": "測試通知發送成功。", "Testing": "測試", + "Text Titles Configuration": "登入頁標題自訂", "The Super Admin role cannot be deleted.": "超級管理員角色不可刪除。", "The Super Admin role is immutable.": "超級管理員角色不可修改。", "The Super Admin role name cannot be modified.": "超級管理員角色的名稱無法修改。", @@ -2111,6 +2140,7 @@ "Upload New Images": "上傳新照片", "Upload Time": "上傳時間", "Upload Video": "上傳影片", + "Upload corporate logo, login portal overall background and card left side image.": "上傳公司 Logo、登入頁大背景圖與左側卡片背景圖。", "Upload failed, please try again": "上傳失敗,請重試", "Upload file or provide URL": "上傳檔案或提供連結", "Uploading new images will replace all existing images.": "上傳新照片將會取代所有現有照片。", @@ -2137,6 +2167,7 @@ "Valid Ticket": "有效憑證", "Valid Until": "有效期限至", "Validation Error": "驗證錯誤", + "Validation failed. Please check the styling configurations.": "驗證失敗,請檢查品牌客製化樣式設定。", "Validity Period": "有效期限", "Validity Period (Days)": "有效期限 (天)", "Validity Period (Hours)": "有效期限 (小時)", @@ -2276,9 +2307,12 @@ "disabled": "停用", "e.g. 500ml / 300g": "例如:500ml / 300g", "e.g. 8.5 for 85折, 8 for 8折": "例如:8.5 代表 85折,8 代表 8折", + "e.g. AIoT Intelligent Management Platform": "例如:AIoT 自動化設備智慧營運平台", "e.g. John Doe": "例如:張曉明", "e.g. Main Warehouse": "如:總倉A", "e.g. New Guest 15% Off Discount": "例如:新客迎賓 85 折優惠", + "e.g. Please enter your account and password to enter the admin dashboard.": "例如:請輸入帳號密碼進入管理後台。", + "e.g. SMART DEVICE MANAGEMENT HUB": "例如:SMART DEVICE MANAGEMENT HUB", "e.g. TWSTAR": "例如:TWSTAR", "e.g. Taiwan Star": "例如:台灣之星", "e.g. Test Code for Maintenance": "例如:維修測試代碼", @@ -2428,6 +2462,5 @@ "video": "影片", "visit_gift": "來店禮", "vs Yesterday": "較昨日", - "warehouses": "倉庫管理", "warning": "警告" } diff --git a/resources/views/admin/companies/branding.blade.php b/resources/views/admin/companies/branding.blade.php new file mode 100644 index 0000000..b65fb5c --- /dev/null +++ b/resources/views/admin/companies/branding.blade.php @@ -0,0 +1,342 @@ +@extends('layouts.admin') + +@section('content') +@php + $logoUrl = !empty($company->settings['logo_path']) ? Storage::disk('public')->url($company->settings['logo_path']) : null; + $bgUrl = !empty($company->settings['login_bg_path']) ? Storage::disk('public')->url($company->settings['login_bg_path']) : null; + $cardBgUrl = !empty($company->settings['login_card_bg_path']) ? Storage::disk('public')->url($company->settings['login_card_bg_path']) : null; +@endphp + +
{{ __('Validation Error') }}
+- {{ isset($company) ? 'Smart Vending Portal' : 'Smart Device Management Hub' }} +
+ {{ (isset($company) && !empty($company->settings['login_sub_title'])) ? $company->settings['login_sub_title'] : (isset($company) ? 'Smart Vending Portal' : 'Smart Device Management Hub') }}