Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
gudusol committed Oct 24, 2024
2 parents c7e473c + c3dfcba commit bf1e95f
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 5 deletions.
8 changes: 8 additions & 0 deletions public/svg/ic_copy.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions src/assets/svg/IcCopy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { SVGProps } from "react";
const SvgIcCopy = (props: SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
{...props}
>
<mask
id="ic_copy_svg__a"
width={24}
height={24}
x={0}
y={0}
maskUnits="userSpaceOnUse"
style={{
maskType: "alpha",
}}
>
<path fill="#D9D9D9" d="M0 0h24v24H0z" />
</mask>
<g mask="url(#ic_copy_svg__a)">
<path
fill="#1C1B1F"
d="M9 18q-.825 0-1.412-.587A1.93 1.93 0 0 1 7 16V4q0-.824.588-1.412A1.93 1.93 0 0 1 9 2h9q.824 0 1.413.587Q20 3.176 20 4v12q0 .824-.587 1.413A1.93 1.93 0 0 1 18 18zm0-2h9V4H9zm-4 6q-.824 0-1.412-.587A1.93 1.93 0 0 1 3 20V6h2v14h11v2z"
/>
</g>
</svg>
);
export default SvgIcCopy;
1 change: 1 addition & 0 deletions src/assets/svg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export { default as IcCheckedTrue } from "./IcCheckedTrue";
export { default as IcClipboardCopy } from "./IcClipboardCopy";
export { default as IcClose } from "./IcClose";
export { default as IcComplete } from "./IcComplete";
export { default as IcCopy } from "./IcCopy";
export { default as IcDelete } from "./IcDelete";
export { default as IcDownload } from "./IcDownload";
export { default as IcFix } from "./IcFix";
Expand Down
40 changes: 40 additions & 0 deletions src/pages/Admin/components/OrderTable/OrderTable.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,43 @@ export const checkboxStyle = css`
width: 1.6rem;
height: 1.6rem;
`;

export const numberText = css`
${flexGenerator()};
`;

export const copyIconStyle = (theme: Theme) => css`
display: inline-block;
width: 2.4rem;
height: 2.4rem;
padding: 0.2rem;
cursor: pointer;
border-radius: 0.4rem;
&:hover {
background-color: ${theme.color.lightgray3};
}
`;

export const confrimModal = css`
${flexGenerator("column")};
padding: 2rem;
gap: 2rem;
width: 35rem;
& hr {
width: 100%;
}
`;

export const modalTitle = (theme: Theme) => css`
${theme.font["head02-b-20"]};
`;

export const productText = (theme: Theme) => css`
${theme.font["head06-b-16"]};
`;

export const modalNotice = (theme: Theme) => css`
${theme.font["head06-b-16"]};
`;
121 changes: 117 additions & 4 deletions src/pages/Admin/components/OrderTable/OrderTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ import { useState } from "react";
import {
buttonContainer,
checkboxStyle,
confrimModal,
copyIconStyle,
iconStyle,
modalNotice,
modalTitle,
numberText,
productText,
sectionStyle,
sectionTitle,
tableHeader,
Expand All @@ -11,9 +17,10 @@ import {
} from "./OrderTable.style";
import { Order } from "@types";
import { usePatchDeliveryShipped } from "@apis/domains/admin/usePatchDeliveryShipped";
import { Button } from "@components";
import { IcCheckedTrue, IcDownload } from "@svg";
import { Button, Modal, Toast } from "@components";
import { IcCheckedTrue, IcCopy, IcDownload } from "@svg";
import * as XLSX from "xlsx";
import useToast from "src/hooks/useToast";

interface OrderTableProps {
orders: Order[];
Expand All @@ -22,12 +29,51 @@ interface OrderTableProps {
const OrderTable = ({ orders }: OrderTableProps) => {
const [selectedOrders, setSelectedOrders] = useState<number[]>([]);

const [isModalOpen, setIsModalOpen] = useState(false);

const { showToast, isToastVisible } = useToast();
const [toastMessage, setToastMessage] = useState("");

const [productCount, setProductCount] = useState<Record<string, number>>({});

const { mutate } = usePatchDeliveryShipped();

const handleShippedClick = () => {
mutate(selectedOrders);
};

const handleModalClose = () => {
setIsModalOpen(false);
};

const handleExcelClick = () => {
if (selectedOrders.length === 0) {
setToastMessage("주문을 선택해주세요.");
showToast();
return;
}
const selectedData = orders.filter((order) =>
selectedOrders.includes(order.deliveryId)
);

const count = selectedData
.map((order) => order.productList)
.flat()
.reduce((acc, product) => {
const match = product.match(/(.+)\s(\d+)EA$/);
if (match) {
const productName = match[1].trim();
const quantity = parseInt(match[2], 10);

acc[productName] = (acc[productName] || 0) + quantity;
}
return acc;
}, {} as Record<string, number>);

setIsModalOpen(true);
setProductCount(count);
};

const exportToExcel = () => {
const selectedData = orders.filter((order) =>
selectedOrders.includes(order.deliveryId)
Expand Down Expand Up @@ -75,6 +121,8 @@ const OrderTable = ({ orders }: OrderTableProps) => {
link.href = url;
link.download = "export.xlsx";
link.click();

handleModalClose();
};

const handleCheckboxChange = (id: number) => {
Expand All @@ -98,6 +146,37 @@ const OrderTable = ({ orders }: OrderTableProps) => {
}
};

const handleCopyClick = async (order: Order) => {
const orderInfoData = `[접수날짜]
${order.orderReceivedDate}
[보내는 분]
${order.senderName}
${order.senderPhone}
[받는 분]
${order.recipientName}
${order.recipientPhone}
${order.recipientAddress} ${order.recipientAddressDetail}
[상품]
${order.productList.join(", ")}`;

if (navigator.clipboard) {
try {
await navigator.clipboard.writeText(orderInfoData);
setToastMessage("주문내역이 복사되었어요.");
showToast();
} catch {
setToastMessage("클립보드 복사 실패");
showToast();
}
} else {
setToastMessage("클립보드에 복사할 수 없습니다.");
showToast();
}
};

const isAllSelected =
selectedOrders.length > 0 &&
selectedOrders.length ===
Expand All @@ -111,7 +190,7 @@ const OrderTable = ({ orders }: OrderTableProps) => {
<IcCheckedTrue css={iconStyle} />
<span>선택 발송완료</span>
</Button>
<Button variant="smallStroke" onClick={exportToExcel}>
<Button variant="smallStroke" onClick={handleExcelClick}>
<IcDownload css={iconStyle} />
<span>엑셀 다운로드</span>
</Button>
Expand Down Expand Up @@ -158,7 +237,17 @@ const OrderTable = ({ orders }: OrderTableProps) => {
/>
</td>
<td>{order.orderReceivedDate}</td>
<td>{order.orderNumber}</td>
<td>
<div css={numberText}>
<span>{order.orderNumber}</span>
<span
css={copyIconStyle}
onClick={() => handleCopyClick(order)}
>
<IcCopy />
</span>
</div>
</td>
<td>
{order.productList.map((product) => {
return <div>{product}</div>;
Expand All @@ -176,6 +265,30 @@ const OrderTable = ({ orders }: OrderTableProps) => {
</tbody>
</table>
</main>
{isModalOpen && (
<Modal onClose={handleModalClose}>
<article css={confrimModal}>
<h3
css={modalTitle}
>{`총 ${selectedOrders.length}개의 주문을 선택했습니다.`}</h3>
<hr />
{Object.entries(productCount).map(([productName, count]) => (
<div key={productName} css={productText}>
<span>{`${productName}: `}</span>
<span>{`${count} 개`}</span>
</div>
))}
<hr />
<p css={modalNotice}>이대로 엑셀을 다운로드 하시겠습니까?</p>
<Button variant="fill" onClick={exportToExcel}>
확인
</Button>
</article>
</Modal>
)}
<Toast isVisible={isToastVisible} toastBottom={3}>
{toastMessage}
</Toast>
</article>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const OrderInfoSection = () => {
<span css={blackSpan}>{orderInfo?.senderName}</span>
</div>
<div css={section3Div}>
<span css={graySpan}>{`상품 (${orderCount}건의 주문)`}</span>
<span css={graySpan}>{`상품 (${orderCount})`}</span>
{(mergedOrders || []).map((order, i) => (
<span
key={i}
Expand Down

0 comments on commit bf1e95f

Please sign in to comment.