조국현

Modify front-end of Search Result:

Change Search Result Image Display (1 row to grid)
const express = require('express');
const session = require('express-session');
const passport = require('passport'), LocalStrategy = require('passport-local').Strategy;
const fs=require('fs');
const router = express.Router()
const fileStore = require('session-file-store')(session);
const app = express();
var flash = require('connect-flash');
var NaverStrategy = require('passport-naver').Strategy;
var KakaoStrategy = require('passport-kakao').Strategy;
//Middle Ware list
app.use(express.urlencoded({extended:false}));
app.use(session({
secret: 'secret key',
resave: false,
saveUninitialized: false,
store : new fileStore()
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
//사용자 정보 세션 읽기, 쓰기
passport.serializeUser(function(user, done) { //쓰기
done(null, user.email);
});
passport.deserializeUser(function(id, done) { //읽기
done(null, id);
});
//첫 페이지
app.get('/',(req,res)=>{
let page = getFirstPage('Passport','This is Passport Example Page',authInfo(req));
res.send(page);
});
//메인 페이지
//Express에서 정적파일(ex: main.html, main.js)들을 사용할경우
//경로를 미리 제시해 주는 부분
app.use(express.static(__dirname + '/main'));
app.get('/main',(req,res)=>{
res.sendFile(__dirname+'/main/main.html')
})
/*--------------------로그인 처리---------------------- */
//로그인 페이지
app.get('/login',(req,res)=>{
let page = getLoginButton(`<a href="/">뒤로가기</a>`);
res.send(page);
});
//로그인 인증 (Passport)
passport.use(new LocalStrategy({
//로그인 페이지 input 태그 내 name
usernameField: 'email',
passwordField: 'password'
},
(id, password, done)=>{
console.log(id,password);
//회원 정보가 한개이상 있을때
if(user){
console.log(user);
//아이디가 다를때
if (id !== user.email){
//alert("존재하는 아이디가 없습니다.")
return done(null, false, { message: '아이디가 다르다' });}
//비밀번호가 다를때
else if (password !== user.password) {
//alert("비밀번호가 다릅니다.");
return done(null, false, { message: '비번이 다르다' });}
//아이디, 비밀번호 모두 맞을 경우
return done(null, user);
}
}));
//로그인 처리 (Passport)
app.post('/login',
passport.authenticate('local', {
//성공시, 메인페이지 이동
//실패시 로그인 페이지 이동
successRedirect: '/',
failureRedirect: '/login',
badRequestMessage : 'Missing username or password.',
failureFlash: true
}));
//로그 아웃 처리
app.get('/logout',(req,res)=>{
//passport 정보 삭제
req.logout();
//서버측 세션 삭제
req.session.destroy(()=>{
//클라이언트 측 세션 암호화 쿠키 삭제
res.cookie('connect.sid','',{maxAge:0});
res.redirect('/');
});
});
//로그인 로그아웃 여부
const authInfo = (req)=>{
if(req.user)
{
return `${user.name} | <a href="/logout">로그아웃</a>`;}
else
return `<a href="/login">로그인</a>`;
}
// naver 로그인
app.get('/naverlogin', passport.authenticate('naver'));
passport.use('naver',new NaverStrategy({
clientID: 'CGVVomc0bhMhzfzbytK2',
clientSecret: 'XHylcjnZxG',
callbackURL: "http://localhost:3000/",
svcType: 0,
authType: 'reauthenticate' // enable re-authentication
},
function(accessToken, refreshToken, profile, done) {
var _profile = profile._json;
console.log(_profile.id);
console.log(_profile.properties.nickname);
}
));
// kakao 로그인
app.get('/kakaologin', passport.authenticate('kakao-login'));
passport.use('kakao-login', new KakaoStrategy({
clientID: '8a854307a99092b4eeeff5e4a79c0ac0',
callbackURL: 'http://localhost:3000/'
},
function (accessToken, refreshToken, profile, done) {
var _profile = profile._json;
console.log(_profile.id);
console.log(_profile.properties.nickname);
}
));
/*--------------------회원가입 처리---------------------- */
//회원가입 처리 Post
var user = {};
app.post('/join',(req,res)=>{
user.email = req.body.email;
user.password = req.body.password;
user.name=req.body.name;
//로그인 페이지로 이동
console.log(user);
res.redirect('/login');
});
//회원가입 페이지 Get
app.get('/join',(req,res)=>{
let page = getPage('회원가입',`
<html>
<head>
<script> function congratulation()
{
alert("새로운 회원이 되신걸 축하합니다!:D \n 레시피 찾을 준비 되셨나요?");
} </script>
<style>
body {
padding-top: 15px;
font-size: 12px
}
.main {
max-width: 320px;
margin-top:300px auto;
margin: 0 auto;
}
.login-or {
position: relative;
font-size: 18px;
color: rgb(7, 7, 7);
margin-top: 10px;
margin-bottom: 10px;
padding-top: 10px;
padding-bottom: 10px;
}
.span-or {
display: block;
position: absolute;
left: 50%;
top: -2px;
margin-left: -25px;
background-color: #fff;
width: 50px;
text-align: center;
}
.hr-or {
background-color: #cdcdcd;
height: 1px;
margin-top: 0px !important;
margin-bottom: 0px !important;
}
h3 {
text-align: center;
line-height: 300%;
margin-top:10px auto;
}
img{
width:320px;
height:150px;
object-fit:cover;
margin-bottom:30px;
}
</style><link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
</head>
<body>
<div class="container">
<div class="row">
<div class="main">
<img src="https://images.unsplash.com/photo-1600577916048-804c9191e36c?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1632&q=80" alt=""/>
<h3>Sign-Up</h3>
<form action="/join" method="post">
<div class="form-group">
<input type="email" class="form-control" name="email" placeholder="email"><br>
</div>
<div class="form-group">
<input type="password" name="password" class="form-control" placeholder="****"><br>
</div>
<div class="form-group">
<input type="name" name="name" class="form-control" placeholder="이름"><br>
</div>
<button type="submit" value="회원가입" class="btn btn btn-primary" onClick="javascript:congratulation()">
회원가입
</button>
</form>
</html>
`,'<a href="/login">뒤로가기</a>');
res.send(page);
});
//포트 연결
app.listen(3000,()=>console.log(`http://localhost:3000`));
//페이지 템플릿
const getPage = (title, content, auth) =>{
return `
<!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">
<title>Passport Example</title>
</head>
<body>
${auth}
<h1>${title}</h1>
<p>${content}</p>
</body>
</html>
`;
}
//로그인 버튼
const getLoginButton = (auth) =>{
return `
<!DOCTYPE html>
<html>
<head>
<style>
body {
padding-top: 15px;
font-size: 12px
}
.main {
max-width: 320px;
margin-top:300px auto;
margin: 0 auto;
}
.login-or {
position: relative;
font-size: 18px;
color: rgb(7, 7, 7);
margin-top: 10px;
margin-bottom: 10px;
padding-top: 10px;
padding-bottom: 10px;
}
.span-or {
display: block;
position: absolute;
left: 50%;
top: -2px;
margin-left: -25px;
background-color: #fff;
width: 50px;
text-align: center;
}
.hr-or {
background-color: #cdcdcd;
height: 1px;
margin-top: 0px !important;
margin-bottom: 0px !important;
}
h3 {
text-align: center;
line-height: 300%;
margin-top:10px auto;
}
img{
width:300px;
height:150px;
object-fit:cover;
margin-bottom:30px;
}
</style>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="https://static.nid.naver.com/js/naverLogin_implicit-1.0.3.js" charset="utf-8"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<title><%= title %></title>
</head>
<body>
${auth}
<div class="container">
<div class="row">
<div class="main">
<img src="https://i.ibb.co/k2zSVcn/142437038-e7b564cb-978a-4018-8834-9984cc3b119e.png" alt=""/>
<!--이미지 아래부분이 살짝 잘림 -->
<!--로그인,회원가입버튼 오른쪽 맞추는게 더 깔끔할거같음 -->
<h3>Login</h3>
<form role="form" method="POST" action="/login">
<div class="form-group">
<label for="userId">아이디</label>
<input type="text" class="form-control" id="email" name="email">
</div>
<div class="form-group">
<label for="password">비밀번호</label>
<input type="password" class="form-control" id="password" name="password">
</div>
<button type="submit" class="btn btn btn-primary">
로그인
</button>
<button type="submit" class="btn btn btn-primary">
<a href="/join" style="color:white;text-decoration-line:none;"> 회원가입</a>
</form>
</div>
</div>
</div>
<div>
<a href="/naverlogin" class="btn btn-block btn-lg btn-success btn_login">Naver</a>
<a href="/kakaologin" class="btn btn-block btn-lg btn-warning btn_login">KaKao</a>
</div>
</body>
</html>
`;
}
//첫 페이지 화면
const getFirstPage =(title, content, auth) =>{
return `
<!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">
<title>Passport Example</title>
</head>
<body>
${auth}
<h1>${title}</h1>
<p>${content}</p>
<div>
<input type="button" value="page move" onClick="movepage()"/>
</div>
<script type="text/javascript">
function movepage(){
location.href="main";
}</script>
</body>
</html>
`;
}
......@@ -4,23 +4,69 @@
box-sizing:border-box;
}
.containter{
position:relative;
width:90%;
height:auto;
max-width:1200px;
margin:0 auto;
margin:0;/*auto*/
color:black;
}
form{
width:50%;
max-width:400px;
width:90%;
border-radius:4px;
margin-top:-10px;
margin-left:10px;
background-color:white;
}
form{
display:inline-block;
}
form input{
.search-result{
/*여러줄로 보여주기 위해선 grid 사용해야하는데, 우선은 영상목록 뽑아보고 결정*/
/*grid로 바꿔놓음. 여러 열로 사진들이 정렬됨*/
display:grid;
grid-gap:25px;
grid-template:auto/repeat(auto-fit,minmax(300px,1fr));
margin-top:50px;
width:100%;
margin-left:265px;
}
/*form input{
width:80%;
padding:10px;
border:none;
outline:none;
font-size:1.8rem;
display:inline-block;
}
form ion-icon{
width:9%;
font-size:3rem;
margin:-15px;
margin-left:10px;
margin-top:15px;
color:rgb(75,75,75);
}
\ No newline at end of file
}*/
.search-box{
margin-left:-10px;
margin-top:10px;
}
img{
width:80%;
height:80%;
object-fit:cover;
}
html{
font-size:12px;
}
section{
min-height:10vh;
width:100%;
display:flex;
padding:100px 0;
}
.brand{
margin-top:-70px;
font-size:4rem;
color:black;
margin-bottom:30px;
}
......
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="style sheet" href="main.css">
</head>
<body>
<section>
<div class="container">
<h1 class="brand">Recipe APP</h1>
<div class="serach-box">
<form>
<input id="name" type="text" placeholder="Search Your Recipe...">
<ion-icon name="search"></ion-icon>
</form>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<section>
<div class="container">
<h1 class="brand">Recipe APP</h1>
<form>
<input id="name" type="text" placeholder="Search Your Recipe...">
<ion-icon name="search"></ion-icon>
</form>
<div class="search-result">
<!--<div class="item">
<img src="./0.jpg" alt="">
<div class="flex-container">
<h1 class="title">This is a recipe</h1>
<a href="#">View Recipe</a>
</div>
<div class="search-result">
<!--<div class="item">
<img src="./0.jpg" alt="">
<div class="flex-container">
<h1 class="title">This is a recipe</h1>
<a href="#">View Recipe</a>
</div>
<p class="item-data">Calories: 120</p>
</div>-->
</div>
</div>
</section>
<script src="./main.js"></script>
<script type="module" src="https://unpkg.com/ionicons@5.5.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule src="https://unpkg.com/ionicons@5.5.2/dist/ionicons/ionicons.js"></script>
</body>
</html>
<p class="item-data">Calories: 120</p>
</div>-->
</div>
</div>
</section>
<script src="./main.js"></script>
<script type="module" src="https://unpkg.com/ionicons@5.5.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule src="https://unpkg.com/ionicons@5.5.2/dist/ionicons/ionicons.js"></script>
</body>
</html>
......
{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},"flash":{"error":["Missing username or password."]},"__lastAccess":1638671002743}
\ No newline at end of file