Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
12 changes: 0 additions & 12 deletions eslint.config 2.mjs

This file was deleted.

10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"date-fns": "^4.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^5.3.0",
Expand Down
3 changes: 1 addition & 2 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
<meta name="theme-color" content="#000000" />
<link
rel="stylesheet"
as="style"dufisdufdsufiudsyfiudsyfiudsyfiudsyfiudsyfiudyfidsuyidus
crossorigin
as="style"
href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css"
/>
<title>판다마켓</title>
Expand Down
20 changes: 20 additions & 0 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { BrowserRouter, Route, Routes } from "react-router-dom";
import ProductPage from "./components/ProductPage/ProductPage";
import ItemPage from "./components/ItemPage/ItemPage";
import AddItem from "./components/AddItemPage/AddItemPage";
import NavBar from "./components/Nav/NavBar";

function App() {
return (
<BrowserRouter>
<NavBar />
<Routes>
<Route path="/items" element={<ProductPage />} />
<Route path="/items/:id" element={<ItemPage />} />
<Route path="/additem" element={<AddItem />} />
</Routes>
</BrowserRouter>
);
}

export default App;
18 changes: 0 additions & 18 deletions src/Main.jsx

This file was deleted.

39 changes: 35 additions & 4 deletions src/api.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,38 @@
const BASE_URL = "https://panda-market-api.vercel.app";

export async function getData({ page = 1, pageSize = 4, orderBy = "recent" }) {
const query = `page=${page}&pageSize=${pageSize}&orderBy=${orderBy}`;
const response = await fetch(`${BASE_URL}/products?${query}`);
const body = response.json();
return body;
const url = new URL("/products", BASE_URL);
url.searchParams.append("page", page);
url.searchParams.append("pageSize", pageSize);
url.searchParams.append("orderBy", orderBy);

const response = await fetch(url.toString());
if (!response.ok) {
throw new Error(`Failed to fetch data: ${response.statusText}`);
}
return response.json();
}

//GET product ID
export async function getProductDetail(id) {
const url = new URL(`/products/${id}`, BASE_URL);
// url.searchParams.append("{id}", id);

const response = await fetch(url.toString());
if (!response.ok) {
throw new Error(`Failed to fetch data: ${response.statusText}`);
}
return response.json();
}

//GET 상세페이지 댓글들

export async function getProductComment(id, limit = 3) {
const url = new URL(`/products/${id}/comments`, BASE_URL);
url.searchParams.append("limit", limit);
const response = await fetch(url.toString());
if (!response.ok) {
throw new Error(`Failed to fetch data: ${response.statusText}`);
}
return response.json();
}
50 changes: 29 additions & 21 deletions src/components/AddItemPage/AddItemPage.jsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
import NavBar from "../Nav/NavBar";
import "../AddItemPage/AddItemPage.scss";
import InputForm from "../AddItemPage/InputForm";
import InputImage from "../AddItemPage/InputImage";
import InputTag from "./InputTag";
import { useRef, useState } from "react";
import InputForm from "./components/InputForm";
import InputImage from "./components/InputImage";
import InputTag from "./components/InputTag";
import { useState } from "react";

function AddItemPage() {
const [values, setValues] = useState({
title: "",
description: "",
price: "",
tag: "",
});

const handleInputChange = (field) => (e) => {
setValues((preValues) => ({
...preValues,
[field]: e.target.value,
}));
};
const [tags, setTags] = useState([]);

const isSubmitDisabled =
!values.title || !values.description || !values.price || !values.tag;
!values.title || !values.description || !values.price || tags.length === 0;

console.log(isSubmitDisabled);

return (
<>
<NavBar />
<form className="formContent">
<form
className="formContent"
action="https://panda-market-api.vercel.app/products"
>
<div className="formTitle">상품 등록하기</div>
<button className="formBtn" type="submit" disabled={isSubmitDisabled}>
<button
className={`formBtn ${isSubmitDisabled ? "disabled" : "active"}`} // 버튼 활성화/비활성화
type="submit"
disabled={isSubmitDisabled} // 조건에 따라 버튼 비활성화
>
등록
</button>
<InputImage title={"상품이미지"} placeholder={"이미지 등록 "} />
Expand All @@ -36,28 +37,35 @@ function AddItemPage() {
value={values.title}
height={56}
placeholder={"상품명을 입력해주세요"}
onChange={(e) => setValues({ ...values, title: e.target.value })} // title 값 변경
/>
<InputForm
title={"상품소개"}
value={values.description}
height={282}
placeholder={"상품 소개를 입력해주세요"}
onChange={(e) =>
setValues({ ...values, description: e.target.value })
} // description 값 변경
/>
<InputForm
title={"판매가격"}
value={values.price}
height={56}
placeholder={"판매 가격을 입력해주세요"}
type="number"
onChange={(e) => setValues({ ...values, price: e.target.value })} // price 값 변경
/>
<InputTag
tags={tags}
setTags={setTags}
title={"태그"}
value={values.tag}
height={56}
placeholder={"태그을 입력해주세요"}
placeholder={"태그를 입력해주세요"}
type="string"
Copy link
Contributor

Choose a reason for hiding this comment

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

"text"를 넣거나 "text"가 기본값이니까 생략해야 하는데 잘못 넣으신 거죠?

/>
</form>
</>
);
}

export default AddItemPage; // default export
export default AddItemPage;
12 changes: 12 additions & 0 deletions src/components/AddItemPage/AddItemPage.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,16 @@
font-size: 12px;
font-weight: 600;
line-height: 26px;
cursor: pointer;

&.active {
background-color: #007bff; /* Blue when enabled */
color: white;
}

&.disabled {
background-color: #ccc; /* Gray when disabled */
color: #888; /* Gray text */
cursor: not-allowed;
}
}
70 changes: 0 additions & 70 deletions src/components/AddItemPage/InputTag.jsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
function InputForm({ title, height, placeholder, type = "text", onChange }) {
function InputForm({
title,
value = "",
height,
placeholder,
type = "text",
onChange,
}) {
return (
<>
<div
Expand All @@ -14,7 +21,7 @@ function InputForm({ title, height, placeholder, type = "text", onChange }) {
</div>
<input
style={{
width: `1200px`,
width: `100%`,
height: `${height}px`,
backgroundColor: "#F3F4F6",
borderRadius: "12px",
Expand All @@ -23,6 +30,7 @@ function InputForm({ title, height, placeholder, type = "text", onChange }) {
fontSize: "16px",
paddingLeft: "24px",
}}
value={value}
type={type}
placeholder={placeholder}
onChange={onChange}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useEffect, useRef, useState } from "react";
import imgButton from "../images/imgPlaceholder.svg";
import deleteButton from "../images/ic_X.svg";
import "../AddItemPage/InputImage.scss";
import imgButton from "../../../img//imgPlaceholder.svg";
import deleteButton from "../../../img/ic_X.svg";
import "./InputImage.scss";

function InputImage({ title, value, placeholder }) {
const [preview, setPreview] = useState("");
Expand All @@ -13,28 +13,15 @@ function InputImage({ title, value, placeholder }) {
const previewUrl = URL.createObjectURL(nextValue);
setPreview(previewUrl); // 미리보기 URL 저장
}
// onChange(title, nextValue);
};

const handleClearClick = () => {
const inputNode = inputRef.current;
if (!inputNode) return;

inputNode.value = "";
// onChange(title, null);
};

// useEffect(() => {
// if (!value) return;
// const nextPreview = URL.createObjectURL(value);
// setPreview(nextPreview);

// return () => {
// setPreview();
// URL.revokeObjectURL(nextPreview);
// };
// }, [value]);

return (
<div>
<div
Expand Down
Loading
Loading