charts
This commit is contained in:
parent
65eddf6fd8
commit
39862c0516
525
main.go
525
main.go
@ -2,18 +2,22 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"math/big"
|
"math/big"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/mail"
|
"net/mail"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/labstack/echo/v5"
|
"github.com/labstack/echo/v5"
|
||||||
"github.com/pocketbase/pocketbase"
|
"github.com/pocketbase/pocketbase"
|
||||||
"github.com/pocketbase/pocketbase/apis"
|
"github.com/pocketbase/pocketbase/apis"
|
||||||
"github.com/pocketbase/pocketbase/core"
|
"github.com/pocketbase/pocketbase/core"
|
||||||
|
"github.com/pocketbase/pocketbase/models"
|
||||||
"github.com/pocketbase/pocketbase/tools/mailer"
|
"github.com/pocketbase/pocketbase/tools/mailer"
|
||||||
"github.com/pocketbase/pocketbase/tools/types"
|
"github.com/pocketbase/pocketbase/tools/types"
|
||||||
)
|
)
|
||||||
@ -29,80 +33,99 @@ type EmailConfigurationResponse struct {
|
|||||||
} `json:"items"`
|
} `json:"items"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GenericData struct {
|
||||||
|
XMLName xml.Name `xml:"GenericData"`
|
||||||
|
DataSet []Obs `xml:"DataSet>Obs"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Obs struct {
|
||||||
|
ObsKey []ObsKey `xml:"ObsKey>Value"` // Dynamic key-value pairs
|
||||||
|
ObsValue ObsValue `xml:"ObsValue"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ObsKey struct {
|
||||||
|
ID string `xml:"id,attr"` // Attribute for 'id'
|
||||||
|
Value string `xml:"value,attr"` // Attribute for 'value'
|
||||||
|
}
|
||||||
|
|
||||||
|
type ObsValue struct {
|
||||||
|
Value string `xml:"value,attr"` // Attribute for 'value'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to map ObsKey into a dictionary
|
||||||
|
func mapObsKey(keys []ObsKey) map[string]string {
|
||||||
|
result := map[string]string{}
|
||||||
|
for _, key := range keys {
|
||||||
|
result[key.ID] = key.Value
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to clean XML namespace prefixes
|
||||||
|
func removeNamespace(xmlBytes []byte) string {
|
||||||
|
return strings.ReplaceAll(string(xmlBytes), "generic:", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to fetch XML from an API and convert it to JSON
|
||||||
|
func fetchAndConvertXMLToJSON(apiURL string) ([]map[string]interface{}, error) {
|
||||||
|
// Call the API and get the XML response
|
||||||
|
resp, err := http.Get(apiURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
// Read the response body
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean the XML by removing namespace prefixes
|
||||||
|
cleanXML := []byte(removeNamespace(body))
|
||||||
|
|
||||||
|
// Parse the cleaned XML data
|
||||||
|
var data GenericData
|
||||||
|
err = xml.Unmarshal(cleanXML, &data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform the data for JSON output
|
||||||
|
response := []map[string]interface{}{}
|
||||||
|
for _, obs := range data.DataSet {
|
||||||
|
obsMap := map[string]interface{}{
|
||||||
|
"ObsKey": mapObsKey(obs.ObsKey),
|
||||||
|
"ObsValue": obs.ObsValue,
|
||||||
|
}
|
||||||
|
response = append(response, obsMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|
||||||
var app *pocketbase.PocketBase
|
var app *pocketbase.PocketBase
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// app := pocketbase.New()
|
// app := pocketbase.New()
|
||||||
app = pocketbase.New()
|
app = pocketbase.New()
|
||||||
|
|
||||||
|
//send mail while status changed from app admin
|
||||||
app.OnRecordBeforeUpdateRequest().Add(func(e *core.RecordUpdateEvent) error {
|
app.OnRecordBeforeUpdateRequest().Add(func(e *core.RecordUpdateEvent) error {
|
||||||
if e.Collection.Name == "users" {
|
if e.Collection.Name == "users" {
|
||||||
// Fetch the original record by ID
|
|
||||||
originalRecord, err := app.Dao().FindRecordById("users", e.Record.GetString("id"))
|
originalRecord, err := app.Dao().FindRecordById("users", e.Record.GetString("id"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to fetch original record: %v", err)
|
return fmt.Errorf("failed to fetch original record: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the old status before the update
|
|
||||||
oldStatus := originalRecord.GetString("status")
|
oldStatus := originalRecord.GetString("status")
|
||||||
newStatus := e.Record.GetString("status")
|
newStatus := e.Record.GetString("status")
|
||||||
|
|
||||||
// If the status has changed, send an email
|
// Check if the status has changed
|
||||||
if newStatus != oldStatus {
|
if oldStatus != newStatus {
|
||||||
userEmail := e.Record.GetString("email")
|
err := sendStatusChangeEmail(app, e.Record, newStatus)
|
||||||
userName := e.Record.GetString("username")
|
if err != nil {
|
||||||
if userEmail != "" {
|
return err
|
||||||
|
|
||||||
var subject string
|
|
||||||
var body string
|
|
||||||
|
|
||||||
// Define the email content based on status
|
|
||||||
if newStatus == "Approved" {
|
|
||||||
subject = "Registration Approved – FCSC"
|
|
||||||
body = fmt.Sprintf(`
|
|
||||||
<p>Dear %s,</p>
|
|
||||||
<p>We are pleased to inform you that your registration with FCSC has been approved. You can now log in using the credentials that you had created.</p>
|
|
||||||
<p>Please access your account using the following link: <a href="http://your-login-url.com">Login</a>.</p>
|
|
||||||
<p>If you have any questions, please feel free to contact us for further clarification.</p>
|
|
||||||
`, userName)
|
|
||||||
} else if newStatus == "Denied" {
|
|
||||||
subject = "Registration Update – FCSC"
|
|
||||||
body = fmt.Sprintf(`
|
|
||||||
<p>Dear %s,</p>
|
|
||||||
<p>Thank you for registering with FCSC. After careful review, we regret to inform you that your registration has not been approved at this time.</p>
|
|
||||||
<p>If you have any questions or believe this decision was made in error, please feel free to contact us for further clarification.</p>
|
|
||||||
<p>We appreciate your understanding and thank you for your interest.</p>
|
|
||||||
<p>Best regards,</p>
|
|
||||||
`, userName)
|
|
||||||
} else {
|
|
||||||
// If the status is neither "Approved" nor "Denied", skip sending an email
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the email message
|
|
||||||
message := &mailer.Message{
|
|
||||||
From: mail.Address{
|
|
||||||
Name: "FCSC",
|
|
||||||
Address: app.Settings().Meta.SenderAddress, // Replace with your sender's email
|
|
||||||
},
|
|
||||||
To: []mail.Address{
|
|
||||||
{
|
|
||||||
Name: userName,
|
|
||||||
Address: userEmail,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Subject: subject,
|
|
||||||
HTML: body,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send the email
|
|
||||||
err = app.NewMailClient().Send(message)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Failed to send status change email: %v", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Println("Status change email sent successfully to:", userEmail)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,7 +192,7 @@ func main() {
|
|||||||
app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
|
app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
|
||||||
|
|
||||||
e.Router.GET("/api/custom/approve", func(c echo.Context) error {
|
e.Router.GET("/api/custom/approve", func(c echo.Context) error {
|
||||||
userId := c.QueryParam("userId") // Get userId from query parameters
|
userId := c.QueryParam("userId")
|
||||||
if userId == "" {
|
if userId == "" {
|
||||||
return c.JSON(400, map[string]interface{}{
|
return c.JSON(400, map[string]interface{}{
|
||||||
"code": 400,
|
"code": 400,
|
||||||
@ -177,7 +200,7 @@ func main() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the user record in PocketBase by userId
|
// Find the user record
|
||||||
record, err := app.Dao().FindRecordById("users", userId)
|
record, err := app.Dao().FindRecordById("users", userId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(500, map[string]interface{}{
|
return c.JSON(500, map[string]interface{}{
|
||||||
@ -186,8 +209,60 @@ func main() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the verified status to true
|
// Check if the email is already verified
|
||||||
|
if record.GetBool("reviewed") {
|
||||||
|
return c.HTML(http.StatusOK, `
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
background-color: #f0f8ff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.message-container {
|
||||||
|
text-align: center;
|
||||||
|
background-color: #ffe0e0;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
.message-container h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
color: #b71c1c;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.message-container p {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #880e4f;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
font-size: 50px;
|
||||||
|
color: #b71c1c;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="message-container">
|
||||||
|
<div class="icon">✖</div>
|
||||||
|
<h1>Your Already Reviewed</h1>
|
||||||
|
<p>You have already been reviewed. No further action is required.</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the status
|
||||||
|
newStatus := "Approved"
|
||||||
record.Set("verified", true)
|
record.Set("verified", true)
|
||||||
|
record.Set("status", newStatus)
|
||||||
|
record.Set("reviewed", true)
|
||||||
if err := app.Dao().SaveRecord(record); err != nil {
|
if err := app.Dao().SaveRecord(record); err != nil {
|
||||||
return c.JSON(500, map[string]interface{}{
|
return c.JSON(500, map[string]interface{}{
|
||||||
"code": 500,
|
"code": 500,
|
||||||
@ -195,39 +270,8 @@ func main() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare the email details
|
// Send the status change email
|
||||||
name := record.GetString("username")
|
err = sendStatusChangeEmail(app, record, newStatus)
|
||||||
email := record.GetString("email")
|
|
||||||
subject := "Registration Approved – FCSC"
|
|
||||||
body := fmt.Sprintf(`
|
|
||||||
<html>
|
|
||||||
<body>
|
|
||||||
<p>Dear %s,</p>
|
|
||||||
<p>We are pleased to inform you that your registration with FCSC has been approved. You can now log in using the credentials that you had created.</p>
|
|
||||||
<p>Please access your account using the following link: <a href="http://your-login-url.com">Login</a>.</p>
|
|
||||||
<p>If you have any questions, please feel free to contact us for further clarification.</p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`, name)
|
|
||||||
|
|
||||||
// Create the email message
|
|
||||||
message := &mailer.Message{
|
|
||||||
From: mail.Address{
|
|
||||||
Name: "FCSC",
|
|
||||||
Address: app.Settings().Meta.SenderAddress,
|
|
||||||
},
|
|
||||||
To: []mail.Address{
|
|
||||||
{
|
|
||||||
Name: name,
|
|
||||||
Address: email,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Subject: subject,
|
|
||||||
HTML: body,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send the approval email
|
|
||||||
err = app.NewMailClient().Send(message)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(500, map[string]interface{}{
|
return c.JSON(500, map[string]interface{}{
|
||||||
"code": 500,
|
"code": 500,
|
||||||
@ -235,9 +279,8 @@ func main() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render a success message as an HTML response
|
|
||||||
return c.HTML(http.StatusOK, `
|
return c.HTML(http.StatusOK, `
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
@ -290,7 +333,7 @@ func main() {
|
|||||||
|
|
||||||
// Approve Endpoint
|
// Approve Endpoint
|
||||||
e.Router.GET("/api/custom/reject", func(c echo.Context) error {
|
e.Router.GET("/api/custom/reject", func(c echo.Context) error {
|
||||||
userId := c.QueryParam("userId") // Get userId from query parameters
|
userId := c.QueryParam("userId")
|
||||||
if userId == "" {
|
if userId == "" {
|
||||||
return c.JSON(400, map[string]interface{}{
|
return c.JSON(400, map[string]interface{}{
|
||||||
"code": 400,
|
"code": 400,
|
||||||
@ -307,49 +350,77 @@ func main() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the verified status to false
|
// Check if the email is already verified
|
||||||
record.Set("verified", false)
|
if record.GetBool("reviewed") {
|
||||||
if err := app.Dao().SaveRecord(record); err != nil {
|
return c.HTML(http.StatusOK, `
|
||||||
return c.JSON(500, map[string]interface{}{
|
<html>
|
||||||
"code": 500,
|
<head>
|
||||||
"message": "Failed to update user status.",
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
background-color: #f0f8ff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.message-container {
|
||||||
|
text-align: center;
|
||||||
|
background-color: #ffe0e0;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
.message-container h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
color: #b71c1c;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.message-container p {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #880e4f;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
font-size: 50px;
|
||||||
|
color: #b71c1c;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="message-container">
|
||||||
|
<div class="icon">✖</div>
|
||||||
|
<h1>Your Already Reviewed</h1>
|
||||||
|
<p>You have already been reviewed. No further action is required.</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the status is already "Denied" to avoid duplicate email
|
||||||
|
if record.GetString("status") == "Denied" {
|
||||||
|
return c.JSON(400, map[string]interface{}{
|
||||||
|
"code": 400,
|
||||||
|
"message": "User is already rejected.",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare the rejection email details
|
// Update the status
|
||||||
name := record.GetString("username")
|
newStatus := "Denied"
|
||||||
email := record.GetString("email")
|
record.Set("verified", true)
|
||||||
subject := "Registration Update – FCSC"
|
record.Set("status", newStatus)
|
||||||
body := fmt.Sprintf(`
|
record.Set("reviewed", true)
|
||||||
<html>
|
if err := app.Dao().SaveRecord(record); err != nil {
|
||||||
<body>
|
return c.JSON(500, map[string]interface{}{
|
||||||
<p>Dear %s,</p>
|
"code": 500,
|
||||||
<p>Thank you for registering with FCSC. After careful review, we regret to inform you that your registration has not been approved at this time.</p>
|
"message": "Failed to verify user.",
|
||||||
<p>If you have any questions or believe this decision was made in error, please feel free to contact us for further clarification.</p>
|
})
|
||||||
<p>We appreciate your understanding and thank you for your interest.</p>
|
|
||||||
<p>Best regards,</p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`, name)
|
|
||||||
|
|
||||||
// Create the rejection email message
|
|
||||||
message := &mailer.Message{
|
|
||||||
From: mail.Address{
|
|
||||||
Name: "FCSC",
|
|
||||||
Address: app.Settings().Meta.SenderAddress,
|
|
||||||
},
|
|
||||||
To: []mail.Address{
|
|
||||||
{
|
|
||||||
Name: name,
|
|
||||||
Address: email,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Subject: subject,
|
|
||||||
HTML: body,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the rejection email
|
// Send the status change email
|
||||||
err = app.NewMailClient().Send(message)
|
err = sendStatusChangeEmail(app, record, newStatus)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSON(500, map[string]interface{}{
|
return c.JSON(500, map[string]interface{}{
|
||||||
"code": 500,
|
"code": 500,
|
||||||
@ -359,44 +430,44 @@ func main() {
|
|||||||
|
|
||||||
// Render a success message as an HTML response
|
// Render a success message as an HTML response
|
||||||
return c.HTML(http.StatusOK, `
|
return c.HTML(http.StatusOK, `
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>User Rejected</title>
|
<title>User Rejected</title>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
background-color: #ffe6e6; /* Light red background */
|
background-color: #ffe6e6;
|
||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
}
|
}
|
||||||
.message-box {
|
.message-box {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #d9534f; /* Bootstrap red */
|
color: #d9534f;
|
||||||
}
|
}
|
||||||
.message-box i {
|
.message-box i {
|
||||||
font-size: 48px;
|
font-size: 48px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
.message-box p {
|
.message-box p {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="message-box">
|
<div class="message-box">
|
||||||
<i>❌</i>
|
<i>❌</i>
|
||||||
<h1>User Rejected</h1>
|
<h1>User Rejected</h1>
|
||||||
<p>Rejection email sent successfully.</p>
|
<p>Rejection email sent successfully.</p>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -410,6 +481,7 @@ func main() {
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
//Feedback Mail Trigger
|
||||||
app.OnRecordAfterCreateRequest().Add(func(e *core.RecordCreateEvent) error {
|
app.OnRecordAfterCreateRequest().Add(func(e *core.RecordCreateEvent) error {
|
||||||
if e.Record.Collection().Name == "feedback" {
|
if e.Record.Collection().Name == "feedback" {
|
||||||
// Retrieve feedback details
|
// Retrieve feedback details
|
||||||
@ -635,6 +707,55 @@ func verifyEmailHandler(c echo.Context) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the email is already verified
|
||||||
|
if record.GetBool("user_mail_verify") {
|
||||||
|
return c.HTML(http.StatusOK, `
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
background-color: #f0f8ff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.message-container {
|
||||||
|
text-align: center;
|
||||||
|
background-color: #ffe0e0;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
.message-container h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
color: #b71c1c;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.message-container p {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #880e4f;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
font-size: 50px;
|
||||||
|
color: #b71c1c;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="message-container">
|
||||||
|
<div class="icon">✖</div>
|
||||||
|
<h1>Email Already Verified</h1>
|
||||||
|
<p>Your email has already been verified. No further action is required.</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
// Set the verified status to true
|
// Set the verified status to true
|
||||||
record.Set("user_mail_verify", true)
|
record.Set("user_mail_verify", true)
|
||||||
// log.Printf("Failed to verify user: %v", err)
|
// log.Printf("Failed to verify user: %v", err)
|
||||||
@ -710,6 +831,7 @@ func verifyEmailHandler(c echo.Context) error {
|
|||||||
func sendAdminEmail(app *pocketbase.PocketBase, userID, username, userEmail string) error {
|
func sendAdminEmail(app *pocketbase.PocketBase, userID, username, userEmail string) error {
|
||||||
adminName := "Admin"
|
adminName := "Admin"
|
||||||
subject := "New User Registration Pending Review"
|
subject := "New User Registration Pending Review"
|
||||||
|
|
||||||
body := fmt.Sprintf(`
|
body := fmt.Sprintf(`
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
@ -755,3 +877,60 @@ func sendAdminEmail(app *pocketbase.PocketBase, userID, username, userEmail stri
|
|||||||
log.Println("Admin email sent successfully.")
|
log.Println("Admin email sent successfully.")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sendStatusChangeEmail(app *pocketbase.PocketBase, record *models.Record, newStatus string) error {
|
||||||
|
userEmail := record.GetString("email")
|
||||||
|
userName := record.GetString("username")
|
||||||
|
|
||||||
|
if userEmail == "" {
|
||||||
|
return fmt.Errorf("user email is empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
var subject, body string
|
||||||
|
|
||||||
|
if newStatus == "Approved" {
|
||||||
|
subject = "Registration Approved – FCSC"
|
||||||
|
body = fmt.Sprintf(`
|
||||||
|
<p>Dear %s,</p>
|
||||||
|
<p>We are pleased to inform you that your registration with FCSC has been approved. You can now log in using the credentials that you had created.</p>
|
||||||
|
<p>Please access your account using the following link: <a href="http://your-login-url.com">Login</a>.</p>
|
||||||
|
<p>If you have any questions, please feel free to contact us for further clarification.</p>
|
||||||
|
`, userName)
|
||||||
|
} else if newStatus == "Denied" {
|
||||||
|
subject = "Registration Update – FCSC"
|
||||||
|
body = fmt.Sprintf(`
|
||||||
|
<p>Dear %s,</p>
|
||||||
|
<p>Thank you for registering with FCSC. After careful review, we regret to inform you that your registration has not been approved at this time.</p>
|
||||||
|
<p>If you have any questions or believe this decision was made in error, please feel free to contact us for further clarification.</p>
|
||||||
|
<p>We appreciate your understanding and thank you for your interest.</p>
|
||||||
|
<p>Best regards,</p>
|
||||||
|
`, userName)
|
||||||
|
} else {
|
||||||
|
// If the status is neither "Approved" nor "Denied", skip sending an email
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and send the email
|
||||||
|
message := &mailer.Message{
|
||||||
|
From: mail.Address{
|
||||||
|
Name: "FCSC",
|
||||||
|
Address: app.Settings().Meta.SenderAddress,
|
||||||
|
},
|
||||||
|
To: []mail.Address{
|
||||||
|
{
|
||||||
|
Name: userName,
|
||||||
|
Address: userEmail,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Subject: subject,
|
||||||
|
HTML: body,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := app.NewMailClient().Send(message)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to send email: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Status change email sent successfully to: %s", userEmail)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user