스파르타 코딩클럽_내일 배움 캠프 spring 트랙 6기
[프로젝트] 팀 소개페이지 미니 프로젝트
2023.05.15 ~ 2023.05.19
<프로젝트 정보>
개발도구 : Visual Studio Code
프로그래밍 언어 : Python
데이터베이스 : MongoDB
프레임워크 : Flask
라이브러리 : venv
와이어프레임 : Figma
<프로젝트 내용>
기존에 작성했던 파일을 git을 사용하여 팀원들이 만든 페이지를 합쳤다.
완성된 페이지는 아니지만 git, branch를 사용하는 방법을 익혔고, 많이 사용해보는 중이다.
<index.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">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<title>Document</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<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://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<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=Alfa+Slab+One&display=swap" rel="stylesheet">
<title>Member</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR&display=swap');
* {
font-family: 'Noto Sans KR', sans-serif;
}
.wrap {
/* 웹종반 1-9 강의 참고 */
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
width: 1320px;
height: 1500px;
margin: 0px auto 0px auto;
}
#main_banner {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 1320px;
height: 300px;
background-size: cover;
background-repeat: no-repeat;
}
#main_title {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 0px 0px 10px 0;
font-size: 80px;
font-weight: bold;
font-family: 'Alfa Slab One', cursive;
letter-spacing: 6px;
color: white;
text-shadow: -1px 0 #000, 0 2.5px #000, 1.5px 0 #000, 0 -1px #000;
}
#nav {
width: 1320px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin: 0px;
border: 0.5px solid gainsboro;
}
div>ol {
display: flex;
flex-direction: row;
align-items: right;
justify-content: right;
margin-right: 40px;
}
div>ol>li {
margin: 0px 30px 0px 30px;
list-style: none;
font-weight: bold;
height: 25px;
font-size: 24px;
}
/* 여기까지 팀원1 */
/* 아래는 팀원2 */
.teamtitle {
text-align: center;
}
.team-body {
background-color: grey;
width: 300px;
height: 100px;
margin: 20px auto 80px auto;
}
.card-header {
font-size: x-large;
text-align: center;
}
.card-text {
text-align: center;
}
.team-text {
margin: 20px auto 20px auto;
}
.card-title {
color: white;
text-align: center;
background-color: dimgrey;
}
.teamintro {
margin-bottom: 50px;
}
/* 여기까지는 팀원2 */
/* 아래는 팀원3 */
.title {
padding: 30px;
}
.name {
margin: auto;
}
.card {
border-color: white;
}
.click_img {
width: 200px;
height: 200px;
border-radius: 100%;
}
/* 아래는 팀장 : guset book*/
/* 여기까지 팀장 */
</style>
<script type="text/javascript">
function profile() {
popupWindow = window.open();
popupWindow.resizeTo(430, 660);
popupWindow.onresize = (_ => {
popupWindow.resizeTo(430, 660);
})
}
function getButton() {
fetch("/test").then(res => res.json()).then(data => {
alert(data['msg'])
})
}
function postButton() {
let formData = new FormData();
formData.append("title_give", "블랙팬서");
fetch("/test", { method: "POST", body: formData }).then(res => res.json()).then(data => {
alert(data['msg'])
})
}
function save_comment() {
let name = $('#name').val()
let comment = $('#comment').val()
let formData = new FormData();
formData.append("name_give", name);
formData.append("comment_give", comment);
fetch('/guestbook', { method: "POST", body: formData, }).then((res) => res.json()).then((data) => {
alert(data["msg"]);
window.location.reload()
});
}
$(document).ready(function () {
show_comment();
});
function show_comment() {
fetch('/guestbook').then((res) => res.json()).then((data) => {
let rows = data['result']
$('#comment-list').empty()
rows.forEach((a) => {
let name = a['name']
let comment = a['comment']
let temp_html = `<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<div style="width:100px; height:70px; border:1px solid grey; float:left;">
${comment}
</div>
<div style="width:150px; height:70px; border:1px solid grey; float:right;">
<footer class="blockquote-footer">${name}</footer>
</div>
</blockquote>
</div>
</div>`
$('#comment-list').append(temp_html)
})
})
}
</script>
</head>
<body>
<div class="wrap">
<div id="main_banner">
<div>
<div>
<h1 id="main_title">
<p>E 1 I 4</p>
</h1>
</div>
<div>
<h1>
<p>   </p>
</h1>
</div>
</div>
</div>
<div id="nav">
<ol>
<li>E1I4 Intro</li>
<li>Member</li>
<li>Design_Empty</li>
<li>Guest Book</li>
</ol>
</div>
<div class="teamintro" style="align-items: center">
<div class="card-body">
<img src="/static/image/banner.png" class="card-img-top" alt="...">
<h5 class="card-text">안녕하세요, 저희는 E 1명과 I 4명으로 구성된 화목한 5남매(+1) 입니다 🙋🏻♂️🧚🏻♂️👩🏻🐶👩🏻🦰👰🏻♀️
</h5>
<h5>모두 비전공자이고 나이도 다르지만, 프로젝트를 완성하고자 의기투합하여 한 마음 한 뜻으로 똘똘 뭉쳤습니다 V</h5>
</div>
</div>
<div class="teaminfo">
<div class="row row-cols-1 row-cols-md-3 g-4">
<div class="col">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">TMI / 우리팀의 특징</h5>
<img src="/static/image/Frame 6.png" class="card-img-top" alt="...">
</div>
</div>
</div>
<div class="col">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">궁극적인 목표</h5>
<P></P>
<p class="card-text"> ✔ Git 사용법 숙지</p>
<p class="card-text"> ✔ 내일배움캠프 포기하지 않고 끝까지 수료하기!</p>
<p class="card-text"> ✔ 프론트와 백의 연결관계 이해하기</p>
<p class="card-text"> ✔ POST, GET 사용법 마스터하기</p>
<p class="card-text"> ✔ ch1 미니 project 구조 정확히 이해하고 만들기</p>
</div>
</div>
</div>
<div class="col">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">우리팀의 규칙</h5>
<P></P>
<p class="card-text"> ✔ 건강이 제일 중요! 밥 세끼 꼬박꼬박 잘 챙겨먹기💕</p>
<p class="card-text"> ✔ 막히는 부분이 있다면 혼자 머리싸매지 말고 팀원과 같이 해결!</p>
<p class="card-text"> ✔ 13-14시 점심 시간, 18-19시 저녁 시간 🐷</p>
<p class="card-text"> ✔ 20시 Git Merge 후 팀원들과 함께 코드리뷰 , 상세 피드백하기</p>
<p class="card-text"> ✔ 20시 40분 개발 일지(TIL) 작성하고 퇴실시간 맞춰 퇴실하기</p>
</div>
</div>
</div>
</div>
</div>
<div class="title">
<h2>MEMBER</h2>
</div>
<div class="member">
<div class="row row-cols-1 row-cols-md-5 g-2">
<div class="col">
<div class="card h-100">
<img src="https://ca.slack-edge.com/T043597JK8V-U053UK80VR8-cbc4d9e1783b-512" class="click_img"
alt="...">
<div class="name">
<h3>팀장</h3>
</div>
</div>
</div>
<div class="col">
<div class="card h-100">
<img src="https://ca.slack-edge.com/T043597JK8V-U051WD9LCNP-45ff45329ac6-512"
class="click_img alt=" ... onclick="profile()">
<div class="name">
<h3>팀원</h3>
</div>
</div>
</div>
<div class="col">
<div class="card h-100">
<img src="https://ca.slack-edge.com/T043597JK8V-U0532LT9LLE-58e265f5a665-512" class="click_img"
alt="..." onclick="profile()">
<div class="name">
<h3>팀원</h3>
</div>
</div>
</div>
<div class="col">
<div class="card h-100">
<img src="https://ca.slack-edge.com/T043597JK8V-U052A5UUG06-fd387358fc87-512" class="click_img"
alt="..." onclick="profile()">
<div class="name">
<h3>팀원</h3>
</div>
</div>
</div>
<div class="col">
<div class="card h-100">
<img src="https://ca.slack-edge.com/T043597JK8V-U053QSM8MT4-e435cca492ea-512" class="click_img"
alt="..." onclick="profile()">
<div class="name">
<h3>팀원</h3>
</div>
</div>
</div>
</div>
</div>
<div>
<button onclick="location.href='/myprofile/new'">상세페이지</button>
</div>
<div class="mypic">
<h1>GUEST BOOK</h1>
</div>
<div class="mypost">
<div class="form-floating mb-3">
<input type="text" class="form-control" id="name" placeholder="닉네임" />
</div>
<div class="form-floating">
<textarea class="form-control" placeholder="방명록을 작성하세요" id="comment" style="height: 100px"></textarea>
</div>
<button onclick="save_comment()" type="button" class="btn btn-dark">
댓글 남기기
</button>
</div>
<div class="mycards" id="comment-list">
<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>새로운 앨범 너무 멋져요!</p>
<footer class="blockquote-footer">호빵맨</footer>
</blockquote>
</div>
</div>
<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>새로운 앨범 너무 멋져요!</p>
<footer class="blockquote-footer">호빵맨</footer>
</blockquote>
</div>
</div>
<div class="card">
<div class="card-body">
<blockquote class="blockquote mb-0">
<p>새로운 앨범 너무 멋져요!</p>
<footer class="blockquote-footer">호빵맨</footer>
</blockquote>
</div>
</div>
</div>
</div>
</body>
</html>
<sub.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 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>
<link href="https://fonts.googleapis.com/css2?family=Gowun+Batang:wght@400;700&display=swap" rel="stylesheet" />
<title>상세페이지</title>
<style>
::selection {
user-select: none
/* 드래그 못하게 */
}
::-webkit-scrollbar {
width: 10px;
}
::-webkit-scrollbar-thumb {
background-color: #2f3542;
border-radius: 10px;
background-clip: padding-box;
border: 2px solid transparent;
}
.container::-webkit-scrollbar-track {
background-color: grey;
border-radius: 10px;
box-shadow: inset 0px 0px 5px white;
}
.imoge {
position: absolute;
width: 49px;
height: 41px;
left: 523px;
top: 151px;
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-size: 70px;
line-height: 85px;
/* background-color: red; */
text-shadow: 0px 8px 20px rgba(0, 0, 0, 0.25);
}
.photo {
box-sizing: border-box;
position: absolute;
width: 293px;
height: 283px;
left: 523px;
top: 248px;
box-shadow: 0px 8px 20px rgba(0, 0, 0, 0.25);
border-radius: 50px;
background-image: url('https://cdn.pixabay.com/photo/2023/04/03/03/20/plant-7895897_1280.jpg');
background-repeat: no-repeat;
background-position: center;
}
.name {
position: absolute;
width: 250px;
height: 77px;
left: 890px;
top: 296px;
font-family: 'Inter';
font-weight: 600;
font-size: 60px;
line-height: 77px;
}
.about_me_area {
position: absolute;
width: 288px;
height: 158px;
left: 905px;
top: 373px;
background: transparent;
}
.about_me_text {
font-style: normal;
font-weight: 400;
font-size: 16px;
line-height: 20px;
}
#tmi_area {
position: absolute;
width: 864px;
height: 323px;
left: 523px;
top: 566px;
background: rgba(217, 217, 217, 0.22);
box-shadow: 0px 8px 20px rgba(0, 0, 0, 0.25);
border-radius: 80px;
}
.profile {
position: absolute;
left: 80px;
top: 40px;
font-family: 'Roboto';
font-style: normal;
font-weight: 567;
font-size: 48px;
line-height: 56px;
font-variant: small-caps;
}
.text {
background-color: transparent;
position: absolute;
left: 100px;
top: 100px;
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-size: 17px;
}
.text:hover {
outline: none;
cursor: pointer
}
summary::marker {
content: "+ ";
font-family: monospace;
font-size: 16px;
}
details[open] summary::marker {
content: "- ";
}
.button {
border: none;
position: absolute;
width: 133px;
height: 53px;
left: 1262px;
top: 911px;
background: #4A99E9;
color: white;
box-shadow: 0px 8px 10px rgba(0, 0, 0, 0.25);
border-radius: 50px;
}
.button:hover {
background: #3E81C4;
}
.button:active {
transform: scale(0.95);
}
</style>
<script>
window.addEventListener('DOMContentLoaded', function () {
document.querySelectorAll('details').forEach(function (item) {
item.addEventListener("toggle", event => {
let toggled = event.target;
if (toggled.attributes.open) {
document.querySelectorAll('details[open]').forEach(function (opened) {
if (toggled != opened)
opened.removeAttribute('open');
});
}
})
});
});
$(document).ready(function () {
show_profiles();
console.log("ready")
});
function show_profiles() {
fetch('/myprofile/new1').then(res => res.json()).then(data => {
let rows = data['result']
console.log(rows)
$('#container').empty();
rows.forEach((a) => {
let imoge = a['imoge']
let photo = a['photo']
let name = a['name']
let about_me = a['about_me']
let q1 = a['q1']
let q2 = a['q2']
let q3 = a['q3']
let q4 = a['q4']
let temp_html = `<div class="container" id="container">
<div>
<text class="imoge">${imoge}</text>
</div>
<div class="photo">${photo}</div>
<div>
<text id="name" class="name">${name}</text>
</div>
<div id="test" class="about_me_area">
<text class="about_me_text">${about_me}</text>
</div>
<div id="tmi_area">
<text class="profile">
Profile
</text>
<div class="text">
<details>
<summary>사용할 수 있는 언어</summary>
<p>${q1}</p>
</details>
<details>
<summary>자신의 장점</summary>
<p>${q2}</p>
</details>
<details>
<summary>나의 MBTI</summary>
<p>${q3}</p>
</details>
<details>
<summary>TMI</summary>
<p>${q4}</p>
</details>
</div>
</div>
<button type="button" onclick="location.href='http://localhost:5000/' " class="button">뒤로가기</button>
</div>`
$('#container').append(temp_html)
})
})
}
</script>
</head>
<body>
<div class="container" id="container">
<div>
<text class="imoge">🐶</text>
</div>
<div class="photo"></div>
<div>
<text class="name">이름</text>
</div>
<div id="test" class="about_me_area">
<text class="about_me_text">자기소개</text>
</div>
<div id="tmi_area">
<text class="profile">
Profile
</text>
<div class="text">
<details>
<summary>사용할 수 있는 언어</summary>
<p>내부에 넣을 내용을 입력해주세요</p>
</details>
<details>
<summary>자신의 장점</summary>
<p>내부에 넣을 내용을 입력해주세요</p>
</details>
<details>
<summary>나의 MBTI</summary>
<p>내부에 넣을 내용을 입력해주세요</p>
</details>
<details>
<summary>TMI</summary>
<p>내부에 넣을 내용을 입력해주세요</p>
</details>
</div>
</div>
<button type="button" onclick="location.href='http://localhost:5000/' " class="button">뒤로가기</button>
</div>
</body>
<app.py>
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
# mongoDB는 OOO - 본인 mongoDB로 변경하기
from pymongo import MongoClient
client = MongoClient('mongodb+srv://sparta:test@cluster0.ziorpfn.mongodb.net/?retryWrites=true&w=majority')
db = client.dbsparta
@app.route('/')
def home():
return render_template('index.html')
@app.route("/myprofile/new", methods=["GET"])
def post_profile():
return render_template('sub.html')
@app.route("/myprofile/new1", methods=["GET"])
def profiles_get():
all_profiles = list(db.profiles.find({}, {'_id': False}))
return jsonify({'result': all_profiles})
@app.route('/sub')
def sub():
return render_template('sub.html')
@app.route('/test', methods=['GET'])
def test_get():
title_receive = request.args.get('title_give')
print(title_receive)
return jsonify({'result':'success', 'msg': '이 요청은 GET!'})
# 방명록 저장하는 곳
@app.route('/guestbook', methods=['POST'])
def guestbook_post():
name_receive = request.form['name_give']
comment_receive = request.form['comment_give']
doc = {
'name' :name_receive,
'comment' : comment_receive
}
db.guestbook_comments.insert_one(doc)
return jsonify({'msg': '방명록이 등록되었습니다!'})
# 방명록 mongDB에서 index.html로 데이터 전송
@app.route("/guestbook", methods=["GET"])
def guestbook_get():
all_comments = list(db.guestbook_comments.find({},{'_id':False}))
#db.user.find 에서 users 바꿔야한다 일단 강의대로 fan으로 저장함
#fan -> guestbool_comments 로 변경
return jsonify({'result': all_comments})
# mac 사용자는 포트5001로 변경하세요.
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
'🏕️내일배움캠프 > 📂팀원 소개 페이지 만들기(23.05.15)' 카테고리의 다른 글
귀여운 Spring A반 5조 모음 :) (0) | 2023.05.19 |
---|---|
팀원 소개 페이지 5일차-코드 발표 및 회고 (1) | 2023.05.19 |
팀원 소개 페이지 4일차-몽고 DB에 개인 데이터 저장하고 연결해보기+멤버 이미지 연결 코드 수정(git 사용) (0) | 2023.05.18 |
팀원 소개 페이지 2일차-멤버 소개 html/css/onclick (2) | 2023.05.16 |
팀원 소개 페이지 1일차_S.A.와 와이어프레임 제작 (0) | 2023.05.15 |