- 어제까지의 진행 상황
👉 계획했던 모든 기능들은 구현이 됐지만 뭔가 디자인 적 요소가 부족.
- 오늘 해야할 것
1) 만든 프로젝트와 ppt로 팀원들의 기가 죽지 않도록 발표를 잘할 것!!
2) 할 것은 아니지만 ... 개인적으로 페이지에 재미요소를 추가했다.
3) 수정 기능도 만들어 보자!- 최종 코드( index.html )
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta property="og:title" content="팀6789땡"/>
<meta property="og:description" content="응원 한마디!!"/>
<meta property="og:image" content="https://cdn.iptnews.kr/news/photo/202202/20200_20185_1236.jpg"/>
<link rel="icon" href="../static/Group2.png"/>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
<title>팀 6789땡</title>
<link href="https://fonts.googleapis.com/css2?family=Noto+Serif+KR:wght@200;300;400;500;600;700;900&display=swap"
rel="stylesheet">
<style>
* {
font-family: 'Noto Serif KR', serif;
}
@keyframes blink-effect {
50% {
opacity: 0;
}
}
.member_content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.top_content {
width: 100%;
height: 250px;
background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url('https://coresos-phinf.pstatic.net/a/30hbb6/0_cf7Ud018svcavwo8ineb9ww_oya09y.jpg?type=cover_a640');
background-position: center;
color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.profile {
display: flex;
flex-direction: row;
margin: 30px auto 0px auto;
width: 95%;
max-width: 900px;
border-radius: 30px;
}
.visitor > button {
width: 200px;
height: 50px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: transparent;
border-radius: 50px;
border: 1px solid;
margin: 10px auto 10px auto;
}
.visitor {
display: flex;
flex-direction: column;
display: none;
}
.mypost {
width: 95%;
max-width: 500px;
margin: 20px auto 20px auto;
box-shadow: 0px 0px 3px 0px black;
padding: 20px;
display: none;
}
.mypost > button {
margin-top: 15px;
}
/*회원 상세페이지 사진 크기*/
.col-md-4 > img {
width: 800px;
height: 400px;
}
/*메인 페이지 이름이랑 간단소개 까맣게 하는 부분*/
.card-body1 {
background-color: black;
color: white;
}
.card {
width: 95%;
max-width: 500px;
margin: auto;
}
#card_borer {
border: 5px solid red;
}
#human {
position: fixed;
width: 27%;
height: 480px;
right: 0px;
bottom: 0px;
}
#human_say {
font-size: 30px;
position: fixed;
width: 22%;
height: 380px;
right: 0px;
bottom: 0px;
}
#pig_tail > img {
width: 50px;
height: 50px;
}
#pig_tail {
margin-right: 100px;
animation: blink-effect 1s step-end infinite;
}
#kim {
position: fixed;
width: 25%;
height: 380px;
left: 0px;
bottom: 0px;
}
#blockquote-footer2 {
border: none;
background-color: transparent;
font-weight: bold;
}
</style>
<script>
//각 회원 프로필 넘어가는 부분
$(document).ready(function () {
show_members();
});
function show_members() {
$('#mypost').hide()
$.ajax({
type: "GET",
url: "/home",
data: {},
success: function (response) {
let rows = response['members']
for (let i = 0; i < rows.length; i++) {
let name = rows[i]['name']
let comment = rows[i]['comment']
let img = rows[i]['img']
let temp_html = `<div class="col">
<div class="card h-100" id="card_borer"token interpolation">${name}')">
<img src="${img}" class="card-img-top" alt="..." width="300px" height="300px">
<div class="card-body1">
<h5 class="card-title">${name}<img src="../static/Group2.png"></h5>
<p class="card-text">${comment}</p>
</div>
</div>
</div>`
$('#members').append(temp_html)
}
}
});
}
function member_post(name) {
$.ajax({
type: "POST",
url: '/one-post',
data: {name_give: name},
success: function (response) {
$('#members').empty()
$('#member_detail').empty()
$('#card').empty()
let rows = response['member']
let name = rows['name']
let comment = rows['comment']
let img = rows['img']
let detail = rows['detail']
let temp_html = `<div class="col-md-4">
<img src="${img}" class="img-fluid rounded-start" alt="...">
</div>
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title">${name}</h5>
<p class="card-text">${detail}</p>
<p class="card-text"><small class="text-muted">${comment}</small></p>
</div>
</div>`
$('#member_detail').append(temp_html)
$('#hidden_name_val').attr('value', name)
$('#visitor').show()
let rows_bang = response['members_bang_list']
for (let i = 0; i < rows_bang.length; i++) {
let nick_name = rows_bang[i]['nick_name']
let comment = rows_bang[i]['comment']
let temp_html = `<div class="card-body">
<blockquote class="blockquote mb-0">
<p><input class="blockquote-footer" id="blockquote-footer2" type="text" value="- ${comment}" disabled="true" ></p>
<footer class="blockquote-footer">${nick_name}<cite title="Source Title"></cite></footer>
<button type="button" class="btn btn-dark">수정하기</button>
<button type="button" class="btn btn-dark"token interpolation">${nick_name}')">완료</button>
<buttontoken interpolation">${nick_name}')" type="button" class="btn btn-outline-primary">삭제</button>
</blockquote>`
$('#card').append(temp_html)
}
$('#comment').val('')
$('#nick_name').val('')
}
});
}
function save_comment() {
let name = $('#hidden_name_val').val()
let comment = $('#comment').val()
let nick_name = $('#nick_name').val()
$.ajax({
type: 'POST',
url: '/save-comment',
data: {
name_give: name,
comment_give: comment,
nick_name_give: nick_name
},
success: function (response) {
alert(response['msg'])
member_post(name)
}
})
}
function open_box() {
$('#post-box').show()
}
function close_box() {
$('#post-box').hide()
}
function update() {
$('#blockquote-footer2').attr("disabled", false)
alert("수정하기 창 활성화!")
$('#update_flag').val("ok")
}
function del_comment(nick_name) {
let name = $('#hidden_name_val').val()
$.ajax({
type: "POST",
url: "/comment/del",
data: {nick_name_give: nick_name},
success: function (response) {
alert(response["msg"])
member_post(name)
}
});
}
function update_finish(nick_name) {
let name = $('#hidden_name_val').val()
let comment = $('#blockquote-footer2').val()
let nick_name2 = nick_name
let update_flag = $('#update_flag').val()
if (update_flag!="ok") {
alert("수정한 후 완료를 눌러주세요!!!")
return
}
$.ajax({
type: 'POST',
url: '/comment_update',
data: {
'comment': comment,
'nick_name': nick_name2
},
success: function (response) {
alert(response['msg'])
member_post(name)
$('#update_flag').val("no")
}
})
}
</script>
</head>
<body>
<div class="top_content">
<h1>6789땡</h1>
<img onclick="window.location.reload()" src="../static/Group2.png">
<p id="pig_tail">홈으로!<img src="../static/pig_tail.png"></p>
</div>
<div class="profile" id="profile2">
<img id="human" src="../static/wow.png">
<p id="human_say">사쿠라여..?</p>
<img id="kim" src="../static/kim.png">
<div class="row row-cols-1 row-cols-md-3 g-4" id="members">
</div>
</div>
<div class="member_content" id="member_content2">
<div class="card mb-3" style="max-width: 1000px;">
<div class="row g-0" id="member_detail">
</div>
</div>
<div class="col-md-6">
<div class="visitor" id="visitor">
<button onclick="open_box()">방명록 남기기</button>
</div>
<div class="mypost" id="post-box">
<div class="form-floating mb-3">
<input type="text" class="form-control" id="nick_name" placeholder="url">
<label for="floatingInput">닉네임</label>
</div>
<div class="form-floating">
<textarea class="form-control" placeholder="Leave a comment here" id="comment"
style="height: 100px"></textarea>
<label for="floatingTextarea2">응원댓글</label>
</div>
<input id="hidden_name_val" type="hidden" value="">
<input id="update_flag" type="hidden" value="">
<button onclick="save_comment()" type="button" class="btn btn-dark">응원 남기기</button>
<button onclick="close_box()" type="button" class="btn btn-outline-dark">닫기</button>
</div>
</div>
</div>
<div class="card" id="card">
</div>
</body>
</html>
- app.py
from flask import Flask, render_template, request, jsonify, redirect, url_for
from pymongo import MongoClient
app = Flask(__name__)
client = MongoClient('mongodb+srv://test:sparta@cluster0.cygiufq.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta
@app.route('/')
def home():
return render_template('index.html')
@app.route("/home", methods=["GET"])
def members_get():
member_list = list(db.members.find({},{'_id':False}))
return jsonify({'members': member_list})
@app.route("/one-post", methods=["POST"])
def one_post():
name_receive = request.form['name_give']
member = db.members.find_one({'name': name_receive}, {'_id': False})
members_bang_list = list(db.members_bang.find({'name': name_receive}, {'_id': False}))
# print(members_bang_list)
# return redirect(url_for('one_get', name = name_receive))
return jsonify({'member': member,
'members_bang_list': members_bang_list
})
@app.route("/save-comment", methods=["POST"])
def save_comment():
name_receive = request.form['name_give']
comment_receive = request.form['comment_give']
nick_name_receive = request.form['nick_name_give']
doc = {
'name': name_receive,
'comment': comment_receive,
'nick_name': nick_name_receive
}
db.members_bang.insert_one(doc)
return jsonify({'msg':'저장 완료!'})
@app.route("/comment/del", methods=["POST"])
def homework_del():
nick_name_receive = request.form['nick_name_give']
db.members_bang.delete_one({'nick_name': nick_name_receive})
return jsonify({'msg':'삭제완료!'})
@app.route("/comment_update", methods=["POST"])
def homework_update():
name_receive = request.form['nick_name']
comment_receive = request.form['comment']
db.members_bang.update_one({'nick_name':str(name_receive)},{'$set':{'comment':comment_receive}})
return jsonify({'msg':'수정 완료!'})
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
- 기존 메인 페이지에는 양 옆 공간이 많이 비어있고, 홈 버튼도 없었다.
- 기존 프로젝트 화면
- 변경한 프로젝트 화면
👉 팀 컨셉인 화투에 걸맞게 영화 '타짜'의 등장인물을 삽입하여 재미요소를 추가했고, 공간의 공백을 채울 수 있었다.
👉 홈버튼을 추가하여 새로고침으로만 메인으로 가는 일을 방지했다.
- 추가 코드 부분( 양 옆 이미지 삽입부분 )
<div class="profile" id="profile2">
<img id="human" src="../static/wow.png">
<p id="human_say">사쿠라여..?</p>
<img id="kim" src="../static/kim.png">
<div class="row row-cols-1 row-cols-md-3 g-4" id="members">
</div>
</div>
#human {
position: fixed;
width: 27%;
height: 480px;
right: 0px;
bottom: 0px;
}
#human_say {
font-size: 30px;
position: fixed;
width: 22%;
height: 380px;
right: 0px;
bottom: 0px;
}
#kim {
position: fixed;
width: 25%;
height: 380px;
left: 0px;
bottom: 0px;
}
- 홈 버튼 깜빡깜빡 거리는 효과 및 경로 추가
@keyframes blink-effect {
50% {
opacity: 0;
}
}
#pig_tail > img {
width: 50px;
height: 50px;
}
#pig_tail {
margin-right: 100px;
animation: blink-effect 1s step-end infinite;
}
<img onclick="window.location.reload()" src="../static/Group2.png">
- 수정 기능
👉 새창이 뜨는 것이 아닌 수정 버튼 클릭시 텍스트창이 활성화 되게 하자.
👉 수정하지 않고 완료를 누를 경우 alert을 띄워 return시키자!
- 코드
#blockquote-footer2 {
border: none;
background-color: transparent;
font-weight: bold;
}
function update() {
//수정 텍스트 창 활성화!
$('#blockquote-footer2').attr("disabled", false)
alert("수정하기 창 활성화!")
$('#update_flag').val("ok")
//update_flag를 숨겨놓고 수정하기 창 들어갔을 때 flag변경!
}
function update_finish(nick_name) {
let name = $('#hidden_name_val').val()
let comment = $('#blockquote-footer2').val()
let nick_name2 = nick_name
let update_flag = $('#update_flag').val()
//flag 판단!
if (update_flag!="ok") {
alert("수정한 후 완료를 눌러주세요!!!")
return
}
$.ajax({
type: 'POST',
url: '/comment_update',
data: {
'comment': comment,
'nick_name': nick_name2
},
success: function (response) {
alert(response['msg'])
member_post(name)
//수정 완료 후 flag다시 변경!
$('#update_flag').val("no")
}
})
}
<div class="card-body">
<blockquote class="blockquote mb-0">
<p><input class="blockquote-footer" id="blockquote-footer2" type="text" value="- ${comment}" disabled="true" ></p>
<footer class="blockquote-footer">${nick_name}<cite title="Source Title"></cite></footer>
<button type="button" class="btn btn-dark" onclick="update()">수정하기</button>
<button type="button" class="btn btn-dark" onclick="update_finish('${nick_name}')">완료</button>
<button onclick="del_comment('${nick_name}')" type="button" class="btn btn-outline-primary">삭제</button>
</blockquote>`
- app.py ( update )
@app.route("/comment_update", methods=["POST"])
def homework_update():
name_receive = request.form['nick_name']
comment_receive = request.form['comment']
db.members_bang.update_one({'nick_name':str(name_receive)},{'$set':{'comment':comment_receive}})
return jsonify({'msg':'수정 완료!'})
1) 부족하지만 끝까지 잘 따라와준 팀원들.. 너무 고맙다...
2) 다른 조들의 프로젝트중 기억에 남는 것들이 많았다.
👉 배경음악을 삽입한 조
👉 삭제 작업 시 보통의 조들이 다 닉네임을 파라미터로 사용했는데
이 때 닉네임 중복시 문제가 된다. 다른 조는 Data()를 사용하여 방명록
추가시 날짜로 고유값을 만들어 삭제기능을 활용했는데 참신했고 기능적
으로도 가장 완벽했다.
👉 프로젝트 제작도 물론 중요하지만 그것을 다른 사람들이 알아 듣기
쉽게 설명하는 능력 또한 매우 중요하다는 것을 느꼈다.