Skip to content

Commit

Permalink
add: 등록하기 기능 및 유효성 검사
Browse files Browse the repository at this point in the history
  • Loading branch information
yousuk88 committed Nov 6, 2024
1 parent b0e1e9e commit 65555b0
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 16 deletions.
16 changes: 16 additions & 0 deletions src/apis/ProductService(MongoDB).js
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,19 @@ export async function getProductList(offset, limit, orderBy, keyword) {
console.error("기타 에러:", error); // 서버 등 예측하지 못한 에러 위해
}
}

export async function registerProduct(productData) {
try {
const response = await fetch(BASE_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(productData),
});
if (!response.ok) {
throw new Error(`등록 실패: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error("상품 등록 중 오류:", error);
}
}
72 changes: 56 additions & 16 deletions src/pages/Registration.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,49 @@
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import styles from './Registration.module.css';
import { registerProduct } from '../apis/ProductService(MongoDB)';

function Registration() {
const [name, setName] = useState('');
const [description, setDescription] = useState('');
const [price, setPrice] = useState('');
const [tags, setTags] = useState([]);
const [tagInput, setTagInput] = useState('');
const [isFormValid, setIsFormValid] = useState(false);
const [showErrors, setShowErrors] = useState(false);
const [isPriceValid, setIsPriceValid] = useState(true);

useEffect(() => {
setIsFormValid(name.trim() && description.trim() && price.trim() && isPriceValid);
}, [name, description, price, isPriceValid]);

const handleNameChange = (e) => setName(e.target.value);
const handleDescriptionChange = (e) => setDescription(e.target.value);

const formatPrice = (value) => {
const number = value.replace(/,/g, ''); // 콤마 제거
return number.replace(/\B(?=(\d{3})+(?!\d))/g, ','); // 세 자리마다 콤마 추가
const number = value.replace(/,/g, '');
return number.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
};

const handlePriceChange = (e) => {
const formattedPrice = formatPrice(e.target.value);
const inputValue = e.target.value;
const numericPrice = parseFloat(inputValue.replace(/,/g, ''));

// 가격 유효성 검사: 숫자 여부와 양수 여부 확인
if (!isNaN(numericPrice) && numericPrice > 0) {
setIsPriceValid(true);
} else {
setIsPriceValid(false);
}

const formattedPrice = formatPrice(inputValue);
setPrice(formattedPrice);
};

const handleTagInputChange = (e) => setTagInput(e.target.value);

const handleTagInputKeyPress = (e) => {
if (e.key === 'Enter' && tagInput.trim()) {
setTags((prevTags) => [...prevTags, `#${tagInput.trim()}`]);
setTags((prevTags) => [...prevTags, tagInput.trim()]);
setTagInput('');
e.preventDefault();
}
Expand All @@ -35,32 +53,57 @@ function Registration() {
setTags(tags.filter((_, index) => index !== indexToRemove));
};

const handleSubmit = () => {
const formattedTags = tags.map(tag => tag.replace(/^#/, '')); // #을 제거
const handleSubmit = async () => {
setShowErrors(true);

if (!isFormValid) return;

const formattedTags = tags.map(tag => tag.replace(/^#/, ''));
const productData = {
name,
description,
price: price.replace(/,/g, ''), // 콤마 제거된 값으로 설정
tags: formattedTags // # 없는 태그들로 설정
price: price.replace(/,/g, ''),
tags: formattedTags,
};

console.log('등록할 상품 데이터:', productData);
// 서버로 productData 전송
try {
const result = await registerProduct(productData);
console.log('등록된 상품:', result);
alert('상품이 성공적으로 등록되었습니다!');
setName('');
setDescription('');
setPrice('');
setTags([]);
setShowErrors(false);
setIsPriceValid(true);
} catch (error) {
console.error("상품 등록 중 오류:", error);
alert('상품 등록 중 문제가 발생했습니다.');
}
};

return (
<div className={styles.main}>
<div className={styles.container}>
<div className={styles.maintitle}>상품등록하기</div>
<button onClick={handleSubmit} className={styles.button}>등록</button>
<button
onClick={handleSubmit}
className={`${styles.button} ${isFormValid ? styles.active : ''}`}
>
등록
</button>

<div className={styles.title}>상품명</div>
{showErrors && !name && <span className={styles.error}>필수 항목입니다</span>}
<input type="text" className={styles.input} value={name} onChange={handleNameChange} placeholder='상품명을 입력해주세요' />

<div className={styles.title}>상품소개</div>
{showErrors && !description && <span className={styles.error}>필수 항목입니다</span>}
<textarea className={`${styles.input} ${styles.description}`} value={description} onChange={handleDescriptionChange} placeholder='상품 소개를 입력해주세요' />

<div className={styles.title}>판매가격</div>
{showErrors && !price && <span className={styles.error}>필수 항목입니다</span>}
{!isPriceValid && <span className={styles.error}>판매가격은 양수로 입력해야 합니다</span>}
<input
type='text'
className={styles.input}
Expand All @@ -83,10 +126,7 @@ function Registration() {
{tags.map((tag, index) => (
<span key={index} className={styles.chip}>
{tag}
<span
className={styles.chip_close}
onClick={() => handleRemoveTag(index)}
></span>
<span className={styles.chip_close} onClick={() => handleRemoveTag(index)}></span>
</span>
))}
</div>
Expand Down
13 changes: 13 additions & 0 deletions src/pages/Registration.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@
font-weight: 700;
font-size: 1.8rem;
line-height: 2.6rem;
display: inline-block;
}

.error {
padding-left: 15px;
font-weight: 700;
font-size: 1.5rem;
line-height: 2.6rem;
color: #f74747;
}

.button {
Expand All @@ -55,7 +64,11 @@
background: #9ca3af;
border-radius: 8px;
border: none;
}

.button.active {
cursor: pointer;
background-color: #3692ff;
}

.input {
Expand Down

0 comments on commit 65555b0

Please sign in to comment.