From c2913318dec546938cab0dd2dd9959f7473265aa Mon Sep 17 00:00:00 2001 From: Patryk Hegenberg Date: Fri, 29 Dec 2023 09:38:09 +0100 Subject: [PATCH 1/8] wrote the server.go file and introduced another file structure --- .env | 6 + {images => assets/images}/01coin.gif | Bin .../images}/16x16DungeonTileset.png | Bin {images => assets/images}/HeroBanner.png | Bin {images => assets/images}/icon.png | Bin {images => assets/images}/monster_imp.png | Bin .../images}/monster_necromancer.png | Bin .../images}/npc_knight_green.png | Bin .../images}/weapon_silver_topaz.png | Bin .../images}/weapon_sword_red.png | Bin .../images}/weapon_sword_ruby.png | Bin {styles => assets/styles}/game.css | 0 {styles => assets/styles}/mathe.css | 0 {styles => assets/styles}/style.css | 132 ++++++++++++++---- server.go | 78 +++++++++++ 15 files changed, 185 insertions(+), 31 deletions(-) create mode 100644 .env rename {images => assets/images}/01coin.gif (100%) rename {images => assets/images}/16x16DungeonTileset.png (100%) rename {images => assets/images}/HeroBanner.png (100%) rename {images => assets/images}/icon.png (100%) rename {images => assets/images}/monster_imp.png (100%) rename {images => assets/images}/monster_necromancer.png (100%) rename {images => assets/images}/npc_knight_green.png (100%) rename {images => assets/images}/weapon_silver_topaz.png (100%) rename {images => assets/images}/weapon_sword_red.png (100%) rename {images => assets/images}/weapon_sword_ruby.png (100%) rename {styles => assets/styles}/game.css (100%) rename {styles => assets/styles}/mathe.css (100%) rename {styles => assets/styles}/style.css (94%) create mode 100644 server.go diff --git a/.env b/.env new file mode 100644 index 0000000..e29f14f --- /dev/null +++ b/.env @@ -0,0 +1,6 @@ +DB_Host: 'db' +DB_Port: 3306 +DB_Name: 'MatheApp' +DB_Charset: 'utf8mb4' +DB_User: 'MatheApp' +DB_Password: 'password' diff --git a/images/01coin.gif b/assets/images/01coin.gif similarity index 100% rename from images/01coin.gif rename to assets/images/01coin.gif diff --git a/images/16x16DungeonTileset.png b/assets/images/16x16DungeonTileset.png similarity index 100% rename from images/16x16DungeonTileset.png rename to assets/images/16x16DungeonTileset.png diff --git a/images/HeroBanner.png b/assets/images/HeroBanner.png similarity index 100% rename from images/HeroBanner.png rename to assets/images/HeroBanner.png diff --git a/images/icon.png b/assets/images/icon.png similarity index 100% rename from images/icon.png rename to assets/images/icon.png diff --git a/images/monster_imp.png b/assets/images/monster_imp.png similarity index 100% rename from images/monster_imp.png rename to assets/images/monster_imp.png diff --git a/images/monster_necromancer.png b/assets/images/monster_necromancer.png similarity index 100% rename from images/monster_necromancer.png rename to assets/images/monster_necromancer.png diff --git a/images/npc_knight_green.png b/assets/images/npc_knight_green.png similarity index 100% rename from images/npc_knight_green.png rename to assets/images/npc_knight_green.png diff --git a/images/weapon_silver_topaz.png b/assets/images/weapon_silver_topaz.png similarity index 100% rename from images/weapon_silver_topaz.png rename to assets/images/weapon_silver_topaz.png diff --git a/images/weapon_sword_red.png b/assets/images/weapon_sword_red.png similarity index 100% rename from images/weapon_sword_red.png rename to assets/images/weapon_sword_red.png diff --git a/images/weapon_sword_ruby.png b/assets/images/weapon_sword_ruby.png similarity index 100% rename from images/weapon_sword_ruby.png rename to assets/images/weapon_sword_ruby.png diff --git a/styles/game.css b/assets/styles/game.css similarity index 100% rename from styles/game.css rename to assets/styles/game.css diff --git a/styles/mathe.css b/assets/styles/mathe.css similarity index 100% rename from styles/mathe.css rename to assets/styles/mathe.css diff --git a/styles/style.css b/assets/styles/style.css similarity index 94% rename from styles/style.css rename to assets/styles/style.css index fbbc2a4..6fbaae5 100644 --- a/styles/style.css +++ b/assets/styles/style.css @@ -20,6 +20,7 @@ h1 { font-size: 2em; margin: 0.67em 0; } + figcaption, figure, main { @@ -50,7 +51,8 @@ img { max-width: 100%; vertical-align: middle; } -.site-header img{ + +.site-header img { height: 60px; } @@ -84,6 +86,7 @@ h6, color: #2e1e26; font-weight: 600; } + h1, .h1 { font-size: 38px; @@ -119,6 +122,7 @@ h2, margin-top: 48px; margin-bottom: 16px; } + h3, .h3 { margin-top: 36px; @@ -141,9 +145,11 @@ p { .container { max-width: 1128px; } + .container-sm { max-width: 848px; } + .container .container-sm { max-width: 800px; padding-left: 0; @@ -167,6 +173,7 @@ p { padding: 12px 0; z-index: 2; } + .site-header-inner { position: relative; display: flex; @@ -179,8 +186,8 @@ p { text-align: center; padding-top: 48px; padding-bottom: 88px; - background-image: url("./../../images/HeroBanner.png"); - background-repeat: no-repeat; + background-image: url("/static/images/HeroBanner.png"); + background-repeat: no-repeat; background-position: center; background-size: cover; } @@ -192,15 +199,18 @@ footer img { .hero-copy { position: relative; } + .hero-paragraph { margin-bottom: 32px; } + .hero-cta { max-width: 400px; margin-left: auto; margin-right: auto; margin-bottom: 80px; } + .lights-toggle { color: rgba(107, 122, 144, 0.64); } @@ -211,10 +221,12 @@ footer img { padding-top: 88px; padding-bottom: 120px; } + .hero-inner { display: flex; justify-content: space-between; } + .hero-copy { padding-top: 40px; padding-right: 48px; @@ -222,33 +234,42 @@ footer img { max-width: 512px; z-index: 1; } + .hero-title { margin-bottom: 16px; } + .hero-paragraph { margin-bottom: 32px; } + .hero-cta { display: flex; align-items: center; margin: 0; } + .hero-cta .button { min-width: 170px; } + .hero-cta .button:first-child { margin-right: 32px; } + .header-illustration { display: block; } + .hero-media { z-index: 0; } + .hero-media img, .hero-media svg { max-width: none; } + .header-illustration-image { display: block; position: absolute; @@ -258,6 +279,7 @@ footer img { height: 324px; } } + .features-wrap { max-width: 540px; margin: 0 auto; @@ -267,21 +289,26 @@ footer img { text-align: center; margin-bottom: 48px; } + .feature:last-of-type { margin-bottom: 0; } + .feature-icon { display: inline-flex; margin-bottom: 16px; } + .feature-icon img, .feature-icon svg { max-width: none; } + .feature-title { position: relative; margin-bottom: 26px; } + .feature-title::after { content: ''; width: 32px; @@ -291,20 +318,25 @@ footer img { left: calc(50% - 16px); background: #e9edf3; } - .feature-title::after { + +.feature-title::after { background: #3f2a34; } + @media (min-width: 641px) { .features { position: relative; } + .features .section-inner { padding-bottom: 100px; } + .features .section-paragraph { padding-left: 72px; padding-right: 72px; } + .features::before { content: ''; width: 100%; @@ -312,40 +344,47 @@ footer img { position: absolute; left: 0; top: 168px; - background: linear-gradient( - to bottom, - #3f2a34, - #3f2a34 - ); + background: linear-gradient(to bottom, + #3f2a34, + #3f2a34); } - .features::before { + + .features::before { display: none; } + .feature { text-align: left; } + .feature-inner { display: flex; } + .feature-icon { display: block; margin-top: 8px; margin-right: 32px; margin-bottom: 0; } + .feature-title::after { left: 0; } } + .cta { position: relative; } + .cta .section-inner { padding-bottom: 64px; } + .cta .section-paragraph { margin-bottom: 32px; } + .cta::before { content: ''; position: absolute; @@ -354,32 +393,39 @@ footer img { height: 263px; width: 1440px; } + .cta-cta { max-width: 400px; margin-left: auto; margin-right: auto; } + @media (max-width: 639px) { .cta-cta .button { display: flex; } } + @media (min-width: 641px) { .cta .section-inner { padding-bottom: 128px; } + .cta .section-paragraph { margin-bottom: 40px; padding-left: 72px; padding-right: 72px; } + .cta::before { bottom: 0; } } + .is-boxed { background: #e9edf3; } + .body-wrap { background: #fff; overflow: hidden; @@ -387,14 +433,17 @@ footer img { flex-direction: column; min-height: 100vh; } + .boxed-container { max-width: 1440px; margin: 0 auto; box-shadow: 0 16px 48px rgba(255, 255, 255, 0.5); } + main { flex: 1 0 auto; } + .section-inner { position: relative; padding-top: 48px; @@ -432,6 +481,7 @@ main { margin: 0 auto; height: 500px; } + .container2 { display: flex; justify-content: center; @@ -440,6 +490,7 @@ main { margin: 0 auto; height: 750px; } + .container3 { display: flex; justify-content: center; @@ -450,6 +501,7 @@ main { background-color: #2e1e26; padding: 20px; } + .container4 { display: flex; justify-content: center; @@ -460,6 +512,7 @@ main { background-color: #2e1e26; padding: 20px; } + .footer-copyright { flex: none; width: 80%; @@ -467,6 +520,7 @@ main { justify-content: center; align-items: center; } + .register { height: 1200px; display: flex; @@ -490,6 +544,7 @@ main { .nes-field { max-width: 400px; } + .login { height: 1200px; display: flex; @@ -510,6 +565,7 @@ main { border-radius: 5px; box-shadow: #3f2a34; } + .learnContainer { display: flex; justify-content: center; @@ -523,6 +579,7 @@ main { border-radius: 5px; box-shadow: 0 0 4px #433e4c } + .profile { height: 1200px; display: flex; @@ -532,58 +589,68 @@ main { border-radius: 5px; box-shadow: #3f2a34; } + .container .login { display: flex; justify-content: center; align-items: center; text-align: center; } + .asset-dark { visibility: hidden; opacity: 0; } + .is-loaded .asset-dark { visibility: visible; opacity: 1; } + .asset-dark { display: none; } - .asset-dark { +.asset-dark { display: block; } - a { + +a { color: #8595ae; } - h1, - h2, - h3, - h4, - h5, - h6, - .h1, - .h2, - .h3, - .h4, - .h5, - .h6 { + +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { color: #fff !important; } + .is-boxed { background: #3f2a34; } - .body-wrap { + +.body-wrap { background: #2e1e26; } - .boxed-container { + +.boxed-container { box-shadow: 0 16px 48px #433e4c; } - .has-top-divider { +.has-top-divider { position: relative; } - .has-top-divider::before { + +.has-top-divider::before { content: ''; position: absolute; top: 0; @@ -593,10 +660,12 @@ main { height: 1px; background: #3f2a34; } - .has-bottom-divider { + +.has-bottom-divider { position: relative; } - .has-bottom-divider::after { + +.has-bottom-divider::after { content: ''; position: absolute; bottom: 0; @@ -606,6 +675,7 @@ main { height: 1px; background: #3f2a34; } + body, a, h1, @@ -625,4 +695,4 @@ h6, .boxed-container { transition: box-shadow 0.15s ease; -} +} \ No newline at end of file diff --git a/server.go b/server.go new file mode 100644 index 0000000..3ad5e8e --- /dev/null +++ b/server.go @@ -0,0 +1,78 @@ +package main + +import ( + // "fmt" + "net/http" + // "os" + // "os/exec" + // "runtime" + // "strconv" + + // "github.com/chasefleming/elem-go" + // "github.com/chasefleming/elem-go/attrs" + // "github.com/chasefleming/elem-go/htmx" + "the_math_wizard/views" + + "github.com/labstack/echo/v4" + "github.com/labstack/echo/v4/middleware" +) + +func main() { + e := echo.New() + e.Static("/static", "assets") + + // Middleware + e.Use(middleware.Logger()) + e.Use(middleware.Recover()) + + // Routes + e.GET("/", RenderIndexRoute) + e.GET("/learn", RenderLearnRoute) + e.GET("/mathe", RenderMatheRoute) + e.GET("/game", RenderGameRoute) + e.GET("/login", RenderLoginRoute) + e.GET("/register", RenderRegisterRoute) + e.GET("/profile", RenderProfileRoute) + e.GET("/logout", LogoutRoute) + e.GET("/delete", DeleteRoute) + e.GET("/updateData", RenderUpdateRoute) + e.GET("/deleteUser", RenderDeleteRoute) + + // Start the server + e.Logger.Fatal(e.Start(":3000")) + +} + +func RenderIndexRoute(c echo.Context) error { + return c.HTML(http.StatusOK, views.RenderIndex()) +} +func RenderLearnRoute(c echo.Context) error { + return nil +} +func RenderMatheRoute(c echo.Context) error { + return nil +} +func RenderGameRoute(c echo.Context) error { + return nil +} +func RenderLoginRoute(c echo.Context) error { + return nil +} +func RenderRegisterRoute(c echo.Context) error { + return nil +} +func RenderProfileRoute(c echo.Context) error { + return nil +} +func LogoutRoute(c echo.Context) error { + return nil +} +func DeleteRoute(c echo.Context) error { + return nil +} +func RenderUpdateRoute(c echo.Context) error { + return nil +} +func RenderDeleteRoute(c echo.Context) error { + return nil +} From b0b0df3b801969a163ab4eb6125543daecc2b376 Mon Sep 17 00:00:00 2001 From: PatrykHegenberg <112555272+PatrykHegenberg@users.noreply.github.com> Date: Fri, 29 Dec 2023 09:53:20 +0100 Subject: [PATCH 2/8] Create README.md --- README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..82efbc1 --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +# The Math Wizard + +The Math Wizard is a browser game that helps children automate the 1x1. It acts as a dungeon crawler game in which children can fight monsters by solving multiplication problems. + +## Requirements + +To run the game, you need Docker and Docker-Compose. Make sure that these are installed and configured on your system. + +## Installation + +1. clone the repository with `git clone https://github.com/PatrykHegenberg/TheMathWizard.git`. +2. change to the project directory with `cd TheMathWizard`. +3. run `docker-compose up --build` to install and start the game. + +Once the installation is complete, you can access the game via your web browser under `localhost:8080` or the computer name. + +## Usage + +To create a new account, go to `localhost:8080/signup` in the browser. After signing up, you can start the game and begin fighting monsters and solving multiplication tasks. Your progress will be saved persistently on the hard disk of the host computer. + +## License + +This project is licensed under the MIT license. For more information, see the LICENSE file. + +## Acknowledgments + +This project uses the following resources: +- [ROT.js](https://github.com/ondras/rot.js/) (BSD-Lizenz) +- [Micro Rogue tileset](https://kenney.nl/assets/micro-roguelike) von Kenney.nl (CC0 1.0 Universelle Lizenz) +- [NES.css](https://nostalgic-css.github.io/NES.css/) (MIT Lizenz) +- [sfxr.me](https://www.sfxr.me/) (Öffentliches Domain) +- [Pixel Coin Bild](https://opengameart.org/content/pixel-coins) (CC-BY 3.0 Lizenz) +- [Roguelike-Browser-Boilerplate](https://github.com/chr15m/roguelike-browser-boilerplate) From e0dca3bbd86f17bcbecf41a9dfa1e6ba0345c443 Mon Sep 17 00:00:00 2001 From: Patryk Hegenberg Date: Fri, 29 Dec 2023 12:26:16 +0100 Subject: [PATCH 3/8] add db.go for database connection --- .gitignore | 1 + db/db.go | 138 +++++++++++++++++++++++++++++++++++++++++ go.mod | 23 +++++++ go.sum | 39 ++++++++++++ views/footer.templ.go | 8 +++ views/head.templ.go | 21 +++++++ views/index.templ.go | 24 +++++++ views/main.templ.go | 94 ++++++++++++++++++++++++++++ views/nav.templ.go | 19 ++++++ views/profile.templ.go | 46 ++++++++++++++ 10 files changed, 413 insertions(+) create mode 100644 db/db.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 views/footer.templ.go create mode 100644 views/head.templ.go create mode 100644 views/index.templ.go create mode 100644 views/main.templ.go create mode 100644 views/nav.templ.go create mode 100644 views/profile.templ.go diff --git a/.gitignore b/.gitignore index d40cde8..09edf85 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ # vscode config files ./.vscode/* +math_wizard_db_data/* \ No newline at end of file diff --git a/db/db.go b/db/db.go new file mode 100644 index 0000000..9676df8 --- /dev/null +++ b/db/db.go @@ -0,0 +1,138 @@ +package main + +import ( + "database/sql" + "fmt" + + _ "github.com/go-sql-driver/mysql" +) + +// Connect to MySQL database. +type Database struct { + connection *sql.DB + statement *sql.Stmt +} + +func NewDatabase(config map[string]string, username string, password string) (*Database, error) { + dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", username, password, config["host"], config["port"], config["dbname"]) + db, err := sql.Open("mysql", dsn) + if err != nil { + return nil, err + } + + return &Database{ + connection: db, + }, nil +} + +func (d *Database) Query(query string, params ...interface{}) (*Database, error) { + stmt, err := d.connection.Prepare(query) + if err != nil { + return nil, err + } + + d.statement = stmt + + _, err = stmt.Exec(params...) + if err != nil { + return nil, err + } + + return d, nil +} + +func (d *Database) Find() (map[string]interface{}, error) { + result := make(map[string]interface{}) + err := d.statement.QueryRow().Scan(result) + if err != nil { + return nil, err + } + + return result, nil +} + +func (d *Database) FindOrFail() (map[string]interface{}, error) { + result, err := d.Find() + if err != nil { + return nil, err + } + + if result == nil { + return nil, fmt.Errorf("Record not found") + } + + return result, nil +} + +func (d *Database) Get() ([]map[string]interface{}, error) { + rows, err := d.statement.Query() + if err != nil { + return nil, err + } + defer rows.Close() + + columns, err := rows.Columns() + if err != nil { + return nil, err + } + + result := make([]map[string]interface{}, 0) + values := make([]interface{}, len(columns)) + valuePtrs := make([]interface{}, len(columns)) + for rows.Next() { + for i := 0; i < len(columns); i++ { + valuePtrs[i] = &values[i] + } + + err := rows.Scan(valuePtrs...) + if err != nil { + return nil, err + } + + entry := make(map[string]interface{}) + for i, col := range columns { + val := values[i] + b, ok := val.([]byte) + if ok { + entry[col] = string(b) + } else { + entry[col] = val + } + } + + result = append(result, entry) + } + + return result, nil +} + +func (d *Database) Delete(params string) (*Database, error) { + _, err := d.Query("DELETE FROM user WHERE username = ?", params) + if err != nil { + return nil, err + } + + return d, nil +} + +func (d *Database) Update(params map[string]interface{}) (*Database, error) { + _, err := d.Query("UPDATE user SET level = ?, xp = ?, coins = ? WHERE username = ?", params["level"], params["xp"], params["coins"], params["username"]) + if err != nil { + return nil, err + } + + return d, nil +} + +func (d *Database) GetPlayerStats(params string) (map[string]interface{}, error) { + result, err := d.Query("SELECT username, level, lesson_count, xp, coins FROM user WHERE username = ?", params).Get() + if err != nil { + return nil, err + } + + if len(result) == 0 { + return nil, fmt.Errorf("Record not found") + } + + return result[0], nil +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..7c4e19e --- /dev/null +++ b/go.mod @@ -0,0 +1,23 @@ +module the_math_wizard + +go 1.21.5 + +require ( + github.com/chasefleming/elem-go v0.17.0 + github.com/labstack/echo/v4 v4.11.4 +) + +require ( + github.com/go-sql-driver/mysql v1.7.1 + github.com/golang-jwt/jwt v3.2.2+incompatible // indirect + github.com/labstack/gommon v0.4.2 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasttemplate v1.2.2 // indirect + golang.org/x/crypto v0.17.0 // indirect + golang.org/x/net v0.19.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.5.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..596e254 --- /dev/null +++ b/go.sum @@ -0,0 +1,39 @@ +github.com/chasefleming/elem-go v0.17.0 h1:9hqg6OSacy2YgHLpY/soZqXLOOMfhmKG5qukrSgjxlI= +github.com/chasefleming/elem-go v0.17.0/go.mod h1:hz73qILBIKnTgOujnSMtEj20/epI+f6vg71RUilJAA4= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= +github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8= +github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8= +github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= +github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/views/footer.templ.go b/views/footer.templ.go new file mode 100644 index 0000000..7e5a9c5 --- /dev/null +++ b/views/footer.templ.go @@ -0,0 +1,8 @@ +package views + +import "github.com/chasefleming/elem-go" + +func RenderFooter() elem.Node { + footerContent := elem.Footer(nil) + return footerContent +} diff --git a/views/head.templ.go b/views/head.templ.go new file mode 100644 index 0000000..c634d17 --- /dev/null +++ b/views/head.templ.go @@ -0,0 +1,21 @@ +package views + +import ( + "github.com/chasefleming/elem-go" + "github.com/chasefleming/elem-go/attrs" +) + +func RenderHead() elem.Node { + headContent := elem.Head(nil, + elem.Meta(attrs.Props{attrs.Charset: "UTF-8", attrs.Name: "viewport", attrs.Content: "width=device-width, initial-scale=1.0"}), + elem.Meta(attrs.Props{attrs.HTTPequiv: "X-UA-Compatible", attrs.Content: "IE=edge"}), + elem.Script(attrs.Props{attrs.Src: "https://unpkg.com/htmx.org"}), + elem.Title(nil, elem.Text("The Math Wizard")), + elem.Link(attrs.Props{attrs.Href: "https://cdn.jsdelivr.net/npm/nes.css@2.3.0/css/nes.min.css", attrs.Rel: "stylesheet"}), + elem.Link(attrs.Props{attrs.Rel: "stylesheet", attrs.Href: "https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css"}), + elem.Link(attrs.Props{attrs.Rel: "stylesheet", attrs.Href: "/static/styles/style.css"}), + elem.Script(attrs.Props{attrs.Src: "https://unpkg.com/scrollreveal@4.0.0/dist/scrollreveal.min.js"}), + elem.Style(nil, elem.Text("@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P');")), + ) + return headContent +} diff --git a/views/index.templ.go b/views/index.templ.go new file mode 100644 index 0000000..7ac46c0 --- /dev/null +++ b/views/index.templ.go @@ -0,0 +1,24 @@ +package views + +import ( + "github.com/chasefleming/elem-go" + "github.com/chasefleming/elem-go/attrs" +) + +func RenderIndex() string { + headContent := RenderHead() + navContent := RenderNav() + mainContent := RenderMain() + footerContent := RenderFooter() + bodyContent := elem.Body(attrs.Props{attrs.Class: "is-boxed"}, + elem.Div(attrs.Props{attrs.Class: "body-wrap boxed-container"}, + navContent, + mainContent, + footerContent, + ), + ) + + htmlContent := elem.Html(nil, headContent, bodyContent) + + return htmlContent.Render() +} diff --git a/views/main.templ.go b/views/main.templ.go new file mode 100644 index 0000000..87e30f6 --- /dev/null +++ b/views/main.templ.go @@ -0,0 +1,94 @@ +package views + +import ( + "github.com/chasefleming/elem-go" + "github.com/chasefleming/elem-go/attrs" +) + +func RenderMain() elem.Node { + mainContent := elem.Main(nil, + elem.Section(attrs.Props{attrs.Class: "hero"}, + elem.Div(attrs.Props{attrs.Class: "container"}, + elem.Div(attrs.Props{attrs.Class: "hero-inner"}, + elem.Div(attrs.Props{attrs.Class: "hero-copy"}, + elem.H1(attrs.Props{attrs.Class: "hero-title"}, elem.Text("Automatisiere spielerisch das 1x1")), + elem.P(attrs.Props{attrs.Class: "hero-paragraph"}, elem.Text("Zeige was du kannst und kämpfe dich durch den Dungeon.")), + elem.Div(attrs.Props{attrs.Class: "hero-cta"}, + elem.A(attrs.Props{attrs.Class: "nes-btn is-primary", attrs.Href: "/login"}, elem.Text("Starte Jetzt!")), + ), + ), + ), + ), + ), + elem.Section(attrs.Props{attrs.Class: "features section"}, + elem.Div(attrs.Props{attrs.Class: "container"}, + elem.Div(attrs.Props{attrs.Class: "features-inner section-inner has-bottom-divider"}, + elem.Div(attrs.Props{attrs.Class: "features-header text-center"}, + elem.Div(attrs.Props{attrs.Class: "container-sm"}, + elem.H2(attrs.Props{attrs.Class: "section-title"}, elem.Text("The Math Wizard")), + elem.P(attrs.Props{attrs.Class: "section-paragraph"}, elem.Text("Ohne es zu bemerken lernst du das 1x1.")), + ), + ), + + elem.Div(attrs.Props{attrs.Class: "features-wrap"}, + elem.Div(attrs.Props{attrs.Class: "feature is-revealing"}, + elem.Div(attrs.Props{attrs.Class: "feature-inner"}, + elem.Div(attrs.Props{attrs.Class: "feature-icon"}, + elem.Img(attrs.Props{attrs.Src: "/static/images/weapon_sword_ruby.png", attrs.Alt: "Feature 01"})), + elem.Div(attrs.Props{attrs.Class: "feature-content"}, + elem.H3(attrs.Props{attrs.Class: "feature-title"}, elem.Text("Immer neue Level")), + elem.P(attrs.Props{attrs.Class: "text-sm mb-0"}, elem.Text("Spannende, zufallsgeneriete Level im Dungeon-Crawler-Stil.")), + ), + ), + ), + elem.Div(attrs.Props{attrs.Class: "feature is-revealing"}, + elem.Div(attrs.Props{attrs.Class: "feature-inner"}, + elem.Div(attrs.Props{attrs.Class: "feature-icon"}, + elem.Img(attrs.Props{attrs.Src: "/static/images/monster_imp.png", attrs.Alt: "Feature 02"})), + elem.Div(attrs.Props{attrs.Class: "feature-content"}, + elem.H3(attrs.Props{attrs.Class: "feature-title"}, elem.Text("Angepasste Schwierigkeit")), + elem.P(attrs.Props{attrs.Class: "text-sm mb-0"}, elem.Text("Die Aufgaben passen sich deinen aktuellen Fähigkeiten an.")), + ), + ), + ), + elem.Div(attrs.Props{attrs.Class: "feature is-revealing"}, + elem.Div(attrs.Props{attrs.Class: "feature-inner"}, + elem.Div(attrs.Props{attrs.Class: "feature-icon"}, + elem.Img(attrs.Props{attrs.Src: "/static/images/npc_knight_green.png", attrs.Alt: "Feature 03"})), + elem.Div(attrs.Props{attrs.Class: "feature-content"}, + elem.H3(attrs.Props{attrs.Class: "feature-title"}, elem.Text("Fokus auf das was zählt")), + elem.P(attrs.Props{attrs.Class: "text-sm mb-0"}, elem.Text("Fokus auf das Automatisieren der Multiplikation im Zahlenraum von 1 bis 10.")), + ), + ), + ), + elem.Div(attrs.Props{attrs.Class: "feature is-revealing"}, + elem.Div(attrs.Props{attrs.Class: "feature-inner"}, + elem.Div(attrs.Props{attrs.Class: "feature-icon"}, + elem.Img(attrs.Props{attrs.Src: "/static/images/monster_necromancer.png", attrs.Alt: "Feature 04"})), + elem.Div(attrs.Props{attrs.Class: "feature-content"}, + elem.H3(attrs.Props{attrs.Class: "feature-title"}, elem.Text("Lernfortschritt immer im Blick")), + elem.P(attrs.Props{attrs.Class: "text-sm mb-0"}, elem.Text("Lernziel und Fortschrittskontrolle, um deinen Fortschritt zu verfolgen.")), + ), + ), + ), + ), + ), + ), + ), + elem.Section(attrs.Props{attrs.Class: "cta section"}, + elem.Div(attrs.Props{attrs.Class: "container-sm"}, + elem.Div(attrs.Props{attrs.Class: "cta-inner section-inner"}, + elem.Div(attrs.Props{attrs.Class: "cta-header text-center"}, + elem.H2(attrs.Props{attrs.Class: "section-title"}, elem.Text("Bereit los zu legen?")), + elem.P(attrs.Props{attrs.Class: "section-paragraph"}, elem.Text("Fange noch heute an zu lernen.")), + elem.Div(attrs.Props{attrs.Class: "cta-cta"}, + elem.A(attrs.Props{attrs.Class: "nes-btn is-primary", attrs.Href: "/login"}, + elem.Text("Los geht's")), + ), + ), + ), + ), + ), + ) + return mainContent +} diff --git a/views/nav.templ.go b/views/nav.templ.go new file mode 100644 index 0000000..7a7d0de --- /dev/null +++ b/views/nav.templ.go @@ -0,0 +1,19 @@ +package views + +import ( + "github.com/chasefleming/elem-go" + "github.com/chasefleming/elem-go/attrs" +) + +func RenderNav() elem.Node { + navContent := elem.Header(attrs.Props{attrs.Class: "site-header"}, + elem.Div(attrs.Props{attrs.Class: "container"}, + elem.Nav(nil, + elem.Div(attrs.Props{attrs.Class: "site-header-inner"}, + elem.A(attrs.Props{attrs.Class: "", attrs.Href: "/"}), + ), + ), + ), + ) + return navContent +} diff --git a/views/profile.templ.go b/views/profile.templ.go new file mode 100644 index 0000000..d7a581c --- /dev/null +++ b/views/profile.templ.go @@ -0,0 +1,46 @@ +package views + +import ( + "fmt" + + "github.com/chasefleming/elem-go" + "github.com/chasefleming/elem-go/attrs" +) + +type Stats struct { + Username string +} + +func RenderProfile() elem.Node { + stats := Stats{ + Username: "TestUser", + } + page := elem.Div(attrs.Props{attrs.Class: "profile"}, + elem.Div(attrs.Props{attrs.Style: "padding: 20px; border-radius: 5px; box-shadow: 0 0 4px #433e4c; margin-top: 20px; margin-bottom: 20px; background-color: #2e1e26;"}, + elem.Div(attrs.Props{attrs.Class: "container3"}, + elem.Section(attrs.Props{attrs.Class: "message-list"}, + elem.Section(attrs.Props{attrs.Class: "message -left"}, + elem.I(attrs.Props{attrs.Class: "nes-bcrikko"}), + elem.Div(attrs.Props{attrs.Class: "nes-balloon from-left"}, + elem.P(nil, elem.Text(fmt.Sprintf("Hallo %s zurück. Wie kann ich dir helfen?", stats.Username))), + ), + ), + ), + elem.Div(attrs.Props{attrs.Class: "container3"}, + elem.Div(attrs.Props{attrs.Class: "text-center"}, + elem.H3(nil, elem.Text("Was möchtest du tun?"))), + ), + elem.Div(nil, + elem.A(attrs.Props{attrs.Class: "nes-btn", attrs.Href: "/learn"}, elem.Text("Lernen")), + elem.A(attrs.Props{attrs.Class: "nes-btn", attrs.Href: "/play"}, elem.Text("Spielen")), + ), + ), + elem.Div(attrs.Props{attrs.Class: "container3"}, + elem.Span(attrs.Props{attrs.Class: "title"}, elem.Text("Dein Fortschritt")), + elem.Span(nil, elem.Text("Du bist aktuell Leven: ")), + ), + ), + ) + + return page +} From 70ddd5e706ae357dd3a0f9343181b887e0a9af3e Mon Sep 17 00:00:00 2001 From: Patryk Hegenberg Date: Fri, 29 Dec 2023 14:47:22 +0100 Subject: [PATCH 4/8] added more changes to db.go --- {scripts => assets/scripts}/addition.js | 0 {scripts => assets/scripts}/game.js | 0 {scripts => assets/scripts}/mathe.js | 0 db.go | 148 ++++++++++++++++++++++++ db/db.go | 138 ---------------------- go.mod | 1 + go.sum | 2 + 7 files changed, 151 insertions(+), 138 deletions(-) rename {scripts => assets/scripts}/addition.js (100%) rename {scripts => assets/scripts}/game.js (100%) rename {scripts => assets/scripts}/mathe.js (100%) create mode 100644 db.go delete mode 100644 db/db.go diff --git a/scripts/addition.js b/assets/scripts/addition.js similarity index 100% rename from scripts/addition.js rename to assets/scripts/addition.js diff --git a/scripts/game.js b/assets/scripts/game.js similarity index 100% rename from scripts/game.js rename to assets/scripts/game.js diff --git a/scripts/mathe.js b/assets/scripts/mathe.js similarity index 100% rename from scripts/mathe.js rename to assets/scripts/mathe.js diff --git a/db.go b/db.go new file mode 100644 index 0000000..a614f60 --- /dev/null +++ b/db.go @@ -0,0 +1,148 @@ +package main + +import ( + "crypto/sha256" + "database/sql" + "encoding/hex" + "fmt" + "os" + + _ "github.com/go-sql-driver/mysql" + "github.com/joho/godotenv" + "github.com/labstack/echo/v4" +) + +var db *sql.DB + +func init() { + err := godotenv.Load() + if err != nil { + fmt.Println("Error loading .env file") + os.Exit(1) + } + + dbHost := os.Getenv("DB_Host") + dbPort := os.Getenv("DB_Port") + dbName := os.Getenv("DB_Name") + dbCharset := os.Getenv("DB_Charset") + dbUser := os.Getenv("DB_User") + dbPassword := os.Getenv("DB_Password") + + // Connect to the database + db, err = sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s", dbUser, dbPassword, dbHost, dbPort, dbName, dbCharset)) + // db, err = sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(db:3306)/%s?charset=utf8mb4", dbUser, dbPassword, dbName)) + + if err != nil { + fmt.Println("Error connecting to the database") + os.Exit(1) + } +} + +// User struct +type User struct { + ID int `json:"id"` + Username string `json:"username"` + Vorname string `json:"vorname"` + Nachname string `json:"nachname"` + Email string `json:"email"` + Password string `json:"password"` + LessonCount int `json:"lesson_count"` + Level int `json:"level"` + XP int `json:"xp"` + Coins int `json:"coins"` + IsAdmin sql.NullBool `json:"is_admin"` +} + +// CRUD operations + +func getUsers(c echo.Context) error { + rows, err := db.Query("SELECT * FROM user") + if err != nil { + return err + } + defer rows.Close() + + users := []User{} + for rows.Next() { + user := User{} + err := rows.Scan(&user.ID, &user.Username, &user.Vorname, &user.Nachname, &user.Email, &user.Password, &user.LessonCount, &user.Level, &user.XP, &user.Coins, &user.IsAdmin) + if err != nil { + return err + } + users = append(users, user) + } + + return c.JSON(200, users) +} + +func getUser(c echo.Context) error { + id := c.Param("id") + + row := db.QueryRow("SELECT * FROM user WHERE id = ?", id) + + user := User{} + err := row.Scan(&user.ID, &user.Username, &user.Vorname, &user.Nachname, &user.Email, &user.Password, &user.LessonCount, &user.Level, &user.XP, &user.Coins, &user.IsAdmin) + if err != nil { + return err + } + + return c.JSON(200, user) +} + +func createUser(c echo.Context) error { + user := new(User) + if err := c.Bind(user); err != nil { + return err + } + + // Hash das Passwort + user.Password = hashPassword(user.Password) + + result, err := db.Exec("INSERT INTO user (username, vorname, nachname, email, password, lesson_count, level, xp, coins, isAdmin) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + user.Username, user.Vorname, user.Nachname, user.Email, user.Password, user.LessonCount, user.Level, user.XP, user.Coins, user.IsAdmin) + if err != nil { + return err + } + + lastInsertID, err := result.LastInsertId() + if err != nil { + return err + } + + user.ID = int(lastInsertID) + + return c.JSON(201, user) +} + +func updateUser(c echo.Context) error { + id := c.Param("id") + + user := new(User) + if err := c.Bind(user); err != nil { + return err + } + + _, err := db.Exec("UPDATE user SET username = ?, vorname = ?, nachname = ?, email = ?, password = ?, lesson_count = ?, level = ?, xp = ?, coins = ?, isAdmin = ? WHERE id = ?", + user.Username, user.Vorname, user.Nachname, user.Email, user.Password, user.LessonCount, user.Level, user.XP, user.Coins, user.IsAdmin, id) + if err != nil { + return err + } + + return c.NoContent(204) +} + +func deleteUser(c echo.Context) error { + id := c.Param("id") + + _, err := db.Exec("DELETE FROM user WHERE id = ?", id) + if err != nil { + return err + } + + return c.NoContent(204) +} + +func hashPassword(password string) string { + hash := sha256.Sum256([]byte(password)) + return hex.EncodeToString(hash[:]) +} diff --git a/db/db.go b/db/db.go deleted file mode 100644 index 9676df8..0000000 --- a/db/db.go +++ /dev/null @@ -1,138 +0,0 @@ -package main - -import ( - "database/sql" - "fmt" - - _ "github.com/go-sql-driver/mysql" -) - -// Connect to MySQL database. -type Database struct { - connection *sql.DB - statement *sql.Stmt -} - -func NewDatabase(config map[string]string, username string, password string) (*Database, error) { - dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", username, password, config["host"], config["port"], config["dbname"]) - db, err := sql.Open("mysql", dsn) - if err != nil { - return nil, err - } - - return &Database{ - connection: db, - }, nil -} - -func (d *Database) Query(query string, params ...interface{}) (*Database, error) { - stmt, err := d.connection.Prepare(query) - if err != nil { - return nil, err - } - - d.statement = stmt - - _, err = stmt.Exec(params...) - if err != nil { - return nil, err - } - - return d, nil -} - -func (d *Database) Find() (map[string]interface{}, error) { - result := make(map[string]interface{}) - err := d.statement.QueryRow().Scan(result) - if err != nil { - return nil, err - } - - return result, nil -} - -func (d *Database) FindOrFail() (map[string]interface{}, error) { - result, err := d.Find() - if err != nil { - return nil, err - } - - if result == nil { - return nil, fmt.Errorf("Record not found") - } - - return result, nil -} - -func (d *Database) Get() ([]map[string]interface{}, error) { - rows, err := d.statement.Query() - if err != nil { - return nil, err - } - defer rows.Close() - - columns, err := rows.Columns() - if err != nil { - return nil, err - } - - result := make([]map[string]interface{}, 0) - values := make([]interface{}, len(columns)) - valuePtrs := make([]interface{}, len(columns)) - for rows.Next() { - for i := 0; i < len(columns); i++ { - valuePtrs[i] = &values[i] - } - - err := rows.Scan(valuePtrs...) - if err != nil { - return nil, err - } - - entry := make(map[string]interface{}) - for i, col := range columns { - val := values[i] - b, ok := val.([]byte) - if ok { - entry[col] = string(b) - } else { - entry[col] = val - } - } - - result = append(result, entry) - } - - return result, nil -} - -func (d *Database) Delete(params string) (*Database, error) { - _, err := d.Query("DELETE FROM user WHERE username = ?", params) - if err != nil { - return nil, err - } - - return d, nil -} - -func (d *Database) Update(params map[string]interface{}) (*Database, error) { - _, err := d.Query("UPDATE user SET level = ?, xp = ?, coins = ? WHERE username = ?", params["level"], params["xp"], params["coins"], params["username"]) - if err != nil { - return nil, err - } - - return d, nil -} - -func (d *Database) GetPlayerStats(params string) (map[string]interface{}, error) { - result, err := d.Query("SELECT username, level, lesson_count, xp, coins FROM user WHERE username = ?", params).Get() - if err != nil { - return nil, err - } - - if len(result) == 0 { - return nil, fmt.Errorf("Record not found") - } - - return result[0], nil -} diff --git a/go.mod b/go.mod index 7c4e19e..0212516 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.21.5 require ( github.com/chasefleming/elem-go v0.17.0 + github.com/joho/godotenv v1.5.1 github.com/labstack/echo/v4 v4.11.4 ) diff --git a/go.sum b/go.sum index 596e254..213e730 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrt github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8= github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= From 3c73706647da914c8f261f4fc54f87bd4cb7c573 Mon Sep 17 00:00:00 2001 From: Patryk Hegenberg Date: Fri, 29 Dec 2023 14:48:54 +0100 Subject: [PATCH 5/8] added persistant db storage to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d40cde8..09edf85 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ # vscode config files ./.vscode/* +math_wizard_db_data/* \ No newline at end of file From 2485af445fc461b59839913fa0cbd62abd4216d6 Mon Sep 17 00:00:00 2001 From: Patryk Hegenberg Date: Sat, 30 Dec 2023 10:44:22 +0100 Subject: [PATCH 6/8] changed docker-compose to work on all machines --- docker-compose.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index b22948e..4642444 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,7 +4,6 @@ services: web: #image: math_wizard build: - context: /home/pata/dev/WebProg/TheMathWizard dockerfile: Dockerfile.math_wizard ports: - "8080:8080" @@ -15,7 +14,6 @@ services: db: build: - context: /home/pata/dev/WebProg/TheMathWizard dockerfile: Dockerfile.db environment: MYSQL_ROOT_PASSWORD: password From cc9fa557fe207356bd1e583850a51628f2f1d6b1 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 4 Jun 2025 15:02:51 +0000 Subject: [PATCH 7/8] Add renovate.json --- renovate.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 renovate.json diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..7190a60 --- /dev/null +++ b/renovate.json @@ -0,0 +1,3 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json" +} From 960e3b7c31507c2209d14f084faaba590fa8a454 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 4 Jun 2025 17:24:08 +0000 Subject: [PATCH 8/8] Update php Docker tag to v8.4 --- Dockerfile.math_wizard | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.math_wizard b/Dockerfile.math_wizard index dc3859f..845815e 100644 --- a/Dockerfile.math_wizard +++ b/Dockerfile.math_wizard @@ -1,5 +1,5 @@ # Verwende ein Basisimage mit PHP -FROM php:8.2-cli +FROM php:8.4-cli # Setze das Arbeitsverzeichnis WORKDIR /app