Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[김영운] Sprint10 #639

Merged
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
25 changes: 25 additions & 0 deletions pages/404.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import Image from 'next/image';
import IMG_NOTFOUND from '@/public/img-notfound.svg';

export default function NotFound() {
return (
<>
<div>
<div>
<Image
width={500}
height={500}
style={{ width: '500px', height: '500px' }}
src={IMG_NOTFOUND}
alt={'찾을 수 없는 페이지 이미지'}
/>
<div>
<p>{'찾을 수 없는 페이지입니다.'}</p>
<p>{'요청하신 페이지가 사라졌거나,'}</p>
<p>{'잘못된 경로를 이용하셨어요. :)'}</p>
</div>
</div>
</div>
</>
);
}
Comment on lines +4 to +25
Copy link
Collaborator

Choose a reason for hiding this comment

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

오호 ! 404 페이지를 만들었군요 ! 굳굳

Copy link
Collaborator

Choose a reason for hiding this comment

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

예전에 에러 컴포넌트 관련하여 다음과 같이 만들었던 기억이 나네요:

import { HttpStatusCode } from 'axios';
import React from 'react';

interface ErrorProps {
  status: HttpStatusCode;
}

const statusMessages: Record<HttpStatusCode, string> = {
  400: "Bad Request - The server could not understand the request due to invalid syntax.",
  401: "Unauthorized - The client must authenticate itself to get the requested response.",
  403: "Forbidden - The client does not have access rights to the content.",
  404: "Not Found - The server can not find the requested resource.",
  500: "Internal Server Error - The server has encountered a situation it doesn't know how to handle.",
  502: "Bad Gateway - The server was acting as a gateway or proxy and received an invalid response from the upstream server.",
  503: "Service Unavailable - The server is not ready to handle the request.",
  504: "Gateway Timeout - The server is acting as a gateway or proxy and did not get a response in time from the upstream server.",
  //  ...
};

const Error: React.FC<ErrorProps> = ({ status }) => {
  const message = statusMessages[status] || "An unknown error has occurred.";

  return (
    <div className="error-container">
      <h1>Error {status}</h1>
      <p>{message}</p>
    </div>
  );
};

export default Error;

34 changes: 34 additions & 0 deletions pages/addboards.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useState } from 'react';
export interface IBoardValues {
title: string;
content: string;
imgFile: string | null;
}

export default function AddBoard() {
const [values, setValues] = useState<IBoardValues>({
title: '',
content: '',
imgFile: null,
});

function onChangeValues(key: keyof IBoardValues, value: string) {
setValues(prevValues => ({ ...prevValues, [key]: value }));
}
Comment on lines +15 to +17
Copy link
Collaborator

Choose a reason for hiding this comment

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

리액트 이벤트 타입은 다음과 같이 정의할 수 있습니다 !

Suggested change
function onChangeValues(key: keyof IBoardValues, value: string) {
setValues(prevValues => ({ ...prevValues, [key]: value }));
}
function onChangeValues(e: React.ChangeEvent<HTMLInputElement>) {
const input = e.target.value;
}

이미 리액트에서 제공되는 타입은 새로 정의할 필요 없겠죠? 😊


return (
<div>
<form>
<div>
<h1>게시글 쓰기</h1>
<button type="submit">등록</button>
</div>
<label>*제목</label>
<input type="text" placeholder="제목을 입력해주세요" />
Comment on lines +26 to +27
Copy link
Collaborator

Choose a reason for hiding this comment

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

다음과 같이 라벨과 인풋을 연결할 수 있습니다 !

Suggested change
<label>*제목</label>
<input type="text" placeholder="제목을 입력해주세요" />
<label>
*제목
<input type="text" placeholder="제목을 입력해주세요" />
</label>

혹은 다음과 같이:

Suggested change
<label>*제목</label>
<input type="text" placeholder="제목을 입력해주세요" />
<label for="title">*제목</label>
<input id="title" type="text" placeholder="제목을 입력해주세요" />

<label>*내용</label>
<textarea placeholder="내용을 입력해주세요"></textarea>
<label>상품 이미지</label>
</form>
</div>
);
}
Empty file added pages/addboards/[id].tsx
Empty file.
1 change: 1 addition & 0 deletions pages/api/apis.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// 일단 파일만 만들어 둠.. 9미션 및 앞으로 들어갈 api 정리 모듈로 쓸 파일 입니다.
Copy link
Collaborator

Choose a reason for hiding this comment

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

굳굳 ! 좋은 생각입니다.

프로젝트에서는 API 호출 로직을 별도의 파일로 분리하여 관리하는 것이 일반적이예요. 이렇게 하면 컴포넌트, 페이지, 훅 등 어디든 사용될 수 있겠죠? 😊
코드의 재사용성을 높이고, 유지보수가 쉬워질 수 있습니다 ! API 함수를 모듈화하여 사용하면 코드가 더 깔끔하고 읽기 쉬워집니다. 다음은 프로젝트의 디렉토리 구조와 API 함수 예제입니다:

// src/services/apis/user.api.ts (예시입니다 !)
export const getUserInfo = async () => {
	try {
		const { data } = await axios.get('/sample/user');
		return data;
	} catch(error) {
		throw error;
	}
};

Loading