Skip to content
Open
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
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VITE_BASE_URL=https://panda-market-api.vercel.app
6 changes: 6 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": true
}
62 changes: 44 additions & 18 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,55 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import { defineConfig, globalIgnores } from 'eslint/config'
import js from '@eslint/js';
import globals from 'globals';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';

export default defineConfig([
globalIgnores(['dist']),
export default [
{ ignores: ['dist', 'node_modules'] },
{
files: ['**/*.{js,jsx}'],
extends: [
js.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
ecmaVersion: 'latest',
sourceType: 'module',
globals: {
...globals.browser,
...globals.es2021,
...globals.node,
},
parserOptions: {
ecmaVersion: 'latest',
ecmaFeatures: { jsx: true },
sourceType: 'module',
},
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
// 1. 리액트 권장 규칙
...js.configs.recommended.rules,
...reactHooks.configs.recommended.rules,

// 2. Vite 전용 규칙 (HMR 유지용)
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],

// 3. 실무형 커스텀 규칙
'no-unused-vars': [
'warn',
{
varsIgnorePattern: '^[A-Z_]', // 대문자로 시작하는 변수(컴포넌트 등) 무시
argsIgnorePattern: '^_', // _로 시작하는 인자 무시
},
],
'no-console': 'warn', // 배포 전 console.log 체크용

// 4. Prettier와 싸우지 않기 위한 설정
// 스타일 관련은 에러를 내지 않고 Prettier가 알아서 하게 둡니다.
indent: 'off',
quotes: 'off',
semi: 'off',
'comma-dangle': 'off',
},
},
])
];
17 changes: 17 additions & 0 deletions package-lock.json

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

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"dev": "vite",
"build": "vite build",
"lint": "eslint .",
"preview": "vite preview"
"preview": "vite preview",
"prepare": "husky install"
},
"dependencies": {
"axios": "^1.13.5",
Expand All @@ -25,6 +26,7 @@
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.24",
"globals": "^16.5.0",
"husky": "^9.1.7",
"vite": "^7.3.1"
}
}
5 changes: 3 additions & 2 deletions src/apis/axiosInstance.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import axios from "axios";
// src/apis/axiosInstance.js
import axios from 'axios';

const axiosInstance = axios.create({
baseURL: "https://panda-market-api.vercel.app",
baseURL: import.meta.env.VITE_BASE_URL,
});

export default axiosInstance;
5 changes: 5 additions & 0 deletions src/assets/Delete.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/assets/plus.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
77 changes: 77 additions & 0 deletions src/components/AddItemInput.jsx
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

AddItemInput 에서 모든 프롭으로 넘기는 부분입니다!

Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import styled from 'styled-components';
import Tag from './Tag';

const AddItemInput = ({
children,
height = 'short',
placeholder,
handleTagAdd,
tag,
handleTagDelete,
name,
value,
onChange,
}) => {
const isLong = height === 'long';
const tagInput = children === '태그';

return (
<InputContainer>
<Label>{children}</Label>
<Input
name={name}
as={isLong ? 'textarea' : 'input'}
$height={height}
placeholder={placeholder}
onKeyDown={tagInput ? handleTagAdd : null}
value={value}
onChange={onChange}
/>
{tagInput ? (
<TagContainer>
{tag.map((title) => (
<Tag key={title} handleTagDelete={handleTagDelete} tag={tag}>
{title}
</Tag>
))}
</TagContainer>
) : null}
</InputContainer>
);
};

export default AddItemInput;

const InputContainer = styled.div`
display: flex;
flex-direction: column;
gap: 16px;
margin-bottom: 24px;
`;

const Label = styled.label`
font-weight: 700;
font-size: 18px;
line-height: 26px;
`;

const Input = styled.input`
border-radius: 12px;
padding: 16px 24px;
border: none;
color: var(--secondary-800);
background-color: var(--coolGray-100);
height: ${({ $height }) => ($height === 'long' ? '282px' : '56px')};
outline: none;

&::placeholder {
color: var(--secondary-400);
}
`;

const TagContainer = styled.div`
display: flex;
justify-content: flex-start;
align-items: center;
gap: 12px;
`;
10 changes: 3 additions & 7 deletions src/components/AllProduct.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import styles from "./AllProduct.module.css";
import ProductItem from "./ProductItem";

const AllProduct = ({products, isLoading}) => {
if (isLoading) {
return null;
}
import styles from './AllProduct.module.css';
import ProductItem from './ProductItem';

const AllProduct = ({ products }) => {
return (
<div className={styles.container}>
<div className={styles.listContainer}>
Expand Down
10 changes: 3 additions & 7 deletions src/components/BestProduct.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import styles from "./BestProduct.module.css";
import ProductItem from "./ProductItem";

const BestProduct = ({bestProducts, isBestLoading}) => {
if (isBestLoading) {
return null;
}
import styles from './BestProduct.module.css';
import ProductItem from './ProductItem';

const BestProduct = ({ bestProducts }) => {
return (
<div className={styles.container}>
<div className={styles.itemContainer}>
Expand Down
23 changes: 20 additions & 3 deletions src/components/Button.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
import styles from "./Button.module.css";
import styled from 'styled-components';

const Button = ({children}) => {
return <div className={styles.button}>{children}</div>;
const Button = ({ children, type = 'button', isActive = false }) => {
return (
<ButtonS type={type} $isActive={isActive}>
{children}
</ButtonS>
);
};

export default Button;

const ButtonS = styled.button`
background-color: ${({ $isActive }) =>
$isActive ? 'var(--primary-100)' : 'var(--coolGray-400)'};
color: var(--coolGray-100);
padding: 12px 23px;
border-radius: 10px;
font-weight: 600;
font-size: 16px;
line-height: 26px;
white-space: nowrap;
flex-shrink: 0;
`;
11 changes: 0 additions & 11 deletions src/components/Button.module.css

This file was deleted.

13 changes: 9 additions & 4 deletions src/components/DropDown.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import styles from "./DropDown.module.css";
import styles from './DropDown.module.css';

const DropDown = ({handleProductsSort}) => {
const DropDown = ({ handleProductsSort, children }) => {
return (
<select className={styles.select} onChange={handleProductsSort}>
<option value="recent">최신순</option>
<option value="favorite">좋아요순</option>
{children}
</select>
);
};

const Option = ({ value, children }) => {
return <option value={value}>{children}</option>;
};

DropDown.Option = Option;

export default DropDown;
67 changes: 67 additions & 0 deletions src/components/ImageRegistration.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import styled from 'styled-components';
import plusIcon from '../assets/plus.svg';
import ImgBox from './ImgBox';

const ImageRegistration = ({
name,
handleImageRegis,
preview,
handleImageDelete,
handleErrorMessage,
}) => {
return (
<Container>
<Label htmlFor="imageRegist">
<img src={plusIcon} alt="이미지 추가 아이콘" />
<P>이미지 등록</P>
</Label>
<HiddenInput
id="imageRegist"
name={name}
type="file"
onChange={handleImageRegis}
onClick={handleErrorMessage}
/>
<ImgBox preview={preview} handleImageDelete={handleImageDelete} />
</Container>
);
};

export default ImageRegistration;

const Container = styled.div`
display: flex;
align-items: center;
gap: 24px;

@media (max-width: 1199px) {
gap: 10px;
}
`;

const Label = styled.label`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: var(--secondary-100);
width: 282px;
height: 282px;
border-radius: 12px;
cursor: pointer;

@media (max-width: 1199px) {
width: 168px;
height: 168px;
}
`;

const HiddenInput = styled.input`
display: none;
`;

const P = styled.p`
font-weight: 400;
line-height: 26px;
color: var(--coolGray-400);
`;
Loading