자바스크립트 -프로젝트(book)

정영찬·2022년 2월 9일
0

자바스크립트

목록 보기
19/21
post-thumbnail

index에서 책 목록에 구현된 view 버튼을 누르면 상세 정보를 보여주는 창으로 이동한다.

book.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>My Faborite Books</title>

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
        integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous" />

    <link rel="stylesheet" type="text/css" href="css/book.css" />
</head>

<body>
    <header>
        <div class="collapse bg-dark" id="navbarHeader">
            <div class="container">
                <div class="row">
                    <div class="col-sm-8 col-md-7 py-4">
                        <h4 class="text-white">About</h4>
                        <p class="text-muted">
                            Add some information about the album below, the author, or any
                            other background context. Make it a few sentences long so folks
                            can pick up some informative tidbits. Then, link them off to
                            some social networking sites or contact information.
                        </p>
                    </div>
                    <div class="col-sm-4 offset-md-1 py-4">
                        <h4 class="text-white">Contact</h4>
                        <ul class="list-unstyled">
                            <li><a href="#" class="text-white">Follow on Twitter</a></li>
                            <li><a href="#" class="text-white">Like on Facebook</a></li>
                            <li><a href="#" class="text-white">Email me</a></li>
                            <li><button id="btn_logout">로그아웃</button></li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
        <div class="navbar navbar-dark bg-dark shadow-sm">
            <div class="container d-flex justify-content-between">
                <a href="/" class="navbar-brand d-flex align-items-center">
                    <strong>My Faborite Books</strong>
                </a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarHeader"
                    aria-controls="navbarHeader" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
            </div>
        </div>
    </header>
    <main role="main">
        <section class="jumbotron text-center">
            <div class="container">
                <h1 class="jumbotron-heading">Book example</h1>
                <p class="lead text-muted">
                    This project is an example for beginners studying JavaScript.<br />
                    You can add your favorite book and check it out of the list.<br />
                    You can delete or modify the book that you add.
                </p>
                <p>
                    <a href="/add" class="btn btn-primary my-2">Add Book</a>
                </p>
            </div>
        </section>
        <div class="album py-5 bg-light">
            <div class="container">
                <div id="detail"></div>
            </div>
        </div>
    </main>

    <footer class="text-muted">
        <div class="container">
            <p class="float-right">
                <a href="#">Back to top</a>
            </p>
            <p>
                Album example is &copy; Bootstrap, but please download and customize
                it for yourself!
            </p>
            <p>
                New to Bootstrap?
                <a href="https://getbootstrap.com/">Visit the homepage</a> or read our
                <a href="/docs/4.3/getting-started/introduction/">getting started guide</a>.
            </p>
        </div>
    </footer>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
        integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous">
    </script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
        integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous">
    </script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
        integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous">
    </script>

    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="js/book.js"></script>
</body>

</html>

book.js
구현한 메서드
bindLogoutButton() 버튼에 이벤트를 연결한다. 헤더쪽 로그아웃 버튼을 누르면 로그인 창으로 이동한다.
getToken() 토큰을 체크한다.
getUserByToken(token) 토큰으로 서버에서 나의 정보를 받아온다.
getBooks(bookId) 서버에서 책의 정보를 받아온다.
render(books) 받아온 책을 정보를 토대로 미리 정의한 element를 이용해서 시각적으로 구현한다.

bookId 브라우저에서 id를 가져온다.

function getToken() {
    return localStorage.getItem('token');
}
async function getUserByToken(token) {
    try {
        const res = await axios.get('https://api.marktube.tv/v1/me', {
            headers: {
                Authorization: `Bearer ${token}`,
            },
        });
        return res.data;
    } catch (error) {
        console.log('getUserByToken error', error);
        return null;
    }

}

async function getBooks(bookId) {
    const token = getToken();
    if (token === null) {
        location.assign('/login');
        return null;
    }
    try {
        const res = await axios.get(`https://api.marktube.tv/v1/book/${bookId}`, {
            headers: {
                Authorization: `Bearer ${token}`,
            },
        });
        return res.data; // 책 데이터
    } catch (error) {
        console.log('getBooks error', error);
        return null;
    }
}

async function logout() {
    const token = getToken();
    if (token === null) {
        location.assign('/login');
        return;
    }
    try {
        await axios.delete('https://api.marktube.tv/v1/me', {
            headers: {
                Authorization: `Bearer ${token}`,
            },
        });
    } catch (error) {
        console.log('logout error', error);
    } finally {
        localStorage.clear();
        location.assign('/login');
    }
}

async function deleteBook(bookId) {
    const token = getToken();
    if (token === null) {
        location.assign('/login');
        return;
    }
    await axios.delete(`https://api.marktube.tv/v1/book/${bookId}`, {
        headers: {
            Authorization: `Bearer ${token}`,
        },
    });
    return;
}

function bindLogoutButton() {
    const btnLogout = document.querySelector("#btn_logout");
    btnLogout.addEventListener('click', logout);
}




function render(books) {
    const detailElement = document.querySelector('#detail');

    detailElement.innerHTML = `<div class="card bg-light w-100">
    <div class="card-header"><h4>${books.title}</h4></div>
    <div class="card-body">
      <h5 class="card-title">"${books.message}"</h5>
      <p class="card-text">글쓴이 : ${books.author}</p>
      <p class="card-text">링크 : <a href="${
        books.url
      }" target="_BLANK">바로 가기</a></p>
      <a href="/edit?id=${books.bookId}" class="btn btn-primary btn-sm">Edit</a>
      <button type="button" class="btn btn-danger btn-sm" id="btn-delete">Delete</button>
    </div>
    <div class="card-footer">
        <small class="text-muted">작성일 : ${new Date(
          books.createdAt,
        ).toLocaleString()}</small>
      </div>
  </div>`;

    document.querySelector('#btn-delete').addEventListener('click', async () => {
        try {
            await deleteBook(books.bookId);
            location.href = '/';
        } catch (error) {
            console.log(error);
        }
    });
}

async function main() {
    //버튼에 이벤트 연결
    bindLogoutButton()
    //브라우저에서 id 가져오기
    const bookId = new URL(location.href).searchParams.get('id');

    //토큰체크
    const token = getToken();
    if (token === null) {
        location.assign('/login');
        return;
    }

    //토큰으로 서버에서 나의정보 받아오기
    const user = await getUserByToken(token);
    if (user === null) {
        localStorage.clear();
        location.assign('/login');
        return;
    }
    console.log(user);

    //책을 서버에서 받아오기
    const books = await getBooks(bookId);

    if (books === null) {
        alert("서버에서 책 받아오기 실패")
        return;
    }

    console.log(books);

    //받아온 책을 그리기
    render(books);


}



document.addEventListener('DOMContentLoaded', main)

결과 화면

profile
개발자 꿈나무

0개의 댓글

관련 채용 정보