[FEAT] 完善全站多語系支援、角色權限篩選優化及 UI 元件重構
All checks were successful
star-cloud-deploy-demo / deploy-demo (push) Successful in 1m4s
All checks were successful
star-cloud-deploy-demo / deploy-demo (push) Successful in 1m4s
- [DOCS] 補齊 en, ja, zh_TW 語系檔翻譯並完善驗證錯誤訊息 (validation.php) - [FEAT] 角色權限頁面新增「所屬單位」篩選功能 (僅限系統管理員) - [STYLE] 優化角色列表顯示,將「類型」變更為具體「所屬單位」名稱 - [STYLE] 修正角色頁面工具列佈局,搜尋框置前並修正下拉箭頭顯示 - [REFACTOR] 統一全站刪除確認視窗,導入新版 <x-delete-confirm-modal /> 組件 - [REFACTOR] 優化 PermissionController 查詢效能 (Eager Loading) - [FIX] 修正 RoleSeeder 角色命名與資料庫同步邏輯
This commit is contained in:
@@ -24,6 +24,11 @@ trigger: always_on
|
|||||||
- 建立新資源時,必須在背景強制綁定 `company_id`,禁止由前端傳參決定。
|
- 建立新資源時,必須在背景強制綁定 `company_id`,禁止由前端傳參決定。
|
||||||
- 範例:`$model->company_id = Auth::user()->company_id;`
|
- 範例:`$model->company_id = Auth::user()->company_id;`
|
||||||
|
|
||||||
|
### 1.4 角色清單隔離 (Role List Isolation)
|
||||||
|
- 租戶管理員 (Tenant Admin) 只能管理隸屬於其公司下的角色。
|
||||||
|
- **嚴禁使用**包含 `NULL` 的 `forCompany` 廣義作用域來展示管理清單。
|
||||||
|
- 查詢時必須嚴格使用 `where('company_id', auth()->user()->company_id)` 隔離系統 Super Admin 或 角色範本。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. 權限開發規範 (spatie/laravel-permission)
|
## 2. 權限開發規範 (spatie/laravel-permission)
|
||||||
@@ -36,6 +41,12 @@ trigger: always_on
|
|||||||
- 權限名稱應遵循 `[module].[action]` 格式(例如 `machine.view`, `machine.edit`)。
|
- 權限名稱應遵循 `[module].[action]` 格式(例如 `machine.view`, `machine.edit`)。
|
||||||
- 所有租戶共用相同的權限定義。
|
- 所有租戶共用相同的權限定義。
|
||||||
|
|
||||||
|
### 2.3 權限遞迴約束 (Privilege Delegation Constraint)
|
||||||
|
為防止權限提升 (Privilege Escalation):
|
||||||
|
- **權限子集驗證**:管理員僅能指派其**自身持有**之權限給其他角色或帳號。
|
||||||
|
- **Controller 實作**:在 `store` 或 `update` 時,必須比對傳入的權限集合是否為操作者 `getPermissionNames()` 的子集。
|
||||||
|
- **UI 過濾**:權限分配介面應基於當前使用者權限清單進行動態過濾展示。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 3. 介面安全 (UI/Blade)
|
## 3. 介面安全 (UI/Blade)
|
||||||
|
|||||||
@@ -67,8 +67,9 @@ description: 定義 Star Cloud 管理後台的「極簡奢華風」設計規範
|
|||||||
|
|
||||||
## 4. 實作檢查清單 (Checklist)
|
## 4. 實作檢查清單 (Checklist)
|
||||||
|
|
||||||
- [ ] **列表佈局**: 是否採用「整合式卡片」結構且內距設為 `p-8`?
|
- [x] **列表佈局**: 是否採用「整合式卡片」結構且內距設為 `p-8`?
|
||||||
- [ ] **分頁與總數**: 列表底部是否正確召喚 `vendor.pagination.luxury`?
|
- [ ] **分頁與總數**: 列表底部是否正確召喚 `vendor.pagination.luxury`?
|
||||||
|
- [ ] **刪除動作**: 是否已全面使用 `<x-delete-confirm-modal />` 封裝執行路徑?
|
||||||
- [ ] **文字色階**: 符合標題 `slate-900/white` 與標籤 `slate-500` 的對比度。
|
- [ ] **文字色階**: 符合標題 `slate-900/white` 與標籤 `slate-500` 的對比度。
|
||||||
- [ ] **可讀性檢查**: 二級資訊是否達到 `text-xs` (12px) 且權重不超過 `font-bold`?
|
- [ ] **可讀性檢查**: 二級資訊是否達到 `text-xs` (12px) 且權重不超過 `font-bold`?
|
||||||
|
|
||||||
@@ -136,7 +137,7 @@ description: 定義 Star Cloud 管理後台的「極簡奢華風」設計規範
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody class="divide-y divide-slate-50 dark:divide-slate-800/80">
|
<tbody class="divide-y divide-slate-50 dark:divide-slate-800/80">
|
||||||
<tr class="group hover:bg-slate-50/80 dark:hover:bg-slate-800/40 transition-all duration-300">
|
<tr class="group hover:bg-slate-50/80 dark:hover:bg-slate-800/40 transition-all duration-300">
|
||||||
<td class="px-6 py-6 font-extrabold text-slate-800 dark:text-slate-100 italic">Example Name</td>
|
<td class="px-6 py-6 font-extrabold text-slate-800 dark:text-slate-100">Example Name</td>
|
||||||
<td class="px-6 py-6 text-right"> </td>
|
<td class="px-6 py-6 text-right"> </td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -152,8 +153,9 @@ description: 定義 Star Cloud 管理後台的「極簡奢華風」設計規範
|
|||||||
```
|
```
|
||||||
|
|
||||||
### 佈局核心原則:
|
### 佈局核心原則:
|
||||||
1. **移除重複內距**: 根容器 `div` 應**禁止**使用 `p-6` 或 `p-10`,因為佈局基底已提供基礎間距。僅使用 `space-y-6` (或 `space-y-8`) 控制區塊間隙。
|
1. **移除重複內距**: 根容器 `div` 應**禁止**使用 `p-6` 或 `p-10`,因為佈局基底已提供基礎間距。
|
||||||
2. **主容器樣式**: 強制對齊為 `luxury-card rounded-3xl p-8`。
|
2. **區塊間隙**: 建議使用 `space-y-6` 或 `space-y-8` 以獲得最佳空氣感。但在「高密度資料管理」或使用者有特殊緊湊需求的情境下,容許縮減至 **`space-y-2`**。
|
||||||
|
3. **主容器樣式**: 強制對齊為 `luxury-card rounded-3xl p-8`。
|
||||||
3. **標題排版**:
|
3. **標題排版**:
|
||||||
- 主標題需應用 `font-display` (Outfit)。
|
- 主標題需應用 `font-display` (Outfit)。
|
||||||
- 描述文字需應用 `uppercase tracking-widest font-bold` 以呈現高級設計感。
|
- 描述文字需應用 `uppercase tracking-widest font-bold` 以呈現高級設計感。
|
||||||
@@ -212,61 +214,24 @@ description: 定義 Star Cloud 管理後台的「極簡奢華風」設計規範
|
|||||||
|
|
||||||
### 空間與反應 (Spacing & Interaction)
|
### 空間與反應 (Spacing & Interaction)
|
||||||
- **單元格內距**: 統一使用 `px-6 py-6`。
|
- **單元格內距**: 統一使用 `px-6 py-6`。
|
||||||
- **懸停反應**: 必須在 `tr` 套用 `group` 且子元素套用 `group-hover:bg-slate-50/80` (深色: `dark:group-hover:bg-slate-800/40`) 以提供高級的互動感知。
|
- **懸停反應**: 必須在 `tr` 套用 `group` 且子<EFBFBD>### 9.4 標竿刪除確認模式 (Luxury Delete Modal Pattern)
|
||||||
- **圖示容器懸停 (Icon Hover Palette)**:
|
當執行刪除或具備破壞性的操作時,**禁止**使用瀏覽器原生 `confirm()` 或簡易的 `x-modal`。全站統一使用 **`<x-delete-confirm-modal />`** Blade 組件進行二次確認。
|
||||||
- 列表左側的主圖示容器在 `group-hover` 時,應由淡色背景轉為 **實體主題色**。
|
|
||||||
- 類別: `group-hover:bg-cyan-500 group-hover:text-white transition-all duration-300`。
|
|
||||||
- **文字同步變色**:
|
|
||||||
- 主標題文字在 `group-hover` 時應同步變色,以強化點擊引導。
|
|
||||||
- 類別: `group-hover:text-cyan-600 dark:group-hover:text-cyan-400 transition-colors`。
|
|
||||||
|
|
||||||
### 分頁與列表控制項 (Pagination & Controls)
|
1. **參數配置**:
|
||||||
為了維持操作一致性,所有列表的分頁與切換組件必須遵循以下「Luxury Jump」模式:
|
- `title`: (選填) 預設為「確認刪除」。
|
||||||
- **統一高度**: 所有控制項(按鈕、下拉選單)固定為 `h-9` (36px)。
|
- `message`: (選填) 定義具體的刪除警告訊息(例如「您確定要永久刪除此帳號嗎?」)。
|
||||||
- **筆數切換 (Limit Selector)**:
|
2. **視覺特徵**:
|
||||||
- 規範: **禁止**在表格上方(Header/Toolbar)重複放置筆數切換選單。統一收納於底部分頁欄位。
|
- **背景**: `bg-slate-900/60 backdrop-blur-sm`。
|
||||||
- **分頁導航 (Luxury Jump)**:
|
- **容器**: `rounded-3xl shadow-2xl animate-luxury-in`。
|
||||||
- 模式: 捨棄傳統頁碼按鈕,全端統一使用「跳轉選單」。
|
- **圖示**: 警告圖示使用 `bg-amber-100/10 text-amber-600`。
|
||||||
- 寬度: 下拉選單內部 Padding 為 `pl-4 pr-10`。
|
- **按鈕**: 刪除按鈕使用 `bg-rose-500` 搭配 `shadow-rose-200` 投影,取消按鈕使用 `bg-slate-100`。
|
||||||
- 字體: 使用 `text-xs font-black tracking-widest`。
|
3. **交互規範**:
|
||||||
- **指示文字**:
|
- **禁止斜體 (No Italics)**: 彈窗標題與按鈕文字嚴禁使用 `italic`,保持直挺專業感。
|
||||||
- 行動端隱藏多餘詞彙,僅保留「1 - 10 / 50」格式。
|
|
||||||
- 數字顏色對齊 `text-slate-600` (深色: `text-slate-300`)。
|
|
||||||
|
|
||||||
### 底部清單控制項 (Bottom List Controls)
|
```html
|
||||||
為了確保長列表的操作便利,清單底部應保持乾淨,統一由分頁與總數組件接管操作。
|
<!-- 使用範例 -->
|
||||||
|
<x-delete-confirm-modal :message="__('Are you sure you want to delete this account?')" />
|
||||||
### 標準操作按鈕 (Standard Action Icons)
|
```
|
||||||
表格內的操作欄位(如「編輯」、「刪除」、「詳情」)必須使用以下定義之 **「黃金標準 (Gold Standard)」**:
|
|
||||||
|
|
||||||
- **共同樣式**:
|
|
||||||
- 容器: `p-2 rounded-lg bg-slate-50 dark:bg-slate-800`
|
|
||||||
- 主色: `text-slate-400`
|
|
||||||
- 邊框: `border border-transparent` (防閃爍處理)
|
|
||||||
- 過渡: `transition-all` (使用預設速度以確保俐落感)
|
|
||||||
- 圖示粗細: `stroke-width="2.5"`
|
|
||||||
- 尺寸: `w-4 h-4`
|
|
||||||
|
|
||||||
- **編輯按鈕 (Edit)**:
|
|
||||||
- 懸停特效: `hover:text-cyan-500 hover:bg-cyan-500/10 hover:border-cyan-500/20`
|
|
||||||
- SVG 路徑:
|
|
||||||
```html
|
|
||||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"/></svg>
|
|
||||||
```
|
|
||||||
|
|
||||||
- **查看詳情 (View/Detail)**:
|
|
||||||
- 懸停特效: `hover:text-indigo-500 hover:bg-indigo-500/10 hover:border-indigo-500/20`
|
|
||||||
- SVG 路徑:
|
|
||||||
```html
|
|
||||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z"/></svg>
|
|
||||||
```
|
|
||||||
|
|
||||||
- **刪除按鈕 (Delete)**:
|
|
||||||
- 懸停特效: `hover:text-rose-500 hover:bg-rose-500/10 hover:border-rose-500/20`
|
|
||||||
- SVG 路徑:
|
|
||||||
```html
|
|
||||||
<svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/><line x1="10" x2="10" y1="11" y2="17"/><line x1="14" x2="14" y1="11" y2="17"/></svg>
|
|
||||||
```
|
|
||||||
|
|
||||||
## 10. 系統兼容性與標準化 (Compatibility & Standardization)
|
## 10. 系統兼容性與標準化 (Compatibility & Standardization)
|
||||||
|
|
||||||
@@ -296,6 +261,47 @@ description: 定義 Star Cloud 管理後台的「極簡奢華風」設計規範
|
|||||||
- **權重載入 (Font Weights)**: 確保 HTML Header 載入了 `800` 與 `900` 權重,避免瀏覽器模擬出的假粗體。
|
- **權重載入 (Font Weights)**: 確保 HTML Header 載入了 `800` 與 `900` 權重,避免瀏覽器模擬出的假粗體。
|
||||||
- **清單資訊密度**: 對於高密度清單中的時間資訊,應優先使用 `font-black` 與 `tracking-widest` 來建立明確的「標籤感」,而非僅僅是「微縮文字」。
|
- **清單資訊密度**: 對於高密度清單中的時間資訊,應優先使用 `font-black` 與 `tracking-widest` 來建立明確的「標籤感」,而非僅僅是「微縮文字」。
|
||||||
|
|
||||||
|
---
|
||||||
|
## 12. 提示與告警規範 (Alerts & Notifications)
|
||||||
|
|
||||||
|
為了確保全站操作回饋的一致性與專業感,所有系統內部的提示(成功、錯誤、警告)必須遵循以下規範。
|
||||||
|
|
||||||
|
### 1. 懸浮式自動消失提示 (Auto-hiding Toasts)
|
||||||
|
- **視覺樣式**:
|
||||||
|
- 位置: 固定於畫面上方中央 (`fixed top-8 left-1/2 -translate-x-1/2`)。
|
||||||
|
- 特效: 毛玻璃背景 (`backdrop-blur-xl`)、圓角 (`rounded-2xl`)、軟陰影。
|
||||||
|
- 動畫: 滑入 (`translate-y-0`) / 滑出 (`-translate-y-4`),配合 `opacity` 變化。
|
||||||
|
- **型態定義**:
|
||||||
|
- **Success (成功)**: 使用 `emerald` 色系。
|
||||||
|
- **Error (錯誤)**: 使用 `rose` 色系。
|
||||||
|
- **時長規範**:
|
||||||
|
- 成功提示: 3 秒後消失。
|
||||||
|
- 錯誤提示: 5 秒後消失(提供使用者更多閱讀錯誤原因的時間)。
|
||||||
|
- **組件實作**: 統一調用 `<x-toast />`。
|
||||||
|
|
||||||
|
### 2. 視窗內操作警告 (Inline Action Warnings)
|
||||||
|
- **適用場景**: 在 Modal 或編輯頁面中,提示可能導致風險的操作(如編輯自身角色)。
|
||||||
|
- **視覺樣式**:
|
||||||
|
- 背景: `bg-amber-500/10` (琥珀色)。
|
||||||
|
- 邊框: `border-amber-500/20`。
|
||||||
|
- 進場動畫: `animate-luxury-in`。
|
||||||
|
- **實作範例**:
|
||||||
|
```html
|
||||||
|
<div class="p-5 bg-amber-500/10 border border-amber-500/20 text-amber-600 rounded-2xl flex items-start gap-4 animate-luxury-in font-bold">
|
||||||
|
<!-- Icon & Text -->
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 通用豪華確認與告警視窗 (General Luxury Modals)
|
||||||
|
**統一準則**: 所有的系統確認 (Confirm) 或重要告警 (Alert/Warning) **必須** 捨棄 `x-modal` 組件,改用 Section 9.4 定義的自定義 Div 結構。
|
||||||
|
|
||||||
|
- **警告模式 (Warning/Alert)**:
|
||||||
|
- 僅提供「關閉/確定」一個按鈕。
|
||||||
|
- 樣式同 9.4,但隱藏刪除 Form 與相關色彩。
|
||||||
|
- **確認模式 (Confirm)**:
|
||||||
|
- 提供「取消」與「執行」兩個按鈕。
|
||||||
|
- 執行按鈕顏色視操作性質而定 (Delete: `rose`, Save/Action: `cyan`)。
|
||||||
|
|
||||||
---
|
---
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> **開發新功能前,必須確認 `app.css` 中的 `.btn-luxury-*` 系列組件是否滿足需求。**
|
> **開發新功能前,必須確認 `app.css` 中的 `.btn-luxury-*` 系列組件是否滿足需求。**
|
||||||
|
|||||||
@@ -17,6 +17,12 @@ class PaymentConfigController extends AdminController
|
|||||||
{
|
{
|
||||||
$per_page = $request->input('per_page', 20);
|
$per_page = $request->input('per_page', 20);
|
||||||
$configs = PaymentConfig::query()
|
$configs = PaymentConfig::query()
|
||||||
|
->when($request->search, function ($query, $search) {
|
||||||
|
$query->where('name', 'like', "%{$search}%")
|
||||||
|
->orWhereHas('company', function ($q) use ($search) {
|
||||||
|
$q->where('name', 'like', "%{$search}%");
|
||||||
|
});
|
||||||
|
})
|
||||||
->with(['company', 'creator'])
|
->with(['company', 'creator'])
|
||||||
->latest()
|
->latest()
|
||||||
->paginate($per_page)
|
->paginate($per_page)
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ class CompanyController extends Controller
|
|||||||
$per_page = $request->input('per_page', 10);
|
$per_page = $request->input('per_page', 10);
|
||||||
$companies = $query->latest()->paginate($per_page)->withQueryString();
|
$companies = $query->latest()->paginate($per_page)->withQueryString();
|
||||||
|
|
||||||
// 取得可供選擇的客戶角色範本 (is_system = 0, company_id = null)
|
// 取得可供選擇的客戶角色範本 (系統層級的角色,排除 super-admin)
|
||||||
$template_roles = \App\Models\System\Role::where('is_system', 0)
|
$template_roles = \App\Models\System\Role::whereNull('company_id')
|
||||||
->whereNull('company_id')
|
->where('name', '!=', 'super-admin')
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
return view('admin.companies.index', compact('companies', 'template_roles'));
|
return view('admin.companies.index', compact('companies', 'template_roles'));
|
||||||
@@ -86,23 +86,23 @@ class CompanyController extends Controller
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
// 角色初始化與克隆邏輯 (優先使用選擇的角色,否則使用預設)
|
// 角色初始化與克隆邏輯 (優先使用選擇的角色,否則使用預設)
|
||||||
$selected_role_name = $validated['admin_role'] ?? '通用客戶角色範本';
|
$selected_role_name = $validated['admin_role'] ?? '客戶管理員角色模板';
|
||||||
$role_to_assign = '管理員';
|
$role_to_assign = null;
|
||||||
|
|
||||||
$template_role = \App\Models\System\Role::where('name', $selected_role_name)
|
$template_role = \App\Models\System\Role::where('name', $selected_role_name)
|
||||||
->whereNull('company_id')
|
->whereNull('company_id')
|
||||||
->where('is_system', 0)
|
->where('name', '!=', 'super-admin')
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
if ($template_role) {
|
if ($template_role) {
|
||||||
// 克隆範本為該公司的「管理員」
|
// 克隆範本為該公司的「管理員」
|
||||||
$clonedRole = \App\Models\System\Role::query()->create([
|
$role_to_assign = \App\Models\System\Role::query()->create([
|
||||||
'name' => '管理員',
|
'name' => '管理員',
|
||||||
'guard_name' => 'web',
|
'guard_name' => 'web',
|
||||||
'company_id' => $company->id,
|
'company_id' => $company->id,
|
||||||
'is_system' => false,
|
'is_system' => false,
|
||||||
]);
|
]);
|
||||||
$clonedRole->syncPermissions($template_role->permissions);
|
$role_to_assign->syncPermissions($template_role->getPermissionNames());
|
||||||
} else {
|
} else {
|
||||||
// 如果找不到選定的角色範本,退而求其次嘗試指派現有角色 (通常不應發生)
|
// 如果找不到選定的角色範本,退而求其次嘗試指派現有角色 (通常不應發生)
|
||||||
$role_to_assign = $selected_role_name;
|
$role_to_assign = $selected_role_name;
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ class PermissionController extends Controller
|
|||||||
{
|
{
|
||||||
$per_page = request()->input('per_page', 10);
|
$per_page = request()->input('per_page', 10);
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
$query = \App\Models\System\Role::query()->with(['permissions', 'users']);
|
$query = \App\Models\System\Role::query()->with(['permissions', 'users', 'company']);
|
||||||
|
|
||||||
// 租戶隔離:租戶只能看到自己公司的角色 + 系統角色 (company_id is null)
|
// 租戶隔離:租戶只能看到自己公司的角色
|
||||||
if (!$user->isSystemAdmin()) {
|
if (!$user->isSystemAdmin()) {
|
||||||
$query->where('company_id', $user->company_id);
|
$query->where('company_id', $user->company_id);
|
||||||
}
|
}
|
||||||
@@ -24,10 +24,27 @@ class PermissionController extends Controller
|
|||||||
$query->where('name', 'like', "%{$search}%");
|
$query->where('name', 'like', "%{$search}%");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 篩選:所屬單位 (僅限系統管理員)
|
||||||
|
if ($user->isSystemAdmin() && request()->filled('company_id')) {
|
||||||
|
if (request()->company_id === 'system') {
|
||||||
|
$query->where('is_system', true);
|
||||||
|
} else {
|
||||||
|
$query->where('company_id', request()->company_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$roles = $query->latest()->paginate($per_page)->withQueryString();
|
$roles = $query->latest()->paginate($per_page)->withQueryString();
|
||||||
$all_permissions = \Spatie\Permission\Models\Permission::all()
|
$companies = $user->isSystemAdmin() ? \App\Models\System\Company::all() : collect();
|
||||||
|
|
||||||
|
// 權限遞迴約束:租戶管理員只能看到並指派自己擁有的權限
|
||||||
|
$permissionQuery = \Spatie\Permission\Models\Permission::query();
|
||||||
|
if (!$user->isSystemAdmin()) {
|
||||||
|
$permissionQuery->whereIn('name', $user->getAllPermissions()->pluck('name'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$all_permissions = $permissionQuery->get()
|
||||||
->filter(function($perm) {
|
->filter(function($perm) {
|
||||||
// 排除子項目的權限,只顯示主選單權限
|
// 排除子項項目,只顯示主要權限
|
||||||
$excluded = [
|
$excluded = [
|
||||||
'menu.basic.machines',
|
'menu.basic.machines',
|
||||||
'menu.basic.payment-configs',
|
'menu.basic.payment-configs',
|
||||||
@@ -47,7 +64,8 @@ class PermissionController extends Controller
|
|||||||
// 根據路由決定標題
|
// 根據路由決定標題
|
||||||
$title = request()->routeIs('*.sub-account-roles') ? __('Sub Account Roles') : __('Role Settings');
|
$title = request()->routeIs('*.sub-account-roles') ? __('Sub Account Roles') : __('Role Settings');
|
||||||
|
|
||||||
return view('admin.permission.roles', compact('roles', 'all_permissions', 'title'));
|
$currentUserRoleIds = $user->roles->pluck('id')->toArray();
|
||||||
|
return view('admin.permission.roles', compact('roles', 'all_permissions', 'title', 'currentUserRoleIds', 'companies'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -78,6 +96,15 @@ class PermissionController extends Controller
|
|||||||
|
|
||||||
if (!empty($validated['permissions'])) {
|
if (!empty($validated['permissions'])) {
|
||||||
$perms = $validated['permissions'];
|
$perms = $validated['permissions'];
|
||||||
|
|
||||||
|
// 權限遞迴約束驗證:確保指派的權限是操作者權限的子集
|
||||||
|
if (!auth()->user()->isSystemAdmin()) {
|
||||||
|
$currentUserPerms = auth()->user()->getAllPermissions()->pluck('name');
|
||||||
|
if (collect($perms)->diff($currentUserPerms)->isNotEmpty()) {
|
||||||
|
return redirect()->back()->with('error', __('You cannot assign permissions you do not possess.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 如果不是系統角色,排除主選單的系統權限
|
// 如果不是系統角色,排除主選單的系統權限
|
||||||
if (!$is_system) {
|
if (!$is_system) {
|
||||||
$perms = array_diff($perms, ['menu.basic-settings', 'menu.permissions']);
|
$perms = array_diff($perms, ['menu.basic-settings', 'menu.permissions']);
|
||||||
@@ -128,6 +155,15 @@ class PermissionController extends Controller
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$perms = $validated['permissions'] ?? [];
|
$perms = $validated['permissions'] ?? [];
|
||||||
|
|
||||||
|
// 權限遞迴約束驗證
|
||||||
|
if (!auth()->user()->isSystemAdmin()) {
|
||||||
|
$currentUserPerms = auth()->user()->getAllPermissions()->pluck('name');
|
||||||
|
if (collect($perms)->diff($currentUserPerms)->isNotEmpty()) {
|
||||||
|
return redirect()->back()->with('error', __('You cannot assign permissions you do not possess.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 如果不是系統角色,排除主選單的系統權限
|
// 如果不是系統角色,排除主選單的系統權限
|
||||||
if (!$is_system) {
|
if (!$is_system) {
|
||||||
$perms = array_diff($perms, ['menu.basic-settings', 'menu.permissions']);
|
$perms = array_diff($perms, ['menu.basic-settings', 'menu.permissions']);
|
||||||
@@ -188,9 +224,9 @@ class PermissionController extends Controller
|
|||||||
$per_page = $request->input('per_page', 10);
|
$per_page = $request->input('per_page', 10);
|
||||||
$users = $query->latest()->paginate($per_page)->withQueryString();
|
$users = $query->latest()->paginate($per_page)->withQueryString();
|
||||||
$companies = auth()->user()->isSystemAdmin() ? \App\Models\System\Company::all() : collect();
|
$companies = auth()->user()->isSystemAdmin() ? \App\Models\System\Company::all() : collect();
|
||||||
$roles_query = \App\Models\System\Role::where('name', '!=', 'super-admin');
|
$roles_query = \App\Models\System\Role::query();
|
||||||
if (!auth()->user()->isSystemAdmin()) {
|
if (!auth()->user()->isSystemAdmin()) {
|
||||||
$roles_query->where('company_id', auth()->user()->company_id);
|
$roles_query->forCompany(auth()->user()->company_id);
|
||||||
}
|
}
|
||||||
$roles = $roles_query->get();
|
$roles = $roles_query->get();
|
||||||
|
|
||||||
@@ -231,9 +267,9 @@ class PermissionController extends Controller
|
|||||||
|
|
||||||
// 驗證角色與公司的匹配性 (RBAC Safeguard)
|
// 驗證角色與公司的匹配性 (RBAC Safeguard)
|
||||||
if ($company_id !== null) {
|
if ($company_id !== null) {
|
||||||
// 如果是租戶帳號,不能選各項系統角色 (is_system = 1)
|
// 如果是租戶帳號,不能選超級管理員角色
|
||||||
if ($role->is_system) {
|
if ($role->is_system && $role->name === 'super-admin') {
|
||||||
return redirect()->back()->with('error', __('System roles cannot be assigned to tenant accounts.'));
|
return redirect()->back()->with('error', __('Super-admin role cannot be assigned to tenant accounts.'));
|
||||||
}
|
}
|
||||||
// 如果角色有特定的 company_id,必須匹配
|
// 如果角色有特定的 company_id,必須匹配
|
||||||
if ($role->company_id !== null && $role->company_id != $company_id) {
|
if ($role->company_id !== null && $role->company_id != $company_id) {
|
||||||
@@ -247,10 +283,9 @@ class PermissionController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 角色初始化與克隆邏輯 (只有 super-admin 在幫空白公司開帳號時觸發)
|
// 角色初始化與克隆邏輯 (只有 super-admin 在幫空白公司開帳號時觸發)
|
||||||
$role_to_assign = $validated['role'];
|
|
||||||
$company_id = auth()->user()->isSystemAdmin() ? ($validated['company_id'] ?? null) : auth()->user()->company_id;
|
$company_id = auth()->user()->isSystemAdmin() ? ($validated['company_id'] ?? null) : auth()->user()->company_id;
|
||||||
|
|
||||||
if ($company_id && $role && !$role->is_system && $role->company_id === null) {
|
if ($company_id && $role && $role->company_id === null && $role->name !== 'super-admin') {
|
||||||
// 檢查該公司是否已有名為「管理員」的角色
|
// 檢查該公司是否已有名為「管理員」的角色
|
||||||
$existingRole = \App\Models\System\Role::where('company_id', $company_id)
|
$existingRole = \App\Models\System\Role::where('company_id', $company_id)
|
||||||
->where('name', '管理員')
|
->where('name', '管理員')
|
||||||
@@ -258,17 +293,17 @@ class PermissionController extends Controller
|
|||||||
|
|
||||||
if (!$existingRole) {
|
if (!$existingRole) {
|
||||||
// 克隆範本為該公司的「管理員」
|
// 克隆範本為該公司的「管理員」
|
||||||
$clonedRole = \App\Models\System\Role::query()->create([
|
$newRole = \App\Models\System\Role::query()->create([
|
||||||
'name' => '管理員',
|
'name' => '管理員',
|
||||||
'guard_name' => 'web',
|
'guard_name' => 'web',
|
||||||
'company_id' => $company_id,
|
'company_id' => $company_id,
|
||||||
'is_system' => false,
|
'is_system' => false,
|
||||||
]);
|
]);
|
||||||
$clonedRole->syncPermissions($role->permissions);
|
$newRole->syncPermissions($role->getPermissionNames());
|
||||||
$role_to_assign = '管理員';
|
$role = $newRole;
|
||||||
} else {
|
} else {
|
||||||
// 如果已存在名為「管理員」的角色,則直接使用它
|
// 如果已存在名為「管理員」的角色,則直接使用它
|
||||||
$role_to_assign = '管理員';
|
$role = $existingRole;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,10 +314,10 @@ class PermissionController extends Controller
|
|||||||
'password' => \Illuminate\Support\Facades\Hash::make($validated['password']),
|
'password' => \Illuminate\Support\Facades\Hash::make($validated['password']),
|
||||||
'status' => $validated['status'],
|
'status' => $validated['status'],
|
||||||
'company_id' => $company_id,
|
'company_id' => $company_id,
|
||||||
'phone' => $validated['phone'],
|
'phone' => $validated['phone'] ?? null,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$user->assignRole($role_to_assign);
|
$user->assignRole($role);
|
||||||
|
|
||||||
return redirect()->back()->with('success', __('Account created successfully.'));
|
return redirect()->back()->with('success', __('Account created successfully.'));
|
||||||
}
|
}
|
||||||
@@ -325,8 +360,8 @@ class PermissionController extends Controller
|
|||||||
// 驗證角色與公司的匹配性 (RBAC Safeguard)
|
// 驗證角色與公司的匹配性 (RBAC Safeguard)
|
||||||
if ($user->id !== auth()->id()) { // 排除編輯自己 (super-admin 有特殊邏輯)
|
if ($user->id !== auth()->id()) { // 排除編輯自己 (super-admin 有特殊邏輯)
|
||||||
if ($target_company_id !== null) {
|
if ($target_company_id !== null) {
|
||||||
if ($roleObj->is_system) {
|
if ($roleObj->is_system && $roleObj->name === 'super-admin') {
|
||||||
return redirect()->back()->with('error', __('System roles cannot be assigned to tenant accounts.'));
|
return redirect()->back()->with('error', __('Super-admin role cannot be assigned to tenant accounts.'));
|
||||||
}
|
}
|
||||||
if ($roleObj->company_id !== null && $roleObj->company_id != $target_company_id) {
|
if ($roleObj->company_id !== null && $roleObj->company_id != $target_company_id) {
|
||||||
return redirect()->back()->with('error', __('This role belongs to another company and cannot be assigned.'));
|
return redirect()->back()->with('error', __('This role belongs to another company and cannot be assigned.'));
|
||||||
@@ -343,7 +378,7 @@ class PermissionController extends Controller
|
|||||||
'username' => $validated['username'],
|
'username' => $validated['username'],
|
||||||
'email' => $validated['email'],
|
'email' => $validated['email'],
|
||||||
'status' => $validated['status'],
|
'status' => $validated['status'],
|
||||||
'phone' => $validated['phone'],
|
'phone' => $validated['phone'] ?? null,
|
||||||
];
|
];
|
||||||
|
|
||||||
if (auth()->user()->isSystemAdmin()) {
|
if (auth()->user()->isSystemAdmin()) {
|
||||||
@@ -361,26 +396,25 @@ class PermissionController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 角色初始化與克隆邏輯
|
// 角色初始化與克隆邏輯
|
||||||
$role_to_assign = $validated['role'];
|
|
||||||
$target_company_id = auth()->user()->isSystemAdmin() ? ($validated['company_id'] ?? null) : auth()->user()->company_id;
|
$target_company_id = auth()->user()->isSystemAdmin() ? ($validated['company_id'] ?? null) : auth()->user()->company_id;
|
||||||
|
|
||||||
if ($target_company_id && $roleObj && !$roleObj->is_system && $roleObj->company_id === null) {
|
if ($target_company_id && $roleObj && $roleObj->company_id === null && $roleObj->name !== 'super-admin') {
|
||||||
// 檢查該公司是否已有名為「管理員」的角色
|
// 檢查該公司是否已有名為「管理員」的角色
|
||||||
$existingRole = \App\Models\System\Role::where('company_id', $target_company_id)
|
$existingRole = \App\Models\System\Role::where('company_id', $target_company_id)
|
||||||
->where('name', '管理員')
|
->where('name', '管理員')
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
if (!$existingRole) {
|
if (!$existingRole) {
|
||||||
$clonedRole = \App\Models\System\Role::query()->create([
|
$newRole = \App\Models\System\Role::query()->create([
|
||||||
'name' => '管理員',
|
'name' => '管理員',
|
||||||
'guard_name' => 'web',
|
'guard_name' => 'web',
|
||||||
'company_id' => $target_company_id,
|
'company_id' => $target_company_id,
|
||||||
'is_system' => false,
|
'is_system' => false,
|
||||||
]);
|
]);
|
||||||
$clonedRole->syncPermissions($roleObj->permissions);
|
$newRole->syncPermissions($roleObj->getPermissionNames());
|
||||||
$role_to_assign = '管理員';
|
$roleObj = $newRole;
|
||||||
} else {
|
} else {
|
||||||
$role_to_assign = '管理員';
|
$roleObj = $existingRole;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,7 +424,7 @@ class PermissionController extends Controller
|
|||||||
if ($user->id === auth()->id() && auth()->user()->isSystemAdmin()) {
|
if ($user->id === auth()->id() && auth()->user()->isSystemAdmin()) {
|
||||||
$user->syncRoles(['super-admin']);
|
$user->syncRoles(['super-admin']);
|
||||||
} else {
|
} else {
|
||||||
$user->syncRoles([$role_to_assign]);
|
$user->syncRoles([$roleObj]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->back()->with('success', __('Account updated successfully.'));
|
return redirect()->back()->with('success', __('Account updated successfully.'));
|
||||||
|
|||||||
@@ -24,6 +24,6 @@ class PasswordController extends Controller
|
|||||||
'password' => Hash::make($validated['password']),
|
'password' => Hash::make($validated['password']),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return back()->with('status', 'password-updated');
|
return back()->with('success', __('Password updated successfully.'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class ProfileController extends Controller
|
|||||||
|
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
||||||
return Redirect::route('profile.edit')->with('status', 'profile-updated');
|
return Redirect::route('profile.edit')->with('success', __('Profile updated successfully.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ class Role extends SpatieRole
|
|||||||
'is_system',
|
'is_system',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'is_system' => 'boolean',
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the company that owns the role.
|
* Get the company that owns the role.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
use Spatie\Permission\Models\Role;
|
use App\Models\System\Role;
|
||||||
use Spatie\Permission\Models\Permission;
|
use Spatie\Permission\Models\Permission;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
@@ -41,14 +41,14 @@ class RoleSeeder extends Seeder
|
|||||||
|
|
||||||
// 建立角色
|
// 建立角色
|
||||||
$superAdmin = Role::updateOrCreate(
|
$superAdmin = Role::updateOrCreate(
|
||||||
['name' => 'super-admin'],
|
['name' => 'super-admin', 'company_id' => null],
|
||||||
['is_system' => true]
|
['is_system' => true, 'guard_name' => 'web']
|
||||||
);
|
);
|
||||||
$superAdmin->syncPermissions(Permission::all());
|
$superAdmin->syncPermissions(Permission::all());
|
||||||
|
|
||||||
$tenantAdmin = Role::updateOrCreate(
|
$tenantAdmin = Role::updateOrCreate(
|
||||||
['name' => '客戶管理員'],
|
['name' => '客戶管理員角色模板', 'company_id' => null],
|
||||||
['is_system' => false]
|
['is_system' => true, 'guard_name' => 'web']
|
||||||
);
|
);
|
||||||
$tenantAdmin->syncPermissions([
|
$tenantAdmin->syncPermissions([
|
||||||
'menu.members',
|
'menu.members',
|
||||||
|
|||||||
830
lang/en.json
830
lang/en.json
@@ -1,381 +1,483 @@
|
|||||||
{
|
{
|
||||||
"Account Settings": "Account Settings",
|
"A new verification link has been sent to your email address.": "A new verification link has been sent to your email address.",
|
||||||
"Manage your profile information, security settings, and login history": "Manage your profile information, security settings, and login history",
|
"Account created successfully.": "Account created successfully.",
|
||||||
"Profile Information": "Profile Information",
|
"Account deleted successfully.": "Account deleted successfully.",
|
||||||
"Update your account's profile information and email address.": "Update your account's profile information and email address.",
|
|
||||||
"Update Password": "Update Password",
|
|
||||||
"Ensure your account is using a long, random password to stay secure.": "Ensure your account is using a long, random password to stay secure.",
|
|
||||||
"Delete Account": "Delete Account",
|
|
||||||
"Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.": "Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.",
|
|
||||||
"Are you sure you want to delete your account?": "Are you sure you want to delete your account?",
|
|
||||||
"Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.": "Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.",
|
|
||||||
"Login History": "Login History",
|
|
||||||
"Name": "Name",
|
|
||||||
"Phone": "Phone",
|
|
||||||
"Email": "Email",
|
|
||||||
"Current Password": "Current Password",
|
|
||||||
"New Password": "New Password",
|
|
||||||
"Confirm Password": "Confirm Password",
|
|
||||||
"Save": "Save",
|
|
||||||
"Saved.": "Saved.",
|
|
||||||
"Update": "Update",
|
|
||||||
"Cancel": "Cancel",
|
|
||||||
"Confirm": "Confirm",
|
|
||||||
"Danger Zone: Delete Account": "Danger Zone: Delete Account",
|
|
||||||
"Permanently Delete Account": "Permanently Delete Account",
|
|
||||||
"Password": "Password",
|
|
||||||
"Enter your password to confirm": "Enter your password to confirm",
|
|
||||||
"Dashboard": "Dashboard",
|
|
||||||
"Connectivity Status": "Connectivity Status",
|
|
||||||
"Real-time status monitoring": "Real-time status monitoring",
|
|
||||||
"LIVE": "LIVE",
|
|
||||||
"Online Machines": "Online Machines",
|
|
||||||
"Offline Machines": "Offline Machines",
|
|
||||||
"Alerts Pending": "Alerts Pending",
|
|
||||||
"Total Connected": "Total Connected",
|
|
||||||
"Monthly Transactions": "Monthly Transactions",
|
|
||||||
"Monthly cumulative revenue overview": "Monthly cumulative revenue overview",
|
|
||||||
"Today's Transactions": "Today's Transactions",
|
|
||||||
"vs Yesterday": "vs Yesterday",
|
|
||||||
"Yesterday": "Yesterday",
|
|
||||||
"Day Before": "Day Before",
|
|
||||||
"Machine Status List": "Machine Status List",
|
|
||||||
"Total items": "Total items: :count",
|
|
||||||
"Real-time monitoring across all machines": "Real-time monitoring across all machines",
|
|
||||||
"Quick search...": "Quick search...",
|
|
||||||
"Machine Info": "Machine Info",
|
|
||||||
"Running Status": "Running Status",
|
|
||||||
"Today Cumulative Sales": "Today Cumulative Sales",
|
|
||||||
"Current Stock": "Current Stock",
|
|
||||||
"Last Signal": "Last Signal",
|
|
||||||
"Alert Summary": "Alert Summary",
|
|
||||||
"No alert summary": "No alert summary",
|
|
||||||
"No data available": "No data available",
|
|
||||||
"Showing :from to :to of :total items": "Showing :from to :to of :total items",
|
|
||||||
"Previous": "Previous",
|
|
||||||
"Next": "Next",
|
|
||||||
"Profile Settings": "Profile Settings",
|
|
||||||
"Profile": "Profile",
|
|
||||||
"Member Management": "Member Management",
|
|
||||||
"Member List": "Member List",
|
|
||||||
"Membership Tiers": "Membership Tiers",
|
|
||||||
"Deposit Bonus": "Deposit Bonus",
|
|
||||||
"Point Rules": "Point Rules",
|
|
||||||
"Gift Definitions": "Gift Definitions",
|
|
||||||
"Machine Management": "Machine Management",
|
|
||||||
"Machine Logs": "Machine Logs",
|
|
||||||
"Machine List": "Machine List",
|
|
||||||
"Machine Permissions": "Machine Permissions",
|
|
||||||
"Utilization Rate": "Utilization Rate",
|
|
||||||
"Expiry Management": "Expiry Management",
|
|
||||||
"Maintenance Records": "Maintenance Records",
|
|
||||||
"APP Management": "APP Management",
|
|
||||||
"UI Elements": "UI Elements",
|
|
||||||
"Helper": "Helper",
|
|
||||||
"Questionnaire": "Questionnaire",
|
|
||||||
"Games": "Games",
|
|
||||||
"Timer": "Timer",
|
|
||||||
"Warehouse Management": "Warehouse Management",
|
|
||||||
"Warehouse List (All)": "Warehouse List (All)",
|
|
||||||
"Warehouse List (Individual)": "Warehouse List (Individual)",
|
|
||||||
"Stock Management": "Stock Management",
|
|
||||||
"Transfers": "Transfers",
|
|
||||||
"Purchases": "Purchases",
|
|
||||||
"Replenishments": "Replenishments",
|
|
||||||
"Replenishment Records": "Replenishment Records",
|
|
||||||
"Machine Stock": "Machine Stock",
|
|
||||||
"Staff Stock": "Staff Stock",
|
|
||||||
"Returns": "Returns",
|
|
||||||
"Sales Management": "Sales Management",
|
|
||||||
"Sales Records": "Sales Records",
|
|
||||||
"Pickup Codes": "Pickup Codes",
|
|
||||||
"Orders": "Orders",
|
|
||||||
"Promotions": "Promotions",
|
|
||||||
"Pass Codes": "Pass Codes",
|
|
||||||
"Store Gifts": "Store Gifts",
|
|
||||||
"Analysis Management": "Analysis Management",
|
|
||||||
"Change Stock": "Change Stock",
|
|
||||||
"Machine Reports": "Machine Reports",
|
|
||||||
"Product Reports": "Product Reports",
|
|
||||||
"Survey Analysis": "Survey Analysis",
|
|
||||||
"Audit Management": "Audit Management",
|
|
||||||
"Purchase Audit": "Purchase Audit",
|
|
||||||
"Transfer Audit": "Transfer Audit",
|
|
||||||
"Replenishment Audit": "Replenishment Audit",
|
|
||||||
"Data Configuration": "Data Configuration",
|
|
||||||
"Product Management": "Product Management",
|
|
||||||
"Advertisement Management": "Advertisement Management",
|
|
||||||
"Admin Sellable Products": "Admin Sellable Products",
|
|
||||||
"Account Management": "Account Management",
|
"Account Management": "Account Management",
|
||||||
"Sub Accounts": "Sub Accounts",
|
"Account Settings": "Account Settings",
|
||||||
"Sub Account Roles": "Sub Account Roles",
|
|
||||||
"Point Settings": "Point Settings",
|
|
||||||
"Badge Settings": "Badge Settings",
|
|
||||||
"Remote Management": "Remote Management",
|
|
||||||
"Machine Restart": "Machine Restart",
|
|
||||||
"Card Reader Restart": "Card Reader Restart",
|
|
||||||
"Remote Checkout": "Remote Checkout",
|
|
||||||
"Remote Lock": "Remote Lock",
|
|
||||||
"Remote Change": "Remote Change",
|
|
||||||
"Remote Dispense": "Remote Dispense",
|
|
||||||
"Line Management": "Line Management",
|
|
||||||
"Line Members": "Line Members",
|
|
||||||
"Line Machines": "Line Machines",
|
|
||||||
"Line Products": "Line Products",
|
|
||||||
"Line Official Account": "Line Official Account",
|
|
||||||
"Line Orders": "Line Orders",
|
|
||||||
"Line Coupons": "Line Coupons",
|
|
||||||
"Reservation System": "Reservation System",
|
|
||||||
"Reservation Members": "Reservation Members",
|
|
||||||
"Store Management": "Store Management",
|
|
||||||
"Time Slots": "Time Slots",
|
|
||||||
"Venue Management": "Venue Management",
|
|
||||||
"Coupons": "Coupons",
|
|
||||||
"Reservations": "Reservations",
|
|
||||||
"Order Management": "Order Management",
|
|
||||||
"Special Permission": "Special Permission",
|
|
||||||
"Clear Stock": "Clear Stock",
|
|
||||||
"APK Versions": "APK Versions",
|
|
||||||
"Discord Notifications": "Discord Notifications",
|
|
||||||
"Basic Settings": "Basic Settings",
|
|
||||||
"Machine Settings": "Machine Settings",
|
|
||||||
"Permission Settings": "Permission Settings",
|
|
||||||
"APP Features": "APP Features",
|
|
||||||
"Sales": "Sales",
|
|
||||||
"Others": "Others",
|
|
||||||
"AI Prediction": "AI Prediction",
|
|
||||||
"Roles": "Role Permissions",
|
|
||||||
"Role Management": "Role Permission Management",
|
|
||||||
"Define and manage security roles and permissions.": "Define and manage security roles and permissions.",
|
|
||||||
"Search roles...": "Search roles...",
|
|
||||||
"No permissions": "No permissions",
|
|
||||||
"No roles found.": "No roles found.",
|
|
||||||
"Create Role": "Create Role",
|
|
||||||
"Edit Role": "Edit Role",
|
|
||||||
"Update existing role and permissions.": "Update existing role and permissions.",
|
|
||||||
"Create a new role and assign permissions.": "Create a new role and assign permissions.",
|
|
||||||
"Enter role name": "Enter role name",
|
|
||||||
"Add Role": "Add Role",
|
|
||||||
"Role Name": "Role Name",
|
|
||||||
"Type": "Type",
|
|
||||||
"Permissions": "Permissions",
|
|
||||||
"Users": "Users",
|
|
||||||
"System role name cannot be modified.": "System role name cannot be modified.",
|
|
||||||
"The Super Admin role name cannot be modified.": "The Super Admin role name cannot be modified.",
|
|
||||||
"System Level": "System Level",
|
|
||||||
"Company Level": "Company Level",
|
|
||||||
"Global roles accessible by all administrators.": "Global roles accessible by all administrators.",
|
|
||||||
"Roles scoped to specific customer companies.": "Roles scoped to specific customer companies.",
|
|
||||||
"members": "Member Management",
|
|
||||||
"machines": "Machine Management",
|
|
||||||
"app": "APP Management",
|
|
||||||
"warehouses": "Warehouse Management",
|
|
||||||
"sales": "Sales Management",
|
|
||||||
"analysis": "Analysis Management",
|
|
||||||
"audit": "Audit Management",
|
|
||||||
"data-config": "Data Configuration",
|
|
||||||
"remote": "Remote Management",
|
|
||||||
"line": "Line Management",
|
|
||||||
"reservation": "Reservation System",
|
|
||||||
"special-permission": "Special Permission",
|
|
||||||
"companies": "Customer Management",
|
|
||||||
"accounts": "Account Management",
|
|
||||||
"roles": "Role Permissions",
|
|
||||||
"Role Permissions": "Role Permissions",
|
|
||||||
"Role Settings": "Role Permissions",
|
|
||||||
"No login history yet": "No login history yet",
|
|
||||||
"Signed in as": "Signed in as",
|
|
||||||
"Logout": "Logout",
|
|
||||||
"Joined": "Joined",
|
|
||||||
"Recent Login": "Recent Login",
|
|
||||||
"Total Logins": "Total Logins",
|
|
||||||
"Account Status": "Account Status",
|
"Account Status": "Account Status",
|
||||||
"Active": "Active",
|
"Account updated successfully.": "Account updated successfully.",
|
||||||
"Customer Management": "Customer Management",
|
"accounts": "Account Management",
|
||||||
"Manage all tenant accounts and validity": "Manage all tenant accounts and validity",
|
|
||||||
"Add Customer": "Add Customer",
|
|
||||||
"Total Customers": "Total Customers",
|
|
||||||
"Expired / Disabled": "Expired / Disabled",
|
|
||||||
"Search customers...": "Search customers...",
|
|
||||||
"All": "All",
|
|
||||||
"Disabled": "Disabled",
|
|
||||||
"Customer Info": "Customer Info",
|
|
||||||
"Accounts / Machines": "Accounts / Machines",
|
"Accounts / Machines": "Accounts / Machines",
|
||||||
"Valid Until": "Valid Until",
|
|
||||||
"Actions": "Actions",
|
|
||||||
"Permanent": "Permanent",
|
|
||||||
"Are you sure to delete this customer?": "Are you sure to delete this customer?",
|
|
||||||
"No customers found": "No customers found",
|
|
||||||
"Edit Customer": "Edit Customer",
|
|
||||||
"Update Customer": "Update Customer",
|
|
||||||
"Create": "Create",
|
|
||||||
"Company Name": "Company Name",
|
|
||||||
"Company Code": "Company Code",
|
|
||||||
"Tax ID (Optional)": "Tax ID (Optional)",
|
|
||||||
"Status": "Status",
|
|
||||||
"Contact Name": "Contact Name",
|
|
||||||
"Contact Phone": "Contact Phone",
|
|
||||||
"Contact Email": "Contact Email",
|
|
||||||
"Notes": "Notes",
|
|
||||||
"Customer created successfully.": "Customer created successfully.",
|
|
||||||
"Customer updated successfully.": "Customer updated successfully.",
|
|
||||||
"Customer deleted successfully.": "Customer deleted successfully.",
|
|
||||||
"Cannot delete company with active accounts.": "Cannot delete company with active accounts.",
|
|
||||||
"Contract Until (Optional)": "Contract Until (Optional)",
|
|
||||||
"Company Information": "Company Information",
|
|
||||||
"Initial Admin Account": "Initial Admin Account",
|
|
||||||
"Optional": "Optional",
|
|
||||||
"Username": "Username",
|
|
||||||
"Enter login ID": "Enter login ID",
|
|
||||||
"Min 8 characters": "Min 8 characters",
|
|
||||||
"Admin display name": "Admin display name",
|
|
||||||
"Initial Role": "Initial Role",
|
|
||||||
"Contact & Details": "Contact & Details",
|
|
||||||
"e.g. Taiwan Star": "e.g. Taiwan Star",
|
|
||||||
"e.g. TWSTAR": "e.g. TWSTAR",
|
|
||||||
"Manage administrative and tenant accounts": "Manage administrative and tenant accounts",
|
|
||||||
"Add Account": "Add Account",
|
|
||||||
"All Companies": "All Companies",
|
|
||||||
"User Info": "User Info",
|
|
||||||
"Belongs To": "Belongs To",
|
|
||||||
"Role": "Role",
|
|
||||||
"SYSTEM": "SYSTEM",
|
|
||||||
"No users found": "No users found",
|
|
||||||
"Data Configuration Permissions": "Data Configuration Permissions",
|
|
||||||
"Sales Permissions": "Sales Permissions",
|
|
||||||
"Machine Management Permissions": "Machine Management Permissions",
|
|
||||||
"Warehouse Permissions": "Warehouse Permissions",
|
|
||||||
"Analysis Permissions": "Analysis Permissions",
|
|
||||||
"Audit Permissions": "Audit Permissions",
|
|
||||||
"Remote Permissions": "Remote Permissions",
|
|
||||||
"Line Permissions": "Line Permissions",
|
|
||||||
"Company": "Company",
|
|
||||||
"Save Changes": "Save Changes",
|
|
||||||
"User": "User",
|
|
||||||
"Admin": "Admin",
|
|
||||||
"Super Admin": "Super Admin",
|
|
||||||
"e.g. John Doe": "e.g. John Doe",
|
|
||||||
"e.g. johndoe": "e.g. johndoe",
|
|
||||||
"Search users...": "Search users...",
|
|
||||||
"Admin Name": "Admin Name",
|
|
||||||
"New Password (leave blank to keep current)": "New Password (leave blank to keep current)",
|
|
||||||
"Are you sure you want to delete this account?": "Are you sure you want to delete this account?",
|
|
||||||
"Show": "Show",
|
|
||||||
"to": "to",
|
|
||||||
"of": "of",
|
|
||||||
"items": "items",
|
|
||||||
"Showing": "Showing",
|
|
||||||
"Monitor events and system activity across your vending fleet.": "Monitor events and system activity across your vending fleet.",
|
|
||||||
"All Machines": "All Machines",
|
|
||||||
"All Levels": "All Levels",
|
|
||||||
"Timestamp": "Timestamp",
|
|
||||||
"Message Content": "Message Content",
|
|
||||||
"No matching logs found": "No matching logs found",
|
|
||||||
"Unknown": "Unknown",
|
|
||||||
"Info": "Info",
|
|
||||||
"Warning": "Warning",
|
|
||||||
"basic-settings": "Basic Settings",
|
|
||||||
"permissions": "Permission Settings",
|
|
||||||
"Error": "Error",
|
|
||||||
"Machine Model Settings": "Machine Model Settings",
|
|
||||||
"Machine Model": "Machine Model",
|
|
||||||
"Model Name": "Model Name",
|
|
||||||
"Machine Count": "Machine Count",
|
|
||||||
"Add Machine Model": "Add Machine Model",
|
|
||||||
"Edit Machine Model": "Edit Machine Model",
|
|
||||||
"Machine model created successfully.": "Machine model created successfully.",
|
|
||||||
"Machine model updated successfully.": "Machine model updated successfully.",
|
|
||||||
"Machine model deleted successfully.": "Machine model deleted successfully.",
|
|
||||||
"Cannot delete model that is currently in use by machines.": "Cannot delete model that is currently in use by machines.",
|
|
||||||
"Machine Details": "Machine Details",
|
|
||||||
"Create Machine": "Create Machine",
|
|
||||||
"Edit Machine": "Edit Machine",
|
|
||||||
"Basic Information": "Basic Information",
|
|
||||||
"Location": "Location",
|
|
||||||
"Temperature": "Temperature",
|
|
||||||
"Firmware Version": "Firmware Version",
|
|
||||||
"Last Heartbeat": "Last Heartbeat",
|
|
||||||
"Never Connected": "Never Connected",
|
|
||||||
"View Logs": "View Logs",
|
|
||||||
"Real-time Operation Logs (Last 50)": "Real-time Operation Logs (Last 50)",
|
|
||||||
"All Times System Timezone": "All times are in system timezone",
|
|
||||||
"Level": "Level",
|
|
||||||
"Logs": "Logs",
|
|
||||||
"Time": "Time",
|
|
||||||
"Message": "Message",
|
|
||||||
"Online": "Online",
|
|
||||||
"Offline": "Offline",
|
|
||||||
"Connecting...": "Connecting...",
|
|
||||||
"No logs found": "No logs found",
|
|
||||||
"Management of operational parameters and models": "Management of operational parameters and models",
|
|
||||||
"ECPay Invoice Settings Description": "ECPay Electronic Invoice Settings",
|
|
||||||
"E.SUN QR Scan Settings Description": "E.SUN Bank QR Scan Payment Settings",
|
|
||||||
"LINE Pay Direct Settings Description": "LINE Pay Official Direct Connection Settings",
|
|
||||||
"TapPay Integration Settings Description": "TapPay Payment Integration Settings",
|
|
||||||
"Merchant IDs": "Merchant IDs",
|
|
||||||
"Parameters": "Parameters",
|
|
||||||
"Hardware & Network": "Hardware & Network",
|
|
||||||
"Serial & Version": "Serial & Version",
|
|
||||||
"Heartbeat": "Heartbeat",
|
|
||||||
"Heating Range": "Heating Range",
|
|
||||||
"API Token": "API Token",
|
|
||||||
"No location set": "No location set",
|
|
||||||
"Close Panel": "Close Panel",
|
|
||||||
"Operations": "Operations",
|
|
||||||
"Operational Parameters": "Operational Parameters",
|
|
||||||
"Hardware & Slots": "Hardware & Slots",
|
|
||||||
"Slot Mechanism (default: Conveyor, check for Spring)": "Slot Mechanism (default: Conveyor, check for Spring)",
|
|
||||||
"Payment & Invoice": "Payment & Invoice",
|
|
||||||
"Payment Config": "Payment Config",
|
|
||||||
"Invoice Status": "Invoice Status",
|
|
||||||
"No Invoice": "No Invoice",
|
|
||||||
"Default Donate": "Default Donate",
|
|
||||||
"Default Not Donate": "Default Not Donate",
|
|
||||||
"Member & External": "Member & External",
|
|
||||||
"Welcome Gift": "Welcome Gift",
|
|
||||||
"Enabled/Disabled": "Enabled/Disabled",
|
|
||||||
"Member System": "Member System",
|
|
||||||
"Machine Images": "Machine Images",
|
|
||||||
"No images uploaded": "No images uploaded",
|
|
||||||
"Upload New Images": "Upload New Images",
|
|
||||||
"Max 3": "Max 3",
|
|
||||||
"Uploading new images will replace all existing images.": "Uploading new images will replace all existing images.",
|
|
||||||
"Search machines...": "Search machines...",
|
|
||||||
"Search models...": "Search models...",
|
|
||||||
"Card Reader": "Card Reader",
|
|
||||||
"Owner": "Owner",
|
|
||||||
"Action": "Action",
|
"Action": "Action",
|
||||||
"Items": "Items",
|
"Actions": "Actions",
|
||||||
"View Details": "View Details",
|
"Active": "Active",
|
||||||
"Edit Settings": "Edit Settings",
|
"Add Account": "Add Account",
|
||||||
"Are you sure?": "Are you sure?",
|
"Add Customer": "Add Customer",
|
||||||
"Serial No": "Serial No",
|
"Add Machine": "Add Machine",
|
||||||
"Select Owner": "Select Owner",
|
"Add Machine Model": "Add Machine Model",
|
||||||
"Select Model": "Select Model",
|
"Add Role": "Add Role",
|
||||||
"Machines": "Machines",
|
"Admin": "Admin",
|
||||||
"Models": "Models",
|
"Admin display name": "Admin display name",
|
||||||
"Edit": "Edit",
|
"Admin Name": "Admin Name",
|
||||||
"Delete": "Delete",
|
"Admin Sellable Products": "Admin Sellable Products",
|
||||||
"None": "None",
|
"Administrator": "Administrator",
|
||||||
"Select Company": "Select Company",
|
"Advertisement Management": "Advertisement Management",
|
||||||
"e.g., Company Standard Pay": "e.g., Company Standard Pay",
|
"Affiliation": "Affiliation",
|
||||||
|
"AI Prediction": "AI Prediction",
|
||||||
|
"Alert Summary": "Alert Summary",
|
||||||
|
"Alerts Pending": "Alerts Pending",
|
||||||
|
"All": "All",
|
||||||
|
"All Affiliations": "All Affiliations",
|
||||||
|
"All Companies": "All Companies",
|
||||||
|
"All Levels": "All Levels",
|
||||||
|
"All Machines": "All Machines",
|
||||||
|
"All Times System Timezone": "All times are in system timezone",
|
||||||
|
"analysis": "Analysis Management",
|
||||||
|
"Analysis Management": "Analysis Management",
|
||||||
|
"Analysis Permissions": "Analysis Permissions",
|
||||||
|
"API Token": "API Token",
|
||||||
|
"APK Versions": "APK Versions",
|
||||||
|
"app": "APP Management",
|
||||||
|
"APP Features": "APP Features",
|
||||||
|
"APP Management": "APP Management",
|
||||||
"APP_ID": "APP_ID",
|
"APP_ID": "APP_ID",
|
||||||
"APP_KEY": "APP_KEY",
|
"APP_KEY": "APP_KEY",
|
||||||
|
"Are you sure to delete this customer?": "Are you sure to delete this customer?",
|
||||||
|
"Are you sure you want to delete this account?": "Are you sure you want to delete this account?",
|
||||||
|
"Are you sure you want to delete this account? This action cannot be undone.": "Are you sure you want to delete this account? This action cannot be undone.",
|
||||||
|
"Are you sure you want to delete this configuration? This action cannot be undone.": "Are you sure you want to delete this configuration? This action cannot be undone.",
|
||||||
|
"Are you sure you want to delete this item? This action cannot be undone.": "Are you sure you want to delete this item? This action cannot be undone.",
|
||||||
|
"Are you sure you want to delete this role? This action cannot be undone.": "Are you sure you want to delete this role? This action cannot be undone.",
|
||||||
|
"Are you sure you want to delete your account?": "Are you sure you want to delete your account?",
|
||||||
|
"Are you sure?": "Are you sure?",
|
||||||
|
"audit": "Audit Management",
|
||||||
|
"Audit Management": "Audit Management",
|
||||||
|
"Audit Permissions": "Audit Permissions",
|
||||||
|
"Avatar updated successfully.": "Avatar updated successfully.",
|
||||||
|
"Badge Settings": "Badge Settings",
|
||||||
|
"Basic Information": "Basic Information",
|
||||||
|
"Basic Settings": "Basic Settings",
|
||||||
|
"basic-settings": "Basic Settings",
|
||||||
|
"Belongs To": "Belongs To",
|
||||||
|
"Belongs To Company": "Belongs To Company",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"Cannot delete company with active accounts.": "Cannot delete company with active accounts.",
|
||||||
|
"Cannot delete model that is currently in use by machines.": "Cannot delete model that is currently in use by machines.",
|
||||||
|
"Cannot Delete Role": "Cannot Delete Role",
|
||||||
|
"Cannot delete role with active users.": "Cannot delete role with active users.",
|
||||||
|
"Card Reader": "Card Reader",
|
||||||
|
"Card Reader No": "Card Reader No",
|
||||||
|
"Card Reader Restart": "Card Reader Restart",
|
||||||
|
"Card Reader Seconds": "Card Reader Seconds",
|
||||||
|
"Change": "Change",
|
||||||
|
"Change Stock": "Change Stock",
|
||||||
"ChannelId": "ChannelId",
|
"ChannelId": "ChannelId",
|
||||||
"ChannelSecret": "ChannelSecret",
|
"ChannelSecret": "ChannelSecret",
|
||||||
|
"Checkout Time 1": "Checkout Time 1",
|
||||||
|
"Checkout Time 2": "Checkout Time 2",
|
||||||
|
"Clear Stock": "Clear Stock",
|
||||||
|
"Click here to re-send the verification email.": "Click here to re-send the verification email.",
|
||||||
|
"Click to upload": "Click to upload",
|
||||||
|
"Close Panel": "Close Panel",
|
||||||
|
"companies": "Customer Management",
|
||||||
|
"Company": "Company",
|
||||||
|
"Company Code": "Company Code",
|
||||||
|
"Company Information": "Company Information",
|
||||||
|
"Company Level": "Company Level",
|
||||||
|
"Company Name": "Company Name",
|
||||||
|
"Configuration Name": "Configuration Name",
|
||||||
|
"Confirm": "Confirm",
|
||||||
|
"Confirm Deletion": "Confirm Deletion",
|
||||||
|
"Confirm Password": "Confirm Password",
|
||||||
|
"Connecting...": "Connecting...",
|
||||||
|
"Connectivity Status": "Connectivity Status",
|
||||||
|
"Contact & Details": "Contact & Details",
|
||||||
|
"Contact Email": "Contact Email",
|
||||||
|
"Contact Name": "Contact Name",
|
||||||
|
"Contact Phone": "Contact Phone",
|
||||||
|
"Contract Until (Optional)": "Contract Until (Optional)",
|
||||||
|
"Coupons": "Coupons",
|
||||||
|
"Create": "Create",
|
||||||
|
"Create a new role and assign permissions.": "Create a new role and assign permissions.",
|
||||||
|
"Create Config": "Create Config",
|
||||||
|
"Create Machine": "Create Machine",
|
||||||
|
"Create Payment Config": "Create Payment Config",
|
||||||
|
"Create Role": "Create Role",
|
||||||
|
"Current Password": "Current Password",
|
||||||
|
"Current Stock": "Current Stock",
|
||||||
|
"Customer created successfully.": "Customer created successfully.",
|
||||||
|
"Customer deleted successfully.": "Customer deleted successfully.",
|
||||||
|
"Customer Info": "Customer Info",
|
||||||
|
"Customer Management": "Customer Management",
|
||||||
|
"Customer Payment Config": "Customer Payment Config",
|
||||||
|
"Customer updated successfully.": "Customer updated successfully.",
|
||||||
|
"Danger Zone: Delete Account": "Danger Zone: Delete Account",
|
||||||
|
"Dashboard": "Dashboard",
|
||||||
|
"Data Configuration": "Data Configuration",
|
||||||
|
"Data Configuration Permissions": "Data Configuration Permissions",
|
||||||
|
"data-config": "Data Configuration",
|
||||||
|
"Day Before": "Day Before",
|
||||||
|
"Default Donate": "Default Donate",
|
||||||
|
"Default Not Donate": "Default Not Donate",
|
||||||
|
"Define and manage security roles and permissions.": "Define and manage security roles and permissions.",
|
||||||
|
"Define new third-party payment parameters": "Define new third-party payment parameters",
|
||||||
|
"Delete": "Delete",
|
||||||
|
"Delete Account": "Delete Account",
|
||||||
|
"Delete Permanently": "Delete Permanently",
|
||||||
|
"Deposit Bonus": "Deposit Bonus",
|
||||||
|
"Detail": "Detail",
|
||||||
|
"Disabled": "Disabled",
|
||||||
|
"Discord Notifications": "Discord Notifications",
|
||||||
|
"e.g. John Doe": "e.g. John Doe",
|
||||||
|
"e.g. johndoe": "e.g. johndoe",
|
||||||
|
"e.g. Taiwan Star": "e.g. Taiwan Star",
|
||||||
|
"e.g. TWSTAR": "e.g. TWSTAR",
|
||||||
|
"e.g., Company Standard Pay": "e.g., Company Standard Pay",
|
||||||
|
"e.g., Taipei Station": "e.g., Taipei Station",
|
||||||
|
"E.SUN QR Scan": "E.SUN QR Scan",
|
||||||
|
"E.SUN QR Scan Settings Description": "E.SUN Bank QR Scan Payment Settings",
|
||||||
"EASY_MERCHANT_ID": "EASY_MERCHANT_ID",
|
"EASY_MERCHANT_ID": "EASY_MERCHANT_ID",
|
||||||
|
"ECPay Invoice": "ECPay Invoice",
|
||||||
|
"ECPay Invoice Settings Description": "ECPay Electronic Invoice Settings",
|
||||||
|
"Edit": "Edit",
|
||||||
|
"Edit Account": "Edit Account",
|
||||||
|
"Edit Customer": "Edit Customer",
|
||||||
|
"Edit Machine": "Edit Machine",
|
||||||
|
"Edit Machine Model": "Edit Machine Model",
|
||||||
|
"Edit Payment Config": "Edit Payment Config",
|
||||||
|
"Edit Role": "Edit Role",
|
||||||
|
"Edit Settings": "Edit Settings",
|
||||||
|
"Email": "Email",
|
||||||
|
"Enabled/Disabled": "Enabled/Disabled",
|
||||||
|
"Ensure your account is using a long, random password to stay secure.": "Ensure your account is using a long, random password to stay secure.",
|
||||||
|
"Enter login ID": "Enter login ID",
|
||||||
|
"Enter machine location": "Enter machine location",
|
||||||
|
"Enter machine name": "Enter machine name",
|
||||||
|
"Enter model name": "Enter model name",
|
||||||
|
"Enter role name": "Enter role name",
|
||||||
|
"Enter serial number": "Enter serial number",
|
||||||
|
"Enter your password to confirm": "Enter your password to confirm",
|
||||||
|
"Error": "Error",
|
||||||
|
"Expired / Disabled": "Expired / Disabled",
|
||||||
|
"Expiry Management": "Expiry Management",
|
||||||
|
"Failed to update machine images: ": "Failed to update machine images: ",
|
||||||
|
"files selected": "files selected",
|
||||||
|
"Firmware Version": "Firmware Version",
|
||||||
|
"Full Name": "Full Name",
|
||||||
|
"Games": "Games",
|
||||||
|
"Gift Definitions": "Gift Definitions",
|
||||||
|
"Global roles accessible by all administrators.": "Global roles accessible by all administrators.",
|
||||||
|
"Got it": "Got it",
|
||||||
|
"Hardware & Network": "Hardware & Network",
|
||||||
|
"Hardware & Slots": "Hardware & Slots",
|
||||||
"HashIV": "HashIV",
|
"HashIV": "HashIV",
|
||||||
"HashKey": "HashKey",
|
"HashKey": "HashKey",
|
||||||
|
"Heartbeat": "Heartbeat",
|
||||||
|
"Heating End Time": "Heating End Time",
|
||||||
|
"Heating Range": "Heating Range",
|
||||||
|
"Heating Start Time": "Heating Start Time",
|
||||||
|
"Helper": "Helper",
|
||||||
|
"Info": "Info",
|
||||||
|
"Initial Admin Account": "Initial Admin Account",
|
||||||
|
"Initial Role": "Initial Role",
|
||||||
|
"Invoice Status": "Invoice Status",
|
||||||
|
"items": "items",
|
||||||
|
"Items": "Items",
|
||||||
"JKO_MERCHANT_ID": "JKO_MERCHANT_ID",
|
"JKO_MERCHANT_ID": "JKO_MERCHANT_ID",
|
||||||
|
"john@example.com": "john@example.com",
|
||||||
|
"Joined": "Joined",
|
||||||
"Key": "Key",
|
"Key": "Key",
|
||||||
|
"Key No": "Key No",
|
||||||
|
"Last Heartbeat": "Last Heartbeat",
|
||||||
|
"Last Signal": "Last Signal",
|
||||||
|
"Last Updated": "Last Updated",
|
||||||
|
"Level": "Level",
|
||||||
|
"line": "Line Management",
|
||||||
|
"Line Coupons": "Line Coupons",
|
||||||
|
"Line Machines": "Line Machines",
|
||||||
|
"Line Management": "Line Management",
|
||||||
|
"Line Members": "Line Members",
|
||||||
|
"Line Official Account": "Line Official Account",
|
||||||
|
"Line Orders": "Line Orders",
|
||||||
|
"LINE Pay Direct": "LINE Pay Direct",
|
||||||
|
"LINE Pay Direct Settings Description": "LINE Pay Official Direct Connection Settings",
|
||||||
|
"Line Permissions": "Line Permissions",
|
||||||
|
"Line Products": "Line Products",
|
||||||
"LINE_MERCHANT_ID": "LINE_MERCHANT_ID",
|
"LINE_MERCHANT_ID": "LINE_MERCHANT_ID",
|
||||||
"PARTNER_KEY": "PARTNER_KEY",
|
"LIVE": "LIVE",
|
||||||
"PI_MERCHANT_ID": "PI_MERCHANT_ID",
|
"Location": "Location",
|
||||||
"PS_MERCHANT_ID": "PS_MERCHANT_ID",
|
"Login History": "Login History",
|
||||||
"Save Config": "Save Config",
|
"Logout": "Logout",
|
||||||
"StoreID": "StoreID",
|
"Logs": "Logs",
|
||||||
"TermID": "TermID",
|
"Machine Count": "Machine Count",
|
||||||
"Photo Slot": "Photo Slot",
|
"Machine created successfully.": "Machine created successfully.",
|
||||||
|
"Machine Details": "Machine Details",
|
||||||
|
"Machine Images": "Machine Images",
|
||||||
|
"Machine images updated successfully.": "Machine images updated successfully.",
|
||||||
|
"Machine Info": "Machine Info",
|
||||||
|
"Machine List": "Machine List",
|
||||||
|
"Machine Logs": "Machine Logs",
|
||||||
|
"Machine Management": "Machine Management",
|
||||||
|
"Machine Management Permissions": "Machine Management Permissions",
|
||||||
|
"Machine Model": "Machine Model",
|
||||||
|
"Machine model created successfully.": "Machine model created successfully.",
|
||||||
|
"Machine model deleted successfully.": "Machine model deleted successfully.",
|
||||||
|
"Machine Model Settings": "Machine Model Settings",
|
||||||
|
"Machine model updated successfully.": "Machine model updated successfully.",
|
||||||
|
"Machine Name": "Machine Name",
|
||||||
|
"Machine Permissions": "Machine Permissions",
|
||||||
|
"Machine Reports": "Machine Reports",
|
||||||
|
"Machine Restart": "Machine Restart",
|
||||||
|
"Machine Settings": "Machine Settings",
|
||||||
|
"Machine settings updated successfully.": "Machine settings updated successfully.",
|
||||||
|
"Machine Status List": "Machine Status List",
|
||||||
|
"Machine Stock": "Machine Stock",
|
||||||
|
"machines": "Machine Management",
|
||||||
|
"Machines": "Machines",
|
||||||
|
"Maintenance Records": "Maintenance Records",
|
||||||
|
"Manage administrative and tenant accounts": "Manage administrative and tenant accounts",
|
||||||
|
"Manage all tenant accounts and validity": "Manage all tenant accounts and validity",
|
||||||
|
"Manage your profile information, security settings, and login history": "Manage your profile information, security settings, and login history",
|
||||||
|
"Management of operational parameters and models": "Management of operational parameters and models",
|
||||||
|
"Max 3": "Max 3",
|
||||||
|
"Member & External": "Member & External",
|
||||||
|
"Member List": "Member List",
|
||||||
|
"Member Management": "Member Management",
|
||||||
|
"Member System": "Member System",
|
||||||
|
"members": "Member Management",
|
||||||
|
"Membership Tiers": "Membership Tiers",
|
||||||
|
"Menu Permissions": "Menu Permissions",
|
||||||
|
"Merchant IDs": "Merchant IDs",
|
||||||
|
"Merchant payment gateway settings management": "Merchant payment gateway settings management",
|
||||||
|
"Message": "Message",
|
||||||
|
"Message Content": "Message Content",
|
||||||
|
"Min 8 characters": "Min 8 characters",
|
||||||
|
"Model": "Model",
|
||||||
|
"Model Name": "Model Name",
|
||||||
|
"Models": "Models",
|
||||||
|
"Modifying your own administrative permissions may result in losing access to certain system functions.": "Modifying your own administrative permissions may result in losing access to certain system functions.",
|
||||||
|
"Monitor events and system activity across your vending fleet.": "Monitor events and system activity across your vending fleet.",
|
||||||
|
"Monthly cumulative revenue overview": "Monthly cumulative revenue overview",
|
||||||
|
"Monthly Transactions": "Monthly Transactions",
|
||||||
|
"Name": "Name",
|
||||||
|
"Never Connected": "Never Connected",
|
||||||
|
"New Password": "New Password",
|
||||||
|
"New Password (leave blank to keep current)": "New Password (leave blank to keep current)",
|
||||||
|
"Next": "Next",
|
||||||
|
"No accounts found": "No accounts found",
|
||||||
|
"No alert summary": "No alert summary",
|
||||||
|
"No configurations found": "No configurations found",
|
||||||
|
"No customers found": "No customers found",
|
||||||
|
"No data available": "No data available",
|
||||||
|
"No file uploaded.": "No file uploaded.",
|
||||||
|
"No images uploaded": "No images uploaded",
|
||||||
|
"No Invoice": "No Invoice",
|
||||||
|
"No location set": "No location set",
|
||||||
|
"No login history yet": "No login history yet",
|
||||||
|
"No logs found": "No logs found",
|
||||||
|
"No matching logs found": "No matching logs found",
|
||||||
|
"No permissions": "No permissions",
|
||||||
|
"No roles found.": "No roles found.",
|
||||||
|
"No users found": "No users found",
|
||||||
|
"None": "None",
|
||||||
|
"Not Used": "Not Used",
|
||||||
|
"Notes": "Notes",
|
||||||
|
"of": "of",
|
||||||
|
"Offline": "Offline",
|
||||||
|
"Offline Machines": "Offline Machines",
|
||||||
|
"Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.": "Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.",
|
||||||
|
"Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.": "Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.",
|
||||||
|
"Online": "Online",
|
||||||
|
"Online Machines": "Online Machines",
|
||||||
|
"Only system roles can be assigned to platform administrative accounts.": "Only system roles can be assigned to platform administrative accounts.",
|
||||||
|
"Operational Parameters": "Operational Parameters",
|
||||||
|
"Operations": "Operations",
|
||||||
"Optimized for display. Supported formats: JPG, PNG, WebP.": "Optimized for display. Supported formats: JPG, PNG, WebP.",
|
"Optimized for display. Supported formats: JPG, PNG, WebP.": "Optimized for display. Supported formats: JPG, PNG, WebP.",
|
||||||
"Change": "Change"
|
"Optional": "Optional",
|
||||||
|
"Order Management": "Order Management",
|
||||||
|
"Orders": "Orders",
|
||||||
|
"Others": "Others",
|
||||||
|
"Owner": "Owner",
|
||||||
|
"Parameters": "Parameters",
|
||||||
|
"PARTNER_KEY": "PARTNER_KEY",
|
||||||
|
"Pass Codes": "Pass Codes",
|
||||||
|
"Password": "Password",
|
||||||
|
"Payment & Invoice": "Payment & Invoice",
|
||||||
|
"Payment Buffer Seconds": "Payment Buffer Seconds",
|
||||||
|
"Payment Config": "Payment Config",
|
||||||
|
"Payment Configuration": "Payment Configuration",
|
||||||
|
"Payment Configuration created successfully.": "Payment Configuration created successfully.",
|
||||||
|
"Payment Configuration deleted successfully.": "Payment Configuration deleted successfully.",
|
||||||
|
"Payment Configuration updated successfully.": "Payment Configuration updated successfully.",
|
||||||
|
"Permanent": "Permanent",
|
||||||
|
"Permanently Delete Account": "Permanently Delete Account",
|
||||||
|
"Permission Settings": "Permission Settings",
|
||||||
|
"Permissions": "Permissions",
|
||||||
|
"permissions": "Permission Settings",
|
||||||
|
"Phone": "Phone",
|
||||||
|
"Photo Slot": "Photo Slot",
|
||||||
|
"PI_MERCHANT_ID": "PI_MERCHANT_ID",
|
||||||
|
"Pickup Codes": "Pickup Codes",
|
||||||
|
"Please check the following errors:": "Please check the following errors:",
|
||||||
|
"Please check the form for errors.": "Please check the form for errors.",
|
||||||
|
"Point Rules": "Point Rules",
|
||||||
|
"Point Settings": "Point Settings",
|
||||||
|
"Previous": "Previous",
|
||||||
|
"Product Management": "Product Management",
|
||||||
|
"Product Reports": "Product Reports",
|
||||||
|
"Profile": "Profile",
|
||||||
|
"Profile Information": "Profile Information",
|
||||||
|
"Profile Settings": "Profile Settings",
|
||||||
|
"Profile updated successfully.": "Profile updated successfully.",
|
||||||
|
"Promotions": "Promotions",
|
||||||
|
"Protected": "Protected",
|
||||||
|
"PS_MERCHANT_ID": "PS_MERCHANT_ID",
|
||||||
|
"Purchase Audit": "Purchase Audit",
|
||||||
|
"Purchases": "Purchases",
|
||||||
|
"Questionnaire": "Questionnaire",
|
||||||
|
"Quick search...": "Quick search...",
|
||||||
|
"Real-time monitoring across all machines": "Real-time monitoring across all machines",
|
||||||
|
"Real-time Operation Logs (Last 50)": "Real-time Operation Logs (Last 50)",
|
||||||
|
"Real-time status monitoring": "Real-time status monitoring",
|
||||||
|
"Recent Login": "Recent Login",
|
||||||
|
"remote": "Remote Management",
|
||||||
|
"Remote Change": "Remote Change",
|
||||||
|
"Remote Checkout": "Remote Checkout",
|
||||||
|
"Remote Dispense": "Remote Dispense",
|
||||||
|
"Remote Lock": "Remote Lock",
|
||||||
|
"Remote Management": "Remote Management",
|
||||||
|
"Remote Permissions": "Remote Permissions",
|
||||||
|
"Replenishment Audit": "Replenishment Audit",
|
||||||
|
"Replenishment Records": "Replenishment Records",
|
||||||
|
"Replenishments": "Replenishments",
|
||||||
|
"reservation": "Reservation System",
|
||||||
|
"Reservation Members": "Reservation Members",
|
||||||
|
"Reservation System": "Reservation System",
|
||||||
|
"Reservations": "Reservations",
|
||||||
|
"Returns": "Returns",
|
||||||
|
"Role": "Role",
|
||||||
|
"Role created successfully.": "Role created successfully.",
|
||||||
|
"Role deleted successfully.": "Role deleted successfully.",
|
||||||
|
"Role Management": "Role Permission Management",
|
||||||
|
"Role Name": "Role Name",
|
||||||
|
"Role name already exists in this company.": "Role name already exists in this company.",
|
||||||
|
"Role not found.": "Role not found.",
|
||||||
|
"Role Permissions": "Role Permissions",
|
||||||
|
"Role Settings": "Role Permissions",
|
||||||
|
"Role Type": "Role Type",
|
||||||
|
"Role updated successfully.": "Role updated successfully.",
|
||||||
|
"Roles": "Role Permissions",
|
||||||
|
"roles": "Role Permissions",
|
||||||
|
"Roles scoped to specific customer companies.": "Roles scoped to specific customer companies.",
|
||||||
|
"Running Status": "Running Status",
|
||||||
|
"Sales": "Sales",
|
||||||
|
"sales": "Sales Management",
|
||||||
|
"Sales Management": "Sales Management",
|
||||||
|
"Sales Permissions": "Sales Permissions",
|
||||||
|
"Sales Records": "Sales Records",
|
||||||
|
"Save": "Save",
|
||||||
|
"Save Changes": "Save Changes",
|
||||||
|
"Save Config": "Save Config",
|
||||||
|
"Saved.": "Saved.",
|
||||||
|
"Search configurations...": "Search configurations...",
|
||||||
|
"Search customers...": "Search customers...",
|
||||||
|
"Search machines...": "Search machines...",
|
||||||
|
"Search models...": "Search models...",
|
||||||
|
"Search roles...": "Search roles...",
|
||||||
|
"Search users...": "Search users...",
|
||||||
|
"Select Company": "Select Company",
|
||||||
|
"Select Model": "Select Model",
|
||||||
|
"Select Owner": "Select Owner",
|
||||||
|
"Serial & Version": "Serial & Version",
|
||||||
|
"Serial No": "Serial No",
|
||||||
|
"Serial Number": "Serial Number",
|
||||||
|
"Show": "Show",
|
||||||
|
"Showing": "Showing",
|
||||||
|
"Showing :from to :to of :total items": "Showing :from to :to of :total items",
|
||||||
|
"Sign in to your account": "Sign in to your account",
|
||||||
|
"Signed in as": "Signed in as",
|
||||||
|
"Slot Mechanism (default: Conveyor, check for Spring)": "Slot Mechanism (default: Conveyor, check for Spring)",
|
||||||
|
"Some fields need attention": "Some fields need attention",
|
||||||
|
"Special Permission": "Special Permission",
|
||||||
|
"special-permission": "Special Permission",
|
||||||
|
"Staff Stock": "Staff Stock",
|
||||||
|
"Status": "Status",
|
||||||
|
"Stock Management": "Stock Management",
|
||||||
|
"Store Gifts": "Store Gifts",
|
||||||
|
"Store ID": "Store ID",
|
||||||
|
"Store Management": "Store Management",
|
||||||
|
"StoreID": "StoreID",
|
||||||
|
"Sub Account Management": "Sub Account Management",
|
||||||
|
"Sub Account Roles": "Sub Account Roles",
|
||||||
|
"Sub Accounts": "Sub Accounts",
|
||||||
|
"Success": "Success",
|
||||||
|
"Super Admin": "Super Admin",
|
||||||
|
"Super-admin role cannot be assigned to tenant accounts.": "Super-admin role cannot be assigned to tenant accounts.",
|
||||||
|
"Survey Analysis": "Survey Analysis",
|
||||||
|
"SYSTEM": "SYSTEM",
|
||||||
|
"System Level": "System Level",
|
||||||
|
"System Role": "System Role",
|
||||||
|
"System role name cannot be modified.": "System role name cannot be modified.",
|
||||||
|
"System roles cannot be deleted by tenant administrators.": "System roles cannot be deleted by tenant administrators.",
|
||||||
|
"System roles cannot be modified by tenant administrators.": "System roles cannot be modified by tenant administrators.",
|
||||||
|
"System super admin accounts cannot be deleted.": "System super admin accounts cannot be deleted.",
|
||||||
|
"System super admin accounts cannot be modified via this interface.": "System super admin accounts cannot be modified via this interface.",
|
||||||
|
"Systems Initializing": "Systems Initializing",
|
||||||
|
"TapPay Integration": "TapPay Integration",
|
||||||
|
"TapPay Integration Settings Description": "TapPay Payment Integration Settings",
|
||||||
|
"Tax ID (Optional)": "Tax ID (Optional)",
|
||||||
|
"Temperature": "Temperature",
|
||||||
|
"TermID": "TermID",
|
||||||
|
"The image is too large. Please upload an image smaller than 1MB.": "The image is too large. Please upload an image smaller than 1MB.",
|
||||||
|
"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.",
|
||||||
|
"This role belongs to another company and cannot be assigned.": "This role belongs to another company and cannot be assigned.",
|
||||||
|
"Time": "Time",
|
||||||
|
"Time Slots": "Time Slots",
|
||||||
|
"Timer": "Timer",
|
||||||
|
"Timestamp": "Timestamp",
|
||||||
|
"to": "to",
|
||||||
|
"Today Cumulative Sales": "Today Cumulative Sales",
|
||||||
|
"Today's Transactions": "Today's Transactions",
|
||||||
|
"Total Connected": "Total Connected",
|
||||||
|
"Total Customers": "Total Customers",
|
||||||
|
"Total items": "Total items: :count",
|
||||||
|
"Total Logins": "Total Logins",
|
||||||
|
"Transfer Audit": "Transfer Audit",
|
||||||
|
"Transfers": "Transfers",
|
||||||
|
"Type": "Type",
|
||||||
|
"UI Elements": "UI Elements",
|
||||||
|
"Unknown": "Unknown",
|
||||||
|
"Update": "Update",
|
||||||
|
"Update Customer": "Update Customer",
|
||||||
|
"Update existing role and permissions.": "Update existing role and permissions.",
|
||||||
|
"Update Password": "Update Password",
|
||||||
|
"Update your account's profile information and email address.": "Update your account's profile information and email address.",
|
||||||
|
"Upload New Images": "Upload New Images",
|
||||||
|
"Uploading new images will replace all existing images.": "Uploading new images will replace all existing images.",
|
||||||
|
"User": "User",
|
||||||
|
"User Info": "User Info",
|
||||||
|
"Username": "Username",
|
||||||
|
"Users": "Users",
|
||||||
|
"Utilization Rate": "Utilization Rate",
|
||||||
|
"Valid Until": "Valid Until",
|
||||||
|
"Venue Management": "Venue Management",
|
||||||
|
"View Details": "View Details",
|
||||||
|
"View Logs": "View Logs",
|
||||||
|
"vs Yesterday": "vs Yesterday",
|
||||||
|
"Warehouse List": "Warehouse List",
|
||||||
|
"Warehouse List (All)": "Warehouse List (All)",
|
||||||
|
"Warehouse List (Individual)": "Warehouse List (Individual)",
|
||||||
|
"Warehouse Management": "Warehouse Management",
|
||||||
|
"Warehouse Permissions": "Warehouse Permissions",
|
||||||
|
"warehouses": "Warehouse Management",
|
||||||
|
"Warning": "Warning",
|
||||||
|
"Warning: You are editing your own role!": "Warning: You are editing your own role!",
|
||||||
|
"Welcome Gift": "Welcome Gift",
|
||||||
|
"Yesterday": "Yesterday",
|
||||||
|
"You cannot assign permissions you do not possess.": "You cannot assign permissions you do not possess.",
|
||||||
|
"You cannot delete your own account.": "You cannot delete your own account.",
|
||||||
|
"Your email address is unverified.": "Your email address is unverified.",
|
||||||
|
"Your recent account activity": "Your recent account activity"
|
||||||
}
|
}
|
||||||
848
lang/ja.json
848
lang/ja.json
@@ -1,388 +1,480 @@
|
|||||||
{
|
{
|
||||||
"Account Settings": "アカウント設定",
|
"A new verification link has been sent to your email address.": "新しい確認リンクがメールアドレスに送信されました。",
|
||||||
"Manage your profile information, security settings, and login history": "プロフィール情報、セキュリティ設定、ログイン履歴の管理",
|
"Account created successfully.": "アカウントが正常に作成されました。",
|
||||||
"Profile Information": "プロフィール情報",
|
"Account deleted successfully.": "アカウントが正常に削除されました。",
|
||||||
"Update your account's profile information and email address.": "アカウントの氏名、電話番号、メールアドレスを更新します。",
|
|
||||||
"Update Password": "パスワードの更新",
|
|
||||||
"Ensure your account is using a long, random password to stay secure.": "セキュリティを維持するため、アカウントには長くランダムなパスワードを使用してください。",
|
|
||||||
"Delete Account": "アカウントの削除",
|
|
||||||
"Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.": "アカウントが削除されると、そのすべてのリソース和データが永久に削除されます。アカウントを削除する前に、保持したいデータや情報をダウンロードしてください。",
|
|
||||||
"Are you sure you want to delete your account?": "真的にアカウントを削除してもよろしいですか?",
|
|
||||||
"Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.": "アカウントが削除されると、すべての関連データが永久に削除されます。アカウントの永久削除を確定するため、パスワードを入力してください。",
|
|
||||||
"Login History": "ログイン履歴",
|
|
||||||
"Name": "氏名",
|
|
||||||
"Phone": "電話番号",
|
|
||||||
"Email": "メールアドレス",
|
|
||||||
"Current Password": "現在のパスワード",
|
|
||||||
"New Password": "新しいパスワード",
|
|
||||||
"Confirm Password": "新しいパスワード(確認)",
|
|
||||||
"Save": "変更を保存",
|
|
||||||
"Saved.": "保存されました",
|
|
||||||
"Update": "更新",
|
|
||||||
"Cancel": "キャンセル",
|
|
||||||
"Confirm": "確認",
|
|
||||||
"Danger Zone: Delete Account": "危険区域:アカウントの削除",
|
|
||||||
"Permanently Delete Account": "アカウントを永久に削除",
|
|
||||||
"Password": "パスワード",
|
|
||||||
"Enter your password to confirm": "確認のためパスワードを入力してください",
|
|
||||||
"Dashboard": "ダッシュボード",
|
|
||||||
"Connectivity Status": "接続ステータス概況",
|
|
||||||
"Real-time status monitoring": "リアルタイムステータス監視",
|
|
||||||
"LIVE": "ライブ",
|
|
||||||
"Online Machines": "オンライン機台",
|
|
||||||
"Offline Machines": "オフライン機台",
|
|
||||||
"Alerts Pending": "アラート待機中",
|
|
||||||
"Total Connected": "接続数合計",
|
|
||||||
"Monthly Transactions": "今月の取引統計",
|
|
||||||
"Monthly cumulative revenue overview": "今月の累計収益概要",
|
|
||||||
"Today's Transactions": "今日の取引額",
|
|
||||||
"vs Yesterday": "前日比",
|
|
||||||
"Yesterday": "昨日",
|
|
||||||
"Day Before": "一昨日",
|
|
||||||
"Machine Status List": "機台稼働状況リスト",
|
|
||||||
"Total items": "合計 :count 件",
|
|
||||||
"Real-time monitoring across all machines": "全機台のリアルタイム監視",
|
|
||||||
"Quick search...": "クイック検索...",
|
|
||||||
"Machine Info": "機台情報",
|
|
||||||
"Running Status": "稼働状況",
|
|
||||||
"Today Cumulative Sales": "本日累計販売",
|
|
||||||
"Current Stock": "現在の在庫",
|
|
||||||
"Last Signal": "最終信号時間",
|
|
||||||
"Alert Summary": "アラート概要",
|
|
||||||
"No alert summary": "アラートなし",
|
|
||||||
"No data available": "データなし",
|
|
||||||
"Showing :from to :to of :total items": ":total 件中 :from から :to 件を表示",
|
|
||||||
"Previous": "前へ",
|
|
||||||
"Next": "次へ",
|
|
||||||
"Profile Settings": "個人設定",
|
|
||||||
"Profile": "プロフィール",
|
|
||||||
"Member Management": "会員管理",
|
|
||||||
"Member List": "会員リスト",
|
|
||||||
"Membership Tiers": "会員ランク",
|
|
||||||
"Deposit Bonus": "入金ボーナス",
|
|
||||||
"Point Rules": "ポイントルール",
|
|
||||||
"Gift Definitions": "ギフト設定",
|
|
||||||
"Machine Management": "機台管理",
|
|
||||||
"Machine Logs": "機台ログ",
|
|
||||||
"Machine List": "機台リスト",
|
|
||||||
"Machine Permissions": "機台権限",
|
|
||||||
"Utilization Rate": "稼働率",
|
|
||||||
"Expiry Management": "有効期限管理",
|
|
||||||
"Maintenance Records": "メンテナンス記録",
|
|
||||||
"APP Management": "APP管理",
|
|
||||||
"UI Elements": "UI要素",
|
|
||||||
"Helper": "ヘルパー",
|
|
||||||
"Questionnaire": "アンケート",
|
|
||||||
"Games": "ゲーム",
|
|
||||||
"Timer": "タイマー",
|
|
||||||
"Warehouse Management": "倉庫管理",
|
|
||||||
"Warehouse List (All)": "倉庫リスト(全)",
|
|
||||||
"Warehouse List (Individual)": "倉庫リスト(個)",
|
|
||||||
"Stock Management": "在庫管理",
|
|
||||||
"Transfers": "転送",
|
|
||||||
"Purchases": "購入",
|
|
||||||
"Replenishments": "補充",
|
|
||||||
"Replenishment Records": "補充記録",
|
|
||||||
"Machine Stock": "機台在庫",
|
|
||||||
"Staff Stock": "スタッフ在庫",
|
|
||||||
"Returns": "返品",
|
|
||||||
"Sales Management": "販売管理",
|
|
||||||
"Sales Records": "販売記録",
|
|
||||||
"Pickup Codes": "受取コード",
|
|
||||||
"Orders": "注文",
|
|
||||||
"Promotions": "プロモーション",
|
|
||||||
"Pass Codes": "パスクード",
|
|
||||||
"Store Gifts": "来店特典",
|
|
||||||
"Analysis Management": "分析管理",
|
|
||||||
"Change Stock": "小銭在庫",
|
|
||||||
"Machine Reports": "機台レポート",
|
|
||||||
"Product Reports": "商品レポート",
|
|
||||||
"Survey Analysis": "アンケート分析",
|
|
||||||
"Audit Management": "監査管理",
|
|
||||||
"Purchase Audit": "購入監査",
|
|
||||||
"Transfer Audit": "転送監査",
|
|
||||||
"Replenishment Audit": "補充監査",
|
|
||||||
"Data Configuration": "データ設定",
|
|
||||||
"Product Management": "商品管理",
|
|
||||||
"Advertisement Management": "廣告管理",
|
|
||||||
"Admin Sellable Products": "管理者販売可能商品",
|
|
||||||
"Account Management": "アカウント管理",
|
"Account Management": "アカウント管理",
|
||||||
"Sub Accounts": "サブアカウント",
|
"Account Settings": "アカウント設定",
|
||||||
"Sub Account Roles": "サブアカウントロール",
|
|
||||||
"Point Settings": "ポイント設定",
|
|
||||||
"Badge Settings": "バッジ設定",
|
|
||||||
"Remote Management": "リモート管理",
|
|
||||||
"Machine Restart": "機台再起動",
|
|
||||||
"Card Reader Restart": "カードリーダー再起動",
|
|
||||||
"Remote Checkout": "リモート決済",
|
|
||||||
"Remote Lock": "リモートロック",
|
|
||||||
"Remote Change": "リモートお釣り",
|
|
||||||
"Remote Dispense": "リモート出庫",
|
|
||||||
"Line Management": "Line管理",
|
|
||||||
"Line Members": "Line会員",
|
|
||||||
"Line Machines": "Line機台",
|
|
||||||
"Line Products": "Line商品",
|
|
||||||
"Line Official Account": "Line公式アカウント",
|
|
||||||
"Line Orders": "Line注文",
|
|
||||||
"Line Coupons": "Lineクーポン",
|
|
||||||
"Reservation System": "予約システム",
|
|
||||||
"Reservation Members": "予約会員",
|
|
||||||
"Store Management": "店舗管理",
|
|
||||||
"Time Slots": "タイムスロット",
|
|
||||||
"Venue Management": "会場管理",
|
|
||||||
"Coupons": "クーポン",
|
|
||||||
"Reservations": "予約",
|
|
||||||
"Order Management": "注文管理",
|
|
||||||
"Special Permission": "特別権限",
|
|
||||||
"Clear Stock": "在庫クリア",
|
|
||||||
"APK Versions": "APKバージョン",
|
|
||||||
"Discord Notifications": "Discord通知",
|
|
||||||
"Basic Settings": "基本設定",
|
|
||||||
"Machine Settings": "機台設定",
|
|
||||||
"Permission Settings": "権限設定",
|
|
||||||
"APP Features": "APP機能",
|
|
||||||
"Others": "その他",
|
|
||||||
"AI Prediction": "AI予測",
|
|
||||||
"Roles": "ロール權限",
|
|
||||||
"Role Management": "ロール權限管理",
|
|
||||||
"Define and manage security roles and permissions.": "システムのセキュリティロールと権限を定義および管理します。",
|
|
||||||
"Search roles...": "ロールを検索...",
|
|
||||||
"No permissions": "権限項目なし",
|
|
||||||
"No roles found.": "ロールが見つかりませんでした。",
|
|
||||||
"Create Role": "ロール作成",
|
|
||||||
"Edit Role": "ロール編集",
|
|
||||||
"Update existing role and permissions.": "既存のロールと権限を更新します。",
|
|
||||||
"Create a new role and assign permissions.": "新しいロールを作成し、権限を割り当てます。",
|
|
||||||
"Enter role name": "ロール名を入力してください",
|
|
||||||
"Add Role": "ロールを追加",
|
|
||||||
"Role Name": "ロール名",
|
|
||||||
"Type": "タイプ",
|
|
||||||
"Permissions": "権限",
|
|
||||||
"Users": "ユーザー数",
|
|
||||||
"System role name cannot be modified.": "システムロール名は変更できません。",
|
|
||||||
"System Level": "システムレベル",
|
|
||||||
"Company Level": "顧客レベル",
|
|
||||||
"Menu Permissions": "メニュー権限",
|
|
||||||
"Save Changes": "変更を保存",
|
|
||||||
"members": "会員管理",
|
|
||||||
"machines": "機台管理",
|
|
||||||
"app": "APP管理",
|
|
||||||
"warehouses": "倉庫管理",
|
|
||||||
"sales": "販売管理",
|
|
||||||
"analysis": "分析管理",
|
|
||||||
"audit": "監査管理",
|
|
||||||
"data-config": "データ設定",
|
|
||||||
"remote": "リモート管理",
|
|
||||||
"line": "Line管理",
|
|
||||||
"reservation": "予約システム",
|
|
||||||
"special-permission": "特別権限",
|
|
||||||
"companies": "顧客管理",
|
|
||||||
"accounts": "アカウント管理",
|
|
||||||
"roles": "ロール權限",
|
|
||||||
"Role Permissions": "ロール權限",
|
|
||||||
"Role Settings": "ロール權限",
|
|
||||||
"No login history yet": "ログイン履歴はまだありません",
|
|
||||||
"Signed in as": "ログイン中",
|
|
||||||
"Logout": "ログアウト",
|
|
||||||
"Joined": "入会日",
|
|
||||||
"Recent Login": "最近のログイン",
|
|
||||||
"Total Logins": "總ログイン數",
|
|
||||||
"Account Status": "アカウント狀態",
|
"Account Status": "アカウント狀態",
|
||||||
"Active": "アクティブ",
|
"Account updated successfully.": "アカウントが正常に更新されました。",
|
||||||
"Customer Management": "顧客管理",
|
"accounts": "アカウント管理",
|
||||||
"Manage all tenant accounts and validity": "すべてのテナントアカウントと有効期限を管理します",
|
|
||||||
"Add Customer": "顧客を追加",
|
|
||||||
"Total Customers": "顧客總數",
|
|
||||||
"Expired / Disabled": "期限切れ / 停止中",
|
|
||||||
"Search customers...": "顧客を検索...",
|
|
||||||
"All": "すべて",
|
|
||||||
"Disabled": "停止中",
|
|
||||||
"Customer Info": "顧客情報",
|
|
||||||
"Accounts / Machines": "アカウント / 機台",
|
"Accounts / Machines": "アカウント / 機台",
|
||||||
"Valid Until": "有効期限",
|
|
||||||
"Actions": "操作",
|
|
||||||
"Permanent": "永久認可",
|
|
||||||
"Are you sure to delete this customer?": "この顧客を削除してもよろしいですか?",
|
|
||||||
"No customers found": "顧客が見つかりません",
|
|
||||||
"Edit Customer": "顧客を編集",
|
|
||||||
"Update Customer": "顧客を更新",
|
|
||||||
"Create": "作成",
|
|
||||||
"Company Name": "会社名",
|
|
||||||
"Company Code": "会社コード",
|
|
||||||
"Tax ID (Optional)": "納税者番号 (任意)",
|
|
||||||
"Status": "ステータス",
|
|
||||||
"Contact Name": "連絡担当者名",
|
|
||||||
"Contact Phone": "連絡先電話番号",
|
|
||||||
"Contact Email": "連絡先メールアドレス",
|
|
||||||
"Notes": "備考",
|
|
||||||
"Customer created successfully.": "顧客が正常に作成されました。",
|
|
||||||
"Customer updated successfully.": "顧客が正常に更新されました。",
|
|
||||||
"Customer deleted successfully.": "顧客が正常に削除されました。",
|
|
||||||
"Cannot delete company with active accounts.": "アクティブなアカウントを持つ会社は削除できません。",
|
|
||||||
"Contract Until (Optional)": "契約期限 (任意)",
|
|
||||||
"Company Information": "会社情報",
|
|
||||||
"Initial Admin Account": "初期管理者アカウント",
|
|
||||||
"Optional": "任意",
|
|
||||||
"Username": "ユーザー名",
|
|
||||||
"Enter login ID": "ログインIDを入力してください",
|
|
||||||
"Min 8 characters": "最低8文字",
|
|
||||||
"Admin display name": "管理者表示名",
|
|
||||||
"Initial Role": "初期ロール",
|
|
||||||
"Contact & Details": "連絡先と詳細",
|
|
||||||
"e.g. Taiwan Star": "例:台湾スター",
|
|
||||||
"e.g. TWSTAR": "例:TWSTAR",
|
|
||||||
"Manage administrative and tenant accounts": "管理者およびテナントアカウントを管理します",
|
|
||||||
"Add Account": "アカウントを追加",
|
|
||||||
"All Companies": "すべての会社",
|
|
||||||
"User Info": "ユーザー情報",
|
|
||||||
"Belongs To": "所属",
|
|
||||||
"Role": "ロール",
|
|
||||||
"SYSTEM": "システムレベル",
|
|
||||||
"No users found": "ユーザーが見つかりません",
|
|
||||||
"Data Configuration Permissions": "データ設定権限",
|
|
||||||
"Sales Permissions": "販売管理権限",
|
|
||||||
"Machine Management Permissions": "機台管理權限",
|
|
||||||
"Warehouse Permissions": "倉庫管理權限",
|
|
||||||
"Analysis Permissions": "分析管理權限",
|
|
||||||
"Audit Permissions": "監査管理權限",
|
|
||||||
"Remote Permissions": "リモート管理權限",
|
|
||||||
"Line Permissions": "Line管理權限",
|
|
||||||
"Company": "所属顧客",
|
|
||||||
"User": "一般ユーザー",
|
|
||||||
"Admin": "管理者",
|
|
||||||
"Super Admin": "スーパー管理者",
|
|
||||||
"e.g. John Doe": "例:山田太郎",
|
|
||||||
"e.g. johndoe": "例:yamadataro",
|
|
||||||
"Search users...": "ユーザーを検索...",
|
|
||||||
"Admin Name": "管理者名",
|
|
||||||
"New Password (leave blank to keep current)": "新しいパスワード (変更しない場合は空欄)",
|
|
||||||
"Are you sure you want to delete this account?": "このアカウントを削除してもよろしいですか?",
|
|
||||||
"Show": "表示",
|
|
||||||
"to": "から",
|
|
||||||
"of": "件中",
|
|
||||||
"items": "個の項目",
|
|
||||||
"Showing": "表示中",
|
|
||||||
"Monitor events and system activity across your vending fleet.": "自販機フリート全体のイベントとシステムアクティビティを監視します。",
|
|
||||||
"All Machines": "すべての機体",
|
|
||||||
"All Levels": "すべてのレベル",
|
|
||||||
"Timestamp": "タイムスタンプ",
|
|
||||||
"Message Content": "ログ内容",
|
|
||||||
"No matching logs found": "一致するログが見つかりません",
|
|
||||||
"Unknown": "不明",
|
|
||||||
"Info": "情報",
|
|
||||||
"Warning": "警告",
|
|
||||||
"basic-settings": "基本設定",
|
|
||||||
"permissions": "權限設定",
|
|
||||||
"Error": "エラー",
|
|
||||||
"Machine Model Settings": "機台型號設定",
|
|
||||||
"Machine Model": "機台型號",
|
|
||||||
"Model Name": "型號名称",
|
|
||||||
"Machine Count": "機台数量",
|
|
||||||
"Add Machine Model": "機台型號を追加",
|
|
||||||
"Edit Machine Model": "機台型號を編輯",
|
|
||||||
"Machine model created successfully.": "機台型號が正常に作成されました。",
|
|
||||||
"Machine model updated successfully.": "機台型號が正常に更新されました。",
|
|
||||||
"Machine model deleted successfully.": "機台型號が正常に削除されました。",
|
|
||||||
"Cannot delete model that is currently in use by machines.": "機台で使用中の型號は削除できません。",
|
|
||||||
"Machine Details": "機台詳情",
|
|
||||||
"Create Machine": "機台新規作成",
|
|
||||||
"Edit Machine": "機台編集",
|
|
||||||
"Basic Information": "基本情報",
|
|
||||||
"Location": "場所",
|
|
||||||
"Temperature": "温度",
|
|
||||||
"Firmware Version": "ファームウェアバージョン",
|
|
||||||
"Last Heartbeat": "最終ハートビート時間",
|
|
||||||
"Never Connected": "未接続",
|
|
||||||
"View Logs": "ログを表示",
|
|
||||||
"Real-time Operation Logs (Last 50)": "リアルタイム操作ログ (直近 50 件)",
|
|
||||||
"All Times System Timezone": "時間はすべてシステムタイムゾーンです",
|
|
||||||
"Level": "レベル",
|
|
||||||
"Logs": "ログ",
|
|
||||||
"Time": "時間",
|
|
||||||
"Message": "メッセージ",
|
|
||||||
"Online": "オンライン",
|
|
||||||
"Offline": "オフライン",
|
|
||||||
"Connecting...": "接続中...",
|
|
||||||
"No logs found": "ログがありません",
|
|
||||||
"Management of operational parameters and models": "運用パラメータと型番の管理",
|
|
||||||
"ECPay Invoice Settings Description": "ECPay 電子発票設定",
|
|
||||||
"E.SUN QR Scan Settings Description": "玉山銀行 QR スキャン決済設定",
|
|
||||||
"LINE Pay Direct Settings Description": "LINE Pay 公式直結設定",
|
|
||||||
"TapPay Integration Settings Description": "TapPay 決済連携設定",
|
|
||||||
"Merchant IDs": "マーチャント ID",
|
|
||||||
"Parameters": "パラメータ設定",
|
|
||||||
"Hardware & Network": "ハードウェアとネットワーク",
|
|
||||||
"Serial & Version": "シリアルとバージョン",
|
|
||||||
"Heartbeat": "ハートビート状態",
|
|
||||||
"Heating Range": "加熱時間帯",
|
|
||||||
"API Token": "API キー",
|
|
||||||
"No location set": "場所が未設定です",
|
|
||||||
"Close Panel": "パネルを閉じる",
|
|
||||||
"Operations": "運用設定",
|
|
||||||
"Operational Parameters": "運用パラメータ",
|
|
||||||
"Hardware & Slots": "ハードウェアと貨道",
|
|
||||||
"Slot Mechanism (default: Conveyor, check for Spring)": "貨道メカニズム (デフォルト:コンベア、チェックでスプリング)",
|
|
||||||
"Payment & Invoice": "決済と発票",
|
|
||||||
"Payment Config": "決済設定",
|
|
||||||
"Invoice Status": "発票発行状態",
|
|
||||||
"No Invoice": "発票を発行しない",
|
|
||||||
"Default Donate": "デフォルト寄付",
|
|
||||||
"Default Not Donate": "デフォルト寄付しない",
|
|
||||||
"Member & External": "会員と外部システム",
|
|
||||||
"Welcome Gift": "会員登録特典",
|
|
||||||
"Enabled/Disabled": "有効/無効",
|
|
||||||
"Member System": "会員システム",
|
|
||||||
"Machine Images": "機台写真",
|
|
||||||
"No images uploaded": "写真がアップロードされていません",
|
|
||||||
"Upload New Images": "新しい写真をアップロード",
|
|
||||||
"Max 3": "最大3枚",
|
|
||||||
"Uploading new images will replace all existing images.": "新しい写真をアップロードすると、既存のすべての写真が置き換えられます。",
|
|
||||||
"Search machines...": "機台を検索...",
|
|
||||||
"Search models...": "型番を検索...",
|
|
||||||
"Card Reader": "カードリーダー",
|
|
||||||
"Owner": "所属会社",
|
|
||||||
"Action": "操作",
|
"Action": "操作",
|
||||||
"Items": "個の項目",
|
"Actions": "操作",
|
||||||
"View Details": "詳細表示",
|
"Active": "アクティブ",
|
||||||
"Edit Settings": "設定編集",
|
"Add Account": "アカウントを追加",
|
||||||
"Are you sure?": "よろしいですか?",
|
"Add Customer": "顧客を追加",
|
||||||
"Serial No": "機台シリアル番号",
|
"Add Machine": "機台を追加",
|
||||||
"Select Owner": "所属会社を選択",
|
"Add Machine Model": "機台型號を追加",
|
||||||
"Select Model": "型番を選択",
|
"Add Role": "ロールを追加",
|
||||||
"Machines": "機台リスト",
|
"Admin": "管理者",
|
||||||
"Models": "型番リスト",
|
"Admin display name": "管理者表示名",
|
||||||
"Edit": "編集",
|
"Admin Name": "管理者名",
|
||||||
"Delete": "削除",
|
"Admin Sellable Products": "管理者販売可能商品",
|
||||||
"None": "なし",
|
"Administrator": "管理者",
|
||||||
"Create Payment Config": "決済設定を新規作成",
|
"Advertisement Management": "廣告管理",
|
||||||
"Edit Payment Config": "決済設定を編集",
|
"Affiliation": "所属",
|
||||||
"Define new third-party payment parameters": "新しいサードパーティ決済パラメータを定義",
|
"AI Prediction": "AI予測",
|
||||||
"Configuration Name": "設定名称",
|
"Alert Summary": "アラート概要",
|
||||||
"Belongs To Company": "所属会社",
|
"Alerts Pending": "アラート待機中",
|
||||||
"Select Company": "会社を選択",
|
"All": "すべて",
|
||||||
"ECPay Invoice": "ECPay 電子発票",
|
"All Affiliations": "全ての所属",
|
||||||
"Store ID": "加盟店ID (MerchantID)",
|
"All Companies": "すべての会社",
|
||||||
"HashKey": "HashKey",
|
"All Levels": "すべてのレベル",
|
||||||
"HashIV": "HashIV",
|
"All Machines": "すべての機体",
|
||||||
"E.SUN QR Scan": "玉山銀行 QR スキャン",
|
"All Times System Timezone": "時間はすべてシステムタイムゾーンです",
|
||||||
"StoreID": "加盟店ID (StoreID)",
|
"analysis": "分析管理",
|
||||||
"TermID": "端末ID (TermID)",
|
"Analysis Management": "分析管理",
|
||||||
"Key": "キー (Key)",
|
"Analysis Permissions": "分析管理權限",
|
||||||
"LINE Pay Direct": "LINE Pay 直結決済",
|
"API Token": "API キー",
|
||||||
"ChannelId": "チャンネルID",
|
"APK Versions": "APKバージョン",
|
||||||
"ChannelSecret": "チャンネルシークレット",
|
"app": "APP管理",
|
||||||
"TapPay Integration": "TapPay 統合決済",
|
"APP Features": "APP機能",
|
||||||
"PARTNER_KEY": "パートナーキー",
|
"APP Management": "APP管理",
|
||||||
"APP_ID": "APP_ID",
|
"APP_ID": "APP_ID",
|
||||||
"APP_KEY": "APP_KEY",
|
"APP_KEY": "APP_KEY",
|
||||||
"LINE_MERCHANT_ID": "LINE Pay 加盟店ID",
|
"Are you sure to delete this customer?": "この顧客を削除してもよろしいですか?",
|
||||||
"JKO_MERCHANT_ID": "街口支付 加盟店ID",
|
"Are you sure you want to delete this account?": "このアカウントを削除してもよろしいですか?",
|
||||||
"PI_MERCHANT_ID": "Pi 拍錢包 加盟店ID",
|
"Are you sure you want to delete this account? This action cannot be undone.": "このアカウントを削除してもよろしいですか?この操作は元に戻せません。",
|
||||||
"PS_MERCHANT_ID": "全盈+Pay 加盟店ID",
|
"Are you sure you want to delete this configuration? This action cannot be undone.": "この設定を削除してもよろしいですか?この操作は元に戻せません。",
|
||||||
"EASY_MERCHANT_ID": "悠遊付 加盟店ID",
|
"Are you sure you want to delete this item? This action cannot be undone.": "この項目を削除してもよろしいですか?この操作は元に戻せません。",
|
||||||
"Save Config": "設定を保存",
|
"Are you sure you want to delete this role? This action cannot be undone.": "このロールを削除してもよろしいですか?この操作は元に戻せません。",
|
||||||
|
"Are you sure you want to delete your account?": "真的にアカウントを削除してもよろしいですか?",
|
||||||
|
"Are you sure?": "よろしいですか?",
|
||||||
|
"audit": "監査管理",
|
||||||
|
"Audit Management": "監査管理",
|
||||||
|
"Audit Permissions": "監査管理權限",
|
||||||
|
"Avatar updated successfully.": "アバターが正常に更新されました。",
|
||||||
|
"Badge Settings": "バッジ設定",
|
||||||
|
"Basic Information": "基本情報",
|
||||||
|
"Basic Settings": "基本設定",
|
||||||
|
"basic-settings": "基本設定",
|
||||||
|
"Belongs To": "所属",
|
||||||
|
"Belongs To Company": "所属会社",
|
||||||
|
"Cancel": "キャンセル",
|
||||||
|
"Cannot delete company with active accounts.": "アクティブなアカウントを持つ会社は削除できません。",
|
||||||
|
"Cannot delete model that is currently in use by machines.": "機台で使用中の型號は削除できません。",
|
||||||
|
"Cannot Delete Role": "ロールを削除できません",
|
||||||
|
"Cannot delete role with active users.": "アクティブなユーザーがいるロールは削除できません。",
|
||||||
|
"Card Reader": "カードリーダー",
|
||||||
|
"Card Reader No": "カードリーダー番号",
|
||||||
|
"Card Reader Restart": "カードリーダー再起動",
|
||||||
|
"Card Reader Seconds": "カードリーダー秒数",
|
||||||
|
"Change": "変更",
|
||||||
|
"Change Stock": "小銭在庫",
|
||||||
|
"ChannelId": "チャンネルID",
|
||||||
|
"ChannelSecret": "チャンネルシークレット",
|
||||||
|
"Checkout Time 1": "決済時間 1",
|
||||||
|
"Checkout Time 2": "決済時間 2",
|
||||||
|
"Clear Stock": "在庫クリア",
|
||||||
|
"Click here to re-send the verification email.": "確認メールを再送信するにはここをクリックしてください。",
|
||||||
|
"Click to upload": "クリックしてアップロード",
|
||||||
|
"Close Panel": "パネルを閉じる",
|
||||||
|
"companies": "顧客管理",
|
||||||
|
"Company": "所属顧客",
|
||||||
|
"Company Code": "会社コード",
|
||||||
|
"Company Information": "会社情報",
|
||||||
|
"Company Level": "顧客レベル",
|
||||||
|
"Company Name": "会社名",
|
||||||
|
"Configuration Name": "設定名称",
|
||||||
|
"Confirm": "確認",
|
||||||
|
"Confirm Deletion": "削除の確認",
|
||||||
|
"Confirm Password": "新しいパスワード(確認)",
|
||||||
|
"Connecting...": "接続中...",
|
||||||
|
"Connectivity Status": "接続ステータス概況",
|
||||||
|
"Contact & Details": "連絡先と詳細",
|
||||||
|
"Contact Email": "連絡先メールアドレス",
|
||||||
|
"Contact Name": "連絡担当者名",
|
||||||
|
"Contact Phone": "連絡先電話番号",
|
||||||
|
"Contract Until (Optional)": "契約期限 (任意)",
|
||||||
|
"Coupons": "クーポン",
|
||||||
|
"Create": "作成",
|
||||||
|
"Create a new role and assign permissions.": "新しいロールを作成し、権限を割り当てます。",
|
||||||
|
"Create Config": "設定を新規作成",
|
||||||
|
"Create Machine": "機台新規作成",
|
||||||
|
"Create Payment Config": "決済設定を新規作成",
|
||||||
|
"Create Role": "ロール作成",
|
||||||
|
"Current Password": "現在のパスワード",
|
||||||
|
"Current Stock": "現在の在庫",
|
||||||
|
"Customer created successfully.": "顧客が正常に作成されました。",
|
||||||
|
"Customer deleted successfully.": "顧客が正常に削除されました。",
|
||||||
|
"Customer Info": "顧客情報",
|
||||||
|
"Customer Management": "顧客管理",
|
||||||
|
"Customer Payment Config": "決済設定管理",
|
||||||
|
"Customer updated successfully.": "顧客が正常に更新されました。",
|
||||||
|
"Danger Zone: Delete Account": "危険区域:アカウントの削除",
|
||||||
|
"Dashboard": "ダッシュボード",
|
||||||
|
"Data Configuration": "データ設定",
|
||||||
|
"Data Configuration Permissions": "データ設定権限",
|
||||||
|
"data-config": "データ設定",
|
||||||
|
"Day Before": "一昨日",
|
||||||
|
"Default Donate": "デフォルト寄付",
|
||||||
|
"Default Not Donate": "デフォルト寄付しない",
|
||||||
|
"Define and manage security roles and permissions.": "システムのセキュリティロールと権限を定義および管理します。",
|
||||||
|
"Define new third-party payment parameters": "新しいサードパーティ決済パラメータを定義",
|
||||||
|
"Delete": "削除",
|
||||||
|
"Delete Account": "アカウントの削除",
|
||||||
|
"Delete Permanently": "完全に削除",
|
||||||
|
"Deposit Bonus": "入金ボーナス",
|
||||||
|
"Detail": "詳細",
|
||||||
|
"Disabled": "停止中",
|
||||||
|
"Discord Notifications": "Discord通知",
|
||||||
|
"e.g. John Doe": "例:山田太郎",
|
||||||
|
"e.g. johndoe": "例:yamadataro",
|
||||||
|
"e.g. Taiwan Star": "例:台湾スター",
|
||||||
|
"e.g. TWSTAR": "例:TWSTAR",
|
||||||
"e.g., Company Standard Pay": "例:標準決済組合せ",
|
"e.g., Company Standard Pay": "例:標準決済組合せ",
|
||||||
"Photo Slot": "写真スロット",
|
"e.g., Taipei Station": "例:台北駅",
|
||||||
|
"E.SUN QR Scan": "玉山銀行 QR スキャン",
|
||||||
|
"E.SUN QR Scan Settings Description": "玉山銀行 QR スキャン決済設定",
|
||||||
|
"EASY_MERCHANT_ID": "悠遊付 加盟店ID",
|
||||||
|
"ECPay Invoice": "ECPay 電子発票",
|
||||||
|
"ECPay Invoice Settings Description": "ECPay 電子発票設定",
|
||||||
|
"Edit": "編集",
|
||||||
|
"Edit Account": "アカウントを編集",
|
||||||
|
"Edit Customer": "顧客を編集",
|
||||||
|
"Edit Machine": "機台編集",
|
||||||
|
"Edit Machine Model": "機台型號を編輯",
|
||||||
|
"Edit Payment Config": "決済設定を編集",
|
||||||
|
"Edit Role": "ロール編集",
|
||||||
|
"Edit Settings": "設定編集",
|
||||||
|
"Email": "メールアドレス",
|
||||||
|
"Enabled/Disabled": "有効/無効",
|
||||||
|
"Ensure your account is using a long, random password to stay secure.": "セキュリティを維持するため、アカウントには長くランダムなパスワードを使用してください。",
|
||||||
|
"Enter login ID": "ログインIDを入力してください",
|
||||||
|
"Enter machine location": "機台の場所を入力してください",
|
||||||
|
"Enter machine name": "機台名を入力してください",
|
||||||
|
"Enter model name": "型番名を入力してください",
|
||||||
|
"Enter role name": "ロール名を入力してください",
|
||||||
|
"Enter serial number": "シリアル番号を入力してください",
|
||||||
|
"Enter your password to confirm": "確認のためパスワードを入力してください",
|
||||||
|
"Error": "エラー",
|
||||||
|
"Expired / Disabled": "期限切れ / 停止中",
|
||||||
|
"Expiry Management": "有効期限管理",
|
||||||
|
"Failed to update machine images: ": "機台画像の更新に失敗しました:",
|
||||||
|
"files selected": "ファイルを選択済み",
|
||||||
|
"Firmware Version": "ファームウェアバージョン",
|
||||||
|
"Full Name": "氏名",
|
||||||
|
"Games": "ゲーム",
|
||||||
|
"Gift Definitions": "ギフト設定",
|
||||||
|
"Got it": "了解",
|
||||||
|
"Hardware & Network": "ハードウェアとネットワーク",
|
||||||
|
"Hardware & Slots": "ハードウェアと貨道",
|
||||||
|
"HashIV": "HashIV",
|
||||||
|
"HashKey": "HashKey",
|
||||||
|
"Heartbeat": "ハートビート状態",
|
||||||
|
"Heating End Time": "加熱終了時間",
|
||||||
|
"Heating Range": "加熱時間帯",
|
||||||
|
"Heating Start Time": "加熱開始時間",
|
||||||
|
"Helper": "ヘルパー",
|
||||||
|
"Info": "情報",
|
||||||
|
"Initial Admin Account": "初期管理者アカウント",
|
||||||
|
"Initial Role": "初期ロール",
|
||||||
|
"Invoice Status": "発票発行状態",
|
||||||
|
"items": "個の項目",
|
||||||
|
"Items": "個の項目",
|
||||||
|
"JKO_MERCHANT_ID": "街口支付 加盟店ID",
|
||||||
|
"john@example.com": "john@example.com",
|
||||||
|
"Joined": "入会日",
|
||||||
|
"Key": "キー (Key)",
|
||||||
|
"Key No": "キー番号",
|
||||||
|
"Last Heartbeat": "最終ハートビート時間",
|
||||||
|
"Last Signal": "最終信号時間",
|
||||||
|
"Last Updated": "最終更新",
|
||||||
|
"Level": "レベル",
|
||||||
|
"line": "Line管理",
|
||||||
|
"Line Coupons": "Lineクーポン",
|
||||||
|
"Line Machines": "Line機台",
|
||||||
|
"Line Management": "Line管理",
|
||||||
|
"Line Members": "Line会員",
|
||||||
|
"Line Official Account": "Line公式アカウント",
|
||||||
|
"Line Orders": "Line注文",
|
||||||
|
"LINE Pay Direct": "LINE Pay 直結決済",
|
||||||
|
"LINE Pay Direct Settings Description": "LINE Pay 公式直結設定",
|
||||||
|
"Line Permissions": "Line管理權限",
|
||||||
|
"Line Products": "Line商品",
|
||||||
|
"LINE_MERCHANT_ID": "LINE Pay 加盟店ID",
|
||||||
|
"LIVE": "ライブ",
|
||||||
|
"Location": "場所",
|
||||||
|
"Login History": "ログイン履歴",
|
||||||
|
"Logout": "ログアウト",
|
||||||
|
"Logs": "ログ",
|
||||||
|
"Machine Count": "機台数量",
|
||||||
|
"Machine created successfully.": "機台が正常に作成されました。",
|
||||||
|
"Machine Details": "機台詳情",
|
||||||
|
"Machine Images": "機台写真",
|
||||||
|
"Machine images updated successfully.": "機台画像が正常に更新されました。",
|
||||||
|
"Machine Info": "機台情報",
|
||||||
|
"Machine List": "機台リスト",
|
||||||
|
"Machine Logs": "機台ログ",
|
||||||
|
"Machine Management": "機台管理",
|
||||||
|
"Machine Management Permissions": "機台管理權限",
|
||||||
|
"Machine Model": "機台型號",
|
||||||
|
"Machine model created successfully.": "機台型號が正常に作成されました。",
|
||||||
|
"Machine model deleted successfully.": "機台型號が正常に削除されました。",
|
||||||
|
"Machine Model Settings": "機台型號設定",
|
||||||
|
"Machine model updated successfully.": "機台型號が正常に更新されました。",
|
||||||
|
"Machine Name": "機台名",
|
||||||
|
"Machine Permissions": "機台権限",
|
||||||
|
"Machine Reports": "機台レポート",
|
||||||
|
"Machine Restart": "機台再起動",
|
||||||
|
"Machine Settings": "機台設定",
|
||||||
|
"Machine settings updated successfully.": "機台設定が正常に更新されました。",
|
||||||
|
"Machine Status List": "機台稼働状況リスト",
|
||||||
|
"Machine Stock": "機台在庫",
|
||||||
|
"machines": "機台管理",
|
||||||
|
"Machines": "機台リスト",
|
||||||
|
"Maintenance Records": "メンテナンス記録",
|
||||||
|
"Manage administrative and tenant accounts": "管理者およびテナントアカウントを管理します",
|
||||||
|
"Manage all tenant accounts and validity": "すべてのテナントアカウントと有効期限を管理します",
|
||||||
|
"Manage your profile information, security settings, and login history": "プロフィール情報、セキュリティ設定、ログイン履歴の管理",
|
||||||
|
"Management of operational parameters and models": "運用パラメータと型番の管理",
|
||||||
|
"Max 3": "最大3枚",
|
||||||
|
"Member & External": "会員と外部システム",
|
||||||
|
"Member List": "会員リスト",
|
||||||
|
"Member Management": "会員管理",
|
||||||
|
"Member System": "会員システム",
|
||||||
|
"members": "会員管理",
|
||||||
|
"Membership Tiers": "会員ランク",
|
||||||
|
"Menu Permissions": "メニュー権限",
|
||||||
|
"Merchant IDs": "マーチャント ID",
|
||||||
|
"Merchant payment gateway settings management": "マーチャント決済ゲートウェイ設定管理",
|
||||||
|
"Message": "メッセージ",
|
||||||
|
"Message Content": "ログ内容",
|
||||||
|
"Min 8 characters": "最低8文字",
|
||||||
|
"Model": "型番",
|
||||||
|
"Model Name": "型號名称",
|
||||||
|
"Models": "型番リスト",
|
||||||
|
"Modifying your own administrative permissions may result in losing access to certain system functions.": "自身の管理權限を変更すると、一部のシステム機能へのアクセス權を失う可能性があります。",
|
||||||
|
"Monitor events and system activity across your vending fleet.": "自販機フリート全体のイベントとシステムアクティビティを監視します。",
|
||||||
|
"Monthly cumulative revenue overview": "今月の累計収益概要",
|
||||||
|
"Monthly Transactions": "今月の取引統計",
|
||||||
|
"Name": "氏名",
|
||||||
|
"Never Connected": "未接続",
|
||||||
|
"New Password": "新しいパスワード",
|
||||||
|
"New Password (leave blank to keep current)": "新しいパスワード (変更しない場合は空欄)",
|
||||||
|
"Next": "次へ",
|
||||||
|
"No accounts found": "アカウントが見つかりません",
|
||||||
|
"No alert summary": "アラートなし",
|
||||||
|
"No configurations found": "設定が見つかりません",
|
||||||
|
"No customers found": "顧客が見つかりません",
|
||||||
|
"No data available": "データなし",
|
||||||
|
"No file uploaded.": "ファイルがアップロードされていません。",
|
||||||
|
"No images uploaded": "写真がアップロードされていません",
|
||||||
|
"No Invoice": "発票を発行しない",
|
||||||
|
"No location set": "場所が未設定です",
|
||||||
|
"No login history yet": "ログイン履歴はまだありません",
|
||||||
|
"No logs found": "ログがありません",
|
||||||
|
"No matching logs found": "一致するログが見つかりません",
|
||||||
|
"No permissions": "権限項目なし",
|
||||||
|
"No roles found.": "ロールが見つかりませんでした。",
|
||||||
|
"No users found": "ユーザーが見つかりません",
|
||||||
|
"None": "なし",
|
||||||
|
"Not Used": "未使用",
|
||||||
|
"Notes": "備考",
|
||||||
|
"of": "件中",
|
||||||
|
"Offline": "オフライン",
|
||||||
|
"Offline Machines": "オフライン機台",
|
||||||
|
"Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.": "アカウントが削除されると、そのすべてのリソース和データが永久に削除されます。アカウントを削除する前に、保持したいデータや情報をダウンロードしてください。",
|
||||||
|
"Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.": "アカウントが削除されると、すべての関連データが永久に削除されます。アカウントの永久削除を確定するため、パスワードを入力してください。",
|
||||||
|
"Online": "オンライン",
|
||||||
|
"Online Machines": "オンライン機台",
|
||||||
|
"Only system roles can be assigned to platform administrative accounts.": "プラットフォーム管理アカウントにはシステムロールのみ割り当て可能です。",
|
||||||
|
"Operational Parameters": "運用パラメータ",
|
||||||
|
"Operations": "運用設定",
|
||||||
"Optimized for display. Supported formats: JPG, PNG, WebP.": "表示用に最適化されています。対応形式:JPG, PNG, WebP。",
|
"Optimized for display. Supported formats: JPG, PNG, WebP.": "表示用に最適化されています。対応形式:JPG, PNG, WebP。",
|
||||||
"Change": "変更"
|
"Optional": "任意",
|
||||||
|
"Order Management": "注文管理",
|
||||||
|
"Orders": "注文",
|
||||||
|
"Others": "その他",
|
||||||
|
"Owner": "所属会社",
|
||||||
|
"Parameters": "パラメータ設定",
|
||||||
|
"PARTNER_KEY": "パートナーキー",
|
||||||
|
"Pass Codes": "パスクード",
|
||||||
|
"Password": "パスワード",
|
||||||
|
"Payment & Invoice": "決済と発票",
|
||||||
|
"Payment Buffer Seconds": "決済バッファ秒数",
|
||||||
|
"Payment Config": "決済設定",
|
||||||
|
"Payment Configuration": "決済設定",
|
||||||
|
"Payment Configuration created successfully.": "決済設定が正常に作成されました。",
|
||||||
|
"Payment Configuration deleted successfully.": "決済設定が正常に削除されました。",
|
||||||
|
"Payment Configuration updated successfully.": "決済設定が正常に更新されました。",
|
||||||
|
"Permanent": "永久認可",
|
||||||
|
"Permanently Delete Account": "アカウントを永久に削除",
|
||||||
|
"Permission Settings": "権限設定",
|
||||||
|
"Permissions": "権限",
|
||||||
|
"permissions": "權限設定",
|
||||||
|
"Phone": "電話番号",
|
||||||
|
"Photo Slot": "写真スロット",
|
||||||
|
"PI_MERCHANT_ID": "Pi 拍錢包 加盟店ID",
|
||||||
|
"Pickup Codes": "受取コード",
|
||||||
|
"Please check the following errors:": "以下のエラーを確認してください:",
|
||||||
|
"Please check the form for errors.": "フォームにエラーがないか確認してください。",
|
||||||
|
"Point Rules": "ポイントルール",
|
||||||
|
"Point Settings": "ポイント設定",
|
||||||
|
"Previous": "前へ",
|
||||||
|
"Product Management": "商品管理",
|
||||||
|
"Product Reports": "商品レポート",
|
||||||
|
"Profile": "プロフィール",
|
||||||
|
"Profile Information": "プロフィール情報",
|
||||||
|
"Profile Settings": "個人設定",
|
||||||
|
"Profile updated successfully.": "プロフィールが正常に更新されました。",
|
||||||
|
"Promotions": "プロモーション",
|
||||||
|
"Protected": "保護されています",
|
||||||
|
"PS_MERCHANT_ID": "全盈+Pay 加盟店ID",
|
||||||
|
"Purchase Audit": "購入監査",
|
||||||
|
"Purchases": "購入",
|
||||||
|
"Questionnaire": "アンケート",
|
||||||
|
"Quick search...": "クイック検索...",
|
||||||
|
"Real-time monitoring across all machines": "全機台のリアルタイム監視",
|
||||||
|
"Real-time Operation Logs (Last 50)": "リアルタイム操作ログ (直近 50 件)",
|
||||||
|
"Real-time status monitoring": "リアルタイムステータス監視",
|
||||||
|
"Recent Login": "最近のログイン",
|
||||||
|
"remote": "リモート管理",
|
||||||
|
"Remote Change": "リモートお釣り",
|
||||||
|
"Remote Checkout": "リモート決済",
|
||||||
|
"Remote Dispense": "リモート出庫",
|
||||||
|
"Remote Lock": "リモートロック",
|
||||||
|
"Remote Management": "リモート管理",
|
||||||
|
"Remote Permissions": "リモート管理權限",
|
||||||
|
"Replenishment Audit": "補充監査",
|
||||||
|
"Replenishment Records": "補充記録",
|
||||||
|
"Replenishments": "補充",
|
||||||
|
"reservation": "予約システム",
|
||||||
|
"Reservation Members": "予約会員",
|
||||||
|
"Reservation System": "予約システム",
|
||||||
|
"Reservations": "予約",
|
||||||
|
"Returns": "返品",
|
||||||
|
"Role": "ロール",
|
||||||
|
"Role created successfully.": "ロールが正常に作成されました。",
|
||||||
|
"Role deleted successfully.": "ロールが正常に削除されました。",
|
||||||
|
"Role Management": "ロール權限管理",
|
||||||
|
"Role Name": "ロール名",
|
||||||
|
"Role name already exists in this company.": "この会社には同じ名前のロールが既に存在します。",
|
||||||
|
"Role not found.": "ロールが見つかりませんでした。",
|
||||||
|
"Role Permissions": "ロール權限",
|
||||||
|
"Role Settings": "ロール權限",
|
||||||
|
"Role Type": "ロールタイプ",
|
||||||
|
"Role updated successfully.": "ロールが正常に更新されました。",
|
||||||
|
"Roles": "ロール權限",
|
||||||
|
"roles": "ロール權限",
|
||||||
|
"Running Status": "稼働状況",
|
||||||
|
"sales": "販売管理",
|
||||||
|
"Sales Management": "販売管理",
|
||||||
|
"Sales Permissions": "販売管理権限",
|
||||||
|
"Sales Records": "販売記録",
|
||||||
|
"Save": "変更を保存",
|
||||||
|
"Save Changes": "変更を保存",
|
||||||
|
"Save Config": "設定を保存",
|
||||||
|
"Saved.": "保存されました",
|
||||||
|
"Search configurations...": "設定を検索...",
|
||||||
|
"Search customers...": "顧客を検索...",
|
||||||
|
"Search machines...": "機台を検索...",
|
||||||
|
"Search models...": "型番を検索...",
|
||||||
|
"Search roles...": "ロールを検索...",
|
||||||
|
"Search users...": "ユーザーを検索...",
|
||||||
|
"Select Company": "会社を選択",
|
||||||
|
"Select Model": "型番を選択",
|
||||||
|
"Select Owner": "所属会社を選択",
|
||||||
|
"Serial & Version": "シリアルとバージョン",
|
||||||
|
"Serial No": "機台シリアル番号",
|
||||||
|
"Serial Number": "シリアル番号",
|
||||||
|
"Show": "表示",
|
||||||
|
"Showing": "表示中",
|
||||||
|
"Showing :from to :to of :total items": ":total 件中 :from から :to 件を表示",
|
||||||
|
"Sign in to your account": "アカウントにサインイン",
|
||||||
|
"Signed in as": "ログイン中",
|
||||||
|
"Slot Mechanism (default: Conveyor, check for Spring)": "貨道メカニズム (デフォルト:コンベア、チェックでスプリング)",
|
||||||
|
"Some fields need attention": "一部のフィールドに注意が必要です",
|
||||||
|
"Special Permission": "特別権限",
|
||||||
|
"special-permission": "特別権限",
|
||||||
|
"Staff Stock": "スタッフ在庫",
|
||||||
|
"Status": "ステータス",
|
||||||
|
"Stock Management": "在庫管理",
|
||||||
|
"Store Gifts": "来店特典",
|
||||||
|
"Store ID": "加盟店ID (MerchantID)",
|
||||||
|
"Store Management": "店舗管理",
|
||||||
|
"StoreID": "加盟店ID (StoreID)",
|
||||||
|
"Sub Account Management": "サブアカウント管理",
|
||||||
|
"Sub Account Roles": "サブアカウントロール",
|
||||||
|
"Sub Accounts": "サブアカウント",
|
||||||
|
"Success": "成功",
|
||||||
|
"Super Admin": "スーパー管理者",
|
||||||
|
"Super-admin role cannot be assigned to tenant accounts.": "スーパー管理者ロールはテナントアカウントに割り当てることはできません。",
|
||||||
|
"Survey Analysis": "アンケート分析",
|
||||||
|
"SYSTEM": "システムレベル",
|
||||||
|
"System Level": "システムレベル",
|
||||||
|
"System Role": "システムロール",
|
||||||
|
"System role name cannot be modified.": "システムロール名は変更できません。",
|
||||||
|
"System roles cannot be deleted by tenant administrators.": "テナント管理者はシステムロールを削除できません。",
|
||||||
|
"System roles cannot be modified by tenant administrators.": "テナント管理者はシステムロールを変更できません。",
|
||||||
|
"System super admin accounts cannot be deleted.": "システムスーパー管理者アカウントは削除できません。",
|
||||||
|
"System super admin accounts cannot be modified via this interface.": "システムスーパー管理者アカウントはこのインターフェースからは変更できません。",
|
||||||
|
"Systems Initializing": "システム初期化中",
|
||||||
|
"TapPay Integration": "TapPay 統合決済",
|
||||||
|
"TapPay Integration Settings Description": "TapPay 決済連携設定",
|
||||||
|
"Tax ID (Optional)": "納税者番号 (任意)",
|
||||||
|
"Temperature": "温度",
|
||||||
|
"TermID": "端末ID (TermID)",
|
||||||
|
"The image is too large. Please upload an image smaller than 1MB.": "画像が大きすぎます。1MB未満の画像をアップロードしてください。",
|
||||||
|
"The Super Admin role cannot be deleted.": "スーパー管理者ロールは削除できません。",
|
||||||
|
"The Super Admin role is immutable.": "スーパー管理者ロールは変更できません。",
|
||||||
|
"The Super Admin role name cannot be modified.": "スーパー管理者のロール名は変更できません。",
|
||||||
|
"This role belongs to another company and cannot be assigned.": "このロールは他の会社に属しており、割り当てることはできません。",
|
||||||
|
"Time": "時間",
|
||||||
|
"Time Slots": "タイムスロット",
|
||||||
|
"Timer": "タイマー",
|
||||||
|
"Timestamp": "タイムスタンプ",
|
||||||
|
"to": "から",
|
||||||
|
"Today Cumulative Sales": "本日累計販売",
|
||||||
|
"Today's Transactions": "今日の取引額",
|
||||||
|
"Total Connected": "接続数合計",
|
||||||
|
"Total Customers": "顧客總數",
|
||||||
|
"Total items": "合計 :count 件",
|
||||||
|
"Total Logins": "總ログイン數",
|
||||||
|
"Transfer Audit": "転送監査",
|
||||||
|
"Transfers": "転送",
|
||||||
|
"Type": "タイプ",
|
||||||
|
"UI Elements": "UI要素",
|
||||||
|
"Unknown": "不明",
|
||||||
|
"Update": "更新",
|
||||||
|
"Update Customer": "顧客を更新",
|
||||||
|
"Update existing role and permissions.": "既存のロールと権限を更新します。",
|
||||||
|
"Update Password": "パスワードの更新",
|
||||||
|
"Update your account's profile information and email address.": "アカウントの氏名、電話番号、メールアドレスを更新します。",
|
||||||
|
"Upload New Images": "新しい写真をアップロード",
|
||||||
|
"Uploading new images will replace all existing images.": "新しい写真をアップロードすると、既存のすべての写真が置き換えられます。",
|
||||||
|
"User": "一般ユーザー",
|
||||||
|
"User Info": "ユーザー情報",
|
||||||
|
"Username": "ユーザー名",
|
||||||
|
"Users": "ユーザー数",
|
||||||
|
"Utilization Rate": "稼働率",
|
||||||
|
"Valid Until": "有効期限",
|
||||||
|
"Venue Management": "会場管理",
|
||||||
|
"View Details": "詳細表示",
|
||||||
|
"View Logs": "ログを表示",
|
||||||
|
"vs Yesterday": "前日比",
|
||||||
|
"Warehouse List": "倉庫リスト",
|
||||||
|
"Warehouse List (All)": "倉庫リスト(全)",
|
||||||
|
"Warehouse List (Individual)": "倉庫リスト(個)",
|
||||||
|
"Warehouse Management": "倉庫管理",
|
||||||
|
"Warehouse Permissions": "倉庫管理權限",
|
||||||
|
"warehouses": "倉庫管理",
|
||||||
|
"Warning": "警告",
|
||||||
|
"Warning: You are editing your own role!": "警告:現在使用中のロールを編集しています!",
|
||||||
|
"Welcome Gift": "会員登録特典",
|
||||||
|
"Yesterday": "昨日",
|
||||||
|
"You cannot assign permissions you do not possess.": "ご自身が所有していない権限を割り當てることはできません。",
|
||||||
|
"You cannot delete your own account.": "ご自身のアカウントは削除できません。",
|
||||||
|
"Your email address is unverified.": "メールアドレスが未確認です。",
|
||||||
|
"Your recent account activity": "最近のアカウントアクティビティ"
|
||||||
}
|
}
|
||||||
889
lang/zh_TW.json
889
lang/zh_TW.json
@@ -1,419 +1,494 @@
|
|||||||
{
|
{
|
||||||
"Account Settings": "帳戶設定",
|
"A new verification link has been sent to your email address.": "已將新的驗證連結發送至您的電子郵件地址。",
|
||||||
"Manage your profile information, security settings, and login history": "管理您的個人資訊、安全設定與登入紀錄",
|
"Account created successfully.": "帳號已成功建立。",
|
||||||
"Profile Information": "個人基本資料",
|
"Account deleted successfully.": "帳號已成功刪除。",
|
||||||
"Update your account's profile information and email address.": "更新您的帳號姓名、手機號碼與電子郵件地址。",
|
|
||||||
"Update Password": "更改密碼",
|
|
||||||
"Ensure your account is using a long, random password to stay secure.": "確保您的帳號使用了足夠強度的隨機密碼以維持安全。",
|
|
||||||
"Delete Account": "刪除帳號",
|
|
||||||
"Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.": "一旦您的帳號被刪除,其所有資源和數據將被永久刪除。在刪除帳號之前,請下載您希望保留的任何數據或資訊。",
|
|
||||||
"Are you sure you want to delete your account?": "您確定要刪除您的帳號嗎?",
|
|
||||||
"Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.": "帳號一旦刪除,所有關連數據將被永久移除。請輸入您的密碼以確認您希望永久刪除此帳號。",
|
|
||||||
"Login History": "登入歷史",
|
|
||||||
"Name": "姓名",
|
|
||||||
"Phone": "手機號碼",
|
|
||||||
"Email": "電子郵件",
|
|
||||||
"Current Password": "當前密碼",
|
|
||||||
"New Password": "新密碼",
|
|
||||||
"Confirm Password": "確認新密碼",
|
|
||||||
"Save": "儲存變更",
|
|
||||||
"Saved.": "已儲存",
|
|
||||||
"Update": "更新",
|
|
||||||
"Cancel": "取消",
|
|
||||||
"Confirm": "確認",
|
|
||||||
"Danger Zone: Delete Account": "危險區域:刪除帳號",
|
|
||||||
"Permanently Delete Account": "永久刪除帳號",
|
|
||||||
"Password": "密碼",
|
|
||||||
"Enter your password to confirm": "請輸入您的密碼以確認",
|
|
||||||
"Dashboard": "儀表板",
|
|
||||||
"Connectivity Status": "連線狀態概況",
|
|
||||||
"Real-time status monitoring": "即時監控機台連線動態",
|
|
||||||
"LIVE": "實時",
|
|
||||||
"Online Machines": "在線機台",
|
|
||||||
"Offline Machines": "離線機台",
|
|
||||||
"Alerts Pending": "待處理告警",
|
|
||||||
"Total Connected": "總計連線數",
|
|
||||||
"Monthly Transactions": "本月交易統計",
|
|
||||||
"Monthly cumulative revenue overview": "本月累計營收概況",
|
|
||||||
"Today's Transactions": "今日交易額",
|
|
||||||
"vs Yesterday": "較昨日",
|
|
||||||
"Yesterday": "昨日",
|
|
||||||
"Day Before": "前日",
|
|
||||||
"Machine Status List": "機台運行狀態列表",
|
|
||||||
"Total items": "總計 :count 項",
|
|
||||||
"Real-time monitoring across all machines": "跨機台即時狀態監控",
|
|
||||||
"Quick search...": "快速搜尋...",
|
|
||||||
"Machine Info": "機台資訊",
|
|
||||||
"Running Status": "運行狀態",
|
|
||||||
"Today Cumulative Sales": "今日累積銷售",
|
|
||||||
"Current Stock": "當前庫存",
|
|
||||||
"Last Signal": "最後訊號時間",
|
|
||||||
"Alert Summary": "告警摘要",
|
|
||||||
"No alert summary": "暫無告警記錄",
|
|
||||||
"No data available": "暫無資料",
|
|
||||||
"Showing :from to :to of :total items": "顯示第 :from 到 :to 項,共 :total 項",
|
|
||||||
"Previous": "上一頁",
|
|
||||||
"Next": "下一頁",
|
|
||||||
"Profile Settings": "個人設定",
|
|
||||||
"Profile": "個人檔案",
|
|
||||||
"Member Management": "會員管理",
|
|
||||||
"Member List": "會員列表",
|
|
||||||
"Membership Tiers": "會員等級",
|
|
||||||
"Deposit Bonus": "儲值回饋",
|
|
||||||
"Point Rules": "點數規則",
|
|
||||||
"Gift Definitions": "禮品設定",
|
|
||||||
"Machine Management": "機台管理",
|
|
||||||
"Machine Logs": "機台日誌",
|
|
||||||
"Machine List": "機台列表",
|
|
||||||
"Machine Permissions": "機台權限",
|
|
||||||
"Utilization Rate": "機台稼動率",
|
|
||||||
"Expiry Management": "效期管理",
|
|
||||||
"Maintenance Records": "維修管理單",
|
|
||||||
"APP Management": "APP管理",
|
|
||||||
"UI Elements": "UI元素",
|
|
||||||
"Helper": "小幫手",
|
|
||||||
"Questionnaire": "問卷",
|
|
||||||
"Games": "互動遊戲",
|
|
||||||
"Timer": "計時器",
|
|
||||||
"Warehouse Management": "倉庫管理",
|
|
||||||
"Warehouse List (All)": "倉庫列表(全)",
|
|
||||||
"Warehouse List (Individual)": "倉庫列表(個)",
|
|
||||||
"Stock Management": "庫存管理單",
|
|
||||||
"Transfers": "調撥單",
|
|
||||||
"Purchases": "採購單",
|
|
||||||
"Replenishments": "機台補貨單",
|
|
||||||
"Replenishment Records": "機台補貨紀錄",
|
|
||||||
"Machine Stock": "機台庫存",
|
|
||||||
"Staff Stock": "人員庫存",
|
|
||||||
"Returns": "回庫單",
|
|
||||||
"Sales Management": "銷售管理",
|
|
||||||
"Sales Records": "銷售紀錄",
|
|
||||||
"Pickup Codes": "取貨碼",
|
|
||||||
"Orders": "購買單",
|
|
||||||
"Promotions": "促銷時段",
|
|
||||||
"Pass Codes": "通行碼",
|
|
||||||
"Store Gifts": "來店禮",
|
|
||||||
"Analysis Management": "分析管理",
|
|
||||||
"Change Stock": "零錢庫存",
|
|
||||||
"Machine Reports": "機台報表",
|
|
||||||
"Product Reports": "商品報表",
|
|
||||||
"Survey Analysis": "問卷分析",
|
|
||||||
"Audit Management": "稽核管理",
|
|
||||||
"Purchase Audit": "採購單",
|
|
||||||
"Transfer Audit": "調撥單",
|
|
||||||
"Replenishment Audit": "補貨單",
|
|
||||||
"Data Configuration": "資料設定",
|
|
||||||
"Product Management": "商品管理",
|
|
||||||
"Advertisement Management": "廣告管理",
|
|
||||||
"Admin Sellable Products": "管理者可賣",
|
|
||||||
"Account Management": "帳號管理",
|
"Account Management": "帳號管理",
|
||||||
"Sub Accounts": "子帳號",
|
"Account Settings": "帳戶設定",
|
||||||
"Sub Account Roles": "子帳號角色",
|
|
||||||
"Point Settings": "點數設定",
|
|
||||||
"Badge Settings": "識別證",
|
|
||||||
"Remote Management": "遠端管理",
|
|
||||||
"Machine Restart": "機台重啟",
|
|
||||||
"Card Reader Restart": "卡機重啟",
|
|
||||||
"Remote Checkout": "遠端結帳",
|
|
||||||
"Remote Lock": "遠端鎖定",
|
|
||||||
"Remote Change": "遠端找零",
|
|
||||||
"Remote Dispense": "遠端出貨",
|
|
||||||
"Line Management": "Line管理",
|
|
||||||
"Line Members": "Line會員",
|
|
||||||
"Line Machines": "Line機台",
|
|
||||||
"Line Products": "Line商品",
|
|
||||||
"Line Official Account": "Line生活圈",
|
|
||||||
"Line Orders": "Line訂單",
|
|
||||||
"Line Coupons": "Line優惠券",
|
|
||||||
"Reservation System": "預約系統",
|
|
||||||
"Reservation Members": "預約會員",
|
|
||||||
"Store Management": "店家管理",
|
|
||||||
"Time Slots": "時段組合",
|
|
||||||
"Venue Management": "場地管理",
|
|
||||||
"Coupons": "優惠券",
|
|
||||||
"Reservations": "預約管理",
|
|
||||||
"Order Management": "訂單管理",
|
|
||||||
"Special Permission": "特殊權限",
|
|
||||||
"Clear Stock": "庫存清空",
|
|
||||||
"APK Versions": "APK版本",
|
|
||||||
"Discord Notifications": "Discord通知",
|
|
||||||
"Basic Settings": "基本設定",
|
|
||||||
"Machine Settings": "機台設定",
|
|
||||||
"Permission Settings": "權限設定",
|
|
||||||
"APP Features": "APP功能",
|
|
||||||
"Sales": "銷售管理",
|
|
||||||
"Others": "其他功能",
|
|
||||||
"AI Prediction": "AI智能預測",
|
|
||||||
"Roles": "角色權限",
|
|
||||||
"Role Management": "角色權限管理",
|
|
||||||
"Define and manage security roles and permissions.": "定義並管理系統安全角色與權限。",
|
|
||||||
"Search roles...": "搜尋角色...",
|
|
||||||
"No permissions": "無權限項目",
|
|
||||||
"No roles found.": "找不到角色資料。",
|
|
||||||
"Create Role": "建立角色",
|
|
||||||
"Edit Role": "編輯角色",
|
|
||||||
"Update existing role and permissions.": "更新現有角色與權限設定。",
|
|
||||||
"Create a new role and assign permissions.": "建立新角色並分配對應權限。",
|
|
||||||
"Enter role name": "請輸入角色名稱",
|
|
||||||
"Add Role": "新增角色",
|
|
||||||
"Role Name": "角色名稱",
|
|
||||||
"Type": "類型",
|
|
||||||
"Permissions": "權限",
|
|
||||||
"Users": "帳號數",
|
|
||||||
"System role name cannot be modified.": "內建系統角色的名稱無法修改。",
|
|
||||||
"The Super Admin role name cannot be modified.": "超級管理員角色的名稱無法修改。",
|
|
||||||
"System Level": "系統層級",
|
|
||||||
"Company Level": "客戶層級",
|
|
||||||
"Global roles accessible by all administrators.": "適用於所有管理者的全域角色。",
|
|
||||||
"Roles scoped to specific customer companies.": "適用於各個客戶單位的特定角色。",
|
|
||||||
"members": "會員管理",
|
|
||||||
"machines": "機台管理",
|
|
||||||
"app": "APP 管理",
|
|
||||||
"warehouses": "倉庫管理",
|
|
||||||
"sales": "銷售管理",
|
|
||||||
"analysis": "分析管理",
|
|
||||||
"audit": "稽核管理",
|
|
||||||
"data-config": "資料設定",
|
|
||||||
"remote": "遠端管理",
|
|
||||||
"line": "Line 管理",
|
|
||||||
"reservation": "預約系統",
|
|
||||||
"special-permission": "特殊權限",
|
|
||||||
"companies": "客戶管理",
|
|
||||||
"accounts": "帳號管理",
|
|
||||||
"roles": "角色權限",
|
|
||||||
"Role Permissions": "角色權限",
|
|
||||||
"Role Settings": "角色權限",
|
|
||||||
"No login history yet": "尚無登入紀錄",
|
|
||||||
"Signed in as": "登入身份",
|
|
||||||
"Logout": "登出",
|
|
||||||
"Joined": "加入日期",
|
|
||||||
"Recent Login": "最近登入",
|
|
||||||
"Total Logins": "總登入次數",
|
|
||||||
"Account Status": "帳號狀態",
|
"Account Status": "帳號狀態",
|
||||||
"Active": "使用中",
|
"Account updated successfully.": "帳號已成功更新。",
|
||||||
"Customer Management": "客戶管理",
|
"accounts": "帳號管理",
|
||||||
"Manage all tenant accounts and validity": "管理所有租戶帳號與合約效期",
|
|
||||||
"Add Customer": "新增客戶",
|
|
||||||
"Total Customers": "客戶總數",
|
|
||||||
"Expired / Disabled": "已過期 / 停用",
|
|
||||||
"Search customers...": "搜尋客戶...",
|
|
||||||
"All": "全部",
|
|
||||||
"Disabled": "已停用",
|
|
||||||
"Customer Info": "客戶資訊",
|
|
||||||
"Accounts / Machines": "帳號 / 機台",
|
"Accounts / Machines": "帳號 / 機台",
|
||||||
"Valid Until": "合約到期日",
|
|
||||||
"Actions": "操作",
|
|
||||||
"Permanent": "永久授權",
|
|
||||||
"Are you sure to delete this customer?": "您確定要刪除此客戶嗎?",
|
|
||||||
"No customers found": "找不到客戶資料",
|
|
||||||
"Edit Customer": "編輯客戶",
|
|
||||||
"Update Customer": "更新客戶",
|
|
||||||
"Create": "建立",
|
|
||||||
"Company Name": "公司名稱",
|
|
||||||
"Company Code": "公司代碼",
|
|
||||||
"Tax ID (Optional)": "統一編號 (選填)",
|
|
||||||
"Status": "狀態",
|
|
||||||
"Contact Name": "聯絡人姓名",
|
|
||||||
"Contact Phone": "聯絡人電話",
|
|
||||||
"Contact Email": "聯絡人信箱",
|
|
||||||
"Notes": "備註",
|
|
||||||
"Customer created successfully.": "客戶新增成功",
|
|
||||||
"Customer updated successfully.": "客戶更新成功",
|
|
||||||
"Customer deleted successfully.": "客戶刪除成功",
|
|
||||||
"Cannot delete company with active accounts.": "無法刪除仍有帳號的客戶",
|
|
||||||
"Contract Until (Optional)": "合約到期日 (選填)",
|
|
||||||
"Company Information": "公司資訊",
|
|
||||||
"Initial Admin Account": "初始管理帳號",
|
|
||||||
"Optional": "選填",
|
|
||||||
"Username": "使用者帳號",
|
|
||||||
"Enter login ID": "請輸入登入帳號",
|
|
||||||
"Min 8 characters": "至少 8 個字元",
|
|
||||||
"Admin display name": "管理員顯示名稱",
|
|
||||||
"Initial Role": "初始角色",
|
|
||||||
"Contact & Details": "聯絡資訊與詳情",
|
|
||||||
"e.g. Taiwan Star": "例如:台灣之星",
|
|
||||||
"e.g. TWSTAR": "例如:TWSTAR",
|
|
||||||
"Manage administrative and tenant accounts": "管理系統管理者與租戶帳號",
|
|
||||||
"Add Account": "新增帳號",
|
|
||||||
"All Companies": "所有公司",
|
|
||||||
"User Info": "用戶資訊",
|
|
||||||
"Company": "所屬客戶",
|
|
||||||
"Belongs To": "所屬單位",
|
|
||||||
"Role": "角色",
|
|
||||||
"SYSTEM": "系統層級",
|
|
||||||
"No users found": "找不到用戶資料",
|
|
||||||
"Data Configuration Permissions": "資料設定權限",
|
|
||||||
"Sales Permissions": "銷售管理權限",
|
|
||||||
"Machine Management Permissions": "機台管理權限",
|
|
||||||
"Warehouse Permissions": "倉庫管理權限",
|
|
||||||
"Analysis Permissions": "分析管理權限",
|
|
||||||
"Audit Permissions": "稽核管理權限",
|
|
||||||
"Remote Permissions": "遠端管理權限",
|
|
||||||
"Line Permissions": "Line 管理權限",
|
|
||||||
"Save Changes": "儲存變更",
|
|
||||||
"User": "一般用戶",
|
|
||||||
"Admin": "管理員",
|
|
||||||
"Super Admin": "超級管理員",
|
|
||||||
"e.g. John Doe": "例如:張曉明",
|
|
||||||
"e.g. johndoe": "例如:xiaoming",
|
|
||||||
"Search users...": "搜尋用戶...",
|
|
||||||
"Admin Name": "管理員姓名",
|
|
||||||
"New Password (leave blank to keep current)": "新密碼 (若不修改請留空)",
|
|
||||||
"Are you sure you want to delete this account?": "您確定要刪除此帳號嗎?",
|
|
||||||
"Show": "顯示",
|
|
||||||
"to": "至",
|
|
||||||
"of": "總計",
|
|
||||||
"items": "筆項目",
|
|
||||||
"Showing": "顯示第",
|
|
||||||
"Full Name": "全名",
|
|
||||||
"super-admin": "超級管理員",
|
|
||||||
"admin": "管理員",
|
|
||||||
"user": "一般用戶",
|
|
||||||
"Product Status": "商品狀態",
|
|
||||||
"Monitor events and system activity across your vending fleet.": "跨機台連線動態與系統日誌監控。",
|
|
||||||
"All Machines": "所有機台",
|
|
||||||
"All Levels": "所有層級",
|
|
||||||
"Timestamp": "時間戳記",
|
|
||||||
"Message Content": "日誌內容",
|
|
||||||
"No matching logs found": "找不到符合條件的日誌",
|
|
||||||
"Unknown": "未知",
|
|
||||||
"Info": "一般",
|
|
||||||
"Warning": "警告",
|
|
||||||
"Error": "異常",
|
|
||||||
"Management of operational parameters": "機台運作參數管理",
|
|
||||||
"Add Machine": "新增機台",
|
|
||||||
"Search machines...": "搜尋機台...",
|
|
||||||
"Items": "個項目",
|
|
||||||
"Machine Name": "機台名稱",
|
|
||||||
"Serial No": "機台序號",
|
|
||||||
"Owner": "所屬公司",
|
|
||||||
"Model": "機台型號",
|
|
||||||
"Action": "操作",
|
"Action": "操作",
|
||||||
"No location set": "尚未設定位置",
|
"Actions": "操作",
|
||||||
"Edit Settings": "編輯設定",
|
"Active": "使用中",
|
||||||
"Enter machine name": "請輸入機台名稱",
|
"Add Account": "新增帳號",
|
||||||
"Enter serial number": "請輸入機台序號",
|
"Add Customer": "新增客戶",
|
||||||
"Select Owner": "選擇所屬公司",
|
"Add Machine": "新增機台",
|
||||||
"Select Model": "選擇型號",
|
"Add Machine Model": "新增機台型號",
|
||||||
"Customer Payment Config": "客戶金流設定",
|
"Add Role": "新增角色",
|
||||||
"Not Used": "不使用",
|
"Admin": "管理員",
|
||||||
"Edit Machine Settings": "編輯機台設定",
|
"admin": "管理員",
|
||||||
"Operational Parameters": "運作參數",
|
"Admin display name": "管理員顯示名稱",
|
||||||
"Card Reader Seconds": "刷卡機秒數",
|
"Admin Name": "管理員姓名",
|
||||||
"Payment Buffer Seconds": "金流緩衝時間(s)",
|
"Admin Sellable Products": "管理者可賣",
|
||||||
"Checkout Time 1": "卡機結帳時間1",
|
"Administrator": "管理員",
|
||||||
"Checkout Time 2": "卡機結帳時間2",
|
"Advertisement Management": "廣告管理",
|
||||||
"Heating Start Time": "開啟-加熱時間",
|
"Affiliation": "所屬單位",
|
||||||
"Heating End Time": "關閉-加熱時間",
|
"AI Prediction": "AI智能預測",
|
||||||
"Hardware & Slots": "硬體與貨道",
|
"Alert Summary": "告警摘要",
|
||||||
"Card Reader No": "刷卡機編號",
|
"Alerts Pending": "待處理告警",
|
||||||
"Key No": "鑰匙編號",
|
"All": "全部",
|
||||||
"Slot Mechanism (default: Conveyor, check for Spring)": "貨道機制 (預設履帶,勾選為彈簧)",
|
"All Affiliations": "全部單位",
|
||||||
"Payment & Invoice": "金流與發票",
|
"All Companies": "所有公司",
|
||||||
"Invoice Status": "發票開立狀態",
|
"All Levels": "所有層級",
|
||||||
"No Invoice": "不開立發票",
|
"All Machines": "所有機台",
|
||||||
"Default Donate": "預設捐贈",
|
"All Times System Timezone": "所有時間為系統時區",
|
||||||
"Default Not Donate": "預設不捐贈",
|
"analysis": "分析管理",
|
||||||
"Member & External": "會員與外部系統",
|
"Analysis Management": "分析管理",
|
||||||
"Welcome Gift": "註冊成效禮",
|
"Analysis Permissions": "分析管理權限",
|
||||||
"Enabled/Disabled": "啟用/停用",
|
"API Token": "API 金鑰",
|
||||||
"Member System": "會員系統",
|
"APK Versions": "APK版本",
|
||||||
"Payment Configuration": "客戶金流設定",
|
"app": "APP 管理",
|
||||||
"Merchant payment gateway settings management": "特約商店支付網關參數管理",
|
"APP Features": "APP功能",
|
||||||
"Create Config": "建立配置",
|
"APP Management": "APP管理",
|
||||||
"Config Name": "配置名稱",
|
|
||||||
"Last Updated": "最後更新日期",
|
|
||||||
"Are you sure you want to delete this configuration?": "您確定要刪除此金流配置嗎?",
|
|
||||||
"Create Payment Config": "建立金流配置",
|
|
||||||
"Define new third-party payment parameters": "定義新的第三方支付介接參數",
|
|
||||||
"Save Config": "儲存配置",
|
|
||||||
"Configuration Name": "金流組合名稱",
|
|
||||||
"Belongs To Company": "所屬客戶公司",
|
|
||||||
"ECPay Invoice": "綠界發票",
|
|
||||||
"Store ID": "特約商店代號 (MerchantID)",
|
|
||||||
"HashKey": "HashKey",
|
|
||||||
"HashIV": "HashIV",
|
|
||||||
"E.SUN QR Scan": "玉山掃碼",
|
|
||||||
"StoreID": "商店代號 (StoreID)",
|
|
||||||
"TermID": "終端代號 (TermID)",
|
|
||||||
"Key": "金鑰 (Key)",
|
|
||||||
"LINE Pay Direct": "Line官方支付",
|
|
||||||
"ChannelId": "ChannelId",
|
|
||||||
"ChannelSecret": "ChannelSecret",
|
|
||||||
"TapPay Integration": "TapPay 整合支付",
|
|
||||||
"PARTNER_KEY": "PARTNER_KEY",
|
|
||||||
"APP_ID": "APP_ID",
|
"APP_ID": "APP_ID",
|
||||||
"APP_KEY": "APP_KEY",
|
"APP_KEY": "APP_KEY",
|
||||||
"Merchant IDs": "商店代號群",
|
"Are you sure to delete this customer?": "您確定要刪除此客戶嗎?",
|
||||||
"LINE_MERCHANT_ID": "LINE Pay 商店代號",
|
"Are you sure you want to delete this account?": "您確定要刪除此帳號嗎?",
|
||||||
"JKO_MERCHANT_ID": "街口支付 商店代號",
|
"Are you sure you want to delete this account? This action cannot be undone.": "確定要刪除此帳號嗎?此操作無法復原。",
|
||||||
"PI_MERCHANT_ID": "Pi 拍錢包 商店代號",
|
"Are you sure you want to delete this configuration?": "您確定要刪除此金流配置嗎?",
|
||||||
"PS_MERCHANT_ID": "全盈+Pay 商店代號",
|
"Are you sure you want to delete this configuration? This action cannot be undone.": "您確定要刪除此金流配置嗎?此操作將無法復原。",
|
||||||
"EASY_MERCHANT_ID": "悠遊付 商店代號",
|
"Are you sure you want to delete this item? This action cannot be undone.": "確定要刪除此項目嗎?此操作無法復原。",
|
||||||
"basic-settings": "基本設定",
|
"Are you sure you want to delete this role? This action cannot be undone.": "您確定要刪除此角色嗎?此操作將無法復原。",
|
||||||
"permissions": "權限設定",
|
"Are you sure you want to delete your account?": "您確定要刪除您的帳號嗎?",
|
||||||
"Edit Payment Config": "編輯金流配置",
|
"Are you sure you want to proceed? This action cannot be undone.": "您確定要繼續嗎?此操作將無法復原。",
|
||||||
"Machine Model Settings": "機台型號設定",
|
|
||||||
"Machine Model": "機台型號",
|
|
||||||
"Model Name": "型號名稱",
|
|
||||||
"Machine Count": "機台數量",
|
|
||||||
"Add Machine Model": "新增機台型號",
|
|
||||||
"Edit Machine Model": "編輯機台型號",
|
|
||||||
"Machine model created successfully.": "機台型號已成功建立。",
|
|
||||||
"Machine model updated successfully.": "機台型號已成功更新。",
|
|
||||||
"Machine model deleted successfully.": "機台型號已成功刪除。",
|
|
||||||
"Cannot delete model that is currently in use by machines.": "無法刪除目前正在被機台使用的型號。",
|
|
||||||
"Machine Details": "機台詳情",
|
|
||||||
"Create Machine": "新增機台",
|
|
||||||
"Edit Machine": "編輯機台",
|
|
||||||
"Basic Information": "基本資訊",
|
|
||||||
"Location": "位置",
|
|
||||||
"Temperature": "溫度",
|
|
||||||
"Firmware Version": "韌體版本",
|
|
||||||
"Last Heartbeat": "最後心跳時間",
|
|
||||||
"Never Connected": "從未連線",
|
|
||||||
"View Logs": "查看日誌",
|
|
||||||
"Real-time Operation Logs (Last 50)": "即時操作日誌 (最後 50 筆)",
|
|
||||||
"All Times System Timezone": "所有時間為系統時區",
|
|
||||||
"Level": "層級",
|
|
||||||
"Logs": "日誌",
|
|
||||||
"Time": "時間",
|
|
||||||
"Message": "訊息",
|
|
||||||
"Online": "線上",
|
|
||||||
"Offline": "離線",
|
|
||||||
"Connecting...": "連線中",
|
|
||||||
"No logs found": "暫無相關日誌",
|
|
||||||
"Management of operational parameters and models": "管理運作參數與型號",
|
|
||||||
"ECPay Invoice Settings Description": "綠界科技電子發票設定",
|
|
||||||
"E.SUN QR Scan Settings Description": "玉山銀行掃碼支付設定",
|
|
||||||
"LINE Pay Direct Settings Description": "LINE Pay 官方直連設定",
|
|
||||||
"TapPay Integration Settings Description": "喬睿科技支付串接設定",
|
|
||||||
"Parameters": "參數設定",
|
|
||||||
"Hardware & Network": "硬體與網路",
|
|
||||||
"Serial & Version": "序號與版本",
|
|
||||||
"Heartbeat": "心跳狀態",
|
|
||||||
"Heating Range": "加熱時段",
|
|
||||||
"API Token": "API 金鑰",
|
|
||||||
"Close Panel": "關閉面板",
|
|
||||||
"Operations": "運作設定",
|
|
||||||
"Payment Config": "金流配置",
|
|
||||||
"Machine Images": "機台照片",
|
|
||||||
"No images uploaded": "尚未上傳照片",
|
|
||||||
"Upload New Images": "上傳新照片",
|
|
||||||
"Max 3": "最多 3 張",
|
|
||||||
"Uploading new images will replace all existing images.": "上傳新照片將會取代所有現有照片。",
|
|
||||||
"Search models...": "搜尋型號...",
|
|
||||||
"Card Reader": "刷卡機",
|
|
||||||
"View Details": "查看詳情",
|
|
||||||
"Are you sure?": "確定要執行此操作嗎?",
|
"Are you sure?": "確定要執行此操作嗎?",
|
||||||
"Machines": "機台列表",
|
"audit": "稽核管理",
|
||||||
"Models": "型號列表",
|
"Audit Management": "稽核管理",
|
||||||
"Edit": "編輯",
|
"Audit Permissions": "稽核管理權限",
|
||||||
|
"Avatar updated successfully.": "頭像已成功更新。",
|
||||||
|
"Badge Settings": "識別證",
|
||||||
|
"Basic Information": "基本資訊",
|
||||||
|
"Basic Settings": "基本設定",
|
||||||
|
"basic-settings": "基本設定",
|
||||||
|
"Belongs To": "所屬公司",
|
||||||
|
"Belongs To Company": "所屬公司",
|
||||||
|
"Cancel": "取消",
|
||||||
|
"Cannot delete company with active accounts.": "無法刪除仍有帳號的客戶",
|
||||||
|
"Cannot delete model that is currently in use by machines.": "無法刪除目前正在被機台使用的型號。",
|
||||||
|
"Cannot Delete Role": "無法刪除該角色",
|
||||||
|
"Cannot delete role with active users.": "無法刪除已有綁定帳號的角色。",
|
||||||
|
"Card Reader": "刷卡機",
|
||||||
|
"Card Reader No": "刷卡機編號",
|
||||||
|
"Card Reader Restart": "卡機重啟",
|
||||||
|
"Card Reader Seconds": "刷卡機秒數",
|
||||||
|
"Change": "更換",
|
||||||
|
"Change Stock": "零錢庫存",
|
||||||
|
"ChannelId": "ChannelId",
|
||||||
|
"ChannelSecret": "ChannelSecret",
|
||||||
|
"Checkout Time 1": "卡機結帳時間1",
|
||||||
|
"Checkout Time 2": "卡機結帳時間2",
|
||||||
|
"Clear Stock": "庫存清空",
|
||||||
|
"Click here to re-send the verification email.": "點擊此處重新發送驗證郵件。",
|
||||||
|
"Click to upload": "點擊上傳",
|
||||||
|
"Close Panel": "關閉面板",
|
||||||
|
"companies": "客戶管理",
|
||||||
|
"Company": "所屬客戶",
|
||||||
|
"Company Code": "公司代碼",
|
||||||
|
"Company Information": "公司資訊",
|
||||||
|
"Company Level": "客戶層級",
|
||||||
|
"Company Name": "公司名稱",
|
||||||
|
"Config Name": "配置名稱",
|
||||||
|
"Configuration Name": "配置名稱",
|
||||||
|
"Confirm": "確認",
|
||||||
|
"Confirm Deletion": "確認刪除資料",
|
||||||
|
"Confirm Password": "確認新密碼",
|
||||||
|
"Connecting...": "連線中",
|
||||||
|
"Connectivity Status": "連線狀態概況",
|
||||||
|
"Contact & Details": "聯絡資訊與詳情",
|
||||||
|
"Contact Email": "聯絡人信箱",
|
||||||
|
"Contact Name": "聯絡人姓名",
|
||||||
|
"Contact Phone": "聯絡人電話",
|
||||||
|
"Contract Until (Optional)": "合約到期日 (選填)",
|
||||||
|
"Coupons": "優惠券",
|
||||||
|
"Create": "建立",
|
||||||
|
"Create a new role and assign permissions.": "建立新角色並分配對應權限。",
|
||||||
|
"Create Config": "建立配置",
|
||||||
|
"Create Machine": "新增機台",
|
||||||
|
"Create Payment Config": "新增金流配置",
|
||||||
|
"Create Role": "建立角色",
|
||||||
|
"Current Password": "當前密碼",
|
||||||
|
"Current Stock": "當前庫存",
|
||||||
|
"Customer created successfully.": "客戶新增成功",
|
||||||
|
"Customer deleted successfully.": "客戶刪除成功",
|
||||||
|
"Customer Info": "客戶資訊",
|
||||||
|
"Customer Management": "客戶管理",
|
||||||
|
"Customer Payment Config": "客戶金流設定",
|
||||||
|
"Customer updated successfully.": "客戶更新成功",
|
||||||
|
"Danger Zone: Delete Account": "危險區域:刪除帳號",
|
||||||
|
"Dashboard": "儀表板",
|
||||||
|
"Data Configuration": "資料設定",
|
||||||
|
"Data Configuration Permissions": "資料設定權限",
|
||||||
|
"data-config": "資料設定",
|
||||||
|
"Day Before": "前日",
|
||||||
|
"Default Donate": "預設捐贈",
|
||||||
|
"Default Not Donate": "預設不捐贈",
|
||||||
|
"Define and manage security roles and permissions.": "定義並管理系統安全角色與權限。",
|
||||||
|
"Define new third-party payment parameters": "定義新的第三方支付參數",
|
||||||
"Delete": "刪除",
|
"Delete": "刪除",
|
||||||
"None": "無",
|
"Delete Account": "刪除帳號",
|
||||||
"Select Company": "選擇所屬公司",
|
"Delete Permanently": "確認永久刪除資料",
|
||||||
|
"Deposit Bonus": "儲值回饋",
|
||||||
|
"Detail": "詳細",
|
||||||
|
"Disabled": "已停用",
|
||||||
|
"Discord Notifications": "Discord通知",
|
||||||
|
"e.g. John Doe": "例如:張曉明",
|
||||||
|
"e.g. johndoe": "例如:xiaoming",
|
||||||
|
"e.g. Taiwan Star": "例如:台灣之星",
|
||||||
|
"e.g. TWSTAR": "例如:TWSTAR",
|
||||||
"e.g., Company Standard Pay": "例如:公司標準支付",
|
"e.g., Company Standard Pay": "例如:公司標準支付",
|
||||||
"Photo Slot": "照片欄位",
|
"e.g., Taipei Station": "例如:台北車站",
|
||||||
|
"E.SUN QR Scan": "玉山銀行標籤支付",
|
||||||
|
"E.SUN QR Scan Settings Description": "玉山銀行掃碼支付設定",
|
||||||
|
"EASY_MERCHANT_ID": "悠遊付 商店代號",
|
||||||
|
"ECPay Invoice": "綠界電子發票",
|
||||||
|
"ECPay Invoice Settings Description": "綠界科技電子發票設定",
|
||||||
|
"Edit": "編輯",
|
||||||
|
"Edit Account": "編輯帳號",
|
||||||
|
"Edit Customer": "編輯客戶",
|
||||||
|
"Edit Machine": "編輯機台",
|
||||||
|
"Edit Machine Model": "編輯機台型號",
|
||||||
|
"Edit Machine Settings": "編輯機台設定",
|
||||||
|
"Edit Payment Config": "編輯金流配置",
|
||||||
|
"Edit Role": "編輯角色",
|
||||||
|
"Edit Settings": "編輯設定",
|
||||||
|
"Email": "電子郵件",
|
||||||
|
"Enabled/Disabled": "啟用/停用",
|
||||||
|
"Ensure your account is using a long, random password to stay secure.": "確保您的帳號使用了足夠強度的隨機密碼以維持安全。",
|
||||||
|
"Enter login ID": "請輸入登入帳號",
|
||||||
|
"Enter machine location": "請輸入機台地點",
|
||||||
|
"Enter machine name": "請輸入機台名稱",
|
||||||
|
"Enter model name": "請輸入型號名稱",
|
||||||
|
"Enter role name": "請輸入角色名稱",
|
||||||
|
"Enter serial number": "請輸入機台序號",
|
||||||
|
"Enter your password to confirm": "請輸入您的密碼以確認",
|
||||||
|
"Error": "異常",
|
||||||
|
"Expired / Disabled": "已過期 / 停用",
|
||||||
|
"Expiry Management": "效期管理",
|
||||||
|
"Failed to update machine images: ": "更新機台圖片失敗:",
|
||||||
|
"files selected": "個檔案已選擇",
|
||||||
|
"Firmware Version": "韌體版本",
|
||||||
|
"Full Name": "全名",
|
||||||
|
"Games": "互動遊戲",
|
||||||
|
"Gift Definitions": "禮品設定",
|
||||||
|
"Global roles accessible by all administrators.": "適用於所有管理者的全域角色。",
|
||||||
|
"Got it": "知道了",
|
||||||
|
"Hardware & Network": "硬體與網路",
|
||||||
|
"Hardware & Slots": "硬體與貨道",
|
||||||
|
"HashIV": "HashIV",
|
||||||
|
"HashKey": "HashKey",
|
||||||
|
"Heartbeat": "心跳狀態",
|
||||||
|
"Heating End Time": "關閉-加熱時間",
|
||||||
|
"Heating Range": "加熱時段",
|
||||||
|
"Heating Start Time": "開啟-加熱時間",
|
||||||
|
"Helper": "小幫手",
|
||||||
|
"Info": "一般",
|
||||||
|
"Initial Admin Account": "初始管理帳號",
|
||||||
|
"Initial Role": "初始角色",
|
||||||
|
"Invoice Status": "發票開立狀態",
|
||||||
|
"items": "筆項目",
|
||||||
|
"Items": "個項目",
|
||||||
|
"JKO_MERCHANT_ID": "街口支付 商店代號",
|
||||||
|
"john@example.com": "john@example.com",
|
||||||
|
"Joined": "加入日期",
|
||||||
|
"Key": "金鑰 (Key)",
|
||||||
|
"Key No": "鑰匙編號",
|
||||||
|
"Last Heartbeat": "最後心跳時間",
|
||||||
|
"Last Signal": "最後訊號時間",
|
||||||
|
"Last Updated": "最後更新日期",
|
||||||
|
"Level": "層級",
|
||||||
|
"line": "Line 管理",
|
||||||
|
"Line Coupons": "Line優惠券",
|
||||||
|
"Line Machines": "Line機台",
|
||||||
|
"Line Management": "Line管理",
|
||||||
|
"Line Members": "Line會員",
|
||||||
|
"Line Official Account": "Line生活圈",
|
||||||
|
"Line Orders": "Line訂單",
|
||||||
|
"LINE Pay Direct": "LINE Pay 官方直連",
|
||||||
|
"LINE Pay Direct Settings Description": "LINE Pay 官方直連設定",
|
||||||
|
"Line Permissions": "Line 管理權限",
|
||||||
|
"Line Products": "Line商品",
|
||||||
|
"LINE_MERCHANT_ID": "LINE Pay 商店代號",
|
||||||
|
"LIVE": "實時",
|
||||||
|
"Location": "位置",
|
||||||
|
"Login History": "登入歷史",
|
||||||
|
"Logout": "登出",
|
||||||
|
"Logs": "日誌",
|
||||||
|
"Machine Count": "機台數量",
|
||||||
|
"Machine created successfully.": "機台已成功建立。",
|
||||||
|
"Machine Details": "機台詳情",
|
||||||
|
"Machine Images": "機台照片",
|
||||||
|
"Machine images updated successfully.": "機台圖片已成功更新。",
|
||||||
|
"Machine Info": "機台資訊",
|
||||||
|
"Machine List": "機台列表",
|
||||||
|
"Machine Logs": "機台日誌",
|
||||||
|
"Machine Management": "機台管理",
|
||||||
|
"Machine Management Permissions": "機台管理權限",
|
||||||
|
"Machine Model": "機台型號",
|
||||||
|
"Machine model created successfully.": "機台型號已成功建立。",
|
||||||
|
"Machine model deleted successfully.": "機台型號已成功刪除。",
|
||||||
|
"Machine Model Settings": "機台型號設定",
|
||||||
|
"Machine model updated successfully.": "機台型號已成功更新。",
|
||||||
|
"Machine Name": "機台名稱",
|
||||||
|
"Machine Permissions": "機台權限",
|
||||||
|
"Machine Reports": "機台報表",
|
||||||
|
"Machine Restart": "機台重啟",
|
||||||
|
"Machine Settings": "機台設定",
|
||||||
|
"Machine settings updated successfully.": "機台設定已成功更新。",
|
||||||
|
"Machine Status List": "機台運行狀態列表",
|
||||||
|
"Machine Stock": "機台庫存",
|
||||||
|
"machines": "機台管理",
|
||||||
|
"Machines": "機台列表",
|
||||||
|
"Maintenance Records": "維修管理單",
|
||||||
|
"Manage administrative and tenant accounts": "管理系統管理者與租戶帳號",
|
||||||
|
"Manage all tenant accounts and validity": "管理所有租戶帳號與合約效期",
|
||||||
|
"Manage your profile information, security settings, and login history": "管理您的個人資訊、安全設定與登入紀錄",
|
||||||
|
"Management of operational parameters": "機台運作參數管理",
|
||||||
|
"Management of operational parameters and models": "管理運作參數與型號",
|
||||||
|
"Max 3": "最多 3 張",
|
||||||
|
"Member & External": "會員與外部系統",
|
||||||
|
"Member List": "會員列表",
|
||||||
|
"Member Management": "會員管理",
|
||||||
|
"Member System": "會員系統",
|
||||||
|
"members": "會員管理",
|
||||||
|
"Membership Tiers": "會員等級",
|
||||||
|
"Menu Permissions": "選單權限",
|
||||||
|
"Merchant IDs": "特店代號清單",
|
||||||
|
"Merchant payment gateway settings management": "特約商店支付網關參數管理",
|
||||||
|
"Message": "訊息",
|
||||||
|
"Message Content": "日誌內容",
|
||||||
|
"Min 8 characters": "至少 8 個字元",
|
||||||
|
"Model": "機台型號",
|
||||||
|
"Model Name": "型號名稱",
|
||||||
|
"Models": "型號列表",
|
||||||
|
"Modifying your own administrative permissions may result in losing access to certain system functions.": "修改自身管理權限可能導致失去對部分系統功能的控制權。",
|
||||||
|
"Monitor events and system activity across your vending fleet.": "跨機台連線動態與系統日誌監控。",
|
||||||
|
"Monthly cumulative revenue overview": "本月累計營收概況",
|
||||||
|
"Monthly Transactions": "本月交易統計",
|
||||||
|
"Name": "姓名",
|
||||||
|
"Never Connected": "從未連線",
|
||||||
|
"New Password": "新密碼",
|
||||||
|
"New Password (leave blank to keep current)": "新密碼 (若不修改請留空)",
|
||||||
|
"Next": "下一頁",
|
||||||
|
"No accounts found": "找不到帳號資料",
|
||||||
|
"No alert summary": "暫無告警記錄",
|
||||||
|
"No configurations found": "暫無相關配置",
|
||||||
|
"No customers found": "找不到客戶資料",
|
||||||
|
"No data available": "暫無資料",
|
||||||
|
"No file uploaded.": "未上傳任何檔案。",
|
||||||
|
"No images uploaded": "尚未上傳照片",
|
||||||
|
"No Invoice": "不開立發票",
|
||||||
|
"No location set": "尚未設定位置",
|
||||||
|
"No login history yet": "尚無登入紀錄",
|
||||||
|
"No logs found": "暫無相關日誌",
|
||||||
|
"No matching logs found": "找不到符合條件的日誌",
|
||||||
|
"No permissions": "無權限項目",
|
||||||
|
"No roles found.": "找不到角色資料。",
|
||||||
|
"No users found": "找不到用戶資料",
|
||||||
|
"None": "無",
|
||||||
|
"Not Used": "不使用",
|
||||||
|
"Not Used Description": "不使用第三方支付介接",
|
||||||
|
"Notes": "備註",
|
||||||
|
"of": "總計",
|
||||||
|
"Offline": "離線",
|
||||||
|
"Offline Machines": "離線機台",
|
||||||
|
"Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.": "一旦您的帳號被刪除,其所有資源和數據將被永久刪除。在刪除帳號之前,請下載您希望保留的任何數據或資訊。",
|
||||||
|
"Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.": "帳號一旦刪除,所有關連數據將被永久移除。請輸入您的密碼以確認您希望永久刪除此帳號。",
|
||||||
|
"Online": "線上",
|
||||||
|
"Online Machines": "在線機台",
|
||||||
|
"Only system roles can be assigned to platform administrative accounts.": "僅系統角色可指派給平台管理帳號。",
|
||||||
|
"Operational Parameters": "運作參數",
|
||||||
|
"Operations": "運作設定",
|
||||||
"Optimized for display. Supported formats: JPG, PNG, WebP.": "已針對顯示進行優化。支援格式:JPG, PNG, WebP。",
|
"Optimized for display. Supported formats: JPG, PNG, WebP.": "已針對顯示進行優化。支援格式:JPG, PNG, WebP。",
|
||||||
"Change": "更換"
|
"Optional": "選填",
|
||||||
|
"Order Management": "訂單管理",
|
||||||
|
"Orders": "購買單",
|
||||||
|
"Others": "其他功能",
|
||||||
|
"Owner": "所屬公司",
|
||||||
|
"Parameters": "參數設定",
|
||||||
|
"PARTNER_KEY": "PARTNER_KEY",
|
||||||
|
"Pass Codes": "通行碼",
|
||||||
|
"Password": "密碼",
|
||||||
|
"Password updated successfully.": "密碼已成功變更。",
|
||||||
|
"Payment & Invoice": "金流與發票",
|
||||||
|
"Payment Buffer Seconds": "金流緩衝時間(s)",
|
||||||
|
"Payment Config": "金流配置",
|
||||||
|
"Payment Configuration": "客戶金流設定",
|
||||||
|
"Payment Configuration created successfully.": "金流設定已成功建立。",
|
||||||
|
"Payment Configuration deleted successfully.": "金流設定已成功刪除。",
|
||||||
|
"Payment Configuration updated successfully.": "金流設定已成功更新。",
|
||||||
|
"Permanent": "永久授權",
|
||||||
|
"Permanently Delete Account": "永久刪除帳號",
|
||||||
|
"Permission Settings": "權限設定",
|
||||||
|
"Permissions": "權限",
|
||||||
|
"permissions": "權限設定",
|
||||||
|
"Phone": "手機號碼",
|
||||||
|
"Photo Slot": "照片欄位",
|
||||||
|
"PI_MERCHANT_ID": "Pi 拍錢包 商店代號",
|
||||||
|
"Pickup Codes": "取貨碼",
|
||||||
|
"Please check the following errors:": "請檢查以下錯誤:",
|
||||||
|
"Please check the form for errors.": "請檢查欄位內容是否正確。",
|
||||||
|
"Point Rules": "點數規則",
|
||||||
|
"Point Settings": "點數設定",
|
||||||
|
"Previous": "上一頁",
|
||||||
|
"Product Management": "商品管理",
|
||||||
|
"Product Reports": "商品報表",
|
||||||
|
"Product Status": "商品狀態",
|
||||||
|
"Profile": "個人檔案",
|
||||||
|
"Profile Information": "個人基本資料",
|
||||||
|
"Profile Settings": "個人設定",
|
||||||
|
"Profile updated successfully.": "個人資料已成功更新。",
|
||||||
|
"Promotions": "促銷時段",
|
||||||
|
"Protected": "受保護",
|
||||||
|
"PS_MERCHANT_ID": "全盈+Pay 商店代號",
|
||||||
|
"Purchase Audit": "採購單",
|
||||||
|
"Purchases": "採購單",
|
||||||
|
"Questionnaire": "問卷",
|
||||||
|
"Quick search...": "快速搜尋...",
|
||||||
|
"Real-time monitoring across all machines": "跨機台即時狀態監控",
|
||||||
|
"Real-time Operation Logs (Last 50)": "即時操作日誌 (最後 50 筆)",
|
||||||
|
"Real-time status monitoring": "即時監控機台連線動態",
|
||||||
|
"Recent Login": "最近登入",
|
||||||
|
"remote": "遠端管理",
|
||||||
|
"Remote Change": "遠端找零",
|
||||||
|
"Remote Checkout": "遠端結帳",
|
||||||
|
"Remote Dispense": "遠端出貨",
|
||||||
|
"Remote Lock": "遠端鎖定",
|
||||||
|
"Remote Management": "遠端管理",
|
||||||
|
"Remote Permissions": "遠端管理權限",
|
||||||
|
"Replenishment Audit": "補貨單",
|
||||||
|
"Replenishment Records": "機台補貨紀錄",
|
||||||
|
"Replenishments": "機台補貨單",
|
||||||
|
"reservation": "預約系統",
|
||||||
|
"Reservation Members": "預約會員",
|
||||||
|
"Reservation System": "預約系統",
|
||||||
|
"Reservations": "預約管理",
|
||||||
|
"Returns": "回庫單",
|
||||||
|
"Role": "角色",
|
||||||
|
"Role created successfully.": "角色已成功建立。",
|
||||||
|
"Role deleted successfully.": "角色已成功刪除。",
|
||||||
|
"Role Management": "角色權限管理",
|
||||||
|
"Role Name": "角色名稱",
|
||||||
|
"Role name already exists in this company.": "該公司已存在相同名稱的角色。",
|
||||||
|
"Role not found.": "角色不存在。",
|
||||||
|
"Role Permissions": "角色權限",
|
||||||
|
"Role Settings": "角色權限",
|
||||||
|
"Role Type": "角色類型",
|
||||||
|
"Role updated successfully.": "角色已成功更新。",
|
||||||
|
"Roles": "角色權限",
|
||||||
|
"roles": "角色權限",
|
||||||
|
"Roles scoped to specific customer companies.": "適用於各個客戶單位的特定角色。",
|
||||||
|
"Running Status": "運行狀態",
|
||||||
|
"Sales": "銷售管理",
|
||||||
|
"sales": "銷售管理",
|
||||||
|
"Sales Management": "銷售管理",
|
||||||
|
"Sales Permissions": "銷售管理權限",
|
||||||
|
"Sales Records": "銷售紀錄",
|
||||||
|
"Save": "儲存變更",
|
||||||
|
"Save Changes": "儲存變更",
|
||||||
|
"Save Config": "儲存配置",
|
||||||
|
"Saved.": "已儲存",
|
||||||
|
"Search configurations...": "搜尋設定...",
|
||||||
|
"Search customers...": "搜尋客戶...",
|
||||||
|
"Search machines...": "搜尋機台...",
|
||||||
|
"Search models...": "搜尋型號...",
|
||||||
|
"Search roles...": "搜尋角色...",
|
||||||
|
"Search users...": "搜尋用戶...",
|
||||||
|
"Select Company": "選擇所屬公司",
|
||||||
|
"Select Model": "選擇型號",
|
||||||
|
"Select Owner": "選擇所屬公司",
|
||||||
|
"Serial & Version": "序號與版本",
|
||||||
|
"Serial No": "機台序號",
|
||||||
|
"Serial Number": "機台序號",
|
||||||
|
"Show": "顯示",
|
||||||
|
"Showing": "顯示第",
|
||||||
|
"Showing :from to :to of :total items": "顯示第 :from 到 :to 項,共 :total 項",
|
||||||
|
"Sign in to your account": "隨時隨地掌控您的業務。",
|
||||||
|
"Signed in as": "登入身份",
|
||||||
|
"Slot Mechanism (default: Conveyor, check for Spring)": "貨道機制 (預設履帶,勾選為彈簧)",
|
||||||
|
"Some fields need attention": "部分欄位需要注意",
|
||||||
|
"Special Permission": "特殊權限",
|
||||||
|
"special-permission": "特殊權限",
|
||||||
|
"Staff Stock": "人員庫存",
|
||||||
|
"Status": "狀態",
|
||||||
|
"Stock Management": "庫存管理單",
|
||||||
|
"Store Gifts": "來店禮",
|
||||||
|
"Store ID": "商店代號",
|
||||||
|
"Store Management": "店家管理",
|
||||||
|
"StoreID": "商店代號 (StoreID)",
|
||||||
|
"Sub Account Management": "子帳號管理",
|
||||||
|
"Sub Account Roles": "子帳號角色",
|
||||||
|
"Sub Accounts": "子帳號",
|
||||||
|
"Success": "成功",
|
||||||
|
"Super Admin": "超級管理員",
|
||||||
|
"super-admin": "超級管理員",
|
||||||
|
"Super-admin role cannot be assigned to tenant accounts.": "超級管理員角色無法指派給租戶帳號。",
|
||||||
|
"Survey Analysis": "問卷分析",
|
||||||
|
"SYSTEM": "系統層級",
|
||||||
|
"System Level": "系統層級",
|
||||||
|
"System Role": "系統角色",
|
||||||
|
"System role name cannot be modified.": "內建系統角色的名稱無法修改。",
|
||||||
|
"System roles cannot be deleted by tenant administrators.": "租戶管理員無法刪除系統角色。",
|
||||||
|
"System roles cannot be modified by tenant administrators.": "租戶管理員無法修改系統角色。",
|
||||||
|
"System super admin accounts cannot be deleted.": "系統超級管理員帳號無法刪除。",
|
||||||
|
"System super admin accounts cannot be modified via this interface.": "系統超級管理員帳號無法透過此介面修改。",
|
||||||
|
"Systems Initializing": "系統初始化中",
|
||||||
|
"TapPay Integration": "TapPay 支付串接",
|
||||||
|
"TapPay Integration Settings Description": "喬睿科技支付串接設定",
|
||||||
|
"Tax ID (Optional)": "統一編號 (選填)",
|
||||||
|
"Temperature": "溫度",
|
||||||
|
"TermID": "終端代號 (TermID)",
|
||||||
|
"The image is too large. Please upload an image smaller than 1MB.": "圖片檔案太大,請上傳小於 1MB 的圖片。",
|
||||||
|
"The Super Admin role cannot be deleted.": "超級管理員角色不可刪除。",
|
||||||
|
"The Super Admin role is immutable.": "超級管理員角色不可修改。",
|
||||||
|
"The Super Admin role name cannot be modified.": "超級管理員角色的名稱無法修改。",
|
||||||
|
"This role belongs to another company and cannot be assigned.": "此角色屬於其他公司,無法指派。",
|
||||||
|
"Time": "時間",
|
||||||
|
"Time Slots": "時段組合",
|
||||||
|
"Timer": "計時器",
|
||||||
|
"Timestamp": "時間戳記",
|
||||||
|
"to": "至",
|
||||||
|
"Today Cumulative Sales": "今日累積銷售",
|
||||||
|
"Today's Transactions": "今日交易額",
|
||||||
|
"Total Connected": "總計連線數",
|
||||||
|
"Total Customers": "客戶總數",
|
||||||
|
"Total items": "總計 :count 項",
|
||||||
|
"Total Logins": "總登入次數",
|
||||||
|
"Transfer Audit": "調撥單",
|
||||||
|
"Transfers": "調撥單",
|
||||||
|
"Type": "類型",
|
||||||
|
"UI Elements": "UI元素",
|
||||||
|
"Unknown": "未知",
|
||||||
|
"Update": "更新",
|
||||||
|
"Update Customer": "更新客戶",
|
||||||
|
"Update existing role and permissions.": "更新現有角色與權限設定。",
|
||||||
|
"Update Password": "更改密碼",
|
||||||
|
"Update your account's profile information and email address.": "更新您的帳號姓名、手機號碼與電子郵件地址。",
|
||||||
|
"Upload New Images": "上傳新照片",
|
||||||
|
"Uploading new images will replace all existing images.": "上傳新照片將會取代所有現有照片。",
|
||||||
|
"User": "一般用戶",
|
||||||
|
"user": "一般用戶",
|
||||||
|
"User Info": "用戶資訊",
|
||||||
|
"Username": "使用者帳號",
|
||||||
|
"Users": "帳號數",
|
||||||
|
"Utilization Rate": "機台稼動率",
|
||||||
|
"Valid Until": "合約到期日",
|
||||||
|
"Venue Management": "場地管理",
|
||||||
|
"View Details": "查看詳情",
|
||||||
|
"View Logs": "查看日誌",
|
||||||
|
"vs Yesterday": "較昨日",
|
||||||
|
"Warehouse List": "倉庫清單",
|
||||||
|
"Warehouse List (All)": "倉庫列表(全)",
|
||||||
|
"Warehouse List (Individual)": "倉庫列表(個)",
|
||||||
|
"Warehouse Management": "倉庫管理",
|
||||||
|
"Warehouse Permissions": "倉庫管理權限",
|
||||||
|
"warehouses": "倉庫管理",
|
||||||
|
"Warning": "警告",
|
||||||
|
"Warning: You are editing your own role!": "警告:您正在編輯目前使用的角色!",
|
||||||
|
"Welcome Gift": "註冊成效禮",
|
||||||
|
"Yesterday": "昨日",
|
||||||
|
"You cannot assign permissions you do not possess.": "您無法指派您自身不具備的權限。",
|
||||||
|
"You cannot delete your own account.": "您無法刪除自己的帳號。",
|
||||||
|
"Your email address is unverified.": "您的電子郵件地址尚未驗證。",
|
||||||
|
"Your recent account activity": "最近的帳號活動"
|
||||||
}
|
}
|
||||||
@@ -13,159 +13,159 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'accepted' => 'The :attribute field must be accepted.',
|
'accepted' => '必須接受 :attribute。',
|
||||||
'accepted_if' => 'The :attribute field must be accepted when :other is :value.',
|
'accepted_if' => '當 :other 為 :value 時,必須接受 :attribute。',
|
||||||
'active_url' => 'The :attribute field must be a valid URL.',
|
'active_url' => ':attribute 並非有效的 URL。',
|
||||||
'after' => 'The :attribute field must be a date after :date.',
|
'after' => ':attribute 必須在 :date 之後。',
|
||||||
'after_or_equal' => 'The :attribute field must be a date after or equal to :date.',
|
'after_or_equal' => ':attribute 必須在 :date 之後或相等。',
|
||||||
'alpha' => 'The :attribute field must only contain letters.',
|
'alpha' => ':attribute 只能包含字母。',
|
||||||
'alpha_dash' => 'The :attribute field must only contain letters, numbers, dashes, and underscores.',
|
'alpha_dash' => ':attribute 只能包含字母、數字、破折號與底線。',
|
||||||
'alpha_num' => 'The :attribute field must only contain letters and numbers.',
|
'alpha_num' => ':attribute 只能包含字母與數字。',
|
||||||
'any_of' => 'The :attribute field is invalid.',
|
'any_of' => ':attribute 無效。',
|
||||||
'array' => 'The :attribute field must be an array.',
|
'array' => ':attribute 必須是一個陣列。',
|
||||||
'ascii' => 'The :attribute field must only contain single-byte alphanumeric characters and symbols.',
|
'ascii' => ':attribute 只能包含單字節的字母、數字與符號。',
|
||||||
'before' => 'The :attribute field must be a date before :date.',
|
'before' => ':attribute 必須在 :date 之前。',
|
||||||
'before_or_equal' => 'The :attribute field must be a date before or equal to :date.',
|
'before_or_equal' => ':attribute 必須在 :date 之前或相等。',
|
||||||
'between' => [
|
'between' => [
|
||||||
'array' => 'The :attribute field must have between :min and :max items.',
|
'array' => ':attribute 必須包含 :min 至 :max 個項目。',
|
||||||
'file' => 'The :attribute field must be between :min and :max kilobytes.',
|
'file' => ':attribute 必須介於 :min 至 :max KB 之間。',
|
||||||
'numeric' => 'The :attribute field must be between :min and :max.',
|
'numeric' => ':attribute 必須介於 :min 至 :max 之間。',
|
||||||
'string' => 'The :attribute field must be between :min and :max characters.',
|
'string' => ':attribute 必須介於 :min 至 :max 個字元之間。',
|
||||||
],
|
],
|
||||||
'boolean' => 'The :attribute field must be true or false.',
|
'boolean' => ':attribute 必須為布林值。',
|
||||||
'can' => 'The :attribute field contains an unauthorized value.',
|
'can' => ':attribute 包含未授權的值。',
|
||||||
'confirmed' => 'The :attribute field confirmation does not match.',
|
'confirmed' => ':attribute 確認欄位不符。',
|
||||||
'contains' => 'The :attribute field is missing a required value.',
|
'contains' => ':attribute 缺少必要的值。',
|
||||||
'current_password' => 'The password is incorrect.',
|
'current_password' => '目前的密碼不正確。',
|
||||||
'date' => 'The :attribute field must be a valid date.',
|
'date' => ':attribute 並非有效的日期。',
|
||||||
'date_equals' => 'The :attribute field must be a date equal to :date.',
|
'date_equals' => ':attribute 必須等於 :date。',
|
||||||
'date_format' => 'The :attribute field must match the format :format.',
|
'date_format' => ':attribute 不符合格式 :format。',
|
||||||
'decimal' => 'The :attribute field must have :decimal decimal places.',
|
'decimal' => ':attribute 必須有 :decimal 位小數。',
|
||||||
'declined' => 'The :attribute field must be declined.',
|
'declined' => ':attribute 必須拒絕。',
|
||||||
'declined_if' => 'The :attribute field must be declined when :other is :value.',
|
'declined_if' => '當 :other 為 :value 時,:attribute 必須拒絕。',
|
||||||
'different' => 'The :attribute field and :other must be different.',
|
'different' => ':attribute 與 :other 必須不同。',
|
||||||
'digits' => 'The :attribute field must be :digits digits.',
|
'digits' => ':attribute 必須是 :digits 位數。',
|
||||||
'digits_between' => 'The :attribute field must be between :min and :max digits.',
|
'digits_between' => ':attribute 必須介於 :min 至 :max 位數之間。',
|
||||||
'dimensions' => 'The :attribute field has invalid image dimensions.',
|
'dimensions' => ':attribute 圖片尺寸無效。',
|
||||||
'distinct' => 'The :attribute field has a duplicate value.',
|
'distinct' => ':attribute 欄位含有重複的值。',
|
||||||
'doesnt_contain' => 'The :attribute field must not contain any of the following: :values.',
|
'doesnt_contain' => ':attribute 不得包含以下任何值::values。',
|
||||||
'doesnt_end_with' => 'The :attribute field must not end with one of the following: :values.',
|
'doesnt_end_with' => ':attribute 不得以以下任何值結尾::values。',
|
||||||
'doesnt_start_with' => 'The :attribute field must not start with one of the following: :values.',
|
'doesnt_start_with' => ':attribute 不得以以下任何值開頭::values。',
|
||||||
'email' => 'The :attribute field must be a valid email address.',
|
'email' => ':attribute 必須是有效的電子郵件地址。',
|
||||||
'encoding' => 'The :attribute field must be encoded in :encoding.',
|
'encoding' => ':attribute 必須以 :encoding 編碼。',
|
||||||
'ends_with' => 'The :attribute field must end with one of the following: :values.',
|
'ends_with' => ':attribute 必須以以下任一值結尾::values。',
|
||||||
'enum' => 'The selected :attribute is invalid.',
|
'enum' => '所選的 :attribute 無效。',
|
||||||
'exists' => 'The selected :attribute is invalid.',
|
'exists' => '所選的 :attribute 無效。',
|
||||||
'extensions' => 'The :attribute field must have one of the following extensions: :values.',
|
'extensions' => ':attribute 必須是以下副檔名之一::values。',
|
||||||
'file' => 'The :attribute field must be a file.',
|
'file' => ':attribute 必須是一個檔案。',
|
||||||
'filled' => 'The :attribute field must have a value.',
|
'filled' => ':attribute 不能為空。',
|
||||||
'gt' => [
|
'gt' => [
|
||||||
'array' => 'The :attribute field must have more than :value items.',
|
'array' => ':attribute 必須包含超過 :value 個項目。',
|
||||||
'file' => 'The :attribute field must be greater than :value kilobytes.',
|
'file' => ':attribute 必須大於 :value KB。',
|
||||||
'numeric' => 'The :attribute field must be greater than :value.',
|
'numeric' => ':attribute 必須大於 :value。',
|
||||||
'string' => 'The :attribute field must be greater than :value characters.',
|
'string' => ':attribute 必須超過 :value 個字元。',
|
||||||
],
|
],
|
||||||
'gte' => [
|
'gte' => [
|
||||||
'array' => 'The :attribute field must have :value items or more.',
|
'array' => ':attribute 必須包含 :value 個以上項目。',
|
||||||
'file' => 'The :attribute field must be greater than or equal to :value kilobytes.',
|
'file' => ':attribute 必須大於或等於 :value KB。',
|
||||||
'numeric' => 'The :attribute field must be greater than or equal to :value.',
|
'numeric' => ':attribute 必須大於或等於 :value。',
|
||||||
'string' => 'The :attribute field must be greater than or equal to :value characters.',
|
'string' => ':attribute 必須大於或等於 :value 個字元。',
|
||||||
],
|
],
|
||||||
'hex_color' => 'The :attribute field must be a valid hexadecimal color.',
|
'hex_color' => ':attribute 必須是有效的十六進位色碼。',
|
||||||
'image' => 'The :attribute field must be an image.',
|
'image' => ':attribute 必須是一張圖片。',
|
||||||
'in' => 'The selected :attribute is invalid.',
|
'in' => '所選的 :attribute 無效。',
|
||||||
'in_array' => 'The :attribute field must exist in :other.',
|
'in_array' => ':attribute 必須存在於 :other 之中。',
|
||||||
'in_array_keys' => 'The :attribute field must contain at least one of the following keys: :values.',
|
'in_array_keys' => ':attribute 必須包含以下至少一個鍵::values。',
|
||||||
'integer' => 'The :attribute field must be an integer.',
|
'integer' => ':attribute 必須是整數。',
|
||||||
'ip' => 'The :attribute field must be a valid IP address.',
|
'ip' => ':attribute 必須是有效的 IP 位址。',
|
||||||
'ipv4' => 'The :attribute field must be a valid IPv4 address.',
|
'ipv4' => ':attribute 必須是有效的 IPv4 位址。',
|
||||||
'ipv6' => 'The :attribute field must be a valid IPv6 address.',
|
'ipv6' => ':attribute 必須是有效的 IPv6 位址。',
|
||||||
'json' => 'The :attribute field must be a valid JSON string.',
|
'json' => ':attribute 必須是有效的 JSON 字串。',
|
||||||
'list' => 'The :attribute field must be a list.',
|
'list' => ':attribute 必須是一個列表。',
|
||||||
'lowercase' => 'The :attribute field must be lowercase.',
|
'lowercase' => ':attribute 必須是小寫。',
|
||||||
'lt' => [
|
'lt' => [
|
||||||
'array' => 'The :attribute field must have less than :value items.',
|
'array' => ':attribute 必須包含少於 :value 個項目。',
|
||||||
'file' => 'The :attribute field must be less than :value kilobytes.',
|
'file' => ':attribute 必須小於 :value KB。',
|
||||||
'numeric' => 'The :attribute field must be less than :value.',
|
'numeric' => ':attribute 必須小於 :value。',
|
||||||
'string' => 'The :attribute field must be less than :value characters.',
|
'string' => ':attribute 必須少於 :value 個字元。',
|
||||||
],
|
],
|
||||||
'lte' => [
|
'lte' => [
|
||||||
'array' => 'The :attribute field must not have more than :value items.',
|
'array' => ':attribute 不得包含超過 :value 個項目。',
|
||||||
'file' => 'The :attribute field must be less than or equal to :value kilobytes.',
|
'file' => ':attribute 必須小於或等於 :value KB。',
|
||||||
'numeric' => 'The :attribute field must be less than or equal to :value.',
|
'numeric' => ':attribute 必須小於或等於 :value。',
|
||||||
'string' => 'The :attribute field must be less than or equal to :value characters.',
|
'string' => ':attribute 必須小於或等於 :value 個字元。',
|
||||||
],
|
],
|
||||||
'mac_address' => 'The :attribute field must be a valid MAC address.',
|
'mac_address' => ':attribute 必須是有效的 MAC 位址。',
|
||||||
'max' => [
|
'max' => [
|
||||||
'array' => 'The :attribute field must not have more than :max items.',
|
'array' => ':attribute 不得超過 :max 個項目。',
|
||||||
'file' => 'The :attribute field must not be greater than :max kilobytes.',
|
'file' => ':attribute 不得大於 :max KB。',
|
||||||
'numeric' => 'The :attribute field must not be greater than :max.',
|
'numeric' => ':attribute 不得大於 :max。',
|
||||||
'string' => 'The :attribute field must not be greater than :max characters.',
|
'string' => ':attribute 不得超過 :max 個字元。',
|
||||||
],
|
],
|
||||||
'max_digits' => 'The :attribute field must not have more than :max digits.',
|
'max_digits' => ':attribute 不得超過 :max 位數。',
|
||||||
'mimes' => 'The :attribute field must be a file of type: :values.',
|
'mimes' => ':attribute 必須是以下檔案類型::values。',
|
||||||
'mimetypes' => 'The :attribute field must be a file of type: :values.',
|
'mimetypes' => ':attribute 必須是以下檔案類型::values。',
|
||||||
'min' => [
|
'min' => [
|
||||||
'array' => 'The :attribute field must have at least :min items.',
|
'array' => ':attribute 至少需要 :min 個項目。',
|
||||||
'file' => 'The :attribute field must be at least :min kilobytes.',
|
'file' => ':attribute 至少需要 :min KB。',
|
||||||
'numeric' => 'The :attribute field must be at least :min.',
|
'numeric' => ':attribute 不得小於 :min。',
|
||||||
'string' => 'The :attribute field must be at least :min characters.',
|
'string' => ':attribute 至少需要 :min 個字元。',
|
||||||
],
|
],
|
||||||
'min_digits' => 'The :attribute field must have at least :min digits.',
|
'min_digits' => ':attribute 至少需要 :min 位數。',
|
||||||
'missing' => 'The :attribute field must be missing.',
|
'missing' => ':attribute 必須不存在。',
|
||||||
'missing_if' => 'The :attribute field must be missing when :other is :value.',
|
'missing_if' => '當 :other 為 :value 時,:attribute 必須不存在。',
|
||||||
'missing_unless' => 'The :attribute field must be missing unless :other is :value.',
|
'missing_unless' => '除非 :other 為 :value,否則 :attribute 必須不存在。',
|
||||||
'missing_with' => 'The :attribute field must be missing when :values is present.',
|
'missing_with' => '當 :values 存在時,:attribute 必須不存在。',
|
||||||
'missing_with_all' => 'The :attribute field must be missing when :values are present.',
|
'missing_with_all' => '當 :values 都存在時,:attribute 必須不存在。',
|
||||||
'multiple_of' => 'The :attribute field must be a multiple of :value.',
|
'multiple_of' => ':attribute 必須是 :value 的倍數。',
|
||||||
'not_in' => 'The selected :attribute is invalid.',
|
'not_in' => '所選的 :attribute 無效。',
|
||||||
'not_regex' => 'The :attribute field format is invalid.',
|
'not_regex' => ':attribute 格式無效。',
|
||||||
'numeric' => 'The :attribute field must be a number.',
|
'numeric' => ':attribute 必須是數字。',
|
||||||
'password' => [
|
'password' => [
|
||||||
'letters' => 'The :attribute field must contain at least one letter.',
|
'letters' => ':attribute 必須包含至少一個字母。',
|
||||||
'mixed' => 'The :attribute field must contain at least one uppercase and one lowercase letter.',
|
'mixed' => ':attribute 必須包含至少一個大寫與一個小寫字母。',
|
||||||
'numbers' => 'The :attribute field must contain at least one number.',
|
'numbers' => ':attribute 必須包含至少一個數字。',
|
||||||
'symbols' => 'The :attribute field must contain at least one symbol.',
|
'symbols' => ':attribute 必須包含至少一個符號。',
|
||||||
'uncompromised' => 'The given :attribute has appeared in a data leak. Please choose a different :attribute.',
|
'uncompromised' => ':attribute 已出現在外洩資料中,請選擇其他 :attribute。',
|
||||||
],
|
],
|
||||||
'present' => 'The :attribute field must be present.',
|
'present' => ':attribute 必須存在。',
|
||||||
'present_if' => 'The :attribute field must be present when :other is :value.',
|
'present_if' => '當 :other 為 :value 時,:attribute 必須存在。',
|
||||||
'present_unless' => 'The :attribute field must be present unless :other is :value.',
|
'present_unless' => '除非 :other 為 :value,否則 :attribute 必須存在。',
|
||||||
'present_with' => 'The :attribute field must be present when :values is present.',
|
'present_with' => '當 :values 存在時,:attribute 必須存在。',
|
||||||
'present_with_all' => 'The :attribute field must be present when :values are present.',
|
'present_with_all' => '當 :values 都存在時,:attribute 必須存在。',
|
||||||
'prohibited' => 'The :attribute field is prohibited.',
|
'prohibited' => ':attribute 被禁止使用。',
|
||||||
'prohibited_if' => 'The :attribute field is prohibited when :other is :value.',
|
'prohibited_if' => '當 :other 為 :value 時,:attribute 被禁止使用。',
|
||||||
'prohibited_if_accepted' => 'The :attribute field is prohibited when :other is accepted.',
|
'prohibited_if_accepted' => '當 :other 被接受時,:attribute 被禁止使用。',
|
||||||
'prohibited_if_declined' => 'The :attribute field is prohibited when :other is declined.',
|
'prohibited_if_declined' => '當 :other 被拒絕時,:attribute 被禁止使用。',
|
||||||
'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.',
|
'prohibited_unless' => '除非 :other 在 :values 之中,否則 :attribute 被禁止使用。',
|
||||||
'prohibits' => 'The :attribute field prohibits :other from being present.',
|
'prohibits' => ':attribute 禁止 :other 存在。',
|
||||||
'regex' => 'The :attribute field format is invalid.',
|
'regex' => ':attribute 格式無效。',
|
||||||
'required' => 'The :attribute field is required.',
|
'required' => ':attribute 為必填欄位。',
|
||||||
'required_array_keys' => 'The :attribute field must contain entries for: :values.',
|
'required_array_keys' => ':attribute 必須包含以下項目::values。',
|
||||||
'required_if' => 'The :attribute field is required when :other is :value.',
|
'required_if' => '當 :other 為 :value 時,:attribute 為必填。',
|
||||||
'required_if_accepted' => 'The :attribute field is required when :other is accepted.',
|
'required_if_accepted' => '當 :other 被接受時,:attribute 為必填。',
|
||||||
'required_if_declined' => 'The :attribute field is required when :other is declined.',
|
'required_if_declined' => '當 :other 被拒絕時,:attribute 為必填。',
|
||||||
'required_unless' => 'The :attribute field is required unless :other is in :values.',
|
'required_unless' => '除非 :other 在 :values 之中,否則 :attribute 為必填。',
|
||||||
'required_with' => 'The :attribute field is required when :values is present.',
|
'required_with' => '當 :values 存在時,:attribute 為必填。',
|
||||||
'required_with_all' => 'The :attribute field is required when :values are present.',
|
'required_with_all' => '當 :values 都存在時,:attribute 為必填。',
|
||||||
'required_without' => 'The :attribute field is required when :values is not present.',
|
'required_without' => '當 :values 不存在時,:attribute 為必填。',
|
||||||
'required_without_all' => 'The :attribute field is required when none of :values are present.',
|
'required_without_all' => '當 :values 都不存在時,:attribute 為必填。',
|
||||||
'same' => 'The :attribute field must match :other.',
|
'same' => ':attribute 必須與 :other 相符。',
|
||||||
'size' => [
|
'size' => [
|
||||||
'array' => 'The :attribute field must contain :size items.',
|
'array' => ':attribute 必須包含 :size 個項目。',
|
||||||
'file' => 'The :attribute field must be :size kilobytes.',
|
'file' => ':attribute 必須是 :size KB。',
|
||||||
'numeric' => 'The :attribute field must be :size.',
|
'numeric' => ':attribute 必須是 :size。',
|
||||||
'string' => 'The :attribute field must be :size characters.',
|
'string' => ':attribute 必須是 :size 個字元。',
|
||||||
],
|
],
|
||||||
'starts_with' => 'The :attribute field must start with one of the following: :values.',
|
'starts_with' => ':attribute 必須以以下任一值開頭::values。',
|
||||||
'string' => 'The :attribute field must be a string.',
|
'string' => ':attribute 必須是字串。',
|
||||||
'timezone' => 'The :attribute field must be a valid timezone.',
|
'timezone' => ':attribute 必須是有效的時區。',
|
||||||
'unique' => 'The :attribute has already been taken.',
|
'unique' => ':attribute 已被使用。',
|
||||||
'uploaded' => 'The :attribute failed to upload.',
|
'uploaded' => ':attribute 上傳失敗。',
|
||||||
'uppercase' => 'The :attribute field must be uppercase.',
|
'uppercase' => ':attribute 必須是大寫。',
|
||||||
'url' => 'The :attribute field must be a valid URL.',
|
'url' => ':attribute 必須是有效的 URL。',
|
||||||
'ulid' => 'The :attribute field must be a valid ULID.',
|
'ulid' => ':attribute 必須是有效的 ULID。',
|
||||||
'uuid' => 'The :attribute field must be a valid UUID.',
|
'uuid' => ':attribute 必須是有效的 UUID。',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@@ -195,6 +195,13 @@ return [
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'attributes' => [],
|
'attributes' => [
|
||||||
|
'name' => '姓名',
|
||||||
|
'email' => '電子郵件',
|
||||||
|
'password' => '密碼',
|
||||||
|
'current_password' => '目前密碼',
|
||||||
|
'password_confirmation' => '確認密碼',
|
||||||
|
'phone' => '電話',
|
||||||
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,72 +1,92 @@
|
|||||||
@extends('layouts.admin')
|
@extends('layouts.admin')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="space-y-8 pb-20">
|
<div class="space-y-2 pb-20">
|
||||||
<!-- Header -->
|
|
||||||
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-6">
|
|
||||||
|
<!-- Header Section -->
|
||||||
|
<div class="flex flex-col md:flex-row md:items-center justify-between gap-4 mb-8">
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
<a href="{{ route('admin.basic-settings.machines.index') }}" class="p-2.5 rounded-xl bg-white dark:bg-slate-900 border border-slate-100 dark:border-slate-800 text-slate-500 hover:text-cyan-500 transition-all shadow-sm">
|
<a href="{{ route('admin.basic-settings.machines.index') }}"
|
||||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18"/></svg>
|
class="inline-flex items-center justify-center w-10 h-10 rounded-xl bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 text-slate-500 hover:text-cyan-500 hover:border-cyan-500/20 transition-all shadow-sm group">
|
||||||
|
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5L3 12m0 0l7.5-7.5M3 12h18"/>
|
||||||
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-3xl font-black text-slate-800 dark:text-white tracking-tight font-display">{{ __('Edit Machine Settings') }}</h1>
|
<h1 class="text-2xl font-black text-slate-800 dark:text-white tracking-tight items-center flex gap-3 outfit-font">
|
||||||
<p class="text-xs font-bold text-slate-500 dark:text-slate-400 mt-1 uppercase tracking-widest">{{ $machine->name }} / {{ $machine->serial_no }}</p>
|
{{ __('Edit Machine') }}
|
||||||
|
</h1>
|
||||||
|
<p class="text-xs font-bold text-slate-500 dark:text-slate-400 mt-1.5 flex items-center gap-2 uppercase tracking-widest leading-none">
|
||||||
|
<span class="inline-flex items-center px-2 py-1 rounded-lg bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300 border border-slate-200 dark:border-slate-800 font-mono tracking-tighter">
|
||||||
|
{{ $machine->name }} / {{ $machine->serial_no }}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<button type="submit" form="edit-form" class="btn-luxury-primary px-8 flex items-center gap-2">
|
<button type="submit" form="edit-form" class="btn-luxury-primary flex items-center gap-2">
|
||||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5"/></svg>
|
<svg class="w-4 h-4 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="m4.5 12.75 6 6 9-13.5" />
|
||||||
|
</svg>
|
||||||
<span>{{ __('Save Changes') }}</span>
|
<span>{{ __('Save Changes') }}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form id="edit-form" action="{{ route('admin.basic-settings.machines.update', $machine) }}" method="POST" enctype="multipart/form-data" class="space-y-8">
|
<form id="edit-form" action="{{ route('admin.basic-settings.machines.update', $machine) }}" method="POST" enctype="multipart/form-data" class="space-y-6">
|
||||||
@csrf
|
@csrf
|
||||||
@method('PUT')
|
@method('PUT')
|
||||||
|
|
||||||
<!-- Validation Errors -->
|
<!-- Validation Errors -->
|
||||||
@if ($errors->any())
|
@if ($errors->any())
|
||||||
<div class="luxury-card p-6 bg-rose-50/50 dark:bg-rose-500/5 border-rose-100 dark:border-rose-500/20 mb-8 animate-luxury-in">
|
<div class="luxury-card p-6 bg-rose-500/5 border-rose-500/10 mb-8 animate-luxury-in">
|
||||||
<div class="flex items-center gap-3 mb-4 text-rose-600 dark:text-rose-400">
|
<div class="flex items-center gap-3 mb-4 text-rose-500">
|
||||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z"/></svg>
|
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<h4 class="font-black text-sm tracking-tight italic">{{ __('Some fields need attention') }}</h4>
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z"/>
|
||||||
|
</svg>
|
||||||
|
<h4 class="font-black text-sm tracking-tight capitalize">{{ __('Some fields need attention') }}</h4>
|
||||||
</div>
|
</div>
|
||||||
<ul class="space-y-1">
|
<ul class="space-y-2">
|
||||||
@foreach ($errors->all() as $error)
|
@foreach ($errors->all() as $error)
|
||||||
<li class="text-[11px] font-bold text-rose-500/80">{{ $error }}</li>
|
<li class="text-xs font-bold text-rose-500/80 flex items-center gap-2">
|
||||||
|
<span class="w-1 h-1 rounded-full bg-rose-500/40"></span>
|
||||||
|
{{ $error }}
|
||||||
|
</li>
|
||||||
@endforeach
|
@endforeach
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||||
<!-- Left: Basic info & Hardware -->
|
<!-- Left: Basic info & Hardware -->
|
||||||
<div class="lg:col-span-2 space-y-8">
|
<div class="lg:col-span-2 space-y-6">
|
||||||
<!-- Basic Information -->
|
<!-- Basic Information -->
|
||||||
<div class="luxury-card rounded-3xl p-7 animate-luxury-in">
|
<div class="luxury-card rounded-3xl p-7 animate-luxury-in">
|
||||||
<div class="flex items-center gap-3 mb-6">
|
<div class="flex items-center gap-3 mb-8">
|
||||||
<div class="w-10 h-10 rounded-xl bg-emerald-500/10 flex items-center justify-center text-emerald-500">
|
<div class="w-10 h-10 rounded-xl bg-emerald-500/10 flex items-center justify-center text-emerald-500">
|
||||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M15 9h3.75M15 12h3.75M15 15h3.75M4.5 19.5h15a2.25 2.25 0 0 0 2.25-2.25V6.75A2.25 2.25 0 0 0 18.75 4.5H5.25a2.25 2.25 0 0 0-2.25 2.25v10.5A2.25 2.25 0 0 0 4.5 19.5Zm6-10.125a1.875 1.875 0 1 1-3.75 0 1.875 1.875 0 0 1 3.75 0Zm1.294 6.336a6.721 6.721 0 0 1-3.17.789 6.721 6.721 0 0 1-3.168-.789 3.376 3.376 0 0 1 6.338 0Z"/></svg>
|
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15 9h3.75M15 12h3.75M15 15h3.75M4.5 19.5h15a2.25 2.25 0 0 0 2.25-2.25V6.75A2.25 2.25 0 0 0 18.75 4.5H5.25a2.25 2.25 0 0 0-2.25 2.25v10.5A2.25 2.25 0 0 0 4.5 19.5Zm6-10.125a1.875 1.875 0 1 1-3.75 0 1.875 1.875 0 0 1 3.75 0Zm1.294 6.336a6.721 6.721 0 0 1-3.17.789 6.721 6.721 0 0 1-3.168-.789 3.376 3.376 0 0 1 6.338 0Z"/>
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight">{{ __('Basic Information') }}</h3>
|
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight">{{ __('Basic Information') }}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-6">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('Machine Name') }}</label>
|
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Machine Name') }}</label>
|
||||||
<input type="text" name="name" value="{{ old('name', $machine->name) }}" class="luxury-input w-full" required>
|
<input type="text" name="name" value="{{ old('name', $machine->name) }}" class="luxury-input w-full" required>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('Serial Number') }}</label>
|
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Serial Number') }}</label>
|
||||||
<input type="text" value="{{ $machine->serial_no }}" class="luxury-input w-full bg-slate-50/50 dark:bg-slate-900/50 text-slate-400 cursor-not-allowed" readonly>
|
<input type="text" value="{{ $machine->serial_no }}" class="luxury-input w-full bg-slate-50/50 dark:bg-slate-900/50 text-slate-400 cursor-not-allowed" readonly>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('Location') }}</label>
|
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Location') }}</label>
|
||||||
<input type="text" name="location" value="{{ old('location', $machine->location) }}" class="luxury-input w-full" placeholder="{{ __('e.g., Taipei Station') }}">
|
<input type="text" name="location" value="{{ old('location', $machine->location) }}" class="luxury-input w-full" placeholder="{{ __('e.g., Taipei Station') }}">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('Machine Model') }}</label>
|
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Machine Model') }}</label>
|
||||||
<select name="machine_model_id" class="luxury-select w-full" required>
|
<select name="machine_model_id" class="luxury-select w-full" required>
|
||||||
@foreach($models as $model)
|
@foreach($models as $model)
|
||||||
<option value="{{ $model->id }}" {{ old('machine_model_id', $machine->machine_model_id) == $model->id ? 'selected' : '' }}>{{ $model->name }}</option>
|
<option value="{{ $model->id }}" {{ old('machine_model_id', $machine->machine_model_id) == $model->id ? 'selected' : '' }}>{{ $model->name }}</option>
|
||||||
@@ -79,35 +99,37 @@
|
|||||||
<!-- Operational Parameters -->
|
<!-- Operational Parameters -->
|
||||||
<div class="luxury-card rounded-3xl p-8 animate-luxury-in" style="animation-delay: 50ms">
|
<div class="luxury-card rounded-3xl p-8 animate-luxury-in" style="animation-delay: 50ms">
|
||||||
<div class="flex items-center gap-3 mb-8">
|
<div class="flex items-center gap-3 mb-8">
|
||||||
<div class="w-10 h-10 rounded-xl bg-cyan-500/10 flex items-center justify-center text-cyan-500">
|
<div class="w-10 h-10 rounded-xl bg-amber-500/10 flex items-center justify-center text-amber-500">
|
||||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M10.5 6h9.75M10.5 6a1.5 1.5 0 1 1-3 0m3 0a1.5 1.5 0 1 0-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 1 1-3 0m3 0a1.5 1.5 0 1 0-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 1 1-3 0m3 0a1.5 1.5 0 1 0-3 0M3.75 12h7.5"/></svg>
|
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 6h9.75M10.5 6a1.5 1.5 0 1 1-3 0m3 0a1.5 1.5 0 1 0-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 1 1-3 0m3 0a1.5 1.5 0 1 0-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 1 1-3 0m3 0a1.5 1.5 0 1 0-3 0M3.75 12h7.5"/>
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight">{{ __('Operational Parameters') }}</h3>
|
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight">{{ __('Operational Parameters') }}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-6">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('Card Reader Seconds') }}</label>
|
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Card Reader Seconds') }}</label>
|
||||||
<input type="number" name="card_reader_seconds" value="{{ $machine->card_reader_seconds }}" class="luxury-input w-full">
|
<input type="number" name="card_reader_seconds" value="{{ $machine->card_reader_seconds }}" class="luxury-input w-full">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('Payment Buffer Seconds') }}</label>
|
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Payment Buffer Seconds') }}</label>
|
||||||
<input type="number" name="payment_buffer_seconds" value="{{ $machine->payment_buffer_seconds }}" class="luxury-input w-full">
|
<input type="number" name="payment_buffer_seconds" value="{{ $machine->payment_buffer_seconds }}" class="luxury-input w-full">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('Checkout Time 1') }}</label>
|
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Checkout Time 1') }}</label>
|
||||||
<x-luxury-time-input name="card_reader_checkout_time_1" value="{{ $machine->card_reader_checkout_time_1 }}" />
|
<x-luxury-time-input name="card_reader_checkout_time_1" value="{{ $machine->card_reader_checkout_time_1 }}" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('Checkout Time 2') }}</label>
|
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Checkout Time 2') }}</label>
|
||||||
<x-luxury-time-input name="card_reader_checkout_time_2" value="{{ $machine->card_reader_checkout_time_2 }}" />
|
<x-luxury-time-input name="card_reader_checkout_time_2" value="{{ $machine->card_reader_checkout_time_2 }}" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('Heating Start Time') }}</label>
|
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Heating Start Time') }}</label>
|
||||||
<x-luxury-time-input name="heating_start_time" value="{{ $machine->heating_start_time }}" />
|
<x-luxury-time-input name="heating_start_time" value="{{ $machine->heating_start_time }}" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('Heating End Time') }}</label>
|
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Heating End Time') }}</label>
|
||||||
<x-luxury-time-input name="heating_end_time" value="{{ $machine->heating_end_time }}" />
|
<x-luxury-time-input name="heating_end_time" value="{{ $machine->heating_end_time }}" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -115,9 +137,11 @@
|
|||||||
|
|
||||||
<!-- hardware & slot types -->
|
<!-- hardware & slot types -->
|
||||||
<div class="luxury-card rounded-3xl p-7 animate-luxury-in" style="animation-delay: 150ms">
|
<div class="luxury-card rounded-3xl p-7 animate-luxury-in" style="animation-delay: 150ms">
|
||||||
<div class="flex items-center gap-3 mb-6">
|
<div class="flex items-center gap-3 mb-8">
|
||||||
<div class="w-10 h-10 rounded-xl bg-indigo-500/10 flex items-center justify-center text-indigo-500">
|
<div class="w-10 h-10 rounded-xl bg-amber-500/10 flex items-center justify-center text-amber-500">
|
||||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M21 7.5V18a2.25 2.25 0 0 1-2.25 2.25H5.25A2.25 2.25 0 0 1 3 18V7.5m0-4.5h18M3 7.5h18M3 12h18M3 16.5h18"/></svg>
|
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M21 7.5V18a2.25 2.25 0 0 1-2.25 2.25H5.25A2.25 2.25 0 0 1 3 18V7.5m0-4.5h18M3 7.5h18M3 12h18M3 16.5h18"/>
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight">{{ __('Hardware & Slots') }}</h3>
|
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight">{{ __('Hardware & Slots') }}</h3>
|
||||||
</div>
|
</div>
|
||||||
@@ -125,23 +149,23 @@
|
|||||||
<div class="space-y-8">
|
<div class="space-y-8">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-6">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('Card Reader No') }}</label>
|
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Card Reader No') }}</label>
|
||||||
<input type="text" name="card_reader_no" value="{{ $machine->card_reader_no }}" class="luxury-input w-full">
|
<input type="text" name="card_reader_no" value="{{ $machine->card_reader_no }}" class="luxury-input w-full">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('Key No') }}</label>
|
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Key No') }}</label>
|
||||||
<input type="text" name="key_no" value="{{ $machine->key_no }}" class="luxury-input w-full">
|
<input type="text" name="key_no" value="{{ $machine->key_no }}" class="luxury-input w-full">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-4">{{ __('Slot Mechanism (default: Conveyor, check for Spring)') }}</label>
|
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-4">{{ __('Slot Mechanism (default: Conveyor, check for Spring)') }}</label>
|
||||||
<div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-6 gap-4">
|
<div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-6 gap-4">
|
||||||
@foreach([['1-10', 'is_spring_slot_1_10'], ['11-20', 'is_spring_slot_11_20'], ['21-30', 'is_spring_slot_21_30'], ['31-40', 'is_spring_slot_31_40'], ['41-50', 'is_spring_slot_41_50'], ['51-60', 'is_spring_slot_51_60']] as $slot)
|
@foreach([['1-10', 'is_spring_slot_1_10'], ['11-20', 'is_spring_slot_11_20'], ['21-30', 'is_spring_slot_21_30'], ['31-40', 'is_spring_slot_31_40'], ['41-50', 'is_spring_slot_41_50'], ['51-60', 'is_spring_slot_51_60']] as $slot)
|
||||||
<label class="flex items-center gap-3 p-3 rounded-xl border border-slate-100 dark:border-slate-800 bg-slate-50/50 dark:bg-slate-900/50 cursor-pointer hover:border-cyan-500/30 transition-all">
|
<label class="flex items-center gap-3 p-3 rounded-xl border border-slate-100 dark:border-slate-800 bg-slate-50/50 dark:bg-slate-900/50 cursor-pointer hover:border-amber-500/30 transition-all">
|
||||||
<input type="hidden" name="{{ $slot[1] }}" value="0">
|
<input type="hidden" name="{{ $slot[1] }}" value="0">
|
||||||
<input type="checkbox" name="{{ $slot[1] }}" value="1" {{ $machine->{$slot[1]} ? 'checked' : '' }} class="w-4 h-4 rounded text-cyan-500 focus:ring-cyan-500/20">
|
<input type="checkbox" name="{{ $slot[1] }}" value="1" {{ $machine->{$slot[1]} ? 'checked' : '' }} class="w-4 h-4 rounded text-amber-500 focus:ring-amber-500/20">
|
||||||
<span class="text-xs font-black text-slate-600 dark:text-slate-400">{{ $slot[0] }}</span>
|
<span class="text-xs font-bold text-slate-600 dark:text-slate-400">{{ $slot[0] }}</span>
|
||||||
</label>
|
</label>
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
@@ -155,14 +179,16 @@
|
|||||||
<div class="luxury-card rounded-3xl p-8 animate-luxury-in" style="animation-delay: 200ms">
|
<div class="luxury-card rounded-3xl p-8 animate-luxury-in" style="animation-delay: 200ms">
|
||||||
<div class="flex items-center gap-3 mb-8">
|
<div class="flex items-center gap-3 mb-8">
|
||||||
<div class="w-10 h-10 rounded-xl bg-emerald-500/10 flex items-center justify-center text-emerald-500">
|
<div class="w-10 h-10 rounded-xl bg-emerald-500/10 flex items-center justify-center text-emerald-500">
|
||||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M2.25 18.75a60.07 60.07 0 0 1 15.797 2.101c.727.198 1.453-.342 1.453-1.096V18.75M3.75 4.5v.75m0-1.5a.75.75 0 0 1 .75.75v.75m-.75 0H3m.75 0h.75m-1.5 0a.75.75 0 0 1-.75-.75V3M3 10.5v1.5m10.5-3v-4.5m0 4.5h5.25m-5.25 0V10.5m0-1.5a.75.75 0 0 1 .75-.75h.75m-1.5 0H12m.75 0h.75m-1.5 0a.75.75 0 0 1-.75-.75V3.75M12 4.5H3.75a2.25 2.25 0 0 0-2.25 2.25v10.5a2.25 2.25 0 0 0 2.25 2.25h15a2.25 2.25 0 0 0 2.25-2.25V6.75A2.25 2.25 0 0 0 18.75 4.5Z"/></svg>
|
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 18.75a60.07 60.07 0 0 1 15.797 2.101c.727.198 1.453-.342 1.453-1.096V18.75M3.75 4.5v.75m0-1.5a.75.75 0 0 1 .75.75v.75m-.75 0H3m.75 0h.75m-1.5 0a.75.75 0 0 1-.75-.75V3M3 10.5v1.5m10.5-3v-4.5m0 4.5h5.25m-5.25 0V10.5m0-1.5a.75.75 0 0 1 .75-.75h.75m-1.5 0H12m.75 0h.75m-1.5 0a.75.75 0 0 1-.75-.75V3.75M12 4.5H3.75a2.25 2.25 0 0 0-2.25 2.25v10.5a2.25 2.25 0 0 0 2.25 2.25h15a2.25 2.25 0 0 0 2.25-2.25V6.75A2.25 2.25 0 0 0 18.75 4.5Z"/>
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight">{{ __('Payment & Invoice') }}</h3>
|
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight">{{ __('Payment & Invoice') }}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('Payment Config') }}</label>
|
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Payment Config') }}</label>
|
||||||
<select name="payment_config_id" class="luxury-select w-full">
|
<select name="payment_config_id" class="luxury-select w-full">
|
||||||
<option value="">{{ __('Not Used') }}</option>
|
<option value="">{{ __('Not Used') }}</option>
|
||||||
@foreach($paymentConfigs as $config)
|
@foreach($paymentConfigs as $config)
|
||||||
@@ -172,7 +198,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('Invoice Status') }}</label>
|
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Invoice Status') }}</label>
|
||||||
<select name="invoice_status" class="luxury-select w-full">
|
<select name="invoice_status" class="luxury-select w-full">
|
||||||
<option value="0" {{ $machine->invoice_status == 0 ? 'selected' : '' }}>{{ __('No Invoice') }}</option>
|
<option value="0" {{ $machine->invoice_status == 0 ? 'selected' : '' }}>{{ __('No Invoice') }}</option>
|
||||||
<option value="1" {{ $machine->invoice_status == 1 ? 'selected' : '' }}>{{ __('Default Donate') }}</option>
|
<option value="1" {{ $machine->invoice_status == 1 ? 'selected' : '' }}>{{ __('Default Donate') }}</option>
|
||||||
@@ -184,34 +210,36 @@
|
|||||||
|
|
||||||
<div class="luxury-card rounded-3xl p-8 animate-luxury-in" style="animation-delay: 300ms">
|
<div class="luxury-card rounded-3xl p-8 animate-luxury-in" style="animation-delay: 300ms">
|
||||||
<div class="flex items-center gap-3 mb-8">
|
<div class="flex items-center gap-3 mb-8">
|
||||||
<div class="w-10 h-10 rounded-xl bg-sky-500/10 flex items-center justify-center text-sky-500">
|
<div class="w-10 h-10 rounded-xl bg-indigo-500/10 flex items-center justify-center text-indigo-500">
|
||||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z"/></svg>
|
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z"/>
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight">{{ __('Member & External') }}</h3>
|
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight">{{ __('Member & External') }}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
<label class="flex items-center justify-between p-4 rounded-2xl border border-slate-100 dark:border-slate-800 bg-slate-50/30 dark:bg-slate-900/30 cursor-pointer">
|
<label class="flex items-center justify-between p-4 rounded-2xl border border-slate-100 dark:border-slate-800 bg-slate-50/30 dark:bg-slate-900/30 cursor-pointer group">
|
||||||
<div>
|
<div>
|
||||||
<span class="block text-sm font-black text-slate-700 dark:text-slate-200">{{ __('Welcome Gift') }}</span>
|
<span class="block text-sm font-black text-slate-700 dark:text-slate-200 group-hover:text-indigo-500 transition-colors">{{ __('Welcome Gift') }}</span>
|
||||||
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">{{ __('Enabled/Disabled') }}</span>
|
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">{{ __('Enabled/Disabled') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="relative inline-flex items-center cursor-pointer">
|
<div class="relative inline-flex items-center cursor-pointer">
|
||||||
<input type="hidden" name="welcome_gift_enabled" value="0">
|
<input type="hidden" name="welcome_gift_enabled" value="0">
|
||||||
<input type="checkbox" name="welcome_gift_enabled" value="1" {{ $machine->welcome_gift_enabled ? 'checked' : '' }} class="sr-only peer">
|
<input type="checkbox" name="welcome_gift_enabled" value="1" {{ $machine->welcome_gift_enabled ? 'checked' : '' }} class="sr-only peer">
|
||||||
<div class="w-11 h-6 bg-slate-200 dark:bg-slate-700 rounded-full peer peer-focus:ring-4 peer-focus:ring-cyan-300 dark:peer-focus:ring-cyan-800 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-cyan-500 transition-colors"></div>
|
<div class="w-11 h-6 bg-slate-200 dark:bg-slate-700 rounded-full peer peer-focus:ring-4 peer-focus:ring-indigo-500/20 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-indigo-500 transition-colors"></div>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="flex items-center justify-between p-4 rounded-2xl border border-slate-100 dark:border-slate-800 bg-slate-50/30 dark:bg-slate-900/30 cursor-pointer">
|
<label class="flex items-center justify-between p-4 rounded-2xl border border-slate-100 dark:border-slate-800 bg-slate-50/30 dark:bg-slate-900/30 cursor-pointer group">
|
||||||
<div>
|
<div>
|
||||||
<span class="block text-sm font-black text-slate-700 dark:text-slate-200">{{ __('Member System') }}</span>
|
<span class="block text-sm font-black text-slate-700 dark:text-slate-200 group-hover:text-indigo-500 transition-colors">{{ __('Member System') }}</span>
|
||||||
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">{{ __('Enabled/Disabled') }}</span>
|
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">{{ __('Enabled/Disabled') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="relative inline-flex items-center cursor-pointer">
|
<div class="relative inline-flex items-center cursor-pointer">
|
||||||
<input type="hidden" name="member_system_enabled" value="0">
|
<input type="hidden" name="member_system_enabled" value="0">
|
||||||
<input type="checkbox" name="member_system_enabled" value="1" {{ $machine->member_system_enabled ? 'checked' : '' }} class="sr-only peer">
|
<input type="checkbox" name="member_system_enabled" value="1" {{ $machine->member_system_enabled ? 'checked' : '' }} class="sr-only peer">
|
||||||
<div class="w-11 h-6 bg-slate-200 dark:bg-slate-700 rounded-full peer peer-focus:ring-4 peer-focus:ring-cyan-300 dark:peer-focus:ring-cyan-800 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-cyan-500 transition-colors"></div>
|
<div class="w-11 h-6 bg-slate-200 dark:bg-slate-700 rounded-full peer peer-focus:ring-4 peer-focus:ring-indigo-500/20 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-indigo-500 transition-colors"></div>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -46,12 +46,19 @@
|
|||||||
const input = document.getElementsByName('machine_image_' + index)[0];
|
const input = document.getElementsByName('machine_image_' + index)[0];
|
||||||
if (input) input.value = '';
|
if (input) input.value = '';
|
||||||
},
|
},
|
||||||
|
isDeleteConfirmOpen: false,
|
||||||
|
deleteFormAction: '',
|
||||||
|
confirmDelete(action) {
|
||||||
|
this.deleteFormAction = action;
|
||||||
|
this.isDeleteConfirmOpen = true;
|
||||||
|
}
|
||||||
}">
|
}">
|
||||||
<!-- 1. Header Area -->
|
<!-- 1. Header Area -->
|
||||||
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
|
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-3xl font-black text-slate-800 dark:text-white tracking-tight font-display">{{ __('Machine Settings') }}</h1>
|
<h1 class="text-3xl font-black text-slate-800 dark:text-white tracking-tight font-display">{{ __('Machine Settings') }}</h1>
|
||||||
<p class="text-sm font-bold text-slate-500 dark:text-slate-400 mt-1 uppercase tracking-widest">{{ __('Management of operational parameters and models') }}</p>
|
<p class="text-sm font-bold text-slate-500 dark:text-slate-400 mt-1 uppercase tracking-widest">{{
|
||||||
|
__('Management of operational parameters and models') }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
@if($tab === 'machines')
|
@if($tab === 'machines')
|
||||||
@@ -111,19 +118,19 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr class="bg-slate-50/50 dark:bg-slate-900/10">
|
<tr class="bg-slate-50/50 dark:bg-slate-900/10">
|
||||||
<th
|
<th
|
||||||
class="px-6 py-4 text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] border-b border-slate-100 dark:border-slate-800">
|
class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800">
|
||||||
{{ __('Machine Info') }}</th>
|
{{ __('Machine Info') }}</th>
|
||||||
<th
|
<th
|
||||||
class="px-6 py-4 text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] border-b border-slate-100 dark:border-slate-800">
|
class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800">
|
||||||
{{ __('Machine Model') }}</th>
|
{{ __('Machine Model') }}</th>
|
||||||
<th
|
<th
|
||||||
class="px-6 py-4 text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] border-b border-slate-100 dark:border-slate-800">
|
class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800">
|
||||||
{{ __('Status') }}</th>
|
{{ __('Status') }}</th>
|
||||||
<th
|
<th
|
||||||
class="px-6 py-4 text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] border-b border-slate-100 dark:border-slate-800">
|
class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800">
|
||||||
{{ __('Card Reader') }}</th>
|
{{ __('Card Reader') }}</th>
|
||||||
<th
|
<th
|
||||||
class="px-6 py-4 text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] border-b border-slate-100 dark:border-slate-800">
|
class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800">
|
||||||
{{ __('Owner') }}</th>
|
{{ __('Owner') }}</th>
|
||||||
<th
|
<th
|
||||||
class="px-6 py-4 text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] border-b border-slate-100 dark:border-slate-800 text-right">
|
class="px-6 py-4 text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] border-b border-slate-100 dark:border-slate-800 text-right">
|
||||||
@@ -138,13 +145,13 @@
|
|||||||
<div
|
<div
|
||||||
class="w-10 h-10 rounded-xl bg-slate-100 dark:bg-slate-800 flex items-center justify-center text-slate-400 border border-slate-200 dark:border-slate-700 group-hover:bg-cyan-500 group-hover:text-white transition-all duration-300 overflow-hidden">
|
class="w-10 h-10 rounded-xl bg-slate-100 dark:bg-slate-800 flex items-center justify-center text-slate-400 border border-slate-200 dark:border-slate-700 group-hover:bg-cyan-500 group-hover:text-white transition-all duration-300 overflow-hidden">
|
||||||
@if(isset($machine->image_urls[0]))
|
@if(isset($machine->image_urls[0]))
|
||||||
<img src="{{ $machine->image_urls[0] }}" class="w-full h-full object-cover">
|
<img src="{{ $machine->image_urls[0] }}" class="w-full h-full object-cover">
|
||||||
@else
|
@else
|
||||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
||||||
stroke-width="2.5">
|
stroke-width="2.5">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round"
|
<path stroke-linecap="round" stroke-linejoin="round"
|
||||||
d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||||
</svg>
|
</svg>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -199,29 +206,28 @@
|
|||||||
{{ $machine->company->name ?? __('None') }}
|
{{ $machine->company->name ?? __('None') }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-6 text-right space-x-2">
|
<td class="px-6 py-6 text-right flex items-center justify-end gap-2">
|
||||||
<button
|
<button @click="openPhotoModal(@js($machine->only(['id', 'name', 'image_urls'])))"
|
||||||
@click="openPhotoModal(@js($machine->only(['id', 'name', 'image_urls'])))"
|
class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-cyan-500 hover:bg-cyan-500/5 dark:hover:bg-cyan-500/10 border border-transparent hover:border-cyan-500/20 transition-all inline-flex group/btn"
|
||||||
class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-emerald-500 hover:bg-emerald-500/5 border border-transparent hover:border-emerald-500/20 transition-all inline-flex"
|
|
||||||
title="{{ __('Machine Images') }}">
|
title="{{ __('Machine Images') }}">
|
||||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
<svg class="w-4 h-4 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round"
|
<path stroke-linecap="round" stroke-linejoin="round"
|
||||||
d="m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z" />
|
d="m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<a href="{{ route('admin.basic-settings.machines.edit', $machine) }}"
|
<a href="{{ route('admin.basic-settings.machines.edit', $machine) }}"
|
||||||
class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-cyan-500 hover:bg-cyan-500/5 border border-transparent hover:border-cyan-500/20 transition-all inline-flex"
|
class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-cyan-500 hover:bg-cyan-500/5 dark:hover:bg-cyan-500/10 border border-transparent hover:border-cyan-500/20 transition-all inline-flex group/btn"
|
||||||
title="{{ __('Edit Settings') }}">
|
title="{{ __('Edit Settings') }}">
|
||||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
<svg class="w-4 h-4 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round"
|
<path stroke-linecap="round" stroke-linejoin="round"
|
||||||
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
|
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<button
|
<button
|
||||||
@click="openDetail(@js($machine->only(['name', 'serial_no', 'status', 'location', 'last_heartbeat_at', 'card_reader_no', 'card_reader_seconds', 'firmware_version', 'api_token', 'heating_start_time', 'heating_end_time', 'image_urls'])))"
|
@click="openDetail(@js($machine->only(['name', 'serial_no', 'status', 'location', 'last_heartbeat_at', 'card_reader_no', 'card_reader_seconds', 'firmware_version', 'api_token', 'heating_start_time', 'heating_end_time', 'image_urls'])))"
|
||||||
class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-indigo-500 hover:bg-indigo-500/5 border border-transparent hover:border-indigo-500/20 transition-all inline-flex"
|
class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-cyan-500 hover:bg-cyan-500/5 dark:hover:bg-cyan-500/10 border border-transparent hover:border-cyan-500/20 transition-all inline-flex group/btn"
|
||||||
title="{{ __('View Details') }}">
|
title="{{ __('View Details') }}">
|
||||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
<svg class="w-4 h-4 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round"
|
<path stroke-linecap="round" stroke-linejoin="round"
|
||||||
d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z" />
|
d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z" />
|
||||||
</svg>
|
</svg>
|
||||||
@@ -231,7 +237,7 @@
|
|||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="5"
|
<td colspan="5"
|
||||||
class="px-6 py-20 text-center text-slate-500 dark:text-slate-400 font-bold tracking-widest italic uppercase">
|
class="px-6 py-20 text-center text-slate-500 dark:text-slate-400 font-bold tracking-widest uppercase">
|
||||||
{{ __('No data available') }}
|
{{ __('No data available') }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -294,39 +300,39 @@
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-6 text-right space-x-2">
|
<td class="px-6 py-6 text-right space-x-2">
|
||||||
<button
|
<div class="flex items-center justify-end gap-2">
|
||||||
@click="currentModel = @js($model); modelActionUrl = '{{ route('admin.basic-settings.machine-models.update', $model) }}'; showEditModelModal = true"
|
<button @click="currentModel = @js($model->only(['name'])); modelActionUrl = '{{ route('admin.basic-settings.machine-models.update', $model) }}'; showEditModelModal = true"
|
||||||
class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-cyan-500 hover:bg-cyan-500/5 border border-transparent hover:border-cyan-500/20 transition-all inline-flex"
|
class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-cyan-500 dark:hover:text-cyan-400 hover:bg-cyan-500/5 dark:hover:bg-cyan-500/10 border border-transparent hover:border-cyan-500/20 transition-all group/btn"
|
||||||
title="{{ __('Edit') }}">
|
title="{{ __('Edit') }}">
|
||||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
<svg class="w-4 h-4 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
stroke-width="2.5">
|
<path stroke-linecap="round" stroke-linejoin="round"
|
||||||
<path stroke-linecap="round" stroke-linejoin="round"
|
d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10" />
|
||||||
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<form action="{{ route('admin.basic-settings.machine-models.destroy', $model) }}" method="POST"
|
|
||||||
class="inline-block" onsubmit="return confirm('{{ addslashes(__('Are you sure?')) }}')">
|
|
||||||
@csrf
|
|
||||||
@method('DELETE')
|
|
||||||
<button type="submit"
|
|
||||||
class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-rose-500 hover:bg-rose-500/5 border border-transparent hover:border-rose-500/20 transition-all inline-flex"
|
|
||||||
title="{{ __('Delete') }}">
|
|
||||||
<svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
||||||
stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
|
||||||
<path d="M3 6h18" />
|
|
||||||
<path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" />
|
|
||||||
<path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" />
|
|
||||||
<line x1="10" x2="10" y1="11" y2="17" />
|
|
||||||
<line x1="14" x2="14" y1="11" y2="17" />
|
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</form>
|
|
||||||
|
<form :id="'delete-model-form-' + {{ $model->id }}"
|
||||||
|
action="{{ route('admin.basic-settings.machine-models.destroy', $model) }}"
|
||||||
|
method="POST" class="inline">
|
||||||
|
@csrf
|
||||||
|
@method('DELETE')
|
||||||
|
<button type="button"
|
||||||
|
@click="confirmDelete('{{ route('admin.basic-settings.machine-models.destroy', $model) }}')"
|
||||||
|
class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-rose-500 dark:hover:text-rose-400 hover:bg-rose-500/5 dark:hover:bg-rose-500/10 border border-transparent hover:border-rose-500/20 transition-all"
|
||||||
|
title="{{ __('Delete') }}">
|
||||||
|
<svg class="w-4 h-4 stroke-[2.5]" fill="none" stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round"
|
||||||
|
d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="4"
|
<td colspan="4"
|
||||||
class="px-6 py-20 text-center text-slate-500 dark:text-slate-400 font-bold tracking-widest italic uppercase">
|
class="px-6 py-20 text-center text-slate-500 dark:text-slate-400 font-bold tracking-widest uppercase">
|
||||||
{{ __('No data available') }}
|
{{ __('No data available') }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -357,7 +363,8 @@
|
|||||||
class="inline-block align-bottom bg-white dark:bg-slate-900 rounded-3xl text-left overflow-hidden shadow-2xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full animate-luxury-in border border-slate-100 dark:border-slate-800">
|
class="inline-block align-bottom bg-white dark:bg-slate-900 rounded-3xl text-left overflow-hidden shadow-2xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full animate-luxury-in border border-slate-100 dark:border-slate-800">
|
||||||
<div
|
<div
|
||||||
class="px-8 pt-8 pb-6 border-b border-slate-50 dark:border-slate-800/50 flex justify-between items-center">
|
class="px-8 pt-8 pb-6 border-b border-slate-50 dark:border-slate-800/50 flex justify-between items-center">
|
||||||
<h3 class="text-xl font-black text-slate-800 dark:text-white tracking-tight font-display">{{ __('Add Machine') }}</h3>
|
<h3 class="text-xl font-black text-slate-800 dark:text-white tracking-tight font-display">{{ __('Add
|
||||||
|
Machine') }}</h3>
|
||||||
<button @click="showCreateMachineModal = false"
|
<button @click="showCreateMachineModal = false"
|
||||||
class="text-slate-400 hover:text-slate-600 dark:hover:text-slate-200 transition-colors">
|
class="text-slate-400 hover:text-slate-600 dark:hover:text-slate-200 transition-colors">
|
||||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
@@ -417,26 +424,35 @@
|
|||||||
<label
|
<label
|
||||||
class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{
|
class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{
|
||||||
__('Machine Images') }} ({{ __('Max 3') }})</label>
|
__('Machine Images') }} ({{ __('Max 3') }})</label>
|
||||||
<label class="relative flex flex-col items-center justify-center w-full h-32 border-2 border-dashed border-slate-200 dark:border-slate-800 rounded-2xl cursor-pointer bg-slate-50/50 dark:bg-slate-900/50 hover:bg-slate-100 dark:hover:bg-slate-800/80 transition-all group">
|
<label
|
||||||
|
class="relative flex flex-col items-center justify-center w-full h-32 border-2 border-dashed border-slate-200 dark:border-slate-800 rounded-2xl cursor-pointer bg-slate-50/50 dark:bg-slate-900/50 hover:bg-slate-100 dark:hover:bg-slate-800/80 transition-all group">
|
||||||
<template x-if="selectedFileCount === 0">
|
<template x-if="selectedFileCount === 0">
|
||||||
<div class="flex flex-col items-center justify-center pt-5 pb-6">
|
<div class="flex flex-col items-center justify-center pt-5 pb-6">
|
||||||
<svg class="w-8 h-8 mb-3 text-slate-400 group-hover:text-cyan-500 transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-8 h-8 mb-3 text-slate-400 group-hover:text-cyan-500 transition-colors"
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" />
|
fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
|
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" />
|
||||||
</svg>
|
</svg>
|
||||||
<p class="text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-widest">{{ __('Click to upload') }}</p>
|
<p
|
||||||
|
class="text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-widest">
|
||||||
|
{{ __('Click to upload') }}</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template x-if="selectedFileCount > 0">
|
<template x-if="selectedFileCount > 0">
|
||||||
<div class="flex flex-col items-center justify-center pt-5 pb-6">
|
<div class="flex flex-col items-center justify-center pt-5 pb-6">
|
||||||
<div class="w-10 h-10 rounded-full bg-emerald-500/10 flex items-center justify-center text-emerald-500 mb-2">
|
<div
|
||||||
|
class="w-10 h-10 rounded-full bg-emerald-500/10 flex items-center justify-center text-emerald-500 mb-2">
|
||||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M5 13l4 4L19 7" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5"
|
||||||
|
d="M5 13l4 4L19 7" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-xs font-black text-emerald-500 uppercase tracking-widest" x-text="`${selectedFileCount} {{ __('files selected') }}`"></p>
|
<p class="text-xs font-black text-emerald-500 uppercase tracking-widest"
|
||||||
|
x-text="`${selectedFileCount} {{ __('files selected') }}`"></p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<input type="file" name="images[]" multiple accept="image/*" class="hidden" @change="handleFileChange">
|
<input type="file" name="images[]" multiple accept="image/*" class="hidden"
|
||||||
|
@change="handleFileChange">
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -467,7 +483,8 @@
|
|||||||
class="inline-block align-bottom bg-white dark:bg-slate-900 rounded-3xl text-left overflow-hidden shadow-2xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full animate-luxury-in border border-slate-100 dark:border-slate-800">
|
class="inline-block align-bottom bg-white dark:bg-slate-900 rounded-3xl text-left overflow-hidden shadow-2xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full animate-luxury-in border border-slate-100 dark:border-slate-800">
|
||||||
<div
|
<div
|
||||||
class="px-8 pt-8 pb-6 border-b border-slate-50 dark:border-slate-800/50 flex justify-between items-center">
|
class="px-8 pt-8 pb-6 border-b border-slate-50 dark:border-slate-800/50 flex justify-between items-center">
|
||||||
<h3 class="text-xl font-black text-slate-800 dark:text-white tracking-tight font-display">{{ __('Add Machine Model') }}</h3>
|
<h3 class="text-xl font-black text-slate-800 dark:text-white tracking-tight font-display">{{ __('Add
|
||||||
|
Machine Model') }}</h3>
|
||||||
<button @click="showCreateModelModal = false"
|
<button @click="showCreateModelModal = false"
|
||||||
class="text-slate-400 hover:text-slate-600 dark:hover:text-slate-200 transition-colors">
|
class="text-slate-400 hover:text-slate-600 dark:hover:text-slate-200 transition-colors">
|
||||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
@@ -560,7 +577,8 @@
|
|||||||
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" @click="showPhotoModal = false">
|
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" @click="showPhotoModal = false">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="fixed inset-0 z-[160] overflow-y-auto pointer-events-none p-4 md:p-8 flex items-center justify-center">
|
<div
|
||||||
|
class="fixed inset-0 z-[160] overflow-y-auto pointer-events-none p-4 md:p-8 flex items-center justify-center">
|
||||||
<div
|
<div
|
||||||
class="w-full max-w-2xl bg-white dark:bg-slate-900 rounded-[2.5rem] shadow-2xl border border-slate-100 dark:border-slate-800 pointer-events-auto overflow-hidden animate-luxury-in">
|
class="w-full max-w-2xl bg-white dark:bg-slate-900 rounded-[2.5rem] shadow-2xl border border-slate-100 dark:border-slate-800 pointer-events-auto overflow-hidden animate-luxury-in">
|
||||||
<div
|
<div
|
||||||
@@ -579,7 +597,8 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form :action="'{{ route('admin.basic-settings.machines.photos.update', ':id') }}'.replace(':id', currentMachine?.id)"
|
<form
|
||||||
|
:action="'{{ route('admin.basic-settings.machines.photos.update', ':id') }}'.replace(':id', currentMachine?.id)"
|
||||||
method="POST" enctype="multipart/form-data">
|
method="POST" enctype="multipart/form-data">
|
||||||
@csrf
|
@csrf
|
||||||
@method('PATCH')
|
@method('PATCH')
|
||||||
@@ -588,16 +607,18 @@
|
|||||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||||
<template x-for="i in [0, 1, 2]" :key="i">
|
<template x-for="i in [0, 1, 2]" :key="i">
|
||||||
<div class="space-y-3">
|
<div class="space-y-3">
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em]"
|
<label
|
||||||
|
class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em]"
|
||||||
x-text="'{{ __('Photo Slot') }} ' + (i + 1)"></label>
|
x-text="'{{ __('Photo Slot') }} ' + (i + 1)"></label>
|
||||||
|
|
||||||
<div class="relative group aspect-square rounded-[2rem] overflow-hidden border-2 border-dashed border-slate-200 dark:border-slate-800 hover:border-emerald-500/50 transition-all bg-slate-50/50 dark:bg-slate-900/50 flex flex-col items-center justify-center cursor-pointer"
|
<div class="relative group aspect-square rounded-[2rem] overflow-hidden border-2 border-dashed border-slate-200 dark:border-slate-800 hover:border-emerald-500/50 transition-all bg-slate-50/50 dark:bg-slate-900/50 flex flex-col items-center justify-center cursor-pointer"
|
||||||
@click="$el.querySelector('input').click()"> <template
|
@click="$el.querySelector('input').click()"> <template
|
||||||
x-if="(selectedFiles[i] || (currentMachine?.image_urls && currentMachine.image_urls[i])) && !deletedPhotos[i]">
|
x-if="(selectedFiles[i] || (currentMachine?.image_urls && currentMachine.image_urls[i])) && !deletedPhotos[i]">
|
||||||
<div class="absolute inset-0 w-full h-full">
|
<div class="absolute inset-0 w-full h-full">
|
||||||
<img :src="selectedFiles[i] || currentMachine.image_urls[i]"
|
<img :src="selectedFiles[i] || currentMachine.image_urls[i]"
|
||||||
class="absolute inset-0 w-full h-full object-cover transition-transform duration-700 group-hover:scale-110">
|
class="absolute inset-0 w-full h-full object-cover transition-transform duration-700 group-hover:scale-110">
|
||||||
<div class="absolute inset-0 bg-slate-900/60 backdrop-blur-[2px] opacity-0 group-hover:opacity-100 transition-all flex flex-col items-center justify-center gap-3">
|
<div
|
||||||
|
class="absolute inset-0 bg-slate-900/60 backdrop-blur-[2px] opacity-0 group-hover:opacity-100 transition-all flex flex-col items-center justify-center gap-3">
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="bg-white text-emerald-600 px-5 py-2.5 rounded-xl text-xs font-black uppercase tracking-widest shadow-xl transform hover:scale-105 transition-all"
|
class="bg-white text-emerald-600 px-5 py-2.5 rounded-xl text-xs font-black uppercase tracking-widest shadow-xl transform hover:scale-105 transition-all"
|
||||||
@click.stop="$el.closest('.group').querySelector('input').click()">
|
@click.stop="$el.closest('.group').querySelector('input').click()">
|
||||||
@@ -612,20 +633,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template x-if="!selectedFiles[i] && !(currentMachine?.image_urls && currentMachine.image_urls[i]) || deletedPhotos[i]">
|
<template
|
||||||
|
x-if="!selectedFiles[i] && !(currentMachine?.image_urls && currentMachine.image_urls[i]) || deletedPhotos[i]">
|
||||||
<div class="flex flex-col items-center gap-3">
|
<div class="flex flex-col items-center gap-3">
|
||||||
<div class="w-12 h-12 rounded-full bg-slate-100 dark:bg-slate-800 flex items-center justify-center text-slate-400 group-hover:bg-emerald-500 group-hover:text-white transition-all">
|
<div
|
||||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
class="w-12 h-12 rounded-full bg-slate-100 dark:bg-slate-800 flex items-center justify-center text-slate-400 group-hover:bg-emerald-500 group-hover:text-white transition-all">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
|
<svg class="w-6 h-6" fill="none" stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round"
|
||||||
|
stroke-width="2" d="M12 4v16m8-8H4" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<span class="text-[10px] font-bold text-slate-400 dark:text-slate-500 uppercase tracking-widest" x-text="'Slot ' + (i + 1)"></span>
|
<span
|
||||||
|
class="text-[10px] font-bold text-slate-400 dark:text-slate-500 uppercase tracking-widest"
|
||||||
|
x-text="'Slot ' + (i + 1)"></span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<input type="file" :name="'machine_image_' + i" class="hidden"
|
<input type="file" :name="'machine_image_' + i" class="hidden" accept="image/*"
|
||||||
accept="image/*" @change="handlePhotoFileChange($event, i)">
|
@change="handlePhotoFileChange($event, i)">
|
||||||
<input type="hidden" :name="'delete_photo_' + i" :value="deletedPhotos[i] ? '1' : '0'">
|
<input type="hidden" :name="'delete_photo_' + i"
|
||||||
|
:value="deletedPhotos[i] ? '1' : '0'">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -639,7 +667,8 @@
|
|||||||
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-xs font-bold text-amber-700 dark:text-amber-300 leading-relaxed text-left flex-1">
|
<p
|
||||||
|
class="text-xs font-bold text-amber-700 dark:text-amber-300 leading-relaxed text-left flex-1">
|
||||||
{{ __('Optimized for display. Supported formats: JPG, PNG, WebP.')
|
{{ __('Optimized for display. Supported formats: JPG, PNG, WebP.')
|
||||||
}}
|
}}
|
||||||
</p>
|
</p>
|
||||||
@@ -660,26 +689,16 @@
|
|||||||
|
|
||||||
<!-- 4.1 Image Lightbox Modal -->
|
<!-- 4.1 Image Lightbox Modal -->
|
||||||
<template x-teleport="body">
|
<template x-teleport="body">
|
||||||
<div x-show="showImageLightbox"
|
<div x-show="showImageLightbox" class="fixed inset-0 z-[200] flex items-center justify-center p-4 sm:p-10" x-cloak>
|
||||||
class="fixed inset-0 z-[200] flex items-center justify-center p-4 sm:p-10"
|
<div x-show="showImageLightbox" x-transition:enter="ease-out duration-300" x-transition:enter-start="opacity-0"
|
||||||
x-cloak>
|
x-transition:enter-end="opacity-100" x-transition:leave="ease-in duration-200"
|
||||||
<div x-show="showImageLightbox"
|
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0" @click="showImageLightbox = false"
|
||||||
x-transition:enter="ease-out duration-300"
|
|
||||||
x-transition:enter-start="opacity-0"
|
|
||||||
x-transition:enter-end="opacity-100"
|
|
||||||
x-transition:leave="ease-in duration-200"
|
|
||||||
x-transition:leave-start="opacity-100"
|
|
||||||
x-transition:leave-end="opacity-0"
|
|
||||||
@click="showImageLightbox = false"
|
|
||||||
class="absolute inset-0 bg-slate-900/90 backdrop-blur-md transition-opacity">
|
class="absolute inset-0 bg-slate-900/90 backdrop-blur-md transition-opacity">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div x-show="showImageLightbox"
|
<div x-show="showImageLightbox" x-transition:enter="ease-out duration-300"
|
||||||
x-transition:enter="ease-out duration-300"
|
x-transition:enter-start="opacity-0 scale-95" x-transition:enter-end="opacity-100 scale-100"
|
||||||
x-transition:enter-start="opacity-0 scale-95"
|
x-transition:leave="ease-in duration-200" x-transition:leave-start="opacity-100 scale-100"
|
||||||
x-transition:enter-end="opacity-100 scale-100"
|
|
||||||
x-transition:leave="ease-in duration-200"
|
|
||||||
x-transition:leave-start="opacity-100 scale-100"
|
|
||||||
x-transition:leave-end="opacity-0 scale-95"
|
x-transition:leave-end="opacity-0 scale-95"
|
||||||
class="relative max-w-5xl w-full max-h-full flex items-center justify-center z-[210]">
|
class="relative max-w-5xl w-full max-h-full flex items-center justify-center z-[210]">
|
||||||
|
|
||||||
@@ -735,14 +754,17 @@
|
|||||||
__('Machine Images') }}</h3>
|
__('Machine Images') }}</h3>
|
||||||
<div class="grid grid-cols-2 gap-3">
|
<div class="grid grid-cols-2 gap-3">
|
||||||
<template x-for="(url, index) in currentMachine.image_urls" :key="index">
|
<template x-for="(url, index) in currentMachine.image_urls" :key="index">
|
||||||
<div
|
<div @click="lightboxImageUrl = url; showImageLightbox = true"
|
||||||
@click="lightboxImageUrl = url; showImageLightbox = true"
|
|
||||||
class="relative group aspect-square rounded-2xl overflow-hidden border border-slate-100 dark:border-slate-800 shadow-sm bg-slate-50 dark:bg-slate-800/50 cursor-pointer">
|
class="relative group aspect-square rounded-2xl overflow-hidden border border-slate-100 dark:border-slate-800 shadow-sm bg-slate-50 dark:bg-slate-800/50 cursor-pointer">
|
||||||
<img :src="url"
|
<img :src="url"
|
||||||
class="absolute inset-0 w-full h-full object-cover transition-transform duration-500 group-hover:scale-110">
|
class="absolute inset-0 w-full h-full object-cover transition-transform duration-500 group-hover:scale-110">
|
||||||
<div class="absolute inset-0 bg-slate-900/40 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
|
<div
|
||||||
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
class="absolute inset-0 bg-slate-900/40 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7" />
|
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -751,7 +773,8 @@
|
|||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
<section class="space-y-6">
|
<section class="space-y-6">
|
||||||
<h3 class="text-[11px] font-black text-cyan-500 uppercase tracking-[0.3em]">{{ __('Hardware & Network') }}</h3>
|
<h3 class="text-[11px] font-black text-cyan-500 uppercase tracking-[0.3em]">{{ __('Hardware
|
||||||
|
& Network') }}</h3>
|
||||||
<div class="grid grid-cols-1 gap-4">
|
<div class="grid grid-cols-1 gap-4">
|
||||||
<div
|
<div
|
||||||
class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80">
|
class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80">
|
||||||
@@ -825,5 +848,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<!-- Global Delete Confirm Modal -->
|
||||||
|
<x-delete-confirm-modal />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@endsection
|
@endsection
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
@extends('layouts.admin')
|
@extends('layouts.admin')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="space-y-10 pb-20">
|
<div class="space-y-6 pb-20">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-6">
|
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-6">
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18"/></svg>
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18"/></svg>
|
||||||
</a>
|
</a>
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-3xl font-black text-slate-800 dark:text-white tracking-tight font-display">{{ __('Create Payment Config') }}</h1>
|
<h1 class="text-2xl font-black text-slate-800 dark:text-white tracking-tight font-display">{{ __('Create Payment Config') }}</h1>
|
||||||
<p class="text-xs font-bold text-slate-500 dark:text-slate-400 mt-1 uppercase tracking-widest">{{ __('Define new third-party payment parameters') }}</p>
|
<p class="text-xs font-bold text-slate-500 dark:text-slate-400 mt-1 uppercase tracking-widest">{{ __('Define new third-party payment parameters') }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -21,12 +21,28 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form id="create-form" action="{{ route('admin.basic-settings.payment-configs.store') }}" method="POST" class="space-y-8">
|
<form id="create-form" action="{{ route('admin.basic-settings.payment-configs.store') }}" method="POST" class="space-y-6">
|
||||||
@csrf
|
@csrf
|
||||||
|
|
||||||
|
@if ($errors->any())
|
||||||
|
<div class="p-5 bg-rose-500/10 border border-rose-500/20 text-rose-600 dark:text-rose-400 rounded-2xl flex items-start gap-4 animate-luxury-in font-bold">
|
||||||
|
<div class="size-8 bg-rose-500/20 rounded-xl flex items-center justify-center flex-shrink-0">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p class="text-sm tracking-wide">{{ __('Please check the following errors:') }}</p>
|
||||||
|
<ul class="mt-1 text-xs list-disc list-inside opacity-80">
|
||||||
|
@foreach ($errors->all() as $error)
|
||||||
|
<li>{{ $error }}</li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-8">
|
<div class="grid grid-cols-1 lg:grid-cols-12 gap-8">
|
||||||
<!-- Left Column: Primary Info -->
|
<!-- Left Column: Primary Info -->
|
||||||
<div class="lg:col-span-12 space-y-8">
|
<div class="lg:col-span-12 space-y-6">
|
||||||
<div class="luxury-card rounded-3xl p-8 animate-luxury-in">
|
<div class="luxury-card rounded-3xl p-8 animate-luxury-in">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||||
<div>
|
<div>
|
||||||
@@ -47,18 +63,18 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- provider groups -->
|
<!-- provider groups -->
|
||||||
<div class="lg:col-span-6 space-y-8">
|
<div class="lg:col-span-6 space-y-6">
|
||||||
<!-- ECPay -->
|
<!-- ECPay -->
|
||||||
<div class="luxury-card rounded-3xl p-8 animate-luxury-in" style="animation-delay: 50ms">
|
<div class="luxury-card rounded-3xl p-8 animate-luxury-in group/card" style="animation-delay: 50ms">
|
||||||
<div class="flex items-center gap-4 mb-8">
|
<div class="flex items-center gap-5 mb-8">
|
||||||
<div class="w-12 h-12 rounded-2xl bg-emerald-50 dark:bg-emerald-500/10 flex items-center justify-center text-emerald-500 border border-emerald-100 dark:border-emerald-500/20 shadow-sm shadow-emerald-500/10">
|
<div class="w-10 h-10 rounded-xl bg-gradient-to-br from-emerald-500/10 to-teal-500/10 flex items-center justify-center text-emerald-500 border border-emerald-500/20 shadow-lg shadow-emerald-500/5 group-hover/card:scale-110 transition-transform duration-500">
|
||||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z"/></svg>
|
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z"/></svg>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-xl font-black text-slate-800 dark:text-white tracking-tight">{{ __('ECPay Invoice') }}</h3>
|
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight font-display uppercase">{{ __('ECPay Invoice') }}</h3>
|
||||||
<p class="text-[10px] font-bold text-slate-400 dark:text-slate-500 uppercase tracking-widest mt-0.5">{{ __('ECPay Invoice Settings Description') }}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('Store ID') }}</label>
|
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('Store ID') }}</label>
|
||||||
@@ -76,16 +92,16 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- E.SUN -->
|
<!-- E.SUN -->
|
||||||
<div class="luxury-card rounded-3xl p-8 animate-luxury-in" style="animation-delay: 100ms">
|
<div class="luxury-card rounded-3xl p-8 animate-luxury-in group/card" style="animation-delay: 100ms">
|
||||||
<div class="flex items-center gap-4 mb-8">
|
<div class="flex items-center gap-5 mb-8">
|
||||||
<div class="w-12 h-12 rounded-2xl bg-indigo-50 dark:bg-indigo-500/10 flex items-center justify-center text-indigo-500 border border-indigo-100 dark:border-indigo-500/20 shadow-sm shadow-indigo-500/10">
|
<div class="w-10 h-10 rounded-xl bg-gradient-to-br from-indigo-500/10 to-blue-500/10 flex items-center justify-center text-indigo-500 border border-indigo-500/20 shadow-lg shadow-indigo-500/5 group-hover/card:scale-110 transition-transform duration-500">
|
||||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5ZM3.75 14.625c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5ZM13.5 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M16.875 12h1.125a3.375 3.375 0 0 1 3.375 3.375v1.125m-11.25 4.5h1.125a3.375 3.375 0 0 0 3.375-3.375V16.5a3.375 3.375 0 0 1 3.375-3.375h1.125m-11.25 4.5h1.125a3.375 3.375 0 0 1 3.375 3.375v1.125m-3.375-1.125h.008v.008h-.008v-.008Zm3.375 3.375h.008v.008h-.008v-.008Zm0-3.375h.008v.008h-.008v-.008Zm-3.375-3.375h.008v.008h-.008v-.008Zm0 3.375h.008v.008h-.008v-.008Z"/></svg>
|
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5ZM3.75 14.625c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5ZM13.5 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M16.875 12h1.125a3.375 3.375 0 0 1 3.375 3.375v1.125m-11.25 4.5h1.125a3.375 3.375 0 0 0 3.375-3.375V16.5a3.375 3.375 0 0 1 3.375-3.375h1.125m-11.25 4.5h1.125a3.375 3.375 0 0 1 3.375 3.375v1.125m-3.375-1.125h.008v.008h-.008v-.008Zm3.375 3.375h.008v.008h-.008v-.008Zm0-3.375h.008v.008h-.008v-.008Zm-3.375-3.375h.008v.008h-.008v-.008Zm0 3.375h.008v.008h-.008v-.008Z"/></svg>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-xl font-black text-slate-800 dark:text-white tracking-tight">{{ __('E.SUN QR Scan') }}</h3>
|
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight font-display uppercase">{{ __('E.SUN QR Scan') }}</h3>
|
||||||
<p class="text-[10px] font-bold text-slate-400 dark:text-slate-500 uppercase tracking-widest mt-0.5">{{ __('E.SUN QR Scan Settings Description') }}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('StoreID') }}</label>
|
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('StoreID') }}</label>
|
||||||
@@ -103,16 +119,16 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- LINE Pay Direct -->
|
<!-- LINE Pay Direct -->
|
||||||
<div class="luxury-card rounded-3xl p-8 animate-luxury-in" style="animation-delay: 150ms">
|
<div class="luxury-card rounded-3xl p-8 animate-luxury-in group/card" style="animation-delay: 150ms">
|
||||||
<div class="flex items-center gap-4 mb-8">
|
<div class="flex items-center gap-5 mb-8">
|
||||||
<div class="w-12 h-12 rounded-2xl bg-emerald-50 dark:bg-emerald-500/10 flex items-center justify-center text-emerald-500 border border-emerald-100 dark:border-emerald-500/20 shadow-sm shadow-emerald-500/10">
|
<div class="w-10 h-10 rounded-xl bg-gradient-to-br from-lime-500/10 to-emerald-500/10 flex items-center justify-center text-emerald-500 border border-emerald-500/20 shadow-lg shadow-emerald-500/5 group-hover/card:scale-110 transition-transform duration-500">
|
||||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 21a9.004 9.004 0 0 0 8.716-6.747M12 21a9.004 9.004 0 0 1-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 0 1 7.843 4.582M12 3a8.997 8.997 0 0 0-7.843 4.582m15.686 0A11.953 11.953 0 0 1 12 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0 1 21 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0 1 12 16.5c-3.162 0-6.133-.815-8.716-2.247m24.408 0a8.959 8.959 0 0 1 .284-2.253m0 2.253C20.46 17.1 16.485 19.5 12 19.5S3.538 17.1 2.284 14.253"/></svg>
|
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 21a9.004 9.004 0 0 0 8.716-6.747M12 21a9.004 9.004 0 0 1-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 0 1 7.843 4.582M12 3a8.997 8.997 0 0 0-7.843 4.582m15.686 0A11.953 11.953 0 0 1 12 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0 1 21 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0 1 12 16.5c-3.162 0-6.133-.815-8.716-2.247m24.408 0a8.959 8.959 0 0 1 .284-2.253m0 2.253C20.46 17.1 16.485 19.5 12 19.5S3.538 17.1 2.284 14.253"/></svg>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-xl font-black text-slate-800 dark:text-white tracking-tight">{{ __('LINE Pay Direct') }}</h3>
|
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight font-display uppercase">{{ __('LINE Pay Direct') }}</h3>
|
||||||
<p class="text-[10px] font-bold text-slate-400 dark:text-slate-500 uppercase tracking-widest mt-0.5">{{ __('LINE Pay Direct Settings Description') }}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('ChannelId') }}</label>
|
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('ChannelId') }}</label>
|
||||||
@@ -126,18 +142,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="lg:col-span-6 space-y-8">
|
<div class="lg:col-span-6 space-y-6">
|
||||||
<!-- Tappay -->
|
<!-- Tappay -->
|
||||||
<div class="luxury-card rounded-3xl p-8 animate-luxury-in" style="animation-delay: 200ms">
|
<div class="luxury-card rounded-3xl p-8 animate-luxury-in group/card" style="animation-delay: 200ms">
|
||||||
<div class="flex items-center gap-4 mb-8">
|
<div class="flex items-center gap-5 mb-8">
|
||||||
<div class="w-12 h-12 rounded-2xl bg-indigo-50 dark:bg-indigo-500/10 flex items-center justify-center text-indigo-500 border border-indigo-100 dark:border-indigo-500/20 shadow-sm shadow-indigo-500/10">
|
<div class="w-10 h-10 rounded-xl bg-gradient-to-br from-indigo-500/10 to-violet-500/10 flex items-center justify-center text-indigo-500 border border-indigo-500/20 shadow-lg shadow-indigo-500/5 group-hover/card:scale-110 transition-transform duration-500">
|
||||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15.91 11.672a.375.375 0 0 1 0 .656l-5.603 3.113a.375.375 0 0 1-.557-.328V8.887c0-.286.307-.466.557-.327l5.603 3.112Z"/></svg>
|
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15.91 11.672a.375.375 0 0 1 0 .656l-5.603 3.113a.375.375 0 0 1-.557-.328V8.887c0-.286.307-.466.557-.327l5.603 3.112Z"/></svg>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-xl font-black text-slate-800 dark:text-white tracking-tight">{{ __('TapPay Integration') }}</h3>
|
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight font-display uppercase">{{ __('TapPay Integration') }}</h3>
|
||||||
<p class="text-[10px] font-bold text-slate-400 dark:text-slate-500 uppercase tracking-widest mt-0.5">{{ __('TapPay Integration Settings Description') }}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
<div class="grid grid-cols-2 gap-4">
|
<div class="grid grid-cols-2 gap-4">
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
@extends('layouts.admin')
|
@extends('layouts.admin')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="space-y-10 pb-20">
|
<div class="space-y-6 pb-20">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-6">
|
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-6">
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18"/></svg>
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18"/></svg>
|
||||||
</a>
|
</a>
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-3xl font-black text-slate-800 dark:text-white tracking-tight font-display">{{ __('Edit Payment Config') }}</h1>
|
<h1 class="text-2xl font-black text-slate-800 dark:text-white tracking-tight font-display">{{ __('Edit Payment Config') }}</h1>
|
||||||
<p class="text-xs font-bold text-slate-500 dark:text-slate-400 mt-1 uppercase tracking-widest">{{ $paymentConfig->name }}</p>
|
<p class="text-xs font-bold text-slate-500 dark:text-slate-400 mt-1 uppercase tracking-widest">{{ $paymentConfig->name }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -21,13 +21,29 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form id="edit-form" action="{{ route('admin.basic-settings.payment-configs.update', $paymentConfig) }}" method="POST" class="space-y-8">
|
<form id="edit-form" action="{{ route('admin.basic-settings.payment-configs.update', $paymentConfig) }}" method="POST" class="space-y-6">
|
||||||
@csrf
|
@csrf
|
||||||
@method('PUT')
|
@method('PUT')
|
||||||
|
|
||||||
|
@if ($errors->any())
|
||||||
|
<div class="p-5 bg-rose-500/10 border border-rose-500/20 text-rose-600 dark:text-rose-400 rounded-2xl flex items-start gap-4 animate-luxury-in font-bold">
|
||||||
|
<div class="size-8 bg-rose-500/20 rounded-xl flex items-center justify-center flex-shrink-0">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p class="text-sm tracking-wide">{{ __('Please check the following errors:') }}</p>
|
||||||
|
<ul class="mt-1 text-xs list-disc list-inside opacity-80">
|
||||||
|
@foreach ($errors->all() as $error)
|
||||||
|
<li>{{ $error }}</li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-8">
|
<div class="grid grid-cols-1 lg:grid-cols-12 gap-8">
|
||||||
<!-- Left Column: Primary Info -->
|
<!-- Left Column: Primary Info -->
|
||||||
<div class="lg:col-span-12 space-y-8">
|
<div class="lg:col-span-12 space-y-6">
|
||||||
<div class="luxury-card rounded-3xl p-8 animate-luxury-in">
|
<div class="luxury-card rounded-3xl p-8 animate-luxury-in">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||||
<div>
|
<div>
|
||||||
@@ -51,18 +67,18 @@
|
|||||||
@php
|
@php
|
||||||
$settings = $paymentConfig->settings ?? [];
|
$settings = $paymentConfig->settings ?? [];
|
||||||
@endphp
|
@endphp
|
||||||
<div class="lg:col-span-6 space-y-8">
|
<div class="lg:col-span-6 space-y-6">
|
||||||
<!-- ECPay -->
|
<!-- ECPay -->
|
||||||
<div class="luxury-card rounded-3xl p-8 animate-luxury-in" style="animation-delay: 50ms">
|
<div class="luxury-card rounded-3xl p-8 animate-luxury-in group/card" style="animation-delay: 50ms">
|
||||||
<div class="flex items-center gap-4 mb-8">
|
<div class="flex items-center gap-5 mb-8">
|
||||||
<div class="w-12 h-12 rounded-2xl bg-emerald-50 dark:bg-emerald-500/10 flex items-center justify-center text-emerald-500 border border-emerald-100 dark:border-emerald-500/20 shadow-sm shadow-emerald-500/10">
|
<div class="w-10 h-10 rounded-xl bg-gradient-to-br from-emerald-500/10 to-teal-500/10 flex items-center justify-center text-emerald-500 border border-emerald-500/20 shadow-lg shadow-emerald-500/5 group-hover/card:scale-110 transition-transform duration-500">
|
||||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z"/></svg>
|
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z"/></svg>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-xl font-black text-slate-800 dark:text-white tracking-tight">{{ __('ECPay Invoice') }}</h3>
|
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight font-display uppercase">{{ __('ECPay Invoice') }}</h3>
|
||||||
<p class="text-[10px] font-bold text-slate-400 dark:text-slate-500 uppercase tracking-widest mt-0.5">{{ __('ECPay Invoice Settings Description') }}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('Store ID') }}</label>
|
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('Store ID') }}</label>
|
||||||
@@ -80,16 +96,16 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- E.SUN -->
|
<!-- E.SUN -->
|
||||||
<div class="luxury-card rounded-3xl p-8 animate-luxury-in" style="animation-delay: 100ms">
|
<div class="luxury-card rounded-3xl p-8 animate-luxury-in group/card" style="animation-delay: 100ms">
|
||||||
<div class="flex items-center gap-4 mb-8">
|
<div class="flex items-center gap-5 mb-8">
|
||||||
<div class="w-12 h-12 rounded-2xl bg-indigo-50 dark:bg-indigo-500/10 flex items-center justify-center text-indigo-500 border border-indigo-100 dark:border-indigo-500/20 shadow-sm shadow-indigo-500/10">
|
<div class="w-10 h-10 rounded-xl bg-gradient-to-br from-indigo-500/10 to-blue-500/10 flex items-center justify-center text-indigo-500 border border-indigo-500/20 shadow-lg shadow-indigo-500/5 group-hover/card:scale-110 transition-transform duration-500">
|
||||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5ZM3.75 14.625c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5ZM13.5 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M16.875 12h1.125a3.375 3.375 0 0 1 3.375 3.375v1.125m-11.25 4.5h1.125a3.375 3.375 0 0 0 3.375-3.375V16.5a3.375 3.375 0 0 1 3.375-3.375h1.125m-11.25 4.5h1.125a3.375 3.375 0 0 1 3.375 3.375v1.125m-3.375-1.125h.008v.008h-.008v-.008Zm3.375 3.375h.008v.008h-.008v-.008Zm0-3.375h.008v.008h-.008v-.008Zm-3.375-3.375h.008v.008h-.008v-.008Zm0 3.375h.008v.008h-.008v-.008Z"/></svg>
|
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3.75 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5ZM3.75 14.625c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5ZM13.5 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 0 1-1.125-1.125v-4.5Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M16.875 12h1.125a3.375 3.375 0 0 1 3.375 3.375v1.125m-11.25 4.5h1.125a3.375 3.375 0 0 0 3.375-3.375V16.5a3.375 3.375 0 0 1 3.375-3.375h1.125m-11.25 4.5h1.125a3.375 3.375 0 0 1 3.375 3.375v1.125m-3.375-1.125h.008v.008h-.008v-.008Zm3.375 3.375h.008v.008h-.008v-.008Zm0-3.375h.008v.008h-.008v-.008Zm-3.375-3.375h.008v.008h-.008v-.008Zm0 3.375h.008v.008h-.008v-.008Z"/></svg>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-xl font-black text-slate-800 dark:text-white tracking-tight">{{ __('E.SUN QR Scan') }}</h3>
|
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight font-display uppercase">{{ __('E.SUN QR Scan') }}</h3>
|
||||||
<p class="text-[10px] font-bold text-slate-400 dark:text-slate-500 uppercase tracking-widest mt-0.5">{{ __('E.SUN QR Scan Settings Description') }}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('StoreID') }}</label>
|
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('StoreID') }}</label>
|
||||||
@@ -107,16 +123,16 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- LINE Pay Direct -->
|
<!-- LINE Pay Direct -->
|
||||||
<div class="luxury-card rounded-3xl p-8 animate-luxury-in" style="animation-delay: 150ms">
|
<div class="luxury-card rounded-3xl p-8 animate-luxury-in group/card" style="animation-delay: 150ms">
|
||||||
<div class="flex items-center gap-4 mb-8">
|
<div class="flex items-center gap-5 mb-8">
|
||||||
<div class="w-12 h-12 rounded-2xl bg-emerald-50 dark:bg-emerald-500/10 flex items-center justify-center text-emerald-500 border border-emerald-100 dark:border-emerald-500/20 shadow-sm shadow-emerald-500/10">
|
<div class="w-10 h-10 rounded-xl bg-gradient-to-br from-lime-500/10 to-emerald-500/10 flex items-center justify-center text-emerald-500 border border-emerald-500/20 shadow-lg shadow-emerald-500/5 group-hover/card:scale-110 transition-transform duration-500">
|
||||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 21a9.004 9.004 0 0 0 8.716-6.747M12 21a9.004 9.004 0 0 1-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 0 1 7.843 4.582M12 3a8.997 8.997 0 0 0-7.843 4.582m15.686 0A11.953 11.953 0 0 1 12 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0 1 21 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0 1 12 16.5c-3.162 0-6.133-.815-8.716-2.247m24.408 0a8.959 8.959 0 0 1 .284-2.253m0 2.253C20.46 17.1 16.485 19.5 12 19.5S3.538 17.1 2.284 14.253"/></svg>
|
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 21a9.004 9.004 0 0 0 8.716-6.747M12 21a9.004 9.004 0 0 1-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 0 1 7.843 4.582M12 3a8.997 8.997 0 0 0-7.843 4.582m15.686 0A11.953 11.953 0 0 1 12 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0 1 21 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0 1 12 16.5c-3.162 0-6.133-.815-8.716-2.247m24.408 0a8.959 8.959 0 0 1 .284-2.253m0 2.253C20.46 17.1 16.485 19.5 12 19.5S3.538 17.1 2.284 14.253"/></svg>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-xl font-black text-slate-800 dark:text-white tracking-tight">{{ __('LINE Pay Direct') }}</h3>
|
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight font-display uppercase">{{ __('LINE Pay Direct') }}</h3>
|
||||||
<p class="text-[10px] font-bold text-slate-400 dark:text-slate-500 uppercase tracking-widest mt-0.5">{{ __('LINE Pay Direct Settings Description') }}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('ChannelId') }}</label>
|
<label class="block text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] mb-2">{{ __('ChannelId') }}</label>
|
||||||
@@ -130,18 +146,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="lg:col-span-6 space-y-8">
|
<div class="lg:col-span-6 space-y-6">
|
||||||
<!-- Tappay -->
|
<!-- Tappay -->
|
||||||
<div class="luxury-card rounded-3xl p-8 animate-luxury-in" style="animation-delay: 200ms">
|
<div class="luxury-card rounded-3xl p-8 animate-luxury-in group/card" style="animation-delay: 200ms">
|
||||||
<div class="flex items-center gap-4 mb-8">
|
<div class="flex items-center gap-5 mb-8">
|
||||||
<div class="w-12 h-12 rounded-2xl bg-indigo-50 dark:bg-indigo-500/10 flex items-center justify-center text-indigo-500 border border-indigo-100 dark:border-indigo-500/20 shadow-sm shadow-indigo-500/10">
|
<div class="w-10 h-10 rounded-xl bg-gradient-to-br from-indigo-500/10 to-violet-500/10 flex items-center justify-center text-indigo-500 border border-indigo-500/20 shadow-lg shadow-indigo-500/5 group-hover/card:scale-110 transition-transform duration-500">
|
||||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15.91 11.672a.375.375 0 0 1 0 .656l-5.603 3.113a.375.375 0 0 1-.557-.328V8.887c0-.286.307-.466.557-.327l5.603 3.112Z"/></svg>
|
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15.91 11.672a.375.375 0 0 1 0 .656l-5.603 3.113a.375.375 0 0 1-.557-.328V8.887c0-.286.307-.466.557-.327l5.603 3.112Z"/></svg>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-xl font-black text-slate-800 dark:text-white tracking-tight">{{ __('TapPay Integration') }}</h3>
|
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight font-display uppercase">{{ __('TapPay Integration') }}</h3>
|
||||||
<p class="text-[10px] font-bold text-slate-400 dark:text-slate-500 uppercase tracking-widest mt-0.5">{{ __('TapPay Integration Settings Description') }}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
<div class="grid grid-cols-2 gap-4">
|
<div class="grid grid-cols-2 gap-4">
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,12 +1,19 @@
|
|||||||
@extends('layouts.admin')
|
@extends('layouts.admin')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="space-y-10 pb-20">
|
<div class="space-y-6 pb-20" x-data="{
|
||||||
|
isDeleteConfirmOpen: false,
|
||||||
|
deleteFormAction: '',
|
||||||
|
confirmDelete(action) {
|
||||||
|
this.deleteFormAction = action;
|
||||||
|
this.isDeleteConfirmOpen = true;
|
||||||
|
}
|
||||||
|
}">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-6">
|
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-6">
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-3xl font-black text-slate-800 dark:text-white tracking-tight font-display">{{ __('Payment Configuration') }}</h1>
|
<h1 class="text-3xl font-black text-slate-800 dark:text-white tracking-tight font-display">{{ __('Payment Configuration') }}</h1>
|
||||||
<p class="text-xs font-bold text-slate-500 dark:text-slate-400 mt-1 uppercase tracking-widest">{{ __('Merchant payment gateway settings management') }}</p>
|
<p class="text-sm font-bold text-slate-500 dark:text-slate-400 mt-1 uppercase tracking-widest">{{ __('Merchant payment gateway settings management') }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a href="{{ route('admin.basic-settings.payment-configs.create') }}" class="btn-luxury-primary flex items-center gap-2">
|
<a href="{{ route('admin.basic-settings.payment-configs.create') }}" class="btn-luxury-primary flex items-center gap-2">
|
||||||
@@ -18,18 +25,35 @@
|
|||||||
|
|
||||||
<!-- Main Card -->
|
<!-- Main Card -->
|
||||||
<div class="luxury-card rounded-3xl p-8 animate-luxury-in">
|
<div class="luxury-card rounded-3xl p-8 animate-luxury-in">
|
||||||
|
<!-- Toolbar & Filters -->
|
||||||
|
<div class="flex items-center justify-between mb-8">
|
||||||
|
<form method="GET" action="{{ route('admin.basic-settings.payment-configs.index') }}" class="relative group">
|
||||||
|
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10">
|
||||||
|
<svg class="h-4 w-4 text-slate-400 group-focus-within:text-cyan-500 transition-colors"
|
||||||
|
viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||||
|
stroke-linejoin="round">
|
||||||
|
<circle cx="11" cy="11" r="8"></circle>
|
||||||
|
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<input type="text" name="search" value="{{ request('search') }}"
|
||||||
|
placeholder="{{ __('Search configurations...') }}"
|
||||||
|
class="luxury-input py-2.5 pl-12 pr-6 block w-64">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="overflow-x-auto">
|
<div class="overflow-x-auto">
|
||||||
<table class="w-full text-left border-separate border-spacing-y-0">
|
<table class="w-full text-left border-separate border-spacing-y-0">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="bg-slate-50/50 dark:bg-slate-900/10">
|
<tr class="bg-slate-50/50 dark:bg-slate-900/10">
|
||||||
<th class="px-6 py-4 text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] border-b border-slate-100 dark:border-slate-800">{{ __('Config Name') }}</th>
|
<th class="px-6 py-4 text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] border-b border-slate-100 dark:border-slate-800">{{ __('Configuration Name') }}</th>
|
||||||
<th class="px-6 py-4 text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] border-b border-slate-100 dark:border-slate-800">{{ __('Belongs To') }}</th>
|
<th class="px-6 py-4 text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] border-b border-slate-100 dark:border-slate-800">{{ __('Belongs To') }}</th>
|
||||||
<th class="px-6 py-4 text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] border-b border-slate-100 dark:border-slate-800">{{ __('Last Updated') }}</th>
|
<th class="px-6 py-4 text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] border-b border-slate-100 dark:border-slate-800">{{ __('Last Updated') }}</th>
|
||||||
<th class="px-6 py-4 text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] border-b border-slate-100 dark:border-slate-800 text-right">{{ __('Action') }}</th>
|
<th class="px-6 py-4 text-[11px] font-black text-slate-400 uppercase tracking-[0.2em] border-b border-slate-100 dark:border-slate-800 text-right">{{ __('Action') }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="divide-y divide-slate-50 dark:divide-slate-800/80">
|
<tbody class="divide-y divide-slate-50 dark:divide-slate-800/80">
|
||||||
@foreach($paymentConfigs as $config)
|
@forelse($paymentConfigs as $config)
|
||||||
<tr class="group hover:bg-slate-50/80 dark:hover:bg-slate-800/40 transition-all duration-300">
|
<tr class="group hover:bg-slate-50/80 dark:hover:bg-slate-800/40 transition-all duration-300">
|
||||||
<td class="px-6 py-6 font-extrabold text-slate-800 dark:text-slate-100">
|
<td class="px-6 py-6 font-extrabold text-slate-800 dark:text-slate-100">
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
@@ -42,7 +66,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-6 border-b border-transparent">
|
<td class="px-6 py-6">
|
||||||
<span class="px-2.5 py-1 rounded-lg text-xs font-bold border border-sky-100 dark:border-sky-900/30 bg-sky-50 dark:bg-sky-900/20 text-sky-600 dark:text-sky-400 tracking-widest">
|
<span class="px-2.5 py-1 rounded-lg text-xs font-bold border border-sky-100 dark:border-sky-900/30 bg-sky-50 dark:bg-sky-900/20 text-sky-600 dark:text-sky-400 tracking-widest">
|
||||||
{{ $config->company->name ?? __('None') }}
|
{{ $config->company->name ?? __('None') }}
|
||||||
</span>
|
</span>
|
||||||
@@ -57,7 +81,7 @@
|
|||||||
class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-cyan-500 hover:bg-cyan-500/5 border border-transparent hover:border-cyan-500/20 transition-all inline-flex" title="{{ __('Edit') }}">
|
class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-cyan-500 hover:bg-cyan-500/5 border border-transparent hover:border-cyan-500/20 transition-all inline-flex" title="{{ __('Edit') }}">
|
||||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"/></svg>
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"/></svg>
|
||||||
</a>
|
</a>
|
||||||
<form action="{{ route('admin.basic-settings.payment-configs.destroy', $config) }}" method="POST" class="inline-block" onsubmit="return confirm('{{ __('Are you sure you want to delete this configuration?') }}')">
|
<form action="{{ route('admin.basic-settings.payment-configs.destroy', $config) }}" method="POST" class="inline-block" @submit.prevent="confirmDelete($el.getAttribute('action'))">
|
||||||
@csrf
|
@csrf
|
||||||
@method('DELETE')
|
@method('DELETE')
|
||||||
<button type="submit"
|
<button type="submit"
|
||||||
@@ -68,7 +92,16 @@
|
|||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@empty
|
||||||
|
<tr>
|
||||||
|
<td colspan="4" class="px-6 py-20 text-center">
|
||||||
|
<div class="inline-flex items-center justify-center w-20 h-20 rounded-3xl bg-slate-50 dark:bg-slate-800/50 mb-6 border border-slate-100 dark:border-slate-800 shadow-sm">
|
||||||
|
<svg class="w-10 h-10 text-slate-300 dark:text-slate-600" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="1.5"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 8.25h19.5M2.25 9h19.5m-16.5 5.25h6m-6 2.25h3m-3.75-6.18c0-.424.344-.766.766-.766h.996c.422 0 .766.342.766.766v.996c0 .422-.344.766-.766.766h-.996a.766.766 0 0 1-.766-.766v-.996ZM3.562 18.125c0 .422.344.766.766.766h.996c.422 0 .766-.344.766-.766v-.996c0-.422-.344-.766-.766-.766h-.996a.766.766 0 0 0-.766.766v.996ZM3.562 13.125c0 .422.344.766.766.766h.996c.422 0 .766-.344.766-.766v-.996c0-.422-.344-.766-.766-.766h-.996a.766.766 0 0 0-.766.766v.996Z"/></svg>
|
||||||
|
</div>
|
||||||
|
<p class="text-base font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest">{{ __('No configurations found') }}</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@@ -77,5 +110,8 @@
|
|||||||
{{ $paymentConfigs->links('vendor.pagination.luxury') }}
|
{{ $paymentConfigs->links('vendor.pagination.luxury') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Global Delete Confirm Modal -->
|
||||||
|
<x-delete-confirm-modal :message="__('Are you sure you want to delete this configuration? This action cannot be undone.')" />
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
@@ -25,7 +25,9 @@
|
|||||||
this.editing = true;
|
this.editing = true;
|
||||||
this.currentCompany = { ...company };
|
this.currentCompany = { ...company };
|
||||||
this.showModal = true;
|
this.showModal = true;
|
||||||
}
|
},
|
||||||
|
isDeleteConfirmOpen: false,
|
||||||
|
deleteFormAction: ''
|
||||||
}">
|
}">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="flex flex-col md:flex-row md:items-center justify-between gap-6">
|
<div class="flex flex-col md:flex-row md:items-center justify-between gap-6">
|
||||||
@@ -180,20 +182,15 @@
|
|||||||
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
|
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<form action="{{ route('admin.permission.companies.destroy', $company->id) }}"
|
<button type="button"
|
||||||
method="POST"
|
@click="deleteFormAction = '{{ route('admin.permission.companies.destroy', $company->id) }}'; isDeleteConfirmOpen = true"
|
||||||
onsubmit="return confirm('{{ addslashes(__('Are you sure to delete this customer?')) }}')"
|
class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-rose-500 hover:bg-rose-500/5 transition-all border border-transparent hover:border-rose-500/20">
|
||||||
class="inline">
|
<svg class="size-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
||||||
@csrf @method('DELETE')
|
stroke-width="2.5">
|
||||||
<button type="submit"
|
<path stroke-linecap="round" stroke-linejoin="round"
|
||||||
class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-rose-500 hover:bg-rose-500/5 transition-all border border-transparent hover:border-rose-500/20">
|
d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
|
||||||
<svg class="size-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
</svg>
|
||||||
stroke-width="2.5">
|
</button>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round"
|
|
||||||
d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -331,7 +328,7 @@
|
|||||||
<label class="text-xs font-black text-slate-500 uppercase tracking-widest pl-1">{{ __('Initial Role') }}</label>
|
<label class="text-xs font-black text-slate-500 uppercase tracking-widest pl-1">{{ __('Initial Role') }}</label>
|
||||||
<select name="admin_role" class="luxury-select w-full">
|
<select name="admin_role" class="luxury-select w-full">
|
||||||
@foreach($template_roles as $role)
|
@foreach($template_roles as $role)
|
||||||
<option value="{{ $role->name }}" {{ $role->name == '通用客戶角色範本' ? 'selected' : '' }}>
|
<option value="{{ $role->name }}" {{ $role->name == '客戶管理員角色模板' ? 'selected' : '' }}>
|
||||||
{{ $role->name }}
|
{{ $role->name }}
|
||||||
</option>
|
</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
@@ -391,6 +388,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<x-delete-confirm-modal :message="__('Are you sure to delete this customer?')" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@endsection
|
@endsection
|
||||||
@@ -20,6 +20,12 @@
|
|||||||
role: '{{ old('role', '') }}',
|
role: '{{ old('role', '') }}',
|
||||||
status: {{ old('status', 1) }}
|
status: {{ old('status', 1) }}
|
||||||
},
|
},
|
||||||
|
isDeleteConfirmOpen: false,
|
||||||
|
deleteFormAction: '',
|
||||||
|
confirmDelete(action) {
|
||||||
|
this.deleteFormAction = action;
|
||||||
|
this.isDeleteConfirmOpen = true;
|
||||||
|
},
|
||||||
get filteredRoles() {
|
get filteredRoles() {
|
||||||
if (this.currentUser.company_id === '' || this.currentUser.company_id === null) {
|
if (this.currentUser.company_id === '' || this.currentUser.company_id === null) {
|
||||||
// 系統層級:顯示 is_system = 1 的角色
|
// 系統層級:顯示 is_system = 1 的角色
|
||||||
@@ -28,9 +34,9 @@
|
|||||||
// 客戶層級:只顯示該公司的角色
|
// 客戶層級:只顯示該公司的角色
|
||||||
let roles = this.allRoles.filter(r => r.company_id == this.currentUser.company_id);
|
let roles = this.allRoles.filter(r => r.company_id == this.currentUser.company_id);
|
||||||
|
|
||||||
// 如果是系統管理員,額外允許選擇「客戶層級範本」
|
// 如果是系統管理員,額外允許選擇「系統層級的角色範本」(排除 super-admin 以免誤派)
|
||||||
@if(auth()->user()->isSystemAdmin())
|
@if(auth()->user()->isSystemAdmin())
|
||||||
let templates = this.allRoles.filter(r => !r.is_system && (r.company_id === null || r.company_id === ''));
|
let templates = this.allRoles.filter(r => (r.company_id === null || r.company_id === '') && r.name !== 'super-admin');
|
||||||
roles = [...roles, ...templates];
|
roles = [...roles, ...templates];
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@@ -59,7 +65,7 @@
|
|||||||
}
|
}
|
||||||
}">
|
}">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="flex flex-col md:flex-row md:items-center justify-between gap-6 mb-8">
|
<div class="flex flex-col md:flex-row md:items-center justify-between gap-6">
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-3xl font-black text-slate-800 dark:text-white font-display tracking-tight">{{ $title }}</h1>
|
<h1 class="text-3xl font-black text-slate-800 dark:text-white font-display tracking-tight">{{ $title }}</h1>
|
||||||
<p class="text-sm font-bold text-slate-500 dark:text-slate-400 mt-1 uppercase tracking-widest">
|
<p class="text-sm font-bold text-slate-500 dark:text-slate-400 mt-1 uppercase tracking-widest">
|
||||||
@@ -176,22 +182,20 @@
|
|||||||
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
|
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<form action="{{ route($baseRoute . '.destroy', $user->id) }}"
|
<form action="{{ route($baseRoute . '.destroy', $user->id) }}"
|
||||||
method="POST"
|
method="POST"
|
||||||
onsubmit="return confirm('{{ __('Are you sure you want to delete this account?') }}')"
|
class="inline-block">
|
||||||
class="inline-block">
|
@csrf
|
||||||
@csrf
|
@method('DELETE')
|
||||||
@method('DELETE')
|
<button type="button"
|
||||||
<button type="submit"
|
@click="confirmDelete('{{ route($baseRoute . '.destroy', $user->id) }}')"
|
||||||
class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-rose-500 hover:bg-rose-500/5 transition-all border border-transparent hover:border-rose-500/20"
|
class="p-2 rounded-xl bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-rose-500 dark:hover:text-rose-400 hover:bg-rose-500/5 dark:hover:bg-rose-500/10 border border-transparent hover:border-rose-500/20 transition-all group/btn"
|
||||||
title="{{ __('Delete') }}">
|
title="{{ __('Delete Account') }}">
|
||||||
<svg class="size-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
stroke-width="2.5">
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" />
|
||||||
<path stroke-linecap="round" stroke-linejoin="round"
|
</svg>
|
||||||
d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
|
</button>
|
||||||
</svg>
|
</form>
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
@else
|
@else
|
||||||
<span class="text-[10px] font-black text-slate-300 dark:text-slate-600 uppercase tracking-[0.15em] px-2">{{ __('Protected') }}</span>
|
<span class="text-[10px] font-black text-slate-300 dark:text-slate-600 uppercase tracking-[0.15em] px-2">{{ __('Protected') }}</span>
|
||||||
@endif
|
@endif
|
||||||
@@ -345,6 +349,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<!-- Global Delete Confirm Modal -->
|
||||||
|
<x-delete-confirm-modal :message="__('Are you sure you want to delete this account? This action cannot be undone.')" />
|
||||||
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
@@ -4,27 +4,9 @@
|
|||||||
@php
|
@php
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
{{-- Toast 通知 --}}
|
|
||||||
@if(session('success'))
|
|
||||||
<div x-data="{ show: false }"
|
|
||||||
x-show="show"
|
|
||||||
x-cloak
|
|
||||||
x-init="setTimeout(() => { show = true; setTimeout(() => show = false, 3000) }, 50)"
|
|
||||||
x-transition:enter="transition cubic-bezier(0.34, 1.56, 0.64, 1) duration-300"
|
|
||||||
x-transition:enter-start="opacity-0 -translate-y-40"
|
|
||||||
x-transition:enter-end="opacity-100 translate-y-0"
|
|
||||||
x-transition:leave="transition ease-in duration-400"
|
|
||||||
x-transition:leave-start="opacity-100 translate-y-0"
|
|
||||||
x-transition:leave-end="opacity-0 -translate-y-40"
|
|
||||||
class="fixed top-4 left-0 right-0 mx-auto w-max z-[100] bg-green-500 text-white px-6 py-3 rounded-lg shadow-lg flex items-center">
|
|
||||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
|
||||||
</svg>
|
|
||||||
{{ session('success') }}
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<div class="px-6 py-8">
|
|
||||||
|
<div class="px-6 py-8" x-data="{ isDeleteConfirmOpen: false, deleteFormAction: '' }">
|
||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex justify-between items-center mb-6">
|
||||||
<h3 class="text-gray-900 dark:text-gray-200 text-3xl font-medium">儲值回饋設定</h3>
|
<h3 class="text-gray-900 dark:text-gray-200 text-3xl font-medium">儲值回饋設定</h3>
|
||||||
<button onclick="document.getElementById('createModal').classList.remove('hidden')" class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700">
|
<button onclick="document.getElementById('createModal').classList.remove('hidden')" class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700">
|
||||||
@@ -59,11 +41,7 @@
|
|||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
<form action="{{ route('admin.deposit-bonus-rules.destroy', $rule) }}" method="POST" class="inline" onsubmit="return confirm('確定要刪除嗎?')">
|
<button type="button" @click="deleteFormAction = '{{ route('admin.deposit-bonus-rules.destroy', $rule) }}'; isDeleteConfirmOpen = true" class="text-red-600 hover:text-red-800">刪除</button>
|
||||||
@csrf
|
|
||||||
@method('DELETE')
|
|
||||||
<button type="submit" class="text-red-600 hover:text-red-800">刪除</button>
|
|
||||||
</form>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
@@ -119,5 +97,6 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<x-delete-confirm-modal :message="__('Are you sure you want to delete this rule?')" />
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
@@ -19,27 +19,9 @@
|
|||||||
];
|
];
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
{{-- Toast 通知 --}}
|
|
||||||
@if(session('success'))
|
|
||||||
<div x-data="{ show: false }"
|
|
||||||
x-show="show"
|
|
||||||
x-cloak
|
|
||||||
x-init="setTimeout(() => { show = true; setTimeout(() => show = false, 3000) }, 50)"
|
|
||||||
x-transition:enter="transition cubic-bezier(0.34, 1.56, 0.64, 1) duration-300"
|
|
||||||
x-transition:enter-start="opacity-0 -translate-y-40"
|
|
||||||
x-transition:enter-end="opacity-100 translate-y-0"
|
|
||||||
x-transition:leave="transition ease-in duration-400"
|
|
||||||
x-transition:leave-start="opacity-100 translate-y-0"
|
|
||||||
x-transition:leave-end="opacity-0 -translate-y-40"
|
|
||||||
class="fixed top-4 left-0 right-0 mx-auto w-max z-[100] bg-green-500 text-white px-6 py-3 rounded-lg shadow-lg flex items-center">
|
|
||||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
|
||||||
</svg>
|
|
||||||
{{ session('success') }}
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<div class="px-6 py-8">
|
|
||||||
|
<div class="px-6 py-8" x-data="{ isDeleteConfirmOpen: false, deleteFormAction: '' }">
|
||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex justify-between items-center mb-6">
|
||||||
<h3 class="text-gray-900 dark:text-gray-200 text-3xl font-medium">禮品設定</h3>
|
<h3 class="text-gray-900 dark:text-gray-200 text-3xl font-medium">禮品設定</h3>
|
||||||
<button onclick="document.getElementById('createModal').classList.remove('hidden')" class="btn-luxury-primary">
|
<button onclick="document.getElementById('createModal').classList.remove('hidden')" class="btn-luxury-primary">
|
||||||
@@ -76,11 +58,7 @@
|
|||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
<form action="{{ route('admin.gift-definitions.destroy', $gift) }}" method="POST" class="inline" onsubmit="return confirm('確定要刪除嗎?')">
|
<button type="button" @click="deleteFormAction = '{{ route('admin.gift-definitions.destroy', $gift) }}'; isDeleteConfirmOpen = true" class="text-red-600 hover:text-red-800">刪除</button>
|
||||||
@csrf
|
|
||||||
@method('DELETE')
|
|
||||||
<button type="submit" class="text-red-600 hover:text-red-800">刪除</button>
|
|
||||||
</form>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
@@ -154,5 +132,6 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<x-delete-confirm-modal :message="__('Are you sure you want to delete this gift?')" />
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
@@ -4,27 +4,9 @@
|
|||||||
@php
|
@php
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
{{-- Toast 通知 --}}
|
|
||||||
@if(session('success'))
|
|
||||||
<div x-data="{ show: false }"
|
|
||||||
x-show="show"
|
|
||||||
x-cloak
|
|
||||||
x-init="setTimeout(() => { show = true; setTimeout(() => show = false, 3000) }, 50)"
|
|
||||||
x-transition:enter="transition cubic-bezier(0.34, 1.56, 0.64, 1) duration-300"
|
|
||||||
x-transition:enter-start="opacity-0 -translate-y-40"
|
|
||||||
x-transition:enter-end="opacity-100 translate-y-0"
|
|
||||||
x-transition:leave="transition ease-in duration-400"
|
|
||||||
x-transition:leave-start="opacity-100 translate-y-0"
|
|
||||||
x-transition:leave-end="opacity-0 -translate-y-40"
|
|
||||||
class="fixed top-4 left-0 right-0 mx-auto w-max z-[100] bg-green-500 text-white px-6 py-3 rounded-lg shadow-lg flex items-center">
|
|
||||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
|
||||||
</svg>
|
|
||||||
{{ session('success') }}
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<div class="px-6 py-8">
|
|
||||||
|
<div class="px-6 py-8" x-data="{ isDeleteConfirmOpen: false, deleteFormAction: '' }">
|
||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex justify-between items-center mb-6">
|
||||||
<h3 class="text-gray-900 dark:text-gray-200 text-3xl font-medium">會員等級設定</h3>
|
<h3 class="text-gray-900 dark:text-gray-200 text-3xl font-medium">會員等級設定</h3>
|
||||||
<button onclick="document.getElementById('createModal').classList.remove('hidden')" class="btn-luxury-primary">
|
<button onclick="document.getElementById('createModal').classList.remove('hidden')" class="btn-luxury-primary">
|
||||||
@@ -57,11 +39,7 @@
|
|||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
<form action="{{ route('admin.membership-tiers.destroy', $tier) }}" method="POST" class="inline" onsubmit="return confirm('確定要刪除嗎?')">
|
<button type="button" @click="deleteFormAction = '{{ route('admin.membership-tiers.destroy', $tier) }}'; isDeleteConfirmOpen = true" class="text-red-600 hover:text-red-800">刪除</button>
|
||||||
@csrf
|
|
||||||
@method('DELETE')
|
|
||||||
<button type="submit" class="text-red-600 hover:text-red-800">刪除</button>
|
|
||||||
</form>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
@@ -116,5 +94,6 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<x-delete-confirm-modal :message="__('Are you sure you want to delete this tier?')" />
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
roleId: '{{ old('roleId', '') }}',
|
roleId: '{{ old('roleId', '') }}',
|
||||||
roleName: '{{ old('name', '') }}',
|
roleName: '{{ old('name', '') }}',
|
||||||
rolePermissions: @js(old('permissions', [])),
|
rolePermissions: @js(old('permissions', [])),
|
||||||
|
currentUserRoleIds: @js($currentUserRoleIds ?? []),
|
||||||
isSystem: {{ old('is_system', '0') }},
|
isSystem: {{ old('is_system', '0') }},
|
||||||
modalTitle: '{{ $errors->any() && old('_method') == 'PUT' ? __('Edit Role') : ($errors->any() ? __('Create Role') : __('Create Role')) }}',
|
modalTitle: '{{ $errors->any() && old('_method') == 'PUT' ? __('Edit Role') : ($errors->any() ? __('Create Role') : __('Create Role')) }}',
|
||||||
openModal(edit = false, id = '', name = '', permissions = [], isSys = false) {
|
openModal(edit = false, id = '', name = '', permissions = [], isSys = false) {
|
||||||
@@ -22,6 +23,18 @@
|
|||||||
this.isSystem = isSys;
|
this.isSystem = isSys;
|
||||||
this.modalTitle = edit ? '{{ __('Edit Role') }}' : '{{ __('Create Role') }}';
|
this.modalTitle = edit ? '{{ __('Edit Role') }}' : '{{ __('Create Role') }}';
|
||||||
this.showModal = true;
|
this.showModal = true;
|
||||||
|
},
|
||||||
|
isWarningModalOpen: false,
|
||||||
|
deleteWarningMsg: '',
|
||||||
|
triggerDeleteWarning(msg) {
|
||||||
|
this.deleteWarningMsg = msg;
|
||||||
|
this.isWarningModalOpen = true;
|
||||||
|
},
|
||||||
|
isDeleteConfirmOpen: false,
|
||||||
|
deleteFormAction: '',
|
||||||
|
confirmDelete(action) {
|
||||||
|
this.deleteFormAction = action;
|
||||||
|
this.isDeleteConfirmOpen = true;
|
||||||
}
|
}
|
||||||
}">
|
}">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
@@ -36,18 +49,34 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Roles Content (Integrated Card) -->
|
<!-- Roles Content (Integrated Card) -->
|
||||||
<div class="luxury-card rounded-3xl p-8 animate-luxury-in">
|
<div class="luxury-card rounded-3xl p-8 animate-luxury-in">
|
||||||
<!-- Toolbar -->
|
<!-- Toolbar -->
|
||||||
<div class="flex flex-col md:flex-row md:items-center justify-between gap-6 mb-10">
|
<div class="flex flex-col md:flex-row md:items-center justify-between gap-6 mb-10">
|
||||||
<form action="{{ route($baseRoute) }}" method="GET" class="relative group">
|
<form action="{{ route($baseRoute) }}" method="GET" class="flex flex-col md:flex-row md:items-center gap-4">
|
||||||
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10">
|
<div class="relative group">
|
||||||
<svg class="h-4 w-4 text-slate-400 group-focus-within:text-cyan-500 transition-colors" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10">
|
||||||
<circle cx="11" cy="11" r="8"></circle>
|
<svg class="h-4 w-4 text-slate-400 group-focus-within:text-cyan-500 transition-colors" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
<circle cx="11" cy="11" r="8"></circle>
|
||||||
</svg>
|
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
||||||
</span>
|
</svg>
|
||||||
<input type="text" name="search" value="{{ request('search') }}" class="py-2.5 pl-12 pr-6 block w-full md:w-80 luxury-input" placeholder="{{ __('Search roles...') }}">
|
</span>
|
||||||
|
<input type="text" name="search" value="{{ request('search') }}" class="py-2.5 pl-12 pr-6 block w-full md:w-80 luxury-input" placeholder="{{ __('Search roles...') }}">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if(auth()->user()->isSystemAdmin())
|
||||||
|
<div class="relative">
|
||||||
|
<select name="company_id" onchange="this.form.submit()" class="py-2.5 pl-4 pr-10 block w-full md:w-60 luxury-input">
|
||||||
|
<option value="">{{ __('All Affiliations') }}</option>
|
||||||
|
<option value="system" {{ request('company_id') === 'system' ? 'selected' : '' }}>{{ __('System Level') }}</option>
|
||||||
|
@foreach($companies as $company)
|
||||||
|
<option value="{{ $company->id }}" {{ request('company_id') == $company->id ? 'selected' : '' }}>{{ $company->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
<input type="hidden" name="per_page" value="{{ request('per_page', 10) }}">
|
<input type="hidden" name="per_page" value="{{ request('per_page', 10) }}">
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -57,7 +86,7 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr class="bg-slate-50/50 dark:bg-slate-900/10">
|
<tr class="bg-slate-50/50 dark:bg-slate-900/10">
|
||||||
<th class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800">{{ __('Role Name') }}</th>
|
<th class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800">{{ __('Role Name') }}</th>
|
||||||
<th class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800">{{ __('Type') }}</th>
|
<th class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800">{{ __('Affiliation') }}</th>
|
||||||
<th class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800">{{ __('Permissions') }}</th>
|
<th class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800">{{ __('Permissions') }}</th>
|
||||||
<th class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800 text-center">{{ __('Users') }}</th>
|
<th class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800 text-center">{{ __('Users') }}</th>
|
||||||
<th class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800 text-right">{{ __('Actions') }}</th>
|
<th class="px-6 py-4 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800 text-right">{{ __('Actions') }}</th>
|
||||||
@@ -85,8 +114,8 @@
|
|||||||
{{ __('System Level') }}
|
{{ __('System Level') }}
|
||||||
</span>
|
</span>
|
||||||
@else
|
@else
|
||||||
<span class="inline-flex items-center px-2.5 py-1 rounded-lg text-xs font-bold bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border border-emerald-500/20 tracking-wider uppercase">
|
<span class="inline-flex items-center px-2.5 py-1 rounded-lg text-xs font-bold bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border border-emerald-500/20 tracking-wider">
|
||||||
{{ __('Company Level') }}
|
{{ $role->company->name ?? __('Company Level') }}
|
||||||
</span>
|
</span>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
@@ -95,7 +124,7 @@
|
|||||||
@forelse($role->permissions->take(6) as $permission)
|
@forelse($role->permissions->take(6) as $permission)
|
||||||
<span class="px-2 py-0.5 text-xs bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300 rounded border border-slate-200 dark:border-slate-700 uppercase font-bold tracking-widest">{{ __(str_replace('menu.', '', $permission->name)) }}</span>
|
<span class="px-2 py-0.5 text-xs bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-300 rounded border border-slate-200 dark:border-slate-700 uppercase font-bold tracking-widest">{{ __(str_replace('menu.', '', $permission->name)) }}</span>
|
||||||
@empty
|
@empty
|
||||||
<span class="text-xs font-bold text-slate-500 dark:text-slate-400 italic tracking-widest">{{ __('No permissions') }}</span>
|
<span class="text-xs font-bold text-slate-500 dark:text-slate-400 tracking-widest">{{ __('No permissions') }}</span>
|
||||||
@endforelse
|
@endforelse
|
||||||
@if($role->permissions->count() > 6)
|
@if($role->permissions->count() > 6)
|
||||||
<span class="px-2 py-0.5 text-xs bg-slate-100 dark:bg-slate-800 text-slate-500 dark:text-slate-400 rounded border border-slate-200 dark:border-slate-700 uppercase font-bold tracking-widest">+{{ $role->permissions->count() - 6 }}</span>
|
<span class="px-2 py-0.5 text-xs bg-slate-100 dark:bg-slate-800 text-slate-500 dark:text-slate-400 rounded border border-slate-200 dark:border-slate-700 uppercase font-bold tracking-widest">+{{ $role->permissions->count() - 6 }}</span>
|
||||||
@@ -111,7 +140,7 @@
|
|||||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"/></svg>
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"/></svg>
|
||||||
</button>
|
</button>
|
||||||
@if($role->name !== 'super-admin' && (auth()->user()->isSystemAdmin() || !$role->is_system))
|
@if($role->name !== 'super-admin' && (auth()->user()->isSystemAdmin() || !$role->is_system))
|
||||||
<form action="{{ route($baseRoute . '.destroy', $role->id) }}" method="POST" @submit.prevent="if(confirm('{{ __('Are you sure you want to delete this role?') }}')) $el.submit()" class="inline text-slate-400">
|
<form action="{{ route($baseRoute . '.destroy', $role->id) }}" method="POST" @submit.prevent="if({{ $role->users()->count() }} > 0) { triggerDeleteWarning('{{ __('Cannot delete role with active users.') }}'); return; } confirmDelete('{{ route($baseRoute . '.destroy', $role->id) }}')" class="inline text-slate-400">
|
||||||
@csrf
|
@csrf
|
||||||
@method('DELETE')
|
@method('DELETE')
|
||||||
<button type="submit" class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-rose-500 hover:bg-rose-500/5 transition-all border border-transparent hover:border-rose-500/20 tooltip" title="{{ __('Delete') }}">
|
<button type="submit" class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-rose-500 hover:bg-rose-500/5 transition-all border border-transparent hover:border-rose-500/20 tooltip" title="{{ __('Delete') }}">
|
||||||
@@ -163,6 +192,19 @@
|
|||||||
<input type="hidden" name="roleId" x-model="roleId">
|
<input type="hidden" name="roleId" x-model="roleId">
|
||||||
|
|
||||||
<div class="p-8 max-h-[65vh] overflow-y-auto custom-scrollbar">
|
<div class="p-8 max-h-[65vh] overflow-y-auto custom-scrollbar">
|
||||||
|
<!-- Warning for editing own role -->
|
||||||
|
<template x-if="isEdit && (currentUserRoleIds || []).map(String).includes(String(roleId))">
|
||||||
|
<div class="mb-8 p-5 bg-amber-500/10 border border-amber-500/20 text-amber-600 dark:text-amber-400 rounded-2xl font-bold flex items-start gap-4 animate-luxury-in">
|
||||||
|
<div class="size-10 bg-amber-500/20 rounded-xl flex items-center justify-center flex-shrink-0">
|
||||||
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>
|
||||||
|
</div>
|
||||||
|
<div class="text-sm">
|
||||||
|
<p class="text-base font-black leading-tight">{{ __('Warning: You are editing your own role!') }}</p>
|
||||||
|
<p class="font-bold mt-1 opacity-90 leading-relaxed">{{ __('Modifying your own administrative permissions may result in losing access to certain system functions.') }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||||
<!-- Left: Basic Info -->
|
<!-- Left: Basic Info -->
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
@@ -185,7 +227,7 @@
|
|||||||
|
|
||||||
@if(auth()->user()->isSystemAdmin())
|
@if(auth()->user()->isSystemAdmin())
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<label class="text-xs font-black text-slate-400 uppercase tracking-widest pl-1">{{ __('Role Type') }}</label>
|
<label class="text-xs font-black text-slate-400 uppercase tracking-widest pl-1">{{ __('Affiliation') }}</label>
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<label class="flex items-center gap-3 p-3 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-800/50 cursor-pointer transition-all border border-slate-200 dark:border-slate-800 group has-[:checked]:border-cyan-500/50 has-[:checked]:bg-cyan-500/5">
|
<label class="flex items-center gap-3 p-3 rounded-xl hover:bg-slate-50 dark:hover:bg-slate-800/50 cursor-pointer transition-all border border-slate-200 dark:border-slate-800 group has-[:checked]:border-cyan-500/50 has-[:checked]:bg-cyan-500/5">
|
||||||
<input type="radio" name="is_system" value="1" x-model="isSystem" class="w-4 h-4 text-cyan-500 bg-transparent border-slate-300 focus:ring-cyan-500" :disabled="isEdit && roleName === 'super-admin'">
|
<input type="radio" name="is_system" value="1" x-model="isSystem" class="w-4 h-4 text-cyan-500 bg-transparent border-slate-300 focus:ring-cyan-500" :disabled="isEdit && roleName === 'super-admin'">
|
||||||
@@ -256,5 +298,51 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<!-- Global Delete Warning Modal -->
|
||||||
|
<div x-show="isWarningModalOpen" class="fixed inset-0 z-[200] overflow-y-auto" x-cloak>
|
||||||
|
<div class="flex items-center justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0">
|
||||||
|
<div x-show="isWarningModalOpen" x-transition:enter="ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100"
|
||||||
|
x-transition:leave="ease-in duration-200" x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0" class="fixed inset-0 transition-opacity bg-slate-900/60 backdrop-blur-sm"
|
||||||
|
@click="isWarningModalOpen = false"></div>
|
||||||
|
|
||||||
|
<span class="hidden sm:inline-block sm:align-middle sm:h-screen">​</span>
|
||||||
|
|
||||||
|
<div x-show="isWarningModalOpen" x-transition:enter="ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
|
x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100" x-transition:leave="ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
|
class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transition-all transform bg-white dark:bg-slate-900 rounded-3xl shadow-2xl sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:p-8 border border-slate-100 dark:border-slate-800">
|
||||||
|
|
||||||
|
<div class="sm:flex sm:items-start">
|
||||||
|
<div class="flex items-center justify-center flex-shrink-0 w-12 h-12 mx-auto bg-rose-100 dark:bg-rose-500/10 rounded-2xl sm:mx-0 sm:h-12 sm:w-12 text-rose-600 dark:text-rose-400">
|
||||||
|
<svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="mt-3 text-center sm:mt-0 sm:ml-6 sm:text-left">
|
||||||
|
<h3 class="text-xl font-black text-slate-800 dark:text-white leading-6 tracking-tight outfit-font">
|
||||||
|
{{ __('Cannot Delete Role') }}
|
||||||
|
</h3>
|
||||||
|
<div class="mt-4">
|
||||||
|
<p class="text-sm font-bold text-slate-500 dark:text-slate-400 leading-relaxed" x-text="deleteWarningMsg"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-8 sm:mt-10 sm:flex sm:flex-row-reverse">
|
||||||
|
<button type="button" @click="isWarningModalOpen = false"
|
||||||
|
class="inline-flex justify-center w-full px-8 py-3 text-sm font-black text-white transition-all bg-slate-800 dark:bg-slate-700 rounded-xl hover:bg-slate-900 dark:hover:bg-slate-600 sm:w-auto tracking-widest uppercase">
|
||||||
|
{{ __('Got it') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Global Delete Confirm Modal -->
|
||||||
|
<x-delete-confirm-modal :message="__('Are you sure you want to delete this role? This action cannot be undone.')" />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
@@ -12,27 +12,9 @@
|
|||||||
];
|
];
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
{{-- Toast 通知 --}}
|
|
||||||
@if(session('success'))
|
|
||||||
<div x-data="{ show: false }"
|
|
||||||
x-show="show"
|
|
||||||
x-cloak
|
|
||||||
x-init="setTimeout(() => { show = true; setTimeout(() => show = false, 3000) }, 50)"
|
|
||||||
x-transition:enter="transition cubic-bezier(0.34, 1.56, 0.64, 1) duration-300"
|
|
||||||
x-transition:enter-start="opacity-0 -translate-y-40"
|
|
||||||
x-transition:enter-end="opacity-100 translate-y-0"
|
|
||||||
x-transition:leave="transition ease-in duration-400"
|
|
||||||
x-transition:leave-start="opacity-100 translate-y-0"
|
|
||||||
x-transition:leave-end="opacity-0 -translate-y-40"
|
|
||||||
class="fixed top-4 left-0 right-0 mx-auto w-max z-[100] bg-green-500 text-white px-6 py-3 rounded-lg shadow-lg flex items-center">
|
|
||||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
|
||||||
</svg>
|
|
||||||
{{ session('success') }}
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<div class="px-6 py-8">
|
|
||||||
|
<div class="px-6 py-8" x-data="{ isDeleteConfirmOpen: false, deleteFormAction: '' }">
|
||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex justify-between items-center mb-6">
|
||||||
<h3 class="text-gray-900 dark:text-gray-200 text-3xl font-medium">點數規則設定</h3>
|
<h3 class="text-gray-900 dark:text-gray-200 text-3xl font-medium">點數規則設定</h3>
|
||||||
<button onclick="document.getElementById('createModal').classList.remove('hidden')" class="btn-luxury-primary">
|
<button onclick="document.getElementById('createModal').classList.remove('hidden')" class="btn-luxury-primary">
|
||||||
@@ -69,11 +51,7 @@
|
|||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
<form action="{{ route('admin.point-rules.destroy', $rule) }}" method="POST" class="inline" onsubmit="return confirm('確定要刪除嗎?')">
|
<button type="button" @click="deleteFormAction = '{{ route('admin.point-rules.destroy', $rule) }}'; isDeleteConfirmOpen = true" class="text-red-600 hover:text-red-800">刪除</button>
|
||||||
@csrf
|
|
||||||
@method('DELETE')
|
|
||||||
<button type="submit" class="text-red-600 hover:text-red-800">刪除</button>
|
|
||||||
</form>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
@@ -134,5 +112,6 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<x-delete-confirm-modal :message="__('Are you sure you want to delete this rule?')" />
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
60
resources/views/components/delete-confirm-modal.blade.php
Normal file
60
resources/views/components/delete-confirm-modal.blade.php
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
@props([
|
||||||
|
'message' => __('Are you sure you want to delete this item? This action cannot be undone.'),
|
||||||
|
'title' => __('Confirm Deletion')
|
||||||
|
])
|
||||||
|
|
||||||
|
<template x-teleport="body">
|
||||||
|
<div x-show="isDeleteConfirmOpen" class="fixed inset-0 z-[200] overflow-y-auto" x-cloak>
|
||||||
|
<div class="flex items-center justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0">
|
||||||
|
<div x-show="isDeleteConfirmOpen" x-transition:enter="ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100"
|
||||||
|
x-transition:leave="ease-in duration-200" x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0" class="fixed inset-0 transition-opacity bg-slate-900/60 backdrop-blur-sm"
|
||||||
|
@click="isDeleteConfirmOpen = false"></div>
|
||||||
|
|
||||||
|
<span class="hidden sm:inline-block sm:align-middle sm:h-screen">​</span>
|
||||||
|
|
||||||
|
<div x-show="isDeleteConfirmOpen" x-transition:enter="ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
|
x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100" x-transition:leave="ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
|
class="inline-block px-4 pt-5 pb-4 overflow-hidden text-left align-bottom transition-all transform bg-white dark:bg-slate-900 rounded-3xl shadow-2xl sm:my-8 sm:align-middle sm:max-w-md sm:w-full sm:p-8 border border-slate-100 dark:border-slate-800">
|
||||||
|
|
||||||
|
<div class="sm:flex sm:items-start text-center sm:text-left">
|
||||||
|
<div
|
||||||
|
class="flex items-center justify-center flex-shrink-0 w-12 h-12 mx-auto bg-amber-100 dark:bg-amber-500/10 rounded-2xl sm:mx-0 sm:h-12 sm:w-12 text-amber-600 dark:text-amber-400">
|
||||||
|
<svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke-width="2.5" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round"
|
||||||
|
d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="mt-3 sm:mt-0 sm:ml-6">
|
||||||
|
<h3 class="text-xl font-black text-slate-800 dark:text-white leading-6 tracking-tight font-display uppercase">
|
||||||
|
{{ $title }}
|
||||||
|
</h3>
|
||||||
|
<div class="mt-4">
|
||||||
|
<p class="text-sm font-bold text-slate-500 dark:text-slate-400 leading-relaxed">
|
||||||
|
{{ $message }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mt-8 sm:mt-10 sm:flex sm:flex-row-reverse gap-3">
|
||||||
|
<form :action="deleteFormAction" method="POST" class="inline">
|
||||||
|
@csrf
|
||||||
|
@method('DELETE')
|
||||||
|
<button type="submit"
|
||||||
|
class="inline-flex justify-center w-full px-6 py-3 text-sm font-black text-white transition-all bg-rose-500 rounded-xl hover:bg-rose-600 shadow-lg shadow-rose-200 dark:shadow-none hover:scale-[1.02] active:scale-[0.98] sm:w-auto uppercase tracking-widest font-display">
|
||||||
|
{{ __('Delete Permanently') }}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<button type="button" @click="isDeleteConfirmOpen = false"
|
||||||
|
class="inline-flex justify-center w-full px-6 py-3 mt-3 text-sm font-black text-slate-700 dark:text-slate-200 transition-all bg-slate-100 dark:bg-slate-800 rounded-xl hover:bg-slate-200 dark:hover:bg-slate-700 sm:mt-0 sm:w-auto uppercase tracking-widest font-display">
|
||||||
|
{{ __('Cancel') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
52
resources/views/components/toast.blade.php
Normal file
52
resources/views/components/toast.blade.php
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
@php
|
||||||
|
$allErrors = [];
|
||||||
|
if (isset($errors)) {
|
||||||
|
foreach ($errors->getBags() as $bag) {
|
||||||
|
$allErrors = array_merge($allErrors, $bag->all());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
<div class="fixed top-8 left-1/2 -translate-x-1/2 z-[99999] w-full max-w-sm px-4 space-y-3 pointer-events-none">
|
||||||
|
@if(session('success'))
|
||||||
|
<div x-data="{ show: true }"
|
||||||
|
x-show="show"
|
||||||
|
x-init="setTimeout(() => show = false, 3000)"
|
||||||
|
x-transition:enter="transition ease-out duration-500"
|
||||||
|
x-transition:enter-start="opacity-0 transform -translate-y-4 scale-95"
|
||||||
|
x-transition:enter-end="opacity-100 transform translate-y-0 scale-100"
|
||||||
|
x-transition:leave="transition ease-in duration-300"
|
||||||
|
x-transition:leave-start="opacity-100 transform translate-y-0 scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 transform -translate-y-4 scale-95"
|
||||||
|
class="p-4 bg-white dark:bg-slate-900 border border-emerald-500/30 text-emerald-600 dark:text-emerald-400 rounded-2xl font-bold shadow-[0_20px_50px_rgba(16,185,129,0.15)] flex items-center gap-3 pointer-events-auto backdrop-blur-xl bg-opacity-90 dark:bg-opacity-90 animate-luxury-in">
|
||||||
|
<div class="size-8 bg-emerald-500/20 rounded-xl flex items-center justify-center flex-shrink-0 text-emerald-500">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M5 13l4 4L19 7"/></svg>
|
||||||
|
</div>
|
||||||
|
<span>{{ session('success') }}</span>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if(session('error') || count($allErrors) > 0)
|
||||||
|
<div x-data="{ show: true }"
|
||||||
|
x-show="show"
|
||||||
|
x-init="setTimeout(() => show = false, 5000)"
|
||||||
|
x-transition:enter="transition ease-out duration-500"
|
||||||
|
x-transition:enter-start="opacity-0 transform -translate-y-4 scale-95"
|
||||||
|
x-transition:enter-end="opacity-100 transform translate-y-0 scale-100"
|
||||||
|
x-transition:leave="transition ease-in duration-300"
|
||||||
|
x-transition:leave-start="opacity-100 transform translate-y-0 scale-100"
|
||||||
|
x-transition:leave-end="opacity-0 transform -translate-y-4 scale-95"
|
||||||
|
class="p-4 bg-white dark:bg-slate-900 border border-rose-500/30 text-rose-600 dark:text-rose-400 rounded-2xl font-bold shadow-[0_20px_50px_rgba(244,63,94,0.15)] flex items-center gap-3 pointer-events-auto backdrop-blur-xl bg-opacity-90 dark:bg-opacity-90 animate-luxury-in">
|
||||||
|
<div class="size-8 bg-rose-500/20 rounded-xl flex items-center justify-center flex-shrink-0 text-rose-500">
|
||||||
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>
|
||||||
|
</div>
|
||||||
|
<span>
|
||||||
|
@if(session('error'))
|
||||||
|
{{ session('error') }}
|
||||||
|
@else
|
||||||
|
{{ $allErrors[0] ?? __('Please check the form for errors.') }}
|
||||||
|
@endif
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
@@ -245,6 +245,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- End Content -->
|
<!-- End Content -->
|
||||||
|
|
||||||
|
<x-toast />
|
||||||
|
|
||||||
@yield('scripts')
|
@yield('scripts')
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -38,15 +38,6 @@
|
|||||||
<span>{{ __('Update') }}</span>
|
<span>{{ __('Update') }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@if (session('status') === 'password-updated')
|
|
||||||
<p
|
|
||||||
x-data="{ show: true }"
|
|
||||||
x-show="show"
|
|
||||||
x-transition
|
|
||||||
x-init="setTimeout(() => show = false, 2000)"
|
|
||||||
class="text-xs font-black text-emerald-500 dark:text-emerald-400 uppercase tracking-widest"
|
|
||||||
>{{ __('Saved.') }}</p>
|
|
||||||
@endif
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -65,15 +65,6 @@
|
|||||||
<span>{{ __('Save') }}</span>
|
<span>{{ __('Save') }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@if (session('status') === 'profile-updated')
|
|
||||||
<p
|
|
||||||
x-data="{ show: true }"
|
|
||||||
x-show="show"
|
|
||||||
x-transition
|
|
||||||
x-init="setTimeout(() => show = false, 2000)"
|
|
||||||
class="text-xs font-black text-emerald-500 dark:text-emerald-400 uppercase tracking-widest"
|
|
||||||
>{{ __('Saved.') }}</p>
|
|
||||||
@endif
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
91
tests/Feature/RoleDeletionTest.php
Normal file
91
tests/Feature/RoleDeletionTest.php
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature;
|
||||||
|
|
||||||
|
use App\Models\System\Company;
|
||||||
|
use App\Models\System\User;
|
||||||
|
use App\Models\System\Role;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class RoleDeletionTest extends TestCase
|
||||||
|
{
|
||||||
|
use RefreshDatabase;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
$this->artisan('db:seed', ['--class' => 'RoleSeeder']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_cannot_delete_role_with_active_users()
|
||||||
|
{
|
||||||
|
$company = Company::create([
|
||||||
|
'name' => 'Test Company',
|
||||||
|
'code' => 'TEST',
|
||||||
|
'status' => 1,
|
||||||
|
]);
|
||||||
|
$admin = User::create([
|
||||||
|
'name' => 'Admin User',
|
||||||
|
'username' => 'admin_user_' . uniqid(),
|
||||||
|
'email' => 'admin_' . uniqid() . '@example.com',
|
||||||
|
'password' => bcrypt('password'),
|
||||||
|
'company_id' => $company->id,
|
||||||
|
]);
|
||||||
|
$admin->assignRole('super-admin');
|
||||||
|
|
||||||
|
$role = Role::create([
|
||||||
|
'name' => 'Test Role',
|
||||||
|
'company_id' => $company->id,
|
||||||
|
'guard_name' => 'web',
|
||||||
|
'is_system' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$user = User::create([
|
||||||
|
'name' => 'Test User',
|
||||||
|
'username' => 'test_user_' . uniqid(),
|
||||||
|
'email' => 'user_' . uniqid() . '@example.com',
|
||||||
|
'password' => bcrypt('password'),
|
||||||
|
'company_id' => $company->id,
|
||||||
|
]);
|
||||||
|
$user->assignRole($role);
|
||||||
|
|
||||||
|
$response = $this->actingAs($admin)
|
||||||
|
->delete(route('admin.permission.roles.destroy', $role->id));
|
||||||
|
|
||||||
|
$response->assertRedirect();
|
||||||
|
$response->assertSessionHas('error', __('Cannot delete role with active users.'));
|
||||||
|
$this->assertDatabaseHas('roles', ['id' => $role->id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_can_delete_role_without_active_users()
|
||||||
|
{
|
||||||
|
$company = Company::create([
|
||||||
|
'name' => 'Test Company 2',
|
||||||
|
'code' => 'TEST2',
|
||||||
|
'status' => 1,
|
||||||
|
]);
|
||||||
|
$admin = User::create([
|
||||||
|
'name' => 'Admin User 2',
|
||||||
|
'username' => 'admin_user_2_' . uniqid(),
|
||||||
|
'email' => 'admin2_' . uniqid() . '@example.com',
|
||||||
|
'password' => bcrypt('password'),
|
||||||
|
'company_id' => $company->id,
|
||||||
|
]);
|
||||||
|
$admin->assignRole('super-admin');
|
||||||
|
|
||||||
|
$role = Role::create([
|
||||||
|
'name' => 'Empty Role',
|
||||||
|
'company_id' => $company->id,
|
||||||
|
'guard_name' => 'web',
|
||||||
|
'is_system' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response = $this->actingAs($admin)
|
||||||
|
->delete(route('admin.permission.roles.destroy', $role->id));
|
||||||
|
|
||||||
|
$response->assertRedirect();
|
||||||
|
$response->assertSessionHas('success');
|
||||||
|
$this->assertDatabaseMissing('roles', ['id' => $role->id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user