From 6eec9f77d9961738324d6c151f95eef791fd311b Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Fri, 10 Oct 2025 21:26:01 -0600 Subject: [PATCH] beginnings of the Edit Profile page, dialog field and rendering additions --- main.go | 1 + ui/dialog.go | 16 ++- ui/dialogs/profile.yaml | 200 +++++++++++++++++++++++++++++++++++ ui/session_mgr.go | 2 - ui/static_images/no-user.png | Bin 0 -> 7200 bytes ui/views/dialog.jet | 35 +++++- ui/views/frame.jet | 2 +- userdata.go | 43 ++++++++ 8 files changed, 290 insertions(+), 9 deletions(-) create mode 100644 ui/dialogs/profile.yaml create mode 100644 ui/static_images/no-user.png create mode 100644 userdata.go diff --git a/main.go b/main.go index cf3e351..03a2251 100644 --- a/main.go +++ b/main.go @@ -52,6 +52,7 @@ func setupEcho() *echo.Echo { e.GET("/verify", ui.AmWrap(VerifyEmailForm)) e.POST("/verify", ui.AmWrap(VerifyEMail)) e.GET("/passrecovery/:uid/:auth", ui.AmWrap(PasswordRecovery)) + e.GET("/profile", ui.AmWrap(EditProfileForm)) return e } diff --git a/ui/dialog.go b/ui/dialog.go index 4577401..3104df0 100644 --- a/ui/dialog.go +++ b/ui/dialog.go @@ -218,11 +218,12 @@ func (d *Dialog) RenderInfo(ctxt AmContext, infoMessage string) (string, any, er func (d *Dialog) LoadFromForm(ctxt AmContext) { for i, fld := range d.Fields { d.Fields[i].Value = "" - if fld.Type == "header" || fld.Type == "button" { + switch fld.Type { + case "header": continue - } - if fld.Type == "date" { - d.Fields[i].Value = "" + case "button": + continue + case "date": dvals := make([]int, 3) var err error dvals[0], err = ctxt.FormFieldInt(fmt.Sprintf("%s_month", fld.Name)) @@ -256,7 +257,9 @@ func (d *Dialog) LoadFromForm(ctxt AmContext) { } } d.Fields[i].AuxData = dvals - } else { + case "userphoto": + d.Fields[i].Value = ctxt.FormField(fmt.Sprintf("%s_data", fld.Name)) + default: d.Fields[i].Value = ctxt.FormField(fld.Name) } } @@ -419,8 +422,11 @@ var validators = map[string]validatorFunc{ "header": nilValidator, "hidden": nilValidator, "integer": validateIntegerField, + "localelist": nilValidator, // TODO "password": validateTextField, "text": validateTextField, + "tzlist": nilValidator, // TODO + "userphoto": nilValidator, } /* Validate validates the values in the dialog. diff --git a/ui/dialogs/profile.yaml b/ui/dialogs/profile.yaml new file mode 100644 index 0000000..2425ad6 --- /dev/null +++ b/ui/dialogs/profile.yaml @@ -0,0 +1,200 @@ +# +# 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/. +# +name: "profile" +formName: "profform" +menuSelector: "nochange" +title: "Edit Your Profile" +action: "/profile" +fields: + - type: "hidden" + name: "tgt" + value: "" + - type: "header" + name: "header1" + caption: "Name" + subcaption: "To change your password, enter a new password into the fields below." + - type: "password" + name: "pass1" + caption: "Password" + required: true + size: 32 + maxlength: 128 + - type: "password" + name: "pass2" + caption: "Password" + subcaption: "(retype)" + required: true + size: 32 + maxlength: 128 + - type: "text" + name: "remind" + caption: "Password reminder phrase" + size: 32 + maxlength: 255 + - type: "header" + name: "header2" + caption: "Name" + - type: "text" + name: "prefix" + caption: "Prefix" + subcaption: "(Mr., Ms., etc.)" + size: 8 + maxlength: 8 + - type: "text" + name: "first" + caption: "First Name" + required: true + size: 32 + maxlength: 64 + - type: "text" + name: "mid" + caption: "Middle Initial" + size: 1 + maxlength: 1 + - type: "text" + name: "last" + caption: "Last Name" + required: true + size: 32 + maxlength: 64 + - type: "text" + name: "suffix" + caption: "Suffix" + subcaption: "(Jr., III, etc.)" + size: 8 + maxlength: 8 + - type: "header" + name: "header3" + caption: "Location" + - type: "text" + name: "company" + caption: "Company" + size: 32 + maxlength: 255 + - type: "text" + name: "addr1" + caption: "Address" + size: 32 + maxlength: 255 + - type: "text" + name: "addr2" + caption: "Address" + subcaption: "(line 2)" + size: 32 + maxlength: 255 + - type: "checkbox" + name: "pvt_addr" + caption: "Hide address in profile" + - type: "text" + name: "loc" + caption: "City" + required: true + size: 32 + maxlength: 64 + - type: "text" + name: "reg" + caption: "State/Province" + required: true + size: 32 + maxlength: 64 + - type: "text" + name: "pcode" + caption: "Zip/Postal Code" + required: true + size: 32 + maxlength: 64 + - type: "countrylist" + name: "country" + caption: "Country" + required: true + - type: "header" + name: "header4" + caption: "Phone Numbers" + - type: "text" + name: "phone" + caption: "Telephone" + size: 32 + maxlength: 32 + - type: "text" + name: "mobile" + caption: "Mobile/cellphone" + size: 32 + maxlength: 32 + - type: "checkbox" + name: "pvt_phone" + caption: "Hide phone/mobile numbers in profile" + - type: "text" + name: "fax" + caption: "Fax" + size: 32 + maxlength: 32 + - type: "checkbox" + name: "pvt_fax" + caption: "Hide fax number in profile" + - type: "header" + name: "header5" + caption: "Internet" + - type: "email" + name: "email" + caption: "E-Mail Address" + required: true + size: 32 + maxlength: 255 + - type: "checkbox" + name: "pvt_email" + caption: "Hide E-mail address in profile" + - type: "text" + name: "url" + caption: "Home Page" + subcaption: "(URL)" + size: 32 + maxlength: 255 + - type: "header" + name: "header6" + caption: "Personal" + - type: "date" + name: "dob" + caption: "Date of Birth" + param: "year:-100" + - type: "text" + name: "descr" + caption: "Personal description" + size: 32 + maxlength: 255 + - type: "userphoto" + name: "photo" + caption: "User Photo" + param: "/profile_photo" + - type: "header" + name: "header7" + caption: "User Preferences" + - type: "checkbox" + name: "pic_in_post" + caption: "Display user photos next to conference posts" + subcaption: "(where applicable)" + - type: "checkbox" + name: "no_mass_mail" + caption: "Don't send me mass E-mail from community/conference hosts" + - type: "localelist" + name: "locale" + caption: "Default locale" + subcaption: "(for formatting dates/times)" + required: true + - type: "tzlist" + name: "tz" + caption: "Default time zone" + required: true + - type: "button" + name: "update" + caption: "Update" + param: "blue" + - type: "button" + name: "cancel" + caption: "Cancel" + param: "red" diff --git a/ui/session_mgr.go b/ui/session_mgr.go index 107bf4c..5da2c02 100644 --- a/ui/session_mgr.go +++ b/ui/session_mgr.go @@ -103,8 +103,6 @@ func (st *AmsterdamStore) New(r *http.Request, name string) (*sessions.Session, * Standard Go error status. */ func (st *AmsterdamStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error { - st.mutex.Lock() - defer st.mutex.Unlock() cookie := sessions.NewCookie(session.Name(), session.ID, session.Options) http.SetCookie(w, cookie) return nil diff --git a/ui/static_images/no-user.png b/ui/static_images/no-user.png new file mode 100644 index 0000000000000000000000000000000000000000..29921c07f31243b884562ebce4eb000f76fc2fb3 GIT binary patch literal 7200 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 fHI
+ value="Y" {{ if .Value != "" }}checked{{ end }} + class="w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" />