[FEAT] 優化客戶合約管理介面與修復日期偏移問題
All checks were successful
star-cloud-deploy-demo / deploy-demo (push) Successful in 52s
All checks were successful
star-cloud-deploy-demo / deploy-demo (push) Successful in 52s
1. 整合「客戶詳情」與「合約歷程」至單一側邊欄,改用分頁 (Tabs) 切換介面。 2. 優化清單「服務期程」顯示:根據客戶模式(租賃/買斷)動態顯示對應期間,並使用完整文字標籤取代縮寫。 3. 修復日期 Bug:在 Company 模型指定日期序列化格式為 Y-m-d,解決時區轉換導致的日期減少一天問題。 4. 新增合約歷程資料表模型、遷移檔以及對應的多語系翻譯(中、英、日)。 5. 移除清單操作列中重複的合約歷程圖示。
This commit is contained in:
@@ -14,7 +14,8 @@ class CompanyController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index(Request $request)
|
public function index(Request $request)
|
||||||
{
|
{
|
||||||
$query = Company::query()->withCount(['users', 'machines']);
|
$query = Company::query()->withCount(['users', 'machines'])
|
||||||
|
->with(['contracts.creator:id,name']);
|
||||||
|
|
||||||
// 搜尋
|
// 搜尋
|
||||||
if ($search = $request->input('search')) {
|
if ($search = $request->input('search')) {
|
||||||
@@ -55,6 +56,10 @@ class CompanyController extends Controller
|
|||||||
'contact_email' => 'nullable|email|max:255',
|
'contact_email' => 'nullable|email|max:255',
|
||||||
'start_date' => 'required|date',
|
'start_date' => 'required|date',
|
||||||
'end_date' => 'nullable|date',
|
'end_date' => 'nullable|date',
|
||||||
|
'warranty_start_date' => 'nullable|date',
|
||||||
|
'warranty_end_date' => 'nullable|date',
|
||||||
|
'software_start_date' => 'nullable|date',
|
||||||
|
'software_end_date' => 'nullable|date',
|
||||||
'status' => 'required|boolean',
|
'status' => 'required|boolean',
|
||||||
'note' => 'nullable|string',
|
'note' => 'nullable|string',
|
||||||
'settings' => 'nullable|array',
|
'settings' => 'nullable|array',
|
||||||
@@ -83,11 +88,28 @@ class CompanyController extends Controller
|
|||||||
'contact_email' => $validated['contact_email'] ?? null,
|
'contact_email' => $validated['contact_email'] ?? null,
|
||||||
'start_date' => $validated['start_date'] ?? null,
|
'start_date' => $validated['start_date'] ?? null,
|
||||||
'end_date' => $validated['end_date'] ?? null,
|
'end_date' => $validated['end_date'] ?? null,
|
||||||
|
'warranty_start_date' => $validated['warranty_start_date'] ?? null,
|
||||||
|
'warranty_end_date' => $validated['warranty_end_date'] ?? null,
|
||||||
|
'software_start_date' => $validated['software_start_date'] ?? null,
|
||||||
|
'software_end_date' => $validated['software_end_date'] ?? null,
|
||||||
'status' => $validated['status'],
|
'status' => $validated['status'],
|
||||||
'note' => $validated['note'] ?? null,
|
'note' => $validated['note'] ?? null,
|
||||||
'settings' => $validated['settings'] ?? [],
|
'settings' => $validated['settings'] ?? [],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// 記錄合約歷程
|
||||||
|
$company->contracts()->create([
|
||||||
|
'type' => $company->original_type,
|
||||||
|
'start_date' => $company->start_date,
|
||||||
|
'end_date' => $company->end_date,
|
||||||
|
'warranty_start_date' => $company->warranty_start_date,
|
||||||
|
'warranty_end_date' => $company->warranty_end_date,
|
||||||
|
'software_start_date' => $company->software_start_date,
|
||||||
|
'software_end_date' => $company->software_end_date,
|
||||||
|
'note' => __('Initial contract registration'),
|
||||||
|
'creator_id' => auth()->id(),
|
||||||
|
]);
|
||||||
|
|
||||||
// 如果有填寫帳號資訊,則建立管理員帳號
|
// 如果有填寫帳號資訊,則建立管理員帳號
|
||||||
if (!empty($validated['admin_username']) && !empty($validated['admin_password'])) {
|
if (!empty($validated['admin_username']) && !empty($validated['admin_password'])) {
|
||||||
$user = \App\Models\System\User::create([
|
$user = \App\Models\System\User::create([
|
||||||
@@ -143,6 +165,10 @@ class CompanyController extends Controller
|
|||||||
'contact_email' => 'nullable|email|max:255',
|
'contact_email' => 'nullable|email|max:255',
|
||||||
'start_date' => 'required|date',
|
'start_date' => 'required|date',
|
||||||
'end_date' => 'nullable|date',
|
'end_date' => 'nullable|date',
|
||||||
|
'warranty_start_date' => 'nullable|date',
|
||||||
|
'warranty_end_date' => 'nullable|date',
|
||||||
|
'software_start_date' => 'nullable|date',
|
||||||
|
'software_end_date' => 'nullable|date',
|
||||||
'status' => 'required|boolean',
|
'status' => 'required|boolean',
|
||||||
'note' => 'nullable|string',
|
'note' => 'nullable|string',
|
||||||
'settings' => 'nullable|array',
|
'settings' => 'nullable|array',
|
||||||
@@ -154,7 +180,22 @@ class CompanyController extends Controller
|
|||||||
$validated['settings']['enable_points'] = filter_var($validated['settings']['enable_points'] ?? false, FILTER_VALIDATE_BOOLEAN);
|
$validated['settings']['enable_points'] = filter_var($validated['settings']['enable_points'] ?? false, FILTER_VALIDATE_BOOLEAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
$company->update($validated);
|
DB::transaction(function () use ($validated, $company) {
|
||||||
|
$company->update($validated);
|
||||||
|
|
||||||
|
// 記錄合約歷程
|
||||||
|
$company->contracts()->create([
|
||||||
|
'type' => $company->current_type,
|
||||||
|
'start_date' => $company->start_date,
|
||||||
|
'end_date' => $company->end_date,
|
||||||
|
'warranty_start_date' => $company->warranty_start_date,
|
||||||
|
'warranty_end_date' => $company->warranty_end_date,
|
||||||
|
'software_start_date' => $company->software_start_date,
|
||||||
|
'software_end_date' => $company->software_end_date,
|
||||||
|
'note' => $validated['note'] ?? __('Contract information updated'),
|
||||||
|
'creator_id' => auth()->id(),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
// 分支邏輯:若停用客戶,連帶停用其所有帳號
|
// 分支邏輯:若停用客戶,連帶停用其所有帳號
|
||||||
if ($validated['status'] == 0) {
|
if ($validated['status'] == 0) {
|
||||||
|
|||||||
@@ -25,17 +25,33 @@ class Company extends Model
|
|||||||
'status',
|
'status',
|
||||||
'start_date',
|
'start_date',
|
||||||
'end_date',
|
'end_date',
|
||||||
|
'warranty_start_date',
|
||||||
|
'warranty_end_date',
|
||||||
|
'software_start_date',
|
||||||
|
'software_end_date',
|
||||||
'note',
|
'note',
|
||||||
'settings',
|
'settings',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'start_date' => 'date',
|
'start_date' => 'date:Y-m-d',
|
||||||
'end_date' => 'date',
|
'end_date' => 'date:Y-m-d',
|
||||||
|
'warranty_start_date' => 'date:Y-m-d',
|
||||||
|
'warranty_end_date' => 'date:Y-m-d',
|
||||||
|
'software_start_date' => 'date:Y-m-d',
|
||||||
|
'software_end_date' => 'date:Y-m-d',
|
||||||
'status' => 'integer',
|
'status' => 'integer',
|
||||||
'settings' => 'array',
|
'settings' => 'array',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the contract history for the company.
|
||||||
|
*/
|
||||||
|
public function contracts(): HasMany
|
||||||
|
{
|
||||||
|
return $this->hasMany(CompanyContract::class)->latest();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the users for the company.
|
* Get the users for the company.
|
||||||
*/
|
*/
|
||||||
|
|||||||
50
app/Models/System/CompanyContract.php
Normal file
50
app/Models/System/CompanyContract.php
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models\System;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
|
class CompanyContract extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'company_id',
|
||||||
|
'type',
|
||||||
|
'start_date',
|
||||||
|
'end_date',
|
||||||
|
'warranty_start_date',
|
||||||
|
'warranty_end_date',
|
||||||
|
'software_start_date',
|
||||||
|
'software_end_date',
|
||||||
|
'note',
|
||||||
|
'creator_id',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'start_date' => 'date:Y-m-d',
|
||||||
|
'end_date' => 'date:Y-m-d',
|
||||||
|
'warranty_start_date' => 'date:Y-m-d',
|
||||||
|
'warranty_end_date' => 'date:Y-m-d',
|
||||||
|
'software_start_date' => 'date:Y-m-d',
|
||||||
|
'software_end_date' => 'date:Y-m-d',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the company that owns the contract.
|
||||||
|
*/
|
||||||
|
public function company(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Company::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the user who created the record.
|
||||||
|
*/
|
||||||
|
public function creator(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class, 'creator_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('companies', function (Blueprint $table) {
|
||||||
|
$table->date('warranty_start_date')->nullable()->after('end_date')->comment('保固起始日');
|
||||||
|
$table->date('warranty_end_date')->nullable()->after('warranty_start_date')->comment('保固結束日');
|
||||||
|
$table->date('software_start_date')->nullable()->after('warranty_end_date')->comment('軟體服務起始日');
|
||||||
|
$table->date('software_end_date')->nullable()->after('software_start_date')->comment('軟體服務結束日');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('companies', function (Blueprint $table) {
|
||||||
|
$table->dropColumn([
|
||||||
|
'warranty_start_date',
|
||||||
|
'warranty_end_date',
|
||||||
|
'software_start_date',
|
||||||
|
'software_end_date'
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('company_contracts', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('company_id')->constrained()->onDelete('cascade');
|
||||||
|
$table->string('type')->comment('buyout, lease');
|
||||||
|
$table->date('start_date')->nullable();
|
||||||
|
$table->date('end_date')->nullable();
|
||||||
|
$table->date('warranty_start_date')->nullable();
|
||||||
|
$table->date('warranty_end_date')->nullable();
|
||||||
|
$table->date('software_start_date')->nullable();
|
||||||
|
$table->date('software_end_date')->nullable();
|
||||||
|
$table->text('note')->nullable();
|
||||||
|
$table->foreignId('creator_id')->nullable()->constrained('users');
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->index(['company_id', 'created_at']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('company_contracts');
|
||||||
|
}
|
||||||
|
};
|
||||||
28
lang/en.json
28
lang/en.json
@@ -1119,5 +1119,31 @@
|
|||||||
"Model changed to :model": "Model changed to :model",
|
"Model changed to :model": "Model changed to :model",
|
||||||
"User logged in: :name": "User logged in: :name",
|
"User logged in: :name": "User logged in: :name",
|
||||||
"Login failed: :account": "Login failed: :account",
|
"Login failed: :account": "Login failed: :account",
|
||||||
"Unauthorized login attempt: :account": "Unauthorized login attempt: :account"
|
"Unauthorized login attempt: :account": "Unauthorized login attempt: :account",
|
||||||
|
"Contract Model": "Contract Model",
|
||||||
|
"Warranty Service": "Warranty Service",
|
||||||
|
"Software Service": "Software Service",
|
||||||
|
"Modification History": "Modification History",
|
||||||
|
"No history records": "No history records",
|
||||||
|
"Initial contract registration": "Initial contract registration",
|
||||||
|
"Contract information updated": "Contract information updated",
|
||||||
|
"Warranty Start": "Warranty Start",
|
||||||
|
"Warranty End": "Warranty End",
|
||||||
|
"Software Start": "Software Start",
|
||||||
|
"Software End": "Software End",
|
||||||
|
"Contract History": "Contract History",
|
||||||
|
"Unlimited": "Unlimited",
|
||||||
|
"Change Note": "Change Note",
|
||||||
|
"Log Time": "Log Time",
|
||||||
|
"Service Periods": "Service Periods",
|
||||||
|
"Creator": "Creator",
|
||||||
|
"View Full History": "View Full History",
|
||||||
|
"Contract Start": "Contract Start",
|
||||||
|
"Contract End": "Contract End",
|
||||||
|
"Contract History Detail": "Contract History Detail",
|
||||||
|
"by": "by",
|
||||||
|
"Service Terms": "Service Periods",
|
||||||
|
"Contract": "Contract",
|
||||||
|
"Warranty": "Warranty",
|
||||||
|
"Software": "Software"
|
||||||
}
|
}
|
||||||
28
lang/ja.json
28
lang/ja.json
@@ -1118,5 +1118,31 @@
|
|||||||
"Model changed to :model": "モデル変更::model",
|
"Model changed to :model": "モデル変更::model",
|
||||||
"User logged in: :name": "ユーザーログイン::name",
|
"User logged in: :name": "ユーザーログイン::name",
|
||||||
"Login failed: :account": "ログイン失敗::account",
|
"Login failed: :account": "ログイン失敗::account",
|
||||||
"Unauthorized login attempt: :account": "不許可のログイン試行::account"
|
"Unauthorized login attempt: :account": "不許可のログイン試行::account",
|
||||||
|
"Contract Model": "契約モデル",
|
||||||
|
"Warranty Service": "保証サービス",
|
||||||
|
"Software Service": "ソフトウェアサービス",
|
||||||
|
"Modification History": "変更履歴",
|
||||||
|
"No history records": "履歴なし",
|
||||||
|
"Initial contract registration": "初期契約登録",
|
||||||
|
"Contract information updated": "契約情報更新",
|
||||||
|
"Warranty Start": "保証開始",
|
||||||
|
"Warranty End": "保証終了",
|
||||||
|
"Software Start": "ソフト開始",
|
||||||
|
"Software End": "ソフト終了",
|
||||||
|
"Contract History": "契約履歴",
|
||||||
|
"Unlimited": "無期限",
|
||||||
|
"Change Note": "変更メモ",
|
||||||
|
"Log Time": "記録時間",
|
||||||
|
"Service Periods": "サービス期間",
|
||||||
|
"Creator": "作成者",
|
||||||
|
"View Full History": "全履歴を表示",
|
||||||
|
"Contract Start": "契約開始",
|
||||||
|
"Contract End": "契約終了",
|
||||||
|
"Contract History Detail": "契約履歴の詳細",
|
||||||
|
"by": "作成者:",
|
||||||
|
"Service Terms": "サービス期間",
|
||||||
|
"Contract": "契約",
|
||||||
|
"Warranty": "保証",
|
||||||
|
"Software": "ソフトウェア"
|
||||||
}
|
}
|
||||||
@@ -677,7 +677,7 @@
|
|||||||
"Pending": "等待機台領取",
|
"Pending": "等待機台領取",
|
||||||
"pending": "等待機台領取",
|
"pending": "等待機台領取",
|
||||||
"Performance": "效能 (Performance)",
|
"Performance": "效能 (Performance)",
|
||||||
"Permanent": "永久授權",
|
"Permanent": "永久",
|
||||||
"Permanently Delete Account": "永久刪除帳號",
|
"Permanently Delete Account": "永久刪除帳號",
|
||||||
"Permission Settings": "權限設定",
|
"Permission Settings": "權限設定",
|
||||||
"Permissions": "權限",
|
"Permissions": "權限",
|
||||||
@@ -1119,5 +1119,31 @@
|
|||||||
"Model changed to :model": "型號變更::model",
|
"Model changed to :model": "型號變更::model",
|
||||||
"User logged in: :name": "使用者登入::name",
|
"User logged in: :name": "使用者登入::name",
|
||||||
"Login failed: :account": "登入失敗::account",
|
"Login failed: :account": "登入失敗::account",
|
||||||
"Unauthorized login attempt: :account": "越權登入嘗試::account"
|
"Unauthorized login attempt: :account": "越權登入嘗試::account",
|
||||||
|
"Contract Model": "合約模式",
|
||||||
|
"Warranty Service": "保固服務",
|
||||||
|
"Software Service": "軟體服務",
|
||||||
|
"Modification History": "異動歷程",
|
||||||
|
"No history records": "尚無歷史紀錄",
|
||||||
|
"Initial contract registration": "初始合約註冊",
|
||||||
|
"Contract information updated": "合約資訊已更新",
|
||||||
|
"Warranty Start": "保固起始",
|
||||||
|
"Warranty End": "保固結束",
|
||||||
|
"Software Start": "軟體起始",
|
||||||
|
"Software End": "軟體結束",
|
||||||
|
"Contract History": "合約歷程",
|
||||||
|
"Unlimited": "無限期",
|
||||||
|
"Change Note": "異動備註",
|
||||||
|
"Log Time": "記錄時間",
|
||||||
|
"Service Periods": "服務區間",
|
||||||
|
"Creator": "建立者",
|
||||||
|
"View Full History": "查看完整歷程",
|
||||||
|
"Contract Start": "合約起始",
|
||||||
|
"Contract End": "合約結束",
|
||||||
|
"Contract History Detail": "合約歷程詳情",
|
||||||
|
"by": "由",
|
||||||
|
"Service Terms": "服務期程",
|
||||||
|
"Contract": "合約",
|
||||||
|
"Warranty": "保固",
|
||||||
|
"Software": "軟體"
|
||||||
}
|
}
|
||||||
@@ -2,8 +2,11 @@
|
|||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="space-y-6" x-data="{
|
<div class="space-y-6" x-data="{
|
||||||
|
|
||||||
showModal: false,
|
showModal: false,
|
||||||
|
showHistoryModal: false,
|
||||||
editing: false,
|
editing: false,
|
||||||
|
sidebarView: 'detail',
|
||||||
currentCompany: {
|
currentCompany: {
|
||||||
id: '',
|
id: '',
|
||||||
name: '',
|
name: '',
|
||||||
@@ -16,6 +19,10 @@
|
|||||||
contact_email: '',
|
contact_email: '',
|
||||||
start_date: '',
|
start_date: '',
|
||||||
end_date: '',
|
end_date: '',
|
||||||
|
warranty_start_date: '',
|
||||||
|
warranty_end_date: '',
|
||||||
|
software_start_date: '',
|
||||||
|
software_end_date: '',
|
||||||
status: 1,
|
status: 1,
|
||||||
note: '',
|
note: '',
|
||||||
settings: {
|
settings: {
|
||||||
@@ -28,7 +35,10 @@
|
|||||||
this.currentCompany = {
|
this.currentCompany = {
|
||||||
id: '', name: '', code: '', original_type: 'lease', current_type: 'lease',
|
id: '', name: '', code: '', original_type: 'lease', current_type: 'lease',
|
||||||
tax_id: '', contact_name: '', contact_phone: '',
|
tax_id: '', contact_name: '', contact_phone: '',
|
||||||
contact_email: '', start_date: '', end_date: '', status: 1, note: '',
|
contact_email: '', start_date: '', end_date: '',
|
||||||
|
warranty_start_date: '', warranty_end_date: '',
|
||||||
|
software_start_date: '', software_end_date: '',
|
||||||
|
status: 1, note: '',
|
||||||
settings: { enable_material_code: false, enable_points: false }
|
settings: { enable_material_code: false, enable_points: false }
|
||||||
};
|
};
|
||||||
this.showModal = true;
|
this.showModal = true;
|
||||||
@@ -39,6 +49,10 @@
|
|||||||
...company,
|
...company,
|
||||||
start_date: company.start_date ? company.start_date.substring(0, 10) : '',
|
start_date: company.start_date ? company.start_date.substring(0, 10) : '',
|
||||||
end_date: company.end_date ? company.end_date.substring(0, 10) : '',
|
end_date: company.end_date ? company.end_date.substring(0, 10) : '',
|
||||||
|
warranty_start_date: company.warranty_start_date ? company.warranty_start_date.substring(0, 10) : '',
|
||||||
|
warranty_end_date: company.warranty_end_date ? company.warranty_end_date.substring(0, 10) : '',
|
||||||
|
software_start_date: company.software_start_date ? company.software_start_date.substring(0, 10) : '',
|
||||||
|
software_end_date: company.software_end_date ? company.software_end_date.substring(0, 10) : '',
|
||||||
settings: {
|
settings: {
|
||||||
enable_material_code: company.settings?.enable_material_code || false,
|
enable_material_code: company.settings?.enable_material_code || false,
|
||||||
enable_points: company.settings?.enable_points || false
|
enable_points: company.settings?.enable_points || false
|
||||||
@@ -57,9 +71,13 @@
|
|||||||
detailCompany: {
|
detailCompany: {
|
||||||
id: '', name: '', code: '', original_type: 'lease', current_type: 'lease',
|
id: '', name: '', code: '', original_type: 'lease', current_type: 'lease',
|
||||||
tax_id: '', contact_name: '', contact_phone: '', contact_email: '',
|
tax_id: '', contact_name: '', contact_phone: '', contact_email: '',
|
||||||
start_date: '', end_date: '', status: 1, note: '',
|
start_date: '', end_date: '',
|
||||||
|
warranty_start_date: '', warranty_end_date: '',
|
||||||
|
software_start_date: '', software_end_date: '',
|
||||||
|
status: 1, note: '',
|
||||||
settings: { enable_material_code: false, enable_points: false },
|
settings: { enable_material_code: false, enable_points: false },
|
||||||
users_count: 0, machines_count: 0
|
users_count: 0, machines_count: 0,
|
||||||
|
contracts: []
|
||||||
},
|
},
|
||||||
openDetailSidebar(company) {
|
openDetailSidebar(company) {
|
||||||
this.detailCompany = {
|
this.detailCompany = {
|
||||||
@@ -69,15 +87,40 @@
|
|||||||
enable_points: company.settings?.enable_points || false
|
enable_points: company.settings?.enable_points || false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
this.sidebarView = 'detail';
|
||||||
this.showDetail = true;
|
this.showDetail = true;
|
||||||
},
|
},
|
||||||
|
openHistorySidebar(company) {
|
||||||
|
this.detailCompany = {
|
||||||
|
...company,
|
||||||
|
settings: {
|
||||||
|
enable_material_code: company.settings?.enable_material_code || false,
|
||||||
|
enable_points: company.settings?.enable_points || false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.sidebarView = 'history';
|
||||||
|
this.showDetail = true;
|
||||||
|
},
|
||||||
|
openFullHistory() {
|
||||||
|
this.showHistoryModal = true;
|
||||||
|
},
|
||||||
|
openHistory(company) {
|
||||||
|
this.detailCompany = {
|
||||||
|
...company,
|
||||||
|
settings: {
|
||||||
|
enable_material_code: company.settings?.enable_material_code || false,
|
||||||
|
enable_points: company.settings?.enable_points || false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.showHistoryModal = true;
|
||||||
|
},
|
||||||
submitConfirmedForm() {
|
submitConfirmedForm() {
|
||||||
if (this.statusToggleSource === 'list') {
|
if (this.statusToggleSource === 'list') {
|
||||||
this.$refs.statusToggleForm.submit();
|
this.$refs.statusToggleForm.submit();
|
||||||
} else {
|
} else {
|
||||||
this.$refs.companyForm.submit();
|
this.$refs.companyForm.submit();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}">
|
}">
|
||||||
<!-- 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">
|
||||||
@@ -164,7 +207,7 @@
|
|||||||
{{ __('Accounts / Machines') }}</th>
|
{{ __('Accounts / Machines') }}</th>
|
||||||
<th
|
<th
|
||||||
class="px-6 py-4 text-[12px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest border-b border-slate-100 dark:border-slate-800 text-center">
|
class="px-6 py-4 text-[12px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest border-b border-slate-100 dark:border-slate-800 text-center">
|
||||||
{{ __('Contract Period') }}</th>
|
{{ __('Service Terms') }}</th>
|
||||||
<th
|
<th
|
||||||
class="px-6 py-4 text-[12px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest border-b border-slate-100 dark:border-slate-800 text-right">
|
class="px-6 py-4 text-[12px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest border-b border-slate-100 dark:border-slate-800 text-right">
|
||||||
{{ __('Actions') }}</th>
|
{{ __('Actions') }}</th>
|
||||||
@@ -235,20 +278,53 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-6 text-center text-slate-500 dark:text-slate-400">
|
<td class="px-6 py-6 border-b border-slate-50 dark:border-slate-800/50">
|
||||||
<div class="flex flex-col items-center gap-1.5 font-mono">
|
<div class="flex flex-col gap-2.5 min-w-[200px] mx-auto w-fit">
|
||||||
<div class="flex items-center gap-2 min-w-[130px] justify-center">
|
<!-- Contract Period (Only for Lease) -->
|
||||||
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-tighter">{{ __('From:') }}</span>
|
@if($company->current_type === 'lease')
|
||||||
<span class="text-[13px] font-bold tracking-tighter text-slate-600 dark:text-slate-300">
|
<div class="flex items-center gap-3 group/term">
|
||||||
{{ $company->start_date ? $company->start_date->format('Y-m-d') : '--' }}
|
<span class="px-2 py-0.5 rounded-md bg-blue-500/10 text-blue-600 text-[10px] font-black border border-blue-500/20 group-hover/term:bg-blue-500 group-hover/term:text-white transition-all tracking-wider whitespace-nowrap min-w-[42px] text-center">
|
||||||
|
{{ __('Contract') }}
|
||||||
</span>
|
</span>
|
||||||
|
<div class="flex items-center gap-1.5 font-mono text-[11px] font-bold">
|
||||||
|
<span class="text-slate-400">{{ $company->start_date ? $company->start_date->format('Y-m-d') : '--' }}</span>
|
||||||
|
<span class="text-slate-300">~</span>
|
||||||
|
<span class="{{ $company->end_date && $company->end_date->isPast() ? 'text-rose-500 shadow-sm shadow-rose-500/10' : 'text-slate-600 dark:text-slate-300' }}">
|
||||||
|
{{ $company->end_date ? $company->end_date->format('Y-m-d') : __('Permanent') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2 min-w-[130px] justify-center">
|
@endif
|
||||||
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-tighter">{{ __('To:') }}</span>
|
|
||||||
<span class="text-[13px] font-bold tracking-tighter {{ $company->end_date && $company->end_date->isPast() ? 'text-rose-500' : 'text-slate-800 dark:text-slate-200' }}">
|
@if($company->current_type === 'buyout')
|
||||||
{{ $company->end_date ? $company->end_date->format('Y-m-d') : __('Permanent') }}
|
<!-- Warranty Period -->
|
||||||
|
<div class="flex items-center gap-3 group/term">
|
||||||
|
<span class="px-2 py-0.5 rounded-md bg-amber-500/10 text-amber-600 text-[10px] font-black border border-amber-500/20 group-hover/term:bg-amber-500 group-hover/term:text-white transition-all tracking-wider whitespace-nowrap min-w-[42px] text-center">
|
||||||
|
{{ __('Warranty') }}
|
||||||
</span>
|
</span>
|
||||||
|
<div class="flex items-center gap-1.5 font-mono text-[11px] font-bold">
|
||||||
|
<span class="text-slate-400">{{ $company->warranty_start_date ? $company->warranty_start_date->format('Y-m-d') : '--' }}</span>
|
||||||
|
<span class="text-slate-300">~</span>
|
||||||
|
<span class="{{ $company->warranty_end_date && $company->warranty_end_date->isPast() ? 'text-rose-500 shadow-sm shadow-rose-500/10' : 'text-slate-500 dark:text-slate-400' }}">
|
||||||
|
{{ $company->warranty_end_date ? $company->warranty_end_date->format('Y-m-d') : '--' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Software Period -->
|
||||||
|
<div class="flex items-center gap-3 group/term">
|
||||||
|
<span class="px-2 py-0.5 rounded-md bg-purple-500/10 text-purple-600 text-[10px] font-black border border-purple-500/20 group-hover/term:bg-purple-500 group-hover/term:text-white transition-all tracking-wider whitespace-nowrap min-w-[42px] text-center">
|
||||||
|
{{ __('Software') }}
|
||||||
|
</span>
|
||||||
|
<div class="flex items-center gap-1.5 font-mono text-[11px] font-bold">
|
||||||
|
<span class="text-slate-400">{{ $company->software_start_date ? $company->software_start_date->format('Y-m-d') : '--' }}</span>
|
||||||
|
<span class="text-slate-300">~</span>
|
||||||
|
<span class="{{ $company->software_end_date && $company->software_end_date->isPast() ? 'text-rose-500 shadow-sm shadow-rose-500/10' : 'text-slate-500 dark:text-slate-400' }}">
|
||||||
|
{{ $company->software_end_date ? $company->software_end_date->format('Y-m-d') : '--' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-6 text-right">
|
<td class="px-6 py-6 text-right">
|
||||||
@@ -447,11 +523,11 @@
|
|||||||
<input type="text" name="tax_id" x-model="currentCompany.tax_id"
|
<input type="text" name="tax_id" x-model="currentCompany.tax_id"
|
||||||
class="luxury-input w-full">
|
class="luxury-input w-full">
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-2 gap-3">
|
<div class="grid grid-cols-2 gap-3" x-show="currentCompany.current_type === 'lease'">
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<label class="text-xs font-black text-slate-500 uppercase tracking-widest pl-1">{{
|
<label class="text-xs font-black text-slate-500 uppercase tracking-widest pl-1">{{
|
||||||
__('Start Date') }} <span class="text-rose-500 ml-0.5">*</span></label>
|
__('Start Date') }} <span class="text-rose-500 ml-0.5">*</span></label>
|
||||||
<input type="date" name="start_date" x-model="currentCompany.start_date" required
|
<input type="date" name="start_date" x-model="currentCompany.start_date" :required="currentCompany.current_type === 'lease'"
|
||||||
class="luxury-input w-full px-2">
|
class="luxury-input w-full px-2">
|
||||||
</div>
|
</div>
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
@@ -462,6 +538,38 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Buyout Specific Dates -->
|
||||||
|
<div x-show="currentCompany.current_type === 'buyout'" x-transition class="space-y-4 pt-2">
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
|
<div class="grid grid-cols-2 gap-3">
|
||||||
|
<div class="space-y-2">
|
||||||
|
<label class="text-[10px] font-black text-amber-600 uppercase tracking-widest pl-1">{{ __('Warranty Start') }}</label>
|
||||||
|
<input type="date" name="warranty_start_date" x-model="currentCompany.warranty_start_date"
|
||||||
|
class="luxury-input w-full px-2 border-amber-100 dark:border-amber-900/30">
|
||||||
|
</div>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<label class="text-[10px] font-black text-amber-600 uppercase tracking-widest pl-1">{{ __('Warranty End') }}</label>
|
||||||
|
<input type="date" name="warranty_end_date" x-model="currentCompany.warranty_end_date"
|
||||||
|
class="luxury-input w-full px-2 border-amber-100 dark:border-amber-900/30">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-2 gap-3">
|
||||||
|
<div class="space-y-2">
|
||||||
|
<label class="text-[10px] font-black text-indigo-600 uppercase tracking-widest pl-1">{{ __('Software Start') }}</label>
|
||||||
|
<input type="date" name="software_start_date" x-model="currentCompany.software_start_date"
|
||||||
|
class="luxury-input w-full px-2 border-indigo-100 dark:border-indigo-900/30">
|
||||||
|
</div>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<label class="text-[10px] font-black text-indigo-600 uppercase tracking-widest pl-1">{{ __('Software End') }}</label>
|
||||||
|
<input type="date" name="software_end_date" x-model="currentCompany.software_end_date"
|
||||||
|
class="luxury-input w-full px-2 border-indigo-100 dark:border-indigo-900/30">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Keep hidden start_date for buyout as well if needed by backend -->
|
||||||
|
<input type="hidden" name="start_date" :value="currentCompany.start_date" x-if="currentCompany.current_type === 'buyout' && !currentCompany.start_date">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Admin Account Section (Account Creation) - Only show when creating -->
|
<!-- Admin Account Section (Account Creation) - Only show when creating -->
|
||||||
@@ -652,7 +760,7 @@
|
|||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="px-8 py-6 border-b border-slate-100 dark:border-slate-800 flex items-center justify-between bg-white dark:bg-slate-900 sticky top-0 z-10">
|
<div class="px-8 py-6 border-b border-slate-100 dark:border-slate-800 flex items-center justify-between bg-white dark:bg-slate-900 sticky top-0 z-10">
|
||||||
<div>
|
<div>
|
||||||
<h2 class="text-xl font-black text-slate-800 dark:text-white tracking-tight">{{ __('Customer Details') }}</h2>
|
<h2 class="text-xl font-black text-slate-800 dark:text-white tracking-tight" x-text="sidebarView === 'history' ? '{{ __('Contract History Detail') }}' : '{{ __('Customer Details') }}'"></h2>
|
||||||
<div class="flex items-center gap-2 mt-1">
|
<div class="flex items-center gap-2 mt-1">
|
||||||
<p class="text-xs font-bold text-slate-400 uppercase tracking-[0.2em]" x-text="detailCompany.name"></p>
|
<p class="text-xs font-bold text-slate-400 uppercase tracking-[0.2em]" x-text="detailCompany.name"></p>
|
||||||
<span class="text-xs font-mono font-black text-cyan-500 px-1.5 py-0.5 bg-cyan-500/10 rounded" x-text="detailCompany.code"></span>
|
<span class="text-xs font-mono font-black text-cyan-500 px-1.5 py-0.5 bg-cyan-500/10 rounded" x-text="detailCompany.code"></span>
|
||||||
@@ -666,7 +774,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Body -->
|
<!-- Body -->
|
||||||
<div class="flex-1 overflow-y-auto px-8 py-8 space-y-8 custom-scrollbar">
|
<div class="flex-1 overflow-y-auto px-8 pt-4 pb-8 space-y-5 custom-scrollbar">
|
||||||
|
<!-- Tab Switcher -->
|
||||||
|
<div class="flex gap-1 p-1 bg-slate-100 dark:bg-slate-800/60 rounded-xl">
|
||||||
|
<button @click="sidebarView = 'detail'"
|
||||||
|
:class="sidebarView === 'detail' ? 'bg-white dark:bg-slate-700 text-slate-800 dark:text-white shadow-sm' : 'text-slate-400 hover:text-slate-600'"
|
||||||
|
class="flex-1 py-2.5 px-3 text-xs font-black uppercase tracking-[0.15em] rounded-lg transition-all">{{ __('Customer Details') }}</button>
|
||||||
|
<button @click="sidebarView = 'history'"
|
||||||
|
:class="sidebarView === 'history' ? 'bg-white dark:bg-slate-700 text-slate-800 dark:text-white shadow-sm' : 'text-slate-400 hover:text-slate-600'"
|
||||||
|
class="flex-1 py-2.5 px-3 text-xs font-black uppercase tracking-[0.15em] rounded-lg transition-all">{{ __('Contract History Detail') }}</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Detail View -->
|
||||||
|
<div x-show="sidebarView === 'detail'" class="space-y-8">
|
||||||
<!-- Validity & Status Section -->
|
<!-- Validity & Status Section -->
|
||||||
<section class="space-y-4">
|
<section class="space-y-4">
|
||||||
<h3 class="text-xs font-black text-emerald-500 uppercase tracking-[0.3em]">{{ __('Account Status') }}</h3>
|
<h3 class="text-xs font-black text-emerald-500 uppercase tracking-[0.3em]">{{ __('Account Status') }}</h3>
|
||||||
@@ -690,38 +810,56 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Business Type -->
|
<!-- Business Type -->
|
||||||
<div class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80">
|
<div class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80 space-y-4">
|
||||||
<h4 class="text-[10px] font-black text-indigo-500 uppercase tracking-[0.2em] mb-4">{{ __('Business Type') }}</h4>
|
<div class="flex justify-between items-start pb-3 border-b border-slate-100/50 dark:border-slate-800/50">
|
||||||
<div class="space-y-4">
|
<div>
|
||||||
<div class="flex items-center justify-between">
|
<h4 class="text-[10px] font-black text-indigo-500 uppercase tracking-[0.2em]">{{ __('Contract Model') }}</h4>
|
||||||
<span class="text-[11px] font-bold text-slate-400">{{ __('Original:') }}</span>
|
|
||||||
<span class="px-2.5 py-1 rounded-lg text-[11px] font-bold uppercase tracking-widest"
|
|
||||||
:class="detailCompany.original_type === 'buyout' ? 'bg-amber-500/10 text-amber-600' : 'bg-blue-500/10 text-blue-600'"
|
|
||||||
x-text="detailCompany.original_type === 'buyout' ? '{{ __('Buyout') }}' : '{{ __('Lease') }}'"></span>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<span class="text-[11px] font-bold text-slate-400">{{ __('Current:') }}</span>
|
|
||||||
<span class="px-2.5 py-1 rounded-lg text-[11px] font-bold uppercase tracking-widest"
|
|
||||||
:class="detailCompany.current_type === 'buyout' ? 'bg-amber-500/10 text-amber-600 border border-amber-500/20' : 'bg-blue-500/10 text-blue-600 border border-blue-500/20'"
|
|
||||||
x-text="detailCompany.current_type === 'buyout' ? '{{ __('Buyout') }}' : '{{ __('Lease') }}'"></span>
|
|
||||||
</div>
|
</div>
|
||||||
|
<span :class="detailCompany.current_type === 'lease' ? 'text-blue-500 bg-blue-500/10' : 'text-amber-500 bg-amber-500/10'"
|
||||||
|
class="text-[10px] font-black uppercase tracking-wider px-2.5 py-1 rounded-lg">
|
||||||
|
<span x-text="detailCompany.current_type === 'lease' ? '{{ __('Lease') }}' : '{{ __('Buyout') }}'"></span>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Lease Info Display -->
|
||||||
|
<template x-if="detailCompany.current_type === 'lease'">
|
||||||
|
<div class="grid grid-cols-2 gap-4">
|
||||||
|
<div class="space-y-1">
|
||||||
|
<p class="text-[9px] font-black text-slate-400 uppercase tracking-widest">{{ __('Start Date') }}</p>
|
||||||
|
<p class="text-xs font-black text-slate-700 dark:text-slate-200" x-text="detailCompany.start_date?.substring(0, 10) || '-'"></p>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-1">
|
||||||
|
<p class="text-[9px] font-black text-slate-400 uppercase tracking-widest">{{ __('End Date') }}</p>
|
||||||
|
<p class="text-xs font-black text-slate-800 dark:text-white" x-text="detailCompany.end_date?.substring(0, 10) || '{{ __('Unlimited') }}'"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- Buyout Info Display -->
|
||||||
|
<template x-if="detailCompany.current_type === 'buyout'">
|
||||||
|
<div class="space-y-4">
|
||||||
|
<div class="grid grid-cols-1 gap-3">
|
||||||
|
<div class="p-3 bg-amber-50/30 dark:bg-amber-500/5 rounded-xl border border-amber-100/50 dark:border-amber-500/10">
|
||||||
|
<p class="text-[9px] font-black text-amber-600 uppercase tracking-widest">{{ __('Warranty Service') }}</p>
|
||||||
|
<div class="flex items-center gap-2 mt-1">
|
||||||
|
<span class="text-xs font-black text-slate-700 dark:text-slate-200" x-text="detailCompany.warranty_start_date?.substring(0, 10) || '-'"></span>
|
||||||
|
<span class="text-slate-400">~</span>
|
||||||
|
<span class="text-xs font-black text-slate-800 dark:text-white" x-text="detailCompany.warranty_end_date?.substring(0, 10) || '-'"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="p-3 bg-indigo-50/30 dark:bg-indigo-500/5 rounded-xl border border-indigo-100/50 dark:border-indigo-500/10">
|
||||||
|
<p class="text-[9px] font-black text-indigo-600 uppercase tracking-widest">{{ __('Software Service') }}</p>
|
||||||
|
<div class="flex items-center gap-2 mt-1">
|
||||||
|
<span class="text-xs font-black text-slate-700 dark:text-slate-200" x-text="detailCompany.software_start_date?.substring(0, 10) || '-'"></span>
|
||||||
|
<span class="text-slate-400">~</span>
|
||||||
|
<span class="text-xs font-black text-slate-800 dark:text-white" x-text="detailCompany.software_end_date?.substring(0, 10) || '-'"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Contract Period -->
|
|
||||||
<div class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80">
|
|
||||||
<h4 class="text-[10px] font-black text-indigo-500 uppercase tracking-[0.2em] mb-4">{{ __('Contract Period') }}</h4>
|
|
||||||
<div class="space-y-3 font-mono">
|
|
||||||
<div class="flex items-center gap-3">
|
|
||||||
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-tighter min-w-[32px]">{{ __('From:') }}</span>
|
|
||||||
<div class="text-[13px] font-bold tracking-tighter text-slate-700 dark:text-slate-200" x-text="detailCompany.start_date || '--'"></div>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center gap-3">
|
|
||||||
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-tighter min-w-[32px]">{{ __('To:') }}</span>
|
|
||||||
<div class="text-[13px] font-bold tracking-tighter text-slate-800 dark:text-white" :class="detailCompany.end_date_expired ? 'text-rose-500' : ''" x-text="detailCompany.end_date || '{{ __('Permanent') }}'"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -803,6 +941,82 @@
|
|||||||
<p class="text-sm font-bold text-slate-600 dark:text-slate-400 leading-relaxed italic" x-text="detailCompany.note"></p>
|
<p class="text-sm font-bold text-slate-600 dark:text-slate-400 leading-relaxed italic" x-text="detailCompany.note"></p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- History View -->
|
||||||
|
<div x-show="sidebarView === 'history'" class="space-y-6">
|
||||||
|
<template x-for="(contract, index) in (detailCompany.contracts || [])" :key="contract.id">
|
||||||
|
<div class="bg-slate-50/50 dark:bg-slate-800/30 rounded-2xl border border-slate-100 dark:border-slate-800/80 overflow-hidden">
|
||||||
|
<!-- Card Header -->
|
||||||
|
<div class="px-5 py-3 bg-white dark:bg-slate-800/50 border-b border-slate-100 dark:border-slate-800 flex justify-between items-center">
|
||||||
|
<div class="flex items-center gap-2.5">
|
||||||
|
<div class="size-7 rounded-full bg-slate-100 dark:bg-slate-700 flex items-center justify-center text-[9px] font-black text-slate-500" x-text="'#' + (detailCompany.contracts.length - index)"></div>
|
||||||
|
<div>
|
||||||
|
<p class="text-[10px] font-black text-slate-700 dark:text-slate-200" x-text="new Date(contract.created_at).toLocaleString()"></p>
|
||||||
|
<div class="flex items-center gap-1.5 mt-0.5">
|
||||||
|
<span :class="contract.type === 'lease' ? 'text-blue-500 bg-blue-500/10' : 'text-amber-500 bg-amber-500/10'"
|
||||||
|
class="text-[8px] font-black uppercase tracking-wider px-1.5 py-0.5 rounded"
|
||||||
|
x-text="contract.type === 'lease' ? '{{ __('Lease') }}' : '{{ __('Buyout') }}'"></span>
|
||||||
|
<span class="text-[9px] text-slate-400">{{ __('by') }} <span class="text-slate-600 dark:text-slate-300" x-text="contract.creator?.name || 'System'"></span></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template x-if="index === 0">
|
||||||
|
<span class="px-2 py-0.5 bg-emerald-500 text-white text-[8px] font-black uppercase tracking-widest rounded-full">{{ __('Current') }}</span>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Card Body -->
|
||||||
|
<div class="p-5 space-y-4">
|
||||||
|
<!-- Lease dates -->
|
||||||
|
<template x-if="contract.type === 'lease'">
|
||||||
|
<div class="grid grid-cols-2 gap-4">
|
||||||
|
<div class="space-y-1.5">
|
||||||
|
<p class="text-[10px] font-black text-slate-400 uppercase tracking-widest">{{ __('Contract Start') }}</p>
|
||||||
|
<p class="text-sm font-black text-slate-700 dark:text-white font-mono" x-text="contract.start_date?.substring(0, 10) || '-'"></p>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-1.5">
|
||||||
|
<p class="text-[10px] font-black text-slate-400 uppercase tracking-widest">{{ __('Contract End') }}</p>
|
||||||
|
<p class="text-sm font-black text-slate-700 dark:text-white font-mono" x-text="contract.end_date?.substring(0, 10) || '{{ __('Unlimited') }}'"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<!-- Buyout dates -->
|
||||||
|
<template x-if="contract.type === 'buyout'">
|
||||||
|
<div class="grid grid-cols-1 gap-4">
|
||||||
|
<div class="p-4 bg-amber-50/40 dark:bg-amber-500/5 rounded-2xl border border-amber-100/50 dark:border-amber-500/10">
|
||||||
|
<p class="text-[10px] font-black text-amber-600 uppercase tracking-widest mb-2">{{ __('Warranty Service') }}</p>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<span class="text-sm font-black text-slate-700 dark:text-slate-200 font-mono" x-text="contract.warranty_start_date?.substring(0, 10) || '-'"></span>
|
||||||
|
<span class="text-slate-400 font-bold">~</span>
|
||||||
|
<span class="text-sm font-black text-slate-800 dark:text-white font-mono" x-text="contract.warranty_end_date?.substring(0, 10) || '-'"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="p-4 bg-indigo-50/40 dark:bg-indigo-500/5 rounded-2xl border border-indigo-100/50 dark:border-indigo-500/10">
|
||||||
|
<p class="text-[10px] font-black text-indigo-600 uppercase tracking-widest mb-2">{{ __('Software Service') }}</p>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<span class="text-sm font-black text-slate-700 dark:text-slate-200 font-mono" x-text="contract.software_start_date?.substring(0, 10) || '-'"></span>
|
||||||
|
<span class="text-slate-400 font-bold">~</span>
|
||||||
|
<span class="text-sm font-black text-slate-800 dark:text-white font-mono" x-text="contract.software_end_date?.substring(0, 10) || '-'"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<!-- Note -->
|
||||||
|
<div class="pt-2 border-t border-slate-100/50 dark:border-slate-800/50" x-show="contract.note">
|
||||||
|
<p class="text-[9px] font-bold text-slate-400 italic" x-text="contract.note"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div x-show="!(detailCompany.contracts || []).length" class="py-12 text-center">
|
||||||
|
<div class="size-14 rounded-2xl bg-slate-50 dark:bg-slate-800/50 flex items-center justify-center mx-auto mb-3 border border-slate-100 dark:border-slate-800">
|
||||||
|
<svg class="size-7 text-slate-300" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18c-2.305 0-4.408.867-6 2.292m0-14.25v14.25" /></svg>
|
||||||
|
</div>
|
||||||
|
<p class="text-xs font-black text-slate-400 uppercase tracking-[0.2em]">{{ __('No history records') }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Footer -->
|
<!-- Footer -->
|
||||||
@@ -815,7 +1029,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
Reference in New Issue
Block a user