오늘은
팀프로젝트에 집중을 하고 있습니다
다들 너무 열심히 잘 해주어서
지지 않으려고 노력중입니다
시너지 효과가 나서 다른 팀들보다 작업 속도도 빠른 것 같고
트러블 없이 잘 진행되어 가는 중인 것 같습니다
팀 프로젝트
피그마로 각자 페이지를 구성하여 각 페이지의 기준을 잡았습니다
그리고선 db를 위한 초기 erd를 작성하였습니다
피그마로 그려보았던 메인 페이지가 어떻게 나올지 궁금해서
먼저 html과 간단한 css로 구현을 해보았습니다
* html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TEST</title>
<link rel="stylesheet" href="main.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100..900&display=swap" rel="stylesheet">
</head>
<body>
<div id="header">
<section class="header">
<div class="header_logo_box">
<a href="#">
<img class="header_logo" src="/img/main_logo.png" alt="logo">
<!-- <p class="header_library_name">선유책숲</p> -->
</a>
</div>
<div class="header_links">
<div class="header_link">
<div class="header_link_search">
<a href="#">도서검색</a>
</div>
<div class="header_link_open_space">
<a href="#">열린공간</a>
</div>
<div class="header_link_library_info">
<a href="#">도서관안내</a>
</div>
<div class="header_link_study_room">
<a href="#">열람실</a>
</div>
<div class="header_link_my_labrary">
<a href="#">나의책숲</a>
</div>
</div>
</div>
<div class="header_member">
<a class="header_member_login" href="#">로그인</a> |
<a class="header_member_join" href="#">회원가입</a>
</div>
<!-- when login, change div element -->
<!-- <div class="header_member">
<div class="header_member_logout"></div>
</div> -->
</section>
</div>
<div id="container">
<section class="main">
<div class="main_top">
<div class="main_pic_box">
<img class="main_pic active" src="/img/main_library_picture1.PNG" alt="">
<img class="main_pic" src="/img/main_library_picture2.PNG" alt="">
<img class="main_pic" src="/img/main_library_picture3.PNG" alt="">
<img class="main_pic" src="/img/main_library_picture4.PNG" alt="">
<img class="main_pic" src="/img/main_library_picture5.PNG" alt="">
</div>
<div class="main_welcome">
<p class="main_big_welcome">
도서관에서 여러분의 다음 책을 만나보세요
</p>
<p class="main_small_welcom">
모든 이야기가 당신을 기다립니다
</p>
</div>
<div class="main_timer">
<div class="main_timer_pointer"></div>
</div>
<div class="main_timer_circle">
<button class="main_toggle_btn" onClick="togglePicture()">||</button>
</div>
<div class="main_search">
<input class="main_search_input" type="text" placeholder="Seacrh">
<img class="main_search_icon" src="/img/magnifying.png">
</div>
</div>
<div class="main_mid">
<div class="main_mid_text_box">
<p class="main_mid_text"></p>
</div>
<div class="main_mid_schedule">
<p class="main_schedule_title"></p>
<article class="main_calender"></article>
<div class="main_using_time_info">
<table class="usable_time_table">
<!-- table_element_area => reference to bottom -->
</table>
<p class="holiday_date"></p>
</div>
</div>
<div class="main_mid_openspace">
<p class="main_openspace_title"></p>
<div class="main_openspace_board">
<table class="openspace_board_table">
<!-- not yet making table element -->
</table>
</div>
</div>
<div class="main_mid_free">
<p class="main_free_title"></p>
<div class="main_free_board">
<table class="free_board_table">
<!-- not yet making table element -->
</table>
</div>
</div>
</div>
<div class="main_icons">
<div class="main_use_info">
<img class="use_info_icon" src="#" alt="">
</div>
<div class="main_reading_event">
<img class="reading_event_icon" src="#" alt="">
</div>
<div class="main_study_room">
<img class="study_room_icon" src="#" alt="">
</div>
<div class="main_request_book">
<img class="request_book_icon" src="#" alt="">
</div>
<div class="main_my_library">
<img class="my_library_icon" src="#" alt="">
</div>
</div>
<div class="main_bottom">
<div class="main_bottom_text_box">
<p class="main_bottom_text"></p>
</div>
<div class="main_bottom_recommend_books">
<div class="main_best_book">
<img class="main_best_book_img" src="#" alt="#">
<p class="main_best_book_title"></p>
<p class="main_best_book_author"></p>
</div>
<div class="main_best_book">
<img class="main_best_book_img" src="#" alt="#">
<p class="main_best_book_title"></p>
<p class="main_best_book_author"></p>
</div>
<div class="main_best_book">
<img class="main_best_book_img" src="#" alt="#">
<p class="main_best_book_title"></p>
<p class="main_best_book_author"></p>
</div>
<div class="main_best_book">
<img class="main_best_book_img" src="#" alt="#">
<p class="main_best_book_title"></p>
<p class="main_best_book_author"></p>
</div>
<div class="main_best_book">
<img class="main_best_book_img" src="#" alt="#">
<p class="main_best_book_title"></p>
<p class="main_best_book_author"></p>
</div>
</div>
</div>
</section>
</div>
<div id="footer">
<section class="footer">
<div class="footer_top">
<div class="footer_top_text_box">
<p>
<a href="open_info_notice">정보공개알림</a> |
<a href="personal_info_raw">개인정보처리방침</a> |
<a href="public_service_raw">행정서비스헌장</a> |
<a href="use_info_raw">이용규정</a> |
<a href="find_load">오시는길</a>
</p>
</div>
</div>
<div class="footer_bottom">
<div class="team_info_box">
<p class="team_basic_info">(우)00000 서울시 영등포구 선유로 (선유책숲) TEL 02-1234-1234 FAX 02-123-1234, 02-123-1235</p>
<p class="team_copyright">Copyright ⓒ 2024 team3_kh_academy. All Rights Reserved.</p>
</div>
</div>
</section>
</div>
<script src="/script/script.js"></script>
</body>
</html>
<!-- usable_time_table element -->
<!-- <thead>
<tr>
<th>구분</th>
<th>이용대상</th>
<th>월요일~금요일</th>
<th>토요일~일요일</th>
</tr>
</thead>
<tbody>
<tr>
<td>문헌정보실</td>
<td>중학생이상</td>
<td>09:00~20:00</td>
<td>09:00~17:00</td>
</tr>
<tr>
<td>어린이실</td>
<td>유아 및 초등학생</td>
<td>09:00~18:00</td>
<td>09:00~17:00</td>
</tr>
<tr>
<td>휴게실</td>
<td>제한없음</td>
<td>09:00~20:00</td>
<td>09:00~17:00</td>
</tr>
<tr>
<td>자율학습실</td>
<td>중학생이상</td>
<td>
<p>(3월~10월)07:00~22:00</p>
<p>(11월~2월)07:00~22:00</p>
</td>
<td>
<p>(3월~10월)07:00~22:00</p>
<p>(11월~2월)07:00~22:00</p>
</td>
</tr>
</tbody> -->
* css
/* general */
* {
margin: 0;
padding: 0;
font-family: "Noto Sans KR", sans-serif;
box-sizing: border-box;
}
button:hover {
cursor: pointer;
}
/* header */
#header{
width: 100%;
margin: 0;
padding: 0;
background-color: #f4f4f4;
display: flex;
justify-content: space-around;
position: fixed;
z-index: 1;
}
.header {
width: 80%;
height: 100px;
margin: 0;
text-align: center;
justify-content: space-around;
display: flex;
align-items: center;
}
/* header_logo */
.header_logo_box {
width: 15%;
display: flex;
justify-content: center;
}
.header_logo {
width: 180px;
}
/* .header_library_name {
font-size: 1.6rem;
font-weight: 600;
color: #7D704E;
} */
/* header_link */
.header_links {
width: 70%;
display: flex;
justify-content: space-around;
}
.header_link {
width: 60%;
display: flex;
justify-content: space-around;
}
.header_link a {
font-weight: 600;
color: #7D704E;
text-decoration: none;
}
/* header_member */
.header_member {
width: 15%;
color: #A5B569;
}
.header_member a {
font-size: 0.7rem;
color: #A5B569;
text-decoration: none;
}
/* main */
#container {
width: 100%;
margin: 0;
padding-top: 100px;
background-color: #f4f4f4;
}
.main {
width: 100%;
height: 3350px;
}
/* main_top */
.main_top {
width: 88.5%;
height: 700px;
background-color: #ccc;
margin: 0 auto;
position: relative;
border-radius: 50px;
}
/* main_pic */
.main_pic_box {
width: 100%;
height: 700px;
position: relative;
}
.main_pic {
width: 100%;
height: 700px;
border-radius: 50px;
position: absolute;
opacity: 0;
transition: opacity 1s ease-in-out;
}
.main_pic.active{
opacity: 1;
}
/* main_welcome */
.main_welcome {
width: 35%;
height: 200px;
border-radius: 25px;
position: absolute;
top: 150px;
left: 150px;
}
.main_big_welcome {
color: #fff;
font-size: 3.5rem;
line-height: 64px;
text-shadow: 2px 2px 5px #aaa;
}
.main_small_welcom {
color: #fff;
font-size: 1.2rem;
line-height: 48px;
text-shadow: 2px 2px 5px #aaa;
}
/* main_timer */
.main_timer {
width: 100px;
height: 100px;
border: 15px solid #555;
border-radius: 100%;
position: absolute;
bottom: 100px;
left: 150px;
animation: rotateBorder 5s linear infinite;
}
.main_timer_pointer {
position: absolute;
top: -15px;
left: 25px;
width: 15px;
height: 15px;
border-radius: 100%;
background-color: #555;
}
@keyframes rotateBorder {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
border-color: #fff;
}
}
.main_timer_circle {
position: absolute;
left:175px;
bottom: 125px;
}
.main_timer_circle button {
border: none;
background: none;
width: 50px;
height: 50px;
font-size: 1.5rem;
font-weight: 800;
color: #fff;
border-radius: 100%;
}
/* main_search */
.main_search {
width: 40%;
height: 100px;
position: absolute;
bottom: 100px;
right: 100px;
}
.main_search_icon {
width: 50px;
width: 50px;
position: absolute;
top: 27.5px;
left: 27.5px;
}
.main_search_input {
width: 100%;
height: 100px;
border: 3px solid #fff;
border-radius: 50px;
background: none;
padding-top: 10px;
padding-right: 30px;
padding-left: 100px;
padding-bottom: 10px;
font-size: 2rem;
color: #fff;
}
.main_search_input::placeholder {
font-size: 2rem;
color: #ddd;
}
input:focus{
outline: none;
}
/* footer */
#footer{
width: 100%;
margin: 0;
padding: 0;
background-color: #f4f4f4;
}
.footer {
width: 100%;
height: 150px;
text-align: center;
}
/* footer-top */
.footer_top {
width: 100%;
height: 50px;
background-color: #7D704E;
display: flex;
justify-content: center;
align-items: center;
}
.footer_top_text_box {
width: 45%;
}
.footer_top_text_box p {
display: flex;
justify-content: space-around;
font-size: 0.9rem;
color: #fff;
}
.footer_top_text_box p a {
color: #fff;
text-decoration: none;
}
/* footer-bottom */
.footer_bottom {
width: 100%;
height: 100px;
background-color: #000;
display: flex;
justify-content: center;
align-items: center;
}
.team_info_box {
width: 75%;
}
.team_info_box p {
color: #fff;
}
.team_basic_info {
font-size: 0.8rem;
}
.team_copyright {
font-size: 0.7rem;
}
백엔드 부분은 도서관에 바란다 게시판 부분을 맡았습니다
dto와 entity를 생성하고 html 페이지를 나눠준 후에
MVC를 이용하여 CRUD 기능 구현을 했습니다
* controller
package com.khit.library.controller;
import com.khit.library.config.SecurityUser;
import com.khit.library.dto.HopeBoardDTO;
import com.khit.library.entity.HopeBoard;
import com.khit.library.service.HopeBoardService;
import lombok.RequiredArgsConstructor;
import java.util.List;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
@RequiredArgsConstructor
public class HopeBoardController {
private final HopeBoardService hopeBoardService;
// write page 글쓰기
@GetMapping("/hopeboard/write")
public String writeForm() {
return "hopeboard/write";
}
// 글쓰기 처리
@PostMapping("/hopeboard/write")
public String write(@ModelAttribute HopeBoard hopeBoard,
@AuthenticationPrincipal SecurityUser principal) {
hopeBoard.setMember(principal.getMember());
hopeBoard.setHbhit(0);
hopeBoardService.save(hopeBoard);
return "redirect:/hopeboard/pagelist";
}
// update page 글 수정
@GetMapping("/hopeboard/update/{hbid}")
public String updateForm(@PathVariable Long hbid, Model model) {
HopeBoardDTO hopeBoardDTO = hopeBoardService.findById(hbid);
model.addAttribute("hopeBoard", hopeBoardDTO);
return "hopeboard/update";
}
// 글 수정 처리
@PostMapping("/hopeboard/update/{hbid}")
public String update(@ModelAttribute HopeBoardDTO hopeBoardDTO) {
hopeBoardService.update(hopeBoardDTO);
return "redirect:/hopeboard/" + hopeBoardDTO.getHbid();
}
// 글 전체 목록
@GetMapping("/hopeboard/pagelist")
public String getAllList(Model model) {
List<HopeBoardDTO> hopeBoardDTOList = hopeBoardService.findAll();
model.addAttribute("hopeBoardList", hopeBoardDTOList);
return "hopeboard/pagelist";
}
// 글 하나 상세보기
@GetMapping("/hopeboard/{hbid}")
public String getDetail(@PathVariable Long hbid, Model model) {
HopeBoardDTO hopeBoardDTO = hopeBoardService.findById(hbid);
model.addAttribute("hopeBoard", hopeBoardDTO);
return "hopeboard/detail";
}
// 글 삭제
@GetMapping("/hopeboard/delete/{hbid}")
public String deleteHopeBoard(@PathVariable Long hbid) {
hopeBoardService.deleteById(hbid);
return "redirect:/hopeboard/pagelist";
}
}
2023. 02. 01 (목)
프로그래머 도전기 112일차 (0) | 2024.02.06 |
---|---|
프로그래머 도전기 111일차 (2) | 2024.02.04 |
프로그래밍 도전기 109일차 (2) | 2024.01.30 |
프로그래밍 도전기 108일차 (2) | 2024.01.28 |
프로그래밍 도전기 107일차 (2) | 2024.01.25 |