ksw_devlog
TIL 5일차 본문
미니 프로젝트 발표가 있는 날이었다.
저희 팀이 만든 웹페이지이다.
[html]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous"
/>
-->
<link
rel="stylesheet"
/>
<script
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"
></script>
<link rel="stylesheet" href="../static/style.css" />
<script type="text/javascript" src="../static/main.js"></script>
<title>메인페이지</title>
<link
rel="stylesheet"
/>
</head>
<body>
<div class="header">
<div class="typing-demo">안녕하세요 우리는 송1김4조입니다 :)</div>
</div>
<div class="wrap">
<div id="introduce" class="card1">
<a
target="_blank"
>
<!-- 클릭 시 링크 설정 -->
<div class="card">
<!-- 카드 헤더 -->
<div class="card-header"></div>
<!-- 카드 바디 -->
<div class="card-body">
<!-- 카드 바디 헤더 -->
<div class="card-body-header">
<h1>김유안</h1>
<p class="card-body-hashtag">#울산거주 #비전공자</p>
</div>
<p class="card-body-description">
7조 김유안 입니다.
<br />
조장을 담당하고 있습니다.
</p>
<!-- 카드 바디 본문 -->
</div>
</div>
</a>
</div>
<div id="introduce" class="card2">
<a
target="_blank"
>
<!-- 클릭 시 링크 설정 -->
<div class="card">
<!-- 카드 헤더 -->
<div class="card-header-1"></div>
<!-- 카드 바디 -->
<div class="card-body">
<!-- 카드 바디 헤더 -->
<div class="card-body-header">
<h1>김예슬</h1>
<p class="card-body-hashtag">#디자인 담당 #고영사랑중</p>
</div>
<p class="card-body-description">
7조 김예슬 입니다.
<br />메인 디자인과 방명록을 배너, 방명록 구현을 담당하고
있습니다.
</p>
<!-- 카드 바디 본문 -->
</div>
</div>
</a>
</div>
<div id="introduce" class="card3">
<a
target="_blank"
>
<!-- 클릭 시 링크 설정 -->
<div class="card">
<!-- 카드 헤더 -->
<div class="card-header-2"></div>
<!-- 카드 바디 -->
<div class="card-body">
<!-- 카드 바디 헤더 -->
<div class="card-body-header">
<h1>김승우</h1>
<p class="card-body-hashtag">#집돌이 #비전공자</p>
</div>
<p class="card-body-description">
7조 김승우입니다.
<br />
발표를 담당하고 있습니다.
</p>
<!-- 카드 바디 본문 -->
</div>
</div>
</a>
</div>
<div id="introduce" class="card4">
<a
target="_blank"
>
<!-- 클릭 시 링크 설정 -->
<div class="card">
<!-- 카드 헤더 -->
<div class="card-header-3"></div>
<!-- 카드 바디 -->
<div class="card-body">
<!-- 카드 바디 헤더 -->
<div class="card-body-header">
<h1>김태욱</h1>
<p class="card-body-hashtag">#구파발 대장 #불주먹 #딸깍</p>
</div>
<p class="card-body-description">
7조 김태욱입니다.
<br />
카드, 탭, 개인페이지를 담당하고 있습니다.
</p>
<!-- 카드 바디 본문 -->
</div>
</div>
</a>
</div>
<div id="introduce" class="card5">
<a
target="_blank"
>
<!-- 클릭 시 링크 설정 -->
<div class="card">
<!-- 카드 헤더 -->
<div class="card-header-4"></div>
<!-- 카드 바디 -->
<div class="card-body">
<!-- 카드 바디 헤더 -->
<div class="card-body-header">
<h1>송원석</h1>
<p class="card-body-hashtag">#막내 #서울거주 #비전공자</p>
</div>
<p class="card-body-description">
7조 송원석 입니다.<br />
카드, 탭, 개인페이지를 담당하고 있습니다.
</p>
<!-- 카드 바디 본문 -->
</div>
</div>
</a>
</div>
</div>
<div class="tabs">
<input id="all" type="radio" name="tab_item" checked />
<label class="tab_item" for="all">특징</label>
<input id="programming" type="radio" name="tab_item" />
<label class="tab_item" for="programming">목표</label>
<input id="design" type="radio" name="tab_item" />
<label class="tab_item" for="design">약속</label>
<input id="play" type="radio" name="tab_item" />
<label class="tab_item" for="play">프로젝트 소개</label>
<div class="tab_content" id="all_content"></div>
<div class="tab_content" id="all_content">
<ul>
<li>✔️ 5명 모두가 비전공자입니다:)</li>
<li>✔️ 사전캠프동안 같이 보낸 조원이 많습니다! (무려 3명!)</li>
<li>✔️ 반려동물을 사랑합니다💖</li>
</ul>
</div>
<div class="tab_content" id="programming_content">
<ul>
<li>✔️ 취업을 하자!</li>
<li>✔️ 이직을 하자!</li>
<li>✔️ 기본만 하자!</li>
<li>✔️ 런..하지..말자...^ㅡ^ㅠ</li>
</ul>
</div>
<div class="tab_content" id="design_content">
<ul>
<li>✔️ 시간을 잘 지키자!</li>
<li>✔️ 취업에 성공하자!</li>
<li>✔️ 원활한 소통하기!</li>
<li>✔️ 서로 서로 도와주기!</li>
</ul>
</div>
<div class="tab_content" id="play_content">
<p>
✔️HTML CSS JS Py DB Flask 사용했습니다.
<br />메인테마는 팔레트이고, 각자 다른 색을 가진 사람들이 모였다는
의미 기능은 HTML, CSS, JS, Py, DB, Flask 사용 하이퍼텍스트 추가 카드
호버 기능 애니메이션 기능을 사용
<br />
ps. 열심히 했습니다...^^b
</p>
</div>
</div>
<div class="mypost">
<form action="http://localhost:5000/login" method="post">
<div class="form-floating mb-3">
<input
id="name"
type="text"
class="form-control"
placeholder="닉네임을 입력해주세요"
/>
<label for="floatingInput">닉네임</label>
</div>
<div class="form-floating">
<textarea
id="comment"
class="form-control"
placeholder="코멘트를 남겨주세요"
style="height: 100px"
></textarea>
<label for="floatingTextarea2">코멘트</label>
</div>
</form>
<div class="mybtns">
<button onclick="save_templates()" type="button" class="btn btn-dark">
제출하기
</button>
</div>
</div>
<div class="mypost" id="comment_list"></div>
<div class="footer">
<p>copyright 2022. 7team All rights reserved.</p>
</div>
</body>
</html>
[css]
* {
-ms-overflow-style: none;
scrollbar-width: none;
}
body {
font-family: Arial, Helvetica, sans-serif, "Nanum Gothic";
height: 100%;
}
.header {
width: 100%;
height: 50rem;
margin-bottom: 80px;
background-size: cover;
background-image: url(../static/img/banner.png);
/*This part is important for centering*/
display: grid;
place-items: center;
}
.typing-demo {
width: 50vh;
animation: typing 3s steps(22), blink 2s step-end infinite alternate;
white-space: nowrap;
overflow: hidden;
border-right: 3px solid;
font-family: "Nanum Gothic", monospace;
font-size: 2em;
color: white;
}
@keyframes typing {
from {
width: 0;
}
}
@keyframes blink {
50% {
border-color: transparent;
}
}
/* ---소개 --- */
.wrap {
max-width: 100%;
height: 100%;
margin-top: 200px;
display: flex;
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
}
.wrap .card {
height: 430px;
width: 295px;
border-radius: 15px;
display: inline-block;
margin-top: 30px;
margin-left: 30px;
margin-bottom: 30px;
position: relative;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
overflow: hidden;
}
.card-header {
-webkit-transition: 0.5s;
/*사파리 & 크롬*/
-moz-transition: 0.5s;
/*파이어폭스*/
-ms-transition: 0.5s;
/*인터넷 익스플로러*/
-o-transition: 0.5s;
/*오페라*/
transition: 0.5s;
width: 100%;
height: 270px;
border-radius: 15px 15px 0 0;
background-image: url("images/korea.jpeg");
background-size: 100% 280px;
background-repeat: no-repeat;
background-color: #45e6cd;
}
.card-header-1 {
-webkit-transition: 0.5s;
/*사파리 & 크롬*/
-moz-transition: 0.5s;
/*파이어폭스*/
-ms-transition: 0.5s;
/*인터넷 익스플로러*/
-o-transition: 0.5s;
/*오페라*/
transition: 0.5s;
width: 100%;
height: 270px;
border-radius: 15px 15px 0 0;
background-image: url("images/korea.jpeg");
background-size: 100% 280px;
background-repeat: no-repeat;
background-color: #ceb3ff;
}
.card-header-2 {
-webkit-transition: 0.5s;
/*사파리 & 크롬*/
-moz-transition: 0.5s;
/*파이어폭스*/
-ms-transition: 0.5s;
/*인터넷 익스플로러*/
-o-transition: 0.5s;
/*오페라*/
transition: 0.5s;
width: 100%;
height: 270px;
border-radius: 15px 15px 0 0;
background-image: url("images/korea.jpeg");
background-size: 100% 280px;
background-repeat: no-repeat;
background-color: #fbfbcb;
}
.card-header-3 {
-webkit-transition: 0.5s;
/*사파리 & 크롬*/
-moz-transition: 0.5s;
/*파이어폭스*/
-ms-transition: 0.5s;
/*인터넷 익스플로러*/
-o-transition: 0.5s;
/*오페라*/
transition: 0.5s;
width: 100%;
height: 270px;
border-radius: 15px 15px 0 0;
background-image: url("images/korea.jpeg");
background-size: 100% 280px;
background-repeat: no-repeat;
background-color: #ffc9e2;
}
.card-header-4 {
-webkit-transition: 0.5s;
/*사파리 & 크롬*/
-moz-transition: 0.5s;
/*파이어폭스*/
-ms-transition: 0.5s;
/*인터넷 익스플로러*/
-o-transition: 0.5s;
/*오페라*/
transition: 0.5s;
width: 100%;
height: 270px;
border-radius: 15px 15px 0 0;
background-image: url("images/korea.jpeg");
background-size: 100% 280px;
background-repeat: no-repeat;
background-color: rgb(73, 185, 222);
}
.card-header-5 {
-webkit-transition: 0.5s;
/*사파리 & 크롬*/
-moz-transition: 0.5s;
/*파이어폭스*/
-ms-transition: 0.5s;
/*인터넷 익스플로러*/
-o-transition: 0.5s;
/*오페라*/
transition: 0.5s;
width: 100%;
height: 270px;
border-radius: 15px 15px 0 0;
background-image: url("images/korea.jpeg");
background-size: 100% 280px;
background-repeat: no-repeat;
background-color: #fbe4c6;
}
.card:hover .card-header {
opacity: 0.8;
height: 100px;
}
.card:hover .card-header-1 {
opacity: 0.8;
height: 100px;
}
.card:hover .card-header-2 {
opacity: 0.8;
height: 100px;
}
.card:hover .card-header-3 {
opacity: 0.8;
height: 100px;
}
.card:hover .card-header-4 {
opacity: 0.8;
height: 100px;
}
.card-header-is_closed {
background-color: #ef5a31;
color: #fff;
font-weight: bold;
text-align: center;
float: right;
margin: 15px 15px 0 0;
border-radius: 50%;
font-weight: bold;
padding: 10px 10px;
line-height: 20px;
}
.card-body-header {
color: black;
line-height: 25px;
margin: 10px 20px 0px 20px;
}
.card-body-description {
opacity: 0;
color: black;
line-height: 25px;
-webkit-transition: 0.2s ease-in-out;
/*사파리&크롬*/
-moz-transition: 0.2s ease-in-out;
/*파이어폭스*/
-ms-transition: 0.2s ease-in-out;
/*익스플로러*/
-o-transition: 0.2s ease-in-out;
/*오페라*/
transition: 0.2s ease-in-out;
overflow: hidden;
height: 180px;
margin: 5px 20px;
}
.card:hover .card-body-description {
opacity: 1;
-webkit-transition: 0.5s ease-in-out;
-moz-transition: 0.5s ease-in-out;
-ms-transition: 0.5s ease-in-out;
-o-transition: 0.5s ease-in-out;
transition: 0.5s ease-in-out;
overflow: hidden;
}
.card-body-hashtag {
width : 100%;
margin-right: 100px;
font-style: italic;
}
.card-body-footer {
position: absolute;
margin-top: 15px;
margin-bottom: 6px;
bottom: 0;
width: 314px;
font-size: 14px;
color: #c2e59c;
padding: 0 15px;
}
.tabs {
/* padding-bottom: 40px; */
background-color: #ffffff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
width: 100%;
height: 600px;
margin: 0 auto;
margin-top: 200px;
background-color: ivory;
}
/* 탭 스타일 */
.tab_item {
width: calc(100% / 4);
height: 50px;
border-bottom: 3px solid #c2e59c;
background-color: #f8f8f8;
line-height: 50px;
font-size: 16px;
text-align: center;
color: #333333;
display: block;
float: left;
text-align: center;
font-weight: bold;
transition: all 0s ease;
}
.tab_item:hover {
opacity: 0.75;
}
/* 라디오 버튼 UI삭제*/
input[name="tab_item"] {
display: none;
}
/* 탭 컨텐츠 스타일 */
.tab_content {
display: none;
padding: 40px 40px 0;
clear: both;
overflow: hidden;
text-align: left;
font-size: 40px;
text-decoration: none;
background-size: cover;
}
ul {
list-style: none;
}
/* 선택 된 탭 콘텐츠를 표시 */
#all:checked ~ #all_content,
#programming:checked ~ #programming_content,
#design:checked ~ #design_content,
#play:checked ~ #play_content {
display: block;
}
/* 선택된 탭 스타일 */
.tabs input:checked + .tab_item {
background-color: #c2e59c;
color: #fff;
}
/* -- 방명록 -- */
.mypost {
width: 95%;
max-width: 100%;
margin: 10rem auto 0px auto;
padding: 20px;
box-shadow: 0px 0px 3px 0px gray;
}
.mypost h4 {
margin-top: 2rem;
}
.mypost button {
max-width: 10rem;
}
.mybtns {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-top: 20px;
}
.mybtns > button {
margin-right: 10px;
}
.footer {
margin-top: 10rem;
}
.footer p {
color: black;
text-align: center;
}
#box {
display: flex;
align-items: center;
justify-content: space-evenly;
margin-top: 30px;
}
[javascript]
$(document).ready(function () {
show_templates();
});
function show_templates() {
$.ajax({
type: "GET",
url: "/templates",
data: {},
success: function (response) {
console.log("성공");
let rows = response["comments"];
for (let i = 0; i < rows.length; i++) {
let name = rows[i]["name"];
let comment = rows[i]["comment"];
let num = rows[i]["num"];
let done = rows[i]["done"];
let temp_html = ``;
if (done == 0) {
temp_html = `
<h4>😊 ${name}</h4>
<p>${comment}</p>
<button onclick="done_templates(${num})" type="button" class="btn btn-outline-primary">댓글 지우기</button>
`;
}
$("#comment_list").append(temp_html);
}
},
});
}
function save_templates() {
let name = $("#name").val();
let comment = $("#comment").val();
$.ajax({
type: "POST",
url: "/templates",
data: { name_give: name, comment_give: comment },
success: function (response) {
alert(response["msg"]);
window.location.reload();
},
});
}
function done_templates(num) {
$.ajax({
type: "POST",
url: "/templates/done",
data: { num_give: num },
success: function (response) {
alert(response["msg"]);
window.location.reload();
},
});
}
[app.py]
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
from pymongo import MongoClient
import certifi
ca = certifi.where()
from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.3ytzhsg.mongodb.net/Cluster0?retryWrites=true&w=majority',tlsCAFile=ca)
db = client.dbsparta
@app.route('/')
def home():
return render_template('index.html')
@app.route("/templates", methods=["POST"])
def templates_post():
name_receive = request.form['name_give']
comment_receive = request.form['comment_give']
comment_list = list(db.templates.find({}, {'_id': False}))
count = len(comment_list) + 1
doc = {
'num': count,
'name': name_receive,
'comment': comment_receive,
'done': 0
}
db.templates.insert_one(doc)
return jsonify({'msg': '소중한 의견 감사합니다!'})
@app.route("/templates/done", methods=["POST"])
def templates_done():
num_receive = request.form['num_give']
db.templates.update_one({'num': int(num_receive)}, {'$set': {'done': 1}})
return jsonify({'msg': '삭제했습니다:)'})
@app.route("/templates", methods=["GET"])
def templates_get():
comment_list = list(db.templates.find({}, {'_id': False}))
return jsonify({'comments': comment_list})
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
우리 팀 최종 코드이다.
[프로젝트 회고]
팀원들이 다 같이 비전공자였지만 조금 더 경험이 있거나 더 코딩을 접해 본 사람들이 더 빠르게 프로젝트를 수행한다는 것을 느꼈다. 주말을 이용하여 더 따라가서 개발 역량을 늘릴 것이다.