diff --git a/app/Filament/Pages/Dashboard.php b/app/Filament/Pages/Dashboard.php index c8e54710a..00157089b 100644 --- a/app/Filament/Pages/Dashboard.php +++ b/app/Filament/Pages/Dashboard.php @@ -1,6 +1,7 @@ input('filters.Plant')); - return $form->schema([ - // Plant Filter - Select::make('Plant') - ->options(Plant::pluck('name', 'id')) // Fetch plant names with their IDs - ->label('Select Plant') - ->reactive() - ->afterStateUpdated(function ($state, callable $set) use ($selectedPlant) { - session(['selected_plant' => $state]); - session()->forget('selected_line'); - $set('Plant', $state); - $set('Line', null); - $this->triggerChartUpdate(); - }), + protected static ?string $navigationGroup = 'Production DashBoard'; - // Line Filter - Select::make('Line') - ->options(function ($get) { - $plantId = $get('Plant'); - return $plantId ? Plant::find($plantId)->getLineNames()->pluck('name', 'id') : []; - }) - ->label('Select Line') - ->reactive() - ->afterStateUpdated(function ($state) { - session(['selected_line' => $state]); // Store in session - $this->triggerChartUpdate(); // Notify chart to refresh - }), - ]); + + public function mount(): void + { + $this->filtersForm->fill([ + 'plant' => Plant::first()?->id // Default to first plant + ]); } - // Helper to check if both filters are set - public function triggerChartUpdate(): void + public function filtersForm(Form $form): Form + { + return $form + ->statePath('filters') // Store form state in 'filters' + ->schema([ + Select::make('plant') + ->options(Plant::pluck('name', 'id')) + ->label('Select Plant') + ->reactive() + ->afterStateUpdated(function ($state) { + session(['selected_plant' => $state]); // fixed typo + $this->dispatch('cumulativeChart'); // custom Livewire event + }), + ]); + + } + + + public static function getNavigationLabel(): string { - if (session()->has('selected_plant') && session()->has('selected_line')) { - $this->dispatch('filtersUpdated'); - } + return 'Production Line Count'; } + + public function getHeading(): string + { + return 'Production Line Count'; + } + + + } diff --git a/app/Filament/Pages/HourlyProduction.php b/app/Filament/Pages/HourlyProduction.php new file mode 100644 index 000000000..71866ce4a --- /dev/null +++ b/app/Filament/Pages/HourlyProduction.php @@ -0,0 +1,78 @@ +filtersForm->fill([ + 'plant' => Plant::first()?->id // Default to first plant + ]); + } + + public function filtersForm(Form $form): Form + { + return $form + ->statePath('filters') + ->schema([ + + Select::make('plant') + ->options(Plant::pluck('name', 'id')) + ->label('Select Plant') + ->reactive() + ->afterStateUpdated(function ($state) { + session(['selected_plant' => $state]); + $this->triggerChartUpdate(); + }), + + // Line Filter + Select::make('line') + ->options(function ($get) { + $plantId = $get('plant'); + return $plantId ? Plant::find($plantId)->getLineNames()->pluck('name', 'id') : []; + }) + ->label('Select Line') + ->reactive() + ->afterStateUpdated(function ($state) { + session(['selected_line' => $state]); + $this->triggerChartUpdate(); + }), + ]) + ->columns(2); + } + + public function triggerChartUpdate(): void + { + if (session()->has('selected_plant') && session()->has('selected_line')) { + $this->dispatch('filtersUpdated'); + } + } + + public static function getNavigationLabel(): string + { + return 'Hourly Production Count'; + } + + public static function canAccess(): bool + { + return Auth::check() && Auth::user()->can('view production dashboard'); + } +} diff --git a/app/Filament/Widgets/CumulativeChart.php b/app/Filament/Widgets/CumulativeChart.php new file mode 100644 index 000000000..c30e50242 --- /dev/null +++ b/app/Filament/Widgets/CumulativeChart.php @@ -0,0 +1,111 @@ +filter; + + // Define date range based on filter + switch ($activeFilter) { + case 'yesterday': + $startDate = now()->subDay()->startOfDay(); + $endDate = now()->subDay()->endOfDay(); + break; + case 'this_week': + $startDate = now()->startOfWeek(); + $endDate = now()->endOfWeek(); + break; + case 'this_month': + $startDate = now()->startOfMonth(); + $endDate = now()->endOfMonth(); + break; + default: // today + $startDate = now()->startOfDay(); + $endDate = now()->endOfDay(); + break; + } + + // Get all lines for selected plant + $lines = Line::where('plant_id', $selectedPlant) + ->pluck('name', 'id') + ->toArray(); + + // Get total production per line in the date range + $production = \DB::table('production_quantities') + ->select('line_id', \DB::raw('COUNT(*) as total_quantity')) + ->whereBetween('created_at', [$startDate, $endDate]) + ->whereIn('line_id', array_keys($lines)) + ->groupBy('line_id') + ->pluck('total_quantity', 'line_id') + ->toArray(); + + // Match quantities with lines (fill 0 if missing) + $labels = []; + $data = []; + + foreach ($lines as $lineId => $lineName) { + $labels[] = $lineName; + $data[] = $production[$lineId] ?? 0; + } + + return [ + 'labels' => $labels, + 'datasets' => [ + [ + 'label' => match ($activeFilter) { + 'yesterday' => "Production Quantity (Yesterday)", + 'this_week' => "Weekly Production This Month", + 'this_month' => "Yesterday's Hourly Production", + default => "Today's Production", + }, + 'data' => $data, + ], + ], + ]; + } + + + protected function getType(): string + { + return 'bar'; + } + + protected function getFilters(): ?array + { + return [ + 'today' => 'Today', + 'yesterday' => 'Yesterday', + 'this_week'=> 'This Week', + 'this_month'=> 'This Month', + ]; + } + + protected function getOptions(): array + { + return [ + 'scales' => [ + 'y' => [ + 'beginAtZero' => true, //Start Y-axis from 0 + 'ticks' => [ + 'stepSize' => 0.5, + ], + ], + ], + + ]; + } + +} diff --git a/app/Filament/Widgets/ItemOverview.php b/app/Filament/Widgets/ItemOverview.php index 4e70c85dd..ea9ddad23 100644 --- a/app/Filament/Widgets/ItemOverview.php +++ b/app/Filament/Widgets/ItemOverview.php @@ -8,8 +8,7 @@ class ItemOverview extends ChartWidget { protected static ?string $heading = 'Hourly Production'; - // protected int|string|array $columnSpan = 'full'; - protected int|string|array $columnSpan = 12; + protected int|string|array $columnSpan = '12'; protected static ?string $maxHeight = '350px'; @@ -146,20 +145,6 @@ class ItemOverview extends ChartWidget return 'line'; } - // protected function getContent(): string - // { - // return '
' . $this->chart->render() . '
'; - // } - // protected function getContent(): string - // { - // return << - // {$this->chart->render()} - // - // HTML; - // } - - protected function getOptions(): array { @@ -173,15 +158,6 @@ class ItemOverview extends ChartWidget ], ], ], - - // 'scales' => [ - // 'y' => [ - // 'beginAtZero' => true, //Start Y-axis from 0 - // 'ticks' => [ - // 'stepSize' => 0.5, - // ], - // ], - // ], ]; } @@ -194,4 +170,10 @@ class ItemOverview extends ChartWidget 'this_month'=> 'This Month', ]; } + + public static function canView(): bool + { + // Only show on HourlyProduction page + return request()->routeIs('filament.pages.hourly-production'); + } } diff --git a/resources/views/filament/pages/hourly-production.blade.php b/resources/views/filament/pages/hourly-production.blade.php new file mode 100644 index 000000000..2b3afb59a --- /dev/null +++ b/resources/views/filament/pages/hourly-production.blade.php @@ -0,0 +1,9 @@ + +
+ {{-- Filters form --}} + {{ $this->filtersForm($this->form) }} + + {{-- Chart Widget --}} + @livewire(\App\Filament\Widgets\ItemOverview::class) +
+