Utenti
+Utenti
{{if .PageData}}{{.PageData.Total}}{{else}}-{{end}}
diff --git a/README.md b/README.md index c5e64c9..bcb79b0 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,6 @@ DB_PG_DSN=postgres://trustcontact:trustcontact@localhost:5432/trustcontact?sslmo - Public: `web/templates/public` - Private: `web/templates/private` - Admin: `web/templates/admin` -- Components Flowbite: `web/templates/components` ## Email in Develop diff --git a/flowbite-ui/input.css b/flowbite-ui/input.css index f7c8b18..72b0504 100644 --- a/flowbite-ui/input.css +++ b/flowbite-ui/input.css @@ -3,3 +3,15 @@ @source "../web/static/**/*.js"; @source "./node_modules/flowbite/**/*.js"; @import "tailwindcss"; + +@layer utilities { + .flag-lang { + width: 32px; + height: 22px; + } + + .flag-lang-ch { + width: 22px; + height: 22px; + } +} diff --git a/internal/controllers/admin_controller.go b/internal/controllers/admin_controller.go index ed77f1b..a97d119 100644 --- a/internal/controllers/admin_controller.go +++ b/internal/controllers/admin_controller.go @@ -23,6 +23,8 @@ func (ac *AdminController) Dashboard(c *fiber.Ctx) error { tmpl, err := template.ParseFiles( "web/templates/layout.html", + "web/templates/admin/_navbar.html", + "web/templates/partials/language_dropdown.html", "web/templates/public/_flash.html", "web/templates/admin/dashboard.html", ) diff --git a/internal/controllers/auth_controller.go b/internal/controllers/auth_controller.go index 3202368..9d9b956 100644 --- a/internal/controllers/auth_controller.go +++ b/internal/controllers/auth_controller.go @@ -19,13 +19,9 @@ func NewAuthController(authService *services.AuthService) *AuthController { } func (ac *AuthController) ShowHome(c *fiber.Ctx) error { - if _, ok := httpmw.CurrentUserFromContext(c); ok { - return c.Redirect("/welcome") - } - return renderPublic(c, "home.html", map[string]any{ "Title": "Home", - "NavSection": "public", + "NavSection": "home", }) } @@ -145,6 +141,13 @@ func (ac *AuthController) ShowVerifyNotice(c *fiber.Ctx) error { }) } +func (ac *AuthController) ShowForbidden(c *fiber.Ctx) error { + return renderPublic(c, "forbidden.html", map[string]any{ + "Title": "Forbidden", + "NavSection": "public", + }) +} + func (ac *AuthController) ShowForgotPassword(c *fiber.Ctx) error { return renderPublic(c, "forgot_password.html", map[string]any{ "Title": "Forgot password", diff --git a/internal/controllers/render.go b/internal/controllers/render.go index 1997a00..c30abb2 100644 --- a/internal/controllers/render.go +++ b/internal/controllers/render.go @@ -26,6 +26,8 @@ func renderPublic(c *fiber.Ctx, page string, data map[string]any) error { files := []string{ "web/templates/layout.html", + "web/templates/public/_navbar.html", + "web/templates/partials/language_dropdown.html", "web/templates/public/_flash.html", filepath.Join("web/templates/public", page), } @@ -62,6 +64,8 @@ func renderPrivate(c *fiber.Ctx, page string, data map[string]any) error { files := []string{ "web/templates/layout.html", + "web/templates/private/_navbar.html", + "web/templates/partials/language_dropdown.html", "web/templates/public/_flash.html", filepath.Join("web/templates/private", page), } diff --git a/internal/controllers/users_controller.go b/internal/controllers/users_controller.go index 6ab15a3..1f3dcee 100644 --- a/internal/controllers/users_controller.go +++ b/internal/controllers/users_controller.go @@ -38,6 +38,8 @@ func (uc *UsersController) Index(c *fiber.Ctx) error { tmpl, err := template.ParseFiles( "web/templates/layout.html", + "web/templates/admin/_navbar.html", + "web/templates/partials/language_dropdown.html", "web/templates/public/_flash.html", "web/templates/admin/users/index.html", "web/templates/admin/users/_table.html", diff --git a/internal/http/middleware/auth.go b/internal/http/middleware/auth.go index d2662b8..e928bbe 100644 --- a/internal/http/middleware/auth.go +++ b/internal/http/middleware/auth.go @@ -25,7 +25,7 @@ func RequireAdmin() fiber.Handler { return c.Redirect("/login") } if user.Role != models.RoleAdmin { - return c.Status(fiber.StatusForbidden).SendString("forbidden") + return c.Status(fiber.StatusForbidden).Redirect("/forbidden") } return c.Next() } diff --git a/internal/http/router.go b/internal/http/router.go index 8974f98..ee4417f 100644 --- a/internal/http/router.go +++ b/internal/http/router.go @@ -48,6 +48,7 @@ func RegisterRoutes(app *fiber.App, store *session.Store, database *gorm.DB, cfg app.Post("/forgot-password", authController.ForgotPassword) app.Get("/reset-password", authController.ShowResetPassword) app.Post("/reset-password", authController.ResetPassword) + app.Get("/forbidden", authController.ShowForbidden) app.Get("/welcome", httpmw.RequireAuth(), authController.ShowWelcome) private := app.Group("/private", httpmw.RequireAuth(), httpmw.RequireAdmin()) diff --git a/web/static/css/app.css b/web/static/css/app.css index e74da59..19a52f8 100644 --- a/web/static/css/app.css +++ b/web/static/css/app.css @@ -901,6 +901,9 @@ .mx-auto { margin-inline: auto; } + .my-2 { + margin-block: calc(var(--spacing) * 2); + } .my-4 { margin-block: calc(var(--spacing) * 4); } @@ -1460,6 +1463,9 @@ .w-10 { width: calc(var(--spacing) * 10); } + .w-40 { + width: calc(var(--spacing) * 40); + } .w-44 { width: calc(var(--spacing) * 44); } @@ -1549,6 +1555,9 @@ border-color: var(--color-blue-600); } } + .min-w-\[95px\] { + min-width: 95px; + } .flex-1 { flex: 1; } @@ -1734,6 +1743,9 @@ .overflow-y-auto { overflow-y: auto; } + .rounded { + border-radius: 0.25rem; + } .rounded-full { border-radius: calc(infinity * 1px); } @@ -2083,6 +2095,9 @@ stroke: var(--color-gray-700) !important; } } + .object-cover { + object-fit: cover; + } .apexcharts-legend { .apexcharts-canvas & { padding: 0 !important; @@ -2138,6 +2153,9 @@ .py-0\.5 { padding-block: calc(var(--spacing) * 0.5); } + .py-1 { + padding-block: calc(var(--spacing) * 1); + } .py-2 { padding-block: calc(var(--spacing) * 2); } @@ -2274,6 +2292,10 @@ --tw-leading: calc(var(--spacing) * 9); line-height: calc(var(--spacing) * 9); } + .leading-none { + --tw-leading: 1; + line-height: 1; + } .leading-relaxed { --tw-leading: var(--leading-relaxed); line-height: var(--leading-relaxed); @@ -2600,11 +2622,6 @@ margin-inline-start: calc(var(--spacing) * 4); } } - .md\:me-0 { - @media (width >= 48rem) { - margin-inline-end: calc(var(--spacing) * 0); - } - } .md\:mt-0 { @media (width >= 48rem) { margin-top: calc(var(--spacing) * 0); @@ -2900,6 +2917,16 @@ } } } +@layer utilities { + .flag-lang { + width: 32px; + height: 22px; + } + .flag-lang-ch { + width: 22px; + height: 22px; + } +} @layer base { .tooltip-arrow,.tooltip-arrow:before { position: absolute; diff --git a/web/static/vendor/flags/ch.svg b/web/static/vendor/flags/ch.svg new file mode 100644 index 0000000..df92656 --- /dev/null +++ b/web/static/vendor/flags/ch.svg @@ -0,0 +1,5 @@ + diff --git a/web/static/vendor/flags/de.svg b/web/static/vendor/flags/de.svg new file mode 100644 index 0000000..cacb423 --- /dev/null +++ b/web/static/vendor/flags/de.svg @@ -0,0 +1,5 @@ + diff --git a/web/static/vendor/flags/en.svg b/web/static/vendor/flags/en.svg new file mode 100644 index 0000000..b321789 --- /dev/null +++ b/web/static/vendor/flags/en.svg @@ -0,0 +1,11 @@ + diff --git a/web/static/vendor/flags/en_us.svg b/web/static/vendor/flags/en_us.svg new file mode 100644 index 0000000..881f770 --- /dev/null +++ b/web/static/vendor/flags/en_us.svg @@ -0,0 +1,12 @@ + diff --git a/web/static/vendor/flags/fr.svg b/web/static/vendor/flags/fr.svg new file mode 100644 index 0000000..574a3e8 --- /dev/null +++ b/web/static/vendor/flags/fr.svg @@ -0,0 +1,5 @@ + diff --git a/web/static/vendor/flags/it.svg b/web/static/vendor/flags/it.svg new file mode 100644 index 0000000..83c5b96 --- /dev/null +++ b/web/static/vendor/flags/it.svg @@ -0,0 +1,5 @@ + diff --git a/web/templates/admin/_navbar.html b/web/templates/admin/_navbar.html new file mode 100644 index 0000000..c9b5566 --- /dev/null +++ b/web/templates/admin/_navbar.html @@ -0,0 +1,53 @@ +{{define "navbar"}} + +{{end}} + +{{define "navbar_controls"}} +{{template "language_dropdown" .}} + +{{if .CurrentUser}} +
| Timestamp | Actor | Action |
|---|---|---|
| Timestamp | +Actor | +Action | +
| - | - | - |
Security logs placeholder.
+Security logs placeholder.
Area amministrazione.
+Area amministrazione.
Utenti
+Utenti
{{if .PageData}}{{.PageData.Total}}{{else}}-{{end}}
Ruolo corrente
+Ruolo corrente
{{if and .CurrentUser (eq .CurrentUser.Role "admin")}} - admin + admin {{else}} - user + user {{end}}
Navigazione
- Gestione utenti +Navigazione
+ Gestione utentiTemplate pagina utenti admin in stile Flowbite.
+Template pagina utenti admin in stile Flowbite.
Ricerca, ordinamento e paging server-side via HTMX.
+Ricerca, ordinamento e paging server-side via HTMX.