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

merge develop to feature/quiz #45

Merged
merged 11 commits into from
Mar 20, 2024
59 changes: 51 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,54 @@
![20240229152145.png](..%2F20240229152145.png)
# 백엔드 도우미 프로젝트

## 개발 목적
백엔드 오르미 부트캠프 학생들을 위해 코딩테스트 관련 주제를 설명 및 질문을 받을 수 있는 페이지를 제공하며
퀴즈와 정답을 출제할 수 있는 페이지를 제공하여 백엔드 개발자가 되는데 도움이 되고자 만들었습니다.
## 📋 프로젝트 소개
<p><strong>ESTsoft</strong> 백엔드 개발자 <strong>오르미 4기</strong>에서 프로젝트를 진행하고 있는 <strong>도우미</strong>입니다. </p>
<p><strong>Bend Doumi</strong>는 코딩 테스트 준비와 지식 공유를 위한 커뮤니티입니다.</p>
<p>알고리즘이 설명되어 있는 <strong>알고리즘 페이지</strong>와 코딩 테스트 관련 문제를 질문할 수 있는 <strong>코딩 테스트 준비 페이지</strong>와
<br>
자신이 알고 있는 지식에 대해 질문과 답을 등록하여 다른 이용자들이 퀴즈 형식으로 학습할 수 있게 함으로써, 지식을 테스트하고 공유하는
<strong>퀴즈 페이지</strong>가 있습니다.<br>
여기서는 모두가 질문하고,가르치면서 함께 배우고 성장할 수 있습니다.

<br><br>

## 개발 기간
2월 ~ 3월(1 ~ 2개월)
## 🚩 프로젝트 목표
클린 코드 작성을 통해 코드의 가독성과 유지 보수성을 향상시켜 개발 과정을 원활하게 만드는 것을 목표로 개발하였습니다.

## 개발 인원
4명
GitHub을 활용하여 프로젝트를 관리하고 코드를 공유하며, 코드 리뷰를 진행함으로써 팀원들 간의 프로젝트 이해도를 향상시켰습니다.

<br><br>

## 📆 프로젝트 진행기간
- 2024-02-13 ~ 2024-03-20

<br><br>

## 👨🏻‍💻 개발 인원 : 3명
강한주, 강성훈, 정지원

<br><br>

## 🔗 배포 주소
http://bend-doumi.com:8080/

## ⚙️Skills

### Languages
[![My Skills](https://skillicons.dev/icons?i=spring,java,js,html,css)](https://skillicons.dev)

### Tools
[![My Skills](https://skillicons.dev/icons?i=idea,gradle,github,figma)](https://skillicons.dev)

### DataBase
[![My Skills](https://skillicons.dev/icons?i=mysql)](https://skillicons.dev)

### OS
[![My Skills](https://skillicons.dev/icons?i=windows,ubuntu)](https://skillicons.dev)

### Deploy
[![My Skills](https://skillicons.dev/icons?i=aws,githubactions)](https://skillicons.dev)

### 🔌 API
- toast UI API

## ✅ 기능 구현 목록
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@

@Controller
public class AlgorithmController {

@GetMapping("/doumiAlgorithm")
@Operation(summary = "알고리즘 메인 페이지를 조회할 수 있는 API")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "알고리즘 메인 HTML을 반환",
content = @Content(mediaType = "text/html"))
@ApiResponse(responseCode = "200", description = "알고리즘 메인 HTML을 반환",
content = @Content(mediaType = "text/html"))
})
public String index() {

Expand All @@ -29,7 +30,17 @@ public String timecomplexity() {
}

@GetMapping("/codingtest/stack")
public String stack(){
public String stack() {
return "algorithm/stackAndQueue";
}

// @GetMapping("/codingtest/bruteforce")
// public String bruteforce() {
// return "algorithm/bruteforce";
// }

@GetMapping("/codingtest/sets&maps")
public String setsAndMaps() {
return "algorithm/setsAndMaps";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.example.doumiproject.dto.PostDto;
import com.example.doumiproject.entity.Comment;
import com.example.doumiproject.entity.User;
import com.example.doumiproject.exception.user.NotValidateUserException;
import com.example.doumiproject.service.CodingTestService;
import com.example.doumiproject.service.CommentService;
import com.example.doumiproject.service.QuizService;
Expand Down Expand Up @@ -31,6 +32,7 @@
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
Expand Down Expand Up @@ -158,7 +160,7 @@ public String myPage(@PathVariable("userId") Long userId, HttpSession session, M
content = @Content(mediaType = "text/html"))
})
public String getCodingTestPost(@PathVariable("userId") Long userId, HttpSession session,
@RequestParam(defaultValue = "1", value = "page") int page, Model model) {
@RequestParam(defaultValue = "1", value = "page") int page, Model model) {
int totalPages = codingTestService.getTotalPagesForMyPage(userId, "COTE", pageSize);

List<PostDto> userCoteList = codingTestService.findByUserId(userId, page, pageSize);
Expand All @@ -175,7 +177,7 @@ public String getCodingTestPost(@PathVariable("userId") Long userId, HttpSession
content = @Content(mediaType = "text/html"))
})
public String getQuizPost(@PathVariable("userId") Long userId, HttpSession session,
@RequestParam(defaultValue = "1", value = "page") int page, Model model) {
@RequestParam(defaultValue = "1", value = "page") int page, Model model) {

int totalPages = quizService.getTotalPagesForMyPage(userId, "QUIZ", pageSize);

Expand All @@ -193,7 +195,7 @@ public String getQuizPost(@PathVariable("userId") Long userId, HttpSession sessi
content = @Content(mediaType = "text/html"))
})
public String getCommentPost(@PathVariable("userId") Long userId, HttpSession session,
@RequestParam(defaultValue = "1", value = "page") int page, Model model) {
@RequestParam(defaultValue = "1", value = "page") int page, Model model) {

int totalPages = commentService.getTotalPagesForMyPage(userId, pageSize);

Expand All @@ -204,7 +206,8 @@ public String getCommentPost(@PathVariable("userId") Long userId, HttpSession se
return "myPage/myPageComment";
}

private void setPaginationAttributes(Model model, int page, int totalPages, Long userId, List<?> contents) {
private void setPaginationAttributes(Model model, int page, int totalPages, Long userId,
List<?> contents) {

if (page < 1) {
page = 1;
Expand All @@ -220,4 +223,17 @@ private void setPaginationAttributes(Model model, int page, int totalPages, Long
model.addAttribute("totalPages", totalPages);
model.addAttribute("userId", userId);
}

@DeleteMapping("/user/{id}/delete")
public ResponseEntity<Void> withdraw(@PathVariable Long id, HttpSession session) {
long userId = (long) session.getAttribute("userId");

if (userId != id) {
throw new NotValidateUserException();
}

userService.deleteUser(userId);

return ResponseEntity.ok().build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public User findByUserId(String userId) {
public List<User> findAllUser() {
return null;
}

@Override
public List<Comment> findAllUserCommentPosts(Long userId) {
String sql = "SELECT user_id,post_id,type,contents,updated_at FROM comment WHERE user_id = ?";
Expand All @@ -77,4 +77,11 @@ public List<Comment> findAllUserCommentPosts(Long userId) {
});
}

@Override
public void deleteUser(Long userId) {
String sql = "DELETE FROM user WHERE id = ?";

jdbcTemplate.update(sql, userId);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,7 @@ default RowMapper<User> userRowMapper() {
return user;
});
}
}

void deleteUser(Long userId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,9 @@ public List<Comment> getAllUserCommentPosts(Long userId) {
List<Comment> userCommentPosts = userRepository.findAllUserCommentPosts(userId);
return userCommentPosts;
}


public void deleteUser(Long userId) {
userRepository.deleteUser(userId);
}
}
82 changes: 25 additions & 57 deletions src/main/resources/static/Js/myPage.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,29 @@
function clickToGoMyCodingtestPost() {
let id = document.getElementById('myPage_userName').getAttribute(
'data-userid');
switchHighlight('coteType');
$.ajax({
//JS에 백틱을 써서 템플릿 리터럴을 사용했다
url: `/user/${id}/codingtest/posts`,
type: "GET",
success: function (data) {
$('.show_user_wrote .table_container .postList').html(data);
console.log(data);
},
error: function (error) {
console.log(error);
}
});
}

function clickToGoMyQuizPost() {
let id = document.getElementById('myPage_userName').getAttribute(
'data-userid');
switchHighlight('quizType');
$.ajax({
url: `/user/${id}/quiz/posts`,
type: "GET",
success: function (data) {
$('.show_user_wrote .table_container .postList').html(data);
console.log(data);
},
error: function (error) {
console.log(error);
}
});
}
function clickToGoLeaveMembership(event) {
event.preventDefault();

function clickToGoMyCommentPost() {
let id = document.getElementById('myPage_userName').getAttribute(
'data-userid');
switchHighlight('commentType');
$.ajax({
url: `/user/${id}/comment/posts`,
type: "GET",
success: function (data) {
$('.show_user_wrote .table_container .postList').html(data);
console.log(data);
},
error: function (error) {
console.log(error);
}
});
}
const isConfirmed = confirm("Bend Doumi에서 탈퇴하시겠습니까?");

function switchHighlight(selectedId) {
let items = ['coteType', 'quizType', 'commentType'];
if (isConfirmed) {
// 사용자 ID 가져오기
let id = document.getElementById('myPage_userName').getAttribute(
'data-userid');

items.forEach(function (id) {
document.getElementById(id).style.color = ''; // 원래 색상으로 초기화
});

document.getElementById(selectedId).style.color = '#04B45F';
fetch(`/user/${id}/delete`, {
method: 'DELETE',
})
.then(response => {
if (response.ok) {
alert("탈퇴 처리가 완료되었습니다.");
window.location.replace('/user/login');
} else {
alert("탈퇴 처리 중 오류가 발생했습니다.");
}
})
.catch(error => {
console.error('탈퇴 요청 실패:', error);
alert("탈퇴 처리 중 문제가 발생했습니다.");
});
} else {
alert("탈퇴 절차가 취소되었습니다.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ body {

/*header 파트*/
.move_to_algorithm {
/*color: #04B45F;*/
color: #04B45F;
}


Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/static/css/codingtest/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ body {
}

/*header 파트*/
.move_to_algorithm {
/*color: #04B45F*/
.move_to_codingtest {
color: #04B45F
}

/*main 파트*/
Expand Down
50 changes: 25 additions & 25 deletions src/main/resources/static/css/fragments/footer.css
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
html,
body {
height: 100%;
min-height: 100vh;
}

body {
display: flex;
flex-direction: column;
display: flex;
flex-direction: column;
}

main {
flex: 1;
width: 100%;
flex: 1;
width: 100%;
}

footer{
width: 100%;
padding: 70px 0 40px 0;
/*border-top: 1px solid #C4C4C4;*/
footer {
width: 100%;
padding: 70px 0 40px 0;
/*border-top: 1px solid #C4C4C4;*/
}

.footer-wrapper{
display: flex;
justify-content: space-between;
max-width: 900px;
margin: 0 auto;
.footer-wrapper {
display: flex;
justify-content: space-between;
max-width: 900px;
margin: 0 auto;
}

.boot-camp-info{
font-size: 13px;
font-weight: 500;
display: flex;
align-items: center;
.boot-camp-info {
font-size: 13px;
font-weight: 500;
display: flex;
align-items: center;
}

.footer-img{
width: 40px;
.footer-img {
width: 40px;
}

.helper{
font-size: 13px;
display: flex;
align-items: center;
.helper {
font-size: 13px;
display: flex;
align-items: center;
}
Loading
Loading