-
Notifications
You must be signed in to change notification settings - Fork 39
[김지현] sprint6 #185
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
The head ref may contain hidden characters: "React-\uAE40\uC9C0\uD604-sprint6"
[김지현] sprint6 #185
Changes from all commits
657d316
43a128d
028ab23
e733c23
0478e89
63013e2
ef8b0f9
3e8da57
22063ba
80a3982
71404f6
10f6827
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,8 +1,19 @@ | ||||||||||||||||||||||||||||||||||||||
| function Button({ children, onClick }) { | ||||||||||||||||||||||||||||||||||||||
| function Button({ children, type, onClick, disabled }) { | ||||||||||||||||||||||||||||||||||||||
| const buttonStyles = { | ||||||||||||||||||||||||||||||||||||||
| login: "w-128 h-48 rounded-lg bg-blue100 text-lg text-white font-semibold", | ||||||||||||||||||||||||||||||||||||||
| shopping: | ||||||||||||||||||||||||||||||||||||||
| "w-357 h-56 rounded-[40px] bg-blue100 text-2lg tablet:text-xl text-white font-semibold", | ||||||||||||||||||||||||||||||||||||||
| additem: | ||||||||||||||||||||||||||||||||||||||
| "py-8 px-24 rounded-lg bg-blue100 text-lg text-white font-semibold", | ||||||||||||||||||||||||||||||||||||||
| upload: | ||||||||||||||||||||||||||||||||||||||
| "w-74 h-42 rounded-lg bg-blue100 text-lg text-white font-semibold disabled:bg-gray400 disabled:cursor-not-allowed", | ||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+2
to
+11
Collaborator
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. 💊 제안 이런 경우 중복되는 친구들을 아래처럼 작성해주시면 코드가 더 명확해집니다.
Suggested change
|
||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||
| <button | ||||||||||||||||||||||||||||||||||||||
| className="py-8 px-24 bg-blue100 text-white text-lg font-semibold rounded-lg cursor-pointer" | ||||||||||||||||||||||||||||||||||||||
| className={`${buttonStyles[type]} cursor-pointer`} | ||||||||||||||||||||||||||||||||||||||
| onClick={onClick} | ||||||||||||||||||||||||||||||||||||||
| disabled={disabled} | ||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||
| {children} | ||||||||||||||||||||||||||||||||||||||
| </button> | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
|
Collaborator
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. 💊 제안 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| function inputField({ type, label, value, onChange, onKeyDown, placeholder }) { | ||
| if (type === "input") { | ||
| return ( | ||
| <div className="flex flex-col justify-center gap-16"> | ||
| <div className="text-2lg font-bold">{label}</div> | ||
|
Collaborator
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. ❗️ 수정요청 |
||
| <input | ||
| className="bg-gray100 .placeholder-text-gray400 text-lg font-regular rounded-xl py-16 px-24" | ||
| value={value} | ||
| onChange={onChange} | ||
| onKeyDown={onKeyDown} | ||
| placeholder={placeholder} | ||
| /> | ||
| </div> | ||
| ); | ||
| } else if (type === "textarea") { | ||
| return ( | ||
| <div className="flex flex-col justify-center gap-16"> | ||
| <div className="text-2lg font-bold">{label}</div> | ||
| <textarea | ||
| className="h-282 bg-gray100 .placeholder-text-gray400 text-lg font-regular rounded-xl py-16 px-24" | ||
| value={value} | ||
| onChange={onChange} | ||
| onKeyDown={onKeyDown} | ||
| placeholder={placeholder} | ||
| ></textarea> | ||
| </div> | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| export default inputField; | ||
|
Collaborator
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. 💊 제안 https://ko.react.dev/learn/choosing-the-state-structure 이는 알고만 계시다가 추후 typescript 적용하실때 다시 생각해보시면 도움이 되실 것 같아요. |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,5 +1,148 @@ | ||||||||||||||||||||||||
| import { useState, useRef } from "react"; | ||||||||||||||||||||||||
| import Button from "../components/Button"; | ||||||||||||||||||||||||
| import Header from "../components/Header"; | ||||||||||||||||||||||||
| import InputField from "../components/InputField"; | ||||||||||||||||||||||||
| import plus from "../assets/icons/plus.svg"; | ||||||||||||||||||||||||
| import x from "../assets/icons/x.svg"; | ||||||||||||||||||||||||
|
Collaborator
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. 💊 제안 |
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| function AddItemPage() { | ||||||||||||||||||||||||
| return <div>hi</div>; | ||||||||||||||||||||||||
| const imgRef = useRef(null); | ||||||||||||||||||||||||
| const [imgPreview, setImgPreview] = useState(""); | ||||||||||||||||||||||||
| const [itemName, setItemName] = useState(""); | ||||||||||||||||||||||||
| const [itemDetail, setItemDetail] = useState(""); | ||||||||||||||||||||||||
| const [price, setPrice] = useState(""); | ||||||||||||||||||||||||
| const [tagInput, setTagInput] = useState(""); | ||||||||||||||||||||||||
| const [tags, setTags] = useState([]); | ||||||||||||||||||||||||
| const isFormValid = itemName && itemDetail && price && tags.length > 0; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| const handleUploadImg = (e) => { | ||||||||||||||||||||||||
| const file = e.target.files[0]; | ||||||||||||||||||||||||
| if (file) { | ||||||||||||||||||||||||
| const previewUrl = URL.createObjectURL(file); | ||||||||||||||||||||||||
| setImgPreview(previewUrl); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
| const handleDeleteImg = () => { | ||||||||||||||||||||||||
| setImgPreview(""); | ||||||||||||||||||||||||
| if (imgRef.current) { | ||||||||||||||||||||||||
| imgRef.current.value = null; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| const handleEnterTag = (e) => { | ||||||||||||||||||||||||
| if (e.key === "Enter" && !e.nativeEvent.isComposing) { | ||||||||||||||||||||||||
|
Collaborator
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. 👍 칭찬 |
||||||||||||||||||||||||
| e.preventDefault(); | ||||||||||||||||||||||||
| const newTag = tagInput.trim(); | ||||||||||||||||||||||||
| if (newTag && !tags.includes(newTag)) { | ||||||||||||||||||||||||
| setTags([...tags, newTag]); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| setTagInput(""); | ||||||||||||||||||||||||
|
Comment on lines
+36
to
+39
Collaborator
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. 💊 제안 |
||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
| const handleDeleteTag = (index) => { | ||||||||||||||||||||||||
| const newTags = [...tags]; | ||||||||||||||||||||||||
| newTags.splice(index, 1); | ||||||||||||||||||||||||
| setTags(newTags); | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||
| <div> | ||||||||||||||||||||||||
| <Header /> | ||||||||||||||||||||||||
| <div className="max-w-1200 m-auto flex flex-col gap-24 pt-24 px-15 pb-52"> | ||||||||||||||||||||||||
| <div className="flex justify-between items-center"> | ||||||||||||||||||||||||
| <div className="text-xl font-bold">상품 등록하기</div> | ||||||||||||||||||||||||
| <Button type="upload" disabled={!isFormValid}> | ||||||||||||||||||||||||
| 등록 | ||||||||||||||||||||||||
| </Button> | ||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||
| <div className="flex flex-col justify-center gap-16"> | ||||||||||||||||||||||||
| <div className="text-2lg font-bold">상품 이미지</div> | ||||||||||||||||||||||||
| <div className="flex gap-10 pc:gap-24"> | ||||||||||||||||||||||||
| <label className="flex flex-col justify-center items-center gap-12 size-168 pc:size-282 bg-gray100 text-gray400 text-lg font-regular rounded-xl cursor-pointer"> | ||||||||||||||||||||||||
| <img className="size-48" src={plus} /> | ||||||||||||||||||||||||
| 이미지 등록 | ||||||||||||||||||||||||
| <input | ||||||||||||||||||||||||
| className="hidden" | ||||||||||||||||||||||||
| type="file" | ||||||||||||||||||||||||
| onChange={handleUploadImg} | ||||||||||||||||||||||||
| ref={imgRef} | ||||||||||||||||||||||||
| disabled={imgPreview} | ||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||
|
Comment on lines
+62
to
+70
Collaborator
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. 💊 제안 |
||||||||||||||||||||||||
| </label> | ||||||||||||||||||||||||
| {imgPreview ? ( | ||||||||||||||||||||||||
| <> | ||||||||||||||||||||||||
| <img | ||||||||||||||||||||||||
| className="size-168 pc:size-282 rounded-xl" | ||||||||||||||||||||||||
| src={imgPreview} | ||||||||||||||||||||||||
| alt="미리보기" | ||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||
| <img | ||||||||||||||||||||||||
| className="relative right-40 pc:right-52 top-8 size-22 cursor-pointer" | ||||||||||||||||||||||||
| src={x} | ||||||||||||||||||||||||
| onClick={handleDeleteImg} | ||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||
| </> | ||||||||||||||||||||||||
| ) : ( | ||||||||||||||||||||||||
| "" | ||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||
| {imgPreview ? ( | ||||||||||||||||||||||||
| <div className="text-red text-lg font-regular"> | ||||||||||||||||||||||||
| *이미지 등록은 최대 1개까지 가능합니다. | ||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||
| ) : ( | ||||||||||||||||||||||||
| "" | ||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||
| <InputField | ||||||||||||||||||||||||
| type="input" | ||||||||||||||||||||||||
| label="상품명" | ||||||||||||||||||||||||
| value={itemName} | ||||||||||||||||||||||||
| onChange={(e) => setItemName(e.target.value)} | ||||||||||||||||||||||||
| placeholder="상품명을 입력해주세요" | ||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||
| <InputField | ||||||||||||||||||||||||
| type="textarea" | ||||||||||||||||||||||||
| label="상품소개" | ||||||||||||||||||||||||
| value={itemDetail} | ||||||||||||||||||||||||
| onChange={(e) => setItemDetail(e.target.value)} | ||||||||||||||||||||||||
| placeholder="상품 소개를 입력해주세요" | ||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||
| <InputField | ||||||||||||||||||||||||
|
Collaborator
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="input" | ||||||||||||||||||||||||
| label="판매가격" | ||||||||||||||||||||||||
| value={price} | ||||||||||||||||||||||||
| onChange={(e) => setPrice(e.target.value)} | ||||||||||||||||||||||||
| placeholder="판매 가격을 입력해주세요" | ||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||
| <InputField | ||||||||||||||||||||||||
| type="input" | ||||||||||||||||||||||||
| label="태그" | ||||||||||||||||||||||||
| value={tagInput} | ||||||||||||||||||||||||
| onChange={(e) => setTagInput(e.target.value)} | ||||||||||||||||||||||||
| onKeyDown={handleEnterTag} | ||||||||||||||||||||||||
| placeholder="태그를 입력해주세요" | ||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||
| <div className="flex gap-12"> | ||||||||||||||||||||||||
| {tags.map((tag, index) => { | ||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||
| <span | ||||||||||||||||||||||||
| key={index} | ||||||||||||||||||||||||
|
Comment on lines
+129
to
+130
Collaborator
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. 💊 제안
Suggested change
|
||||||||||||||||||||||||
| className="flex items-center gap-8 py-6 pl-16 pr-12 bg-gray100 rounded-[26px]" | ||||||||||||||||||||||||
| > | ||||||||||||||||||||||||
| #{tag} | ||||||||||||||||||||||||
| <img | ||||||||||||||||||||||||
| className="size-22 cursor-pointer" | ||||||||||||||||||||||||
| src={x} | ||||||||||||||||||||||||
| onClick={() => handleDeleteTag(index)} | ||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||
|
Comment on lines
+134
to
+138
Collaborator
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. ❗️ 수정요청
Suggested change
|
||||||||||||||||||||||||
| </span> | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| })} | ||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| export default AddItemPage; | ||||||||||||||||||||||||
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.
❗️ 수정요청
버튼의 type은 일반적으로 버튼 태그의 type: "button" | "reset" | "submit" 을 의미합니다.
type은 중요한 속성이니 type prop가 "button" | "reset" | "submit"을 받게 하시고, style의 종류는 variant와 같은 이름으로 변경하시는 것을 추천드립니다.