diff --git a/app/handlers/admin.go b/app/handlers/admin.go index 9bdae3174..38959925b 100644 --- a/app/handlers/admin.go +++ b/app/handlers/admin.go @@ -5,6 +5,7 @@ import ( "github.com/getfider/fider/app/actions" "github.com/getfider/fider/app/models/cmd" + "github.com/getfider/fider/app/models/entity" "github.com/getfider/fider/app/models/query" "github.com/getfider/fider/app/pkg/bus" "github.com/getfider/fider/app/pkg/web" @@ -126,11 +127,19 @@ func ManageMembers() web.HandlerFunc { return c.Failure(err) } + // Create an array of UserWithEmail structs from the allUsers.Result + allUsersWithEmail := make([]entity.UserWithEmail, len(allUsers.Result)) + for i, user := range allUsers.Result { + allUsersWithEmail[i] = entity.UserWithEmail{ + User: user, + } + } + return c.Page(http.StatusOK, web.Props{ Page: "Administration/pages/ManageMembers.page", Title: "Manage Members ยท Site Settings", Data: web.Map{ - "users": allUsers.Result, + "users": allUsersWithEmail, }, }) } diff --git a/app/models/entity/user.go b/app/models/entity/user.go index bcf37e02b..8e270e293 100644 --- a/app/models/entity/user.go +++ b/app/models/entity/user.go @@ -1,8 +1,12 @@ package entity -import "github.com/getfider/fider/app/models/enum" +import ( + "encoding/json" -//User represents an user inside our application + "github.com/getfider/fider/app/models/enum" +) + +// User represents an user inside our application type User struct { ID int `json:"id"` Name string `json:"name"` @@ -16,7 +20,7 @@ type User struct { Status enum.UserStatus `json:"status"` } -//HasProvider returns true if current user has registered with given provider +// HasProvider returns true if current user has registered with given provider func (u *User) HasProvider(provider string) bool { for _, p := range u.Providers { if p.Name == provider { @@ -36,8 +40,24 @@ func (u *User) IsAdministrator() bool { return u.Role == enum.RoleAdministrator } -//UserProvider represents the relationship between an User and an Authentication provide +// UserProvider represents the relationship between an User and an Authentication provide type UserProvider struct { Name string UID string } + +// UserWithEmail is a wrapper around User that includes the email field when marshaling to JSON +type UserWithEmail struct { + *User +} + +func (umc UserWithEmail) MarshalJSON() ([]byte, error) { + type Alias User // Prevent recursion + return json.Marshal(&struct { + *Alias + Email string `json:"email"` + }{ + Alias: (*Alias)(umc.User), + Email: umc.User.Email, + }) +} diff --git a/app/models/entity/user_test.go b/app/models/entity/user_test.go new file mode 100644 index 000000000..af391886b --- /dev/null +++ b/app/models/entity/user_test.go @@ -0,0 +1,55 @@ +package entity_test + +import ( + "encoding/json" + "testing" + + "github.com/getfider/fider/app/models/entity" + . "github.com/getfider/fider/app/pkg/assert" +) + +func TestUserWithEmail_MarshalJSON(t *testing.T) { + + RegisterT(t) + user := entity.UserWithEmail{ + User: &entity.User{ + ID: 1, + Name: "John Doe", + Email: "johndoe@example.com", + Role: 1, + Status: 1, + }, + } + + expectedJSON := `{"id":1,"name":"John Doe","role":"visitor","status":"active","email":"johndoe@example.com"}` + + jsonData, err := json.Marshal(user) + if err != nil { + t.Errorf("Failed to marshal user to JSON: %v", err) + } + + Expect(string(jsonData)).Equals(expectedJSON) + +} + +func TestUser_MarshalJSON(t *testing.T) { + + RegisterT(t) + user := entity.User{ + ID: 1, + Name: "John Doe", + Email: "johndoe@example.com", + Role: 1, + Status: 1, + } + + expectedJSON := `{"id":1,"name":"John Doe","role":"visitor","status":"active"}` + + jsonData, err := json.Marshal(user) + if err != nil { + t.Errorf("Failed to marshal user to JSON: %v", err) + } + + Expect(string(jsonData)).Equals(expectedJSON) + +} diff --git a/public/components/common/UserName.scss b/public/components/common/UserName.scss index aaa8a796b..e4c70594f 100644 --- a/public/components/common/UserName.scss +++ b/public/components/common/UserName.scss @@ -6,6 +6,13 @@ display: inline-flex; align-items: center; + &--email { + margin-left: 10px; + color: get("colors.gray.600"); + font-size: get("font.size.xs"); + font-weight: 400; + } + &--staff { color: get("colors.primary.base"); border-color: get("colors.primary.base"); diff --git a/public/components/common/UserName.tsx b/public/components/common/UserName.tsx index 8559d3bd0..b7a7eb7a7 100644 --- a/public/components/common/UserName.tsx +++ b/public/components/common/UserName.tsx @@ -9,6 +9,7 @@ interface UserNameProps { id: number name: string role?: UserRole + email?: string } } @@ -22,6 +23,8 @@ export const UserName = (props: UserNameProps) => { return (