Skip to content

Commit

Permalink
Add Notify Report Download API endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
waveyboym committed Sep 29, 2024
1 parent d509e0e commit 2d32b26
Show file tree
Hide file tree
Showing 5 changed files with 283 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ const statusColorMap: Record<string, ChipProps["color"]> = {
};

// type BookingComponentProps = {
// roleColumnName: string; // Add other props as needed
// positionColumnName: string; // Add other props as needed
// };

const INITIAL_VISIBLE_COLUMNS = ["name", "role", "status", "actions"];
const INITIAL_VISIBLE_COLUMNS = ["name", "position", "status", "role", "actions"];

type User = (typeof users)[0];

Expand Down Expand Up @@ -131,7 +131,7 @@ export default function App() {
{user.email}
</User>
);
case "role":
case "position":
return (
<div className="flex flex-col">
<p className="text-bold text-small text-text_col capitalize">
Expand All @@ -153,7 +153,26 @@ export default function App() {
{cellValue}
</Chip>
);

case "role":
return (
<Dropdown>
<DropdownTrigger>
<Button
color={user.role === "basic" ? "primary" : "secondary"}
variant="bordered"
>
{user.role}
</Button>
</DropdownTrigger>
<DropdownMenu
aria-label="Action event example"
onAction={(key) => alert(key)}
>
<DropdownItem key="basic">basic</DropdownItem>
<DropdownItem key="admin">admin</DropdownItem>
</DropdownMenu>
</Dropdown>
)

case "actions":

Expand Down
195 changes: 182 additions & 13 deletions occupi-backend/pkg/handlers/api_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -1431,7 +1431,7 @@ func AddIP(ctx *gin.Context, appsession *models.AppSession) {
}

// Add the IP to the database
err := database.AddIP(ctx, appsession, request)
ipInfo, err := database.AddIP(ctx, appsession, request)
if err != nil {
configs.CaptureError(ctx, err)
ctx.JSON(http.StatusInternalServerError, utils.ErrorResponse(
Expand All @@ -1443,6 +1443,39 @@ func AddIP(ctx *gin.Context, appsession *models.AppSession) {
return
}

// get logged users email from ctx
email, errv := AttemptToGetEmail(ctx, appsession)
if errv != nil {
configs.CaptureError(ctx, errv)
logrus.Error("Failed to get logged users email because: ", errv)
// we are more focused on theadding of the ip address so we will not return an error
ctx.JSON(http.StatusOK, utils.SuccessResponse(http.StatusOK, "Successfully toggled admin status!", nil))
return
}

if err := CreateAndSendNotificationLogic(
ctx,
appsession,
email,
request.Emails,
"IP address added",
fmt.Sprintf("%s has added %s to the list of allowed IP addresses for you. Check your email for more details.", email, request.IP),
fmt.Sprintf("You have successfully added %s to the list of allowed IP addresses for %s.", request.IP, utils.ConvertArrayToCommaDelimitedString(request.Emails)),
); err != nil {
configs.CaptureError(ctx, err)
logrus.Error("Failed to send notification because: ", err)
ctx.JSON(http.StatusInternalServerError, utils.InternalServerError())
return
}

subject := "IP address added"
body := utils.FormatIPAddressAddedEmailBody(ipInfo, email)

if err := mail.SendBulkEmailWithBCC(request.Emails, subject, body, appsession); err != nil {
ctx.JSON(http.StatusInternalServerError, utils.InternalServerError())
return
}

ctx.JSON(http.StatusOK, utils.SuccessResponse(http.StatusOK, "Successfully added IP!", nil))
}

Expand All @@ -1467,7 +1500,7 @@ func RemoveIP(ctx *gin.Context, appsession *models.AppSession) {
}

// Remove the IP from the database
err := database.RemoveIP(ctx, appsession, request)
ipInfo, err := database.RemoveIP(ctx, appsession, request)
if err != nil {
configs.CaptureError(ctx, err)
ctx.JSON(http.StatusInternalServerError, utils.ErrorResponse(
Expand All @@ -1479,6 +1512,39 @@ func RemoveIP(ctx *gin.Context, appsession *models.AppSession) {
return
}

// get logged users email from ctx
email, errv := AttemptToGetEmail(ctx, appsession)
if errv != nil {
configs.CaptureError(ctx, errv)
logrus.Error("Failed to get logged users email because: ", errv)
// we are more focused on the removing the ip address so we will not return an error
ctx.JSON(http.StatusOK, utils.SuccessResponse(http.StatusOK, "Successfully toggled admin status!", nil))
return
}

if err := CreateAndSendNotificationLogic(
ctx,
appsession,
email,
request.Emails,
"IP address removed",
fmt.Sprintf("%s has removed %s from the list of allowed IP addresses for you. Check your email for more details.", email, request.IP),
fmt.Sprintf("You have successfully removed %s from the list of allowed IP addresses for %s.", request.IP, utils.ConvertArrayToCommaDelimitedString(request.Emails)),
); err != nil {
configs.CaptureError(ctx, err)
logrus.Error("Failed to send notification because: ", err)
ctx.JSON(http.StatusInternalServerError, utils.InternalServerError())
return
}

subject := "IP address removed"
body := utils.FormatIPAddressRemovedEmailBody(ipInfo, email)

if err := mail.SendBulkEmailWithBCC(request.Emails, subject, body, appsession); err != nil {
ctx.JSON(http.StatusInternalServerError, utils.InternalServerError())
return
}

ctx.JSON(http.StatusOK, utils.SuccessResponse(http.StatusOK, "Successfully removed IP!", nil))
}

Expand All @@ -1503,15 +1569,48 @@ func ToggleAllowAnonymousIP(ctx *gin.Context, appsession *models.AppSession) {
}

// Toggle the allow anonymous IP status
err := database.ToggleAllowAnonymousIP(ctx, appsession, request)

if err != nil {
if err := database.ToggleAllowAnonymousIP(ctx, appsession, request); err != nil {
configs.CaptureError(ctx, err)
logrus.Error("Failed to toggle allow anonymous IP because: ", err)
ctx.JSON(http.StatusInternalServerError, utils.InternalServerError())
return
}

// get logged users email from ctx
email, errv := AttemptToGetEmail(ctx, appsession)
if errv != nil {
configs.CaptureError(ctx, errv)
logrus.Error("Failed to get logged users email because: ", errv)
// we are more focused on the removing the ip address so we will not return an error
ctx.JSON(http.StatusOK, utils.SuccessResponse(http.StatusOK, "Successfully toggled admin status!", nil))
return
}

var receiverAllow string
var senderAllow string
if request.BlockAnonymousIPAddress {
receiverAllow = fmt.Sprintf(("%s has allowed anonymous IP addresses for you."), email)
senderAllow = fmt.Sprintf("You have successfully allowed anonymous IP addresses for %s.", utils.ConvertArrayToCommaDelimitedString(request.Emails))
} else {
receiverAllow = fmt.Sprintf(("%s has disallowed anonymous IP addresses for you."), email)
senderAllow = fmt.Sprintf("You have successfully disallowed anonymous IP addresses for %s.", utils.ConvertArrayToCommaDelimitedString(request.Emails))
}

if err := CreateAndSendNotificationLogic(
ctx,
appsession,
email,
request.Emails,
"Allow anonymous IP address toggled",
receiverAllow,
senderAllow,
); err != nil {
configs.CaptureError(ctx, err)
logrus.Error("Failed to send notification because: ", err)
ctx.JSON(http.StatusInternalServerError, utils.InternalServerError())
return
}

ctx.JSON(http.StatusOK, utils.SuccessResponse(http.StatusOK, "Successfully toggled allow anonymous IP status!", nil))
}

Expand Down Expand Up @@ -1632,13 +1731,6 @@ func ToggleAdminStatus(ctx *gin.Context, appsession *models.AppSession) {
return
}

// ensure email exists
if !database.EmailExists(ctx, appsession, request.Email) {
configs.CaptureError(ctx, errors.New("email does not exist"))
ctx.JSON(http.StatusBadRequest, utils.ErrorResponse(http.StatusBadRequest, "Invalid request payload", constants.InvalidRequestPayloadCode, "Email does not exist", nil))
return
}

// Toggle the admin status
err := database.ToggleAdminStatus(ctx, appsession, request)
if err != nil {
Expand All @@ -1648,5 +1740,82 @@ func ToggleAdminStatus(ctx *gin.Context, appsession *models.AppSession) {
return
}

ctx.JSON(http.StatusOK, utils.SuccessResponse(http.StatusOK, "Successfully toggled admin status!", nil))
email, err := AttemptToGetEmail(ctx, appsession)
if err != nil {
configs.CaptureError(ctx, err)
ctx.JSON(http.StatusBadRequest, utils.ErrorResponse(
http.StatusBadRequest,
"Invalid request payload",
constants.InvalidRequestPayloadCode,
"Email must be provided",
nil))
return
}

if err := CreateAndSendNotificationLogic(
ctx,
appsession,
email,
[]string{request.Email},
"Role status changed",
fmt.Sprintf("%s has changed your role status to %s", email, request.Role),
fmt.Sprintf("You have changed %s's role status to %s", request.Email, request.Role),
); err != nil {
configs.CaptureError(ctx, err)
logrus.Error("Failed to send notification because: ", err)
ctx.JSON(http.StatusInternalServerError, utils.InternalServerError())
return
}

ctx.JSON(http.StatusOK, utils.SuccessResponse(http.StatusOK, "Successfully toggled admin status and sent notifications!", nil))
}

func SendDownloadReportNotification(ctx *gin.Context, appsession *models.AppSession) {
var request models.RequestEmail
if err := ctx.ShouldBindJSON(&request); err != nil {
configs.CaptureError(ctx, err)
ctx.JSON(http.StatusBadRequest, utils.ErrorResponse(
http.StatusBadRequest,
"Invalid request payload",
constants.InvalidRequestPayloadCode,
"Invalid JSON payload",
nil))
return
}

// valdidate the email
if !utils.ValidateEmail(request.Email) {
configs.CaptureError(ctx, errors.New("invalid email address"))
ctx.JSON(http.StatusBadRequest, utils.ErrorResponse(http.StatusBadRequest, "Invalid request payload", constants.InvalidRequestPayloadCode, "Invalid email address", nil))
return
}

email, err := AttemptToGetEmail(ctx, appsession)
if err != nil {
configs.CaptureError(ctx, err)
ctx.JSON(http.StatusBadRequest, utils.ErrorResponse(
http.StatusBadRequest,
"Invalid request payload",
constants.InvalidRequestPayloadCode,
"Email must be provided",
nil))
return
}

if err := CreateAndSendNotificationLogic(
ctx,
appsession,
email,
[]string{request.Email},
"Report Downloaded",
fmt.Sprintf("%s has downloaded your report", email),
fmt.Sprintf("You have downloaded %s's report", request.Email),
); err != nil {
configs.CaptureError(ctx, err)
logrus.Error("Failed to send notification because: ", err)
ctx.JSON(http.StatusInternalServerError, utils.InternalServerError())
return
}

ctx.JSON(http.StatusOK, utils.SuccessResponse(http.StatusOK, "Successfully sent notification!", nil))
}
70 changes: 70 additions & 0 deletions occupi-backend/pkg/handlers/api_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ import (
"os"
"path/filepath"
"strings"
"time"

"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
"github.com/COS301-SE-2024/occupi/occupi-backend/configs"
"github.com/COS301-SE-2024/occupi/occupi-backend/pkg/constants"
"github.com/COS301-SE-2024/occupi/occupi-backend/pkg/database"
"github.com/COS301-SE-2024/occupi/occupi-backend/pkg/models"
"github.com/COS301-SE-2024/occupi/occupi-backend/pkg/receiver"
"github.com/COS301-SE-2024/occupi/occupi-backend/pkg/utils"
"github.com/ccoveille/go-safecast"
"github.com/gin-gonic/gin"
Expand Down Expand Up @@ -249,3 +252,70 @@ func DefaultFemalePFP(race ...string) string {
func DefaultNBPFP() string {
return "default_nb1.jpg"
}

func CreateAndSendNotificationLogic(ctx *gin.Context, appsession *models.AppSession, senderEmail string, receiverEmails []string,
title string, messageReciever string, messageSender string) error {
// get the users expo push token
tokens, err := database.GetUsersPushTokens(ctx, appsession, receiverEmails)
if err != nil {
configs.CaptureError(ctx, err)
logrus.Error("Failed to get users push tokens because: ", err)
ctx.JSON(http.StatusInternalServerError, utils.InternalServerError())
return err
}

tokenArr, err := utils.ConvertTokensToStringArray(tokens, "expoPushToken")
if err != nil {
configs.CaptureError(ctx, err)
logrus.Error("Failed to convert tokens to string array because: ", err)
ctx.JSON(http.StatusInternalServerError, utils.InternalServerError())
return err
}

notificationReciever := models.ScheduledNotification{
NotiID: utils.GenerateUUID(),
Title: title,
Message: messageReciever,
Sent: false,
SendTime: time.Now(),
Emails: receiverEmails,
UnsentExpoPushTokens: tokenArr,
UnreadEmails: receiverEmails,
}

notificationSender := models.ScheduledNotification{
NotiID: utils.GenerateUUID(),
Title: title,
Message: messageSender,
Sent: true,
SendTime: time.Now(),
Emails: []string{senderEmail},
UnsentExpoPushTokens: []string{},
UnreadEmails: []string{senderEmail},
}

// Save the notifications to the database
if saved, err := database.AddNotification(ctx, appsession, notificationReciever, false); err != nil || !saved {
configs.CaptureError(ctx, err)
logrus.Error("Failed to save notification to the database because: ", err)
ctx.JSON(http.StatusInternalServerError, utils.InternalServerError())
return err
}

if saved, err := database.AddNotification(ctx, appsession, notificationSender, true); err != nil || !saved {
configs.CaptureError(ctx, err)
logrus.Error("Failed to save notification to the database because: ", err)
ctx.JSON(http.StatusInternalServerError, utils.InternalServerError())
return err
}

// send the notification
if err := receiver.SendPushNotification(notificationReciever, appsession); err != nil {
configs.CaptureError(ctx, err)
logrus.Error("Failed to send notification because: ", err)
ctx.JSON(http.StatusInternalServerError, utils.InternalServerError())
return err
}

return nil
}
Loading

0 comments on commit 2d32b26

Please sign in to comment.