product = $product; $this->months = $months; // Lấy tất cả addon từ database $addonsFromDb = Addon::all()->toArray(); // Chuyển đổi dữ liệu addon từ database sang định dạng phù hợp với component $this->addons = collect($addonsFromDb)->map(function ($addon) { return [ 'id' => $addon['id'], 'name' => $addon['name'], 'price' => $addon['price'], 'min' => $addon['min'], 'max' => $addon['max'], 'step' => $addon['step'], 'prefix' => $addon['prefix'], 'type_id' => $addon['type_id'], 'qty' => 0, // Khởi tạo số lượng ban đầu là 0 ]; })->toArray(); $this->index = $index; } public function increment($key) { if ($this->addons[$key]['qty'] < ($this->addons[$key]['max'] ?? PHP_INT_MAX)) { $this->addons[$key]['qty'] += ($this->addons[$key]['step'] ?? 1); } $this->calculateTotal(); $this->dispatch('addonUpdated', addons: $this->addons); } public function decrement($key) { if ($this->addons[$key]['qty'] > ($this->addons[$key]['min'] ?? 0)) { $this->addons[$key]['qty'] -= ($this->addons[$key]['step'] ?? 1); } $this->calculateTotal(); $this->dispatch('addonUpdated', addons: $this->addons); } // Triggered when input fields are updated directly public function updated($name, $value) { // Check if the updated property is related to addon quantity if (strpos($name, 'addons.') !== false && strpos($name, '.qty') !== false) { $parts = explode('.', $name); $key = $parts[1] ?? null; if ($key !== null && isset($this->addons[$key])) { // Ensure quantity is within bounds $min = $this->addons[$key]['min'] ?? 0; $max = $this->addons[$key]['max'] ?? PHP_INT_MAX; $step = $this->addons[$key]['step'] ?? 1; // Round to the nearest step $this->addons[$key]['qty'] = round($value / $step) * $step; // Apply min/max constraints $this->addons[$key]['qty'] = max($min, $this->addons[$key]['qty']); $this->addons[$key]['qty'] = min($max, $this->addons[$key]['qty']); // Ensure total is recalculated immediately $this->calculateTotal(); // Notify listeners that addon has been updated $this->dispatch('addonUpdated', addons: $this->addons); } } } public function hydrate() { // This method is called on every Livewire request // Perfect place to make sure our computed properties are up-to-date $this->calculateTotal(); } protected function calculateTotal() { // Lấy giá sản phẩm ưu tiên sale nếu có $basePrice = $this->product->price_sale ?: $this->product->price; // Nhân với số tháng $total = $basePrice * $this->months; foreach ($this->addons as $addon) { $total += $addon['qty'] * $addon['price'] * $this->months; } $this->cachedTotalPrice = $total; return $total; } public function getTotalAddonPriceProperty() { return collect($this->addons)->sum(function ($addon) { return $addon['qty'] * ($addon['price'] ?? 0) * $this->months; }); } public function getTotalPriceProperty() { // Use cached value if available, otherwise calculate return $this->cachedTotalPrice ?? $this->calculateTotal(); } public function render() { return view('livewire.cart.summary-addons'); } }