Skip to content

Commit

Permalink
Merge branch 'main' into profile-pages
Browse files Browse the repository at this point in the history
  • Loading branch information
Alder Whiteford authored and Alder Whiteford committed Jun 15, 2024
2 parents 19784b7 + f7c6e7c commit e129072
Show file tree
Hide file tree
Showing 39 changed files with 33,118 additions and 4,864 deletions.
20 changes: 10 additions & 10 deletions backend/entities/clubs/members/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
)

type ClubMemberServiceInterface interface {
GetClubMembers(clubID string, pageInfo fiberpaginate.PageInfo) ([]models.User, error)
CreateClubMember(clubID string, userID string) error
GetClubMembers(clubID string, pageInfo fiberpaginate.PageInfo) ([]models.User, error)
DeleteClubMember(clubID string, userID string) error
}

Expand All @@ -21,15 +21,6 @@ func NewClubMemberService(params types.ServiceParams) ClubMemberServiceInterface
return &ClubMemberService{params}
}

func (cms *ClubMemberService) GetClubMembers(clubID string, pageInfo fiberpaginate.PageInfo) ([]models.User, error) {
clubIDAsUUID, err := utilities.ValidateID(clubID)
if err != nil {
return nil, err
}

return GetClubMembers(cms.DB, *clubIDAsUUID, pageInfo)
}

func (cms *ClubMemberService) CreateClubMember(clubID string, userID string) error {
clubIDAsUUID, err := utilities.ValidateID(clubID)
if err != nil {
Expand All @@ -44,6 +35,15 @@ func (cms *ClubMemberService) CreateClubMember(clubID string, userID string) err
return CreateClubMember(cms.DB, *clubIDAsUUID, *userIDAsUUID)
}

func (cms *ClubMemberService) GetClubMembers(clubID string, pageInfo fiberpaginate.PageInfo) ([]models.User, error) {
clubIDAsUUID, err := utilities.ValidateID(clubID)
if err != nil {
return nil, err
}

return GetClubMembers(cms.DB, *clubIDAsUUID, pageInfo)
}

func (cms *ClubMemberService) DeleteClubMember(clubID string, userID string) error {
clubIDAsUUID, err := utilities.ValidateID(clubID)
if err != nil {
Expand Down
11 changes: 11 additions & 0 deletions backend/entities/clubs/transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,14 @@ func GetAdminIDs(db *gorm.DB, clubID uuid.UUID) ([]uuid.UUID, error) {

return adminUUIDs, nil
}

func IsMember(db *gorm.DB, clubID uuid.UUID, userID uuid.UUID) (bool, error) {
db = cache.SetUseCache(db, true)

var count int64
if err := db.Table("user_club_members").Where("club_id = ? AND user_id = ?", clubID, userID).Count(&count).Error; err != nil {
return false, err
}

return count > 0, nil
}
2 changes: 2 additions & 0 deletions backend/entities/events/base/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package base

import (
"github.com/GenerateNU/sac/backend/entities/events/previews"
"github.com/GenerateNU/sac/backend/entities/events/rsvps"
"github.com/GenerateNU/sac/backend/entities/events/series"
"github.com/GenerateNU/sac/backend/entities/events/tags"

Expand All @@ -17,6 +18,7 @@ func EventRoutes(eventParams types.RouteParams) {
// MARK: must be called first to avoid conflict between api/v1/events/preview and api/v1/events/:eventID
previews.EventPreviews(eventParams)
EventRouter(eventParams)
rsvps.EventsRSVPs(eventParams)
series.EventSeries(eventParams)
tags.EventTags(eventParams)
}
Expand Down
2 changes: 1 addition & 1 deletion backend/entities/events/previews/transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func processEventStubs(db *gorm.DB, events []EventStub) ([]EventPreview, error)
}

var hosts []models.Club
if err := db.Where("id IN ?", eventIDs).Find(&hosts).Error; err != nil {
if err := db.Joins("JOIN events ON events.host = clubs.id").Where("events.id IN ?", eventIDs).Find(&hosts).Error; err != nil {
return nil, err
}

Expand Down
47 changes: 47 additions & 0 deletions backend/entities/events/rsvps/controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package rsvps

import (
"net/http"

"github.com/GenerateNU/sac/backend/utilities"
"github.com/garrettladley/fiberpaginate"
"github.com/gofiber/fiber/v2"
)

type Controller struct {
service Service
}

func NewController(service Service) *Controller {
return &Controller{service: service}
}

func (co *Controller) GetEventRSVPs(c *fiber.Ctx) error {
pageInfo, ok := fiberpaginate.FromContext(c)
if !ok {
return utilities.ErrExpectedPageInfo
}

followers, err := co.service.GetEventRSVPs(c.Params("eventID"), *pageInfo)
if err != nil {
return err
}

return c.Status(http.StatusOK).JSON(followers)
}

func (co *Controller) CreateEventRSVP(c *fiber.Ctx) error {
if err := co.service.CreateEventRSVP(c.Params("eventID"), c.Params("userID")); err != nil {
return err
}

return c.SendStatus(http.StatusCreated)
}

func (co *Controller) DeleteEventRSVP(c *fiber.Ctx) error {
if err := co.service.DeleteEventRSVP(c.Params("eventID"), c.Params("userID")); err != nil {
return err
}

return c.SendStatus(http.StatusNoContent)
}
18 changes: 18 additions & 0 deletions backend/entities/events/rsvps/routes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package rsvps

import (
"github.com/GenerateNU/sac/backend/permission"
"github.com/GenerateNU/sac/backend/types"
"github.com/gofiber/fiber/v2"
)

func EventsRSVPs(params types.RouteParams) {
controller := NewController(NewHandler(params.ServiceParams))

// api/v1/events/:eventID/rsvps/*
params.Router.Route("/rsvps", func(r fiber.Router) {
r.Get("/", params.UtilityMiddleware.Paginator, controller.GetEventRSVPs)
r.Post("/:userID", controller.CreateEventRSVP)
r.Delete("/:userID", params.AuthMiddleware.UserAuthorizeById, params.AuthMiddleware.Authorize(permission.DeleteAll), controller.DeleteEventRSVP)
})
}
59 changes: 59 additions & 0 deletions backend/entities/events/rsvps/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package rsvps

import (
"github.com/GenerateNU/sac/backend/entities/models"
"github.com/GenerateNU/sac/backend/types"
"github.com/GenerateNU/sac/backend/utilities"
"github.com/garrettladley/fiberpaginate"
)

type Service interface {
CreateEventRSVP(eventID string, userID string) error
GetEventRSVPs(eventID string, pageInfo fiberpaginate.PageInfo) ([]models.User, error)
DeleteEventRSVP(eventID string, userID string) error
}

type Handler struct {
types.ServiceParams
}

func NewHandler(params types.ServiceParams) Service {
return &Handler{params}
}

func (h *Handler) CreateEventRSVP(eventID string, userID string) error {
eventIDAsUUID, err := utilities.ValidateID(eventID)
if err != nil {
return err
}

userIDAsUUID, err := utilities.ValidateID(userID)
if err != nil {
return err
}

return CreateEventRSVP(h.DB, *eventIDAsUUID, *userIDAsUUID)
}

func (h *Handler) GetEventRSVPs(eventID string, pageInfo fiberpaginate.PageInfo) ([]models.User, error) {
eventIDAsUUID, err := utilities.ValidateID(eventID)
if err != nil {
return nil, err
}

return GetEventRSVPs(h.DB, *eventIDAsUUID, pageInfo)
}

func (h *Handler) DeleteEventRSVP(eventID string, userID string) error {
eventIDAsUUID, err := utilities.ValidateID(eventID)
if err != nil {
return err
}

userIDAsUUID, err := utilities.ValidateID(userID)
if err != nil {
return err
}

return DeleteEventRSVP(h.DB, *eventIDAsUUID, *userIDAsUUID)
}
93 changes: 93 additions & 0 deletions backend/entities/events/rsvps/transactions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package rsvps

import (
"errors"

"github.com/GenerateNU/sac/backend/database/cache"
"github.com/GenerateNU/sac/backend/entities/clubs"
"github.com/GenerateNU/sac/backend/entities/events"
"github.com/GenerateNU/sac/backend/entities/models"
"github.com/GenerateNU/sac/backend/entities/users"
"github.com/GenerateNU/sac/backend/utilities"
"github.com/garrettladley/fiberpaginate"
"github.com/google/uuid"
"gorm.io/gorm"
)

func CreateEventRSVP(db *gorm.DB, eventID uuid.UUID, userID uuid.UUID) error {
db = cache.SetUseCache(db, true)

event, err := events.GetEvent(db, eventID)
if err != nil {
return err
}

if event.IsArchived {
return utilities.ForbiddenReason(errors.New("cannot RSVP to an archived event"))
}

if event.IsDraft {
return utilities.ForbiddenReason(errors.New("cannot RSVP to a draft event"))
}

user, err := users.GetUser(db, userID)
if err != nil {
return err
}

if !event.IsPublic {
isMember, err := clubs.IsMember(db, *event.Host, userID)
if err != nil {
return err
}

if !isMember {
return utilities.ForbiddenReason(errors.New("cannot RSVP to a private event when not a member"))
}
}

if err := db.Model(&user).Association("RSVP").Append(event); err != nil {
return err
}

return nil
}

func GetEventRSVPs(db *gorm.DB, eventID uuid.UUID, pageInfo fiberpaginate.PageInfo) ([]models.User, error) {
db = cache.SetUseCache(db, true)

event, err := events.GetEvent(db, eventID)
if err != nil {
return nil, err
}

var users []models.User
if err := db.Scopes(utilities.IntoScope(pageInfo, db)).Model(&event).Association("RSVP").Find(&users); err != nil {
return nil, err
}

return users, nil
}

func DeleteEventRSVP(db *gorm.DB, eventID uuid.UUID, userID uuid.UUID) error {
db = cache.SetUseCache(db, true)

user, err := users.GetUser(db, userID)
if err != nil {
return err
}

event, err := events.GetEvent(db, eventID)
if err != nil {
return err
}

if err := db.Model(&user).Association("RSVP").Delete(event); err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return utilities.BadRequest(errors.New("user was never RSVPed to this event"))
}
return err
}

return nil
}
14 changes: 9 additions & 5 deletions backend/utilities/api_error.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,27 @@ func BadRequest(err error) APIError {
}

func InvalidJSON() APIError {
return NewAPIError(http.StatusBadRequest, fmt.Errorf("invalid JSON request data"))
return NewAPIError(http.StatusBadRequest, errors.New("invalid JSON request data"))
}

func Unauthorized() APIError {
return NewAPIError(http.StatusUnauthorized, fmt.Errorf("unauthorized"))
return NewAPIError(http.StatusUnauthorized, errors.New("unauthorized"))
}

func Forbidden() APIError {
return NewAPIError(http.StatusForbidden, fmt.Errorf("forbidden"))
return NewAPIError(http.StatusForbidden, errors.New("forbidden"))
}

func ForbiddenReason(err error) APIError {
return NewAPIError(http.StatusForbidden, err)
}

func Conflict() APIError {
return NewAPIError(http.StatusConflict, fmt.Errorf("conflict"))
return NewAPIError(http.StatusConflict, errors.New("conflict"))
}

func InternalServerError() APIError {
return NewAPIError(http.StatusInternalServerError, fmt.Errorf("internal server error"))
return NewAPIError(http.StatusInternalServerError, errors.New("internal server error"))
}

func ErrorHandler(c *fiber.Ctx, err error) error {
Expand Down
2 changes: 1 addition & 1 deletion frontend/lib/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@generatesac/lib",
"version": "0.0.164",
"version": "0.0.169",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
1 change: 0 additions & 1 deletion frontend/lib/src/api/eventApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export const eventApi = baseApi.injectEndpoints({
? result.map((event) => ({ type: "Event", id: event.id }))
: ["Event"],
transformResponse: (response) => {
console.log('here!!!!')
return z.array(eventSchema).parse(response);
},
}),
Expand Down
4 changes: 2 additions & 2 deletions frontend/lib/src/types/club.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { z } from "zod";

import { rootModelSchema } from "./root";
import { recruitmentSchema } from "./recruitment";

// Schemas:
export const createClubRequestBodySchema = z.object({
Expand Down Expand Up @@ -35,11 +36,10 @@ const clubSchemaIntermediate = z.object({
preview: z.string().max(255),
description: z.string(),
num_members: z.number(),
is_recruiting: z.boolean(),
application_link: z.string().max(255),
logo: z.string().max(255).optional(),
weekly_time_committment: z.number().optional(),
one_word_to_describe_us: z.string().max(20).optional(),
recruitment: recruitmentSchema.optional(),
});

export const clubSchema = clubSchemaIntermediate.merge(rootModelSchema);
Expand Down
3 changes: 2 additions & 1 deletion frontend/lib/src/types/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const eventPreviewSchemaIntermediate = z.object({
start_time: z.string(),
end_time: z.string(),

tags: tagSchema.array(),
tags: tagSchema.array().optional().nullable(),
host_name: z.string().max(255),
host_logo: z.string().max(255).optional(),
});
Expand All @@ -76,3 +76,4 @@ export type UpdateEventRequestBody = z.infer<
>;
export type Event = z.infer<typeof eventSchema>;
export type EventPreview = z.infer<typeof eventPreviewSchema>;
export type EventType = z.infer<typeof eventTypeEnum>;
2 changes: 1 addition & 1 deletion frontend/mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"@fortawesome/free-solid-svg-icons": "^6.5.2",
"@fortawesome/react-fontawesome": "^0.2.2",
"@fortawesome/react-native-fontawesome": "^0.3.2",
"@generatesac/lib": "0.0.164",
"@generatesac/lib": "0.0.169",
"@gorhom/bottom-sheet": "^4.6.3",
"@hookform/resolvers": "^3.4.2",
"@react-native-async-storage/async-storage": "^1.23.1",
Expand Down
Loading

0 comments on commit e129072

Please sign in to comment.