feat: add category filter to product index page

This commit is contained in:
Yoga Pangestu 2026-06-14 02:54:06 +07:00
parent d27ac7ed6f
commit 67439af903
3 changed files with 20 additions and 3 deletions

View File

@ -29,13 +29,16 @@ public function index(Request $request): Response
{
$tableQuery = $this->parseDataTableQuery($request);
$isActive = $request->string('is_active')->toString();
$categoryId = $request->string('category_id')->toString();
return Inertia::render('admin/master/products/Index', [
'products' => $this->productService->paginateForIndex($tableQuery, $isActive),
'products' => $this->productService->paginateForIndex($tableQuery, $isActive, $categoryId),
'outOfStockGroups' => $this->productService->outOfStockGroups(),
'stockWarningGroups' => $this->productService->stockWarningGroups(),
'categories' => $this->productService->categoryOptions(),
'filters' => $this->dataTableFilters($tableQuery, [
'is_active' => $isActive,
'category_id' => $categoryId,
]),
]);
}

View File

@ -113,7 +113,7 @@ private function inventoryAlertGroups(callable $filter): array
/**
* @param array{search: string, sort: string, direction: 'asc'|'desc'} $tableQuery
*/
public function paginateForIndex(array $tableQuery, string $isActive): LengthAwarePaginator
public function paginateForIndex(array $tableQuery, string $isActive, string $categoryId = ''): LengthAwarePaginator
{
$query = Product::query()
->with([
@ -135,6 +135,10 @@ public function paginateForIndex(array $tableQuery, string $isActive): LengthAwa
->when(
$isActive !== '',
fn (Builder $query) => $query->where('is_active', $isActive === '1')
)
->when(
$categoryId !== '',
fn (Builder $query) => $query->whereHas('categories', fn (Builder $query) => $query->where('categories.id', $categoryId))
);
$this->applySorting($query, $tableQuery['sort'], $tableQuery['direction']);

View File

@ -14,6 +14,7 @@ import {
import AdminLayout from '@/layouts/AdminLayout.vue';
import type { DataTableFilterDef } from '@/types/data-table';
import type {
CategoryOption,
PaginatedProducts,
ProductOutOfStockGroup,
ProductStockWarningGroup,
@ -23,11 +24,13 @@ const props = defineProps<{
products: PaginatedProducts;
outOfStockGroups: ProductOutOfStockGroup[];
stockWarningGroups: ProductStockWarningGroup[];
categories: CategoryOption[];
filters: {
search: string;
sort?: string;
direction?: 'asc' | 'desc';
is_active?: string;
category_id?: string;
};
}>();
@ -38,12 +41,18 @@ const { query, setSearch, setFilter, resetFilters, syncFromServer } =
useDataTableQuery({
url: '/admin/master/products',
initial: { ...props.filters },
filterKeys: ['is_active'],
filterKeys: ['is_active', 'category_id'],
});
useDataTableQuerySync(() => props.filters, syncFromServer);
const filterDefs = computed<DataTableFilterDef[]>(() => [
{
key: 'category_id',
label: 'Kategori',
type: 'select',
options: props.categories.map((c) => ({ value: String(c.value), label: c.label })),
},
{
key: 'is_active',
label: 'Status',
@ -56,6 +65,7 @@ const filterDefs = computed<DataTableFilterDef[]>(() => [
]);
const filterValues = computed(() => ({
category_id: query.value.category_id ?? '',
is_active: query.value.is_active ?? '',
}));