'required|string|max:255', 'metric_value' => 'required|numeric', 'performance_date' => 'required|date', 'period_type' => 'required|in:daily,weekly,monthly,quarterly,yearly', 'notes' => 'nullable|string|max:1000' ]; public function mount() { $this->startDate = now()->startOfMonth()->format('Y-m-d'); $this->endDate = now()->format('Y-m-d'); $this->performance_date = now()->format('Y-m-d'); } #[On('track-performance')] public function trackPerformance($technicianId) { $this->technicianId = $technicianId; $this->technician = Technician::with('performances')->findOrFail($technicianId); $this->showModal = true; $this->resetForm(); $this->loadChartData(); } public function updatedPeriodFilter() { $this->setDateRange(); $this->loadChartData(); } public function updatedSelectedMetric() { $this->loadChartData(); } public function updatedStartDate() { $this->loadChartData(); } public function updatedEndDate() { $this->loadChartData(); } public function setDateRange() { switch ($this->periodFilter) { case 'current_week': $this->startDate = now()->startOfWeek()->format('Y-m-d'); $this->endDate = now()->endOfWeek()->format('Y-m-d'); break; case 'current_month': $this->startDate = now()->startOfMonth()->format('Y-m-d'); $this->endDate = now()->endOfMonth()->format('Y-m-d'); break; case 'current_quarter': $this->startDate = now()->startOfQuarter()->format('Y-m-d'); $this->endDate = now()->endOfQuarter()->format('Y-m-d'); break; case 'current_year': $this->startDate = now()->startOfYear()->format('Y-m-d'); $this->endDate = now()->endOfYear()->format('Y-m-d'); break; case 'last_30_days': $this->startDate = now()->subDays(30)->format('Y-m-d'); $this->endDate = now()->format('Y-m-d'); break; } } public function loadChartData() { if (!$this->technician) return; $performances = $this->technician->performances() ->where('metric_type', $this->selectedMetric) ->whereBetween('performance_date', [$this->startDate, $this->endDate]) ->orderBy('performance_date') ->get(); $this->chartData = $performances->map(function ($performance) { return [ 'date' => $performance->performance_date->format('Y-m-d'), 'value' => $performance->metric_value, 'formatted_value' => $performance->formatted_value ]; })->toArray(); } public function addPerformanceRecord() { $this->resetForm(); $this->editing = false; } public function editPerformance($performanceId) { $performance = TechnicianPerformance::findOrFail($performanceId); $this->performanceId = $performance->id; $this->metric_type = $performance->metric_type; $this->metric_value = $performance->metric_value; $this->performance_date = $performance->performance_date->format('Y-m-d'); $this->period_type = $performance->period_type; $this->notes = $performance->notes; $this->editing = true; } public function savePerformance() { $this->validate(); $data = [ 'technician_id' => $this->technicianId, 'metric_type' => $this->metric_type, 'metric_value' => $this->metric_value, 'performance_date' => $this->performance_date, 'period_type' => $this->period_type, 'notes' => $this->notes, ]; if ($this->editing) { $performance = TechnicianPerformance::findOrFail($this->performanceId); $performance->update($data); session()->flash('message', 'Performance record updated successfully!'); } else { TechnicianPerformance::create($data); session()->flash('message', 'Performance record added successfully!'); } $this->technician->refresh(); $this->loadChartData(); $this->resetForm(); } public function deletePerformance($performanceId) { TechnicianPerformance::findOrFail($performanceId)->delete(); $this->technician->refresh(); $this->loadChartData(); session()->flash('message', 'Performance record deleted successfully!'); } public function closeModal() { $this->showModal = false; $this->resetForm(); } public function resetForm() { $this->performanceId = null; $this->metric_type = ''; $this->metric_value = ''; $this->performance_date = now()->format('Y-m-d'); $this->period_type = 'daily'; $this->notes = ''; $this->editing = false; $this->resetErrorBag(); } public function getMetricTypesProperty() { return TechnicianPerformance::getMetricTypes(); } public function getPeriodTypesProperty() { return TechnicianPerformance::getPeriodTypes(); } public function getFilteredPerformancesProperty() { if (!$this->technician) return collect(); return $this->technician->performances() ->whereBetween('performance_date', [$this->startDate, $this->endDate]) ->orderBy('performance_date', 'desc') ->get(); } public function getPerformanceStatsProperty() { if (!$this->technician) return []; $performances = $this->filteredPerformances; $stats = []; foreach ($this->metricTypes as $type => $label) { $typePerformances = $performances->where('metric_type', $type); if ($typePerformances->count() > 0) { $stats[$type] = [ 'label' => $label, 'current' => $typePerformances->first()->metric_value ?? 0, 'average' => round($typePerformances->avg('metric_value'), 2), 'total' => round($typePerformances->sum('metric_value'), 2), 'count' => $typePerformances->count() ]; } } return $stats; } public function render() { return view('livewire.technician-management.performance-tracking', [ 'metricTypes' => $this->metricTypes, 'periodTypes' => $this->periodTypes, 'filteredPerformances' => $this->filteredPerformances, 'performanceStats' => $this->performanceStats ]); } }