From ed74f2cffa902a3e9aeb614f8dcf65f04658a597 Mon Sep 17 00:00:00 2001 From: Bobby <30593201+luciferreeves@users.noreply.github.com> Date: Fri, 19 Dec 2025 18:52:39 +0530 Subject: error controllers, types and templates and layouts --- controllers/errors.go | 53 +++++++++++++++++++++++++ static/css/main.css | 86 ++++++++++++++++++++++++++++++++++++++++ static/css/style.css | 86 ---------------------------------------- templates/auth/login.django | 54 ++++++++++--------------- templates/error.django | 8 ++++ templates/layouts/generic.django | 27 +++++++++++++ types/errors.go | 10 +++++ utils/shortcuts/error.go | 25 ++++++++++++ 8 files changed, 230 insertions(+), 119 deletions(-) create mode 100644 controllers/errors.go create mode 100644 static/css/main.css delete mode 100644 static/css/style.css create mode 100644 templates/error.django create mode 100644 templates/layouts/generic.django create mode 100644 types/errors.go create mode 100644 utils/shortcuts/error.go diff --git a/controllers/errors.go b/controllers/errors.go new file mode 100644 index 0000000..019083a --- /dev/null +++ b/controllers/errors.go @@ -0,0 +1,53 @@ +package controllers + +import ( + "lain/types" + "lain/utils/shortcuts" + + "github.com/gofiber/fiber/v2" +) + +func BadRequest(context *fiber.Ctx, err error) error { + return shortcuts.RenderError(types.TemplateError{ + Context: context, + PageTitle: "400 – Bad Request", + ErrorMessage: shortcuts.BuildErrorMessage(err, "The request could not be understood by the server."), + StatusCode: fiber.StatusBadRequest, + }) +} + +func Forbidden(context *fiber.Ctx, err error) error { + return shortcuts.RenderError(types.TemplateError{ + Context: context, + PageTitle: "403 – Forbidden", + ErrorMessage: shortcuts.BuildErrorMessage(err, "You do not have permission to access this resource."), + StatusCode: fiber.StatusForbidden, + }) +} + +func InternalServerError(context *fiber.Ctx, err error) error { + return shortcuts.RenderError(types.TemplateError{ + Context: context, + PageTitle: "500 – Internal Server Error", + ErrorMessage: shortcuts.BuildErrorMessage(err, "An unexpected error occurred on the server."), + StatusCode: fiber.StatusInternalServerError, + }) +} + +func NotFound(context *fiber.Ctx, err error) error { + return shortcuts.RenderError(types.TemplateError{ + Context: context, + PageTitle: "404 – Not Found", + ErrorMessage: shortcuts.BuildErrorMessage(err, "The page you are looking for does not exist."), + StatusCode: fiber.StatusNotFound, + }) +} + +func Unauthorized(context *fiber.Ctx, err error) error { + return shortcuts.RenderError(types.TemplateError{ + Context: context, + PageTitle: "401 – Unauthorized", + ErrorMessage: shortcuts.BuildErrorMessage(err, "You must be logged in to access this resource."), + StatusCode: fiber.StatusUnauthorized, + }) +} diff --git a/static/css/main.css b/static/css/main.css new file mode 100644 index 0000000..683a620 --- /dev/null +++ b/static/css/main.css @@ -0,0 +1,86 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Verdana', sans-serif; + background: #fff5f8; +} + +.login-page { + display: flex; + align-items: center; + justify-content: center; + min-height: 100vh; +} + +.login-container { + background: white; + padding: 2rem; + border: 2px solid #ffccee; + border-radius: 8px; + max-width: 400px; + width: 100%; +} + +.login-container h1 { + color: #663366; + text-align: center; + margin-bottom: 0.5rem; +} + +.subtitle { + text-align: center; + color: #ff99cc; + margin-bottom: 2rem; + font-style: italic; +} + +.error { + background: #ffcccc; + color: #cc0000; + padding: 0.75rem; + border-radius: 4px; + margin-bottom: 1rem; +} + +.field { + margin-bottom: 1rem; +} + +.field label { + display: block; + color: #663366; + margin-bottom: 0.25rem; +} + +.field input { + width: 100%; + padding: 0.5rem; + border: 1px solid #ffccee; + border-radius: 4px; +} + +button { + width: 100%; + padding: 0.75rem; + background: #ff99cc; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 1rem; +} + +button:hover { + background: #ff66aa; +} + +footer { + margin-top: 2rem; + text-align: center; + font-size: 0.75rem; + color: #999; +} \ No newline at end of file diff --git a/static/css/style.css b/static/css/style.css deleted file mode 100644 index 683a620..0000000 --- a/static/css/style.css +++ /dev/null @@ -1,86 +0,0 @@ -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} - -body { - font-family: 'Verdana', sans-serif; - background: #fff5f8; -} - -.login-page { - display: flex; - align-items: center; - justify-content: center; - min-height: 100vh; -} - -.login-container { - background: white; - padding: 2rem; - border: 2px solid #ffccee; - border-radius: 8px; - max-width: 400px; - width: 100%; -} - -.login-container h1 { - color: #663366; - text-align: center; - margin-bottom: 0.5rem; -} - -.subtitle { - text-align: center; - color: #ff99cc; - margin-bottom: 2rem; - font-style: italic; -} - -.error { - background: #ffcccc; - color: #cc0000; - padding: 0.75rem; - border-radius: 4px; - margin-bottom: 1rem; -} - -.field { - margin-bottom: 1rem; -} - -.field label { - display: block; - color: #663366; - margin-bottom: 0.25rem; -} - -.field input { - width: 100%; - padding: 0.5rem; - border: 1px solid #ffccee; - border-radius: 4px; -} - -button { - width: 100%; - padding: 0.75rem; - background: #ff99cc; - color: white; - border: none; - border-radius: 4px; - cursor: pointer; - font-size: 1rem; -} - -button:hover { - background: #ff66aa; -} - -footer { - margin-top: 2rem; - text-align: center; - font-size: 0.75rem; - color: #999; -} \ No newline at end of file diff --git a/templates/auth/login.django b/templates/auth/login.django index 0fbdceb..33ed81a 100644 --- a/templates/auth/login.django +++ b/templates/auth/login.django @@ -1,37 +1,25 @@ - - - - - - {{ Title }} - - - -
-

{{ AppName }}

-

{{ AppDescription }}

+{% extends 'layouts/generic.django' %} +{% block content %} +
+

{{ AppName }}

+

{{ AppDescription }}

- {% if Error %} -
{{ Error }}
- {% endif %} + {% if Error %} +
{{ Error }}
+ {% endif %} -
-
- - -
+ +
+ + +
-
- - -
+
+ + +
- -
- -
- {{ AppName }} - Powered by {{ AppEngine }} - © shi.foo 2025 -
-
- - + + +
+{% endblock %} diff --git a/templates/error.django b/templates/error.django new file mode 100644 index 0000000..f766688 --- /dev/null +++ b/templates/error.django @@ -0,0 +1,8 @@ +{% extends 'layouts/generic.django' %} +{% block content %} +
+

{{ ErrorTitle }}

+

{{ ErrorMessage }}

+ Go back home +
+{% endblock %} diff --git a/templates/layouts/generic.django b/templates/layouts/generic.django new file mode 100644 index 0000000..3ca183b --- /dev/null +++ b/templates/layouts/generic.django @@ -0,0 +1,27 @@ + + + + + {{ Title }} - {{ Appname }} + + + + {% block head %} + + {% endblock %} + + +
+ {% block content %} + + {% endblock %} +
+ + + + {% block scripts %} + + {% endblock %} + diff --git a/types/errors.go b/types/errors.go new file mode 100644 index 0000000..11f60f9 --- /dev/null +++ b/types/errors.go @@ -0,0 +1,10 @@ +package types + +import "github.com/gofiber/fiber/v2" + +type TemplateError struct { + Context *fiber.Ctx + PageTitle string + ErrorMessage error + StatusCode int +} diff --git a/utils/shortcuts/error.go b/utils/shortcuts/error.go new file mode 100644 index 0000000..4cb0e81 --- /dev/null +++ b/utils/shortcuts/error.go @@ -0,0 +1,25 @@ +package shortcuts + +import ( + "errors" + "lain/types" + "lain/utils/meta" + + "github.com/gofiber/fiber/v2" +) + +func BuildErrorMessage(err error, alternateString string) error { + if err != nil { + return err + } + + return errors.New(alternateString) +} + +func RenderError(error types.TemplateError) error { + meta.SetPageTitle(error.Context, error.PageTitle) + return RenderWithStatus(error.Context, "error", fiber.Map{ + "ErrorTitle": error.PageTitle, + "ErrorMessage": error.ErrorMessage.Error(), + }, error.StatusCode) +} -- cgit v1.2.3