diff --git a/app/src/App.tsx b/app/src/App.tsx index eaa91bc..bdf35b4 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -45,7 +45,7 @@ function App() { } /> } /> } /> - } /> + } /> ); diff --git a/app/src/pages/admin/AEPostView.tsx b/app/src/pages/admin/AEPostView.tsx index 24d39c0..98f319c 100644 --- a/app/src/pages/admin/AEPostView.tsx +++ b/app/src/pages/admin/AEPostView.tsx @@ -71,7 +71,7 @@ function PostTile({ label, icon, role, posts }: PostTileProps) { {posts.map((post) => (
  • {/* ID chip */} diff --git a/app/src/pages/admin/AdminPostView.tsx b/app/src/pages/admin/AdminPostView.tsx index 459a116..44aeace 100644 --- a/app/src/pages/admin/AdminPostView.tsx +++ b/app/src/pages/admin/AdminPostView.tsx @@ -214,7 +214,9 @@ function MetaRow({ icon, label, value }: { icon: React.ReactNode; label: string; // ── Page ─────────────────────────────────────────────────────────────────────── export function AdminPostView() { - const { adminType, role, post_id } = useParams<{ adminType: string; role: string; post_id: string }>(); + const { role, post_id } = useParams<{ role: string; post_id: string }>(); + const adminPosition = sessionStorage.getItem('adminPosition') ?? ''; + const adminType = adminPosition.startsWith('XEN') ? 'xen' : adminPosition.startsWith('AE') ? 'ae' : adminPosition.startsWith('JE') ? 'je' : ''; const navigate = useNavigate(); const [post, setPost] = useState(null); diff --git a/app/src/pages/admin/JEPostView.tsx b/app/src/pages/admin/JEPostView.tsx index 61c8f51..31bf217 100644 --- a/app/src/pages/admin/JEPostView.tsx +++ b/app/src/pages/admin/JEPostView.tsx @@ -71,7 +71,7 @@ function PostTile({ label, icon, role, posts }: PostTileProps) { {posts.map((post) => (
  • {/* ID chip */} diff --git a/app/src/pages/admin/XENPostView.tsx b/app/src/pages/admin/XENPostView.tsx index 52af183..961f7b5 100644 --- a/app/src/pages/admin/XENPostView.tsx +++ b/app/src/pages/admin/XENPostView.tsx @@ -76,7 +76,7 @@ function PostTile({ label, icon, role, posts }: PostTileProps) { {posts.map((post) => (
  • {/* ID chip */} diff --git a/app/src/pages/auth/StaffLogin.tsx b/app/src/pages/auth/StaffLogin.tsx index 8ec75f5..73ed41a 100644 --- a/app/src/pages/auth/StaffLogin.tsx +++ b/app/src/pages/auth/StaffLogin.tsx @@ -43,6 +43,7 @@ export function StaffLogin() { setStatus('error'); setMessage(`Unknown position "${data.position}" — contact admin.`); } else { + sessionStorage.setItem('adminPosition', data.position ?? ''); navigate(dest); } } else { diff --git a/handlers/admin_auth.go b/handlers/admin_auth.go index 9a2af8b..2f47b2c 100644 --- a/handlers/admin_auth.go +++ b/handlers/admin_auth.go @@ -55,10 +55,10 @@ func (h *AdminHandler) AdminLogin (c *gin.Context) { return } - // if admin.IsVerified == false { - // c.JSON(401, gin.H{"error": "unverified user"}) - // return - // } + if admin.IsVerified == false { + c.JSON(401, gin.H{"error": "unverified user"}) + return + } err := bcrypt.CompareHashAndPassword([]byte(admin.Password), []byte(inputs.Password)) if err != nil { diff --git a/handlers/admin_post.go b/handlers/admin_post.go index a6cd72f..0a143a9 100644 --- a/handlers/admin_post.go +++ b/handlers/admin_post.go @@ -233,8 +233,10 @@ func (h* AdminHandler) GetJEPosts (c *gin.Context) { }) } -// for now we treat 404 and 500 during fetching post the same -func (h *AdminHandler) AdminGetPost (c *gin.Context) { + +// AdminGetPost fetches the whole post page for any admin +// (for now we treat 404 and 500 during fetching post the same) +func (h *AdminHandler) AdminGetPost(c *gin.Context) { // get email from gin context email, exists := c.Get(middleware.EmailKey) diff --git a/handlers/admin_status.go b/handlers/admin_status.go index 1f3538e..b60b4cc 100644 --- a/handlers/admin_status.go +++ b/handlers/admin_status.go @@ -1,12 +1,15 @@ package handlers import ( + "fmt" "errors" + "log" "strconv" "strings" "github.com/ayush00git/cms-web/middleware" "github.com/ayush00git/cms-web/models" + "github.com/ayush00git/cms-web/services" "github.com/gin-gonic/gin" "gorm.io/gorm" ) @@ -16,7 +19,8 @@ type AdminReview struct { } // AdminFacultyPostStatus sets the stage of the faculty posts -func (h *AdminHandler) AdminFacultyPostStatus (c *gin.Context) { +// Sends email to the corresponding post using goroutines +func (h *AdminHandler) AdminFacultyPostStatus(c *gin.Context) { adminEmail, exists := c.Get(middleware.EmailKey) if !exists { c.JSON(401, gin.H{"error": "permission denied"}) @@ -65,8 +69,18 @@ func (h *AdminHandler) AdminFacultyPostStatus (c *gin.Context) { return } + // create the postURL + postURL := fmt.Sprintf(`http://localhost:5173/admin/posts/%s/%d`, "faculty", post.ID) switch post.Status { + case "Resolved_JE": + if !strings.Contains(string(admin.Position), "XEN") { + c.JSON(403, gin.H{"error": "permissions denied"}) + return + } + if review.Review == "close" { + post.Status = "Closed" + } case "Pending_XEN" : if !strings.Contains(string(admin.Position), "XEN") { c.JSON(403, gin.H{"error": "permissions denied"}) @@ -74,8 +88,26 @@ func (h *AdminHandler) AdminFacultyPostStatus (c *gin.Context) { } if review.Review == "to_ae" { post.Status = "Pending_AE" - } else if review.Review == "open" { - post.Status = "Pending_XEN" + // send mail to ae + go func() { + // search for email of ae + var position models.PositionType + if post.TypeOfPost == "Civil" { + position = models.TypeAECivil + } else { + position = models.TypeAEElectrical + } + var ae models.Admin + result := h.DB.Where("position = ?", position).Take(&ae) + if result.Error != nil { + log.Printf("failed to send AE mail for post %d", post.ID) + return + } + if err := services.SendPostMailToAdmins(ae.Email, postURL); err != nil { + log.Printf("failed to send AE mail for post %d: %s", post.ID, err) + return + } + } () } else if review.Review == "close" { post.Status = "Closed" } else { @@ -90,8 +122,48 @@ func (h *AdminHandler) AdminFacultyPostStatus (c *gin.Context) { } if review.Review == "to_je" { post.Status = "Pending_JE" + // send mail to je + go func() { + // search for email of je + var position models.PositionType + if post.TypeOfPost == "Civil" { + position = models.TypeJECivil + } else { + position = models.TypeJEElectrical + } + var je models.Admin + result := h.DB.Where("position = ?", position).Take(&je) + if result.Error != nil { + log.Printf("failed to send AE mail for post %d", post.ID) + return + } + if err := services.SendPostMailToAdmins(je.Email, postURL); err != nil { + log.Printf("failed to send AE mail for post %d: %s", post.ID, err) + return + } + } () } else if review.Review == "require_review" { post.Status = "Pending_XEN" + // send mail to xen + go func() { + // search for email of xen + var position models.PositionType + if post.TypeOfPost == "Civil" { + position = models.TypeXENCivil + } else { + position = models.TypeXENElectrical + } + var xen models.Admin + result := h.DB.Where("position = ?", position).Take(&xen) + if result.Error != nil { + log.Printf("failed to send AE mail for post %d", post.ID) + return + } + if err := services.SendPostMailToAdmins(xen.Email, postURL); err != nil { + log.Printf("failed to send AE mail for post %d: %s", post.ID, err) + return + } + } () } else { c.JSON(400, gin.H{"error": "invalid review type"}) return @@ -104,8 +176,48 @@ func (h *AdminHandler) AdminFacultyPostStatus (c *gin.Context) { } if review.Review == "resolved" { post.Status = "Resolved_JE" + // send mail to xen + go func() { + // search for email of xen + var position models.PositionType + if post.TypeOfPost == "Civil" { + position = models.TypeXENCivil + } else { + position = models.TypeXENElectrical + } + var xen models.Admin + result := h.DB.Where("position = ?", position).Take(&xen) + if result.Error != nil { + log.Printf("failed to send AE mail for post %d", post.ID) + return + } + if err := services.SendPostMailToAdmins(xen.Email, postURL); err != nil { + log.Printf("failed to send AE mail for post %d: %s", post.ID, err) + return + } + } () } else if review.Review == "require_review" { post.Status = "Pending_AE" + // send mail to ae + go func() { + // search for email of ae + var position models.PositionType + if post.TypeOfPost == "Civil" { + position = models.TypeAECivil + } else { + position = models.TypeAEElectrical + } + var ae models.Admin + result := h.DB.Where("position = ?", position).Take(&ae) + if result.Error != nil { + log.Printf("failed to send AE mail for post %d", post.ID) + return + } + if err := services.SendPostMailToAdmins(ae.Email, postURL); err != nil { + log.Printf("failed to send AE mail for post %d: %s", post.ID, err) + return + } + } () } else { c.JSON(400, gin.H{"error": "invalid review type"}) return @@ -134,8 +246,10 @@ func (h *AdminHandler) AdminFacultyPostStatus (c *gin.Context) { c.JSON(200, gin.H{"success": "status updated"}) } + // AdminWardenPostStatus sets the stage of the warden posts -func (h *AdminHandler) AdminWardenPostStatus (c *gin.Context) { +// Sends email to the corresponding post using goroutines +func (h *AdminHandler) AdminWardenPostStatus(c *gin.Context) { adminEmail, exists := c.Get(middleware.EmailKey) if !exists { c.JSON(401, gin.H{"error": "permission denied"}) @@ -181,8 +295,18 @@ func (h *AdminHandler) AdminWardenPostStatus (c *gin.Context) { return } + // create the postURL + postURL := fmt.Sprintf(`http://localhost:5173/admin/posts/%s/%d`, "warden", post.ID) switch post.Status { + case "Resolved_JE": + if !strings.Contains(string(admin.Position), "XEN") { + c.JSON(403, gin.H{"error": "permissions denied"}) + return + } + if review.Review == "close" { + post.Status = "Closed" + } case "Pending_XEN" : if !strings.Contains(string(admin.Position), "XEN") { c.JSON(403, gin.H{"error": "permissions denied"}) @@ -190,8 +314,26 @@ func (h *AdminHandler) AdminWardenPostStatus (c *gin.Context) { } if review.Review == "to_ae" { post.Status = "Pending_AE" - } else if review.Review == "open" { - post.Status = "Pending_XEN" + // send mail to ae + go func() { + // search for email of ae + var position models.PositionType + if post.TypeOfPost == "Civil" { + position = models.TypeAECivil + } else { + position = models.TypeAEElectrical + } + var ae models.Admin + result := h.DB.Where("position = ?", position).Take(&ae) + if result.Error != nil { + log.Printf("failed to send AE mail for post %d", post.ID) + return + } + if err := services.SendPostMailToAdmins(ae.Email, postURL); err != nil { + log.Printf("failed to send AE mail for post %d: %s", post.ID, err) + return + } + } () } else if review.Review == "close" { post.Status = "Closed" } else { @@ -206,8 +348,48 @@ func (h *AdminHandler) AdminWardenPostStatus (c *gin.Context) { } if review.Review == "to_je" { post.Status = "Pending_JE" + // send mail to je + go func() { + // search for email of je + var position models.PositionType + if post.TypeOfPost == "Civil" { + position = models.TypeJECivil + } else { + position = models.TypeJEElectrical + } + var je models.Admin + result := h.DB.Where("position = ?", position).Take(&je) + if result.Error != nil { + log.Printf("failed to send AE mail for post %d", post.ID) + return + } + if err := services.SendPostMailToAdmins(je.Email, postURL); err != nil { + log.Printf("failed to send AE mail for post %d: %s", post.ID, err) + return + } + } () } else if review.Review == "require_review" { post.Status = "Pending_XEN" + // send mail to xen + go func() { + // search for email of xen + var position models.PositionType + if post.TypeOfPost == "Civil" { + position = models.TypeXENCivil + } else { + position = models.TypeXENElectrical + } + var xen models.Admin + result := h.DB.Where("position = ?", position).Take(&xen) + if result.Error != nil { + log.Printf("failed to send AE mail for post %d", post.ID) + return + } + if err := services.SendPostMailToAdmins(xen.Email, postURL); err != nil { + log.Printf("failed to send AE mail for post %d: %s", post.ID, err) + return + } + } () } else { c.JSON(400, gin.H{"error": "invalid review type"}) return @@ -220,8 +402,48 @@ func (h *AdminHandler) AdminWardenPostStatus (c *gin.Context) { } if review.Review == "resolved" { post.Status = "Resolved_JE" + // send mail to xen + go func() { + // search for email of xen + var position models.PositionType + if post.TypeOfPost == "Civil" { + position = models.TypeXENCivil + } else { + position = models.TypeXENElectrical + } + var xen models.Admin + result := h.DB.Where("position = ?", position).Take(&xen) + if result.Error != nil { + log.Printf("failed to send AE mail for post %d", post.ID) + return + } + if err := services.SendPostMailToAdmins(xen.Email, postURL); err != nil { + log.Printf("failed to send AE mail for post %d: %s", post.ID, err) + return + } + } () } else if review.Review == "require_review" { post.Status = "Pending_AE" + // send mail to ae + go func() { + // search for email of ae + var position models.PositionType + if post.TypeOfPost == "Civil" { + position = models.TypeAECivil + } else { + position = models.TypeAEElectrical + } + var ae models.Admin + result := h.DB.Where("position = ?", position).Take(&ae) + if result.Error != nil { + log.Printf("failed to send AE mail for post %d", post.ID) + return + } + if err := services.SendPostMailToAdmins(ae.Email, postURL); err != nil { + log.Printf("failed to send AE mail for post %d: %s", post.ID, err) + return + } + } () } else { c.JSON(400, gin.H{"error": "invalid review type"}) return @@ -250,7 +472,9 @@ func (h *AdminHandler) AdminWardenPostStatus (c *gin.Context) { c.JSON(200, gin.H{"success": "status updated"}) } + // AdminCentreheadPostStatus sets the stage of the centrehead posts +// Sends email to the corresponding post using goroutines func (h *AdminHandler) AdminCentreheadPostStatus(c *gin.Context) { adminEmail, exists := c.Get(middleware.EmailKey) if !exists { @@ -297,8 +521,18 @@ func (h *AdminHandler) AdminCentreheadPostStatus(c *gin.Context) { return } + // create the postURL + postURL := fmt.Sprintf(`http://localhost:5173/admin/posts/%s/%d`, "centrehead", post.ID) switch post.Status { + case "Resolved_JE": + if !strings.Contains(string(admin.Position), "XEN") { + c.JSON(403, gin.H{"error": "permissions denied"}) + return + } + if review.Review == "close" { + post.Status = "Closed" + } case "Pending_XEN" : if !strings.Contains(string(admin.Position), "XEN") { c.JSON(403, gin.H{"error": "permissions denied"}) @@ -306,8 +540,26 @@ func (h *AdminHandler) AdminCentreheadPostStatus(c *gin.Context) { } if review.Review == "to_ae" { post.Status = "Pending_AE" - } else if review.Review == "open" { - post.Status = "Pending_XEN" + // send mail to ae + go func() { + // search for email of ae + var position models.PositionType + if post.TypeOfPost == "Civil" { + position = models.TypeAECivil + } else { + position = models.TypeAEElectrical + } + var ae models.Admin + result := h.DB.Where("position = ?", position).Take(&ae) + if result.Error != nil { + log.Printf("failed to send AE mail for post %d", post.ID) + return + } + if err := services.SendPostMailToAdmins(ae.Email, postURL); err != nil { + log.Printf("failed to send AE mail for post %d: %s", post.ID, err) + return + } + } () } else if review.Review == "close" { post.Status = "Closed" } else { @@ -322,8 +574,48 @@ func (h *AdminHandler) AdminCentreheadPostStatus(c *gin.Context) { } if review.Review == "to_je" { post.Status = "Pending_JE" + // send mail to je + go func() { + // search for email of je + var position models.PositionType + if post.TypeOfPost == "Civil" { + position = models.TypeJECivil + } else { + position = models.TypeJEElectrical + } + var je models.Admin + result := h.DB.Where("position = ?", position).Take(&je) + if result.Error != nil { + log.Printf("failed to send AE mail for post %d", post.ID) + return + } + if err := services.SendPostMailToAdmins(je.Email, postURL); err != nil { + log.Printf("failed to send AE mail for post %d: %s", post.ID, err) + return + } + } () } else if review.Review == "require_review" { post.Status = "Pending_XEN" + // send mail to xen + go func() { + // search for email of xen + var position models.PositionType + if post.TypeOfPost == "Civil" { + position = models.TypeXENCivil + } else { + position = models.TypeXENElectrical + } + var xen models.Admin + result := h.DB.Where("position = ?", position).Take(&xen) + if result.Error != nil { + log.Printf("failed to send AE mail for post %d", post.ID) + return + } + if err := services.SendPostMailToAdmins(xen.Email, postURL); err != nil { + log.Printf("failed to send AE mail for post %d: %s", post.ID, err) + return + } + } () } else { c.JSON(400, gin.H{"error": "invalid review type"}) return @@ -336,8 +628,48 @@ func (h *AdminHandler) AdminCentreheadPostStatus(c *gin.Context) { } if review.Review == "resolved" { post.Status = "Resolved_JE" + // send mail to xen + go func() { + // search for email of xen + var position models.PositionType + if post.TypeOfPost == "Civil" { + position = models.TypeXENCivil + } else { + position = models.TypeXENElectrical + } + var xen models.Admin + result := h.DB.Where("position = ?", position).Take(&xen) + if result.Error != nil { + log.Printf("failed to send AE mail for post %d", post.ID) + return + } + if err := services.SendPostMailToAdmins(xen.Email, postURL); err != nil { + log.Printf("failed to send AE mail for post %d: %s", post.ID, err) + return + } + } () } else if review.Review == "require_review" { post.Status = "Pending_AE" + // send mail to ae + go func() { + // search for email of ae + var position models.PositionType + if post.TypeOfPost == "Civil" { + position = models.TypeAECivil + } else { + position = models.TypeAEElectrical + } + var ae models.Admin + result := h.DB.Where("position = ?", position).Take(&ae) + if result.Error != nil { + log.Printf("failed to send AE mail for post %d", post.ID) + return + } + if err := services.SendPostMailToAdmins(ae.Email, postURL); err != nil { + log.Printf("failed to send AE mail for post %d: %s", post.ID, err) + return + } + } () } else { c.JSON(400, gin.H{"error": "invalid review type"}) return diff --git a/handlers/centrehead_post.go b/handlers/centrehead_post.go index d8a66b3..9e31e12 100644 --- a/handlers/centrehead_post.go +++ b/handlers/centrehead_post.go @@ -1,11 +1,14 @@ package handlers import ( + "fmt" + "log" "time" "errors" "github.com/ayush00git/cms-web/middleware" "github.com/ayush00git/cms-web/models" + "github.com/ayush00git/cms-web/services" "github.com/gin-gonic/gin" "gorm.io/gorm" @@ -27,7 +30,7 @@ type CentreheadPostType struct { // CentreheadPost registers the post of centre-head members. // forwards the post to the associated XEN. -func (h *PostHandler) CentreheadPost (c *gin.Context) { +func (h *PostHandler) CentreheadPost(c *gin.Context) { var inputs CentreheadPostType if err := c.ShouldBindJSON(&inputs); err != nil { @@ -70,13 +73,36 @@ func (h *PostHandler) CentreheadPost (c *gin.Context) { return } + // send the mail to the corresponding xen + // } /> + postURL := fmt.Sprintf(`http://localhost:5173/admin/posts/%s/%d`, head.Role, post.ID) + go func() { + var position models.PositionType + if post.TypeOfPost == "Civil" { + position = models.TypeXENCivil + } else { + position = models.TypeXENElectrical + } + // through type of post send the mail to the corresponding civil/electrical XEN + var xen models.Admin + result := h.DB.Where("position = ?", position).Take(&xen) + if result.Error != nil { + log.Printf("failed to send XEN mail for post %d", post.ID) + return + } + // send mail to that user + if err := services.SendPostMailToAdmins(xen.Email, postURL); err != nil { + log.Printf("failed to send XEN mail for post %d: %v", post.ID, err) + } + }() + c.JSON(201, gin.H{"success": "post submitted successfully", "post": post}) } // CentreheadPostEdit let's the author of the post edit it. // Match is the author trying to edit. -func (h *PostHandler) CentreheadPostEdit (c *gin.Context) { +func (h *PostHandler) CentreheadPostEdit(c *gin.Context) { // get the id of the user from gin context userID, exists := c.Get(middleware.UserIDKey) if !exists { @@ -121,7 +147,7 @@ func (h *PostHandler) CentreheadPostEdit (c *gin.Context) { // CentreheadPostDelete lets the author delete his post. // Matches is the author trying to delete. -func (h *PostHandler) CentreheadPostDelete (c *gin.Context) { +func (h *PostHandler) CentreheadPostDelete(c *gin.Context) { // get userID from gin context userID, exists := c.Get(middleware.UserIDKey); if !exists { @@ -157,7 +183,7 @@ func (h *PostHandler) CentreheadPostDelete (c *gin.Context) { // GetCentreheadPosts fetch the posts of the centre head member along with their status and comments -func (h *PostHandler) GetCentreheadPosts (c *gin.Context) { +func (h *PostHandler) GetCentreheadPosts(c *gin.Context) { email, exists := c.Get(middleware.EmailKey) if !exists { c.JSON(401, gin.H{"error": "unauthenticated user"}) diff --git a/handlers/faculty_post.go b/handlers/faculty_post.go index d5b2886..8883a1d 100644 --- a/handlers/faculty_post.go +++ b/handlers/faculty_post.go @@ -1,11 +1,14 @@ package handlers import ( - "time" "errors" + "fmt" + "log" + "time" "github.com/ayush00git/cms-web/middleware" "github.com/ayush00git/cms-web/models" + "github.com/ayush00git/cms-web/services" "github.com/gin-gonic/gin" "gorm.io/gorm" @@ -33,7 +36,7 @@ type FacultyPostType struct { // FacultyPost registers the post of faculty members. // forwards the post to the associated XEN. -func (h *PostHandler) FacultyPost (c *gin.Context) { +func (h *PostHandler) FacultyPost(c *gin.Context) { var inputs FacultyPostType if err := c.ShouldBindJSON(&inputs); err != nil { @@ -76,14 +79,37 @@ func (h *PostHandler) FacultyPost (c *gin.Context) { c.JSON(500, gin.H{"error": "failed inserting to table"}) return } - + + // send the mail to the corresponding xen + // } /> + postURL := fmt.Sprintf(`http://localhost:5173/admin/posts/%s/%d`, faculty.Role, post.ID) + go func() { + var position models.PositionType + if post.TypeOfPost == "Civil" { + position = models.TypeXENCivil + } else { + position = models.TypeXENElectrical + } + // through type of post send the mail to the corresponding civil/electrical XEN + var xen models.Admin + result := h.DB.Where("position = ?", position).Take(&xen) + if result.Error != nil { + log.Printf("failed to send XEN mail for post %d", post.ID) + return + } + // send mail to that user + if err := services.SendPostMailToAdmins(xen.Email, postURL); err != nil { + log.Printf("failed to send XEN mail for post %d: %v", post.ID, err) + } + }() + c.JSON(201, gin.H{"success": "post submitted successfully", "post": post}) } // FacultyPostEdit let's the author of the post edit it. // Match is the author trying to edit. -func (h *PostHandler) FacultyPostEdit (c *gin.Context) { +func (h *PostHandler) FacultyPostEdit(c *gin.Context) { // who is trying to edit the post userID, exists := c.Get(middleware.UserIDKey) if !exists { @@ -128,7 +154,7 @@ func (h *PostHandler) FacultyPostEdit (c *gin.Context) { // FacultyPostDelete lets the author delete his post. // Matches is the author trying to delete. -func (h *PostHandler) FacultyPostDelete (c *gin.Context) { +func (h *PostHandler) FacultyPostDelete(c *gin.Context) { // get userID from gin context userID, exists := c.Get(middleware.UserIDKey); if !exists { @@ -165,7 +191,7 @@ func (h *PostHandler) FacultyPostDelete (c *gin.Context) { // GetFacultyPosts fetch the posts of the faculty member along with their status and comments // This API returns all the posts collectively -func (h *PostHandler) GetFacultyPosts (c *gin.Context) { +func (h *PostHandler) GetFacultyPosts(c *gin.Context) { // get email of the logged in user email, exists := c.Get(middleware.EmailKey) if !exists { diff --git a/handlers/warden_post.go b/handlers/warden_post.go index 57e1db6..f7289a4 100644 --- a/handlers/warden_post.go +++ b/handlers/warden_post.go @@ -1,11 +1,14 @@ package handlers import ( + "fmt" + "log" "time" "errors" "github.com/ayush00git/cms-web/middleware" "github.com/ayush00git/cms-web/models" + "github.com/ayush00git/cms-web/services" "github.com/gin-gonic/gin" "gorm.io/gorm" @@ -30,7 +33,7 @@ type WardenPostType struct { // WardenPost registers the post of warden members. // forwards the post to the associated XEN. -func (h *PostHandler) WardenPost (c *gin.Context) { +func (h *PostHandler) WardenPost(c *gin.Context) { var inputs WardenPostType if err := c.ShouldBindJSON(&inputs); err != nil { @@ -74,13 +77,36 @@ func (h *PostHandler) WardenPost (c *gin.Context) { return } + // send the mail to the corresponding xen + // } /> + postURL := fmt.Sprintf(`http://localhost:5173/admin/posts/%s/%d`, warden.Role, post.ID) + go func() { + var position models.PositionType + if post.TypeOfPost == "Civil" { + position = models.TypeXENCivil + } else { + position = models.TypeXENElectrical + } + // through type of post send the mail to the corresponding civil/electrical XEN + var xen models.Admin + result := h.DB.Where("position = ?", position).Take(&xen) + if result.Error != nil { + log.Printf("failed to send XEN mail for post %d", post.ID) + return + } + // send mail to that user + if err := services.SendPostMailToAdmins(xen.Email, postURL); err != nil { + log.Printf("failed to send XEN mail for post %d: %v", post.ID, err) + } + }() + c.JSON(201, gin.H{"success": "post submitted successfully", "post": post}) } // WardenPostEdit let's the author of the post edit it. // Match is the author trying to edit. -func (h *PostHandler) WardenPostEdit (c *gin.Context) { +func (h *PostHandler) WardenPostEdit(c *gin.Context) { // get the id of the user from gin context userID, exists := c.Get(middleware.UserIDKey) if !exists { @@ -125,7 +151,7 @@ func (h *PostHandler) WardenPostEdit (c *gin.Context) { // WardenPostDelete lets the author delete his post. // Matches is the author trying to delete. -func (h *PostHandler) WardenPostDelete (c *gin.Context) { +func (h *PostHandler) WardenPostDelete(c *gin.Context) { // get userID from gin context userID, exists := c.Get(middleware.UserIDKey); if !exists { @@ -161,7 +187,7 @@ func (h *PostHandler) WardenPostDelete (c *gin.Context) { // GetWardenPosts fetch the posts of the warden member along with their status and comments -func (h *PostHandler) GetWardenPosts (c *gin.Context) { +func (h *PostHandler) GetWardenPosts(c *gin.Context) { email, exists := c.Get(middleware.EmailKey) if !exists { c.JSON(401, gin.H{"error": "unauthenticated user"}) diff --git a/models/centrehead_auth.go b/models/centrehead_auth.go index 4625bcc..9ea77a3 100644 --- a/models/centrehead_auth.go +++ b/models/centrehead_auth.go @@ -33,6 +33,7 @@ type Centrehead struct { Password string `gorm:"not null" json:"password"` Building BuildingName `gorm:"type:varchar(100);not null" json:"building"` PhoneNumber string `gorm:"type:char(10);not null" json:"phone_number"` + Role string `gorm:"default:centrehead" json:"role"` IsVerified bool `gorm:"default:false" json:"is_verified"` CreatedAt time.Time `json:"created_at"` } diff --git a/models/faculty_auth.go b/models/faculty_auth.go index f964d6c..0d3fb4e 100644 --- a/models/faculty_auth.go +++ b/models/faculty_auth.go @@ -51,6 +51,7 @@ type Faculty struct { Block BlockLabel `gorm:"type:char(1);not null" json:"block"` Type BlockType `gorm:"type:char(1);not null" json:"type"` PhoneNumber string `gorm:"type:char(10);not null" json:"phone_number"` + Role string `gorm:"default:faculty" json:"role"` IsVerified bool `gorm:"default:false" json:"is_verified"` CreatedAt time.Time `json:"created_at"` } diff --git a/models/warden_auth.go b/models/warden_auth.go index dfdff4e..5240f5a 100644 --- a/models/warden_auth.go +++ b/models/warden_auth.go @@ -27,6 +27,7 @@ type Warden struct { Password string `gorm:"not null" json:"password"` Hostel HostelName `gorm:"type:varchar(30);not null" json:"hostel"` PhoneNumber string `gorm:"type:char(10);not null" json:"phone_number"` + Role string `gorm:"default:warden" json:"role"` IsVerified bool `gorm:"default:false" json:"is_verified"` CreatedAt time.Time `json:"created_at"` } diff --git a/services/email.go b/services/email.go index 761f63a..7a45f09 100644 --- a/services/email.go +++ b/services/email.go @@ -108,3 +108,32 @@ func SendPasswordResetMail(userID uint, email, role string) error { log.Printf("Password reset link sent to %s", email) return nil } + +func SendPostMailToAdmins(email, postURL string) error { + // send the email + mail := fmt.Sprintf(` + + + + + + + +

    Reset your password

    +

    + Reset! +

    + + + `, postURL) + + err := SendMail(email, "New complaint recieved", mail) + if err != nil { + return err + } + log.Printf("complaint mail was sent to %s", email) + return nil +}