'nullable|date', 'customToDate' => 'nullable|date|after_or_equal:customFromDate', ]; protected $messages = [ 'customFromDate.date' => 'The from date must be a valid date.', 'customToDate.date' => 'The to date must be a valid date.', 'customToDate.after_or_equal' => 'The to date must be after or equal to the from date.', ]; /** * @param string $default Which option starts selected. A parameter rather * than a constant so a future consumer can differ; * both current ones use the rolling year. */ public function mount($label = 'Select Period', string $default = 'since_one_year_ago', bool $allowAllTime = false) { $this->label = $label; $this->allowAllTime = $allowAllTime; $this->selectedPeriod = $default; $this->setPeriodDates(); } public function updatedSelectedPeriod() { $this->setPeriodDates(); } public function applyCustomPeriod(string $fromDate = '', string $toDate = '') { $this->customFromDate = $fromDate ?: null; $this->customToDate = $toDate ?: null; $this->validate(); $this->dispatchDates(); } private function setPeriodDates() { $fromDate = null; $toDate = null; switch ($this->selectedPeriod) { // A rolling twelve months ending today, as opposed to // 'previous_year', which is the last *calendar* year. case 'since_one_year_ago': $fromDate = Carbon::now()->subYear()->format('Y-m-d'); $toDate = Carbon::now()->format('Y-m-d'); break; case 'previous_year': $fromDate = Carbon::now()->subYear()->startOfYear()->format('Y-m-d'); $toDate = Carbon::now()->subYear()->endOfYear()->format('Y-m-d'); break; case 'previous_quarter': $fromDate = Carbon::now()->subQuarter()->startOfQuarter()->format('Y-m-d'); $toDate = Carbon::now()->subQuarter()->endOfQuarter()->format('Y-m-d'); break; case 'previous_month': $fromDate = Carbon::now()->subMonth()->startOfMonth()->format('Y-m-d'); $toDate = Carbon::now()->subMonth()->endOfMonth()->format('Y-m-d'); break; case 'custom': $fromDate = $this->customFromDate; $toDate = $this->customToDate; break; // No bounds at all. The consumer decides what that means: Stats // reports over every transaction on record. case 'all_time': $fromDate = null; $toDate = null; break; } if ($this->selectedPeriod !== 'custom' && $this->selectedPeriod !== 'all_time') { $this->customFromDate = $fromDate; $this->customToDate = $toDate; } $this->dispatchDates(); } private function dispatchDates() { // If no period is selected, dispatch clear event if (!$this->selectedPeriod) { $this->dispatch('periodCleared'); return; } // For custom periods, ensure both dates are provided before dispatching if ($this->selectedPeriod === 'custom') { if (!$this->customFromDate || !$this->customToDate) { // If custom is selected but dates are missing, dispatch clear $this->dispatch('periodCleared'); return; } } $this->dispatch('periodSelected', [ 'fromDate' => $this->customFromDate, 'toDate' => $this->customToDate, 'period' => $this->selectedPeriod ]); } public function render() { return view('livewire.select-period'); } }