diff --git a/.env.dev b/.env.dev new file mode 100644 index 0000000..998ed7e --- /dev/null +++ b/.env.dev @@ -0,0 +1,12 @@ + +# Example ".env" for development, just copy this file to ".env" and edit that one +MODE=development + +# Development server host +HOST=:4000 + +# Development server url +URL=http://localhost:3000 + +EMAIL=mail@example.org + diff --git a/.gitignore b/.gitignore index b947077..f94630c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ dist/ +.env \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..dcd2fa9 --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ + +.PHONY: all +all: setup build + +.PHONY: setup +setup: + cp -n .env.dev .env + cp -n .env.dev server/.env + mkdir -p dist/ + + $(MAKE) -C server setup + $(MAKE) -C client setup + +# rsync options: [a]rchive [c]hecksum [v]erbose [h]uman +.PHONY: build +build: + $(MAKE) -C server build + $(MAKE) -C client build + + rsync -acvh server/bin/posti-dm dist/ + rsync -acvh client/dist/ dist/ + + cp .env dist/.env + + diff --git a/README.md b/README.md index 2bea328..1221661 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,53 @@ # Posti DM +![homepage screenshot](./screenshot.png) + Prototipo di applicazione web per prenotare posti in dipartimento. -- FrontEnd: Vite + VanillaJS +- FrontEnd: Vite + VanillaJS (?) + +- BackEnd: Golang + go-chi + godotent + sqlite3 (?) + +## Usage + +The first time you want to build the project you should run first + +```bash +$ make setup +``` + +Then to build the client and the server just run + +```bash +$ make build +``` + +### Running: In Development + +You need to start two concurrent processes as follows + +```bash +# +# Firstly start the backend +# +$ cd server +$ go run . + +# or also to reload the server on changes with "entr" +$ find -name '*.go' | entr -r -s 'go run .' + +# +# Then in another shell start ViteJS to live-reload the frontend +# +$ cd client +$ npm run dev +``` + +### Running: In Production + +Just `make build` at the root of the project and then run the following (ehm forse alcuni path sono relativi rispetto alla directory corrent quindi per ora รจ meglio fare `cd` dentro `dist/`) -- BackEnd: Golang + go-chi + sqlite3 (?) +```bash +$ cd dist/ +$ ./posti-dm +``` diff --git a/client/Makefile b/client/Makefile new file mode 100644 index 0000000..b21928b --- /dev/null +++ b/client/Makefile @@ -0,0 +1,12 @@ + +.PHONY: all +all: setup build + +.PHONY: setup +setup: + mkdir -p dist/ + +.PHONY: build +build: + npm run build + diff --git a/client/src/style.scss b/client/src/style.scss index f6ed08a..45bdddb 100644 --- a/client/src/style.scss +++ b/client/src/style.scss @@ -1,4 +1,5 @@ @use './reset.scss'; + @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600&display=swap'); $media-small-device-size: 750px; diff --git a/client/vite.config.js b/client/vite.config.js index dae6c68..f9e99ce 100644 --- a/client/vite.config.js +++ b/client/vite.config.js @@ -1,6 +1,15 @@ +import { resolve } from 'path' import { defineConfig } from 'vite' export default defineConfig({ + build: { + rollupOptions: { + input: { + main: resolve(__dirname, 'index.html'), + login: resolve(__dirname, 'login.html'), + }, + }, + }, server: { proxy: { '/api': { diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000..9a37b0c Binary files /dev/null and b/screenshot.png differ diff --git a/server/Makefile b/server/Makefile new file mode 100644 index 0000000..a2bd782 --- /dev/null +++ b/server/Makefile @@ -0,0 +1,20 @@ + +.PHONY: all +all: setup build + +.PHONY: setup +setup: + mkdir -p bin/ + +.PHONY: build +build: + go build -o bin/posti-dm . + +.PHONY: run +run: + go run . + +.PHONY: watch +watch: + find -name '*.go' | entr -r -s 'go run .' + diff --git a/server/config/config.go b/server/config/config.go new file mode 100644 index 0000000..6efc7b3 --- /dev/null +++ b/server/config/config.go @@ -0,0 +1,37 @@ +package config + +import ( + "log" + "os" + "strings" + + "github.com/joho/godotenv" +) + +var Mode string + +var Host string +var Url string + +var Email string + +func loadEnv(target *string, name, defaultValue string) { + value := os.Getenv(name) + if len(strings.TrimSpace(value)) == 0 { + *target = defaultValue + } else { + *target = value + } + log.Printf("%s = %v", name, *target) +} + +func Load() { + godotenv.Load() + + log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) + + loadEnv(&Mode, "MODE", "production") + loadEnv(&Host, "HOST", "localhost:4000") + loadEnv(&Url, "URL", "http://localhost:3000") + loadEnv(&Email, "EMAIL", "mail@example.org") +} diff --git a/server/go.mod b/server/go.mod index 7f7a537..943c040 100644 --- a/server/go.mod +++ b/server/go.mod @@ -5,4 +5,5 @@ go 1.17 require ( github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae github.com/go-chi/chi/v5 v5.0.7 + github.com/joho/godotenv v1.4.0 ) diff --git a/server/go.sum b/server/go.sum index 32ab0ba..e468445 100644 --- a/server/go.sum +++ b/server/go.sum @@ -2,3 +2,5 @@ github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae h1:zzGwJfFlFGD94Cy github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8= github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= +github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= diff --git a/server/main.go b/server/main.go index aec6ccb..0475a4c 100644 --- a/server/main.go +++ b/server/main.go @@ -4,13 +4,14 @@ import ( "log" "net/http" + "git.phc.dm.unipi.it/aziis98/posti-dm/server/config" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" ) -var HOST = ":4000" - func main() { + config.Load() + r := chi.NewRouter() r.Use(middleware.RequestID) @@ -18,25 +19,30 @@ func main() { r.Use(middleware.Logger) r.Use(middleware.Recoverer) - server := NewServer() + if config.Mode == "production" { + log.Printf(`Adding production routes...`) + + // Assets + r.Handle("/assets/*", http.StripPrefix("/assets/", http.FileServer(http.Dir("./assets")))) - // api := chi.NewRouter() - // api.Get("/example", func(w http.ResponseWriter, r *http.Request) { - // w.Header().Add("Content-Type", "application/json") - // http.SetCookie(w, &http.Cookie{ - // Name: "test", - // Value: "Prova", - // Expires: time.Now().Add(120 * time.Second), - // }) - // json.NewEncoder(w).Encode(map[string]interface{}{ - // "foo": "bar", - // }) - // }) + r.Get("/", func(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "./index.html") + }) + r.Get("/login", func(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "./login.html") + }) + // FIXME: Route temporanea, basta configurare ViteJS per bene + r.Get("/login.html", func(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/login", http.StatusTemporaryRedirect) + }) + } + + server := NewServer() r.Mount("/api", server.ApiRoute) - log.Printf(`Starting server on %s...`, HOST) - err := http.ListenAndServe(HOST, r) + log.Printf(`Starting server on "%s"...`, config.Host) + err := http.ListenAndServe(config.Host, r) if err != nil { panic(err) }