diff --git a/server/category_group_new.go b/server/category_group_new.go
new file mode 100644
index 0000000..7b5a6fc
--- /dev/null
+++ b/server/category_group_new.go
@@ -0,0 +1,35 @@
+package server
+
+import (
+ "net/http"
+
+ "git.javil.eu/jacob1123/budgeteer/postgres"
+ "github.com/google/uuid"
+ "github.com/labstack/echo/v4"
+)
+
+type newCategoryGroupInformation struct {
+ BudgetID uuid.UUID `json:"budgetId"`
+ Group string `json:"group"`
+}
+
+func (h *Handler) newCategoryGroup(c echo.Context) error {
+ var newCategory newCategoryGroupInformation
+ if err := c.Bind(&newCategory); err != nil {
+ return echo.NewHTTPError(http.StatusNotAcceptable, err)
+ }
+
+ if newCategory.Group == "" {
+ return echo.NewHTTPError(http.StatusBadRequest, "category group is required")
+ }
+
+ budget, err := h.Service.CreateCategoryGroup(c.Request().Context(), postgres.CreateCategoryGroupParams{
+ BudgetID: newCategory.BudgetID,
+ Name: newCategory.Group,
+ })
+ if err != nil {
+ return err
+ }
+
+ return c.JSON(http.StatusOK, budget)
+}
diff --git a/server/http.go b/server/http.go
index f5a54e6..d41a46d 100644
--- a/server/http.go
+++ b/server/http.go
@@ -56,6 +56,9 @@ func (h *Handler) LoadRoutes(router *echo.Echo) {
category := authenticated.Group("/category")
category.POST("/new", h.newCategory)
+ categoryGroup := authenticated.Group("/category-group")
+ categoryGroup.POST("/new", h.newCategoryGroup)
+
budget := authenticated.Group("/budget")
budget.POST("/new", h.newBudget)
budget.GET("/:budgetid", h.budget)
diff --git a/web/src/dialogs/CreateCategoryGroup.vue b/web/src/dialogs/CreateCategoryGroup.vue
new file mode 100644
index 0000000..fdb3cc6
--- /dev/null
+++ b/web/src/dialogs/CreateCategoryGroup.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ error }}
+
+
+
diff --git a/web/src/pages/Budgeting.vue b/web/src/pages/Budgeting.vue
index 1a1578d..8a302b5 100644
--- a/web/src/pages/Budgeting.vue
+++ b/web/src/pages/Budgeting.vue
@@ -9,6 +9,7 @@ import { POST } from "../api";
import CreateCategory from "../dialogs/CreateCategory.vue";
import BudgetingSummary from "../components/BudgetingSummary.vue";
import { Category } from "../stores/category";
+import CreateCategoryGroup from "../dialogs/CreateCategoryGroup.vue";
const props = defineProps<{
budgetid: string,
@@ -57,7 +58,6 @@ onMounted(() => {
useSessionStore().setTitle("Budget for " + selected.value.Month + "/" + selected.value.Year);
})
-
const expandedGroups = ref