__('Expire date is required.'), 'till.date' => __('Expire date must be a valid date.'), 'till.after' => __('Expire date must be in the future.'), 'till.before_or_equal'=> __('Expire date exceeds the maximum allowed period.'), ]; } public function getTillMaxDays(): ?int { $callableType = $this->call->callable_type ?? session('activeProfileType'); if ($callableType && $callableType !== \App\Models\User::class) { return timebank_config('calls.till_max_days_non_user'); } return timebank_config('calls.till_max_days'); } protected function rules(): array { $tillMaxDays = $this->getTillMaxDays(); $tillRule = 'required|date|after:today'; if ($tillMaxDays !== null) { $tillRule .= '|before_or_equal:' . now()->addDays($tillMaxDays)->format('Y-m-d'); } return [ 'content' => ['required', 'string', 'max:' . timebank_config('calls.content_max_input', 200)], 'till' => $tillRule, 'tagId' => 'required|integer|exists:taggable_tags,tag_id', 'country' => 'required|integer|exists:countries,id', 'city' => 'nullable|integer|exists:cities,id', 'district'=> 'nullable|integer|exists:districts,id', ]; } public function openModal(): void { $this->resetValidation(); // Pre-fill from existing call $this->tagId = $this->call->tag_id; $this->content = $this->call->translations->where('locale', App::getLocale())->first()?->content ?? $this->call->translations->first()?->content ?? ''; $this->till = $this->call->till?->format('Y-m-d'); $this->isPublic = (bool) $this->call->is_public; $location = $this->call->location; $this->country = $location?->country_id; $this->division = $location?->division_id; $this->city = $location?->city_id; $this->district = $location?->district_id; $this->showModal = true; } public function callTagSelected(int $tagId): void { $this->tagId = $tagId; $this->resetValidation('tagId'); } public function callTagCleared(): void { $this->tagId = null; } public function countryToParent($value): void { $this->country = $value ?: null; } public function divisionToParent($value): void { $this->division = $value ?: null; } public function cityToParent($value): void { $this->city = $value ?: null; } public function districtToParent($value): void { $this->district = $value ?: null; } public function confirmDelete(): void { $this->showDeleteConfirm = true; } public function delete(): void { $activeProfile = getActiveProfile(); if (!$activeProfile || get_class($activeProfile) !== $this->call->callable_type || $activeProfile->id !== $this->call->callable_id) { abort(403); } $this->call->unsearchable(); $this->call->translations()->delete(); $this->call->delete(); $this->redirect(route('home')); } public function save(): void { // Only the callable owner may edit $activeProfile = getActiveProfile(); if (!$activeProfile || get_class($activeProfile) !== $this->call->callable_type || $activeProfile->id !== $this->call->callable_id) { abort(403); } $this->validate(); // Resolve or create a standalone Location record $locationId = null; if ($this->country || $this->city) { $attributes = array_filter([ 'country_id' => $this->country ?: null, 'division_id' => $this->division ?: null, 'city_id' => $this->city ?: null, 'district_id' => $this->district ?: null, ]); $location = Location::whereNull('locatable_id') ->whereNull('locatable_type') ->where($attributes) ->first(); if (!$location) { $location = new Location($attributes); $location->save(); } $locationId = $location->id; } $this->call->update([ 'tag_id' => $this->tagId, 'location_id' => $locationId, 'till' => $this->till ?: null, 'is_public' => $this->isPublic, ]); // Update or create translation for current locale CallTranslation::updateOrCreate( ['call_id' => $this->call->id, 'locale' => App::getLocale()], ['content' => $this->content ?: null] ); $this->call->searchable(); $this->showModal = false; $this->notification()->success( title: __('Saved'), description: __('Your Call has been updated.') ); $this->redirect(request()->header('Referer') ?: route('call.show', ['id' => $this->call->id])); } public function render() { return view('livewire.calls.edit', [ 'profileName' => $this->call->callable?->name ?? '', ]); } }