From f52bf4334433565a67fd2111061679de728eb733 Mon Sep 17 00:00:00 2001 From: The Magician Date: Sun, 7 Apr 2024 12:44:55 +0100 Subject: [PATCH] Initial commit --- go.mod | 7 ++ go.sum | 4 + images/theredphone.ico | Bin 0 -> 6101 bytes images/theredphone.png | Bin 0 -> 13804 bytes main.go | 236 +++++++++++++++++++++++++++++++++++ styles/er.css | 29 +++++ styles/index.css | 34 +++++ styles/main.css | 17 +++ styles/paramedic.css | 30 +++++ templates/er.tmpl | 54 ++++++++ templates/index.tmpl | 25 ++++ templates/paramedicForm.tmpl | 90 +++++++++++++ 12 files changed, 526 insertions(+) create mode 100644 go.mod create mode 100644 go.sum create mode 100644 images/theredphone.ico create mode 100644 images/theredphone.png create mode 100644 main.go create mode 100644 styles/er.css create mode 100644 styles/index.css create mode 100644 styles/main.css create mode 100644 styles/paramedic.css create mode 100644 templates/er.tmpl create mode 100644 templates/index.tmpl create mode 100644 templates/paramedicForm.tmpl diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..82b0932 --- /dev/null +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..19dbcec --- /dev/null +++ b/go.sum @@ -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= diff --git a/images/theredphone.ico b/images/theredphone.ico new file mode 100644 index 0000000000000000000000000000000000000000..457864d291904a223add4d6132895495758f6772 GIT binary patch literal 6101 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 P-vW@vmPWM~+#mc8d#Io@ literal 0 HcmV?d00001 diff --git a/main.go b/main.go new file mode 100644 index 0000000..4057542 --- /dev/null +++ b/main.go @@ -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) +} diff --git a/styles/er.css b/styles/er.css new file mode 100644 index 0000000..fcef106 --- /dev/null +++ b/styles/er.css @@ -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; +} diff --git a/styles/index.css b/styles/index.css new file mode 100644 index 0000000..8f82529 --- /dev/null +++ b/styles/index.css @@ -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; +} diff --git a/styles/main.css b/styles/main.css new file mode 100644 index 0000000..16f7ec1 --- /dev/null +++ b/styles/main.css @@ -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; +} diff --git a/styles/paramedic.css b/styles/paramedic.css new file mode 100644 index 0000000..3f976db --- /dev/null +++ b/styles/paramedic.css @@ -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; +} diff --git a/templates/er.tmpl b/templates/er.tmpl new file mode 100644 index 0000000..d56a921 --- /dev/null +++ b/templates/er.tmpl @@ -0,0 +1,54 @@ + + + + + + + + + + TheRedPhone.xyz -- ER Personnel + + + + + +
+

TheRedPhone.xyz -- ER Personnel

+
+ +
+
+ {{ range . }} +
+

Categorization

+

Categorization: {{ .MedicalOrTrauma }}

+ +
+ +

Patient Data

+

Age: {{ .Age }}

+

Sex: {{ .Sex }}

+

NHS Number: {{ .NhsNumber }}

+ +
+ +

Observations

+

Heart rate: {{ .HeartRate }}

+

Respiratory rate: {{ .RespiratoryRate }}

+

Oxygen Saturation: {{ .OxygenSaturation }}

+

GCS: {{ .Gcs }}

+

Blood pressure: {{ .BloodPressure }}

+ +
+ +

Extra Information

+

Estimated Time of Arrival: {{ .Eta }}

+

Interventions given: {{ .Interventions }}

+

Background info: {{ .BackgroundInfo }}

+
+ {{ end }} +
+
+ + diff --git a/templates/index.tmpl b/templates/index.tmpl new file mode 100644 index 0000000..66621ea --- /dev/null +++ b/templates/index.tmpl @@ -0,0 +1,25 @@ + + + + + + + + + + TheRedPhone.xyz + + + + + +
+

TheRedPhone.xyz

+

Are you a paramedic or ER personnel?

+
+ + + diff --git a/templates/paramedicForm.tmpl b/templates/paramedicForm.tmpl new file mode 100644 index 0000000..38cc6ef --- /dev/null +++ b/templates/paramedicForm.tmpl @@ -0,0 +1,90 @@ + + + + + + + + + + TheRedPhone.xyz: Paramedics + + + + + +
+
+

TheRedPhone.xyz: Paramedics

+

You Are Ambulance Crew Number: 9836283762

+
+ +
+
+

Categorization

+ + +
+ +
+ +
+

Patient Data

+ + + + + + + + +
+ +
+ +
+

Observations

+ + + + + + + + + + + + + + +
+ +
+ +
+

Extra Information

+ + + + + + + + +
+ +
+ +
+
+
+ +