diff --git a/.air.toml b/.air.toml deleted file mode 100644 index 3ed7c7c..0000000 --- a/.air.toml +++ /dev/null @@ -1,46 +0,0 @@ -root = "." -testdata_dir = ".testdata" -tmp_dir = ".tmp" - -[build] -args_bin = [] -bin = "./main" -cmd = "make build" -delay = 1000 -exclude_dir = ["assets", ".tmp", "vendor", ".testdata"] -exclude_file = [] -exclude_regex = ["_test.go", ".*_templ.go"] -exclude_unchanged = false -follow_symlink = false -full_bin = "" -include_dir = [] -include_ext = ["go", "tpl", "tmpl", "html", "templ"] -include_file = [] -kill_delay = "0s" -log = "build-errors.log" -poll = false -poll_interval = 0 -post_cmd = [] -pre_cmd = [] -rerun = false -rerun_delay = 500 -send_interrupt = false -stop_on_error = false - -[color] -app = "" -build = "yellow" -main = "magenta" -runner = "green" -watcher = "cyan" - -[log] -main_only = false -time = false - -[misc] -clean_on_exit = false - -[screen] -clear_on_rebuild = false -keep_scroll = true diff --git a/Makefile b/Makefile index bec86eb..9309a29 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ setup: build: @echo "Building..." @templ generate - @tailwindcss -i static/css/input.css -o static/css/output.css + @tailwindcss -i static/css/input.css -o static/css/output.css --minify @go build -o main cmd/main.go @@ -43,11 +43,12 @@ clean: @rm -f main + # run templ generation in watch mode to detect all .templ files and # re-create _templ.txt files on change, then send reload event to browser. # Default url: http://localhost:7331 watch/templ: - templ generate --watch --proxy="http://localhost:3000" --open-browser=false -v + templ generate --watch --proxy="http://localhost:3000" --open-browser=false # run air to detect any go file changes to re-build and re-run the server. @@ -56,7 +57,7 @@ watch/server: --build.cmd "go build -o .tmp/main cmd/main.go" \ --build.bin ".tmp/main" \ --build.delay "100" \ - --build.exclude_dir "node_modules" \ + --build.exclude_dir ".tmp" \ --build.include_ext "go" \ --build.stop_on_error "false" \ --misc.clean_on_exit true @@ -74,11 +75,12 @@ watch/sync_assets: --build.bin "true" \ --build.delay "100" \ --build.exclude_dir "" \ + --build.exclude_regex "output.css" \ --build.include_dir "static" \ --build.include_ext "js,css" # start all 4 watch processes in parallel. -.PHONY: build +.PHONY: watch watch: make -j4 watch/templ watch/server watch/tailwind watch/sync_assets diff --git a/cmd/main.go b/cmd/main.go index f34f1d2..bdace72 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -29,12 +29,15 @@ func main() { server.HandleFunc("POST /login", authHandler.Login) server.HandleFunc("/logout", authHandler.Logout) - fs := http.FileServer(http.Dir("./static")) server.Handle("/static/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") - w.Header().Set("Pragma", "no-cache") - w.Header().Set("Expires", "0") - http.StripPrefix("/static/", fs).ServeHTTP(w, r) + // Clean cache in dev mode + if os.Getenv("APP_ENV") != "production" { + w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") + w.Header().Set("Pragma", "no-cache") + w.Header().Set("Expires", "0") + } + + http.StripPrefix("/static/", http.FileServer(http.Dir("./static"))).ServeHTTP(w, r) })) err := http.ListenAndServe(addr, server) diff --git a/go.mod b/go.mod index faa1b65..6cb3b83 100644 --- a/go.mod +++ b/go.mod @@ -5,13 +5,13 @@ go 1.22.4 require ( github.com/a-h/templ v0.2.747 github.com/joho/godotenv v1.5.1 + github.com/go-playground/validator/v10 v10.22.0 ) require ( github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect golang.org/x/crypto v0.22.0 // indirect golang.org/x/net v0.24.0 // indirect diff --git a/static/css/input.css b/static/css/input.css index 7574b41..3bb8434 100644 --- a/static/css/input.css +++ b/static/css/input.css @@ -50,6 +50,58 @@ --orange-10: #ff801f; --orange-11: #ffa057; --orange-12: #ffe0c2; + + --tomato-1: #181111; + --tomato-2: #1f1513; + --tomato-3: #391714; + --tomato-4: #4e1511; + --tomato-5: #5e1c16; + --tomato-6: #6e2920; + --tomato-7: #853a2d; + --tomato-8: #ac4d39; + --tomato-9: #e54d2e; + --tomato-10: #ec6142; + --tomato-11: #ff977d; + --tomato-12: #fbd3cb; + + --cyan-1: #0b161a; + --cyan-2: #101b20; + --cyan-3: #082c36; + --cyan-4: #003848; + --cyan-5: #004558; + --cyan-6: #045468; + --cyan-7: #12677e; + --cyan-8: #11809c; + --cyan-9: #00a2c7; + --cyan-10: #23afd0; + --cyan-11: #4ccce6; + --cyan-12: #b6ecf7; + + --green-1: #0e1512; + --green-2: #121b17; + --green-3: #132d21; + --green-4: #113b29; + --green-5: #174933; + --green-6: #20573e; + --green-7: #28684a; + --green-8: #2f7c57; + --green-9: #30a46c; + --green-10: #33b074; + --green-11: #3dd68c; + --green-12: #b1f1cb; + + --amber-1: #16120c; + --amber-2: #1d180f; + --amber-3: #302008; + --amber-4: #3f2700; + --amber-5: #4d3000; + --amber-6: #5c3d05; + --amber-7: #714f19; + --amber-8: #8f6424; + --amber-9: #ffc53d; + --amber-10: #ffd60a; + --amber-11: #ffca16; + --amber-12: #ffe7b3; } .light { @@ -78,66 +130,58 @@ --orange-10: #ef5f00; --orange-11: #cc4e00; --orange-12: #582d1d; - } - @supports (color: color(display-p3 1 1 1)) { - @media (color-gamut: p3) { - .dark { - --sand-1: color(display-p3 0.067 0.067 0.063); - --sand-2: color(display-p3 0.098 0.098 0.094); - --sand-3: color(display-p3 0.135 0.135 0.129); - --sand-4: color(display-p3 0.164 0.163 0.156); - --sand-5: color(display-p3 0.193 0.192 0.183); - --sand-6: color(display-p3 0.23 0.229 0.217); - --sand-7: color(display-p3 0.285 0.282 0.267); - --sand-8: color(display-p3 0.384 0.378 0.357); - --sand-9: color(display-p3 0.434 0.428 0.403); - --sand-10: color(display-p3 0.487 0.481 0.456); - --sand-11: color(display-p3 0.707 0.703 0.68); - --sand-12: color(display-p3 0.933 0.933 0.926); - - --orange-1: color(display-p3 0.088 0.07 0.057); - --orange-2: color(display-p3 0.113 0.089 0.061); - --orange-3: color(display-p3 0.189 0.12 0.056); - --orange-4: color(display-p3 0.262 0.132 0); - --orange-5: color(display-p3 0.315 0.168 0.016); - --orange-6: color(display-p3 0.376 0.219 0.088); - --orange-7: color(display-p3 0.465 0.283 0.147); - --orange-8: color(display-p3 0.601 0.359 0.201); - --orange-9: color(display-p3 0.9 0.45 0.2); - --orange-10: color(display-p3 0.98 0.51 0.23); - --orange-11: color(display-p3 1 0.63 0.38); - --orange-12: color(display-p3 0.98 0.883 0.775); - } - - .light { - --sand-1: color(display-p3 0.992 0.992 0.989); - --sand-2: color(display-p3 0.977 0.977 0.973); - --sand-3: color(display-p3 0.943 0.942 0.936); - --sand-4: color(display-p3 0.913 0.912 0.903); - --sand-5: color(display-p3 0.885 0.883 0.873); - --sand-6: color(display-p3 0.854 0.852 0.839); - --sand-7: color(display-p3 0.813 0.81 0.794); - --sand-8: color(display-p3 0.738 0.734 0.713); - --sand-9: color(display-p3 0.553 0.553 0.528); - --sand-10: color(display-p3 0.511 0.511 0.488); - --sand-11: color(display-p3 0.388 0.388 0.37); - --sand-12: color(display-p3 0.129 0.126 0.111); - - --orange-1: color(display-p3 0.995 0.988 0.985); - --orange-2: color(display-p3 0.994 0.968 0.934); - --orange-3: color(display-p3 0.989 0.938 0.85); - --orange-4: color(display-p3 1 0.874 0.687); - --orange-5: color(display-p3 1 0.821 0.583); - --orange-6: color(display-p3 0.975 0.767 0.545); - --orange-7: color(display-p3 0.919 0.693 0.486); - --orange-8: color(display-p3 0.877 0.597 0.379); - --orange-9: color(display-p3 0.9 0.45 0.2); - --orange-10: color(display-p3 0.87 0.409 0.164); - --orange-11: color(display-p3 0.76 0.34 0); - --orange-12: color(display-p3 0.323 0.185 0.127); - } - } + --tomato-1: #fffcfc; + --tomato-2: #fff8f7; + --tomato-3: #feebe7; + --tomato-4: #ffdcd3; + --tomato-5: #ffcdc2; + --tomato-6: #fdbdaf; + --tomato-7: #f5a898; + --tomato-8: #ec8e7b; + --tomato-9: #e54d2e; + --tomato-10: #dd4425; + --tomato-11: #d13415; + --tomato-12: #5c271f; + + --cyan-1: #fafdfe; + --cyan-2: #f2fafb; + --cyan-3: #def7f9; + --cyan-4: #caf1f6; + --cyan-5: #b5e9f0; + --cyan-6: #9ddde7; + --cyan-7: #7dcedc; + --cyan-8: #3db9cf; + --cyan-9: #00a2c7; + --cyan-10: #0797b9; + --cyan-11: #107d98; + --cyan-12: #0d3c48; + + --green-1: #fbfefc; + --green-2: #f4fbf6; + --green-3: #e6f6eb; + --green-4: #d6f1df; + --green-5: #c4e8d1; + --green-6: #adddc0; + --green-7: #8eceaa; + --green-8: #5bb98b; + --green-9: #30a46c; + --green-10: #2b9a66; + --green-11: #218358; + --green-12: #193b2d; + + --amber-1: #fefdfb; + --amber-2: #fefbe9; + --amber-3: #fff7c2; + --amber-4: #ffee9c; + --amber-5: #fbe577; + --amber-6: #f3d673; + --amber-7: #e9c162; + --amber-8: #e2a336; + --amber-9: #ffc53d; + --amber-10: #ffba18; + --amber-11: #ab6400; + --amber-12: #4f3422; } } @@ -146,5 +190,6 @@ -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; - border-color: var(--sand-8); + border-color: var(--sand-7); + outline-color: var(--orange-10); } diff --git a/tailwind.config.js b/tailwind.config.js index dec0a85..5e60a98 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -26,6 +26,10 @@ module.exports = { colors: { accent: generateScale("orange"), gray: generateScale("sand"), + info: generateScale("cyan"), + error: generateScale("tomato"), + success: generateScale("green"), + warning: generateScale("amber"), }, }, fontFamily: { diff --git a/web/view/employee/employee_create.templ b/web/view/employee/employee_create.templ index a20c66b..50622ad 100644 --- a/web/view/employee/employee_create.templ +++ b/web/view/employee/employee_create.templ @@ -6,8 +6,13 @@ import ( ) templ EmployeeCreatePage() { - @layout.Dashbaord("Painel", "employees") { + @layout.Dashbaord("Painel", "employees/create") {
+ @ui.Breadcrumb([]ui.BreadcrumbItem{ + {Label: "Profissinais", Href: "/employees"}, + {Label: "Novo", Href: "/employees/create"}, + }) +

Novo Profissinal

@EmployeeCreateForm()
} @@ -19,21 +24,22 @@ type EmployeeCreateFormProps struct { } templ EmployeeCreateForm() { -
- @ui.TextInput(ui.TextInputProps{ - Name: "name", - Label: "Nome", - }) - @ui.TextInput(ui.TextInputProps{ - Name: "email", - Label: "Email", - }) - @ui.TextInput(ui.TextInputProps{ - Name: "password", - Label: "Senha", - }) - -
+ @ui.Card(ui.CardProps{}) { +
+ @ui.TextInput(ui.TextInputProps{ + Name: "name", + Label: "Nome", + Placeholder: "Nome do Profissinal", + }) + @ui.TextInput(ui.TextInputProps{ + Name: "email", + Label: "Email", + Placeholder: "exemplo@gmail.com", + }) + @ui.Button(ui.ButtonProps{Type: "submit", Class: "ml-auto"}) { + + Criar + } +
+ } } diff --git a/web/view/employee/employees.templ b/web/view/employee/employees.templ index 29593f0..bcd2148 100644 --- a/web/view/employee/employees.templ +++ b/web/view/employee/employees.templ @@ -8,11 +8,15 @@ import ( templ EmployeesPage() { @layout.Dashbaord("Painel", "employees") {
+ @ui.Breadcrumb([]ui.BreadcrumbItem{ + {Label: "Profissinais", Href: "/employees"}, + }) +

Novo Profissinal

@ui.TextInput(ui.TextInputProps{}) - + @ui.Link(ui.LinkProps{Href: "employees/create"}) { Novo Profissional - + }
EMPLOYEES diff --git a/web/view/layout/base.templ b/web/view/layout/base.templ index cbf3a69..76b5b65 100644 --- a/web/view/layout/base.templ +++ b/web/view/layout/base.templ @@ -7,11 +7,16 @@ templ Base(title string) { { title } | Imperium Tattoo - - + + + { children... } + } diff --git a/web/view/layout/dashboard.templ b/web/view/layout/dashboard.templ index bfd31be..9832e90 100644 --- a/web/view/layout/dashboard.templ +++ b/web/view/layout/dashboard.templ @@ -12,9 +12,9 @@ templ Dashbaord(title, route string) { LOGO USER @@ -23,7 +23,7 @@ templ Dashbaord(title, route string) { -
+
{ children... }
diff --git a/web/view/ui/breadcrumb.templ b/web/view/ui/breadcrumb.templ new file mode 100644 index 0000000..df86a11 --- /dev/null +++ b/web/view/ui/breadcrumb.templ @@ -0,0 +1,31 @@ +package ui + +import "strconv" + +type BreadcrumbItem struct { + Label string + Href string +} + +// data-active={i == len(items)-1} +templ Breadcrumb(items []BreadcrumbItem) { +
+ for i, item := range items { + if i > 0 { + - + } + + { item.Label } + + } +
+} diff --git a/web/view/ui/button.templ b/web/view/ui/button.templ index 048250c..1f9aeed 100644 --- a/web/view/ui/button.templ +++ b/web/view/ui/button.templ @@ -1,10 +1,27 @@ package ui type ButtonProps struct { + Class string + Type string } -templ Button() { - } + +type LinkProps struct { + Class string + Href string +} + +templ Link(props LinkProps) { + + { children... } + +} diff --git a/web/view/ui/card.templ b/web/view/ui/card.templ new file mode 100644 index 0000000..366c8a7 --- /dev/null +++ b/web/view/ui/card.templ @@ -0,0 +1,11 @@ +package ui + +type CardProps struct { + Class string +} + +templ Card(props CardProps) { +
+ { children... } +
+} diff --git a/web/view/ui/form-field.templ b/web/view/ui/form_field.templ similarity index 50% rename from web/view/ui/form-field.templ rename to web/view/ui/form_field.templ index 4701d3c..ed91b93 100644 --- a/web/view/ui/form-field.templ +++ b/web/view/ui/form_field.templ @@ -6,11 +6,11 @@ type FormFieldProps struct { } templ FormField(props FormFieldProps) { -
- +
+ { children... } if props.Error != "" { - { props.Error } + { props.Error } }
} diff --git a/web/view/ui/text-input.templ b/web/view/ui/text_input.templ similarity index 58% rename from web/view/ui/text-input.templ rename to web/view/ui/text_input.templ index 6afa7d4..797fbb6 100644 --- a/web/view/ui/text-input.templ +++ b/web/view/ui/text_input.templ @@ -1,12 +1,13 @@ package ui type TextInputProps struct { - Name string - Placeholder string Label string - Value string Error string Class string + Name string + Value string + Type string + Placeholder string } templ TextInput(props TextInputProps) { @@ -15,7 +16,13 @@ templ TextInput(props TextInputProps) { name={ props.Name } placeholder={ props.Placeholder } value={ props.Value } - class={ "rounded px-2 h-10 bg-neutral-600 placeholder:text-neutral-400" + props.Class } + type={ props.Type } + class=" + rounded-md px-2 h-9 bg-gray-1 border outline-none + placeholder:text-gray-10 + hover:border-gray-10 active:border-accent-10 + focus:border-accent-10 focus:ring-2 focus:ring-accent-10 + " /> } }