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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ dist-ssr
*.njsproj
*.sln
*.sw?

*.env
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
15 changes: 15 additions & 0 deletions package-lock.json

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

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"build": "tsc && vite build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
Expand All @@ -24,6 +24,7 @@
"eslint-plugin-react": "^7.34.1",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"typescript": "^5.9.2",
"vite": "^5.2.0"
}
}
File renamed without changes.
4 changes: 2 additions & 2 deletions src/components/Inquiry.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
import { requestInquiryLists } from "../services/inquiryApi";
import { useNavigate } from "react-router";
import icBack from "../assets/icons/ic_back.svg";
import useService from "../hooks/useService";
import useFetch from "../hooks/useService";
Copy link
Collaborator

Choose a reason for hiding this comment

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

굿굿 ! 함수의 이름이 더욱 명확해졌네요 👍

의미가 명확해져서 어떤 훅인지 더욱 정확히 알 수 있군요 😉

import InquiryWriteArea from "./InquiryWriteArea";
import InquiryList from "../pages/components/ItemDetail/InquiryList";

Expand All @@ -16,7 +16,7 @@ export default function Inquiry({ id }) {
/**
* 문의 내역을 가져온다.
*/
const { data, isLoading } = useService(() => requestInquiryLists(id));
const { data, isLoading } = useFetch(() => requestInquiryLists(id));

return (
<>
Expand Down
3 changes: 1 addition & 2 deletions src/components/InquiryWriteArea.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useState } from "react";
import usePost from "../hooks/usePost";
import {
InquirySubmitButton,
InquiryTextArea,
Expand Down Expand Up @@ -30,7 +29,7 @@ export default function InquiryWriteArea() {
},
};

const { data: success } = usePost(requestPostInquiry(data));
// const { data: success } = usePost(requestPostInquiry(data));

if (success) {
location.reload(true);
Expand Down
9 changes: 0 additions & 9 deletions src/hooks/usePost.jsx

This file was deleted.

12 changes: 6 additions & 6 deletions src/hooks/useService.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ import { useEffect, useState } from "react";
/**
* 데이터 통신을 위한 공통 커스텀 훅
* @param {Function} fetchFunction 서버와 직접 통신하는 함수
* @returns {data: object, isLoading: boolean}
* @returns {data: object, isLoading: boolean, error: boolean}
Copy link
Collaborator

Choose a reason for hiding this comment

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

타입스크립트를 적용하게 되면 !

이제 jsdoc으로 일일히 타입을 명시하지 않아도 되겠네요 😊😊😊
jsdoc으로 명시를 하더라도 이 전에는 런타임 때 타입이 어떻게 정의되는지 정확하지 않을 수 있었으나 이제는 타입스크립트를 쓰므로 더욱 정확하며 빠르게 타입을 확인할 수 있겠어요 👍

*/
const useService = (fetchFunction) => {
const useFetch = (fetchFunction) => {
const [isLoading, setIsLoading] = useState(false);
const [data, setData] = useState();
const [error, setError] = useState(false);

useEffect(() => {
const getService = async (getDataFunction) => {
const fetcher = async (fetching) => {
try {
setIsLoading(true);
const response = await getDataFunction();
const response = await fetching();

if (!response) {
throw new Error("서버와의 통신에 실패했습니다.");
Expand All @@ -29,10 +29,10 @@ const useService = (fetchFunction) => {
}
};

getService(fetchFunction);
fetcher(fetchFunction);
}, []);

return { data, isLoading, error };
};

export default useService;
export default useFetch;
15 changes: 9 additions & 6 deletions src/layout/AuthLayout.jsx → src/layout/AuthLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { useState } from 'react';
import { Outlet } from 'react-router';
import visibleEye_off from '../assets/icons/eyes_off.png';
import visibleEye_on from '../assets/icons/eyes_on.png';
import { useState } from "react";
import { Outlet } from "react-router";
import visibleEye_off from "../assets/icons/eyes_off.png";
import visibleEye_on from "../assets/icons/eyes_on.png";
import { isVisibleKey, VisibleValue } from "../types/authType";

export default function AuthLayout() {
/**
* 비밀번호 보이기 / 가리기 상태
*/
const [visible, setVisible] = useState({
const [visible, setVisible] = useState<VisibleValue>({
pw: false,
checkPw: false,
});
Expand All @@ -16,7 +17,9 @@ export default function AuthLayout() {
* id 별로 비밀번호 가리기 여부를 변경한다.
* @param {string} id
*/
const onClickVisible = (id) => {
const onClickVisible = (id: string) => {
if (!isVisibleKey(id)) return;

setVisible((prevState) => ({
...prevState,
[id]: !visible[id],
Expand Down
10 changes: 5 additions & 5 deletions src/layout/Footer.jsx → src/layout/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import '../styles/layout/footer.css';
import ic_facebook from '../assets/icons/ic_facebook.svg';
import ic_twitter from '../assets/icons/ic_twitter.svg';
import ic_youtube from '../assets/icons/ic_youtube.svg';
import ic_instagram from '../assets/icons/ic_instagram.svg';
import "../styles/layout/footer.css";
import ic_facebook from "../assets/icons/ic_facebook.svg";
import ic_twitter from "../assets/icons/ic_twitter.svg";
import ic_youtube from "../assets/icons/ic_youtube.svg";
import ic_instagram from "../assets/icons/ic_instagram.svg";

/**
* 푸터
Expand Down
File renamed without changes.
6 changes: 3 additions & 3 deletions src/layout/MainLayout.jsx → src/layout/MainLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Header from './Header';
import Footer from './Footer';
import { Outlet } from 'react-router';
import Header from "./Header";
import Footer from "./Footer";
import { Outlet } from "react-router";

export default function MainLayout() {
return (
Expand Down
12 changes: 0 additions & 12 deletions src/main.jsx

This file was deleted.

12 changes: 12 additions & 0 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";
import { BrowserRouter } from "react-router";

ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
14 changes: 7 additions & 7 deletions src/pages/Home.jsx → src/pages/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import '../styles/style.css';
import home_top from '../assets/images/Img_home_top.png';
import hot_item from '../assets/images/hot_item.png';
import search_img from '../assets/images/search.png';
import register_img from '../assets/images/register.png';
import home_bottom from '../assets/images/Img_home_bottom.png';
import { Link } from 'react-router';
import "../styles/style.css";
import home_top from "../assets/images/Img_home_top.png";
import hot_item from "../assets/images/hot_item.png";
import search_img from "../assets/images/search.png";
import register_img from "../assets/images/register.png";
import home_bottom from "../assets/images/Img_home_bottom.png";
import { Link } from "react-router";

/**
* 메인화면
Expand Down
46 changes: 25 additions & 21 deletions src/pages/auth/Login.jsx → src/pages/auth/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import '../../styles/auth.css';
import ic_kakao from '../../assets/icons/ic_kakao.png';
import ic_google from '../../assets/icons/ic_google.png';
import { Link, useOutletContext } from 'react-router';
import { useForm } from 'react-hook-form';
import { useEffect } from 'react';
import "../../styles/auth.css";
import ic_kakao from "../../assets/icons/ic_kakao.png";
import ic_google from "../../assets/icons/ic_google.png";
import { Link, useOutletContext } from "react-router";
import { useForm } from "react-hook-form";
import { useEffect } from "react";
import { AuthType } from "../../types/authType";

/**
* 로그인 화면
*/
export default function Login() {
const { visible, setVisible, onClickVisible, visibleEye_off, visibleEye_on } =
useOutletContext();
const {
visible,
setVisible,
onClickVisible,
visibleEye_off,
visibleEye_on,
}: AuthType = useOutletContext();

/**
* 기본적으로 비밀번호 숨김 상태 유지
Expand All @@ -28,8 +34,8 @@ export default function Login() {
const {
register,
formState: { errors },
handleSubmit,
} = useForm({ mode: 'onBlur' });
// handleSubmit,
} = useForm({ mode: "onBlur" });

return (
<>
Expand All @@ -40,20 +46,19 @@ export default function Login() {
<div className="auth-logo-img"></div>
</Link>
</div>
<form id="form" className="form-box" onSubmit={handleSubmit}>
<form id="form" className="form-box">
<div className="input-container">
<div id="email-box" className="email-box">
<label htmlFor="email" className="basic-p">
이메일
</label>
<input
className={`input-box email ${
errors.email ? 'auth-err-border' : ''
errors.email ? "auth-err-border" : ""
}`}
name="email"
type="email"
placeholder="이메일을 입력해주세요"
{...register('email', {
{...register("email", {
required: true,
pattern:
/^[a-zA-Z0-9+-\_.]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/,
Expand All @@ -70,12 +75,11 @@ export default function Login() {
</label>
<input
className={`input-box pw ${
errors.password ? 'auth-err-border' : ''
errors.password ? "auth-err-border" : ""
}`}
name="password"
type={visible.pw ? 'text' : 'password'}
type={visible.pw ? "text" : "password"}
placeholder="비밀번호를 입력해주세요"
{...register('password', {
{...register("password", {
required: true,
minLength: 8,
})}
Expand All @@ -86,15 +90,15 @@ export default function Login() {
src={visible.pw ? visibleEye_on : visibleEye_off}
alt="visible-icon"
onClick={(e) => {
onClickVisible(e.target.id);
onClickVisible(e.currentTarget.id);
}}
/>
</div>
</div>
{errors.password?.type === 'required' && (
{errors.password?.type === "required" && (
<p className="auth-err-msg">비밀번호를 입력해주세요</p>
)}
{errors.password?.type === 'minLength' && (
{errors.password?.type === "minLength" && (
<p className="auth-err-msg">
비밀번호를 8자 이상 입력해주세요.
</p>
Expand Down
Loading
Loading