Skip to content

Commit

Permalink
Add profile editing form
Browse files Browse the repository at this point in the history
Signed-off-by: Jo Vandeginste <[email protected]>
  • Loading branch information
jovandeginste committed Feb 23, 2024
1 parent 8c14019 commit 4018783
Show file tree
Hide file tree
Showing 14 changed files with 188 additions and 69 deletions.
17 changes: 0 additions & 17 deletions assets/output.css
Original file line number Diff line number Diff line change
Expand Up @@ -565,13 +565,6 @@ form {
label {
text-align: right;
}
label {
font-weight: 700;
}
label::after {
--tw-content: ':';
content: var(--tw-content);
}
}
}

Expand Down Expand Up @@ -860,19 +853,9 @@ table {
padding-left: 0.5rem;
padding-right: 0.5rem;
}
td {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
tr {
margin-bottom: 0.5rem;
}
tbody th {
font-weight: 700;
}
tbody th::after {
--tw-content: ':';
content: var(--tw-content);
}
}

.workout-tile-info {
Expand Down
7 changes: 0 additions & 7 deletions main.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
@apply mb-2 gap-4;
label {
@apply text-right py-1 block;
@apply font-bold after:content-[':'];
}
}
}
Expand Down Expand Up @@ -138,15 +137,9 @@
td {
@apply px-2;
}
td {
@apply font-mono;
}
tr {
@apply mb-2;
}
tbody th {
@apply font-bold after:content-[':'];
}
}

.workout-tile-info {
Expand Down
40 changes: 32 additions & 8 deletions pkg/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,6 @@ import (

"github.com/vorlif/spreak"
"github.com/vorlif/spreak/humanize"
"github.com/vorlif/spreak/humanize/locale/nl"
)

const (
DefaultTheme = "browser"
DefaultLanguage = "browser"
)

type Version struct {
Expand Down Expand Up @@ -67,7 +61,7 @@ func (a *App) ConfigureLocalizer() error {
// Set the path from which the translations should be loaded
spreak.WithDomainFs(spreak.NoDomain, a.Translations),
// Specify the languages you want to load
spreak.WithLanguage(language.Dutch),
spreak.WithLanguage(translations()...),
)
if err != nil {
return err
Expand All @@ -76,12 +70,19 @@ func (a *App) ConfigureLocalizer() error {
a.translator = bundle

a.humanizer = humanize.MustNew(
humanize.WithLocale(nl.New()),
humanize.WithLocale(humanLocales()...),
)

return nil
}

func (a *App) Serve() error {
go a.BackgroundWorker()

a.logger.Info("Starting web server on " + a.Config.Bind)
return a.echo.Start(a.Config.Bind)
}

func (a *App) Configure() error {
if err := a.ReadConfiguration(); err != nil {
return err
Expand Down Expand Up @@ -169,3 +170,26 @@ func (a *App) createAdminUser() error {

return u.Create(a.db)
}

func (a *App) BackgroundWorker() {
l := a.logger.With("module", "worker")

for {
l.Info("Worker started...")

var w []database.Workout

if err := a.db.Where(&database.Workout{Dirty: true}).Limit(10).Find(&w).Error; err != nil {
l.Error("Worker error: " + err.Error())
}

for _, v := range w {
if err := v.UpdateData(a.db); err != nil {
l.Error("Worker error: " + err.Error())
}
}

l.Info("Worker finished...")
time.Sleep(time.Minute)
}
}
1 change: 1 addition & 0 deletions pkg/app/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func (a *App) addUserInfo(data map[string]interface{}, c echo.Context) {

data["currentUser"] = u
data["userProfileLanguage"] = u.Profile.Language
data["userProfileTheme"] = u.Profile.Theme
}

func (a *App) addWorkouts(u *database.User, data map[string]interface{}) error {
Expand Down
40 changes: 40 additions & 0 deletions pkg/app/i18n.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package app

import (
"github.com/vorlif/spreak/humanize"
"github.com/vorlif/spreak/humanize/locale/nl"
"golang.org/x/text/language"
)

var (
DefaultLanguage = "browser"

DefaultTheme = Theme{Name: "System default", Code: "browser", Icon: "🌐"}
DarkTheme = Theme{Name: "Dark theme", Code: "dark", Icon: "🌑"}
)

func translations() []interface{} {
return []interface{}{
language.English,
language.Dutch,
}
}

func humanLocales() []*humanize.LocaleData {
return []*humanize.LocaleData{
nl.New(),
}
}

func themes() []Theme {
return []Theme{
DefaultTheme,
DarkTheme,
}
}

type Theme struct {
Code string
Icon string
Name string
}
12 changes: 5 additions & 7 deletions pkg/app/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,11 @@ func (a *App) secureRoutes(e *echo.Group) *echo.Group {

secureGroup.GET("/", a.dashboardHandler).Name = "dashboard"
secureGroup.GET("/statistics", a.statisticsHandler).Name = "statistics"
secureGroup.GET("/user/profile", a.userProfileHandler).Name = "user-profile"
secureGroup.POST("/user/refresh", a.userRefreshHandler).Name = "user-refresh"

selfGroup := secureGroup.Group("/user")
selfGroup.GET("/profile", a.userProfileHandler).Name = "user-profile"
selfGroup.POST("/profile", a.userProfileUpdateHandler).Name = "user-profile-update"
selfGroup.POST("/refresh", a.userRefreshHandler).Name = "user-refresh"

usersGroup := secureGroup.Group("/users")
usersGroup.GET("/:id", a.userShowHandler).Name = "user-show"
Expand Down Expand Up @@ -155,8 +158,3 @@ func (a *App) adminRoutes(e *echo.Group) *echo.Group {

return adminGroup
}

func (a *App) Serve() error {
a.logger.Info("Starting web server on " + a.Config.Bind)
return a.echo.Start(a.Config.Bind)
}
45 changes: 45 additions & 0 deletions pkg/app/self_handlers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package app

import (
"net/http"

"github.com/jovandeginste/workout-tracker/pkg/database"
"github.com/labstack/echo/v4"
)

func (a *App) userProfileHandler(c echo.Context) error {
data := a.defaultData(c)
return c.Render(http.StatusOK, "user_profile.html", data)
}

func (a *App) userProfileUpdateHandler(c echo.Context) error {
u := a.getCurrentUser(c)
p := &database.Profile{}

if err := c.Bind(p); err != nil {
return a.redirectWithError(c, a.echo.Reverse("user-profile"), err)
}

u.Profile.Language = p.Language
u.Profile.Theme = p.Theme

if err := u.Profile.Save(a.db); err != nil {
return a.redirectWithError(c, a.echo.Reverse("user-profile"), err)
}

a.setNotice(c, "Profile updated")

return c.Redirect(http.StatusFound, a.echo.Reverse("user-profile"))
}

func (a *App) userRefreshHandler(c echo.Context) error {
u := a.getCurrentUser(c)

if err := u.MarkWorkoutsDirty(a.db); err != nil {
return a.redirectWithError(c, a.echo.Reverse("user-profile"), err)
}

a.setNotice(c, "All workouts will be refreshed in the coming minutes.")

return c.Redirect(http.StatusFound, a.echo.Reverse("user-profile"))
}
2 changes: 2 additions & 0 deletions pkg/app/tempates.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ func (a *App) viewTemplateFunctions() template.FuncMap {
"BoolToCheckbox": templatehelpers.BoolToCheckbox,
"BuildDecoratedAttribute": templatehelpers.BuildDecoratedAttribute,
"ToLanguageInformation": templatehelpers.ToLanguageInformation,
"supportedLanguaged": a.translator.SupportedLanguages,
"supportedThemes": themes,

"RelativeDate": h.NaturalTime,

Expand Down
28 changes: 1 addition & 27 deletions pkg/app/users_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func (a *App) userRegisterHandler(c echo.Context) error {
return a.redirectWithError(c, a.echo.Reverse("user-login"), fmt.Errorf("%w: %s", ErrInternalError, err))
}

u.Profile.Theme = DefaultLanguage
u.Profile.Theme = DefaultTheme.Code
u.Profile.Language = DefaultLanguage

if err := u.Create(a.db); err != nil {
Expand All @@ -80,32 +80,6 @@ func (a *App) userRegisterHandler(c echo.Context) error {
return c.Redirect(http.StatusFound, a.echo.Reverse("user-login"))
}

func (a *App) userProfileHandler(c echo.Context) error {
data := a.defaultData(c)
return c.Render(http.StatusOK, "user_profile.html", data)
}

func (a *App) userRefreshHandler(c echo.Context) error {
u := a.getCurrentUser(c)

workouts, err := u.GetWorkouts(a.db)
if err != nil {
return a.redirectWithError(c, a.echo.Reverse("user-signout"), err)
}

for _, w := range workouts {
a.logger.Debug("Refreshing workout: " + w.Name)

if err := w.UpdateData(a.db); err != nil {
return a.redirectWithError(c, a.echo.Reverse("user-signout"), err)
}
}

a.setNotice(c, "All workouts have been refreshed.")

return c.Redirect(http.StatusFound, a.echo.Reverse("user-profile"))
}

func (a *App) userShowHandler(c echo.Context) error {
data := a.defaultData(c)

Expand Down
12 changes: 9 additions & 3 deletions pkg/database/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,13 @@ func GetUser(db *gorm.DB, username string) (*User, error) {
type Profile struct {
gorm.Model
UserID int
Theme ThemePreference
Language string
Theme string `form:"theme"`
Language string `form:"language"`
}

type ThemePreference string
func (p *Profile) Save(db *gorm.DB) error {
return db.Save(p).Error
}

func (u *User) IsActive() bool {
if u == nil {
Expand Down Expand Up @@ -174,6 +176,10 @@ func (u *User) GetWorkout(db *gorm.DB, id int) (*Workout, error) {
return w, nil
}

func (u *User) MarkWorkoutsDirty(db *gorm.DB) error {
return db.Model(&Workout{}).Where(&Workout{UserID: u.ID}).Update("dirty", true).Error
}

func (u *User) GetWorkouts(db *gorm.DB) ([]*Workout, error) {
var w []*Workout

Expand Down
2 changes: 2 additions & 0 deletions pkg/database/workouts.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type Workout struct {
Name string `gorm:"nut null"`
Date *time.Time `gorm:"not null"`
UserID uint `gorm:"not null;index"`
Dirty bool
User *User
Notes string
Type string
Expand Down Expand Up @@ -94,6 +95,7 @@ func (w *Workout) UpdateData(db *gorm.DB) error {
}

w.Data = gpxAsMapData(gpxContent)
w.Dirty = false

return db.Save(w).Error
}
16 changes: 16 additions & 0 deletions views/partials/user_profile_language.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{{ define "user_profile_language" }} {{ $userLanguage := . }}
<select id="language" name="language">
{{ $selected := "" }} {{ if eq $userLanguage "browser" }} {{ $selected =
"selected" }}{{ end }}
<option value="browser" {{ $selected }}>🌐 Browser language</option>
{{ range supportedLanguages }} {{ $linf := .String | ToLanguageInformation }}
{{ $selected := "" }} {{ if eq $linf.Code $userLanguage }} {{ $selected =
"selected" }} {{ end }}
<option value="{{ $linf.Code }}" {{ $selected }}>
{{ $linf.Flag }} {{ $linf.LocalName }} {{ if ne $linf.EnglishName "" }} {{
if ne $linf.EnglishName $linf.LocalName }} ({{ $linf.EnglishName }}) {{ end
}}{{ end }}
</option>
{{ end }}
</select>
{{ end }}
8 changes: 8 additions & 0 deletions views/partials/user_profile_theme.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{{ define "user_profile_theme" }}{{ $userTheme := . }}
<select id="theme" name="theme">
{{ range supportedThemes }} {{ $selected := "" }} {{ if eq .Code $userTheme }}
{{ $selected = "selected" }} {{ end }}
<option value="{{ .Code }}" {{ $selected }}>{{ .Icon }} {{ .Name }}</option>
{{ end }}
</select>
{{ end }}
Loading

0 comments on commit 4018783

Please sign in to comment.