Urban_Oasis 1) 2020.06.20

오범준·2020년 7월 8일
0

UrbanOasis

목록 보기
1/3

To Do

1. If User is Loggined, Then I want to show "Logout" Logo instead of "Login"

Trial 1 : use "ejs" + apply js so that if user is logined, show "login format", else, show "logout format" on every ejs file( ex. home, produce, about ... )

That is,
if token exist, show "logout" , if not, show "login"

PB : applying "If" + "Varabile existence" in EJS is not working

1st trial : Below is the code I want to apply

<li class="nav-item px-lg-4">
            <% if(  <%= _id %>  ){ %>
              <a class="nav-link text-uppercase text-expanded" href="/login">Login</a> 
              <% }else{ %>
                 <a class="nav-link text-uppercase text-expanded" href="/logout">Logout</a> 
            <%} %>
          </li>

But it comes with following error

Error: Could not find matching close tag for "<%".

The reason is, I used <%= before "_id", which means, I added opening of <% before closing the first <% which is located in front of "if"

2nd trial : removed <%=, %> next to "_id"

<li class="nav-item px-lg-4">
            <% if(  _id  ){ %>
              <a class="nav-link text-uppercase text-expanded" href="/login">Login</a> 
              <% }else{ %>
                 <a class="nav-link text-uppercase text-expanded" href="/logout">Logout</a> 
            <%} %>
          </li>

It also comes with following error

_id is not defined

Solution

1) Send "Found data" to "ejs" with key

var x_auth = req.cookies.x_auth

    if( x_auth){
        // x_auth가 true : x_auth가 있다는 것 : login 된 상태 
        console.log('x_auth : ',x_auth)

        connection.db.collection("users", function(err, collection){

            collection.find({token:x_auth}).toArray(function(err, data){
                //검색 개수 보여주기
                // data는 collection에서 user , 혹은 dancer 정보를 받아오는 것이고, 그것을 mypageDancer 라는 router 에다가 넘겨주는 것이다 
                // 아래 코드를 통해, mypage.ejs 에서, mongodb에 있는 내용의 data 들을 value 값으로 넣어줄 수가 있는 것이다 

            console.log("loged in")
            console.log("data : " , data[0])
            res.render('index', { member : data[0] })

            })   
        });
    }else{
        console.log("Not loged in")
        // token이 없을시 빈 object 형태로 member를 넘겨준다
        res.render('index', { member : {})
    }

2) use "key" to apply "if, else "

<% if( !member.token ){ %> 
              <a class="nav-link text-uppercase text-expanded" href="/login">Login</a> 
              <% }else{ %>
                 <a class="nav-link text-uppercase text-expanded" href="/logout">Logout</a> 
            <%} %>

2. Non-Admin Not allowed : notices, recipes

Server


router.get('/notice', function(req,res){

    var x_auth = req.cookies.x_auth

    if( x_auth){
        // x_auth가 true : x_auth가 있다는 것 : login 된 상태 
        console.log('x_auth : ',x_auth)

        connection.db.collection("users", function(err, collection){

            collection.find({token:x_auth}).toArray(function(err, data){
                //검색 개수 보여주기
                // data는 collection에서 user , 혹은 dancer 정보를 받아오는 것이고, 그것을 mypageDancer 라는 router 에다가 넘겨주는 것이다 
                // 아래 코드를 통해, mypage.ejs 에서, mongodb에 있는 내용의 data 들을 value 값으로 넣어줄 수가 있는 것이다 

            console.log("loged in")
            console.log("data : " , data[0])
            res.render('notice', { member : data[0] })

            })   
        });
    }else{
        console.log("Not loged in")
        res.render('notice', { member : {}})
        
    }
})

Html : if logined, show original notice board, if not, show other html

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

<head>

  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="">
  <meta name="author" content="">

  <title>Business Casual - Start Bootstrap Theme</title>

  <!-- Bootstrap core CSS -->
  <link href="../vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">

  <!-- Custom fonts for this template -->
  <link href="https://fonts.googleapis.com/css?family=Raleway:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
  <link href="https://fonts.googleapis.com/css?family=Lora:400,400i,700,700i" rel="stylesheet">

  <!-- Custom styles for this template -->
  <link href="../css/business-casual.css" rel="stylesheet">

</head>

<body>

  <h1 class="site-heading text-center text-white d-none d-lg-block">
    <span class="site-heading-upper text-primary mb-3">Wish Your Comfort</span>
    <span class="site-heading-lower">Urban Oasis</span>
  </h1>

  <!-- Navigation -->
  <nav class="navbar navbar-expand-lg navbar-dark py-lg-4" id="mainNav">

    <div class="container">

      <a class="navbar-brand text-uppercase text-expanded font-weight-bold d-lg-none" href="#">Welcome to Urban Oasis</a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarResponsive">
        <ul class="navbar-nav mx-auto">
          <li class="nav-item active px-lg-4">
            <a class="nav-link text-uppercase text-expanded" href="/">Home
              <span class="sr-only">(current)</span>
            </a>
          </li>
          <li class="nav-item px-lg-4">
            <a class="nav-link text-uppercase text-expanded" href="/about">
              About</a>
          </li>
          <li class="nav-item px-lg-4">
            <a class="nav-link text-uppercase text-expanded" href="/products">Products</a>
          </li>
          <li class="nav-item px-lg-4">
            <a class="nav-link text-uppercase text-expanded" href="/recipe">Recipe</a>
          </li>
          <li class="nav-item px-lg-4">
            <a class="nav-link text-uppercase text-expanded" href="/songs">Recommended Songs</a>
          </li>
          <li class="nav-item px-lg-4">
            <a class="nav-link text-uppercase text-expanded" href="/notice">Notices</a>
          </li>
          <li class="nav-item px-lg-4">
            <% if( !member.token ){ %> 
              <a class="nav-link text-uppercase text-expanded" href="/login">Login</a> 
              <% }else{ %>
                 <a class="nav-link text-uppercase text-expanded" href="/logout">Logout</a> 
            <%} %>
          </li>
        </ul>
      </div>
    </div>
  </nav>

  <section class="page-section about-heading">
    <div class="container">

      <% if( member.token ){ %> 
        <section class="page-section cta">
          <div class="container">
            <div class="row">
              <div class="col-xl-9 mx-auto">
                <div class="cta-inner text-center rounded">
                  <h2 class="section-heading mb-5">
                    <span class="section-heading-upper">Regular</span>
                    <span class="section-heading-lower">Checklist</span>
                  </h2>
                  <ul class="list-unstyled list-hours mb-5 text-left mx-auto">
                    <li class="list-unstyled-item list-hours-item d-flex">
                      <span class="ml-title">
                        Common 
                        <span class="ml-edit">💙</span>
                        <span class="ml-cancel"><br/>
                        </span>
                        <span class="ml-save"></span>
                      </span>
                      <span class="ml-auto">
                        청소기
                        <br/>
                        물걸레 ( floor, table )
                        <br/>
                        아기 선인장 물주기
                        <br/>
                        샌드위치( 빵, 치즈, 햄 ) 재고 확인
                        <br/>
                      </span>
                      <textarea type="text" class="ml-input"></textarea>
                    </li>
                    <li class="list-unstyled-item list-hours-item d-flex">
                      <span class="ml-title">
                        Sunday
                        <br/>
                        <span class="ml-edit">💙</span>
                        <span class="ml-cancel"></span>
                        <span class="ml-save"></span>
                      </span>
                      <span class="ml-auto">
                        빵 개수 확인
                      </span>
                      <textarea type="text" value = "input" class="ml-input"></textarea>
                    </li>
                    <li class="list-unstyled-item list-hours-item d-flex">
                      <span class="ml-title">
                        Monday
                        <br/>
                        <span class="ml-edit">💙</span>
                        <span class="ml-cancel"></span>
                        <span class="ml-save"></span>
  
                      </span>
                      <span class="ml-auto">11:00 AM to 11:00 PM</span>
                      <textarea type="text" value = "input" class="ml-input"></textarea>
                    </li>
                    <li class="list-unstyled-item list-hours-item d-flex">
                      <span class="ml-title">
                        Tuesday
                        <br/>
                        <span class="ml-edit">💙</span>
                        <span class="ml-cancel"></span>
                        <span class="ml-save"></span>
  
                      </span>
                      <span class="ml-auto">11:00 AM to 11:00 PM</span>
                      <textarea type="text" value = "input" class="ml-input"></textarea>
                    </li>
                    <li class="list-unstyled-item list-hours-item d-flex">
                      <span class="ml-title">
                        Wednesday
                        <br/>
                        <span class="ml-edit">💙</span>
                        <span class="ml-cancel"></span>
                        <span class="ml-save"></span>
  
                      </span>
                      <span class="ml-auto">11:00 AM to 11:00 PM</span>
                      <textarea type="text" value = "input" class="ml-input"></textarea>
                    </li>
                    <li class="list-unstyled-item list-hours-item d-flex">
                      <span class="ml-title">
                        Thursday
                        <br/>
                        <span class="ml-edit">💙</span>
                        <span class="ml-cancel"></span>
                        <span class="ml-save"></span>
  
                      </span>
                      <span class="ml-auto">11:00 AM to 11:00 PM</span>
                      <textarea type="text" value = "input" class="ml-input"></textarea>
                    </li>
                    <li class="list-unstyled-item list-hours-item d-flex">
                      <span class="ml-title">
                        Friday
                        <br/>
                        <span class="ml-edit">💙</span>
                        <span class="ml-cancel"></span>
                        <span class="ml-save"></span>
  
                      </span>
                      <span class="ml-auto">11:00 AM to 11:00 PM</span>
                      <textarea type="text" value = "input" class="ml-input"></textarea>
                    </li>
                    <li class="list-unstyled-item list-hours-item d-flex">
                      <span class="ml-title">
                        Saturday
                        <br/>
                        <span class="ml-edit">💙</span>
                        <span class="ml-cancel"></span>
                        <span class="ml-save"></span>
  
                      </span>
                      <span class="ml-auto">11:00 AM to 11:00 PM</span>
                      <textarea type="text" value = "input" class="ml-input"></textarea>
                    </li>
                    
                  </ul>
                  <p class="address mb-5">
                    <em>
                      <strong>서울 강남구 개포로 17길 13 1층</strong>
                      <br>
                      Seoul GangnamGu Gaeporo 17Gil 13 1st floor
                    </em>
                  </p>
                  <p class="mb-0">
                    <small>
                      <em>Call Anytime</em>
                    </small>
                    <br>
                    02-6494-1227
                  </p>
                </div>
              </div>
            </div>
          </div>
        </section>
  
        <section class="page-section cta">
          <div class="container">
            <div class="row">
              <div class="col-xl-9 mx-auto">
                
                <div class="cta-inner-line text-center rounded">
                  <h2 class="section-heading-line mb-4">
                    <span class="section-heading-upper">Daliy Notices</span>
                    <span id = "DailyAdd" class="section-heading-add">
                      Add Notice
                    </span>
                    
                  </h2>
                </div>
              </div>
            </div>
            <div class="row">
              <div class="col-xl-9 mx-auto">
                
                <div class="cta-inner-notice text-center rounded">
                  <div class="notice-item">
                    <span class = "notice-date">Date</span>
                    <img class = "notice-img" src="../img/urban1.jpg" alt="">
                    <p class = "notice-content">케익 식재료 왔습니다</p>
  
                  </div>
                  <div class="notice-item">
                    <span class = "notice-date">Date</span>
                    <img class = "notice-img" src="../img/urban1.jpg" alt="">
                    <p class = "notice-content">케익 식재료 왔습니다</p>
  
                  </div>
                </div>
              </div>
            </div>
          </div>
        </section>
  
        
  <!-- 
        <img class="img-fluid rounded about-heading-img mb-3 mb-lg-0" src="../img/urban1.jpg" alt="">
        <div class="about-heading-content">
          <div class="row">
            <div class="col-xl-9 col-lg-10 mx-auto">
              <div class="bg-faded rounded p-5">
                <h2 class="section-heading mb-4">
                  <span class="section-heading-upper">Strong Coffee, Strong Roots</span>
                  <span class="section-heading-lower">About Our Cafe</span>
                </h2>
                <p>Hello</p>
                <p class="mb-0">We guarantee that you will fall in <em>lust</em> with our decadent blends the moment you walk inside until you finish your last sip. Join us for your daily routine, an outing with friends, or simply just to enjoy some alone time.</p>
              </div>
            </div>
          </div>
        </div>
        <br/>
        <br/>
        <img class="img-fluid rounded about-heading-img mb-3 mb-lg-0" src="img/wash1.jpg" alt="">
        <div class="about-heading-content">
          <div class="row">
            <div class="col-xl-9 col-lg-10 mx-auto">
              <div class="bg-faded rounded p-5">
                <h2 class="section-heading mb-4">
                  <span class="section-heading-upper">Strong Coffee, Strong Roots</span>
                  <span class="section-heading-lower">About Our Cafe</span>
                </h2>
                <p>Founded in 1987 by the Hernandez brothers, our establishment has been serving up rich coffee sourced from artisan farmers in various regions of South and Central America. We are dedicated to travelling the world, finding the best coffee, and bringing back to you here in our cafe.</p>
                <p class="mb-0">We guarantee that you will fall in <em>lust</em> with our decadent blends the moment you walk inside until you finish your last sip. Join us for your daily routine, an outing with friends, or simply just to enjoy some alone time.</p>
              </div>
            </div>
          </div>
        </div> -->
  
        
  
      </div>
    </section>
    <!-- notice 입력을 위한 모델창 -->
    <div class="modal hidden">
      <div class="modal__overlay"></div>
      <div class="modal__content">
          <form class = "form" enctype = "multipart/form-data" method = 'POST' action = "/notice" id = 'upload_form'>
              <h3 class = "modal-title">New Notice</h3>
              <label for="inpVideo">
                  Choose Video
                  <input type="file" value = "Choose Video" name = "upload" id = "inpVideo" accept ="video/mp4" />
              </label>
              <label for="inpImage">
                  Choose Image
                  <input type="file" value = "Choose Image" name = "upload" id = "inpImage" accept ="image/gif, image/jpeg, image/png" />
              </label>
              <div class="image-preview" id ="image-preview">
                  <img src="" class="image-preview__image" name = "upload">
                  <br/>
                  <video id="video-element" controls autoplay muted>
                    <source type="video/mp4">
                </video>
                  <span class="image-preview__default-text">Image/Video Preview
                  </span>
              </div>
  <!-- 
              <div class="video-preview">
                  
              </div> -->
                <textarea type="text" name = "upload" id = "inpText" ></textarea>
              <button type="submit" id="submit-btn" class='btn-deactive'>Submit
              </button>
          </form>
      </div>
  </div> 
        <% }else{ %>
          <section class="login" style = "text-align: center; height: 30vh;">
            <h1 style = "color: white; margin-top: 30px">Please login</h1>
          </section> 
      <%} %>
      

  <footer class="footer text-faded text-center py-5">
    <div class="footer-container">
      <p class="m-0 small">Web Developer &copy; BUM JUN OH </p><br/>
      <p class="m-0 small">KakaotalkID : dhsys112</p>

    </div>
  </footer>

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

</body>

</html>

3. Update Notices

3.1) Daily Notice + Regular Notice

PB : I want to Edit Text without changing the URL

Trial 1 : Apply Js ( if I click "💙", hidden "input" appears with the value of existing "text", and after I put new value in the input, the change is reflected to "text", then "input" is hidden, "text" is shown

PB : Line break of Input value is needed. ( content is hidden behind .. )

3.2) DB for "Regular Checklist" and "Daily Checklist" is needed

Both have to be saved in seprate DB, which will be much more comfortable than saving in One collection,

which also means, two seperate Schema is needed also,

1st. Regular Checklist

Schema

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var ChecklistSchema = new Schema({
    rowNum : {
        type : String
    },
    Text : {
        type :  String
    }
});

//recursive한거 때문에 콜스택 에러 발생??
// boardSchema.plugin(require('mongoose-beautiful-unique-validation')); 

const Checklist = mongoose.model('Checklist', ChecklistSchema);
module.exports = {Checklist}


Javascript( send Function)

// Edit 버튼들 
var Edit_Buttons = document.querySelectorAll('.ml-edit')
// Edit_Cancel 버튼들
var Edit_Cancels = document.querySelectorAll('.ml-cancel')
// 현재 내용 
var Edit_Contents = document.querySelectorAll('.ml-auto')
// 입력할 input
var Edit_Inputs = document.querySelectorAll('.ml-input')
// Input Save 버튼
var Edit_Saves  = document.querySelectorAll('.ml-save')

console.log(Edit_Buttons)
console.log(Edit_Contents)
console.log(Edit_Inputs)

for(var i = 0 ; i < Edit_Buttons.length ; i++){

    let CurrentRow = i;
    let Content    = Edit_Contents[i]
    let Input      = Edit_Inputs[i]
    let Btn        = Edit_Buttons[i]
    let Cancel     = Edit_Cancels[i]
    let Save       = Edit_Saves[i]
    
    // Edit 버튼을 클릭하면 , Edit_cancel 과 Textarea는 나타나게 하고, 기존의 Text 내용은 숨긴다 
    Btn.addEventListener('click', function(){
        
        Input.value            = Content.innerHTML

        Input.style.display    = "block"
        Cancel.style.display   = "block"
        Save.style.display     = "block"
        Btn.style.display      = "none"
        Content.style.display  = "none"
        
    })
    
    // Edit-Cancel 버튼을 누르면, 원상복귀시킨다
    Cancel.addEventListener('click', function(){
        
        Save.style.display    = "none"
        Input.style.display   = "none"
        Cancel.style.display  = "none"
        Btn.style.display     = "block"
        Content.style.display = "block"
        
    })
    
    // Edit-save 버튼을 누르면 textarea 값을 text value로 바꿔주고, 동시에 DB에 해당내용을 저장한다
    Save.addEventListener('click', function(){
        
        
        // 1. Input 내용을 DB에 저장해주기 위해 post 내용을 날린다 
        var xhr = new XMLHttpRequest()

        //해당 내용과, 어떤 내용의 글이 수정되는지 확인하기 위해, 각 요일에 대해서 row num을 부여할 것이고, 그것을 위해 i 라는 인자를 전달한다 
        const requestData = `input=${Input.value}&num=${CurrentRow}`
        
        

        xhr.onload = function(){
            
            console.log("post to edit server success")

            if(xhr.status === 200){

                console.log("Save success arrvied in Client")

                // 2. Input 내용을 Content 내용으로 바꿔준다.
                Content.innerHTML   = Input.value
        
                // 3. 해당 내용들을 다시 원상태 visual로 돌려놓는다 
                Save.style.display    = "none"
                Input.style.display   = "none"
                Cancel.style.display  = "none"
                Btn.style.display     = "block"
                Content.style.display = "block"

                // 4. 저장 완료라는 alert를 띄운다
                alert("Checklist Edit Complete")
                
                event.preventDefault();
                return ;

            }else{
                alert("Something wrong going on")
                return false;
            }
        }

        xhr.open('POST','/notice/ChecklistEdit', true);
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhr.send(requestData);

        return ;
    })

}

Server

const express = require('express');
const router = express.Router();
const mongoose = require('mongoose')
const path = require('path');
const { User } = require('../models/User')
const { Checklist } = require('../models/Checklist')
// auth 라는 middleware 을 가져온다 ( 인증처리 )
const { auth } = require( '../middleware/auth' );
const jwt = require('jsonwebtoken');

const mongoURI = '~~~';

mongoose.connect(
    mongoURI,
    { useNewUrlParser : true }
).then(() => console.log("MongoDB Connected in Edit.js")).catch(err => console.log(err))

var connection = mongoose.connection;
connection.on('error', console.error.bind(console, 'connection error:'));

router.post('/notice/ChecklistEdit', ( req, res) => {

    console.log(req.body)

    Checklist.findOneAndUpdate({ rowNum : req.body.num } , {
        $set : {
            Text : req.body.input
        }},
        {
            upsert : true,
            new : true
    } , ( err, doc ) => {
        
        console.log("Checklist update in Server ongoing")
        if(err){
            console.log("Something wrong when updating data")
            console.log("error : " , err )
            return res.status(400).json({ error : err})
        }

        console.log("Checklist update no problem, response is sent to the client")
        
        return res.status(200).json({ 'message' : 'success'})
    })
})

module.exports = router;

Html

<ul class="list-unstyled list-hours mb-5 text-left mx-auto">
                  <li class="list-unstyled-item list-hours-item d-flex">
                    <span class="ml-title">
                      Common 
                      <br/>
                      <span class="ml-edit">💙</span>
                      <span class="ml-cancel"></span>
                      <span class="ml-save"></span>
                    </span>
                    <span class="ml-auto">
                      청소기
                      <br/>
                      물걸레 ( floor, table )
                      <br/>
                      아기 선인장 물주기
                      <br/>
                      샌드위치( 빵, 치즈, 햄 ) 재고 확인
                      <br/>
                    </span>
                    <textarea type="text" class="ml-input"></textarea>
                  </li>
</ul>

2nd. Change "\n" in "textarea" to "actual \n" so that line change is automatically reflected,

If user puts "\n" , it has to be changed into "br", sich works as a "\n" in html

// Edit-save 버튼을 누르면 textarea 값을 text value로 바꿔주고, 동시에 DB에 해당내용을 저장한다
    Save.addEventListener('click', function(){
        
        Input.value            = Input.value.replace(/(?:\r\n|\r|\n)/g, '<br />')
        console.log(Input.value)

        // 1. Input 내용을 DB에 저장해주기 위해 post 내용을 날린다 
        var xhr = new XMLHttpRequest()

        //해당 내용과, 어떤 내용의 글이 수정되는지 확인하기 위해, 각 요일에 대해서 row num을 부여할 것이고, 그것을 위해 i 라는 인자를 전달한다 
        const requestData = `input=${Input.value}&num=${CurrentRow}`
        
        

        xhr.onload = function(){
            
            console.log("post to edit server success")

            if(xhr.status === 200){

                console.log("Save success arrvied in Client")

                // 2. Input 내용을 Content 내용으로 바꿔준다.
                Content.innerHTML   = Input.value
        
                // 3. 해당 내용들을 다시 원상태 visual로 돌려놓는다 
                Save.style.display    = "none"
                Input.style.display   = "none"
                Cancel.style.display  = "none"
                Btn.style.display     = "block"
                Content.style.display = "block"

                // 4. 저장 완료라는 alert를 띄운다
                alert("Checklist Edit Complete")
                
                event.preventDefault();
                return ;

            }else{
                alert("Something wrong going on")
                return false;
            }
        }

        xhr.open('POST','/notice/ChecklistEdit', true);
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhr.send(requestData);

        return ;
    })
profile
Dream of being "물빵개" ( Go abroad for Dance and Programming)

0개의 댓글