-
Notifications
You must be signed in to change notification settings - Fork 44
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
[김한샘] Week12 #390
The head ref may contain hidden characters: "part2-\uAE40\uD55C\uC0D8-week12"
[김한샘] Week12 #390
Changes from all commits
771e7a1
e6af1ee
c83ed0d
516989f
9b34bec
a745f55
8504573
d0384e6
2ea5507
19fc358
25f4ccf
1168a01
6a2e5ce
e8b8cda
6477d00
01de7d7
88434e3
71f499e
2cc4953
09acc16
d001534
4f2dbf1
f85510c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,5 +37,8 @@ | |
"last 1 firefox version", | ||
"last 1 safari version" | ||
] | ||
}, | ||
"devDependencies": { | ||
"typescript": "^4.9.5" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,20 @@ | ||
import "./styles/form.css"; | ||
import "./styles/pages/main/main.css"; | ||
|
||
import React from "react"; | ||
import Footer from "./components/Footer/Footer"; | ||
import Header from "./components/Header/Header"; | ||
import { BrowserRouter } from "react-router-dom"; | ||
import AppRouter from "./routes"; | ||
|
||
function App() { | ||
return ( | ||
<BrowserRouter> | ||
<Header /> | ||
<AppRouter /> | ||
<Footer /> | ||
</BrowserRouter> | ||
); | ||
return ( | ||
<BrowserRouter> | ||
<Header /> | ||
<AppRouter /> | ||
<Footer /> | ||
</BrowserRouter> | ||
); | ||
} | ||
|
||
export default App; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,13 @@ | ||
import React from "react"; | ||
import starIcon from "../../assets/svg/star.svg"; | ||
import "./EditableStarButton.css"; | ||
|
||
function EditableStarButton() { | ||
return ( | ||
<button className="editable-star"> | ||
<img src={starIcon} alt="즐겨찾기" /> | ||
</button> | ||
); | ||
return ( | ||
<button className="editable-star"> | ||
<img src={starIcon} alt="즐겨찾기" /> | ||
</button> | ||
); | ||
} | ||
|
||
export default EditableStarButton; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,30 @@ | ||
import "./KebabList.css"; | ||
import { useContext } from "react"; | ||
import ModalContext from "../Modal/ModalContext"; | ||
import React from "react"; | ||
|
||
function KebabList({ url, setDisplay }) { | ||
const { openModal, setModalType, setCardUrl } = useContext(ModalContext); | ||
interface KebabListInterface { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 변수명에 변수 타입이 들어가는 것이 안좋듯이, type과 interface도 마찬가지입니다. |
||
url: string; | ||
setDisplay: boolean | (() => void); | ||
} | ||
|
||
function KebabList({ url, setDisplay }: KebabListInterface) { | ||
const { openModal, setModalType, setCardUrl } = useContext(ModalContext)!; | ||
|
||
const onClickDeleteLinkModalOpen = (e) => { | ||
const onClickDeleteLinkModalOpen = (e: React.MouseEvent<HTMLButtonElement>) => { | ||
e.preventDefault(); | ||
setModalType("linkDelete"); | ||
setCardUrl(url); | ||
openModal(); | ||
setDisplay(); | ||
if (typeof setDisplay === "function") setDisplay(); | ||
}; | ||
|
||
const onClickAddFolderModalOpen = (e) => { | ||
const onClickAddFolderModalOpen = (e: React.MouseEvent<HTMLButtonElement>) => { | ||
e.preventDefault(); | ||
setModalType("folderAdd"); | ||
setCardUrl(url); | ||
openModal(); | ||
setDisplay(); | ||
if (typeof setDisplay === "function") setDisplay(); | ||
}; | ||
return ( | ||
<ul className="Kebab-list"> | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import React from "react"; | ||
import "./CardList.css"; | ||
import Card from "../Card/Card"; | ||
|
||
interface CardListData { | ||
id: number; | ||
createdAt: string; | ||
url: string; | ||
title: string; | ||
description: string; | ||
imageSource?: string; | ||
} | ||
|
||
interface UserFolderCardDataList { | ||
data: { | ||
id: number; | ||
createdAt: string; | ||
description?: string; | ||
folderId?: number; | ||
title?: string; | ||
updatedAt?: string; | ||
url: string; | ||
imageSource?: string; | ||
}; | ||
} | ||
Comment on lines
+14
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 바로 위에 선언한 CardListData를 재활용하는 것이 좋습니다. TS의 & 를 잘 이용해보세요. |
||
|
||
function renderCardList(cardData: CardListData[] | UserFolderCardDataList["data"][]) { | ||
return ( | ||
<ul className="card-list"> | ||
{Array.isArray(cardData) && | ||
cardData.map((card) => { | ||
return <Card card={card} key={card.id} />; | ||
})} | ||
</ul> | ||
); | ||
} | ||
|
||
function CardList({ | ||
cardListData, | ||
userFolderDataList, | ||
}: { | ||
cardListData?: CardListData[]; | ||
userFolderDataList?: UserFolderCardDataList; | ||
}) { | ||
return ( | ||
<> | ||
{cardListData && cardListData.length > 0 && renderCardList(cardListData)} | ||
{userFolderDataList && | ||
Array.isArray(userFolderDataList.data) && | ||
userFolderDataList.data.length > 0 && | ||
renderCardList(userFolderDataList.data)} | ||
{!cardListData && !userFolderDataList && ( | ||
<div className="empty-link">저장된 링크가 없습니다.</div> | ||
)} | ||
</> | ||
); | ||
} | ||
|
||
export default CardList; |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import React from "react"; | ||
import "./ConHeader.css"; | ||
|
||
interface FolderData { | ||
id: number; | ||
name: string; | ||
owner: { | ||
id: number; | ||
name: string; | ||
profileImageSource: string; | ||
}; | ||
links: { | ||
id: number; | ||
createdAt: string; | ||
url: string; | ||
title: string; | ||
description: string; | ||
imageSource?: string; | ||
}[]; | ||
count: number; | ||
} | ||
|
||
function ConHeader({ folderData }: { folderData: FolderData | null }) { | ||
const owner = folderData?.owner; | ||
|
||
return ( | ||
<div className="con-header-wrap"> | ||
<div className="con-header"> | ||
<img src={owner?.profileImageSource} alt="" /> | ||
<h3>{owner?.name}</h3> | ||
</div> | ||
<h2>{folderData?.name}</h2> | ||
</div> | ||
); | ||
} | ||
|
||
export default ConHeader; |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import React from "react"; | ||
import "./Button.css"; | ||
|
||
interface buttonData { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 타입의 이름들은 파스칼케이스로 작성해주시는 편이 좋습니다. |
||
data: { | ||
id: number; | ||
name: string; | ||
}; | ||
onClickButton: (id: number, name: string) => void; | ||
buttonClass: number | null; | ||
} | ||
|
||
function Button({ data, onClickButton, buttonClass }: buttonData) { | ||
const { id, name } = data; | ||
|
||
return ( | ||
<button className={buttonClass === id ? "select" : ""} onClick={() => onClickButton(id, name)}> | ||
{name} | ||
</button> | ||
); | ||
} | ||
|
||
export default Button; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Card 컴포넌트의 Prop에 대한 type인데 CardPropType 정도로 표현하면 더 직관적이지 않을까요?