mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 15:25:46 +00:00
feat(FE): Add badge display for category columns in tables
This commit is contained in:
@@ -7,8 +7,9 @@ import { ColumnDef, SortingState } from '@tanstack/react-table';
|
|||||||
|
|
||||||
import Table from '@/components/Table';
|
import Table from '@/components/Table';
|
||||||
import Card from '@/components/Card';
|
import Card from '@/components/Card';
|
||||||
|
import Badge from '@/components/Badge';
|
||||||
|
|
||||||
import { formatNumber } from '@/lib/helper';
|
import { cn, formatNumber } from '@/lib/helper';
|
||||||
import { isResponseSuccess } from '@/lib/api-helper';
|
import { isResponseSuccess } from '@/lib/api-helper';
|
||||||
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||||
import { ClosingApi } from '@/services/api/closing';
|
import { ClosingApi } from '@/services/api/closing';
|
||||||
@@ -66,6 +67,48 @@ const ClosingIncomingSapronaksSummaryTable = ({
|
|||||||
{
|
{
|
||||||
accessorKey: 'category',
|
accessorKey: 'category',
|
||||||
header: 'Kategori',
|
header: 'Kategori',
|
||||||
|
cell: (props) => {
|
||||||
|
const categories = props.row.original.category
|
||||||
|
.split(' ')
|
||||||
|
.filter((cat) => cat.trim());
|
||||||
|
const maxBadges = 4;
|
||||||
|
const visibleCategories = categories.slice(0, maxBadges);
|
||||||
|
const remainingCount = categories.length - maxBadges;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='flex flex-wrap gap-1 whitespace-nowrap'>
|
||||||
|
{visibleCategories.map((category, index) => (
|
||||||
|
<Badge
|
||||||
|
key={index}
|
||||||
|
variant='soft'
|
||||||
|
className={{
|
||||||
|
badge: cn(
|
||||||
|
'px-2 py-1 flex flex-row justify-start gap-1 rounded-lg border border-base-content/10 text-xs font-medium text-base-content bg-base-content/5 whitespace-nowrap'
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
title={category}
|
||||||
|
>
|
||||||
|
{category.length > 12
|
||||||
|
? `${category.slice(0, 12)}...`
|
||||||
|
: category}
|
||||||
|
</Badge>
|
||||||
|
))}
|
||||||
|
{remainingCount > 0 && (
|
||||||
|
<Badge
|
||||||
|
variant='soft'
|
||||||
|
className={{
|
||||||
|
badge: cn(
|
||||||
|
'px-2 py-1 flex flex-row justify-start gap-1 rounded-lg border border-base-content/10 text-xs font-medium text-base-content bg-base-content/20'
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
title={categories.join(' ')}
|
||||||
|
>
|
||||||
|
+{remainingCount}
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'total_qty',
|
accessorKey: 'total_qty',
|
||||||
|
|||||||
@@ -9,8 +9,9 @@ import { Icon } from '@iconify/react';
|
|||||||
import Table from '@/components/Table';
|
import Table from '@/components/Table';
|
||||||
import DebouncedTextInput from '@/components/input/DebouncedTextInput';
|
import DebouncedTextInput from '@/components/input/DebouncedTextInput';
|
||||||
import Card from '@/components/Card';
|
import Card from '@/components/Card';
|
||||||
|
import Badge from '@/components/Badge';
|
||||||
|
|
||||||
import { formatDate, formatNumber } from '@/lib/helper';
|
import { cn, formatDate, formatNumber } from '@/lib/helper';
|
||||||
import { isResponseSuccess } from '@/lib/api-helper';
|
import { isResponseSuccess } from '@/lib/api-helper';
|
||||||
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||||
import { ClosingApi } from '@/services/api/closing';
|
import { ClosingApi } from '@/services/api/closing';
|
||||||
@@ -79,6 +80,48 @@ const ClosingIncomingSapronaksTable = ({
|
|||||||
{
|
{
|
||||||
accessorKey: 'product_category',
|
accessorKey: 'product_category',
|
||||||
header: 'Kategori Produk',
|
header: 'Kategori Produk',
|
||||||
|
cell: (props) => {
|
||||||
|
const categories = props.row.original.product_category
|
||||||
|
.split(' ')
|
||||||
|
.filter((cat) => cat.trim());
|
||||||
|
const maxBadges = 4;
|
||||||
|
const visibleCategories = categories.slice(0, maxBadges);
|
||||||
|
const remainingCount = categories.length - maxBadges;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='flex flex-wrap gap-1 whitespace-nowrap'>
|
||||||
|
{visibleCategories.map((category, index) => (
|
||||||
|
<Badge
|
||||||
|
key={index}
|
||||||
|
variant='soft'
|
||||||
|
className={{
|
||||||
|
badge: cn(
|
||||||
|
'px-2 py-1 flex flex-row justify-start gap-1 rounded-lg border border-base-content/10 text-xs font-medium text-base-content bg-base-content/5 whitespace-nowrap'
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
title={category}
|
||||||
|
>
|
||||||
|
{category.length > 12
|
||||||
|
? `${category.slice(0, 12)}...`
|
||||||
|
: category}
|
||||||
|
</Badge>
|
||||||
|
))}
|
||||||
|
{remainingCount > 0 && (
|
||||||
|
<Badge
|
||||||
|
variant='soft'
|
||||||
|
className={{
|
||||||
|
badge: cn(
|
||||||
|
'px-2 py-1 flex flex-row justify-start gap-1 rounded-lg border border-base-content/10 text-xs font-medium text-base-content bg-base-content/20'
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
title={categories.join(' ')}
|
||||||
|
>
|
||||||
|
+{remainingCount}
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'source_warehouse',
|
accessorKey: 'source_warehouse',
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ import { ColumnDef, SortingState } from '@tanstack/react-table';
|
|||||||
|
|
||||||
import Table from '@/components/Table';
|
import Table from '@/components/Table';
|
||||||
import Card from '@/components/Card';
|
import Card from '@/components/Card';
|
||||||
|
import Badge from '@/components/Badge';
|
||||||
|
|
||||||
import { formatNumber } from '@/lib/helper';
|
import { cn, formatNumber } from '@/lib/helper';
|
||||||
import { isResponseSuccess } from '@/lib/api-helper';
|
import { isResponseSuccess } from '@/lib/api-helper';
|
||||||
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||||
import { ClosingApi } from '@/services/api/closing';
|
import { ClosingApi } from '@/services/api/closing';
|
||||||
@@ -66,6 +67,48 @@ const ClosingOutgoingSapronaksSummaryTable = ({
|
|||||||
{
|
{
|
||||||
accessorKey: 'category',
|
accessorKey: 'category',
|
||||||
header: 'Kategori',
|
header: 'Kategori',
|
||||||
|
cell: (props) => {
|
||||||
|
const categories = props.row.original.category
|
||||||
|
.split(' ')
|
||||||
|
.filter((cat) => cat.trim());
|
||||||
|
const maxBadges = 4;
|
||||||
|
const visibleCategories = categories.slice(0, maxBadges);
|
||||||
|
const remainingCount = categories.length - maxBadges;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='flex flex-wrap gap-1 whitespace-nowrap'>
|
||||||
|
{visibleCategories.map((category, index) => (
|
||||||
|
<Badge
|
||||||
|
key={index}
|
||||||
|
variant='soft'
|
||||||
|
className={{
|
||||||
|
badge: cn(
|
||||||
|
'px-2 py-1 flex flex-row justify-start gap-1 rounded-lg border border-base-content/10 text-xs font-medium text-base-content bg-base-content/5 whitespace-nowrap'
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
title={category}
|
||||||
|
>
|
||||||
|
{category.length > 12
|
||||||
|
? `${category.slice(0, 12)}...`
|
||||||
|
: category}
|
||||||
|
</Badge>
|
||||||
|
))}
|
||||||
|
{remainingCount > 0 && (
|
||||||
|
<Badge
|
||||||
|
variant='soft'
|
||||||
|
className={{
|
||||||
|
badge: cn(
|
||||||
|
'px-2 py-1 flex flex-row justify-start gap-1 rounded-lg border border-base-content/10 text-xs font-medium text-base-content bg-base-content/20'
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
title={categories.join(' ')}
|
||||||
|
>
|
||||||
|
+{remainingCount}
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'total_qty',
|
accessorKey: 'total_qty',
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ import { Icon } from '@iconify/react';
|
|||||||
import Table from '@/components/Table';
|
import Table from '@/components/Table';
|
||||||
import DebouncedTextInput from '@/components/input/DebouncedTextInput';
|
import DebouncedTextInput from '@/components/input/DebouncedTextInput';
|
||||||
import Card from '@/components/Card';
|
import Card from '@/components/Card';
|
||||||
|
import Badge from '@/components/Badge';
|
||||||
|
|
||||||
|
import { cn } from '@/lib/helper';
|
||||||
|
|
||||||
import { formatDate, formatNumber } from '@/lib/helper';
|
import { formatDate, formatNumber } from '@/lib/helper';
|
||||||
import { isResponseSuccess } from '@/lib/api-helper';
|
import { isResponseSuccess } from '@/lib/api-helper';
|
||||||
@@ -79,6 +82,48 @@ const ClosingOutgoingSapronaksTable = ({
|
|||||||
{
|
{
|
||||||
accessorKey: 'product_category',
|
accessorKey: 'product_category',
|
||||||
header: 'Kategori Produk',
|
header: 'Kategori Produk',
|
||||||
|
cell: (props) => {
|
||||||
|
const categories = props.row.original.product_category
|
||||||
|
.split(' ')
|
||||||
|
.filter((cat) => cat.trim());
|
||||||
|
const maxBadges = 4;
|
||||||
|
const visibleCategories = categories.slice(0, maxBadges);
|
||||||
|
const remainingCount = categories.length - maxBadges;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='flex flex-wrap gap-1 whitespace-nowrap'>
|
||||||
|
{visibleCategories.map((category, index) => (
|
||||||
|
<Badge
|
||||||
|
key={index}
|
||||||
|
variant='soft'
|
||||||
|
className={{
|
||||||
|
badge: cn(
|
||||||
|
'px-2 py-1 flex flex-row justify-start gap-1 rounded-lg border border-base-content/10 text-xs font-medium text-base-content bg-base-content/5 whitespace-nowrap'
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
title={category}
|
||||||
|
>
|
||||||
|
{category.length > 12
|
||||||
|
? `${category.slice(0, 12)}...`
|
||||||
|
: category}
|
||||||
|
</Badge>
|
||||||
|
))}
|
||||||
|
{remainingCount > 0 && (
|
||||||
|
<Badge
|
||||||
|
variant='soft'
|
||||||
|
className={{
|
||||||
|
badge: cn(
|
||||||
|
'px-2 py-1 flex flex-row justify-start gap-1 rounded-lg border border-base-content/10 text-xs font-medium text-base-content bg-base-content/20'
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
title={categories.join(' ')}
|
||||||
|
>
|
||||||
|
+{remainingCount}
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'source_warehouse',
|
accessorKey: 'source_warehouse',
|
||||||
|
|||||||
Reference in New Issue
Block a user