seat($uuid); abort_if($seat === null, 404); $this->uuid = $uuid; $this->name = (string) $seat->name; $this->email = (string) $seat->email; $this->isOwner = $seat->role === 'owner'; $this->addressEditable = $seat->status === 'invited'; } public function save() { $customer = $this->requireCustomer(); $seat = $this->seat($this->uuid); if ($customer === null || $seat === null) { return $this->closeModal(); } $rules = ['name' => 'nullable|string|max:255']; // Re-read from the record, never from the hydrated property: a forged // addressEditable would otherwise open the address of an accepted seat. if ($seat->status === 'invited') { $rules['email'] = 'required|email|max:255'; } $data = $this->validate($rules); $changes = ['name' => trim($data['name'] ?? '') ?: null]; if ($seat->status === 'invited') { $address = trim($data['email']); if ($address !== $seat->email) { if ($customer->seats()->where('email', $address)->whereKeyNot($seat->id)->exists()) { $this->addError('email', __('users.duplicate')); return null; } $changes['email'] = $address; } } $seat->update($changes); $this->dispatch('notify', message: __('users.saved')); return $this->redirectRoute('users', navigate: true); } private function seat(string $uuid): ?Seat { return $this->customer()?->seats()->where('uuid', $uuid)->first(); } public function render() { return view('livewire.edit-seat'); } }