Skip to content

Commit

Permalink
feat(settings): add settings edit modal and backend logic
Browse files Browse the repository at this point in the history
  • Loading branch information
scottmckendry committed Aug 22, 2024
1 parent 08b2c14 commit 6e1a77b
Show file tree
Hide file tree
Showing 9 changed files with 302 additions and 1 deletion.
26 changes: 26 additions & 0 deletions data/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,29 @@ func (s *Storage) getGenericSettings(email string, settings *UserSettings) *User

return settings
}

func (s *Storage) UpdateUserSettings(email string, settings *UserSettings) error {
settingsMap := map[string]interface{}{
"SearchEngine": settings.SearchEngine,
"LeaderKey": settings.LeaderKey,
}

for settingKey, settingValue := range settingsMap {
_, err := s.db.Exec(
`INSERT OR REPLACE INTO user_settings (user_id, setting_key, setting_value)
VALUES (
(SELECT id FROM users WHERE email = ?),
?,
?
)`,
email,
settingKey,
settingValue,
)
if err != nil {
return err
}
}

return nil
}
41 changes: 41 additions & 0 deletions handlers/settings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package handlers

import (
"log"
"net/http"

"github.com/scottmckendry/mnemstart/views"
)

func (h *Handler) HandleSettings(w http.ResponseWriter, r *http.Request) {
user, err := h.auth.GetSessionUser(r)
if err != nil {
log.Println(err)
return
}

userSettings := h.store.GetUserSettings(user.Email)
views.Settings(user, userSettings).Render(r.Context(), w)
}

func (h *Handler) HandleSettingsUpdate(w http.ResponseWriter, r *http.Request) {
user, err := h.auth.GetSessionUser(r)
if err != nil {
log.Println(err)
return
}

err = r.ParseForm()
if err != nil {
log.Println(err)
return
}

userSettings := h.store.GetUserSettings(user.Email)
userSettings.LeaderKey = r.FormValue("leaderKey")
userSettings.SearchEngine = r.FormValue("searchEngine")
h.store.UpdateUserSettings(user.Email, userSettings)

w.Header().Set("HX-Refresh", "true")
views.Home(user, userSettings).Render(r.Context(), w)
}
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ func main() {

// app routes
r.HandleFunc("/", auth.RequireAuth(handler.HandleRoot, authService))
r.HandleFunc("/settings", auth.RequireAuth(handler.HandleSettings, authService))
r.HandleFunc("/update-settings", auth.RequireAuth(handler.HandleSettingsUpdate, authService))

// auth
r.HandleFunc("/auth/{provider}", handler.HandleProviderLogin)
Expand Down
111 changes: 111 additions & 0 deletions public/modal.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#modal {
/* Underlay covers entire screen. */
position: fixed;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
background-color: rgba(0, 0, 0, 0.5);
z-index: 1000;

/* Flexbox centers the .modal-content vertically and horizontally */
display: flex;
flex-direction: column;
align-items: center;

/* Animate when opening */
animation-name: fadeIn;
animation-duration: 150ms;
animation-timing-function: ease;
}

#modal > .modal-underlay {
/* underlay takes up the entire viewport. This is only
required if you want to click to dismiss the popup */
position: absolute;
z-index: -1;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
}

#modal > .modal-content {
/* Position visible dialog near the top of the window */
margin-top: 10vh;

/* Sizing for visible dialog */
width: 80%;
max-width: 600px;

/* Display properties for visible dialog*/
border: solid 1px #999;
border-radius: 8px;
box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.3);
background-color: #323130;
padding: 20px;

/* Animate when opening */
animation-name: zoomIn;
animation-duration: 150ms;
animation-timing-function: ease;
}

#modal.closing {
/* Animate when closing */
animation-name: fadeOut;
animation-duration: 150ms;
animation-timing-function: ease;
}

#modal.closing > .modal-content {
/* Animate when closing */
animation-name: zoomOut;
animation-duration: 150ms;
animation-timing-function: ease;
}

#modal input[type="text"] {
width: 95%;
padding: 5px;
font-size: 16px;
margin-bottom: 10px;
border: 1px solid #fff;
border-radius: 5px;
}

@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

@keyframes fadeOut {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}

@keyframes zoomIn {
0% {
transform: scale(0.9);
}
100% {
transform: scale(1);
}
}

@keyframes zoomOut {
0% {
transform: scale(1);
}
100% {
transform: scale(0.9);
}
}
1 change: 1 addition & 0 deletions public/styles.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@import "./reset.css";
@import "./modal.css";

body {
font-family: "Roboto", sans-serif;
Expand Down
2 changes: 2 additions & 0 deletions views/page.templ
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ templ Page(nav bool, user goth.User) {
<link rel="stylesheet" href="/public/styles.css"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"/>
<script src="https://unpkg.com/htmx.org@2.0.2"></script>
<script src="https://unpkg.com/hyperscript.org@0.9.12"></script>
</head>
<body>
<button hx-get="/settings" hx-target="body" hx-swap="beforeend">Settings</button>
{ children... }
if nav {
<footer>
Expand Down
2 changes: 1 addition & 1 deletion views/page_templ.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions views/settings.templ
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package views

import (
"github.com/markbates/goth"
"github.com/scottmckendry/mnemstart/data"
)

templ Settings(user goth.User, settings *data.UserSettings) {
<div id="modal" _="on closeModal add .closing then wait for animationend then remove me">
<div class="modal-underlay" _="on click trigger closeModal"></div>
<div class="modal-content">
<h2>Settings</h2>
/*
<table id="mappings-table">
<thead>
<tr>
<th>Keymap</th>
<th>URL</th>
<th></th>
</tr>
</thead>
<tbody>
for keymap, url := range settings.Mappings {
<tr>
<td>{ keymap }</td>
<td>{ url }</td>
<td>
<button class="button" hx-delete={ "/delete-mapping/" + keymap } hx-swap="#mappings-table">Delete</button>
</td>
</tr>
}
<tr>
<td><input type="text" name="keymap" placeholder="Keymap" mapping-include-edit=""/></td>
<td><input type="text" name="url" placeholder="URL" mapping-include-edit=""/></td>
<td>
<button class="button" _="on click trigger addMapping" hx-put="/add-mapping" hx-include="input[mapping-include-edit]" hx-swap="#mappings-table">Add</button>
</td>
</tr>
</tbody>
</table>
*/
<label for="leaderKey">Leader Key</label>
<input type="text" name="leaderKey" value={ settings.LeaderKey } placeholder="Leader Key" data-include-edit=""/>
<label for="searchEngine">Search Engine</label>
<input type="text" name="searchEngine" value={ settings.SearchEngine } placeholder="Search Engine" data-include-edit=""/>
<div class="action-buttons">
<button class="button" _="on click trigger closeModal" hx-put="/update-settings" hx-include="input[data-include-edit]">Save</button>
<button class="button" _="on click trigger closeModal">Cancel</button>
</div>
</div>
</div>
}
66 changes: 66 additions & 0 deletions views/settings_templ.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6e1a77b

Please sign in to comment.