Skip to content

Latest commit

 

History

History
1753 lines (1493 loc) · 57.2 KB

sandy_sc.md

File metadata and controls

1753 lines (1493 loc) · 57.2 KB

<routes/db/pool.js>

// routes/db/pool.js
// Pool 생성

// 1. 모듈 가져오기 (이 코드는 서버가 가동되면 1회만 수행) -> 설치
const genericPool = require('generic-pool')
const mysql = require('mysql')

// 2. 풀링 생성
const factory = {
    create : () => {
        var connection = mysql.createConnection({
            host : 'localhost',
            user : 'root',
            password : '12341234',
            database : 'sandydb'
        })
        // DB와 연결
        connection.connect()
        // 연결객체 리턴
        return connection
    },
    destroy : ( db_session ) => {
        // db_session : 연결 커넥션
        db_session.end() // 연결 종료
    }
}

const opts = {
    // 서버가 가동되면 최소 50개의 커넥션을 준비
    // 요청이 증가하면 계속 커넥션을 증가시킨다 -> 최대 100까지
    max : 100,
    min : 50
}

const myPool = genericPool.createPool(factory, opts)

// 3. 풀링 해제
// 노드 서버가 종료되기 직전의 이벤트를 잡아서
// 풀링이 가지고 있는 DB 연결 세션을 다 반납한다(끊어준다)
process.on('beforeExit', ()=>{
    myPool.drain().then(()=>{
        // 풀링 해제 수행
        myPool.clear()
    })
})

// 예외 상황이 발생되면 try~catch, 이벤트로 캐치
process.on('uncaughtException', (err)=>{
    // 로그 처리를 하던, 관리자에게 통보
    console.log(new Date(), err)
})

// 4. 대표 모듈화
module.exports = myPool

<routes/db/index.js>

// routes/db/index.js
// db 모듈

// mysql 모듈을 이용하여 노드에서 mysql 엑세스, 쿼리 수행
// 모듈 가져오기
const mysql = require('mysql')
const pool = require('./pool')

// 풀 객체 가져오기
// 풀 적용하여 쿼리 수행
// 1. 커넥션 획득  2. 쿼리  3. 커넥션 반납

// 닉네임 중복 여부 조회
exports.checkExistNickname = ({nickName}, cb) => {

  const db_session = pool.acquire()

  db_session
  .then((connection) => {
      let sql = `select * from users where nickName =?`

      connection.query(sql, [nickName], (error, rows)=> {
          pool.release(connection)
          cb(error, rows)
      })
  })
  .catch((error)=>{
      cb(error)
  })
}

// 사용자(user) 추가
exports.registerUser = ( {userName, nickName, upw}, cb ) => {

  const db_session = pool.acquire()

  db_session
  .then((connection) => {
      let sql = `insert into users (userName, nickName, upw) values (?, ?, ?);`

      connection.query(sql, [userName, nickName, upw], (error, rows)=> {
          pool.release(connection)
          cb(error, rows)
      })
  })
  .catch((error)=>{
      cb(error)
  })
}

// 로그인 정보 조회
exports.checkLoginInfo = ( {nickName, upw}, cb ) => {

  const db_session = pool.acquire()

  db_session
  .then((connection) => {
      let sql = `select * from users where nickName =? and upw =?;`

      connection.query(sql, [nickName, upw], (error, rows)=> {
          pool.release(connection)
          cb(error, rows)
      })
  })
  .catch((error)=>{
      cb(error)
  })
}

// 전체 할일 조회
exports.checkTodo = (cb) => {

  const db_session = pool.acquire()

  db_session
  .then((connection) => {
      let sql =   `select * from tasks;`

      connection.query(sql, (error, rows)=> {
          pool.release(connection)
          cb(error, rows)
      })
  })
  .catch((error)=>{
      cb(error)
  })
}

// (select-option 목록을 위한) 전체 사용자 조회
exports.checkAllUser = (cb) => {

  const db_session = pool.acquire()

  db_session
  .then((connection) => {
      let sql =   `select nickName from users;`

      connection.query(sql, (error, rows)=> {
          pool.release(connection)
          cb(error, rows)
      })
  })
  .catch((error)=>{
      cb(error)
  })
}

// 할일 등록
exports.registerTodo = ({title, name, sequence}, cb ) => {

  const db_session = pool.acquire()

  db_session
  .then((connection) => {
      let sql = `insert into tasks (title, name, sequence) values(?, ?, ?);`

      connection.query(sql, [title, name, sequence], (error, rows)=> {
          pool.release(connection)
          cb(error, rows)
      })
  })
  .catch((error)=>{
      cb(error)
  })
}

// id(고유값)으로 타입 값 확인
exports.checkTodoType = ({id}, cb) => {

  const db_session = pool.acquire()

  db_session
  .then((connection) => {
      let sql = `select type from tasks where id=?`

      connection.query(sql, [id], (error, rows)=> {
          pool.release(connection)
          cb(error, rows)
      })
  })
  .catch((error)=>{
      cb(error)
  })
}

// ex) update tasks set type='DOING' where id=9;
exports.updateTodoType = ( {type, id}, cb ) => {

  const db_session = pool.acquire()

  db_session
  .then((connection) => {
      let sql = `update tasks set type=? where id=?`

      connection.query(sql, [type, id], (error, rows)=> {
          pool.release(connection)
          cb(error, rows)
      })
  })
  .catch((error)=>{
      cb(error)
  })  
}

// 사용자(User) 조회
exports.selectUser=(cb)=>{

    const db_session = pool.acquire()

    db_session
    .then((connection)=>{
      let sql = `select * from users where uid = ? and upw = ?;`
      connection.query(sql, [uid, upw], (error, rows)=>{                      
        connection.end()
        cb(error, rows)
        // console.log(rows)  
      })
    })
    .catch((err)=>{   
      cb(err)
    })

}

exports.selectTypes=(cb)=>{

    const db_session = pool.acquire()

    db_session
    .then((connection)=>{
      let sql = `select * from tasks`
      connection.query(sql, (error, rows)=>{                      
        connection.end()
        cb(error, rows)
        // console.log(rows)  
      })
    })
    .catch((err)=>{   
      cb(err)
    })

}

// 'ARCHIVE' 상태 조회
exports.selectArchieveTypes=(cb)=>{

    const db_session = pool.acquire()

    db_session
    .then((connection)=>{
      let sql = `select * from tasks where type = 'ARCHIVE'`
      connection.query(sql, (error, rows)=>{                      
        connection.end()
        cb(error, rows)
        // console.log(rows)  
      })
    })
    .catch((err)=>{   
      cb(err)
    })
}

// 할일 삭제
exports.deleteArchieveTypes = ({id}, cb) => {

    const db_session = pool.acquire()

    db_session
    .then((connection) => {
        let sql = `delete from tasks where id=?`

        connection.query(sql, [id], (error, rows)=> {
            pool.release(connection)
            cb(error, rows)
        })
    })
    .catch((error)=>{
        cb(error)
    })
}

<routes/db/test.js>

// routes/db/test.js
// DB 연결 테스트

const mysql = require('mysql')

exports.testDB = (cb) => {
  var connection = mysql.createConnection({
    host : 'localhost',
    user : 'root',
    password : '12341234',
    database : 'sandydb'
  })

  connection.connect((err)=>{
    if(err) {
        console.log('접속 오류', err)
    } else {
        console.log('접속 성공')
        connection.end((e)=>{
            console.log('접속 종료?', e)
        })
    }
  });
}  

<routes/index.js>

// routes/index.js

var express = require('express');
// 라우터 생성
var router = express.Router();
let db = require('./db');

// http://localhost:3000
router.get('/', function(req, res, next) {
   // views/index.ejs
   res.render('index')
});

// http://localhost:3000/board
// ~/board
router.get('/board', function(req, res, next) {

    // 전체 사용자 조회
    db.checkAllUser((err, names)=> {

        // 전체 할일 조회
        db.checkTodo((err, rows)=> {

            let userName =[]    
            for(i in rows){
              userName.push(rows[i].name)
            }

            userName = userName.filter(function(item, pos, self) {
                              return self.indexOf(item) == pos;
            })
            res.render('board', {names: names, rows:rows, userName: userName})
        })
    })    
});

router.post('/boardData', function(req, res, next) {

    db.checkAllUser((err, names)=> {
        db.checkTodo((err, rows)=> {
            res.json(rows)
        })
    })    
});

// ~/register
router.get('/register', (req, res, next)=>{

    db.checkAllUser((err, rows)=>{

        if(err) {
            res.render('error')
        } else {
            console.log(rows)
            res.render('register', {rows:rows})
        }
    })

})

// ~/register
router.post('/register', (req, res, next)=>{

    let title = req.body.title
    let name = req.body.name
    let sequence = req.body.sequence
    console.log(title, name, sequence)

    db.registerTodo({title, name, sequence}, (err, rows)=>{

        if(err) {
            res.render('error')
        } else {
            console.log(rows)
            res.redirect('board')
        }
    })
})

// ~/update
router.post('/update', (req, res, next)=>{

    let id = req.body.updateData
    console.log('id : ', id)

    db.checkTodoType({id : id}, (err, rows)=>{
        console.log(rows)

        if(err) {
            res.render('error')
        } else {
            if(rows[0].type == 'TODO') {
                db.updateTodoType({type:'DOING', id:id}, (err, rows)=>{
                    db.selectTypes( (err, rows)=>{
                        res.json(rows)
                    } )
                })
            } else if(rows[0].type == 'DOING') {
                db.updateTodoType({type:'DONE', id:id}, (err, rows)=>{
                    db.selectTypes( (err, rows)=>{
                        res.json(rows)
                    } )
                })
            } else if(rows[0].type == 'DONE') {
                db.updateTodoType({type:'ARCHIVE', id:id}, (err, rows)=>{
                    db.selectTypes( (err, rows)=>{
                        res.json(rows)
                    } )
                })
            }
        }
    })
})

router.get('/updateArchieve', (req, res, next)=>{

    let id = req.query.archiveData
    console.log(id)

    db.checkTodoType({id:id}, (err, rows)=>{
        if(err) {
            res.render('error')
        } else {
            db.updateTodoType({type:'ARCHIVE', id:id}, (err, rows)=>{
                db.selectTypes( (err, rows)=>{
                    res.json(rows)
                } )
            })
        }
    })
})


router.get('/search', (req, res, next)=>{

    let userData= req.query.userName
    // console.log(userData)

    db.selectTypes( (err, rows)=>{
      res.json(rows)
    } )

});

router.get('/list', (req, res, next)=>{

    db.selectTypes( (err, rows)=>{
        res.json(rows)
        console.log(rows)
    } )

});

router.get('/archive', (req, res, next)=>{

    db.selectArchieveTypes((err,rows)=>{
        res.render('ARCHIVE', {rows:rows})
        console.log(rows)
    })
});

router.get('/remove', (req, res, next)=>{

    let id = req.query.updateData
    console.log(id)

    db.deleteArchieveTypes({id:id}, (err, rows)=>{
        if(err) {
            res.render('error')
        } else {
            db.selectArchieveTypes( (err, rows)=>{
                res.json(rows)
            } )
        }
    })

})

module.exports = router;

<routes/users.js>

// routes/users.js

var express = require('express');
var router = express.Router();
var db = require('./db');

// ~/users
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});

// 회원가입 처리
// ~/users/join (get 방식)으로 들어온 요청 처리
router.get('/join', (req, res, next)=>{
  res.render('join')
})

// ~/users/join (post 방식)으로 들어온 요청 처리
router.post('/join', (req, res, next)=> {

  // 닉네임 중복 확인
  let nickName = req.body.nickName

  db.checkExistNickname({nickName:nickName}, (err, rows)=>{

    if(err) {
      res.render('error')
    } else {
        if(rows.length==0) {  // 없는 닉네임 → 회원가입 진행
          console.log('회원가입 가능')
          console.log(rows)

          let userName = req.body.userName
          let nickName = req.body.nickName
          let upw = req.body.upw

          db.registerUser({userName:userName, nickName:nickName, upw:upw}, (err,rows)=>{
            if(err) {
              res.render('error')
            } else {
              console.log(rows)
              res.redirect('login')
            }
          })
        } else {  // 있는 닉네임
          console.log('회원가입 불가능')
          console.log(rows)
        }
    }
  })
})

// 로그인 처리
// ~/users/login (get 방식)으로 들어온 요청 처리
router.get('/login', (req, res, next)=>{
  res.render('login')
})

// ~/users/login (post 방식)으로 들어온 요청 처리
router.post('/login', (req, res, next)=> {

  let nickName = req.body.nickName
  let upw = req.body.upw
  console.log(nickName, upw)

  db.checkLoginInfo({nickName:nickName, upw:upw}, (err, rows)=>{

      if(err) {
        res.render('error')
      }
      else {
        if(rows.length==0) {
          // console.log('로그인 실패')
          res.render('loginFail')
        } else {

          // 로그인 성공
           console.log('로그인 성공')

          // 세션 생성
          req.session.nickName = nickName
          console.log(req.session.nickName)

          res.redirect('/board')
        }
      }
  })
})

  // 로그아웃 처리
  router.get('/logout', (req, res, next)=>{

    // 세션 제거
    req.session.nickName = null  
    // 홈페이지로 이동
    res.redirect('/users/login')
})


// ~/users/check
router.get('/check', (req, res, next)=>{

  let nickName = req.query.nickName
  // console.log(checkNickName)

  db.checkExistNickname({nickName : nickName}, (err, rows)=>{
      console.log(rows)
      res.json(rows)
  })
})

module.exports = router;

<views/index.ejs>

<!-- views/index.ejs -->
<!-- 시작 화면 -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport"
    content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, width=device-width" />
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="description" content="">
  <meta name="author" content="">
  <script src="//developers.kakao.com/sdk/js/kakao.min.js"></script>
  <title>SandyIndex</title>
  <link href="/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
  <link
    href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i"
    rel="stylesheet">
  <link href="/css/sb-admin-2.min.css" rel="stylesheet">
</head>

<body class="bg-gradient-primary">
  <div class="container">
    <div class="row justify-content-center">
      <div class="col-xl-10 col-lg-12 col-md-9">
        <div class="card o-hidden border-0 shadow-lg my-5">
          <div class="card-body p-0">
            <div class="row">
              <div class="col-lg-6 d-none d-lg-block">
                <img src="logo.png" width="100%">
              </div>
              <div class="col-lg-6">
                <div class="p-5" style="margin-top: 90px">
                  <div class="text-center">
                    <h1 class="h4 text-gray-900 mb-4">Welcome To Sandy!</h1>
                  </div>
                  <form class="user">
                    <div>
                        <a input class="btn btn-primary btn-user btn-block" href ='http://localhost:3000/users/login'>로그인</a>
                    </div>
                    <div style="margin-top: 10px">
                        <a input class="btn btn-primary btn-user btn-block" href ='http://localhost:3000/users/join'>회원가입</a>
                    </div>
                  </form>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- Bootstrap core JavaScript-->
  <script src="/vendor/jquery/jquery.min.js"></script>
  <script src="/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>

  <!-- Core plugin JavaScript-->
  <script src="/vendor/jquery-easing/jquery.easing.min.js"></script>
  <script src="/js/sb-admin-2.min.js"></script>

</body>
</html>

<views/login.ejs>

<!-- views/login.ejs -->
<!-- 로그인 화면 -->
<!DOCTYPE html>
<html lang="en">

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="">
  <meta name="author" content="">

  <title>Login</title>

  <!-- Custom fonts for this template-->
  <link href="/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
  <link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">

  <!-- Custom styles for this template-->
  <link href="/css/sb-admin-2.min.css" rel="stylesheet">
</head>

<body class="bg-gradient-primary">

  <div class="container">

    <!-- Outer Row -->
    <div class="row justify-content-center">

      <div class="col-xl-10 col-lg-12 col-md-9">

        <div class="card o-hidden border-0 shadow-lg my-5">
          <div class="card-body p-0">
            <!-- Nested Row within Card Body -->
            <div class="row">
                <div class="col-lg-6 d-none d-lg-block">
                    <img src="/logo.png" width="100%">
                </div>
              <div class="col-lg-6">
                <div class="p-5">
                  <div class="text-center">
                    <h1 class="h4 text-gray-900 mb-4">Welcome Back!</h1>
                  </div>
                  <form method='post' class="user" action="/users/login">
                    <div class="form-group">
                      <input type="text" class="form-control form-control-user" name="nickName" placeholder="Nickname" autofocus required >
                    </div>
                    <div class="form-group">
                      <input type="password" class="form-control form-control-user" name="upw" placeholder="Password" required >
                    </div>
                    <div class="form-group">

                    </div>
                    <input type="submit" class="btn btn-primary btn-user btn-block" value="Login" />
                    <hr>
                    <a href="index.html" class="btn btn-google btn-user btn-block" style="background-color: rgb(254, 225, 1); color: black">
                      Login with KaKao
                    </a>
                  </form>
                  <hr>
                  <div class="text-center">
                    <a class="small" href="join">Create an Account!</a>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- Bootstrap core JavaScript-->
  <script src="/vendor/jquery/jquery.min.js"></script>
  <script src="/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>

  <!-- Core plugin JavaScript-->
  <script src="/vendor/jquery-easing/jquery.easing.min.js"></script>

  <!-- Custom scripts for all pages-->
  <script src="/js/sb-admin-2.min.js"></script>

</body>
</html>

<views/board.ejs>

<!-- views/board.ejs -->
<!-- 메인 화면-->

<!DOCTYPE html>
<html>

<head>
    <title>board page</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
        integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">

  <!-- Custom fonts for this template-->
  <link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
  <link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">

  <!-- Custom styles for this template-->
  <link href="css/sb-admin-2.min.css" rel="stylesheet">

  <style>
    .card{
        margin: 20px;
        padding-top: 20px;
        padding-bottom: 10px;
    }
    .card-header{
        color: white;
        text-align: center;
        margin-left: 25px;
        margin-right: 25px;
        margin-bottom: 25px;
        width: 100%;
    }
    .btn-mine {
        width: 30px;
        height: 30px;
        float: right;
        margin-right: 10px;
    }
    #todoDiv, #doingDiv, #doneDiv{
        overflow:auto; width:100%; height:500px; margin-right: 30px;
    }

    html {
        scrollbar-arrow-color: #efefef;
        scrollbar-Track-Color: #efefef;
        scrollbar-base-color: #dfdfdf;
        scrollbar-Face-Color: #dfdfdf;
        scrollbar-3dLight-Color: #dfdfdf;         
        scrollbar-DarkShadow-Color: #dfdfdf;
        scrollbar-Highlight-Color: #dfdfdf;
        scrollbar-Shadow-Color: #dfdfdf
    }
    /* Chrome, Safari용 스크롤 바 */
    ::-webkit-scrollbar {width: 12px; height: 12px;  }
    ::-webkit-scrollbar-button:start:decrement,
    ::-webkit-scrollbar-button:end:increment {display: block; width: 12px;height: 12px; background: url() rgba(0,0,0,.05);}
    ::-webkit-scrollbar-track {     background: rgba(0,0,0,.05); }
    ::-webkit-scrollbar-thumb {  background: rgba(0,0,0,.1);  }
  </style>
</head>

<body>
    <nav class="navbar navbar-expand navbar-light bg-white topbar mb-4 static-top shadow" style="height: 60px">
        <div class="container-fluid">
            <div class="navbar-header">
            <a class="navbar-brand" href="/board">
                <img alt="Brand" src="logo.png" style="margin-top: -30px;width:110px">
            </a>
            </div>
        </div>
    </nav>
    <div class="container" >
        <div style='float:right'>
        <%  for( user of userName){ %>
            <a class="btn btn-info btn-icon-split ">
                <span class="text text-white text-lg"  onclick='showUsers("<%=user %>")'> <%=user %></span>
            </a>
        <% }  %>
        <a class="btn btn-light btn-icon-split">
          <span id='showAll' class='text text-lg' >모두 보기</span>  
        </a>
            <a href='/register' class="btn btn-light btn-icon-split">
                <span id='registerBtn' class='text text-lg' >할일 등록</span>  
            </a>
            <a href='/users/logout' class="btn btn-light btn-icon-split">
                <span id='logoutBtn' class='text text-lg' >로그아웃</span>  
            </a>
            <a href='/archive'  class='btn btn-danger btn-circle'><i class="fas fa-trash"></i></a>  
        </div>
    </div>

    <div class='content' style="margin: 5em">
        <div class="row col-md-4">
            <h1 class="card-header">To do</h1>
            <div id='todoDiv'>
                <% for(row of rows) {
                if (row.type=='TODO') {%>
                    <div class="card border-left-primary shadow">
                        <ul>
                            <li>제목 : <%=row.title %></li>
                            <li>등록날짜 : <%=row.regdate %></li>
                            <li>담당자 : <%=row.name %></li>
                            <li>우선순위 : <%=row.sequence %></li>
                            <input type="hidden" name='updateData' value='<%=row.id %>'/>
                        </ul>
                        <div>
                            <button class="btn btn-light btn-icon-split btn-mine" onclick='todoArchive("<%=row.id %>")'><i class="fas fa-trash"></i></button>
                            <button class="btn btn-light btn-icon-split btn-mine" onclick='moveBtn("<%=row.id %>")'><i class="fas fa-arrow-right"></i></button>                            
                        </div>
                    </div>  
                <% }
             } %>
            </div>
        </div>

        <div class="row col-md-4">
            <h1 class="card-header">Doing</h1>
            <div id='doingDiv'>
                <% for(row of rows) {
                    if (row.type=='DOING') {%>
                <div class="card border-left-primary shadow" >
                    <ul>
                        <li>제목 : <%=row.title %></li>
                        <li>등록날짜 : <%=row.regdate %></li>
                        <li>담당자 : <%=row.name %></li>
                        <li>우선순위 : <%=row.sequence %></li>
                    </ul>
                    <div>
                        <button class="btn btn-light btn-icon-split btn-mine" onclick='doingArchive("<%=row.id %>")'><i class="fas fa-trash"></i></button>
                        <button class="btn btn-light btn-icon-split btn-mine" onclick='moveBtn("<%=row.id %>")'><i class="fas fa-arrow-right"></i></button>                         
                    </div>
                </div>
                <% }
                 } %>
            </div>
        </div>

        <div class="row col-md-4">
            <h1 class="card-header">Done</h1>
            <div id='doneDiv'>
                <% for(row of rows) {
                if (row.type=='DONE') {%>
                <div class="card border-left-primary shadow">
                    <ul>
                        <li>제목 : <%=row.title %></li>
                        <li>등록날짜 : <%=row.regdate %></li>
                        <li>담당자 : <%=row.name %></li>
                        <li>우선순위 : <%=row.sequence %></li>
                    </ul>
                    <div>
                        <button class="btn btn-light btn-icon-split btn-mine" onclick='doneArchive("<%=row.id %>")'><i class="fas fa-trash"></i></button>
                        <button class="btn btn-light btn-icon-split btn-mine" onclick='moveBtn("<%=row.id %>")'><i class="fas fa-arrow-right"></i></button>                         
                    </div>
                </div>
                <% }
                } %>
            </div>
        </div>

    </div>

    <script>

    let id = 0;
    let user = 0;

    function todoArchive(id) {
        console.log('id', id);

        $.ajax({
            url: '/updateArchieve',
            data: {
                archiveData: id
            },
            type: 'get',
            dataType: 'json',

            success: (data) => {
                console.log('성공', data)

                $('#todoDiv').empty()

                //화면 조작: dom 조작
                $.each(data, (index, item) => {
                    if (item.type === 'TODO'){
                        $('#todoDiv').append(`
                        <div class="card border-left-primary shadow">
                            <ul>
                                <li>제목 : ${item.title}</li>
                                <li>등록날짜 :  ${item.regdate}</li>
                                <li>담당자 : ${item.name}</li>
                                <li>우선순위 : ${item.sequence}</li>
                            </ul>
                            <div>
                                <button class="btn btn-light btn-icon-split btn-mine" onclick='todoArchive(${item.id})'><i class="fas fa-trash"></i></button>
                                <button class="btn btn-light btn-icon-split btn-mine" onclick='moveBtn(${item.id})'><i class="fas fa-arrow-right"></i></button>                            
                            </div>
                        </div>`)                        
                    }
                }) //each문 end
            },
            error: (err) => {
                console.log('실패', err)
            }
        });
    }

    function doingArchive(id) {
        console.log('id', id);

        $.ajax({
            url: '/updateArchieve',
            data: {
                archiveData: id
            },
            type: 'get',
            dataType: 'json',

            success: (data) => {
                console.log('성공', data)

                $('#doingDiv').empty()

                //화면 조작: dom 조작
                $.each(data, (index, item) => {
                    if (item.type === 'DOING'){
                        $('#doingDiv').append(`
                        <div class="card border-left-primary shadow">
                            <ul>
                                <li>제목 :      ${item.title}</li>
                                <li>등록날짜 :  ${item.regdate}</li>
                                <li>담당자 :    ${item.name}</li>
                                <li>우선순위 :  ${item.sequence}</li>
                            </ul>
                            <div>
                                <button class="btn btn-light btn-icon-split btn-mine" onclick='doingArchive(${item.id})'><i class="fas fa-trash"></i></button>
                                <button class="btn btn-light btn-icon-split btn-mine" onclick='moveBtn(${item.id})'><i class="fas fa-arrow-right"></i></button>                            
                            </div>
                        </div>`)                        
                    }
                }) //each문 end
            },
            error: (err) => {
                console.log('실패', err)
            }
        });
    }

    function doneArchive(id) {
        console.log('id', id);

        $.ajax({
            url: '/updateArchieve',
            data: {
                archiveData: id
            },
            type: 'get',
            dataType: 'json',

            success: (data) => {
                console.log('성공', data)

                $('#doneDiv').empty()

                //화면 조작: dom 조작
                $.each(data, (index, item) => {
                    if (item.type === 'DONE'){
                        $('#doneDiv').append(`
                        <div class="card border-left-primary shadow">
                        <ul>
                            <li>제목 :      ${item.title}</li>
                            <li>등록날짜 :  ${item.regdate}</li>
                            <li>담당자 :    ${item.name}</li>
                            <li>우선순위 :  ${item.sequence}</li>
                        </ul>
                        <div>
                            <button class="btn btn-light btn-icon-split btn-mine" onclick='doneArchive(${item.id})'><i class="fas fa-trash"></i></button>
                            <button class="btn btn-light btn-icon-split btn-mine" onclick='moveBtn(${item.id})'><i class="fas fa-arrow-right"></i></button>                            
                        </div>
                    </div>`)                        
                    }
                }) //each문 end
            },
            error: (err) => {
                console.log('실패', err)
            }
        });
    }

    function moveBtn(id){
        $.ajax({
            url: '/update',
            data: {
                updateData: id
            },
            type: 'post',
            dataType: 'json',
            success: (data) => {
                // 기존 데이터 삭제
                $('#todoDiv').empty()
                $('#doingDiv').empty()
                $('#doneDiv').empty()
                // 신규 데이터 추가
                $.each(data, (idx, row)=>{
                    let html = `
                        <div class="card border-left-primary shadow">
                            <ul>
                                <li>제목 : ${row.title}</li>
                                <li>등록날짜 :  ${row.regdate}</li>
                                <li>담당자 : ${row.name}</li>
                                <li>우선순위 : ${row.sequence}</li>
                            </ul>`

                        if( row.type == 'TODO' ) {
                            $('#todoDiv').append(html+`
                            <div>
                                <button class="btn btn-light btn-icon-split btn-mine" onclick='todoArchive(${row.id})'><i class="fas fa-trash"></i></button>
                                <button class="btn btn-light btn-icon-split btn-mine" onclick='moveBtn(${row.id})'><i class="fas fa-arrow-right"></i></button>                            
                            </div>
                        </div>`)
                        } else if( row.type == 'DOING' ) {
                            $('#doingDiv').append(html+`
                            <div>
                                <button class="btn btn-light btn-icon-split btn-mine" onclick='doingArchive(${row.id})'><i class="fas fa-trash"></i></button>
                                <button class="btn btn-light btn-icon-split btn-mine" onclick='moveBtn(${row.id})'><i class="fas fa-arrow-right"></i></button>                            
                            </div>
                        </div>`)
                        } else if( row.type == 'DONE' ) {
                            $('#doneDiv').append(html+`
                            <div>
                                <button class="btn btn-light btn-icon-split btn-mine" onclick='doneArchive(${row.id})'><i class="fas fa-trash"></i></button>
                                <button class="btn btn-light btn-icon-split btn-mine" onclick='moveBtn(${row.id})'><i class="fas fa-arrow-right"></i></button>                            
                            </div>
                        </div>`)
                        }
                })   
            },
            error: (err) => {
                console.log('실패', err)
            }
        });
    }

    $('#showAll').on('click', (evt) => {
        evt.preventDefault()

        $.ajax({
            url: '/list',
            data: $('form').serialize(),
            type: 'get',
            dataType: 'json',
            success: (data) => {
                console.log('성공', data)

                $('#todoDiv').empty()
                $('#doingDiv').empty()
                $('#doneDiv').empty()

                //화면 조작: dom 조작
                $.each(data, (index, item) => {
                    if (item.type === 'TODO') {
                        $('#todoDiv').append(`
                        <div class="card border-left-primary shadow">
                            <ul>
                                <li>제목 :      ${item.title}</li>
                                <li>등록날짜 :  ${item.regdate}</li>
                                <li>담당자 :    ${item.name}</li>
                                <li>우선순위 :  ${item.sequence}</li>
                            </ul>
                            <div>
                                <button class="btn btn-light btn-icon-split btn-mine" onclick='todoArchive(${item.id})'><i class="fas fa-trash"></i></button>
                                <button class="btn btn-light btn-icon-split btn-mine" onclick='moveBtn(${item.id})'><i class="fas fa-arrow-right"></i></button>                            
                            </div>
                        </div>`)  
                    } else if (item.type === 'DOING') {
                        $('#doingDiv').append(`
                        <div class="card border-left-primary shadow">
                            <ul>
                                <li>제목 :      ${item.title}</li>
                                <li>등록날짜 :  ${item.regdate}</li>
                                <li>담당자 :    ${item.name}</li>
                                <li>우선순위 :  ${item.sequence}</li>
                            </ul>
                            <div>
                                <button class="btn btn-light btn-icon-split btn-mine" onclick='doingArchive(${item.id})'><i class="fas fa-trash"></i></button>
                                <button class="btn btn-light btn-icon-split btn-mine" onclick='moveBtn(${item.id})'><i class="fas fa-arrow-right"></i></button>                            
                            </div>
                        </div>`)
                    } else if (item.type === 'DONE') {
                        $('#doneDiv').append(`
                        <div class="card border-left-primary shadow">
                        <ul>
                            <li>제목 :      ${item.title}</li>
                            <li>등록날짜 :  ${item.regdate}</li>
                            <li>담당자 :    ${item.name}</li>
                            <li>우선순위 :  ${item.sequence}</li>
                        </ul>
                        <div>
                            <button class="btn btn-light btn-icon-split btn-mine" onclick='doneArchive(${item.id})'><i class="fas fa-trash"></i></button>
                            <button class="btn btn-light btn-icon-split btn-mine" onclick='moveBtn(${item.id})'><i class="fas fa-arrow-right"></i></button>                            
                        </div>
                    </div>`)
                    }
                }) //each문 end
            },
            error: (err) => {
                console.log('실패', err)
            }
        });
        return false
    })

    function showUsers(user){

        $.ajax({
            url: '/search',
            data: {
                userName: user
            },
            type: 'get',
            dataType: 'json',

            success: (data) => {
                console.log('성공', data)

                $('#todoDiv').empty()
                $('#doingDiv').empty()
                $('#doneDiv').empty()

                //화면 조작: dom 조작
                $.each(data, (index, item) => {

                    if (item.name === user) {
                        console.log(item.name, user)
                        if (item.type === 'TODO') {
                            $('#todoDiv').append(`
                                <div class="card border-left-primary shadow">
                                    <ul>
                                        <li>제목 :      ${item.title}</li>
                                        <li>등록날짜 :  ${item.regdate}</li>
                                        <li>담당자 :    ${item.name}</li>
                                        <li>우선순위 :  ${item.sequence}</li>
                                    </ul>
                                    <div>
                                        <button class="btn btn-light btn-icon-split btn-mine" onclick='todoArchive(${item.id})'><i class="fas fa-trash"></i></button>
                                        <button class="btn btn-light btn-icon-split btn-mine" onclick='moveBtn(${item.id})'><i class="fas fa-arrow-right"></i></button>                            
                                    </div>
                                </div>`)  
                        } else if (item.type === 'DOING') {
                            $('#doingDiv').append(`
                                <div class="card border-left-primary shadow">
                                    <ul>
                                        <li>제목 :      ${item.title}</li>
                                        <li>등록날짜 :  ${item.regdate}</li>
                                        <li>담당자 :    ${item.name}</li>
                                        <li>우선순위 :  ${item.sequence}</li>
                                    </ul>
                                    <div>
                                        <button class="btn btn-light btn-icon-split btn-mine" onclick='doingArchive(${item.id})'><i class="fas fa-trash"></i></button>
                                        <button class="btn btn-light btn-icon-split btn-mine" onclick='moveBtn(${item.id})'><i class="fas fa-arrow-right"></i></button>                            
                                    </div>
                                </div>`)
                        } else if (item.type === 'DONE') {
                            $('#doneDiv').append(`
                            <div class="card border-left-primary shadow">
                                <ul>
                                    <li>제목 :      ${item.title}</li>
                                    <li>등록날짜 :  ${item.regdate}</li>
                                    <li>담당자 :    ${item.name}</li>
                                    <li>우선순위 :  ${item.sequence}</li>
                                </ul>
                                <div>
                                    <button class="btn btn-light btn-icon-split btn-mine" onclick='doneArchive(${item.id})'><i class="fas fa-trash"></i></button>
                                    <button class="btn btn-light btn-icon-split btn-mine" onclick='moveBtn(${item.id})'><i class="fas fa-arrow-right"></i></button>                            
                                </div>
                            </div>`)
                        }
                    }
                }) //each문 end
            },
            error: (err) => {
                console.log('실패', err)
            }
        });
    }
    </script>
</body>
</html>

<views/join.ejs>

<!-- views/join.ejs -->
<!-- 회원가입 화면-->

<!DOCTYPE html>
<html lang="en">

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  <title>Create an Account!</title>

  <!-- Custom fonts for this template-->
  <link href="/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
  <link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">

  <!-- Custom styles for this template-->
  <link href="/css/sb-admin-2.min.css" rel="stylesheet">

</head>

<body class="bg-gradient-primary">

  <div class="container">

    <!-- Outer Row -->
    <div class="row justify-content-center">

      <div class="col-md-6">

        <div class="card o-hidden border-0 shadow-lg my-5">
          <div class="card-body p-0">
            <!-- Nested Row within Card Body -->
            <div class="row">
              <div class="col-lg-12">
                <div class="p-5">
                  <div class="text-center">
                    <h1 class="h4 text-gray-900 mb-4">Create an Account!</h1>
                  </div>
                  <br/>
                  <form method='post' class="user" action="/users/join">
                    <div class="form-group">
                      <input type="text" class="form-control form-control-user"  name="nickName" id="checkExistNickName" aria-describedby="emailHelp" placeholder="Nickname" required />
                    </div>
                    <p class="text-center small" id ="checkNickNameMsg"></p>
                    <div class="form-group">
                      <input type="password" class="form-control form-control-user" name="upw" id="password" onchange="checkSamePassword()" placeholder="Password" required />
                    </div>
                    <div class="form-group">
                        <input type="password" class="form-control form-control-user" name="checkUpw" id="checkPassword" onchange="checkSamePassword()" placeholder="Password check" required />
                    </div>
                    <p class="text-center small" id="checkMsg"></p>
                    <div class="form-group">
                        <input type="text" class="form-control form-control-user" name="userName" placeholder="Name" required />
                    </div>
                    <hr>
                    <input type="submit" class="btn btn-primary btn-user btn-block" id="join" value="join" />
                  </form>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- Bootstrap core JavaScript-->
  <script src="/vendor/jquery/jquery.min.js"></script>
  <script src="/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>

  <!-- Core plugin JavaScript-->
  <script src="/vendor/jquery-easing/jquery.easing.min.js"></script>

  <!-- Custom scripts for all pages-->
  <script src="/js/sb-admin-2.min.js"></script>

  <script>

        var checkNickNameMsg = document.getElementById('checkNickNameMsg')

        $('#checkExistNickName').on('change', (evt)=> {
            console.log(evt)

            $.ajax({
                url : '/users/check',
                data : {
                   nickName : $('[name=nickName]').val()
                },
                type : 'get',
                dataType : 'json',
                success : (data) => {
                    console.log('성공', typeof data, data)
                    console.log(data.length)

                    if (data.length == 0) {
                       //$('#checkNickNameMsg').append('사용할 수 있는 닉네임입니다')
                        checkNickNameMsg.innerHTML = '사용할 수 있는 닉네임입니다'
                        checkNickNameMsg.style.color = 'green'
                        checkNickNameMsg.style.fontSize = '10px'
                        // join 버튼 활성화
                        $('#join').attr("disabled", false)
                    } else {
                        checkNickNameMsg.innerHTML = '이미 존재하는 닉네임입니다'
                        checkNickNameMsg.style.color = 'red'
                        checkNickNameMsg.style.fontSize = '10px'
                        // join 버튼 비활성화
                        $('#join').attr("disabled", true)
                    }
                },
                error : (err) => {
                    console.log('실패', err)
                }
            })
        })

        function checkSamePassword() {

            var password = document.getElementById('password')
            var checkPassword = document.getElementById('checkPassword')
            var checkMsg = document.getElementById('checkMsg')

            if(password.value !='' && checkPassword.value != '') {
                if(password.value == checkPassword.value) {
                    checkMsg.innerHTML = '비밀번호가 일치합니다'
                    checkMsg.style.color = 'green'
                    checkMsg.style.fontSize = '10px'
                    // join 버튼 활성화
                    $('#join').attr("disabled", false)
                } else {
                    checkMsg.innerHTML = '비밀번호가 일치하지 않습니다'
                    checkMsg.style.color = 'red'
                    checkMsg.style.fontSize = '10px'
                    // join 버튼 비활성화
                    $('#join').attr("disabled", true)  
                }
            }    
        }    
  </script>

</body>
</html>

<views/register.ejs>

<!-- views/register.ejs -->
<!-- 할일 등록 화면-->

<!DOCTYPE html>
<html>

<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>register</title>
    <link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
    <link
        href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i"
        rel="stylesheet">
    <link href="css/sb-admin-2.min.css" rel="stylesheet">
</head>

<body class="bg-gradient-primary">

        <div class="container">

          <!-- Outer Row -->
          <div class="row justify-content-center">

            <div class="col-md-6">

              <div class="card o-hidden border-0 shadow-lg my-5">
                <div class="card-body p-0">
                  <!-- Nested Row within Card Body -->
                  <div class="row">
                    <div class="col-lg-12">
                      <div class="p-5">
                        <div class="text-center">
                          <h1 class="h4 text-gray-900 mb-4">할일 등록</h1>
                        </div>
                        <br/>
                        <form method='post' class="user" action="/register">
                            <div class="form-group">
                                <p>어떤 일인가요?</p>
                                <input type="text" class="form-control form-control-user" name="title" maxlength="24"
                                    placeholder="24자 이내로 입력하세요" required />
                            </div>
                            <div class="form-group">
                                <p>누가 할일인가요?</p>
                                <select class="form-control" name="name" required>
                                    <% for(row of rows) {%>
                                    <option><%=row.nickName %></option>
                                    <% } %>
                                </select>
                            </div>
                            <div class="form-group">
                                <p>우선순위를 선택하세요</p>
                                <input type="radio" name="sequence" value=1 required /> 1순위
                                <input type="radio" name="sequence" value=2 /> 2순위
                                <input type="radio" name="sequence" value=3 /> 3순위
                            </div>
                            <div class="form-group">
                                <input class="btn btn-primary btn-user btn-block" type="submit" value="등록하기" />                    
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>

  <!-- Bootstrap core JavaScript-->
  <script src="/vendor/jquery/jquery.min.js"></script>
  <script src="/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>

  <!-- Core plugin JavaScript-->
  <script src="/vendor/jquery-easing/jquery.easing.min.js"></script>

  <!-- Custom scripts for all pages-->
  <script src="/js/sb-admin-2.min.js"></script>

</body>
</html>

<views/archive.ejs>

<!-- views/archive.ejs -->
<!-- 휴지통 화면 -->

<!DOCTYPE html>
<html>
<head>
    <title>archieve page</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <link rel='stylesheet' href='/stylesheets/style.css' />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
    <link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
    <link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">

    <link href="css/sb-admin-2.min.css" rel="stylesheet">
    <style>
        .card{
            margin: 20px;
            padding-top: 20px;
            padding-bottom: 10px;
        }
        .card-header{
            color: white;
            text-align: center;
            margin-left: 25px;
            margin-right: 25px;
            margin-bottom: 25px;
        }
        .btn-mine {
            width: 30px;
            height: 30px;
            float: right;
            margin-right: 10px;
        }
        html {
            scrollbar-arrow-color: #efefef;
            scrollbar-Track-Color: #efefef;
            scrollbar-base-color: #dfdfdf;  
            scrollbar-Face-Color: #dfdfdf;
            scrollbar-3dLight-Color: #dfdfdf;         
            scrollbar-DarkShadow-Color: #dfdfdf;
            scrollbar-Highlight-Color: #dfdfdf;
            scrollbar-Shadow-Color: #dfdfdf
        }
        /* Chrome, Safari용 스크롤 바 */
        ::-webkit-scrollbar {width: 12px; height: 12px;  }
        ::-webkit-scrollbar-button:start:decrement,
        ::-webkit-scrollbar-button:end:increment {display: block; width: 12px;height: 12px; background: url() rgba(0,0,0,.05);}
        ::-webkit-scrollbar-track {     background: rgba(0,0,0,.05); }
        ::-webkit-scrollbar-thumb {  background: rgba(0,0,0,.1);  }

    </style>
</head>

<body style='padding: 0'>
    <nav class="navbar navbar-expand navbar-light bg-white topbar mb-4 static-top shadow" style="height: 60px">
        <div class="container-fluid">
            <div class="navbar-header">
            <a class="navbar-brand" href="/board">
                <img alt="Brand" src="logo.png" style="margin-top: -30px;width:110px">
            </a>
            </div>
        </div>
    </nav>
    <div class="container">
        <h1 class="card-header" style='margin-top: 10px;width:300px;' >Archive</h1>
        <div id='removeDiv' style="overflow:auto; width:100%; height:550px">
            <% for(row of rows) { %>
            <div class="card border-left-primary shadow" style="float:left">
                <ul>
                    <li>제목 :      <%=row.title %></li>
                    <li>등록날짜 :  <%=row.regdate %></li>
                    <li>담당자 :    <%=row.name %></li>
                    <li>우선순위 :  <%=row.sequence %></li>
                    <li>타입 :      <%=row.type %></li>
                </ul>
                <div>
                    <button class="btn btn-light btn-icon-split btn-mine" onclick='clickRemove("<%=row.id %>")'><i class="fas fa-trash"></i></button>
                </div>
            </div>
            <% } %>
        </div>
    </div>

    <script>
        let id = 0;
        function clickRemove(id) {
            var con_test = confirm("영구 삭제 하시겠습니까?");

            if (con_test) {
                console.log('id', id);

                $.ajax({
                    url: '/remove',
                    data: {
                        updateData: id
                    },
                    type: 'get',
                    dataType: 'json',

                    success: (data) => {
                        console.log('성공', data)

                        $('#removeDiv').empty()

                        //화면 조작: dom 조작
                        $.each(data, (index, item) => {

                            $('#removeDiv').append(`
                            <div class="card border-left-primary shadow" style="float:left">
                                <ul>
                                    <li>제목 :      ${item.title}</li>
                                    <li>등록날짜 :  ${item.regdate}</li>
                                    <li>담당자 :    ${item.name}</li>
                                    <li>우선순위 :  ${item.sequence}</li>
                                </ul>
                                <div>
                                    <button class="btn btn-light btn-icon-split btn-mine" onclick='clickRemove(${item.id})'><i class="fas fa-trash"></i></button>
                                </div>
                            </div>`)
                        }) // each문 end
                    },
                    error: (err) => {
                        console.log('실패', err)
                    }
                });
            }
        }
    </script>
</body>
</html>

<views/error.ejs>

<!-- views/error.ejs -->
<!-- 에러 발생 시 -->

<script>
    alert('에러 페이지')
    history.back();
</script>

<views/loginFail.ejs>

<!-- views/loginFail.ejs -->
<!-- 로그인 실패 시 -->

<script>
        alert('사용자 이름 또는 비밀번호를 잘못 입력하셨습니다')
        history.back();
</script>

<app.js>

// app.js

// 써드 파트 패키지 모듈 가져오기
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
// var bodyParser = require('body-parser')

// 세션 추가
const session = require('express-session')

// 특정 요청에 대한 응답을 누가 할 것인지
// 어떤 url로 할 것인지 정의하고 가져온다
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

// 웹 서비스의 핵심 객체(앱) → express 객체
var app = express();

app.set('trust proxy', 1)
app.use(session({
  secret : 'sandysecret',
  resave : false,
  saveUninitialized : true
}))

// view engine setup
app.set('views', path.join(__dirname, 'views'));
// 렌더링 템플릿 엔진으로 ejs 사용
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
// 정적 데이터 위치 설정
app.use(express.static(path.join(__dirname, 'public')));

// 세션이 없어도 진입할 수 있는 사이트
app.use('/users', usersRouter);

app.use((req, res, next)=>{

  console.log('세션 체크 지점')

  if(req.session.nickName == null || typeof(req.session.nickName) === 'undefined') {
    console.log("세션 없음 : "+ req.session.nickName)
    res.redirect('/users/login')
  } else { // 세션이 존재
    console.log("세션 있음 : "+ req.session.nickName)
    next()
  }
})

app.use('/', indexRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

// 대표 모듈
// 외부에서는 app을 통해서만 접근 가능
module.exports = app;