package controller import ( "net/http" "github.com/labstack/echo/v4" "gitrepo.ru/neonxp/nquest/api" "gitrepo.ru/neonxp/nquest/pkg/contextlib" "gitrepo.ru/neonxp/nquest/pkg/models" "gitrepo.ru/neonxp/nquest/pkg/service" ) type Team struct { UserService *service.User TeamService *service.Team } func (t *Team) GetTeams(ctx echo.Context) error { currentTeamID := uint(0) user := contextlib.GetUser(ctx) if user.Team != nil { currentTeamID = user.Team.TeamID } teams, err := t.TeamService.List(ctx.Request().Context()) if err != nil { return err } resp := make([]api.TeamView, 0, len(teams)) for _, t := range teams { memberCount := len(t.Members) isCurrentTeam := currentTeamID == t.ID resp = append(resp, api.TeamView{ Id: int(t.ID), Members: &memberCount, Name: t.Name, CurrentTeam: &isCurrentTeam, CreatedAt: t.CreatedAt.Format("02.01.06"), }) } return ctx.JSON(http.StatusOK, api.TeamsListResponse(resp)) } func (t *Team) GetTeamsTeamID(ctx echo.Context, teamID int) error { return t.getTeamResponse(ctx, teamID) } func (t *Team) PostTeamsTeamIDMembers(ctx echo.Context, teamID int) error { user := contextlib.GetUser(ctx) if user.Team == nil || user.Team.TeamID != uint(teamID) || user.Team.Role != models.Captain { return ctx.JSON(http.StatusForbidden, api.ErrorResponse{ Code: http.StatusForbidden, Message: "Вам нельзя менять состав команды", }) } req := &api.PostTeamsTeamIDMembersJSONRequestBody{} if err := ctx.Bind(req); err != nil { return ctx.JSON(http.StatusBadRequest, api.ErrorResponse{ Code: http.StatusBadRequest, Message: err.Error(), }) } if err := t.TeamService.UpdateMembers(ctx.Request().Context(), uint(teamID), req.Members); err != nil { return ctx.JSON(http.StatusBadRequest, api.ErrorResponse{ Code: http.StatusBadRequest, Message: err.Error(), }) } return t.getTeamResponse(ctx, teamID) } func (t *Team) PostTeams(ctx echo.Context) error { req := &api.PostTeamsJSONRequestBody{} if err := ctx.Bind(req); err != nil { return err } user := contextlib.GetUser(ctx) team, err := t.TeamService.Create(ctx.Request().Context(), req.Name, user) if err != nil { return err } return ctx.JSON(http.StatusCreated, api.TeamView{ Id: int(team.ID), Name: team.Name, CreatedAt: team.CreatedAt.Format("02.01.06"), }) } func (t *Team) DeleteTeamsTeamID(ctx echo.Context, teamID int) error { user := contextlib.GetUser(ctx) if user.Team == nil || user.Team.TeamID != uint(teamID) || user.Team.Role != models.Captain { return ctx.JSON(http.StatusForbidden, api.ErrorResponse{ Code: http.StatusForbidden, Message: "Нельзя удалить не свою команду", }) } if err := t.TeamService.Delete(ctx.Request().Context(), uint(teamID)); err != nil { return ctx.JSON(http.StatusForbidden, api.ErrorResponse{ Code: http.StatusForbidden, Message: err.Error(), }) } return ctx.NoContent(http.StatusNoContent) } func (t *Team) getTeamResponse(ctx echo.Context, teamID int) error { team, err := t.TeamService.GetByID(ctx.Request().Context(), uint(teamID)) if err != nil { return ctx.JSON(http.StatusNotFound, api.ErrorResponse{ Code: http.StatusNotFound, Message: err.Error(), }) } members := make([]api.TeamMember, 0, len(team.Members)) for _, tm := range team.Members { members = append(members, api.TeamMember{ Role: api.MapTeamRole[tm.Role], User: api.UserView{ Id: int(tm.User.ID), Username: tm.User.Username, }, CreatedAt: tm.CreatedAt.Format("02.01.06"), }) } requests := make([]api.TeamRequest, 0, len(team.Requests)) for _, tm := range team.Requests { requests = append(requests, api.TeamRequest{ User: api.UserView{ Id: int(tm.User.ID), Username: tm.User.Username, }, CreatedAt: tm.CreatedAt.Format("02.01.06"), }) } return ctx.JSON(http.StatusOK, api.TeamResponse(api.TeamResponse{ Id: teamID, Name: team.Name, Members: members, Requests: requests, CreatedAt: team.CreatedAt.Format("02.01.06"), })) } // (POST /teams/{teamID}/requests) func (t *Team) PostTeamsTeamIDRequests(ctx echo.Context, teamID int) error { user := contextlib.GetUser(ctx) if user.Team != nil { return ctx.JSON(http.StatusForbidden, api.ErrorResponse{ Code: http.StatusForbidden, Message: "Вы уже в другой команде", }) } if err := t.TeamService.Request(ctx.Request().Context(), uint(teamID), user); err != nil { return ctx.JSON(http.StatusBadRequest, api.ErrorResponse{ Code: http.StatusBadRequest, Message: err.Error(), }) } return t.getTeamResponse(ctx, teamID) } // (POST /teams/{teamID}/requests/{userID}) func (t *Team) PostTeamsTeamIDRequestsUserID(ctx echo.Context, teamID int, userID int) error { user := contextlib.GetUser(ctx) if user.Team == nil || user.Team.TeamID != uint(teamID) || user.Team.Role != models.Captain { return ctx.JSON(http.StatusForbidden, api.ErrorResponse{ Code: http.StatusForbidden, Message: "Вам нельзя менять состав команды", }) } req := &api.PostTeamsTeamIDRequestsUserIDJSONRequestBody{} if err := ctx.Bind(req); err != nil { return ctx.JSON(http.StatusBadRequest, api.ErrorResponse{ Code: http.StatusBadRequest, Message: err.Error(), }) } if err := t.TeamService.ApproveRequest(ctx.Request().Context(), teamID, uint(userID), req.Approve); err != nil { return ctx.JSON(http.StatusBadRequest, api.ErrorResponse{ Code: http.StatusBadRequest, Message: err.Error(), }) } return t.getTeamResponse(ctx, teamID) } // (DELETE /teams/{teamID}/members) func (t *Team) DeleteTeamsTeamIDMembers(ctx echo.Context, teamID int) error { user := contextlib.GetUser(ctx) if err := t.TeamService.DeleteMember(ctx.Request().Context(), teamID, user.ID); err != nil { return ctx.JSON(http.StatusBadRequest, api.ErrorResponse{ Code: http.StatusBadRequest, Message: err.Error(), }) } return t.getTeamResponse(ctx, teamID) }