ソースを参照

Item deletion, time left calculation, login redirection

Frans Bergman 8 年 前
コミット
b2ff13ea68
7 ファイル変更127 行追加65 行削除
  1. 4 0
      css/style.css
  2. 1 1
      deploy.sh
  3. 9 0
      index.php
  4. 47 0
      js/LoginForm.jsx
  5. 57 58
      js/index.js
  6. 1 0
      package.json
  7. 8 6
      php/api.php

+ 4 - 0
css/style.css

@@ -7,3 +7,7 @@ form textarea {
   width: 100%;
   width: 100%;
   height: 100px;
   height: 100px;
 }
 }
+
+span.deadline {
+  float: right;
+}

+ 1 - 1
deploy.sh

@@ -1 +1 @@
-sftp pi@tankernn.eu:/var/www/todo <<< $'put bundle.js\nput php/api.php php/api.php\nput index.html\nput css/style.css css/style.css'
+sftp pi@tankernn.eu:/var/www/todo <<< $'put bundle.js\nput php/api.php php/api.php\nput index.php\nput css/style.css css/style.css'

+ 9 - 0
index.html → index.php

@@ -1,3 +1,12 @@
+<?php
+  session_name('default');
+  session_set_cookie_params(0, '/', '.tankernn.eu');
+  session_start();
+  if (!isset($_SESSION['userid'])) {
+    header("Location: http://tankernn.eu/login?redirect=http://todo.tankernn.eu");
+  }
+?>
+
 <!DOCTYPE html>
 <!DOCTYPE html>
 <html>
 <html>
 
 

+ 47 - 0
js/LoginForm.jsx

@@ -0,0 +1,47 @@
+const LOGIN_URL = "https://tankernn.eu/login/check_login.php";
+
+var LoginForm = React.createClass({
+  getInitialState: function() {
+    return {user: '', pass: ''};
+  },
+  handleUserChange: function(e) {
+    this.setState({user: e.target.value});
+  },
+  handlePassChange: function(e) {
+    this.setState({pass: e.target.value});
+  },
+  handleSubmit: function(e) {
+    e.preventDefault();
+    var user = this.state.user;
+    var pass = this.state.pass;
+    if (!user || !pass) {
+      return;
+    }
+    this.props.onLoginSubmit({user: user, pass: pass});
+    this.setState(this.getInitialState());
+  },
+  render: function() {
+    return (
+      <form id="loginForm" name="loginForm" onSubmit={this.handleSubmit}>
+        <FormControl type="text" value={this.state.user} onChange={this.handleUserChange} />
+        <FormControl type="password" value={this.state.pass} onChange={this.handlePassChange} />
+        <Button bsStyle="primary" type="submit">Log in</Button>
+      </form>
+    );
+  }
+});
+
+var handleLoginSubmit = function(data) {
+  $.ajax({
+    url: LOGIN_URL,
+    cache: false,
+    type: 'POST',
+    data: data,
+    success: function(result) {
+      console.log(result);
+      this.forceUpdate();
+    }.bind(this)
+  });
+}
+
+<LoginForm onLoginSubmit=handleLoginSubmit />

+ 57 - 58
js/index.js

@@ -2,20 +2,25 @@ var React = require('react');
 var ReactDOM = require('react-dom');
 var ReactDOM = require('react-dom');
 var Remarkable = require('remarkable');
 var Remarkable = require('remarkable');
 var Button = require('react-bootstrap').Button;
 var Button = require('react-bootstrap').Button;
+var ButtonToolbar = require('react-bootstrap').ButtonToolbar;
 var FormControl = require('react-bootstrap').FormControl;
 var FormControl = require('react-bootstrap').FormControl;
 var FormGroup = require('react-bootstrap').FormGroup;
 var FormGroup = require('react-bootstrap').FormGroup;
 var Panel = require('react-bootstrap').Panel;
 var Panel = require('react-bootstrap').Panel;
 var DatePicker = require('react-bootstrap-date-picker');
 var DatePicker = require('react-bootstrap-date-picker');
+var dateFormat = require('dateformat');
 var $ = require('jquery');
 var $ = require('jquery');
 
 
-const LOGIN_URL = "https://tankernn.eu/login/check_login.php";
 const API_URL = "https://todo.tankernn.eu/php/api.php";
 const API_URL = "https://todo.tankernn.eu/php/api.php";
 
 
 const priorityNames = {1: "danger", 2: "warning", 3: "primary", 4: "success"};
 const priorityNames = {1: "danger", 2: "warning", 3: "primary", 4: "success"};
 
 
+function dateToString(date) {
+  return dateFormat(date, "yyyy-mm-dd");
+}
+
 var TodoForm = React.createClass({
 var TodoForm = React.createClass({
   getInitialState: function() {
   getInitialState: function() {
-    return {title: '', text: '', deadline: new Date().toISOString(), priority: '1'};
+    return {title: '', text: '', deadline: new Date().toISOString(), priority: 1};
   },
   },
   handleTitleChange: function(e) {
   handleTitleChange: function(e) {
     this.setState({title: e.target.value});
     this.setState({title: e.target.value});
@@ -34,7 +39,7 @@ var TodoForm = React.createClass({
     var title = this.state.title.trim();
     var title = this.state.title.trim();
     var text = this.state.text.trim();
     var text = this.state.text.trim();
     var priority = this.state.priority;
     var priority = this.state.priority;
-    var deadline = this.state.deadline;
+    var deadline = dateToString(this.state.deadline);
     console.log(deadline);
     console.log(deadline);
     if (!title || !text || !deadline) {
     if (!title || !text || !deadline) {
       return;
       return;
@@ -73,37 +78,6 @@ var TodoForm = React.createClass({
   }
   }
 });
 });
 
 
-var LoginForm = React.createClass({
-  getInitialState: function() {
-    return {user: '', pass: ''};
-  },
-  handleUserChange: function(e) {
-    this.setState({user: e.target.value});
-  },
-  handlePassChange: function(e) {
-    this.setState({pass: e.target.value});
-  },
-  handleSubmit: function(e) {
-    e.preventDefault();
-    var user = this.state.user;
-    var pass = this.state.pass;
-    if (!user || !pass) {
-      return;
-    }
-    this.props.onLoginSubmit({user: user, pass: pass});
-    this.setState(this.getInitialState());
-  },
-  render: function() {
-    return (
-      <form id="loginForm" name="loginForm" onSubmit={this.handleSubmit}>
-        <FormControl type="text" value={this.state.user} onChange={this.handleUserChange} />
-        <FormControl type="password" value={this.state.pass} onChange={this.handlePassChange} />
-        <Button bsStyle="primary" type="submit">Log in</Button>
-      </form>
-    );
-  }
-});
-
 var Item = React.createClass({
 var Item = React.createClass({
   rawMarkup: function() {
   rawMarkup: function() {
     var md = new Remarkable();
     var md = new Remarkable();
@@ -113,10 +87,37 @@ var Item = React.createClass({
   handleEditClick: function() {
   handleEditClick: function() {
     console.log("I wanna edit.");
     console.log("I wanna edit.");
   },
   },
+  handleDeleteClick: function() {
+    console.log("Deleting " + this.props.id);
+    this.props.handleDeleteClick(this.props.id);
+
+  },
   render: function() {
   render: function() {
     var md = new Remarkable();
     var md = new Remarkable();
+
+    var daysLeft = Math.ceil((new Date(this.props.deadline) - new Date()) / (1000 * 60 * 60 * 24));
+
+    if (daysLeft > 1) {
+      daysLeft += " days left.";
+    } else if (daysLeft == 1) {
+      daysLeft = "One day left.";
+    } else if (daysLeft == 0) {
+      daysLeft = "Today!";
+    } else {
+      daysLeft = "Should have been done " + Math.abs(daysLeft) + " day(s) ago."
+    }
+
     return (
     return (
-      <Panel header={this.props.title} footer={<FormGroup><Button bsStyle="primary" onClick={this.handleEditClick}>Edit</Button><Button bsStyle="danger">Delete</Button></FormGroup>} bsStyle={priorityNames[this.props.priority]}>
+      <Panel
+        header={<header><span className="deadline">{daysLeft}</span><h3>{this.props.title}</h3></header>}
+        footer={
+          <ButtonToolbar>
+            <Button bsStyle="primary" onClick={this.handleEditClick}>Edit</Button>
+            <Button bsStyle="danger" onClick={this.handleDeleteClick}>Delete</Button>
+          </ButtonToolbar>
+        }
+        bsStyle={priorityNames[this.props.priority]}
+      >
         <span dangerouslySetInnerHTML={this.rawMarkup()} />
         <span dangerouslySetInnerHTML={this.rawMarkup()} />
       </Panel>
       </Panel>
     );
     );
@@ -126,9 +127,10 @@ var Item = React.createClass({
 var TodoList = React.createClass({
 var TodoList = React.createClass({
   render: function() {
   render: function() {
     console.log(this.props.list);
     console.log(this.props.list);
+    var onDeleteClick = this.props.onDeleteClick;
     var itemList = this.props.list.map(function(item) {
     var itemList = this.props.list.map(function(item) {
       return (
       return (
-        <Item priority={item.priority} title={item.title} key={item.id} deadline={item.deadline}>
+        <Item handleDeleteClick={onDeleteClick} priority={item.priority} title={item.title} id={item.id} key={item.id} deadline={item.deadline}>
           {item.description}
           {item.description}
         </Item>
         </Item>
       );
       );
@@ -172,6 +174,9 @@ var App = React.createClass({
         if (data.result != 0) {
         if (data.result != 0) {
           console.log("Error in API: " + data.result);
           console.log("Error in API: " + data.result);
         }
         }
+        if (data.hasOwnProperty("message")) {
+          console.log("API message: " + data.message);
+        }
         this.setState({list: data.list, result: data.result});
         this.setState({list: data.list, result: data.result});
       }.bind(this),
       }.bind(this),
       error: function(xhr, status, err) {
       error: function(xhr, status, err) {
@@ -180,35 +185,29 @@ var App = React.createClass({
       }.bind(this)
       }.bind(this)
     });
     });
   },
   },
-  handleLoginSubmit: function(data) {
+  handleDelete: function(id) {
     $.ajax({
     $.ajax({
-      url: LOGIN_URL,
+      url: this.props.url,
+      dataType: 'json',
       cache: false,
       cache: false,
       type: 'POST',
       type: 'POST',
-      data: data,
-      success: function(result) {
-        console.log(result);
-        this.forceUpdate();
+      data: {a: 'rm', id: id},
+      success: function(data) {
+        this.setState({list: data.list, result: data.result});
+      }.bind(this),
+      error: function(xhr, status, err) {
+        console.error(this.props.url, status, err.toString());
       }.bind(this)
       }.bind(this)
     });
     });
   },
   },
   render: function() {
   render: function() {
-    console.log(this.state);
-    if (this.state.result != 1)
-      return (
-        <main>
-          <h1>Tankernn TODO list</h1>
-          <TodoForm onCommentSubmit={this.handleCommentSubmit} />
-          <TodoList list={this.state.list} />
-        </main>
-      );
-    else
-      return (
-        <main>
-          <h1>Tankernn TODO list</h1>
-          <LoginForm onLoginSubmit={this.handleLoginSubmit} />
-        </main>
-      );
+    return (
+      <main>
+        <h1>Tankernn TODO list</h1>
+        <TodoForm onCommentSubmit={this.handleCommentSubmit} />
+        <TodoList onDeleteClick={this.handleDelete} list={this.state.list} />
+      </main>
+    );
   }
   }
 });
 });
 
 

+ 1 - 0
package.json

@@ -6,6 +6,7 @@
   "dependencies": {
   "dependencies": {
     "babel-preset-react": "^6.16.0",
     "babel-preset-react": "^6.16.0",
     "babelify": "^7.3.0",
     "babelify": "^7.3.0",
+    "dateformat": "^1.0.12",
     "jquery": "^3.1.1",
     "jquery": "^3.1.1",
     "moment": "^2.15.1",
     "moment": "^2.15.1",
     "react": "^15.3.2",
     "react": "^15.3.2",

+ 8 - 6
php/api.php

@@ -14,9 +14,8 @@
     $data->result = 1;
     $data->result = 1;
   } else {
   } else {
     $userid = $_SESSION['userid'];
     $userid = $_SESSION['userid'];
-    if (!isset($_POST['a'])) {
-      $data->result = 2;
-    } else {
+    if (isset($_POST['a'])) {
+      // Additional actions to perform before returning the list
       switch ($_POST['a']) {
       switch ($_POST['a']) {
         case 'add':
         case 'add':
           $title = $_POST['title'];
           $title = $_POST['title'];
@@ -24,15 +23,18 @@
           $deadline = $_POST['deadline'];
           $deadline = $_POST['deadline'];
           $priority = $_POST['priority'];
           $priority = $_POST['priority'];
 
 
-          $sql = "INSERT INTO Todo (userid, priority, deadline, title, description) VALUES ($userid, $priority, $deadline, '$title', '$text')";
+          $data->message = $deadline;
+
+          $sql = "INSERT INTO Todo (userid, priority, deadline, title, description) VALUES ($userid, $priority, '$deadline', '$title', '$text')";
 
 
           $data->result = $conn->query($sql) ? 0 : $conn->error;
           $data->result = $conn->query($sql) ? 0 : $conn->error;
 
 
           break;
           break;
         case 'rm':
         case 'rm':
-          $id = $_GET['id'];
+          $id = $_POST['id'];
 
 
-          $sql = "DELETE FROM Todo WHERE id=$id";
+          $sql = "DELETE FROM Todo WHERE id=$id AND userid=$userid";
+          $data->result = $conn->query($sql) ? 0 : $conn->error;
           break;
           break;
       }
       }
     }
     }