본문 바로가기

Dot Programming/Spring Clone

[스프링 웹앱 프로젝트 #21] 프로필 뷰

21. 프로필 뷰

뷰 종류
1. 정보가 없는 프로필 뷰
2.정보가 있는 프로필 뷰

> 정보의 유/무 여부에 따라 보여줄 메시지가 다르다.
> 현재 유저가 프로필을 수정할 수 있는 권한이 있는지 판단해야 한다.

부트스트랩
 > ListGroup
 > Grid

 

Controller 작성

AccountController에 프로필 정보 가져오는 Get메소드를 정의하기

 

 1. nickname을 가진 유저가 있는지 확인 (없으면 에러처리)

 2. model에 속성 추가 

   >  nickname을 가진 유저 정보

   > 유저 프로필 주인 여부 (해당 nickname의 account == @CurrentUser account ? true : false)

/**
     * 프로필 정보 보여주기
     */
    @GetMapping("/profile/{nickname}")
    public String viewProfile(@PathVariable String nickname, Model model, @CurrentUser Account account){

        //nickname을 가진 유저가 있는지 확인
        Account byNickname = accountRepository.findByNickname(nickname);
        if(nickname == null){
            throw new IllegalArgumentException(nickname + "에 해당하는 사용자가 없습니다.");
        }

        /**
         *  model.addAttribute(byNickname); == model.addAttribute("account", byNickname);
         *  "" 선언 안해주면 byNickname객체 이름이 camelcase로 자동으로 삽입됨 -> signUpForm메소드에서 말한 것과 동일한 내용
         */
        model.addAttribute(byNickname);
        model.addAttribute("isOwner", byNickname.equals(account)); // 정보가 일치하면 프로필 주인임을 알 수 있음

        return "account/profile";
    }

 

 

프로필 뷰 만들기

1. 유저 프로필이 존재하는가?

th:if="${#strings.isEmpty(account.profileImage)} ?  jdenticon으로 무작위 이미지 보여주기 : 해당 유저 프로필이미지 보여주기

 

2. 유저 소개글이 존재하는가?

th:if="${!#strings.isEmpty(account.bio)} ?  프로필 소개글 보여주기 :  2-1로 이동

2-1. 해당 프로필의 주인인가?
isOwner ? "한 줄 소개를 추가하세요" 텍스트 노출 : empty

 

1, 2번 코드

 <div class ="row mt-5 justify-content-center">

   <!--1.유저 프로필이 존재하는가? -->
   <div class="col-2">
      <!-- Avatar -->
      <svg th:if="${#strings.isEmpty(account.profileImage)}" class="img-fluid float-left rounded img-thumbnail"
         th:data-jdenticon-value="${account.nickname}" width="125" height="125"></svg>
      <img th:if="${!#strings.isEmpty(account.profileImage)}" class="img-fluid float-left rounded img-thumbnail"
         th:src="${account.profileImage}"
         width="125" height="125"/>
   </div>
   <!--2. 유저 소개글이 존재하는가? -->
   <div class="col-8">
      <h1 class="display-4 " th:text="${account.nickname}">Whiteship</h1>
      <p class="lead" th:if="${!#strings.isEmpty(account.bio)}" th:text="${account.bio}">bio</p>
      <p class="lead" th:if="${#strings.isEmpty(account.bio) && isOwner}">
         한 줄 소개를 추가하세요.
      </p>
   </div>
</div>

 

3. ListGroup을 사용하여 간단한 메뉴 보여주기

1. 소개 탭 / 스터디 탭 만들기

2. 소개 탭 클릭시 목록 보여주기
   > 해당 내용이 존재할 때만 노출 
      >> url, 직업, 위치 보여주기
   > Owner == true , 해당 내용 존재할 때만 노출
      >> 이메일 주소 보여주기
      >> 이메일 인증 여부
         >>> 안했을 시 "가입을 완료하려면 이메일을 확인하세요" 보여주기
         >>> 가입한 날짜 보여죽

 3. 수정 버튼 보여주기

 

3번 코드

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head th:replace ="fragments.html :: head"></head>
<body class="bg-light">
    <nav th:replace="fragments.html :: main-nav"></nav>
    <div class="container">
        <div class ="row mt-5 justify-content-center">

            <!--1.유저 프로필이 존재하는가? -->
            <div class="col-2">
            <!-- Avatar -->
                <svg th:if="${#strings.isEmpty(account.profileImage)}" class="img-fluid float-left rounded img-thumbnail"
                     th:data-jdenticon-value="${account.nickname}" width="125" height="125"></svg>
                <img th:if="${!#strings.isEmpty(account.profileImage)}" class="img-fluid float-left rounded img-thumbnail"
                     th:src="${account.profileImage}"
                     width="125" height="125"/>
            </div>
            <!--2. 유저 소개글이 존재하는가? -->
            <div class="col-8">
                <h1 class="display-4 " th:text="${account.nickname}">Whiteship</h1>
                <p class="lead" th:if="${!#strings.isEmpty(account.bio)}" th:text="${account.bio}">bio</p>
                <p class="lead" th:if="${#strings.isEmpty(account.bio) && isOwner}">
                    한 줄 소개를 추가하세요.
                </p>
            </div>
        </div>

        <div class="row mt-3 justify-content-center">

            <!--3. ListGroup으로 메뉴 보여주기 -->
            <div class="col-2">
                <div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
                    <!--소개 탭-->
                    <a class="nav-link active" id="v-pills-intro-tab" data-toggle="pill" href="#v-pills-profile"
                       role="tab" aria-controls="v-pills-profile" aria-selected="true">소개</a>
                    <!--스터디 탭-->
                    <a class="nav-link" id="v-pills-study-tab" data-toggle="pill" href="#v-pills-study"
                       role="tab" aria-controls="v-pills-study" aria-selected="false">스터디</a>
                </div>
            </div>

            <!--3. ListGroup으로 메뉴 보여주기 -->
            <div class="col-8">
                <div class="tab-content" id="v-pills-tabContent">

                    <!--소개 탭 목록 보여주기-->
                    <div class="tab-pane fade show active" id="v-pills-profile" role="tabpanel" aria-labelledby="v-pills-home-tab">
                        <p th:if="${!#strings.isEmpty(account.url)}">
                            <span style="font-size: 20px;">
                                <i class="fa fa-link col-1"></i>
                            </span>
                            <span th:text="${account.url}" class="col-11"></span>
                        </p>
                        <p th:if="${!#strings.isEmpty(account.occupation)}">
                            <span style="font-size: 20px;">
                                <i class="fa fa-briefcase col-1"></i>
                            </span>
                            <span th:text="${account.occupation}" class="col-9"></span>
                        </p>
                        <p th:if="${!#strings.isEmpty(account.location)}">
                            <span style="font-size: 20px;">
                                <i class="fa fa-location-arrow col-1"></i>
                            </span>
                            <span th:text="${account.location}" class="col-9"></span>
                        </p>
                        <p th:if="${isOwner}">
                            <span style="font-size: 20px;">
                                <i class="fa fa-envelope-o col-1"></i>
                            </span>
                            <span th:text="${account.email}" class="col-9"></span>
                        </p>
                        <p th:if="${isOwner || account.emailVerified}">
                            <span style="font-size: 20px;">
                                <i class="fa fa-calendar-o col-1"></i>
                            </span>
                            <span th:if="${isOwner && !account.emailVerified}" class="col-9">
                                <a href="#" th:href="@{'/checkemail?email=' + ${account.email}}">가입을 완료하려면 이메일을 확인하세요.</a>
                            </span>
                            <span th:text="${#temporals.format(account.joinedAt, 'yyyy년 M월 가입')}" class="col-9"></span>
                        </p>
                        <div th:if="${isOwner}">
                            <a class="btn btn-outline-primary" href="#" th:href="@{/settings/profile}">프로필 수정</a>
                        </div>
                    </div>

                    <!--스터디 탭 목록 보여주기-->
                    <div class="tab-pane fade" id="v-pills-study" role="tabpanel" aria-labelledby="v-pills-profile-tab">
                        Study
                    </div>
                </div>
            </div>

        </div>
    </div>
</body>
</html>

 

 

결과화면

 

소개탭 > 해당 목록  

 

스터디탭 > 해당 목록

 

 

그런데 이메일 인증을 완료 하여도 해당 화면이 변하지 않는다

 

버그 발생!

트랜잭션 범위 밖에서 일어난 일이기 때문이다 (다음 강의에서 다루겠다 #22)

 


참고

인프런 강의 - 스프링과 JPA 기반 웹 애플리케이션 개발