Compare commits

...

17 Commits

6 changed files with 142 additions and 34 deletions

Binary file not shown.

View File

@@ -16,7 +16,6 @@
height: 85%;
width: 100%;
padding: 5%;
overflow: auto;
}
#menu {
@@ -40,4 +39,25 @@
#taskButton {
padding-left: 0;
}
#historyContent {
height: 75%;
overflow: scroll;
width: 100%;
}
#stats {
height: 25%;
width: 100%;
}
#tasks {
overflow: scroll;
}
pre {
padding: 0;
background: white;
border-radius: 0;
}

View File

@@ -29,7 +29,17 @@
<div id="mainPage" style="display: none;">
<div id="content">
<div id="tasks" class="screen flex two demo" style=""></div>
<div id="history" class="screen" style="display: none;"></div>
<div id="history" class="screen" style="display: none;">
<div id="stats">
<article class="card">
<header>
<h1>Stats</h1>
<pre id="statData"></pre>
</header>
</article>
</div>
<div id="historyContent"></div>
</div>
<div id="addTask" class="screen" style="display: none;">Add Task</div>
</div>
<div id="menu" class="flex three demo">

View File

@@ -54,22 +54,43 @@ async function populateScreen() {
let tasks = tasksRaw.tasks;
// get historical data
let historyPage = document.getElementById("history");
let historyPage = document.getElementById("historyContent");
historyPage.innerHTML = "";
response = await fetch("/getHistory");
let historyRaw = await response.json();
let history = historyRaw.history;
// get points data
let statsPage = document.getElementById("statData");
statsPage.innerText = "";
response = await fetch("/getUserPoints");
let statsRaw = await response.json();
let stats = statsRaw.userPoints;
for (let i = 0; i < tasks.length; i++) {
taskPage.innerHTML += `
<div id="${tasks[i].tid}" class="half" style="height: fit-content">
<div class="button" onclick="completeTask(${tasks[i].tid})">
<p id="taskName">${tasks[i].name}</p>
<p id="${tasks[i].tid}-p">${tasks[i].points} points</p>
</div>
</div>`
// if it is a user make the tasks add points
// or if admin make it do nothing
if (sessionStorage.getItem("role") === "user") {
for (let i = 0; i < tasks.length; i++) {
taskPage.innerHTML += `
<div id="${tasks[i].tid}" class="half" style="height: fit-content">
<div class="button" onclick="completeTask(${tasks[i].tid})">
<p id="taskName">${tasks[i].name}</p>
<p id="${tasks[i].tid}-p">${tasks[i].points} points</p>
</div>
</div>`
}
} else if (sessionStorage.getItem("role") === "admin") {
for (let i = 0; i < tasks.length; i++) {
taskPage.innerHTML += `
<div id="${tasks[i].tid}" class="half" style="height: fit-content">
<div class="button" disabled data-tooltip="Admins can't get points">
<p id="taskName">${tasks[i].name}</p>
<p id="${tasks[i].tid}-p">${tasks[i].points} points</p>
</div>
</div>`
}
}
for (let i = (history.length -1); i >= 0; i-=1) {
historyPage.innerHTML += `
<div class="full">
@@ -83,13 +104,17 @@ async function populateScreen() {
</article>
</div>`
}
for (let i = 0; i < stats.length; i++) {
// put user points in box
statsPage.innerText += `${stats[i].name}: ${stats[i].points} \n`
}
}
async function completeTask(taskID) {
let points = document.getElementById(`${taskID}-p`).innerText;
let points = document.getElementById(`${taskID}-p`).innerText.split(" ")[0];
let time = new Date().toISOString().split(".")[0];
let uid = sessionStorage.getItem("uid");
let response = await fetch("/completeTask", {
await fetch("/completeTask", {
method: "POST",
headers: {
"Content-Type": "application/json",

BIN
main

Binary file not shown.

95
main.go
View File

@@ -2,6 +2,7 @@ package main
import (
"database/sql"
"flag"
"github.com/gin-gonic/gin"
_ "github.com/mattn/go-sqlite3"
"net/http"
@@ -17,11 +18,12 @@ type loginInput struct {
Password string `json:"password"`
}
type loginOutput struct {
type userData struct {
UID int `json:"uid"`
Name string `json:"name"`
Password string `json:"password"`
Role string `json:"role"`
Points int `json:"points"`
}
type task struct {
@@ -34,14 +36,14 @@ type taskArray struct {
Tasks []task `json:"tasks"`
}
type historyReqData struct {
type newHistoryData struct {
UID int `json:"uid"`
TID int `json:"tid"`
Time string `json:"time"`
PointsGained int `json:"pointsGained"`
}
type historyResData struct {
type historyData struct {
User string `json:"user"`
Task string `json:"task"`
Time string `json:"time"`
@@ -49,32 +51,41 @@ type historyResData struct {
}
type historyArray struct {
History []historyResData `json:"history"`
History []historyData `json:"history"`
}
type userPointsData struct {
Name string `json:"name"`
Points int `json:"points"`
}
type userPointsArray struct {
UserPoints []userPointsData `json:"userPoints"`
}
// log the user into their account
func login(c *gin.Context) {
// get the username and password from the request
var userData loginInput
if err := c.BindJSON(&userData); err != nil {
c.IndentedJSON(http.StatusBadRequest, userData)
var requestedUser loginInput
if err := c.BindJSON(&requestedUser); err != nil {
c.IndentedJSON(http.StatusBadRequest, requestedUser)
return
}
// check for user using given credentials
stmt, err := db.Prepare("SELECT * FROM users WHERE name=?")
checkErr(err)
defer stmt.Close()
var user loginOutput
err = stmt.QueryRow(userData.Name).Scan(&user.UID, &user.Name, &user.Password, &user.Role)
var user userData
err = stmt.QueryRow(requestedUser.Name).Scan(&user.UID, &user.Name, &user.Password, &user.Role, &user.Points)
if err != nil {
// search failed user not real
c.IndentedJSON(http.StatusNotFound, userData)
c.IndentedJSON(http.StatusNotFound, requestedUser)
panic(err)
return
}
if user.Password != userData.Password {
if user.Password != requestedUser.Password {
// user not real
c.IndentedJSON(http.StatusNotFound, userData)
c.IndentedJSON(http.StatusNotFound, requestedUser)
panic(err)
return
} else {
@@ -107,7 +118,7 @@ func getTasks(c *gin.Context) {
func completeTask(c *gin.Context) {
// get the task data from the request
var completedTask historyReqData
var completedTask newHistoryData
if err := c.BindJSON(&completedTask); err != nil {
c.IndentedJSON(http.StatusBadRequest, completedTask)
return
@@ -123,17 +134,30 @@ func completeTask(c *gin.Context) {
c.IndentedJSON(http.StatusNotModified, completedTask)
return
}
// add points to user table
stmt, err = db.Prepare("UPDATE users SET points = points + ? WHERE uid=?")
if err != nil {
c.IndentedJSON(http.StatusNotModified, completedTask)
return
}
_, err = stmt.Exec(completedTask.PointsGained, completedTask.UID)
if err != nil {
c.IndentedJSON(http.StatusNotModified, completedTask)
return
}
c.IndentedJSON(http.StatusOK, completedTask)
}
func getHistory(c *gin.Context) {
// get the log of past points gained
var history []historyReqData
// get array of all historyReqData
var history []newHistoryData
// get array of all history Data
rows, err := db.Query("SELECT * FROM history")
checkErr(err)
for rows.Next() {
var tempHistoryData historyReqData
var tempHistoryData newHistoryData
err = rows.Scan(&tempHistoryData.UID, &tempHistoryData.TID, &tempHistoryData.Time, &tempHistoryData.PointsGained)
if err != nil {
c.IndentedJSON(http.StatusNotFound, history)
@@ -143,15 +167,15 @@ func getHistory(c *gin.Context) {
}
rows.Close()
var historyRes []historyResData
var historyRes []historyData
// make the data human-readable
for i := 0; i < len(history); i++ {
var tempHistory historyResData
var tempHistory historyData
// get the username
var tempUser loginOutput
var tempUser userData
stmt, err := db.Prepare("SELECT * FROM users WHERE uid=?")
checkErr(err)
err = stmt.QueryRow(history[i].UID).Scan(&tempUser.UID, &tempUser.Name, &tempUser.Password, &tempUser.Role)
err = stmt.QueryRow(history[i].UID).Scan(&tempUser.UID, &tempUser.Name, &tempUser.Password, &tempUser.Role, &tempUser.Points)
checkErr(err)
tempHistory.User = tempUser.Name
stmt.Close()
@@ -197,7 +221,35 @@ func addTask(c *gin.Context) {
c.IndentedJSON(http.StatusOK, newTask)
}
func getUserPoints(c *gin.Context) {
// get the names of all users
var allUsers []userPointsData
rows, err := db.Query("SELECT name, points FROM users WHERE role='user'")
checkErr(err)
// put them in an array of users
for rows.Next() {
var tempUser userPointsData
err = rows.Scan(&tempUser.Name, &tempUser.Points)
if err != nil {
c.IndentedJSON(http.StatusNotFound, allUsers)
return
}
allUsers = append(allUsers, tempUser)
}
rows.Close()
// return to the requester
var jsonUserPoints userPointsArray
jsonUserPoints.UserPoints = allUsers
c.IndentedJSON(http.StatusOK, jsonUserPoints)
}
func main() {
var port string
flag.StringVar(&port, "port", "localhost:8080", "define the port you want the program to use to serve")
flag.Parse()
//release mode
//gin.SetMode(gin.ReleaseMode)
router := gin.Default()
@@ -208,6 +260,7 @@ func main() {
router.POST("/addTask", addTask)
router.GET("/getTasks", getTasks)
router.GET("/getHistory", getHistory)
router.GET("/getUserPoints", getUserPoints)
// page routes
router.LoadHTMLGlob("frontend/*")
@@ -216,7 +269,7 @@ func main() {
})
router.Static("/frontend", "./frontend")
router.Run("localhost:8080")
router.Run(port)
}
func checkErr(err error) {