{Array.from({ length: 10 }).map((_, i) => {
const YEAR = START_YEAR + i;
return (
diff --git a/src/components/ui/index.ts b/src/components/ui/index.ts
index 031face..a74f51c 100644
--- a/src/components/ui/index.ts
+++ b/src/components/ui/index.ts
@@ -1,3 +1,4 @@
+export { Badge, StatusBadge } from '@/components/ui/badge';
export {
Calendar,
CalendarHeader,
diff --git a/src/components/ui/input/DateInput.tsx b/src/components/ui/input/DateInput.tsx
index 9721b6d..b4c8af6 100644
--- a/src/components/ui/input/DateInput.tsx
+++ b/src/components/ui/input/DateInput.tsx
@@ -40,9 +40,10 @@ export default function DateInput({
(date: Date) => {
setSelectedDate(date);
setInputValue(formatDate(date));
+ setClose();
onChange?.(date);
},
- [onChange]
+ [onChange, setClose]
);
// 날짜 선택
@@ -124,7 +125,7 @@ export default function DateInput({
/>
{isOpen && (
-
+
)}
diff --git a/src/components/ui/pagination/index.ts b/src/components/ui/pagination/index.ts
index 9128b29..fe89635 100644
--- a/src/components/ui/pagination/index.ts
+++ b/src/components/ui/pagination/index.ts
@@ -1 +1 @@
-export { default as Pagination } from './pagination';
+export { default as Pagination } from '@/components/ui/pagination/pagination';
diff --git a/src/components/ui/table/Table.stories.tsx b/src/components/ui/table/Table.stories.tsx
index 2569e45..a77d293 100644
--- a/src/components/ui/table/Table.stories.tsx
+++ b/src/components/ui/table/Table.stories.tsx
@@ -8,12 +8,8 @@ import { fetchTableData } from './testApi';
const meta: Meta
= {
title: 'UI/Table',
component: Table,
- argTypes: {
- userType: {
- control: { type: 'radio' },
- options: ['employer', 'employee'],
- },
- },
+ tags: ['autodocs'],
+ parameters: { layout: 'fullscreen' },
};
export default meta;
@@ -23,6 +19,8 @@ type Story = StoryObj;
function TableWithTestApi({ userType }: { userType: UserType }) {
const [headers, setHeaders] = useState([]);
const [data, setData] = useState([]);
+ const [offset, setOffset] = useState(0);
+ const limit = 5;
useEffect(() => {
const getData = async () => {
@@ -33,12 +31,32 @@ function TableWithTestApi({ userType }: { userType: UserType }) {
getData();
}, [userType]);
- return ;
+ const count = data.length;
+ const paginatedData = data.slice(offset, offset + limit);
+
+ return (
+
+ );
}
-export const TableExample: Story = {
+export const EmployerTable: Story = {
args: {
userType: 'employer',
},
render: args => ,
};
+
+export const EmployeeTable: Story = {
+ args: {
+ userType: 'employee',
+ },
+ render: args => ,
+};
diff --git a/src/components/ui/table/Table.tsx b/src/components/ui/table/Table.tsx
index a9d99b8..1019d86 100644
--- a/src/components/ui/table/Table.tsx
+++ b/src/components/ui/table/Table.tsx
@@ -1,35 +1,68 @@
-import TableRow from '@/components/ui/table/TableRow';
+import { Pagination } from '@/components/ui';
import { TableRowProps } from '@/components/ui/table/TableRowProps';
+import { cn } from '@/lib/utils/cn';
import { UserType } from '@/types/user';
+import TableRow from './TableRow';
interface TableProps {
data: TableRowProps[];
headers: string[];
userType: UserType;
+ total: number;
+ limit: number;
+ offset: number;
+ onPageChange: (newOffset: number) => void;
}
// type은 확인이 좀 더 필요합니다
-export default function Table({ data, headers, userType }: TableProps) {
+export default function Table({
+ data,
+ headers,
+ userType,
+ total,
+ limit,
+ offset,
+ onPageChange,
+}: TableProps) {
return (
-
-
-
-
- {headers.map((header, index) => (
- |
- {header}
- |
- ))}
-
-
-
- {data.map((row, index) => (
-
- ))}
-
-
-
페이지네이션
+
+
+ {userType === 'employer' ? '신청자 목록' : '신청 목록'}
+
+
+
+
+
+
+ {headers.map((header, index) => (
+ | 0 && index < headers.length - 1 && 'w-[245px]',
+ index === headers.length - 1 && 'w-[220px] md:w-[230px]'
+ )}
+ >
+ {header}
+ |
+ ))}
+
+
+
+ {data.map(row => (
+
+ ))}
+
+
+
+
+
+
);
}
diff --git a/src/components/ui/table/TableRow.tsx b/src/components/ui/table/TableRow.tsx
index 3665c13..07beb3d 100644
--- a/src/components/ui/table/TableRow.tsx
+++ b/src/components/ui/table/TableRow.tsx
@@ -1,23 +1,31 @@
+import { StatusBadge } from '@/components/ui/badge';
+import { StatusType } from '@/components/ui/badge/StatusBadge';
import { TableRowProps } from '@/components/ui/table/TableRowProps';
+import { cn } from '@/lib/utils/cn';
import { getTime } from '@/lib/utils/dateFormatter';
+import { useState } from 'react';
interface TableTypeVariant {
rowData: TableRowProps;
variant: 'employer' | 'employee';
}
-const TD_BASE = 'border-b px-2 py3';
+const TD_BASE = 'border-b border-r px-3 py-5 text-base gap-3 md:border-r-0';
const TD_STATUS = 'border-b px-2 py-[9px]';
export default function TableRow({ rowData, variant }: TableTypeVariant) {
const { date, startTime, endTime, duration } = getTime(rowData.startsAt, rowData.workhour);
+ const [status, setStatus] = useState
(rowData.status as StatusType);
+
+ const handleApprove = () => setStatus('approved');
+ const handleReject = () => setStatus('rejected');
return (
- | {rowData.name} |
+ {rowData.name} |
{variant === 'employee' ? (
<>
- {`${date} ${startTime} ~ ${date} ${endTime}} (${duration})`} |
+ {`${date} ${startTime} ~ ${date} ${endTime} (${duration})`} |
{rowData.hourlyPay} |
>
) : (
@@ -26,7 +34,14 @@ export default function TableRow({ rowData, variant }: TableTypeVariant) {
{rowData.phone} |
>
)}
- {rowData.status} |
+
+
+ |
);
}
diff --git a/src/components/ui/table/TableRowProps.tsx b/src/components/ui/table/TableRowProps.tsx
index 5544174..8605805 100644
--- a/src/components/ui/table/TableRowProps.tsx
+++ b/src/components/ui/table/TableRowProps.tsx
@@ -1,4 +1,5 @@
export type TableRowProps = {
+ id: string;
name: string;
startsAt: string;
workhour: number;
diff --git a/src/components/ui/table/testApi.tsx b/src/components/ui/table/testApi.tsx
index 1060a38..6e6d4ae 100644
--- a/src/components/ui/table/testApi.tsx
+++ b/src/components/ui/table/testApi.tsx
@@ -11,31 +11,73 @@ export const fetchTableData = async (userType: UserType) => {
name: '김강현',
bio: '최선을 다해 열심히 일합니다. 다수의 업무 경험을 바탕으로 확실한 일처리 보여드리겠습니다.',
phone: '010-1234-5678',
- status: '버튼',
+ status: 'pending',
},
{
name: '서혜진',
bio: '열심히 하겠습니다!',
- phone: '010-0000-0000',
+ phone: '010-1111-2222',
status: 'rejected',
},
{
name: '주진혁',
bio: '성실한 자세로 열심히 일합니다.',
- phone: '010-0000-0000',
- status: 'accepted',
+ phone: '010-3333-4444',
+ status: 'approved',
},
{
name: '장민혁',
bio: '일을 꼼꼼하게 하는 성격입니다.',
- phone: '010-0000-0000',
- status: 'accepted',
+ phone: '010-5555-5555',
+ status: 'approved',
},
{
name: '고기훈',
bio: '하루라도 최선을 다해서 일하겠습니다!',
- phone: '010-0000-0000',
- status: 'accepted',
+ phone: '010-6666-6666',
+ status: 'rejected',
+ },
+ {
+ name: '최현수',
+ bio: '열심히 하겠습니다!',
+ phone: '010-1123-5448',
+ status: 'pending',
+ },
+ {
+ name: '강주하',
+ bio: '성실한 자세로 열심히 일합니다.',
+ phone: '010-4123-2323',
+ status: 'approved',
+ },
+ {
+ name: '배수지',
+ bio: '열심히 배우고 일하겠습니다!',
+ phone: '010-3123-1111',
+ status: 'approved',
+ },
+ {
+ name: '강규하',
+ bio: '꼼꼼한 일처리 보여드리겠습니다.',
+ phone: '010-5123-0098',
+ status: 'rejected',
+ },
+ {
+ name: '고선영',
+ bio: '최선을 다해서 일하겠습니다!',
+ phone: '010-6662-6326',
+ status: 'peding',
+ },
+ {
+ name: '박하연',
+ bio: '뽑아주시면 열심히 하겠습니다.',
+ phone: '010-1277-1385',
+ status: 'pending',
+ },
+ {
+ name: '김연아',
+ bio: '잘 부탁드립니다!',
+ phone: '010-1232-6216',
+ status: 'rejected',
},
],
});
@@ -48,7 +90,7 @@ export const fetchTableData = async (userType: UserType) => {
startsAt: '2025-10-01T11:00',
workhour: 2,
hourlyPay: '12,500원',
- status: 'accepted',
+ status: 'pending',
},
{
name: '너구리네 라면집',
@@ -62,21 +104,28 @@ export const fetchTableData = async (userType: UserType) => {
startsAt: '2025-10-01T11:00',
workhour: 2,
hourlyPay: '12,500원',
- status: 'accepted',
+ status: 'approved',
+ },
+ {
+ name: '너구리네 라면집',
+ startsAt: '2025-10-01T11:00',
+ workhour: 2,
+ hourlyPay: '12,500원',
+ status: 'rejected',
},
{
name: '너구리네 라면집',
startsAt: '2025-10-01T11:00',
workhour: 2,
hourlyPay: '12,500원',
- status: 'accepted',
+ status: 'approved',
},
{
name: '너구리네 라면집',
startsAt: '2025-10-01T11:00',
workhour: 2,
hourlyPay: '12,500원',
- status: 'accepted',
+ status: 'approved',
},
],
});