feat: add filter popover component for delivery status

- Tambah fungsional close button untuk komponen Filter
- Penyesuaian warna neutral sesuai Design System
This commit is contained in:
Hafid Nur
2025-03-29 01:17:32 +07:00
parent 088a0fc41f
commit 7eecf2621d
8 changed files with 88 additions and 59 deletions
+20 -11
View File
@@ -1,13 +1,13 @@
import * as React from 'react'; import * as React from 'react';
import { FC, ReactElement } from 'react'; import { FC, ReactElement, useState } from 'react';
import { import {
FilterOutlined, FilterOutlined,
SearchOutlined, SearchOutlined,
EditOutlined, EditOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import { Button, Input } from '@imphnen-frontend-service/ui/atoms'; import { Button, Input } from '@imphnen-frontend-service/ui/atoms';
import { DataTable } from '@imphnen-frontend-service/ui/organisms'; import { DataTable, Filter } from '@imphnen-frontend-service/ui/organisms';
import { import {
ColumnDef, ColumnDef,
@@ -100,6 +100,7 @@ export const Components: FC = (): ReactElement => {
}); });
const [rowSelection, setRowSelection] = React.useState<RowSelectionState>({}); const [rowSelection, setRowSelection] = React.useState<RowSelectionState>({});
const [showFilter, setShowFilter] = useState(false);
const table = useReactTable({ const table = useReactTable({
data: mockData, data: mockData,
@@ -138,15 +139,23 @@ export const Components: FC = (): ReactElement => {
</div> </div>
</div> </div>
<Button <div className="relative">
variant="primary" <Button
disabled variant="primary"
size="md" size="md"
className="flex items-center gap-3" className="flex items-center gap-3"
> disabled
<FilterOutlined /> onClick={() => setShowFilter(!showFilter)}
Filters >
</Button> <FilterOutlined />
Filters
</Button>
{showFilter && (
<div className="absolute right-0 top-[calc(100%+12px)] z-10 shadow-lg">
<Filter onClose={() => setShowFilter(false)} />
</div>
)}
</div>
</div> </div>
{/* Table */} {/* Table */}
+19 -10
View File
@@ -1,13 +1,13 @@
import * as React from 'react'; import * as React from 'react';
import { FC, ReactElement } from 'react'; import { FC, ReactElement, useState } from 'react';
import { import {
FilterOutlined, FilterOutlined,
SearchOutlined, SearchOutlined,
AuditOutlined, AuditOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import { Button, Input } from '@imphnen-frontend-service/ui/atoms'; import { Button, Input } from '@imphnen-frontend-service/ui/atoms';
import { DataTable } from '@imphnen-frontend-service/ui/organisms'; import { DataTable, Filter } from '@imphnen-frontend-service/ui/organisms';
import { import {
ColumnDef, ColumnDef,
@@ -165,6 +165,7 @@ export const Components: FC = (): ReactElement => {
}); });
const [rowSelection, setRowSelection] = React.useState<RowSelectionState>({}); const [rowSelection, setRowSelection] = React.useState<RowSelectionState>({});
const [showFilter, setShowFilter] = useState(false);
const table = useReactTable({ const table = useReactTable({
data: mockData, data: mockData,
@@ -203,14 +204,22 @@ export const Components: FC = (): ReactElement => {
</div> </div>
</div> </div>
<Button <div className="relative">
variant="primary" <Button
size="md" variant="primary"
className="flex items-center gap-3" size="md"
> className="flex items-center gap-3"
<FilterOutlined /> onClick={() => setShowFilter(!showFilter)}
Filters >
</Button> <FilterOutlined />
Filters
</Button>
{showFilter && (
<div className="absolute right-0 top-[calc(100%+12px)] z-10 shadow-lg">
<Filter onClose={() => setShowFilter(false)} />
</div>
)}
</div>
</div> </div>
{/* Table */} {/* Table */}
+19 -11
View File
@@ -1,13 +1,12 @@
import * as React from 'react'; import * as React from 'react';
import { FC, ReactElement, useState } from 'react';
import { FC, ReactElement } from 'react';
import { import {
FilterOutlined, FilterOutlined,
SearchOutlined, SearchOutlined,
AuditOutlined, AuditOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import { Button, Input } from '@imphnen-frontend-service/ui/atoms'; import { Button, Input } from '@imphnen-frontend-service/ui/atoms';
import { DataTable } from '@imphnen-frontend-service/ui/organisms'; import { DataTable, Filter } from '@imphnen-frontend-service/ui/organisms';
import { import {
ColumnDef, ColumnDef,
@@ -120,6 +119,7 @@ export const Components: FC = (): ReactElement => {
}); });
const [rowSelection, setRowSelection] = React.useState<RowSelectionState>({}); const [rowSelection, setRowSelection] = React.useState<RowSelectionState>({});
const [showFilter, setShowFilter] = useState(false);
const table = useReactTable({ const table = useReactTable({
data: mockTransactions, data: mockTransactions,
@@ -158,14 +158,22 @@ export const Components: FC = (): ReactElement => {
</div> </div>
</div> </div>
<Button <div className="relative">
variant="primary" <Button
size="md" variant="primary"
className="flex items-center gap-3" size="md"
> className="flex items-center gap-3"
<FilterOutlined /> onClick={() => setShowFilter(!showFilter)}
Filters >
</Button> <FilterOutlined />
Filters
</Button>
{showFilter && (
<div className="absolute right-0 top-[calc(100%+12px)] z-10 shadow-lg">
<Filter onClose={() => setShowFilter(false)} />
</div>
)}
</div>
</div> </div>
{/* Table */} {/* Table */}
+7 -7
View File
@@ -17,14 +17,14 @@
--color-neutral-50: #f6f6f6; --color-neutral-50: #f6f6f6;
--color-neutral-100: #e7e7e7; --color-neutral-100: #e7e7e7;
--color-neutral-200: #d0d0d0; --color-neutral-200: #d1d1d1;
--color-neutral-300: #b7b7b7; --color-neutral-300: #b0b0b0;
--color-neutral-400: #9f9f9f; --color-neutral-400: #888888;
--color-neutral-500: #7e7e7e; --color-neutral-500: #6d6d6d;
--color-neutral-600: #5d5d5d; --color-neutral-600: #5d5d5d;
--color-neutral-700: #4a4a4a; --color-neutral-700: #4f4f4f;
--color-neutral-800: #3a3a3a; --color-neutral-800: #454545;
--color-neutral-900: #2f2f2f; --color-neutral-900: #3d3d3d;
--color-neutral-950: #2b2b2b; --color-neutral-950: #2b2b2b;
--color-success-100: #e0fbd8; --color-success-100: #e0fbd8;
+7 -7
View File
@@ -17,14 +17,14 @@
--color-neutral-50: #f6f6f6; --color-neutral-50: #f6f6f6;
--color-neutral-100: #e7e7e7; --color-neutral-100: #e7e7e7;
--color-neutral-200: #d0d0d0; --color-neutral-200: #d1d1d1;
--color-neutral-300: #b7b7b7; --color-neutral-300: #b0b0b0;
--color-neutral-400: #9f9f9f; --color-neutral-400: #888888;
--color-neutral-500: #7e7e7e; --color-neutral-500: #6d6d6d;
--color-neutral-600: #5d5d5d; --color-neutral-600: #5d5d5d;
--color-neutral-700: #4a4a4a; --color-neutral-700: #4f4f4f;
--color-neutral-800: #3a3a3a; --color-neutral-800: #454545;
--color-neutral-900: #2f2f2f; --color-neutral-900: #3d3d3d;
--color-neutral-950: #2b2b2b; --color-neutral-950: #2b2b2b;
--color-success-100: #e0fbd8; --color-success-100: #e0fbd8;
+7 -7
View File
@@ -17,14 +17,14 @@
--color-neutral-50: #f6f6f6; --color-neutral-50: #f6f6f6;
--color-neutral-100: #e7e7e7; --color-neutral-100: #e7e7e7;
--color-neutral-200: #d0d0d0; --color-neutral-200: #d1d1d1;
--color-neutral-300: #b7b7b7; --color-neutral-300: #b0b0b0;
--color-neutral-400: #9f9f9f; --color-neutral-400: #888888;
--color-neutral-500: #7e7e7e; --color-neutral-500: #6d6d6d;
--color-neutral-600: #5d5d5d; --color-neutral-600: #5d5d5d;
--color-neutral-700: #4a4a4a; --color-neutral-700: #4f4f4f;
--color-neutral-800: #3a3a3a; --color-neutral-800: #454545;
--color-neutral-900: #2f2f2f; --color-neutral-900: #3d3d3d;
--color-neutral-950: #2b2b2b; --color-neutral-950: #2b2b2b;
--color-success-100: #e0fbd8; --color-success-100: #e0fbd8;
+8 -6
View File
@@ -20,7 +20,7 @@ const Radio = ({
value, value,
onChange, onChange,
}: RadioProps) => ( }: RadioProps) => (
<div className="flex gap-2 items-start"> <div className="flex gap-2 items-center">
<div className="relative grid place-items-center mt-1"> <div className="relative grid place-items-center mt-1">
<input <input
type="radio" type="radio"
@@ -40,7 +40,11 @@ const Radio = ({
</div> </div>
); );
export const Filter = () => { interface FilterProps {
onClose?: () => void;
}
export const Filter = ({ onClose }: FilterProps) => {
const [selectedStatus, setSelectedStatus] = useState('delivered'); const [selectedStatus, setSelectedStatus] = useState('delivered');
const handleStatusChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleStatusChange = (e: React.ChangeEvent<HTMLInputElement>) => {
@@ -48,13 +52,11 @@ export const Filter = () => {
}; };
return ( return (
<div className="inline-flex flex-col p-[20px] bg-white rounded-lg gap-4 w-[122px]"> <div className="inline-flex flex-col p-[20px] bg-white rounded-lg gap-4 w-[122px] shadow">
<div className="flex justify-between items-baseline"> <div className="flex justify-between items-baseline">
<span className="font-semibold text-p3 text-primary-500">Filters</span> <span className="font-semibold text-p3 text-primary-500">Filters</span>
<button <button
onClick={() => { onClick={onClose}
console.log('clicked');
}}
className="cursor-pointer text-neutral-400 hover:text-neutral-600" className="cursor-pointer text-neutral-400 hover:text-neutral-600"
> >
<CloseOutlined className="text-[12px]" /> <CloseOutlined className="text-[12px]" />
+1
View File
@@ -2,3 +2,4 @@ export * from './navbar';
export * from './modals-gacha'; export * from './modals-gacha';
export * from './backoffice-sidebar' export * from './backoffice-sidebar'
export * from './datatable' export * from './datatable'
export * from './filter'