diff --git a/Internal/adapters/repository/postgres.go b/Internal/adapters/repository/postgres.go index e1974f5..cbf2b20 100644 --- a/Internal/adapters/repository/postgres.go +++ b/Internal/adapters/repository/postgres.go @@ -41,6 +41,7 @@ func (db *DBContainer) Migrate() error { err := db.Gorm.AutoMigrate( &domain.User{}, &domain.Invitation{}, + &domain.Project{}, ) if err != nil { log.Fatalf("Failed to migrate users: %v", err) diff --git a/Internal/adapters/repository/projectRepo.go b/Internal/adapters/repository/projectRepo.go new file mode 100644 index 0000000..a06199f --- /dev/null +++ b/Internal/adapters/repository/projectRepo.go @@ -0,0 +1,27 @@ +package repository + +import ( + "github.com/Arjuna-Ragil/Localbase/Internal/core/domain" +) + +type ProjectRepo struct { + DB *DBContainer +} + +func NewProjectRepo(db *DBContainer) *ProjectRepo { + return &ProjectRepo{DB: db} +} + +func (pr *ProjectRepo) CreateProject(project *domain.Project) (*domain.Project, error) { + if err := pr.DB.Gorm.Create(project).Error; err != nil { + return nil, err + } + return project, nil +} + +func (pr *ProjectRepo) FetchProjects(projects []domain.Project) ([]domain.Project, error) { + if err := pr.DB.Gorm.Find(&projects).Error; err != nil { + return nil, err + } + return projects, nil +} diff --git a/Internal/api/Routes/routev1.go b/Internal/api/Routes/routev1.go index 2a50cb8..1fc52f9 100644 --- a/Internal/api/Routes/routev1.go +++ b/Internal/api/Routes/routev1.go @@ -12,6 +12,7 @@ type Deps struct { User *handlers.UserHandler Auth *handlers.AuthHandler System *handlers.SystemHandler + Project *handlers.ProjectHandler UserRepo *repository.UserRepository Config *config.Config } @@ -45,6 +46,11 @@ func SetupRouterV1(r *gin.Engine, deps Deps) { admin.POST("/invite", deps.Auth.CreateInviteHandler) admin.GET("/alluser", deps.User.AllUserHandler) admin.PUT("/updaterole", deps.User.UpdateRoleHandler) + admin.POST("/createproject", deps.Project.CreateProjectHandler) + } + project := protected.Group("/project") + { + project.GET("/projects", deps.Project.GetAllProjectHandler) } } } diff --git a/Internal/api/handlers/projectHandler.go b/Internal/api/handlers/projectHandler.go new file mode 100644 index 0000000..d4d37ec --- /dev/null +++ b/Internal/api/handlers/projectHandler.go @@ -0,0 +1,63 @@ +package handlers + +import ( + "github.com/Arjuna-Ragil/Localbase/Internal/core/services" + "github.com/gin-gonic/gin" +) + +type ProjectHandler struct { + ProjectService *services.ProjectService +} + +func NewProjectHandler(projectService *services.ProjectService) *ProjectHandler { + return &ProjectHandler{ProjectService: projectService} +} + +func (ph *ProjectHandler) CreateProjectHandler(c *gin.Context) { + var input services.CreateInput + userRole, _ := c.Get("userRole") + if userRole != "admin" { + c.JSON(401, gin.H{ + "message": "You are not authorized to perform this action", + "data": nil, + }) + return + } + err := c.ShouldBindJSON(&input) + if err != nil { + c.JSON(400, gin.H{ + "message": "Invalid input", + "data": err.Error(), + }) + return + } + + project, err := ph.ProjectService.CreateProject(&input) + if err != nil { + c.JSON(500, gin.H{ + "message": "failed to create project", + "data": err.Error(), + }) + return + } + c.JSON(200, gin.H{ + "message": "successfully created project", + "data": project, + }) +} + +func (ph *ProjectHandler) GetAllProjectHandler(c *gin.Context) { + userRole := c.GetString("userRole") + projects, err := ph.ProjectService.GetProjects(userRole) + if err != nil { + c.JSON(500, gin.H{ + "message": "failed to get projects", + "data": err.Error(), + }) + return + } + c.JSON(200, gin.H{ + "message": "got all projects", + "data": projects, + }) +} diff --git a/Internal/api/handlers/userHandler.go b/Internal/api/handlers/userHandler.go index 26fb067..679ebf8 100644 --- a/Internal/api/handlers/userHandler.go +++ b/Internal/api/handlers/userHandler.go @@ -60,14 +60,14 @@ func (uh *UserHandler) AllUserHandler(c *gin.Context) { func (uh *UserHandler) UpdateRoleHandler(c *gin.Context) { var input services.RoleInput - //userRole, _ := c.Get("userRole") - //if userRole != "admin" { - // c.JSON(400, gin.H{ - // "message": "Not allowed to update role", - // "data": false, - // }) - // return - //} + userRole, _ := c.Get("userRole") + if userRole != "admin" { + c.JSON(400, gin.H{ + "message": "Not allowed to update role", + "data": false, + }) + return + } if err := c.ShouldBindJSON(&input); err != nil { c.JSON(400, gin.H{ "message": "input not valid", diff --git a/Internal/api/middleware/auth.go b/Internal/api/middleware/auth.go index d9a6038..6fb6683 100644 --- a/Internal/api/middleware/auth.go +++ b/Internal/api/middleware/auth.go @@ -14,7 +14,8 @@ import ( func AuthMiddleware(userRepo *repository.UserRepository, cfg *config.Config) gin.HandlerFunc { return func(c *gin.Context) { if cfg.AuthMode == "false" { - c.Set("userID", 1) + c.Set("userID", uint(1)) + c.Set("userRole", "admin") c.Next() return } diff --git a/Internal/core/domain/projectdb.go b/Internal/core/domain/projectdb.go new file mode 100644 index 0000000..031512a --- /dev/null +++ b/Internal/core/domain/projectdb.go @@ -0,0 +1,11 @@ +package domain + +import "time" + +type Project struct { + ID uint `gorm:"primary_key;auto_increment" json:"id"` + Name string `gorm:"size:255;not null" json:"name"` + Desc string `gorm:"size:255;" json:"desc"` + AdminID uint `json:"admin_id"` + CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"` +} diff --git a/Internal/core/services/projectService.go b/Internal/core/services/projectService.go new file mode 100644 index 0000000..b9ce760 --- /dev/null +++ b/Internal/core/services/projectService.go @@ -0,0 +1,47 @@ +package services + +import ( + "errors" + + "github.com/Arjuna-Ragil/Localbase/Internal/adapters/repository" + "github.com/Arjuna-Ragil/Localbase/Internal/core/domain" +) + +type ProjectService struct { + ProjectRepo *repository.ProjectRepo +} + +func NewProjectService(projectRepo *repository.ProjectRepo) *ProjectService { + return &ProjectService{ProjectRepo: projectRepo} +} + +type CreateInput struct { + Name string `json:"name"` + Desc string `json:"desc"` + AdminID uint `json:"admin_id"` +} + +func (ps *ProjectService) CreateProject(input *CreateInput) (*domain.Project, error) { + projectInfo := domain.Project{ + Name: input.Name, + Desc: input.Desc, + AdminID: input.AdminID, + } + project, err := ps.ProjectRepo.CreateProject(&projectInfo) + if err != nil { + return nil, err + } + return project, nil +} + +func (ps *ProjectService) GetProjects(Role string) ([]domain.Project, error) { + if Role != "admin" { + return nil, errors.New("permission denied") + } + var projects []domain.Project + project, err := ps.ProjectRepo.FetchProjects(projects) + if err != nil { + return nil, err + } + return project, nil +} diff --git a/Lb-web/src/components/ui/textarea.tsx b/Lb-web/src/components/ui/textarea.tsx new file mode 100644 index 0000000..87c2072 --- /dev/null +++ b/Lb-web/src/components/ui/textarea.tsx @@ -0,0 +1,24 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +export interface TextareaProps + extends React.TextareaHTMLAttributes { } + +const Textarea = React.forwardRef( + ({ className, ...props }, ref) => { + return ( +