Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[정원식] Sprint 8 #251

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,569 changes: 2,557 additions & 12 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"react-router-dom": "^6.25.1"
},
"devDependencies": {
"@svgr/webpack": "^8.1.0",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^7.15.0",
Expand All @@ -27,6 +28,7 @@
"eslint-plugin-react-refresh": "^0.4.7",
"sass": "^1.77.8",
"typescript": "^5.2.2",
"vite": "^5.3.4"
"vite": "^5.3.4",
"vite-plugin-svgr": "^4.2.0"
}
}
14 changes: 7 additions & 7 deletions src/components/items/BestItems/BestItems.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import './BestItems.css';
import { useEffect, useState } from 'react';
import Item from '../Item/Item';
import { getProducts } from '../../../pages/api/Items';
import { useNavigate } from 'react-router-dom';
import Item from '../Item/Item';
import './BestItems.css';

const getPageSize = () => {
const width = window.innerWidth;
Expand All @@ -24,10 +24,10 @@ function BestItems() {
const [pageSize, setPageSize] = useState(4);
const [keyword, setKeyword] = useState('');
// 에러
const [fetchingError, setfetchingError] = useState(null);
const [fetchingError, setfetchingError] = useState<any>(null);
const navigate = useNavigate();

const fetchItemList = async ({ order, page, pageSize, keyword }) => {
const fetchItemList = async () => {
try {
setfetchingError(null);
const products = await getProducts({ order, page, pageSize, keyword });
Expand All @@ -42,15 +42,15 @@ function BestItems() {
setPageSize(getPageSize());
};

const handleClickItem = (e) => {
const handleClickItem = (e: any) => {
e.preventDefault();

navigate(`/items/${e.currentTarget.dataset.itemId}`);
};

useEffect(() => {
window.addEventListener('resize', handleResize);
fetchItemList({ order, page, pageSize, keyword });
fetchItemList();

return () => {
window.removeEventListener('resize', handleResize);
Expand All @@ -64,7 +64,7 @@ function BestItems() {

<div className="list-best-items">
{fetchingError && fetchingError.message}
{itemList?.map((item) => (
{itemList?.map((item: any) => (
<Item
item={item}
key={`best-item-${item.id}`}
Expand Down
14 changes: 9 additions & 5 deletions src/components/items/Item/Item.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import React from 'react';
import { ReactComponent as IconHeart } from '../../../assets/images/icons/ic_heart.svg';
// import { ReactComponent as IconHeart } from '../../../assets/images/icons/ic_heart.svg';
import ImgDefault from '../../../assets/images/market/img_default.png';

function Item({ item, handleClick = () => {} }) {
const handleErrorImage = (e) => {
interface ItemProps {
item: any;
handleClick: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void;
}

function Item({ item, handleClick }: ItemProps) {
const handleErrorImage = (e: any) => {
e.target.src = ImgDefault;
};

Expand All @@ -19,7 +23,7 @@ function Item({ item, handleClick = () => {} }) {
<p className="item-name">{item.name}</p>
<p className="item-price">{item.price.toLocaleString()}원</p>
<div className="item-favorite-count">
<IconHeart />
{/* <IconHeart /> */}
{item.favoriteCount}
</div>
</div>
Expand Down
11 changes: 10 additions & 1 deletion src/components/items/ItemInfo/ItemInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,23 @@ import HorizontalLine from '../../../core/ui/lines/HorizontalLine/HorizontalLine
import TagList from '../../../core/ui/tags/TagList/TagList';
import styles from './ItemInfo.module.scss';

interface ItemInfoProps {
itemImgSrc: string;
itemTitle: string;
itemPrice: number;
itemDesc: string;
itemTags: any[];
itemFavoriteCount: number;
}

function ItemInfo({
itemImgSrc = '',
itemTitle = '',
itemPrice = 0,
itemDesc = '',
itemTags = [],
itemFavoriteCount = 0,
}) {
}: ItemInfoProps) {
return (
<>
<div className={styles['item-info']}>
Expand Down
21 changes: 15 additions & 6 deletions src/components/items/PaginationBar/PaginationBar.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import React from 'react';
// import { ReactComponent as IconArrowLeft } from '../../../assets/images/icons/arrow_left.svg';
// import { ReactComponent as IconArrowRight } from '../../../assets/images/icons/arrow_right.svg';
import './PaginatinoBar.css';
import { ReactComponent as IconArrowLeft } from '../../../assets/images/icons/arrow_left.svg';
import { ReactComponent as IconArrowRight } from '../../../assets/images/icons/arrow_right.svg';

function PaginationBar({ totalPageNum, activePageNum, onPageChange }) {
interface PaginatinoBarProps {
totalPageNum: number;
activePageNum: number;
onPageChange: (i: number) => void;
}

function PaginationBar({
totalPageNum,
activePageNum,
onPageChange,
}: PaginatinoBarProps) {
const maxVisiblePages = 5;
let startPage;

Expand All @@ -26,7 +35,7 @@ function PaginationBar({ totalPageNum, activePageNum, onPageChange }) {
disabled={activePageNum === 1}
onClick={() => onPageChange(activePageNum - 1)}
>
<IconArrowLeft />
{/* <IconArrowLeft /> */}
</button>
{/* 반복 */}
{pages.map((page) => (
Expand All @@ -45,7 +54,7 @@ function PaginationBar({ totalPageNum, activePageNum, onPageChange }) {
disabled={activePageNum === totalPageNum}
onClick={() => onPageChange(activePageNum + 1)}
>
<IconArrowRight />
{/* <IconArrowRight /> */}
</button>
</div>
</>
Expand Down
45 changes: 31 additions & 14 deletions src/components/items/SellingItems/SellingItems.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { ReactComponent as IconSearch } from '../../../assets/images/icons/ic_search.svg';
import { ReactComponent as IconSort } from '../../../assets/images/icons/ic_sort.svg';
// import { ReactComponent as IconSearch } from '../../../assets/images/icons/ic_search.svg';
// import { ReactComponent as IconSort } from '../../../assets/images/icons/ic_sort.svg';
import { useEffect, useState } from 'react';
import { getProducts } from '../../../pages/api/Items';
import Item from '../Item/Item';
import PaginationBar from '../PaginationBar/PaginationBar';
import './SellingItems.css';
import { useNavigate } from 'react-router-dom';

interface Item {
id: number;
}

const getPageSize = () => {
const width = window.innerWidth;
if (width < 768) {
Expand All @@ -20,7 +24,7 @@ const getPageSize = () => {

function SellingItems() {
// 상품
const [itemList, setItemList] = useState([]);
const [itemList, setItemList] = useState<Item[]>([]);
// 쿼리
const [order, setOrder] = useState('recent');
const [page, setPage] = useState(1);
Expand All @@ -29,35 +33,48 @@ function SellingItems() {
// 검색
const [isDropdownVisible, setIsDropdownVisible] = useState(false);
// 페이지네이션
const [totalPageNum, setTotalPageNum] = useState();
const [totalPageNum, setTotalPageNum] = useState<number>(0);
// 에러
const [fetchingError, setfetchingError] = useState(null);
const [fetchingError, setfetchingError] = useState<null | Error>(null);
const navigate = useNavigate();

const handlePageChange = (pageNumber) => {
const handlePageChange = (pageNumber: number) => {
setPage(pageNumber);
};
const handleClickDropdown = () => {
setIsDropdownVisible(!isDropdownVisible);
};
const handleClickDropdownItem = (order) => {
const handleClickDropdownItem = (order: string) => {
setOrder(order);
setIsDropdownVisible(!isDropdownVisible);
};
const handleKeyupSearchInput = (event) => {
const handleKeyupSearchInput = (
event: React.KeyboardEvent<HTMLInputElement>
) => {
if (event.keyCode === 13) {
event.preventDefault();
setKeyword(event.target.value);
const target = event.target as HTMLInputElement;
setKeyword(target.value);
}
};

const handleClickItem = (e) => {
const handleClickItem = (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
e.preventDefault();

navigate(`/items/${e.currentTarget.dataset.itemId}`);
};

const fetchItemList = async ({ order, page, pageSize, keyword }) => {
const fetchItemList = async ({
order,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기서 미리 정의한 type OrderType = 'recent' | 'favorite' 값을 가져오면 되겠네요!

Copy link
Collaborator

@arthurkimdev arthurkimdev Aug 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아래 다른 값들도 처음 js -> ts 전환할때 any 로 시작하는 방법 좋구요. 👍 천천히 바꿔나가시면 됩니다.

page,
pageSize,
keyword,
}: {
order: any;
page: any;
pageSize: any;
keyword: any;
}) => {
try {
setfetchingError(null);
const products = await getProducts({ order, page, pageSize, keyword });
Expand All @@ -66,7 +83,7 @@ function SellingItems() {
} catch (err) {
setItemList([]);
setTotalPageNum(0);
setfetchingError(err);
setfetchingError(err as Error);
}
};

Expand Down Expand Up @@ -99,7 +116,7 @@ function SellingItems() {
상품 등록하기
</a>
<div className="wrapper-input-search-item">
<IconSearch />
{/* <IconSearch /> */}
<input
className="input-search-item"
placeholder="검색할 상품을 입력해 주세요"
Expand All @@ -109,7 +126,7 @@ function SellingItems() {
<div className="wrapper-sort-item">
<button className="btn-sort-item" onClick={handleClickDropdown}>
{order === 'recent' ? '최신순' : '좋아요순'}
<IconSort />
{/* <IconSort /> */}
</button>
{isDropdownVisible && (
<div className="dropdown-sort-item">
Expand Down
19 changes: 15 additions & 4 deletions src/core/ui/buttons/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
import { useEffect, useRef } from 'react';

import './Button.css';

interface ButtonProps {
text?: string;
onClick?: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void;
isDisabled?: boolean;
iconFront?: React.ReactNode;
iconBack?: React.ReactNode;
customBorderRound?: any;
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

customBorderRound 값은 사용하지 않는 값이라 제거해도 될 것 같은데요!? 🤖

function Button({
text = '버튼',
onClick = () => {},
isDisabled = false,
iconFront,
iconBack,
customBorderRound,
}) {
const ref = useRef();
}: ButtonProps) {
const ref = useRef<HTMLButtonElement>(null);

useEffect(() => {
ref.current.disabled = isDisabled ? true : false;
if (ref.current) {
ref.current.disabled = isDisabled;
}
}, [isDisabled]);

return (
Expand Down
4 changes: 2 additions & 2 deletions src/core/ui/buttons/FavoriteButton/FavoriteButton.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useState } from 'react';
import { ReactComponent as IconHeart } from '../../../../assets/images/icons/ic_heart.svg';
// import { ReactComponent as IconHeart } from '../../../../assets/images/icons/ic_heart.svg';
import styles from './FavoriteButton.module.scss';

function FavoriteButton({ initCount = 0 }) {
Expand All @@ -13,7 +13,7 @@ function FavoriteButton({ initCount = 0 }) {
<>
<button className={styles.btn} onClick={handleClick}>
<div className={styles.btn__wrapper}>
<IconHeart />
{/* <IconHeart /> */}
<p className={styles.btn__count}>{count}</p>
</div>
</button>
Expand Down
12 changes: 10 additions & 2 deletions src/core/ui/cards/ImageCard/ImageCard.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import styles from './ImageCard.module.scss';
import errImg from '../../../../assets/images/market/img_default.png';

interface ImageCardProps {
imageSrc: string;
ImgDeafault?: string;
isRoundEdged?: boolean;
isRound?: boolean;
}

function ImageCard({
imageSrc,
ImgDeafault,
isRoundEdged = false,
isRound = false,
}) {
}: ImageCardProps) {
return (
<>
<div className={styles.wrapper}>
Expand All @@ -18,7 +25,8 @@ function ImageCard({
`}
alt="상품 사진"
onError={(e) => {
e.target.src = errImg;
const target = e.target as HTMLImageElement;
target.src = errImg;
}}
/>
</div>
Expand Down
9 changes: 8 additions & 1 deletion src/core/ui/comments/CommentItem/CommentItem.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import ImageCard from '../../cards/ImageCard/ImageCard';
import styles from './CommentItem.module.scss';

interface CommentItemProps {
profileImageSrc: string;
nickname: string;
content: string;
updatedAt: string;
}

export default function CommentItem({
profileImageSrc,
nickname = 'nickname',
content = 'content',
updatedAt = '0시간 전',
}) {
}: CommentItemProps) {
return (
<>
<div className={styles.comment}>
Expand Down
9 changes: 8 additions & 1 deletion src/core/ui/comments/CommentList/CommentList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@ import HorizontalLine from '../../lines/HorizontalLine/HorizontalLine';
import CommentItem from '../CommentItem/CommentItem';
import styles from './CommentList.module.scss';

interface CommentListProps {
initCommentCount: number;
comments: any[];
emptyIcon: any;
emptyMessage: string;
}

export default function CommentList({
initCommentCount = 3,
comments = [],
emptyIcon,
emptyMessage = '',
}) {
}: CommentListProps) {
return (
<>
<div className={styles.list}>
Expand Down
Loading