package httpapi import ( "net/http" "strings" "spin/internal/models" ) // MeResponse enriches the proxy identity with the matched Member profile. type MeResponse struct { User User `json:"user"` Member *models.Member `json:"member"` IsAdmin bool `json:"isAdmin"` LogoutURL string `json:"logoutUrl"` } func (s *Server) handleMe(w http.ResponseWriter, r *http.Request) { u := currentUser(r.Context()) writeJSON(w, http.StatusOK, MeResponse{ User: u, Member: s.lookupMember(u.Email), IsAdmin: s.isAdmin(r), LogoutURL: s.cfg.LogoutURL, }) } // NavItem is one sidebar entry; adminOnly entries are filtered for members. type NavItem struct { Key string `json:"key"` Label string `json:"label"` Path string `json:"path"` Icon string `json:"icon"` AdminOnly bool `json:"adminOnly"` Section string `json:"section"` } var navItems = []NavItem{ {Key: "dashboard", Label: "대시보드", Path: "/", Icon: "LayoutDashboard", Section: "개요"}, {Key: "inbox", Label: "메일함", Path: "/inbox", Icon: "Inbox", Section: "개요"}, {Key: "attendance", Label: "근무", Path: "/attendance", Icon: "Clock", Section: "나의 업무"}, {Key: "projects", Label: "프로젝트", Path: "/projects", Icon: "FolderKanban", Section: "나의 업무"}, {Key: "incentive", Label: "인센티브", Path: "/incentive", Icon: "Coins", Section: "나의 업무"}, {Key: "profile", Label: "내 프로필", Path: "/profile", Icon: "UserCircle", Section: "나의 업무"}, {Key: "approvals", Label: "승인 관리", Path: "/admin/approvals", Icon: "CheckSquare", AdminOnly: true, Section: "관리자"}, {Key: "attendance-admin", Label: "근무 관리", Path: "/admin/attendance", Icon: "ClipboardList", AdminOnly: true, Section: "관리자"}, {Key: "projects-admin", Label: "프로젝트 관리", Path: "/admin/projects", Icon: "FolderCog", AdminOnly: true, Section: "관리자"}, {Key: "incentive-admin", Label: "인센티브 관리", Path: "/admin/incentive", Icon: "Calculator", AdminOnly: true, Section: "관리자"}, {Key: "accounting", Label: "회계", Path: "/admin/accounting", Icon: "Wallet", AdminOnly: true, Section: "관리자"}, {Key: "members", Label: "구성원", Path: "/admin/members", Icon: "Users", AdminOnly: true, Section: "관리자"}, {Key: "settings", Label: "설정", Path: "/admin/settings", Icon: "Settings", AdminOnly: true, Section: "관리자"}, } func (s *Server) handleNav(w http.ResponseWriter, r *http.Request) { admin := s.isAdmin(r) out := make([]NavItem, 0, len(navItems)) for _, it := range navItems { if it.AdminOnly && !admin { continue } out = append(out, it) } writeJSON(w, http.StatusOK, out) } // lc lower-cases & trims a string (small helper used across handlers). func lc(s string) string { return strings.ToLower(strings.TrimSpace(s)) }