Initial commit
This commit is contained in:
commit
f52bf43344
|
@ -0,0 +1,7 @@
|
||||||
|
module main
|
||||||
|
|
||||||
|
go 1.22.1
|
||||||
|
|
||||||
|
require github.com/go-sql-driver/mysql v1.8.1
|
||||||
|
|
||||||
|
require filippo.io/edwards25519 v1.1.0 // indirect
|
|
@ -0,0 +1,4 @@
|
||||||
|
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||||
|
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||||
|
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||||
|
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
|
@ -0,0 +1,236 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/go-sql-driver/mysql"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getIndex(w http.ResponseWriter, r *http.Request) {
|
||||||
|
tmpl, err := template.ParseFiles("templates/index.tmpl")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tmpl.Execute(w, nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getParamedicView(w http.ResponseWriter, r *http.Request) {
|
||||||
|
tmpl, err := template.ParseFiles("templates/paramedicForm.tmpl")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tmpl.Execute(w, nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Alert struct {
|
||||||
|
Id int
|
||||||
|
|
||||||
|
// Categorization
|
||||||
|
MedicalOrTrauma string
|
||||||
|
|
||||||
|
// Patient data
|
||||||
|
Age string
|
||||||
|
Sex string
|
||||||
|
NhsNumber string
|
||||||
|
|
||||||
|
// Observations
|
||||||
|
HeartRate string
|
||||||
|
RespiratoryRate string
|
||||||
|
OxygenSaturation string
|
||||||
|
Gcs string
|
||||||
|
BloodPressure string
|
||||||
|
|
||||||
|
// Extra information
|
||||||
|
Eta string
|
||||||
|
Interventions string
|
||||||
|
BackgroundInfo string
|
||||||
|
}
|
||||||
|
|
||||||
|
func postParamedicForm(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Parse data from form
|
||||||
|
var alert Alert
|
||||||
|
alert.MedicalOrTrauma = r.PostFormValue("medical-or-trauma")
|
||||||
|
alert.Age = r.PostFormValue("age")
|
||||||
|
alert.Sex = r.PostFormValue("sex")
|
||||||
|
alert.NhsNumber = r.PostFormValue("nhs-number")
|
||||||
|
alert.HeartRate = r.PostFormValue("heart-rate")
|
||||||
|
alert.RespiratoryRate = r.PostFormValue("respiratory-rate")
|
||||||
|
alert.OxygenSaturation = r.PostFormValue("oxygen-saturation")
|
||||||
|
alert.Gcs = r.PostFormValue("gcs")
|
||||||
|
alert.BloodPressure = r.PostFormValue("blood-pressure")
|
||||||
|
alert.Eta = r.PostFormValue("eta")
|
||||||
|
alert.Interventions = r.PostFormValue("interventions")
|
||||||
|
alert.BackgroundInfo = r.PostFormValue("background")
|
||||||
|
|
||||||
|
// Insert data into database
|
||||||
|
query := `INSERT INTO Alert (
|
||||||
|
MedicalOrTrauma,
|
||||||
|
Age,
|
||||||
|
Sex,
|
||||||
|
NhsNumber,
|
||||||
|
HeartRate,
|
||||||
|
RespiratoryRate,
|
||||||
|
OxygenSaturation,
|
||||||
|
Gcs,
|
||||||
|
BloodPressure,
|
||||||
|
Eta,
|
||||||
|
Interventions,
|
||||||
|
BackgroundInfo) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`
|
||||||
|
|
||||||
|
insert, err := database.Prepare(query)
|
||||||
|
defer insert.Close()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := insert.Exec(alert.MedicalOrTrauma,
|
||||||
|
alert.Age,
|
||||||
|
alert.Sex,
|
||||||
|
alert.NhsNumber,
|
||||||
|
alert.HeartRate,
|
||||||
|
alert.RespiratoryRate,
|
||||||
|
alert.OxygenSaturation,
|
||||||
|
alert.Gcs,
|
||||||
|
alert.BloodPressure,
|
||||||
|
alert.Eta,
|
||||||
|
alert.Interventions,
|
||||||
|
alert.BackgroundInfo)
|
||||||
|
rowsAffected, err := result.RowsAffected()
|
||||||
|
if err != nil || rowsAffected != 1 {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
http.Redirect(w, r, "http://localhost:3333/paramedic", http.StatusFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getERView(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Get list of alerts from database
|
||||||
|
alerts := []Alert{}
|
||||||
|
|
||||||
|
rows, err := database.Query("SELECT * FROM Alert;")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var alert Alert
|
||||||
|
for rows.Next() {
|
||||||
|
err := rows.Scan(&alert.Id,
|
||||||
|
&alert.MedicalOrTrauma,
|
||||||
|
&alert.Age,
|
||||||
|
&alert.Sex,
|
||||||
|
&alert.NhsNumber,
|
||||||
|
&alert.HeartRate,
|
||||||
|
&alert.RespiratoryRate,
|
||||||
|
&alert.OxygenSaturation,
|
||||||
|
&alert.Gcs,
|
||||||
|
&alert.BloodPressure,
|
||||||
|
&alert.Eta,
|
||||||
|
&alert.Interventions,
|
||||||
|
&alert.BackgroundInfo)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
alerts = append(alerts, alert)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, j := 0, len(alerts)-1; i < j; i, j = i+1, j-1 {
|
||||||
|
alerts[i], alerts[j] = alerts[j], alerts[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute template with list
|
||||||
|
tmpl, err := template.ParseFiles("templates/er.tmpl")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = tmpl.Execute(w, alerts)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupDatabaseTable(db *sql.DB) {
|
||||||
|
query := `CREATE TABLE IF NOT EXISTS Alert (
|
||||||
|
Id SERIAL PRIMARY KEY,
|
||||||
|
MedicalOrTrauma VARCHAR(100) NULL,
|
||||||
|
Age VARCHAR(100) NULL,
|
||||||
|
Sex VARCHAR(100) NULL,
|
||||||
|
NhsNumber VARCHAR(100) NULL,
|
||||||
|
HeartRate VARCHAR(100) NULL,
|
||||||
|
RespiratoryRate VARCHAR(100) NULL,
|
||||||
|
OxygenSaturation VARCHAR(100) NULL,
|
||||||
|
Gcs VARCHAR(100) NULL,
|
||||||
|
BloodPressure VARCHAR(100) NULL,
|
||||||
|
Eta VARCHAR(100) NULL,
|
||||||
|
Interventions VARCHAR(100) NULL,
|
||||||
|
BackgroundInfo VARCHAR(100) NULL
|
||||||
|
)`
|
||||||
|
|
||||||
|
_, err := db.Exec(query)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var database *sql.DB
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
config := mysql.Config{
|
||||||
|
User: "root",
|
||||||
|
Passwd: "o7MS6CIn660jIApSP",
|
||||||
|
Net: "tcp",
|
||||||
|
Addr: "127.0.0.1:3306",
|
||||||
|
DBName: "theredphone",
|
||||||
|
AllowNativePasswords: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
db, err := sql.Open("mysql", config.FormatDSN())
|
||||||
|
defer db.Close()
|
||||||
|
database = db
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = db.Ping(); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Connected to database")
|
||||||
|
setupDatabaseTable(db)
|
||||||
|
|
||||||
|
//mux := http.NewServeMux()
|
||||||
|
|
||||||
|
http.HandleFunc("/", getIndex)
|
||||||
|
http.HandleFunc("/paramedic", getParamedicView)
|
||||||
|
http.HandleFunc("/paramedicForm", postParamedicForm)
|
||||||
|
http.HandleFunc("/er", getERView)
|
||||||
|
|
||||||
|
http.Handle("/styles/", http.StripPrefix("/styles/", http.FileServer(http.Dir("styles"))))
|
||||||
|
http.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir("images"))))
|
||||||
|
|
||||||
|
fmt.Println("Serving")
|
||||||
|
http.ListenAndServe(":3333", nil)
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
body {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.er__title {
|
||||||
|
height: 20%;
|
||||||
|
|
||||||
|
background: #d6130c;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
|
||||||
|
border-bottom-left-radius:50%;
|
||||||
|
border-bottom-right-radius:50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alerts {
|
||||||
|
height: 80%;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
justify-items: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert {
|
||||||
|
border: 1px solid black;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
.theredphone__title {
|
||||||
|
height: 40%;
|
||||||
|
|
||||||
|
background: #d6130c;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
|
||||||
|
border-bottom-left-radius:50%;
|
||||||
|
border-bottom-right-radius:50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theredphone__links {
|
||||||
|
height: 60%;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theredphone__link {
|
||||||
|
font-size: 2rem;
|
||||||
|
|
||||||
|
padding-top: 2rem;
|
||||||
|
padding-bottom: 2rem;
|
||||||
|
padding-left: 1rem;
|
||||||
|
padding-right: 1rem;
|
||||||
|
|
||||||
|
border: 1px solid red;
|
||||||
|
border-radius: 25%;
|
||||||
|
color: black;
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: red;
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
*, *::before, *::after {
|
||||||
|
margin: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-grid {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
.paramedic-form__title {
|
||||||
|
height: 20%;
|
||||||
|
|
||||||
|
background: #d6130c;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
|
||||||
|
border-bottom-left-radius:50%;
|
||||||
|
border-bottom-right-radius:50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-block {
|
||||||
|
width: 30%;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="MobileOptimized" content="320" />
|
||||||
|
<meta name="HandheldFriendly" content="true" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie-edge">
|
||||||
|
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width, user-scalable=no" />
|
||||||
|
|
||||||
|
<title>TheRedPhone.xyz -- ER Personnel</title>
|
||||||
|
<link rel="icon" type="image/x-icon" href="images/theredphone.ico" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="styles/main.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="styles/er.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="er__title">
|
||||||
|
<h1>TheRedPhone.xyz -- ER Personnel</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alerts-wrapper">
|
||||||
|
<div class="alerts">
|
||||||
|
{{ range . }}
|
||||||
|
<div class="alert">
|
||||||
|
<h3>Categorization</h3>
|
||||||
|
<p>Categorization: {{ .MedicalOrTrauma }}</p>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<h3>Patient Data</h3>
|
||||||
|
<p>Age: {{ .Age }}</p>
|
||||||
|
<p>Sex: {{ .Sex }}</p>
|
||||||
|
<p>NHS Number: {{ .NhsNumber }}</p>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<h3>Observations</h3>
|
||||||
|
<p>Heart rate: {{ .HeartRate }}</p>
|
||||||
|
<p>Respiratory rate: {{ .RespiratoryRate }}</p>
|
||||||
|
<p>Oxygen Saturation: {{ .OxygenSaturation }}</p>
|
||||||
|
<p>GCS: {{ .Gcs }}</p>
|
||||||
|
<p>Blood pressure: {{ .BloodPressure }}</p>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<h3>Extra Information</h3>
|
||||||
|
<p>Estimated Time of Arrival: {{ .Eta }}</p>
|
||||||
|
<p>Interventions given: {{ .Interventions }}</p>
|
||||||
|
<p>Background info: {{ .BackgroundInfo }}</p>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="MobileOptimized" content="320" />
|
||||||
|
<meta name="HandheldFriendly" content="true" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie-edge">
|
||||||
|
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width, user-scalable=no" />
|
||||||
|
|
||||||
|
<title>TheRedPhone.xyz</title>
|
||||||
|
<link rel="icon" type="image/x-icon" href="images/theredphone.ico" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="styles/main.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="styles/index.css" />
|
||||||
|
</head>
|
||||||
|
<body class="theredphone">
|
||||||
|
<div class="theredphone__title">
|
||||||
|
<h1 style="display: inline;">TheRedPhone.xyz</h1>
|
||||||
|
<h2 class="theredphone__title">Are you a paramedic or ER personnel?</h2>
|
||||||
|
</div>
|
||||||
|
<div class="theredphone__links">
|
||||||
|
<a class="theredphone__link" href="/paramedic">Paramedic</a>
|
||||||
|
<a class="theredphone__link" href="/er">ER Personnel</a>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,90 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="MobileOptimized" content="320" />
|
||||||
|
<meta name="HandheldFriendly" content="true" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie-edge">
|
||||||
|
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, width=device-width, user-scalable=no" />
|
||||||
|
|
||||||
|
<title>TheRedPhone.xyz: Paramedics</title>
|
||||||
|
<link rel="icon" type="image/x-icon" href="images/theredphone.ico" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="styles/main.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="styles/paramedic.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="paramedic-form">
|
||||||
|
<div class="paramedic-form__title">
|
||||||
|
<h1>TheRedPhone.xyz: Paramedics</h1>
|
||||||
|
<h2>You Are Ambulance Crew Number: 9836283762</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form method="POST" action="/paramedicForm">
|
||||||
|
<div class="form-block">
|
||||||
|
<h3>Categorization</h3>
|
||||||
|
<label for="medical-or-trauma">Medical or Trauma?</label>
|
||||||
|
<select id="medical-or-truama" name="medical-or-trauma">
|
||||||
|
<option value="medical">Medical</option>
|
||||||
|
<option value="trauma">Trauma</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div class="form-block">
|
||||||
|
<h3>Patient Data</h3>
|
||||||
|
<label for="age">Age:</label>
|
||||||
|
<input type="number" name="age" id="age" />
|
||||||
|
|
||||||
|
<label for="sex">Sex:</label>
|
||||||
|
<select id="sex" name="sex">
|
||||||
|
<option value="male">Male</option>
|
||||||
|
<option value="female">Female</option>
|
||||||
|
<option value="nocontroversy">Non-Controversial Third Option</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="nhs-number">NHS Number:</label>
|
||||||
|
<input type="text" name="nhs-number" id="nhs-number" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div class="form-block">
|
||||||
|
<h3>Observations</h3>
|
||||||
|
<label for="heart-rate">Heart rate:</label>
|
||||||
|
<input type="number" name="heart-rate" id="heart-rate" />
|
||||||
|
|
||||||
|
<label for="respiratory-rate">Respiratory rate:</label>
|
||||||
|
<input type="number" name="respiratory-rate" id="respiratory-rate" />
|
||||||
|
|
||||||
|
<label for="oxygen-saturation">Oxygen saturation:</label>
|
||||||
|
<input type="number" name="oxygen-saturation" id="oxygen-saturation" />
|
||||||
|
|
||||||
|
<label for="gcs">GCS:</label>
|
||||||
|
<input type="number" name="gcs" id="gcs" />
|
||||||
|
|
||||||
|
<label for="blood-pressure">Blood pressure:</label>
|
||||||
|
<input type="number" name="blood-pressure" id="blood-pressure" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div class="form-block">
|
||||||
|
<h3>Extra Information</h3>
|
||||||
|
<label for="eta">Estimated Time of Arrival:</label>
|
||||||
|
<input type="text" name="eta" id="eta" />
|
||||||
|
|
||||||
|
<label for="interventions">Interventions given:</label>
|
||||||
|
<textarea name="interventions" id="interventions" cols="50"></textarea>
|
||||||
|
|
||||||
|
<label for="background">Background info:</label>
|
||||||
|
<textarea name="background" id="background" cols="50" rows="20"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-block">
|
||||||
|
<input type="submit" value="Send Report" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue