Initial commit
This commit is contained in:
71
cpone-dashboard/menu/projects/handler.go
Normal file
71
cpone-dashboard/menu/projects/handler.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package projects
|
||||
|
||||
import (
|
||||
"cpone-dashboard/menu/auth"
|
||||
"embed"
|
||||
"html/template"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var tmplFS *embed.FS
|
||||
var basePath string
|
||||
|
||||
func SetTemplateFS(fs *embed.FS) { tmplFS = fs }
|
||||
func SetBasePath(p string) { basePath = p }
|
||||
|
||||
type pageData struct {
|
||||
Username string
|
||||
Projects []ProjectItem
|
||||
CurrentProject *ProjectItem
|
||||
}
|
||||
|
||||
func Index(w http.ResponseWriter, r *http.Request) {
|
||||
username := auth.Username(r)
|
||||
selectedID := auth.SelectedProjectID(r)
|
||||
|
||||
items, err := GetUserProjects(username)
|
||||
if err != nil {
|
||||
log.Printf("[projects] GetUserProjects error: %v", err)
|
||||
http.Error(w, "query error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
b := func(path string) string { return basePath + path }
|
||||
t := template.Must(template.New("").Funcs(template.FuncMap{"b": b}).ParseFS(tmplFS, "templates/projects/index.html"))
|
||||
var current *ProjectItem
|
||||
if selectedID > 0 {
|
||||
if item, ok, _ := GetUserProject(username, selectedID); ok {
|
||||
current = &item
|
||||
}
|
||||
}
|
||||
if err := t.ExecuteTemplate(w, "projects", pageData{
|
||||
Username: username,
|
||||
Projects: items,
|
||||
CurrentProject: current,
|
||||
}); err != nil {
|
||||
log.Printf("[projects] template error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func Select(w http.ResponseWriter, r *http.Request) {
|
||||
username := auth.Username(r)
|
||||
mcuID, _ := strconv.Atoi(r.URL.Query().Get("mcu_id"))
|
||||
if mcuID <= 0 {
|
||||
http.Redirect(w, r, basePath+"/projects", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
if _, ok, err := GetUserProject(username, mcuID); err != nil {
|
||||
log.Printf("[projects] GetUserProject error: %v", err)
|
||||
http.Error(w, "query error", http.StatusInternalServerError)
|
||||
return
|
||||
} else if !ok {
|
||||
http.Redirect(w, r, basePath+"/projects", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
auth.SetSelectedProject(w, mcuID)
|
||||
http.Redirect(w, r, basePath+"/dashboard", http.StatusSeeOther)
|
||||
}
|
||||
93
cpone-dashboard/menu/projects/query.go
Normal file
93
cpone-dashboard/menu/projects/query.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package projects
|
||||
|
||||
import (
|
||||
"cpone-dashboard/db"
|
||||
"cpone-dashboard/menu/auth"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type ProjectItem struct {
|
||||
McuID int
|
||||
Label string
|
||||
CorporateName string
|
||||
Number string
|
||||
StartDate string
|
||||
EndDate string
|
||||
TotalParticipant int
|
||||
}
|
||||
|
||||
func HasAccess(username string, mcuID int) (bool, error) {
|
||||
var count int
|
||||
err := db.DB.QueryRow(`
|
||||
SELECT COUNT(*)
|
||||
FROM dashboard_user_project up
|
||||
JOIN dashboard_user u ON u.User_ID = up.UserProj_UserID
|
||||
WHERE u.User_Username = ?
|
||||
AND up.UserProj_McuID = ?
|
||||
AND up.UserProj_IsActive = 'Y'
|
||||
`, username, mcuID).Scan(&count)
|
||||
return count > 0, err
|
||||
}
|
||||
|
||||
func GetUserProjects(username string) ([]ProjectItem, error) {
|
||||
rows, err := db.DB.Query(`
|
||||
SELECT
|
||||
p.Mcu_ProjectMcuID,
|
||||
COALESCE(p.Mcu_ProjectLabel, ''),
|
||||
COALESCE(p.Mcu_ProjectCorporateName, ''),
|
||||
COALESCE(p.Mcu_ProjectNumber, ''),
|
||||
COALESCE(DATE_FORMAT(p.Mcu_ProjectStartDate, '%d/%m/%Y'), ''),
|
||||
COALESCE(DATE_FORMAT(p.Mcu_ProjectEndDate, '%d/%m/%Y'), ''),
|
||||
p.Mcu_ProjectTotalParticipant
|
||||
FROM dashboard_user_project up
|
||||
JOIN dashboard_user u ON u.User_ID = up.UserProj_UserID
|
||||
JOIN mcu_project p ON p.Mcu_ProjectMcuID = up.UserProj_McuID
|
||||
WHERE u.User_Username = ?
|
||||
AND up.UserProj_IsActive = 'Y'
|
||||
AND p.Mcu_ProjectIsActive = 'Y'
|
||||
ORDER BY p.Mcu_ProjectStartDate DESC
|
||||
`, username)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var items []ProjectItem
|
||||
for rows.Next() {
|
||||
var item ProjectItem
|
||||
if err := rows.Scan(
|
||||
&item.McuID,
|
||||
&item.Label,
|
||||
&item.CorporateName,
|
||||
&item.Number,
|
||||
&item.StartDate,
|
||||
&item.EndDate,
|
||||
&item.TotalParticipant,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, item)
|
||||
}
|
||||
return items, rows.Err()
|
||||
}
|
||||
|
||||
func GetUserProject(username string, mcuID int) (ProjectItem, bool, error) {
|
||||
items, err := GetUserProjects(username)
|
||||
if err != nil {
|
||||
return ProjectItem{}, false, err
|
||||
}
|
||||
for _, item := range items {
|
||||
if item.McuID == mcuID {
|
||||
return item, true, nil
|
||||
}
|
||||
}
|
||||
return ProjectItem{}, false, nil
|
||||
}
|
||||
|
||||
func ResolveCurrentProject(username string, r *http.Request) (ProjectItem, bool, error) {
|
||||
selectedID := auth.SelectedProjectID(r)
|
||||
if selectedID == 0 {
|
||||
return ProjectItem{}, false, nil
|
||||
}
|
||||
return GetUserProject(username, selectedID)
|
||||
}
|
||||
8
cpone-dashboard/menu/projects/route.go
Normal file
8
cpone-dashboard/menu/projects/route.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package projects
|
||||
|
||||
import "github.com/go-chi/chi/v5"
|
||||
|
||||
func Routes(r chi.Router) {
|
||||
r.Get("/", Index)
|
||||
r.Get("/select", Select)
|
||||
}
|
||||
Reference in New Issue
Block a user