Featured users

This commit is contained in:
Asaf Gartner 2024-07-06 18:47:46 +03:00
parent ed41600061
commit 5ea589dbfa
7 changed files with 82 additions and 7 deletions

View File

@ -0,0 +1,50 @@
package migrations
import (
"context"
"time"
"git.handmade.network/hmn/hmn/src/migration/types"
"git.handmade.network/hmn/hmn/src/utils"
"github.com/jackc/pgx/v5"
)
func init() {
registerMigration(AddFeaturedToUser{})
}
type AddFeaturedToUser struct{}
func (m AddFeaturedToUser) Version() types.MigrationVersion {
return types.MigrationVersion(time.Date(2024, 7, 6, 15, 34, 32, 0, time.UTC))
}
func (m AddFeaturedToUser) Name() string {
return "AddFeaturedToUser"
}
func (m AddFeaturedToUser) Description() string {
return "Add featured flag to users"
}
func (m AddFeaturedToUser) Up(ctx context.Context, tx pgx.Tx) error {
utils.Must1(tx.Exec(ctx,
`
ALTER TABLE hmn_user
ADD COLUMN featured BOOLEAN NOT NULL DEFAULT false;
CREATE INDEX hmn_user_featured ON hmn_user(featured);
`,
))
return nil
}
func (m AddFeaturedToUser) Down(ctx context.Context, tx pgx.Tx) error {
utils.Must1(tx.Exec(ctx,
`
DROP INDEX hmn_user_featured;
ALTER TABLE hmn_user
DROP COLUMN featured;
`,
))
return nil
}

View File

@ -31,6 +31,7 @@ type User struct {
IsStaff bool `db:"is_staff"` IsStaff bool `db:"is_staff"`
Status UserStatus `db:"status"` Status UserStatus `db:"status"`
EducationRole EduRole `db:"education_role"` EducationRole EduRole `db:"education_role"`
Featured bool `db:"featured"`
Name string `db:"name"` Name string `db:"name"`
Bio string `db:"bio"` Bio string `db:"bio"`

View File

@ -217,6 +217,7 @@ func UserToTemplate(u *models.User) User {
Email: email, Email: email,
IsStaff: u.IsStaff, IsStaff: u.IsStaff,
Status: int(u.Status), Status: int(u.Status),
Featured: u.Featured,
Name: u.BestName(), Name: u.BestName(),
Bio: u.Bio, Bio: u.Bio,

View File

@ -125,6 +125,12 @@
<option value="author" {{ if .ProfileUser.IsEduAuthor }}selected{{ end }}>Author</option> <option value="author" {{ if .ProfileUser.IsEduAuthor }}selected{{ end }}>Author</option>
</select> </select>
</div> </div>
<div class="input-group">
<div>
<input id="featured" name="featured" type="checkbox" {{ if .ProfileUser.Featured }}checked{{ end }} />
<label for="featured">Featured</label>
</div>
</div>
<div class="input-group"> <div class="input-group">
<input class="btn-primary" type="submit" value="Save" /> <input class="btn-primary" type="submit" value="Save" />
</div> </div>

View File

@ -208,6 +208,7 @@ type User struct {
Email string Email string
IsStaff bool IsStaff bool
Status int Status int
Featured bool
Name string Name string
Blurb string Blurb string

View File

@ -4,6 +4,7 @@ import (
"html/template" "html/template"
"net/http" "net/http"
"git.handmade.network/hmn/hmn/src/db"
"git.handmade.network/hmn/hmn/src/hmndata" "git.handmade.network/hmn/hmn/src/hmndata"
"git.handmade.network/hmn/hmn/src/hmnurl" "git.handmade.network/hmn/hmn/src/hmnurl"
"git.handmade.network/hmn/hmn/src/models" "git.handmade.network/hmn/hmn/src/models"
@ -65,18 +66,29 @@ func Index(c *RequestContext) ResponseData {
} }
} }
featuredProjects, err := hmndata.FetchProjects(c, c.Conn, c.CurrentUser, hmndata.ProjectsQuery{ featuredProjectIDs, err := db.QueryScalar[int](c, c.Conn,
FeaturedOnly: true, `
}) SELECT id
FROM project
WHERE featured = true
`,
)
if err != nil { if err != nil {
c.Logger.Warn().Err(err).Msg("failed to fetch featured projects") c.Logger.Warn().Err(err).Msg("failed to fetch featured projects")
} }
var featuredProjectIDs []int featuredUserIDs, err := db.QueryScalar[int](c, c.Conn,
for _, p := range featuredProjects { `
featuredProjectIDs = append(featuredProjectIDs, p.Project.ID) SELECT id
FROM hmn_user
WHERE featured = true
`,
)
if err != nil {
c.Logger.Warn().Err(err).Msg("failed to fetch featured users")
} }
featuredItems, err = FetchTimeline(c, c.Conn, c.CurrentUser, lineageBuilder, hmndata.TimelineQuery{ featuredItems, err = FetchTimeline(c, c.Conn, c.CurrentUser, lineageBuilder, hmndata.TimelineQuery{
ProjectIDs: featuredProjectIDs, ProjectIDs: featuredProjectIDs,
OwnerIDs: featuredUserIDs,
Limit: maxPostsPerTab, Limit: maxPostsPerTab,
}) })
if err != nil { if err != nil {

View File

@ -500,15 +500,19 @@ func UserProfileAdminSetOptions(c *RequestContext) ResponseData {
return c.RejectRequest("the education role is bad and you should feel bad") return c.RejectRequest("the education role is bad and you should feel bad")
} }
featuredFlag := c.Req.Form.Get("featured")
featured := featuredFlag != ""
_, err = c.Conn.Exec(c, _, err = c.Conn.Exec(c,
` `
UPDATE hmn_user UPDATE hmn_user
SET status = $2, education_role = $3 SET status = $2, education_role = $3, featured = $4
WHERE id = $1 WHERE id = $1
`, `,
userId, userId,
desiredStatus, desiredStatus,
desiredEduRole, desiredEduRole,
featured,
) )
if err != nil { if err != nil {
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to update user admin settings")) return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to update user admin settings"))