Rundown of Final Version of our code - Alna132/GO-Group-Web-App GitHub Wiki
- index.html
- Internal.html
- login.html
- signup.html
Main.go
This page is the first thing a user will see on this website, it is accessible to a user regardless of having an account set up.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WorkTracker</title>
<!-- Stylesheets -->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- JQuery -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<!--Adapted from: https://www.sitepoint.com/ -->
</head>
<body>
<!-- Use Jumbotron template from Bootstrap as our look to the website -->
<div class="jumbotron">
<!-- Display Home Page Header -->
<h1>Home Page</h1>
</div>
<!-- Create a navbar fixed to the top of the website -->
<nav class="navbar navbar-inverse navbar-fixed-top">
<!-- Like a Stackpanel in C#, A container handles how things are formatted/spaced out -->
<div class="container">
<!-- Create a NavBar Header -->
<div class="navbar-header">
<!-- Creating the NavBar styling -->
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<!-- Using the Success button to create a green button with a Login Link on it -->
<button class="btn btn-success"><a href="/login">Login</a></button>
<!-- Using the Warning button to create an Orange button with a Sign Up Link on it -->
<button class="btn btn-warning"><a href="/signup">Sign Up</a></button>
<button class="navbar-toggle collapsed">To get navbar-brand to appear</button>
<!-- The title of the website -->
<a class="navbar-brand" href="#">Work Tracker</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<form class="navbar-form navbar-right">
</form>
</form>
</body>
</html>
This page is only accessible to a user if they have signed up to the website with a username and password, this user is already stored in the database.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<h1>-</h1>
<hr>
<small>Welcome!</small>
<html ng-app> <!-- 'ng-app'' placed within a tag (in this case, the HTML tag)
allows HTML to become the route element for AngularJS.
All AngularJS applications must have a root element. Only one instance allowed. -->
<head>
<title>WorkTracker</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<!--Adapted from: https://www.sitepoint.com/ -->
<!-- Using JavaScript -->
<script language="javascript">
// Create a Function called Calculate()
function Calculate()
{
//Create a variable called h which gets the values in the hoursWorked dropdownlist
var h = document.getElementById('hoursWorked').value;
//Create a variable called t which gets the values in the hourlyPay dropdownlist
var t = document.getElementById('hourlyPay').value;
// multiply h (hoursWorked) by t (hourlyPay)
var result = h * t;
//Output this result to a label
document.getElementById('lblRes').innerHTML = result;
}
//End the JavaScript
</script>
</head>
<body>
<!-- Main jumbotron for a primary marketing message or call to action -->
<div class="jumbotron">
<!--Changed the top header here to include a name being entered and shown back to the user with a friendly hello-->
<div class="container">
<h2><input type="text" placeholder="Your Name here" ng-model="yes"></h2>
<h3><p>Hello <span ng-bind="yes"></span></p></h3>
<p>This is a place where you can record all of your daily duties in one place, ready to show the boss. </p>
</div>
</div>
<div class="container">
</div>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<form method="post" action="/logout">
<button type="submit" class="btn btn-danger">Logout</button>
</button>
<a class="navbar-brand" href="#">Work Tracker</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<form class="navbar-form navbar-right">
</form>
</form>
</div><!--/.navbar-collapse -->
</div>
</nav>
<div class="container">
<!-- Example row of columns -->
<div class="row">
<div class="col-md-4">
<h2>Job Title</h2>
<!-- Dropdown list with Tradesperson's job titles
adapted from https://www.socketloop.com/tutorials/golang-populate-dropdown-with-html-template-example -->
<select>
<option value="Beautician">Beautician</option>
<option value="Builder">Builder</option>
<option value="Carpenter">Carpenter</option>
<option value="Cleaner">Cleaner</option>
<option value="Delivery">Delivery</option>
<option value="Electrician">Electrician</option>
<option value="Farmer">Farmer</option>
<option value="Gardener">Gardener</option>
<option value="Hair and Beauty">Hair and Beauty</option>
<option value="Hairdresser">Hairdresser</option>
<option value="Mechanic">Mechanic</option>
<option value="Painter">Painter</option>
<option value="Plumber">Plumber</option>
<option value="Technician">Technician</option>
<option value="Tiler">Tiler</option>
<option value="Transport">Transport</option>
<option value="Other">Other</option>
<!-- Code adapted from http://stackoverflow.com/questions/30717105/adding-view-details-button-with-js -->
</select>
<!-- Allows you to see more information about the dropdown list -->
<details>
<summary>View Details</summary>
<p>
Please select your correct job title here from the dropdown list.
</p>
</details>
</div>
<!-- Code adapted from http://www.w3schools.com/html/html_form_elements.asp -->
<div class="col-md-4">
<!-- Dropdown list with Tradesperson's hours worked that week, min 10 max 40 -->
<h2>Hours Worked This Week</h2>
<select Id="hoursWorked" onChange="Calculate();">
<option value=10>10</option>
<option value=11>11</option>
<option value=12>12</option>
<option value=13>13</option>
<option value=14>14</option>
<option value=15>15</option>
<option value=16>16</option>
<option value=17>17</option>
<option value=18>18</option>
<option value=19>19</option>
<option value=20>20</option>
<option value=21>21</option>
<option value=22>22</option>
<option value=23>23</option>
<option value=24>24</option>
<option value=25>25</option>
<option value=26>26</option>
<option value=27>27</option>
<option value=28>28</option>
<option value=29>29</option>
<option value=30>30</option>
<option value=31>31</option>
<option value=32>32</option>
<option value=33>33</option>
<option value=34>34</option>
<option value=35>35</option>
<option value=36>36</option>
<option value=37>37</option>
<option value=38>38</option>
<option value=39>39</option>
<option value=40>40</option>
</select>
<!-- See function in header, it calculates hourly pay that the worker receives -->
*
Hourly Pay:
<select Id="hourlyPay" onChange="Calculate();">
<!-- This dropdown list contains the pay rates that are multiplied by the hours worked by the Tradesperson
within the calculation in the header above -->
<option value=6.24>6.24</option>
<option value=7.25>7.25</option>
<option value=9.15>9.15</option>
<option value=11.25>11.25</option>
<option value=20.83>20.83</option>
</select>
<!-- Just inserts a few spaces -->
= Total:
<!-- label -->
<label id="lblRes"> <!-- result of Calculating hoursWorked * hourlyPay -->
100
</label>
<details>
<summary>View Details</summary>
<p>
Please select the correct amount of hours you worked this week.
<br> Please note: In order to use this site you have to be working a minimum of 10 hours a week and a maximum of 40 hours. </br>
</p>
</details>
</div>
<!-- A textbox which the user can enter into to tell their boss any additional information about their week's work -->
<div class="col-md-4">
<h2>Additonal Information</h2>
<!--Adapted from http://www.w3schools.com/tags/tag_input.asp-->
<!-- A form action to submit all of the details given on the form -->
<form action="demo_form.asp">
<input type="text" name="AddInfo" value=""><br>
<input type="submit" value="Submit">
</form>
<details>
<summary>View Details</summary>
<p>
Please add any additional information that you feel is relevent for your boss to know about regarding this week's work.
</p>
</details>
</div>
</div>
<hr>
<!-- Just including a Company trademark in the footer -->
<footer>
<p>© 2016 WorkTracker, Inc.</p>
</footer>
</div> <!-- /container -->
<!-- To use AngularJS -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.3/angular.min.js"></script>
</body>
</html>
This is the page that allows the user to Signup to the website.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WorkTracker</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<!--Adapted from: https://www.sitepoint.com/ -->
</head>
<body>
<div class="jumbotron">
<h1>Sign up</h1>
<form method="POST" action="/signup">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="Submit">
</form>
</div>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<button class="navbar-toggle collapsed">To get navbar-brand to appear<button>
<a class="navbar-brand" href="#">Work Tracker</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<form class="navbar-form navbar-right">
</form>
</form>
</body>
</html>
This is the page that allows the user to login to the website.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WorkTracker</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<!--Adapted from: https://www.sitepoint.com/ -->
</head>
<body>
<div class="jumbotron">
<h1>Login Page</h1>
<form method="POST" action="/login">
<input type="text" name="username" placeholder="username">
<input type="password" name="password" placeholder="password">
<input type="submit" value="Submit">
</form>
</div>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<button class="navbar-toggle collapsed">To get navbar-brand to appear</button>
<a class="navbar-brand" href="#">Work Tracker</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<form class="navbar-form navbar-right">
</form>
</form>
</body>
</html>
This file contains all of the golang code and handles the connection between the client and server
//https://dinosaurscode.xyz/go/2016/06/19/golang-mysql-authentication/
package main
// This allows us to use the SQL Database
import "database/sql" //need to type "database/sql" into cmder to use
// This installs a driver in order to be able to use mySQL
import _ "github.com/go-sql-driver/mysql" //need to type "github.com/go-sql-driver/mysql" into cmder to use
// This import statement allows encryption and decryption of passwords
import "golang.org/x/crypto/bcrypt" //need to type "golang.org/x/crypto/bcrypt" into cmder to use
import "net/http"
//A variable which initialises the use of sql
var db *sql.DB
// A variable ro handle errors
var err error
//We start off with a Signup function so the user can Signup
// We initialise the use of the response (res) using the ResponseWriter
// and the request (req) by using http.Request
func signupPage(res http.ResponseWriter, req *http.Request) {
//If the request is not a POST method (the POST request method requests that a web server accept and store
// the data enclosed in the body of the request message. It is used when submitting a completed web Form)
if req.Method != "POST" {
//then serve the SignUp page
http.ServeFile(res, req, "signup.html")
return
}
//The username and password are set up as a formValue
username := req.FormValue("username")
password := req.FormValue("password")
//the user is initialised as a string
var user string
// Query the database to see if the user signing in is clashing credentials
//with any existing users within the database
err := db.QueryRow("SELECT username FROM users WHERE username=?", username).Scan(&user)
//a switch statement to handle the signin
switch {
case err == sql.ErrNoRows:
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
//If the error list is not equal to null, in other words if there is (are) error(s)
if err != nil {
//There will be a server error 500 and your account will not be created
http.Error(res, "Server error, unable to create your account.", 500)
return
}
// The "_" (blank identifier) avoids having to declare all the variables for the return values.
// Try inserting a username and password into the users table abd encrypt the password
_, err = db.Exec("INSERT INTO users(username, password) VALUES(?, ?)", username, hashedPassword)
//If there are errors
if err != nil {
// The response (res) will say Server eror 500 and you can't create your account
http.Error(res, "Server error, unable to create your account.", 500)
return
}
// Otherwise A user is created
res.Write([]byte("User created!"))
return
case err != nil:
http.Error(res, "Server error, unable to create your account.", 500)
return
default:
http.Redirect(res, req, "/", 301)
}
}
// This is a function to allow a user to log into the website
func loginPage(res http.ResponseWriter, req *http.Request) {
if req.Method != "POST" {
http.ServeFile(res, req, "login.html")
return
}
username := req.FormValue("username")
password := req.FormValue("password")
//This time we have a Username variable and a Password variable
var databaseUsername string
var databasePassword string
//Scan the database to find the returning user as they login with their username and password
err := db.QueryRow("SELECT username, password FROM users WHERE username=?", username).Scan(&databaseUsername, &databasePassword)
//If there are errors with the user logging in
if err != nil {
//Error 301
http.Redirect(res, req, "/login", 301)
return
}
err = bcrypt.CompareHashAndPassword([]byte(databasePassword), []byte(password))
if err != nil {
http.Redirect(res, req, "/login", 301)
return
}
//If all is successful, serve up the internal.html file which only a logged-in user should be able to see
http.ServeFile(res, req, "Internal.html")
//res.Write([]byte("Hello" + databaseUsername))
}
//A function to serve up the homepage called index.html which includes the login and signup buttons
func homePage(res http.ResponseWriter, req *http.Request) {
http.ServeFile(res, req, "index.html")
}
//Main function
func main() {
//Open an sql connection, and handle errors,
// The database is mysql, then we have the hostName of the server on Azure (b71da173aea4cf)
// (05606ea1)
//TCP stands for Transmission Control Protocol which is a set of networking protocols that allows
// two or more computers to communicate
// (eu-cdbr-azure-west-a.cloudapp.net)
// Port Name on Azure (3306)
// The name of the database (godatabase)
db, err = sql.Open("mysql", "b71da173aea4cf:05606ea1@tcp(eu-cdbr-azure-west-a.cloudapp.net:3306)/godatabase")
//If there are errors connecting to the server
if err != nil {
//output a panic error
panic(err.Error())
}
//close the connection to the database
defer db.Close()
//Checking is the connection to the database still alive
err = db.Ping()
//otherwise painic
if err != nil {
panic(err.Error())
}
//Handle all of our functions
http.HandleFunc("/signup", signupPage)
http.HandleFunc("/login", loginPage)
http.HandleFunc("/", homePage)
//serve on the port 8000 forever
http.ListenAndServe(":8000", nil)
}