From 185d1456a67b44f951c0c42522e36591735f49c8 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Sat, 11 Oct 2025 21:38:01 -0600 Subject: [PATCH] added user photo upload page --- login.go | 4 +-- main.go | 1 + ui/render_wrap.go | 2 +- ui/views/dialog.jet | 3 +- ui/views/photo_upload.jet | 76 +++++++++++++++++++++++++++++++++++++++ userdata.go | 33 ++++++++++++++++- 6 files changed, 114 insertions(+), 5 deletions(-) create mode 100644 ui/views/photo_upload.jet diff --git a/login.go b/login.go index aed2bb9..fb95bfd 100644 --- a/login.go +++ b/login.go @@ -127,7 +127,7 @@ func Login(ctxt ui.AmContext) (string, any, error) { if user.VerifyEMail { return "redirect", target, nil } else { - return "redirect", "/verify?tgt=" + url.PathEscape(target), nil + return "redirect", "/verify?tgt=" + url.QueryEscape(target), nil } } return dlg.RenderError(ctxt, "No known button click on POST to login function.") @@ -393,7 +393,7 @@ func NewAccount(ctxt ui.AmContext) (string, any, error) { if err == nil { // user is now logged in! redirect to E-mail verification ctxt.ReplaceUser(user) - return "redirect", "/verify?tgt=" + url.PathEscape(target), nil + return "redirect", "/verify?tgt=" + url.QueryEscape(target), nil } } } diff --git a/main.go b/main.go index 858005f..72cef4e 100644 --- a/main.go +++ b/main.go @@ -54,6 +54,7 @@ func setupEcho() *echo.Echo { e.GET("/passrecovery/:uid/:auth", ui.AmWrap(PasswordRecovery)) e.GET("/profile", ui.AmWrap(EditProfileForm)) e.POST("/profile", ui.AmWrap(EditProfile)) + e.GET("/profile_photo", ui.AmWrap(ProfilePhotoForm)) return e } diff --git a/ui/render_wrap.go b/ui/render_wrap.go index 2a47e94..4f553e3 100644 --- a/ui/render_wrap.go +++ b/ui/render_wrap.go @@ -106,7 +106,7 @@ func AmWrap(myfunc func(AmContext) (string, any, error)) echo.HandlerFunc { if !user.VerifyEMail { // bounce to E-mail verification before we go anywhere return sendPageData(ctxt, amctxt, "redirect", - "/verify?tgt="+url.PathEscape(ctxt.Request().URL.Path)) + "/verify?tgt="+url.QueryEscape(ctxt.Request().URL.Path)) } } else { log.Errorf("login cookie bogus, do not use: %v", cerr) diff --git a/ui/views/dialog.jet b/ui/views/dialog.jet index bb73682..a50cc14 100644 --- a/ui/views/dialog.jet +++ b/ui/views/dialog.jet @@ -186,7 +186,8 @@ - + Click to upload photo diff --git a/ui/views/photo_upload.jet b/ui/views/photo_upload.jet new file mode 100644 index 0000000..7efa93d --- /dev/null +++ b/ui/views/photo_upload.jet @@ -0,0 +1,76 @@ +{* + * Amsterdam Web Communities System + * Copyright (c) 2025 Erbosoft Metaverse Design Solutions, All Rights Reserved + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + *} + +
+
+

Upload User Photo

+
+
+ + +
+ + +
+
+ +
+
+ Current user photo +
+

Current Photo

+
+ + +
+
+ + +

+ Recommended: Square images work best. Maximum file size: 2MB. Supported formats: JPG, PNG, GIF. +

+
+ + +
+ + + +
+
+
+ + +
+

Photo Guidelines:

+
    +
  • Your photo will be visible to other users in the community
  • +
  • Photos should be appropriate for a professional community setting
  • +
  • The image will be automatically resized to fit the profile display
  • +
  • You can update or remove your photo at any time
  • +
+
+
+
+
\ No newline at end of file diff --git a/userdata.go b/userdata.go index 21eb7e3..46e2dec 100644 --- a/userdata.go +++ b/userdata.go @@ -39,6 +39,7 @@ func EditProfileForm(ctxt ui.AmContext) (string, any, error) { dlg, err := ui.AmLoadDialog("profile") if err == nil { dlg.Field("tgt").Value = target + ctxt.VarMap().Set("target", target) var ci *database.ContactInfo ci, err = u.ContactInfo() if err == nil { @@ -93,6 +94,7 @@ func EditProfile(ctxt ui.AmContext) (string, any, error) { if target == "" { target = "/" } + ctxt.VarMap().Set("target", target) action := dlg.WhichButton(ctxt) if action == "cancel" { // Cancel button pressed @@ -162,7 +164,7 @@ func EditProfile(ctxt ui.AmContext) (string, any, error) { if emailChange { err = sendEmailConfirmationEmail(u, ci, ctxt.RemoteIP()) if err == nil { - return "redirect", "/verify?tgt=" + url.PathEscape(target), nil + return "redirect", "/verify?tgt=" + url.QueryEscape(target), nil } } else { return "redirect", target, nil @@ -174,3 +176,32 @@ func EditProfile(ctxt ui.AmContext) (string, any, error) { } return ui.ErrorPage(ctxt, err) } + +/* ProfilePhotoForm renders the Amsterdam profile photo upload form. + * Parameters: + * ctxt - The AmContext for the request. + * Returns: + * Command string dictating what to be rendered. + * Data as a parameter for the command string. + * Standard Go error status. + */ +func ProfilePhotoForm(ctxt ui.AmContext) (string, any, error) { + // Get target URI. + target := ctxt.Parameter("tgt") + if target == "" { + target = "/" + } + u := ctxt.CurrentUser() + if u.IsAnon { + return ui.ErrorPage(ctxt, errors.New("you are not logged in")) + } + ci, err := u.ContactInfo() + if err == nil { + _ = ci + ctxt.VarMap().Set("target", target) + ctxt.VarMap().Set("photo_url", "/img/builtin/no-user.png") + ctxt.VarMap().Set("amsterdam_pageTitle", "Upload User Photo") + return "framed_template", "photo_upload.jet", nil + } + return ui.ErrorPage(ctxt, err) +}