diff --git a/conferenceadmin.go b/conferenceadmin.go index 590aaa1..9ac1a44 100644 --- a/conferenceadmin.go +++ b/conferenceadmin.go @@ -377,6 +377,65 @@ func ConferenceMembers(ctxt ui.AmContext) (string, any) { return "framed", "conf_members.jet" } +/* ConfCustomForm displays the form for editing the conference's custom HTML blocks. + * Parameters: + * ctxt - The AmContext for the request. + * Returns: + * Command string dictating what to be rendered. + * Data as a parameter for the command string. + */ +func ConfCustomForm(ctxt ui.AmContext) (string, any) { + comm := ctxt.CurrentCommunity() + conf := ctxt.GetScratch("currentConference").(*database.Conference) + myLevel := ctxt.GetScratch("levelInConference").(uint16) + if !conf.TestPermission("Conference.Change", myLevel) { + return "error", ENOPERM + } + + topBlock, bottomBlock, err := conf.GetCustomBlocks(ctxt.Ctx()) + if err != nil { + return "error", err + } + + ctxt.VarMap().Set("confName", conf.Name) + ctxt.VarMap().Set("selfLink", fmt.Sprintf("/comm/%s/conf/%s/custom", comm.Alias, ctxt.GetScratch("currentAlias"))) + ctxt.VarMap().Set("topText", topBlock) + ctxt.VarMap().Set("bottomText", bottomBlock) + ctxt.SetFrameTitle(fmt.Sprintf("Customize Conference: %s", conf.Name)) + return "framed", "conf_custom.jet" +} + +/* ConfCustom modifies or removes the conference's custom HTML blocks. + * Parameters: + * ctxt - The AmContext for the request. + * Returns: + * Command string dictating what to be rendered. + * Data as a parameter for the command string. + */ +func ConfCustom(ctxt ui.AmContext) (string, any) { + comm := ctxt.CurrentCommunity() + conf := ctxt.GetScratch("currentConference").(*database.Conference) + myLevel := ctxt.GetScratch("levelInConference").(uint16) + if !conf.TestPermission("Conference.Change", myLevel) { + return "error", ENOPERM + } + + var err error + if ctxt.FormFieldIsSet("cancel") { + err = nil + } else if ctxt.FormFieldIsSet("remove") { + err = conf.RemoveCustomBlocks(ctxt.Ctx()) + } else if ctxt.FormFieldIsSet("update") { + err = conf.SetCustomBlocks(ctxt.Ctx(), ctxt.FormField("tx"), ctxt.FormField("bx")) + } else { + return "error", EBUTTON + } + if err != nil { + return "error", err + } + return "redirect", fmt.Sprintf("/comm/%s/conf/%s/manage", comm.Alias, ctxt.GetScratch("currentAlias")) +} + /* CreateConferenceForm displays the dialog for creating a new conference. * Parameters: * ctxt - The AmContext for the request. diff --git a/database/conference.go b/database/conference.go index 4249f14..d6a1250 100644 --- a/database/conference.go +++ b/database/conference.go @@ -624,6 +624,56 @@ func (c *Conference) Fixseen(ctx context.Context, u *User) error { return nil } +// GetCustomBlocks gets the custom HTML blocks for the conference. +func (c *Conference) GetCustomBlocks(ctx context.Context) (string, string, error) { + row := amdb.QueryRowContext(ctx, "SELECT htmltop, htmlbottom FROM confcustom WHERE confid = ?", c.ConfId) + var topBlock, bottomBlock string + err := row.Scan(&topBlock, &bottomBlock) + switch err { + case nil: + return topBlock, bottomBlock, nil + case sql.ErrNoRows: + err = nil + } + return "", "", err +} + +// SetCustomBlocks sets the custom HTML blocks for this conference. +func (c *Conference) SetCustomBlocks(ctx context.Context, topBlock, bottomBlock string) error { + success := false + tx := amdb.MustBegin() + defer func() { + if !success { + tx.Rollback() + } + }() + row := tx.QueryRowContext(ctx, "SELECT COUNT(*) FROM confcustom WHERE confid = ?", c.ConfId) + ct := 0 + err := row.Scan(&ct) + if err != nil { + return err + } + if ct == 0 { + _, err = tx.ExecContext(ctx, "INSERT INTO confcustom (confid, htmltop, htmlbottom) VALUES (?, ?, ?)", c.ConfId, topBlock, bottomBlock) + } else { + _, err = tx.ExecContext(ctx, "UPDATE confcustom SET htmltop = ?, htmlbottom = ? WHERE confid = ?", topBlock, bottomBlock, c.ConfId) + } + if err != nil { + return err + } + if err = tx.Commit(); err != nil { + return err + } + success = true + return nil +} + +// RemoveCustomBlocks removes the custom HTML blocks from this conference. +func (c *Conference) RemoveCustomBlocks(ctx context.Context) error { + _, err := amdb.ExecContext(ctx, "DELETE FROM confcustom WHERE confid = ?", c.ConfId) + return err +} + /* AmGetConference returns a conference given its ID. * Parameters: * ctx - Standard Go context value. diff --git a/main.go b/main.go index e8750c8..9e3f978 100644 --- a/main.go +++ b/main.go @@ -119,6 +119,8 @@ func setupEcho() *echo.Echo { fn = ui.AmWrap(ConferenceMembers) confGroup.GET("/members", fn) confGroup.POST("/members", fn) + confGroup.GET("/custom", ui.AmWrap(ConfCustomForm)) + confGroup.POST("/custom", ui.AmWrap(ConfCustom)) confGroup.GET("/hotlist", ui.AmWrap(AddToHotlist)) confGroup.GET("/invite", ui.AmWrap(InviteToConference)) confGroup.GET("/r/:topic", ui.AmWrap(ReadPosts), ui.SetTopic) diff --git a/ui/menudefs.yaml b/ui/menudefs.yaml index 7840ea0..f64d595 100644 --- a/ui/menudefs.yaml +++ b/ui/menudefs.yaml @@ -98,7 +98,7 @@ menudefs: - text: "Manage Conference Members" link: "/comm/[CID]/conf/[CONFID]/members" - text: "Customize Conference Appearance" - link: "/TODO/comm/[CID]/conf/[CONFID]/custom" + link: "/comm/[CID]/conf/[CONFID]/custom" - text: "Conference Activity Reports" link: "/TODO/comm/[CID]/conf/[CONFID]/activity" - text: "Conference E-Mail" diff --git a/ui/views/conf_custom.jet b/ui/views/conf_custom.jet new file mode 100644 index 0000000..87e57c6 --- /dev/null +++ b/ui/views/conf_custom.jet @@ -0,0 +1,88 @@ +{* + * Amsterdam Web Communities System + * Copyright (c) 2025-2026 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/. + *} +