diff --git a/public/images/carousel1.png b/public/images/carousel1.png new file mode 100644 index 00000000..a8db2fd5 Binary files /dev/null and b/public/images/carousel1.png differ diff --git a/public/images/carousel2.png b/public/images/carousel2.png new file mode 100644 index 00000000..f0a3d848 Binary files /dev/null and b/public/images/carousel2.png differ diff --git a/public/images/carousel3.png b/public/images/carousel3.png new file mode 100644 index 00000000..750a85e3 Binary files /dev/null and b/public/images/carousel3.png differ diff --git a/src/Apis/productApi.ts b/src/Apis/productApi.ts index 9bcd673a..b795b625 100644 --- a/src/Apis/productApi.ts +++ b/src/Apis/productApi.ts @@ -1,4 +1,3 @@ -//import axios from '@/Apis/axios'; import axios from 'axios'; const { VITE_CLIENT_ID } = import.meta.env; @@ -19,7 +18,7 @@ export async function getList(category: number) { category: category, }, }); - console.log(data.products); + //console.log(data.products); return data.products; } catch (err) { console.log(err); @@ -34,3 +33,12 @@ export async function getRecommand() { console.log(err); } } + +export async function getDetail(product_no: string) { + try { + const res = await ajax.get(`/products/${product_no}`); + return res.data; + } catch (err) { + console.log(err); + } +} diff --git a/src/App.scss b/src/App.scss index 1b9d15cf..78fe4718 100644 --- a/src/App.scss +++ b/src/App.scss @@ -6,12 +6,13 @@ body { margin: 0; - // width: 100%; + // width: 100%; //height: 100vh; - background-color: #F8EDE3; + background-color: #f8ede3; //background-color: rebeccapurple; // font-family: 'Dovemayo_gothic'; -}; + font-family: 'SUITE-Regular'; +} a { text-decoration: none; @@ -26,8 +27,8 @@ a { @font-face { font-family: 'SUITE-Regular'; - src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_2304-2@1.0/SUITE-Regular.woff2') format('woff2'); + src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_2304-2@1.0/SUITE-Regular.woff2') + format('woff2'); font-weight: 400; font-style: normal; } - diff --git a/src/App.tsx b/src/App.tsx index 1f2a3294..9c11872e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,14 +1,12 @@ -import './App.scss' -import RoutesPage from 'routes/routes' - - +import './App.scss'; +import RoutesPage from './routes/routes'; function App() { - return ( + return ( <> - + - ) + ); } -export default App +export default App; diff --git a/src/Common/Form/Login/login.tsx b/src/Common/Form/Login/login.tsx index 155f3fd8..a604e73a 100644 --- a/src/Common/Form/Login/login.tsx +++ b/src/Common/Form/Login/login.tsx @@ -1,20 +1,16 @@ -import './login.scss' +import './login.scss'; import { useNavigate, Link } from 'react-router-dom'; //import { useDispatch } from "react-redux"; -import { FormEvent, useState, ChangeEvent } from 'react'; +import { FormEvent, useState, ChangeEvent } from 'react'; //import { loginUser } from '_reducers/user_reducer'; -import { LoginForm } from 'Apis/apis'; +import { LoginForm } from '@/Apis/register'; - function Login() { - const navigate = useNavigate(); //const dispatch = useDispatch(); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); - - const onChangeEmail = (e: ChangeEvent) => { setEmail(e.target.value); }; @@ -24,93 +20,99 @@ function Login() { }; interface DataToSubmit { - email: string // 사용자 아이디 (필수!) - password: string // 사용자 비밀번호 (필수!) + email: string; // 사용자 아이디 (필수!) + password: string; // 사용자 비밀번호 (필수!) } - async function Signin(event: FormEvent) { event.preventDefault(); - - if (email === undefined || email === "" || email === null) { + + if (email === undefined || email === '' || email === null) { alert('이메일을 입력해주세요.'); return false; } - - if (password === undefined || password === "" || password === null) { + + if (password === undefined || password === '' || password === null) { alert('비밀번호를 입력해주세요.'); return false; } - + const dataToSubmit: DataToSubmit = { email: email, - password: password + password: password, }; try { - //const data = await dispatch(loginUser(dataToSubmit)); - const data = await LoginForm(email, password) + const data = await LoginForm(email, password); console.log(data); - if(data.accessToken){ - alert("로그인 되었습니다!"); + if (data.accessToken) { + alert('로그인 되었습니다!'); window.localStorage.setItem('token', data.accessToken); - navigate("/"); + navigate('/'); } else { - alert("로그인에 실패하였습니다. 다시 시도해주세요."); + alert('로그인에 실패하였습니다. 다시 시도해주세요.'); } } catch (error) { console.error(error); - alert("오류가 발생했습니다. 다시 시도해주세요."); + alert('오류가 발생했습니다. 다시 시도해주세요.'); } } - - return( + return ( <> -
-
-
-

로그인

-
- -
-
- +
+ +
+

로그인

-
- -
+
+
+ +
-
- +
+ +
+ +
+ +
-
- -
-

아이디가 없으신가요?

- + +
+

아이디가 없으신가요?

+

회원가입 하러 가기!

+
-
- ) + ); } -export default Login \ No newline at end of file +export default Login; diff --git a/src/Common/Form/Signin/join.tsx b/src/Common/Form/Signin/join.tsx index 41b291b7..c9b6056a 100644 --- a/src/Common/Form/Signin/join.tsx +++ b/src/Common/Form/Signin/join.tsx @@ -1,74 +1,79 @@ -import { FormEvent, useState, useCallback } from 'react'; +import { FormEvent, useState, useCallback } from 'react'; import axios from 'axios'; import { useNavigate } from 'react-router-dom'; import { PwCheck, emailCheck } from '../Validation '; -import { JoinForm } from 'Apis/apis'; -import './join.scss' - - -function Join () { +import { JoinForm } from '@/Apis/register'; +import './join.scss'; +function Join() { const navigate = useNavigate(); - - // 이름 , 비밀번호, 이메일 , 비밀번호 확인 - const [email, setUserEmail] = useState(""); - const [displayName, setdDisplayName] = useState(""); - const [password, setUserPassword] = useState(""); - const [confirmPassword, setConfirmPassword] = useState(""); - + // 이름 , 비밀번호, 이메일 , 비밀번호 확인 + const [email, setUserEmail] = useState(''); + const [displayName, setdDisplayName] = useState(''); + const [password, setUserPassword] = useState(''); + const [confirmPassword, setConfirmPassword] = useState(''); - //비밀번호 유효성 검사 - const [isName, setIsName] = useState(false) - const [isEmail, setIsEmail] = useState(false) - const [isPassword, setIsPassword] = useState(false) - const [isPasswordConfirm, setIsPasswordConfirm] = useState(false) + //비밀번호 유효성 검사 + const [isName, setIsName] = useState(false); + const [isEmail, setIsEmail] = useState(false); + const [isPassword, setIsPassword] = useState(false); + const [isPasswordConfirm, setIsPasswordConfirm] = useState(false); //오류 메세지 저장 - const [nameMessage, setNameMessage] = useState('') - const [emailMessage, setEmailMessage] = useState('') - const [passwordMessage, setPasswordMessage] = useState('') - const [passwordConfirmMessage, setPasswordConfirmMessage] = useState('') - - - - const onChangeEmail = useCallback((e: React.ChangeEvent) => { - const emails = e.target.value - setUserEmail(emails) - if (emailCheck(emails)) { - setEmailMessage('올바른 이메일 형식이에요 : )') - setIsEmail(true) - } else { - setEmailMessage('이메일 형식이 틀렸습니다') - setIsEmail(false) - } - },[]) + const [nameMessage, setNameMessage] = useState(''); + const [emailMessage, setEmailMessage] = useState(''); + const [passwordMessage, setPasswordMessage] = useState(''); + const [passwordConfirmMessage, setPasswordConfirmMessage] = useState(''); + + const onChangeEmail = useCallback( + (e: React.ChangeEvent) => { + const emails = e.target.value; + setUserEmail(emails); + if (emailCheck(emails)) { + setEmailMessage('올바른 이메일 형식이에요 : )'); + setIsEmail(true); + } else { + setEmailMessage('이메일 형식이 틀렸습니다'); + setIsEmail(false); + } + }, + [] + ); const onChangeName = useCallback((e: React.ChangeEvent) => { - setdDisplayName(e.target.value) + setdDisplayName(e.target.value); if (e.target.value.length < 2 || e.target.value.length > 21) { - setNameMessage('2글자 이상 21글자 미만으로 입력해주세요.') - setIsName(false) - } else { - setNameMessage('올바른 이름 형식입니다 :)') - setIsName(true) - } - }, []) - - const onChangePassword = useCallback((e: React.ChangeEvent) => { - const passwordCurrent = e.target.value - setUserPassword(passwordCurrent) - - if (!PwCheck(passwordCurrent)) { - setPasswordMessage('8자리 이상 입력해주세요.') - setIsPassword(false) + setNameMessage('2글자 이상 21글자 미만으로 입력해주세요.'); + setIsName(false); } else { - setPasswordMessage('안전한 비밀번호에요 : )') - setIsPassword(true) - } - }, [confirmPassword]) - - const onChangePasswordConfirm = (password:any, confirmPassword:any, setPasswordConfirmMessage:any, setIsPasswordConfirm:any) => { + setNameMessage('올바른 이름 형식입니다 :)'); + setIsName(true); + } + }, []); + + const onChangePassword = useCallback( + (e: React.ChangeEvent) => { + const passwordCurrent = e.target.value; + setUserPassword(passwordCurrent); + + if (!PwCheck(passwordCurrent)) { + setPasswordMessage('8자리 이상 입력해주세요.'); + setIsPassword(false); + } else { + setPasswordMessage('안전한 비밀번호에요 : )'); + setIsPassword(true); + } + }, + [confirmPassword] + ); + + const onChangePasswordConfirm = ( + password: any, + confirmPassword: any, + setPasswordConfirmMessage: any, + setIsPasswordConfirm: any + ) => { if (password === confirmPassword) { setPasswordConfirmMessage('비밀번호를 똑같이 입력했어요 : )'); setIsPasswordConfirm(true); @@ -78,116 +83,144 @@ function Join () { } }; - const onPasswordConfirmChange = useCallback((e: React.ChangeEvent) => { - const passwordConfirmCurrent = e.target.value; - setConfirmPassword(passwordConfirmCurrent); - onChangePasswordConfirm(password, passwordConfirmCurrent, setPasswordConfirmMessage, setIsPasswordConfirm); - }, [password]); - - - async function signUp (event: FormEvent) { - event.preventDefault() - if(email === undefined || email === "" || email === null ){ - alert("이메일 입력해주세요."); + const onPasswordConfirmChange = useCallback( + (e: React.ChangeEvent) => { + const passwordConfirmCurrent = e.target.value; + setConfirmPassword(passwordConfirmCurrent); + onChangePasswordConfirm( + password, + passwordConfirmCurrent, + setPasswordConfirmMessage, + setIsPasswordConfirm + ); + }, + [password] + ); + + async function signUp(event: FormEvent) { + event.preventDefault(); + if (email === undefined || email === '' || email === null) { + alert('이메일 입력해주세요.'); return false; } - if( isEmail === false || isPassword === false || isPasswordConfirm === false){ - alert("값이 잘못 되었습니다. 다시 입력해주세요"); + if ( + isEmail === false || + isPassword === false || + isPasswordConfirm === false + ) { + alert('값이 잘못 되었습니다. 다시 입력해주세요'); return false; - } - - const param = { - email: email, - password: password, - displayName: displayName - } + } - try{ - const res = await JoinForm(email,displayName,password); - if (res.accessToken) { - alert("가입되었습니다."); - //localStorage.setItem('token', res.accessToken); - navigate("/login"); - } else { - alert("가입에 실패했습니다. 다시 시도해주세요."); + const param = { + email: email, + password: password, + displayName: displayName, + }; + + try { + const res = await JoinForm(email, displayName, password); + if (res.accessToken) { + alert('가입되었습니다.'); + //localStorage.setItem('token', res.accessToken); + navigate('/login'); + } else { + alert('가입에 실패했습니다. 다시 시도해주세요.'); + } + } catch (error) { + alert('시스템 오류입니다. 문의해주세요.'); } - } catch (error) { - alert("시스템 오류입니다. 문의해주세요."); } -} - return( + return ( <> -
-
-
-

회원가입📖

-
- -
-
- - {email.length > 0 && {emailMessage}} +
+ +
+

회원가입📖

-
- - {displayName.length > 0 && {nameMessage}} +
+
+ + {email.length > 0 && ( + + {emailMessage} + + )} +
+ +
+ + {displayName.length > 0 && ( + + {nameMessage} + + )} +
+ +
+ + {password.length > 0 && ( + + {passwordMessage} + + )} +
+ +
+ + {confirmPassword.length > 0 && ( + + {passwordConfirmMessage} + + )} +
+ +
+ +
- -
- - {password.length > 0 && ( - {passwordMessage} - )} -
- -
- - {confirmPassword.length > 0 && ( - {passwordConfirmMessage} - )} -
- -
- -
- - -
- - -
+ +
- ) - + ); } -export default Join; \ No newline at end of file +export default Join; diff --git a/src/Common/Layout/Header/header.tsx b/src/Common/Layout/Header/header.tsx index 03d81809..b38d11e3 100644 --- a/src/Common/Layout/Header/header.tsx +++ b/src/Common/Layout/Header/header.tsx @@ -1,71 +1,70 @@ import { Link, useNavigate } from 'react-router-dom'; //import { useSelector } from 'react-redux'; -import './headers.scss' +import './headers.scss'; //import { RootState } from '../_reducers'; //import { useDispatch } from 'react-redux'; //import { logoutUser } from '_reducers/user_reducer'; -import { LogoutForm } from 'Apis/apis'; - -function Header(){ +import { LogoutForm } from '@/Apis/register'; +function Header() { // const userState = useSelector((state) => state.user); // const accessToken = userState.accessToken; // console.log("1", accessToken); // const dispatch = useDispatch(); - const navigate = useNavigate(); - + const logoutHandler = () => { LogoutForm() - .then(() => { - localStorage.removeItem('token'); - alert("로그아웃 되셨습니다") - navigate('/'); - }) - .catch((error:string) => { - console.log('Logout failed:', error); - }); + .then(() => { + localStorage.removeItem('token'); + alert('로그아웃 되셨습니다'); + navigate('/'); + }) + .catch((error: string) => { + console.log('Logout failed:', error); + }); }; const token = localStorage.getItem('token'); - return( - <> -
-
- - - logo - - -
- -
+ return ( + <> +
+
+ + logo + +
+ +
-
- 장바구니 - 마이페이지 - {token ? ( -
-

로그아웃

-
- ) : ( - <> - -

회원가입

+
+ + 장바구니 - -

로그인

+ + 마이페이지 - - )} -
-
-
-
- - ) + {token ? ( +
+

로그아웃

+
+ ) : ( + <> + +

회원가입

+ + +

로그인

+ + + )} +
+
+
+ + + ); } -export default Header - +export default Header; diff --git a/src/Components/Views/CartPage/CartItems/CartItems.tsx b/src/Components/Views/CartPage/CartItems/CartItems.tsx index 95f01b3b..473ce715 100644 --- a/src/Components/Views/CartPage/CartItems/CartItems.tsx +++ b/src/Components/Views/CartPage/CartItems/CartItems.tsx @@ -1,13 +1,12 @@ -import React from "react" -import { useState } from "react"; +import React from 'react'; +import { useState } from 'react'; import Box from '@mui/material/Box'; import Checkbox from '@mui/material/Checkbox'; import FormControlLabel from '@mui/material/FormControlLabel'; -import YearBox from "Common/section/number"; -import './CartItems.scss' +import YearBox from 'Common/section/number'; +import './CartItems.scss'; function CartItems() { - interface Item { id: number; // image:string; @@ -15,28 +14,60 @@ function CartItems() { text: string; price: string; sale: string; - malize:string; + malize: string; } - const [info, setInfo] = useState([]) + const [info, setInfo] = useState([]); const [checked, setChecked] = useState([true, false]); const [items, setItems] = useState([ - { id: 1, name: '[국내도서]시작하세요! C# 10프로그래밍', text:"*밤 11시 잠들기전 배송", - price:"정가: 36000", sale:"판매가:32,400", malize:"마일리지: 1,800원"}, - { id: 2, name: '도서명2', text:"*밤 11시 잠들기전 배송", - price:"정가: 36000", sale:"판매가:32,400", malize:"마일리지: 1,800원" }, - { id: 3, name: '도서명3', text:"*밤 11시 잠들기전 배송", - price:"정가: 36000", sale:"판매가:32,400", malize:"마일리지: 1,800원"}, - { id: 4, name: '도서명3', text:"*밤 11시 잠들기전 배송", - price:"정가: 36000", sale:"판매가:32,400", malize:"마일리지: 1,800원"}, - { id: 5, name: '도서명3', text:"*밤 11시 잠들기전 배송", - price:"정가: 36000", sale:"판매가:32,400", malize:"마일리지: 1,800원"}, + { + id: 1, + name: '[국내도서]시작하세요! C# 10프로그래밍', + text: '*밤 11시 잠들기전 배송', + price: '정가: 36000', + sale: '판매가:32,400', + malize: '마일리지: 1,800원', + }, + { + id: 2, + name: '도서명2', + text: '*밤 11시 잠들기전 배송', + price: '정가: 36000', + sale: '판매가:32,400', + malize: '마일리지: 1,800원', + }, + { + id: 3, + name: '도서명3', + text: '*밤 11시 잠들기전 배송', + price: '정가: 36000', + sale: '판매가:32,400', + malize: '마일리지: 1,800원', + }, + { + id: 4, + name: '도서명3', + text: '*밤 11시 잠들기전 배송', + price: '정가: 36000', + sale: '판매가:32,400', + malize: '마일리지: 1,800원', + }, + { + id: 5, + name: '도서명3', + text: '*밤 11시 잠들기전 배송', + price: '정가: 36000', + sale: '판매가:32,400', + malize: '마일리지: 1,800원', + }, ]); const [checkedItems, setCheckedItems] = useState([]); const handleChange1 = (event: React.ChangeEvent) => { const checkedValue = event.target.checked; - const updatedCheckedItems = checkedValue ? items.map((item) => item.id) : []; + const updatedCheckedItems = checkedValue + ? items.map((item) => item.id) + : []; setCheckedItems(updatedCheckedItems); }; @@ -51,86 +82,98 @@ function CartItems() { } setCheckedItems(updatedCheckedItems); }; - + const children = (itemId: number) => ( - + } + control={ + + } /> ); const handleChange = (e: React.ChangeEvent) => { - console.log() + console.log(); setInfo({ - ...info, [e.target.name]: e.target.value + ...info, + [e.target.name]: e.target.value, }); }; - return( + return ( <> -
- - 0 && checkedItems.length < items.length} - onChange={handleChange1} - /> -
- } - /> +
+ + 0 && checkedItems.length < items.length + } + onChange={handleChange1} + /> +
+ } + /> - {/*
+ {/*
구매
*/} -
+
상품명 -
+
-
+

가격

-
+
-
+
보관/삭제 -
-
- -
- {items.map((item) => ( -
-
- {children(item.id)} -
-
- cartbookimage -
-
- {item.name} - {item.text} -
+
+
-
- {item.price} - {item.sale} - {item.malize} -
+
+ {items.map((item) => ( +
+
{children(item.id)}
+
+ cartbookimage +
+
+ {item.name} + {item.text} +
- +
+ {item.price} + {item.sale} + {item.malize} +
-
- +
+ +
-
- ))} -
+ ))} +
- ) + ); } -export default CartItems \ No newline at end of file +export default CartItems; diff --git a/src/Components/Views/DetailPage/DetailPage.tsx b/src/Components/Views/DetailPage/DetailPage.tsx index 0421fd81..461799ee 100644 --- a/src/Components/Views/DetailPage/DetailPage.tsx +++ b/src/Components/Views/DetailPage/DetailPage.tsx @@ -1,101 +1,92 @@ -import BookCustom from '../../../bookcustom/bookcustom' -import axios from 'axios'; +import BookCustom from '../../../bookcustom/bookcustom'; import { useEffect, useState } from 'react'; -import './DetailPage.scss' - - -const { VITE_CLIENT_ID } = import.meta.env; -const ajax = axios.create({ - baseURL: '/cafe24/api/v2', - headers: { - 'Content-Type': 'application/json', - 'X-Cafe24-Client-Id': VITE_CLIENT_ID, - }, -}); - - -function DetailPage(){ +import './DetailPage.scss'; +import { useParams } from 'react-router-dom'; +import { getDetail } from '@/Apis/productApi'; +function DetailPage() { const [detail, setDetail] = useState({} as Product); + const { productNo } = useParams(); async function getDetails() { try { - const { data } = await ajax.get('/products/21'); + const data = await getDetail(productNo as string); setDetail(data.product); } catch (err) { console.log(err); } } - useEffect(() => { (async () => { await getDetails(); })(); }, []); - - return( + return ( <> - -
-
- -
- -
-
-

제목입니다.

+
+
+
-
- bookimgs -
-
-
-
-

책모양 아크릴 거울
(대상 도서 포함 3만원 이상 구매 시)

-
- -
-
- 정가 - 22,000 -
-
- 판매가 - 22,000 +
+
+

제목입니다.

-
- 수량 - 22,000 +
+ bookimgs
-
- 줄거리 - -

더 이상 설명이 필요 없는 20세기 환경학 최고의 고전 [침묵의 봄]이 - 50주년 기념 개정판으로 나왔다. 이번 개정판에는 서문과 후기가 - 완전히 새롭게 단장되었으며, 2002년 출간본에는 없던(원서에도 - 없었음) 찾아보기를 새롭게 추가했다. 그리고 편집과 장정도 완전히 - 바뀌었다.

-
-
-
- 카드 - 무이자 할부 - 소득공제300원 +
+ +
+
+

+ 책모양 아크릴 거울
+ (대상 도서 포함 3만원 이상 구매 시) +

-
- - +
+
+ 정가 + 22,000 +
+
+ 판매가 + 22,000 +
+
+ 수량 + 22,000 +
+
+ 줄거리 + +

+ 더 이상 설명이 필요 없는 20세기 환경학 최고의 고전 [침묵의 + 봄]이 50주년 기념 개정판으로 나왔다. 이번 개정판에는 서문과 + 후기가 완전히 새롭게 단장되었으며, 2002년 출간본에는 + 없던(원서에도 없었음) 찾아보기를 새롭게 추가했다. 그리고 + 편집과 장정도 완전히 바뀌었다. +

+
+
+
+ 카드 + 무이자 할부 + 소득공제300원 +
+ +
+ + +
-
- -
+
- ) + ); } -export default DetailPage \ No newline at end of file +export default DetailPage; diff --git a/src/Components/Views/MainPage/Component/Carousel.tsx b/src/Components/Views/MainPage/Component/Carousel.tsx index 1066b6ea..ac69fb3d 100644 --- a/src/Components/Views/MainPage/Component/Carousel.tsx +++ b/src/Components/Views/MainPage/Component/Carousel.tsx @@ -63,7 +63,7 @@ export default function Carousel() { > {arr.map((v, i) => (
- +
))}
diff --git a/src/Components/Views/MainPage/Component/Genre.tsx b/src/Components/Views/MainPage/Component/Genre.tsx index 46e53818..e9b08323 100644 --- a/src/Components/Views/MainPage/Component/Genre.tsx +++ b/src/Components/Views/MainPage/Component/Genre.tsx @@ -1,6 +1,7 @@ import axios from 'axios'; import { useEffect, useState } from 'react'; import { getList } from '@/Apis/productApi'; +import { Link } from 'react-router-dom'; interface Props { type: string; @@ -31,7 +32,11 @@ export default function Genre({ category }: { category: Props }) {
{list && list.map((item) => ( -
+ {item.product_name}
{item.product_name},{item.product_no} @@ -39,7 +44,7 @@ export default function Genre({ category }: { category: Props }) {
{item.retail_price}
{item.price}
{item.main ? item.main.map((v) =>
{v}
) : null} -
+ ))}
diff --git a/src/Components/Views/MainPage/Component/Main.tsx b/src/Components/Views/MainPage/Component/Main.tsx index f1a9880a..f3fb6cef 100644 --- a/src/Components/Views/MainPage/Component/Main.tsx +++ b/src/Components/Views/MainPage/Component/Main.tsx @@ -43,24 +43,19 @@ export default function Main() { return (
-
-
    - {category.map((item) => ( -
  • - {item.type} -
  • - ))} -
- -
- {/* CATEGORY */} - {category.map((item) => ( - - ))} -
+
    + {category.map((item) => ( +
  • + {item.type} +
  • + ))} +
+ +
+ {/* CATEGORY */} + {category.map((item) => ( + + ))}
); diff --git a/src/Components/Views/MainPage/Component/Recommand.scss b/src/Components/Views/MainPage/Component/Recommand.scss new file mode 100644 index 00000000..7a51f994 --- /dev/null +++ b/src/Components/Views/MainPage/Component/Recommand.scss @@ -0,0 +1,95 @@ +.recommand { + //border: 2px solid; + //border-radius: 10px; + margin: 100px auto 0; + width: 80%; + overflow: hidden; + + h1 { + border-bottom: 1px solid; + padding-bottom: 10px; + } +} +.recommand-wrapper { + //display: grid; + //grid-template-columns: 2fr 8fr; + display: flex; + flex-wrap: wrap; + justify-content: space-evenly; + gap: 20px; + padding: 20px 0; + background-color: #fff; +} +.test { + width: calc(100% / 4); + height: 150px; + overflow: hidden; + border-radius: 10px; + + h3 { + padding: 10px 5px; + text-align: center; + } + p { + padding: 5px; + } + + &:nth-child(1) { + background-color: #3e47bc; + color: #fafffb; + p { + color: #c3c2ea; + } + } + &:nth-child(2) { + background-color: #8edcb4; + color: #000000; + p { + color: #56886f; + } + } + &:nth-child(3) { + background-color: #f8e83b; + color: #000201; + p { + color: #807718; + } + } + &:nth-child(4) { + background-color: #f8ff97; + color: #000004; + p { + color: #9c9f5a; + } + } + &:nth-child(5) { + background-color: #f1eae2; + color: #000000; + p { + color: #94918c; + } + } +} +.title { + border-right: 1px solid; + padding: 10px 10px; + cursor: pointer; + &:not(:last-child) { + border-bottom: 1px solid; + } +} +.description { + position: relative; + padding: 5% 5%; + background-color: rgb(254, 246, 243); + + a { + position: absolute; + font-size: 0.8rem; + right: 10%; + bottom: 10%; + &:hover { + color: blue; + } + } +} diff --git a/src/Components/Views/MainPage/Component/Recommand.tsx b/src/Components/Views/MainPage/Component/Recommand.tsx index d537fd51..f0b19231 100644 --- a/src/Components/Views/MainPage/Component/Recommand.tsx +++ b/src/Components/Views/MainPage/Component/Recommand.tsx @@ -1,8 +1,19 @@ import { useEffect, useState } from 'react'; import { getRecommand } from '@/Apis/productApi'; +import './Recommand.scss'; +import { Link } from 'react-router-dom'; + +type RecommandProducts = RecommandProduct[]; + +interface RecommandProduct { + shop_no: number; + product_no: number; + product_name: string; + summary_description: string; +} export default function Recommand() { - const [list, setList] = useState(); + const [list, setList] = useState(); async function recommand() { try { const res = await getRecommand(); @@ -18,14 +29,23 @@ export default function Recommand() { })(); }, []); return ( -
-

Recommand!

-
+
+

추천도서

+
{list && list.map((item) => ( -
-
{item.product_name}
-
+ +

{item.product_name}

+

+ {item.summary_description.length > 85 + ? item.summary_description.slice(0, 85) + '...' + : item.summary_description} +

+ ))}
diff --git a/src/Components/Views/MainPage/MainPage.scss b/src/Components/Views/MainPage/MainPage.scss index 030a8cd6..cee92cc3 100644 --- a/src/Components/Views/MainPage/MainPage.scss +++ b/src/Components/Views/MainPage/MainPage.scss @@ -4,15 +4,25 @@ margin: 0; padding: 0; } -main { - position: relative; - display: flex; +.wrapper { + width: 1200px; + margin: 100px auto 0; } a { display: block; text-decoration: none; color: black; } +// CATEGORY +main { + position: relative; + display: flex; + width: 1200px; + margin: 100px auto; + .tag-box { + width: 300px; + } +} .category-menu { position: sticky; top: 0; @@ -34,16 +44,6 @@ a { border-radius: 30px; } } -// CATEGORY -.wrapper { - position: relative; - display: flex; - width: 1200px; - margin: 100px auto; - .tag-box { - width: 300px; - } -} .books { display: flex; diff --git a/src/Components/Views/MainPage/MainPage.tsx b/src/Components/Views/MainPage/MainPage.tsx index 024cf775..914d8b84 100644 --- a/src/Components/Views/MainPage/MainPage.tsx +++ b/src/Components/Views/MainPage/MainPage.tsx @@ -20,10 +20,10 @@ if (params.get('code')) { export default function MainPage() { return ( - <> +
- +
); } diff --git a/src/main.tsx b/src/main.tsx index 39808af3..a9043054 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,22 +1,16 @@ -import React from 'react' -import ReactDOM from 'react-dom/client' -import App from './App.tsx' -import './index.scss' -import { Provider } from 'react-redux'; -import store from './store/' +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import App from './App'; +import './index.scss'; + //import ReduxThunk from 'redux-thunk'; // import thunk from 'redux-thunk'; // import { createStore, applyMiddleware } from 'redux'; // import reducer from '_reducers/user_reducer.tsx'; - //const createStoreWithMiddleware = applyMiddleware(promiseMiddleware, ReduxThunk)(createStore); //const store = createStore(reducer, applyMiddleware(thunk)); ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( - - - - - -) + +); diff --git a/src/routes/routes.tsx b/src/routes/routes.tsx index 63546b65..71b91cde 100644 --- a/src/routes/routes.tsx +++ b/src/routes/routes.tsx @@ -1,50 +1,49 @@ -import Header from 'Common/Layout/Header/header' -import Footer from 'Common/Layout/Footer/footer' -import MainPage from 'Components/Views/MainPage/mainPage' -import Join from 'Common/Form/Signin/join' -import Login from 'Common/Form/Login/login' -import CartPage from 'Components/Views/CartPage/CartPage' -import MyPage from 'Components/Views/MyPage/MyPage' -import PrivatePage from './privateRoute' -import DetailPage from 'Components/Views/DetailPage/DetailPage' +import Header from '@/Common/Layout/Header/header'; +import Footer from '@/Common/Layout/Footer/footer'; +import MainPage from '@/Components/Views/MainPage/mainPage'; +import Join from '@/Common/Form/Signin/join'; +import Login from '@/Common/Form/Login/login'; +import CartPage from '@/Components/Views/CartPage/CartPage'; +import MyPage from '@/Components/Views/MyPage/MyPage'; +import PrivatePage from './privateRoute'; +import DetailPage from '@/Components/Views/DetailPage/DetailPage'; -import { Routes, BrowserRouter, Route, Outlet } from 'react-router-dom' +import { Routes, BrowserRouter, Route, Outlet } from 'react-router-dom'; - const Layout = () => { - return( +const Layout = () => { + return ( <> -
+
-