diff --git a/handlers/dev/md.bahan.handlers.go b/handlers/dev/md.bahan.handlers.go index 6ac26a0..9f6147d 100644 --- a/handlers/dev/md.bahan.handlers.go +++ b/handlers/dev/md.bahan.handlers.go @@ -5,11 +5,13 @@ import ( navbarmenu "cpone/component/navbar" "cpone/component/pagination" sidebaruserprofile "cpone/component/sidebar_user_profile" + customtoastv2 "cpone/component/toastbootstrap" "cpone/models" "cpone/services" "cpone/utils" dev_mdbahanview "cpone/views/dev/mdbahan" "strconv" + "strings" "github.com/a-h/templ" "github.com/labstack/echo/v4" @@ -23,7 +25,11 @@ type MdBahanServices interface { currentPage int, rowPerPage int) ([]models.Bahan, int, error) GetMdBahanBreadCrumb(title string) (models.BreadCrumbV1, error) - GetListSampleStation() ([]models.TmpSampleStation, error) + GetListSampleStation(isFilter bool) ([]models.TmpSampleStation, error) + AddMdBahan(code string, name string, stationid string) (bool, error) + EditMdBahan(id string, code string, name string, stationid string) (bool, error) + GetMdBahanByID(id string) (models.Bahan, error) + DeleteMdBahan(id string) (bool, error) } func NewMdBahanHandler(us MdBahanServices) *MdBahanHandler { @@ -41,6 +47,13 @@ func (lh *MdBahanHandler) HandleShowMdBahanScreen(c echo.Context) error { dataMenu, err := services.GetMenu() paginationID := utils.GenerateRandomID("paginationID") + modalAddID := utils.GenerateRandomID("modalAdd") + modalAddBodyID := utils.GenerateRandomID("modalAddbody") + modalEditID := utils.GenerateRandomID("modalEdit") + modalEditBodyID := utils.GenerateRandomID("modalEditbody") + modalDeleteID := utils.GenerateRandomID("modalDelete") + modalDeleteBodyID := utils.GenerateRandomID("modalDeletebody") + tableBahanID := utils.GenerateRandomID("BahanID") if err != nil { defer logger.Sync() @@ -80,36 +93,47 @@ func (lh *MdBahanHandler) HandleShowMdBahanScreen(c echo.Context) error { // sidebar sidebaruserprofileComponent := sidebaruserprofile.Navbaruserprofile(dataUser) - bahanList, totalPage, err := lh.MdBahanServices.GetListMdBahan("", "1", 1, 5) + bahanList, totalPage, err := lh.MdBahanServices.GetListMdBahan("", "0", 1, 5) defer logger.Sync() logger.Info("GET DATA BAHAN", zap.Any("data", bahanList), zap.Any("err", err), zap.Any("totalPage", totalPage), ) - stationList, err := lh.MdBahanServices.GetListSampleStation() + stationListFilter, err := lh.MdBahanServices.GetListSampleStation(true) defer logger.Sync() - logger.Info("GET DATA BAHAN", - zap.Any("data", bahanList), + logger.Info("GET STATION LIST Filter", + zap.Any("err", err), + ) + stationList, err := lh.MdBahanServices.GetListSampleStation(false) + defer logger.Sync() + logger.Info("GET STATION LIST ", zap.Any("err", err), - zap.Any("totalPage", totalPage), ) //Bahan Table - tableBahanID := utils.GenerateRandomID("BahanID") + // #dialogDeleteBodyID, #dialogDeleteID mdBahanTable := dev_mdbahanview.TableBahan( bahanList, - tableBahanID, "getedt", "trgtEdit", "swpEdit", "imcldEdit", "getDlt", "trgtDlt", "swpDlt", "imcldDlt") + tableBahanID, + "/dev/md/bahan/openedit", + "#"+modalEditBodyID, + "outerHTML", + "#dialogEditBodyID, #dialogEditID, #dialogDeleteBodyID, #dialogDeleteID", + "/dev/md/bahan/opendelete", + "#"+modalDeleteBodyID, + "outerHTML", + "#dialogDeleteBodyID, #dialogDeleteID, #dialogEditBodyID, #dialogEditID") //FIlter table mdBahanFilter := dev_mdbahanview.MdBahanFilter( "/dev/md/bahan/filter", "input changed delay:500ms", - "#filter-name, #filter-station, #tableID, #paginationID", + "#filter-name, #filter-station, #tableID, #paginationID, #dialogAddID, #dialogAddBodyID, #dialogEditID, #dialogEditBodyID, #dialogDeleteBodyID, #dialogDeleteID, #currpage"+paginationID, "outerHTML", "#"+paginationID, - stationList, - stationList[0].T_SampleStationID, + stationListFilter, + stationListFilter[0].T_SampleStationID, dev_mdbahanview.BeforeRequestContent(), dev_mdbahanview.AfterRequestContent(), ) @@ -120,7 +144,7 @@ func (lh *MdBahanHandler) HandleShowMdBahanScreen(c echo.Context) error { totalPage, 1, "/dev/md/bahan/pagination", paginationID, - "#filter-name, #filter-station, #tableID, #paginationID, #currpage"+paginationID, + "#filter-name, #filter-station, #tableID, #paginationID, #dialogAddID, #dialogAddBodyID, #dialogEditID, #dialogEditBodyID, #dialogDeleteBodyID, #dialogDeleteID, #currpage"+paginationID, "#"+paginationID, "outerHTML", "", @@ -128,8 +152,112 @@ func (lh *MdBahanHandler) HandleShowMdBahanScreen(c echo.Context) error { dev_mdbahanview.BeforeRequestContent(), dev_mdbahanview.AfterRequestContent(), ) + //Form Add + modalAddBody := dev_mdbahanview.BodyFormBahan( + "", + models.CustomTextFieldv2Prm{Label: "Kode Bahan", + Name: "kodebahan", + Placeholder: "Kode Bahan", + Type: "text"}, + models.CustomTextFieldv2Prm{Label: "Nama Bahan", + Name: "namabahan", + Placeholder: "Nama Bahan", + Type: "text"}, + models.CustomDropdownV2Prm{ + Name: "stationid", + Label: "Sample Station", + ListItem: dev_mdbahanview.ListItemStation(stationList, 0), + }, + modalAddBodyID, + dev_mdbahanview.JsShowModal(""), + ) + modalAddAction := dev_mdbahanview.ActionFormBahan("/dev/md/bahan/closeaddform", "#"+modalAddBodyID, "outerHTML", "#"+modalAddID) + modalAddBtnCls := dev_mdbahanview.BtnCloseFormBahan("/dev/md/bahan/closeaddform", "#"+modalAddBodyID, "outerHTML", "#"+modalAddID) + modalAddBahan := dev_mdbahanview.BahanForm(models.BahanFormComponent{ + IDComponent: "", + Link: "/dev/md/bahan/add", + HxTarget: "#" + modalAddBodyID, + HxSwap: "outerHTML", + HxInclude: "#filter-name, #filter-station, #tableID, #paginationID, #dialogAddID, #dialogAddBodyID, #dialogEditID, #dialogEditBodyID, #dialogDeleteBodyID, #dialogDeleteID, #currpage" + paginationID, + ModalID: modalAddID, + ModalTitle: "New-Bahan", + DialogBody: modalAddBody, + DialogAction: modalAddAction, + ButtonCLose: modalAddBtnCls, + }) - mdBahanScreen := dev_mdbahanview.MdBahanScreen(tableBahanID, paginationID, breadcrumbComponent, mdBahanTable, mdBahanFilter, mdbahanPagination) + //Form Edit + modalEditBody := dev_mdbahanview.BodyFormBahan( + "", + models.CustomTextFieldv2Prm{Label: "Kode Bahan", + Name: "kodebahan", + Placeholder: "Kode Bahan", + Type: "text"}, + models.CustomTextFieldv2Prm{Label: "Nama Bahan", + Name: "namabahan", + Placeholder: "Nama Bahan", + Type: "text"}, + models.CustomDropdownV2Prm{ + Name: "stationid", + Label: "Sample Station", + ListItem: dev_mdbahanview.ListItemStation(stationList, 0), + }, + modalEditBodyID, + dev_mdbahanview.JsShowModal(""), + ) + modalEditAction := dev_mdbahanview.ActionFormBahan("/dev/md/bahan/closeeditform", "#"+modalEditBodyID, "outerHTML", "#"+modalEditID) + modalEditBtnCls := dev_mdbahanview.BtnCloseFormBahan("/dev/md/bahan/closeeditform", "#"+modalEditBodyID, "outerHTML", "#"+modalEditID) + modalEditBahan := dev_mdbahanview.BahanForm(models.BahanFormComponent{ + IDComponent: "", + Link: "/dev/md/bahan/edit", + HxTarget: "#" + modalEditBodyID, + HxSwap: "outerHTML", + HxInclude: "#filter-name, #filter-station, #tableID, #paginationID, #dialogEditID, #dialogEditBodyID, #dialogDeleteBodyID, #dialogDeleteID, #currpage" + paginationID, + ModalID: modalEditID, + ModalTitle: "Edit-Bahan", + DialogBody: modalEditBody, + DialogAction: modalEditAction, + ButtonCLose: modalEditBtnCls, + }) + + //Form Delete + modalDeleteBody := dev_mdbahanview.DeleteConfirmationBody( + "", + modalDeleteBodyID, + "Apakah anda yakin menghapus bahan berikut ?", + []string{"Kode", "Nama Bahan", "Sample Station"}, + []string{"", "", ""}, dev_mdbahanview.JsShowModal("")) + modalDeleteAction := dev_mdbahanview.ActionFormBahanDelete("/dev/md/bahan/closedeleteform", "#"+modalDeleteBodyID, "outerHTML", "#"+modalDeleteID) + modalDeleteBtnCls := dev_mdbahanview.BtnCloseFormBahan("/dev/md/bahan/closedeleteform", "#"+modalDeleteBodyID, "outerHTML", "#"+modalDeleteID) + modalDeleteBahan := dev_mdbahanview.BahanForm(models.BahanFormComponent{ + IDComponent: "", + Link: "/dev/md/bahan/delete", + HxTarget: "#" + modalDeleteBodyID, + HxSwap: "outerHTML", + HxInclude: "#filter-name, #filter-station, #tableID, #paginationID, #dialogEditID, #dialogEditBodyID, #dialogDeleteBodyID, #dialogDeleteID, #currpage" + paginationID, + ModalID: modalDeleteID, + ModalTitle: "Delete-Bahan", + DialogBody: modalDeleteBody, + DialogAction: modalDeleteAction, + ButtonCLose: modalDeleteBtnCls, + }) + + mdBahanScreen := dev_mdbahanview.MdBahanScreen( + tableBahanID, + paginationID, + modalAddID, + modalAddBodyID, + modalEditID, + modalEditBodyID, + modalDeleteID, + modalDeleteBodyID, + breadcrumbComponent, + mdBahanTable, + mdBahanFilter, + mdbahanPagination, + modalAddBahan, + modalEditBahan, + modalDeleteBahan) cssMdBahan := dev_mdbahanview.CssMdUserGroup() jsMdBahan := dev_mdbahanview.JsMdBahan() @@ -149,6 +277,8 @@ func (lh *MdBahanHandler) HandleFilterMdBahan(c echo.Context) error { var retval []templ.Component filtername := c.QueryParam("filtername") filterstation := c.QueryParam("filterstation") + dialogEditBodyID := c.QueryParam("dialogEditBodyID") + dialogDeleteBodyID := c.QueryParam("dialogDeleteBodyID") tableID := c.QueryParam("tableID") paginationID := c.QueryParam("paginationID") bahanList, totalPage, err := lh.MdBahanServices.GetListMdBahan(filtername, filterstation, 1, 5) @@ -162,14 +292,22 @@ func (lh *MdBahanHandler) HandleFilterMdBahan(c echo.Context) error { mdBahanTable := dev_mdbahanview.TableBahan( bahanList, - tableID, "getedt", "trgtEdit", "swpEdit", "imcldEdit", "getDlt", "trgtDlt", "swpDlt", "imcldDlt") + tableID, + "/dev/md/bahan/openedit", + "#"+dialogEditBodyID, + "outerHTML", + "#dialogEditBodyID, #dialogEditID, #dialogDeleteBodyID, #dialogDeleteID", + "/dev/md/bahan/opendelete", + "#"+dialogDeleteBodyID, + "outerHTML", + "#dialogEditBodyID, #dialogEditID, #dialogDeleteBodyID, #dialogDeleteID") //Pagination mdbahanPagination := pagination.PaginationV3( totalPage, 1, "/dev/md/bahan/pagination", paginationID, - "#filter-name, #filter-station, #tableID, #paginationID, #currpage"+paginationID, + "#filter-name, #filter-station, #tableID, #paginationID, #dialogAddID, #dialogAddBodyID, #dialogEditID, #dialogEditBodyID, #dialogDeleteBodyID, #dialogDeleteID, #currpage"+paginationID, "#"+paginationID, "outerHTML", "", @@ -189,6 +327,8 @@ func (lh *MdBahanHandler) HandlePaginationMdBahan(c echo.Context) error { filtername := c.QueryParam("filtername") filterstation := c.QueryParam("filterstation") tableID := c.QueryParam("tableID") + dialogEditBodyID := c.QueryParam("dialogEditBodyID") + dialogDeleteBodyID := c.QueryParam("dialogDeleteBodyID") paginationID := c.QueryParam("paginationID") page, err := strconv.Atoi(pageparam) if err != nil { @@ -210,14 +350,22 @@ func (lh *MdBahanHandler) HandlePaginationMdBahan(c echo.Context) error { mdBahanTable := dev_mdbahanview.TableBahan( bahanList, - tableID, "getedt", "trgtEdit", "swpEdit", "imcldEdit", "getDlt", "trgtDlt", "swpDlt", "imcldDlt") + tableID, + "/dev/md/bahan/openedit", + "#"+dialogEditBodyID, + "outerHTML", + "#dialogEditBodyID, #dialogEditID, #dialogDeleteBodyID, #dialogDeleteID", + "/dev/md/bahan/opendelete", + "#"+dialogDeleteBodyID, + "outerHTML", + "#dialogEditBodyID, #dialogEditID, #dialogDeleteBodyID, #dialogDeleteID") //Pagination mdbahanPagination := pagination.PaginationV3( totalPage, page, "/dev/md/bahan/pagination", paginationID, - "#filter-name, #filter-station, #tableID, #paginationID, #currpage"+paginationID, + "#filter-name, #filter-station, #tableID, #paginationID, #dialogAddID, #dialogAddBodyID, #dialogEditID, #dialogEditBodyID, #dialogDeleteBodyID, #dialogDeleteID, #currpage"+paginationID, "#"+paginationID, "outerHTML", "", @@ -229,3 +377,578 @@ func (lh *MdBahanHandler) HandlePaginationMdBahan(c echo.Context) error { retval = append(retval, mdbahanPagination) return utils.ViewMulti(c, retval) } +func (lh *MdBahanHandler) HandleCloseFormAddMdBahan(c echo.Context) error { + logger, _ := zap.NewProduction() + stationList, err := lh.MdBahanServices.GetListSampleStation(false) + defer logger.Sync() + logger.Info("GET DATA STATIOn", + zap.Any("err", err), + ) + dialogAddBodyID := c.FormValue("dialogAddBodyID") + dialogAddID := c.FormValue("dialogAddID") + + modalAddBody := dev_mdbahanview.BodyFormBahan( + "", + models.CustomTextFieldv2Prm{Label: "Kode Bahan", + Name: "kodebahan", + Placeholder: "Kode Bahan", + Type: "text"}, + models.CustomTextFieldv2Prm{Label: "Nama Bahan", + Name: "namabahan", + Placeholder: "Nama Bahan", + Type: "text"}, + models.CustomDropdownV2Prm{ + Name: "stationid", + Label: "Sample Station", + ListItem: dev_mdbahanview.ListItemStation(stationList, 0), + }, + dialogAddBodyID, + dev_mdbahanview.JsHideModal("#"+dialogAddID), + ) + return utils.View(c, modalAddBody) +} +func (lh *MdBahanHandler) HandleAddMdBahan(c echo.Context) error { + logger, _ := zap.NewProduction() + + code := c.FormValue("kodebahan") + name := c.FormValue("namabahan") + stationIDPrm := c.FormValue("stationid") + tableID := c.FormValue("tableID") + paginationID := c.FormValue("paginationID") + filtername := c.FormValue("filtername") + filterstation := c.FormValue("filterstation") + currPagePrm := c.FormValue("currpage" + paginationID) + dialogAddBodyID := c.FormValue("dialogAddBodyID") + // searchID := c.FormValue("searchID") + dialogAddID := c.FormValue("dialogAddID") + dialogEditBodyID := c.FormValue("dialogEditBodyID") + dialogDeleteBodyID := c.FormValue("dialogDeleteBodyID") + currPage, err := strconv.Atoi(currPagePrm) + if err != nil { + return err + } + stationID, err := strconv.Atoi(stationIDPrm) + if err != nil { + return err + } + formValidation := "" + codeValidation := "" + nameValidation := "" + stationValidation := "" + + if strings.TrimSpace(code) == "" { + formValidation = "Code bahan tidak boleh kosong" + codeValidation = "Code bahan tidak boleh kosong" + nameValidation = "" + stationValidation = "" + } + if strings.TrimSpace(name) == "" { + formValidation = "Nama bahan tidak boleh kosong" + codeValidation = "" + stationValidation = "" + nameValidation = "Nama bahan tidak boleh kosong" + } + if stationID == 0 { + formValidation = "Pilih salah satu station" + codeValidation = "" + nameValidation = "" + stationValidation = "Pilih salah satu station" + } + if strings.TrimSpace(code) == "" && strings.TrimSpace(name) == "" { + formValidation = "Code,nama, dan station bahan tidak boleh kosong" + codeValidation = "Code bahan tidak boleh kosong" + stationValidation = "Pilih salah satu station" + nameValidation = "Nama bahan tidak boleh kosong" + + } + stationList, err := lh.MdBahanServices.GetListSampleStation(false) + defer logger.Sync() + logger.Info("GET DATA STATIOn", + zap.Any("err", err), + ) + if formValidation != "" || codeValidation != "" || nameValidation != "" || stationValidation != "" { + newForm := dev_mdbahanview.BodyFormBahan( + "", + models.CustomTextFieldv2Prm{Label: "Kode Bahan", + Name: "kodebahan", + Placeholder: "Kode Bahan", + Value: code, + ErrorMsg: codeValidation, + Type: "text"}, + models.CustomTextFieldv2Prm{Label: "Nama Bahan", + Name: "namabahan", + Placeholder: "Nama Bahan", + ErrorMsg: nameValidation, + Value: name, + Type: "text"}, + models.CustomDropdownV2Prm{ + Name: "stationid", + Label: "Sample Station", + ErrorMsg: stationValidation, + ListItem: dev_mdbahanview.ListItemStation(stationList, stationID), + }, + dialogAddBodyID, + dev_mdbahanview.JsShowModal(""), + ) + return utils.ViewMulti(c, []templ.Component{customtoastv2.CustomToastV2Show("Warning", formValidation, "warning"), newForm}) + } + _, err = lh.MdBahanServices.AddMdBahan(code, name, stationIDPrm) + if err != nil { + newForm := dev_mdbahanview.BodyFormBahan( + "", + models.CustomTextFieldv2Prm{Label: "Kode Bahan", + Name: "kodebahan", + Placeholder: "Kode Bahan", + Value: code, + Type: "text"}, + models.CustomTextFieldv2Prm{Label: "Nama Bahan", + Name: "namabahan", + Placeholder: "Nama Bahan", + Value: name, + Type: "text"}, + models.CustomDropdownV2Prm{ + Name: "stationid", + Label: "Sample Station", + ListItem: dev_mdbahanview.ListItemStation(stationList, int(stationID)), + }, + dialogAddBodyID, + dev_mdbahanview.JsShowModal(""), + ) + return utils.ViewMulti(c, []templ.Component{customtoastv2.CustomToastV2Show("Gagal", err.Error(), "danger"), newForm}) + } + + bahanList, totalPage, err := lh.MdBahanServices.GetListMdBahan(filtername, filterstation, currPage, 5) + defer logger.Sync() + logger.Info("GET DATA BAHAN", + zap.Any("data", bahanList), + zap.Any("err", err), + zap.Any("totalPage", totalPage), + ) + //Bahan Table + mdBahanTable := dev_mdbahanview.TableBahan( + bahanList, + tableID, + "/dev/md/bahan/openedit", + "#"+dialogEditBodyID, + "outerHTML", + "#dialogEditBodyID, #dialogEditID, #dialogDeleteBodyID, #dialogDeleteID", + "/dev/md/bahan/opendelete", + "#"+dialogDeleteBodyID, + "outerHTML", + "#dialogEditBodyID, #dialogEditID, #dialogDeleteBodyID, #dialogDeleteID") + + //Pagination + + mdbahanPagination := pagination.PaginationV3( + totalPage, currPage, + "/dev/md/bahan/pagination", + paginationID, + "#filter-name, #filter-station, #tableID, #paginationID, #dialogAddID, #dialogAddBodyID, #dialogEditID, #dialogEditBodyID, #dialogDeleteBodyID, #dialogDeleteID, #currpage"+paginationID, + "#"+paginationID, + "outerHTML", + "", + "true", + dev_mdbahanview.BeforeRequestContent(), + dev_mdbahanview.AfterRequestContent(), + ) + //Form Add + modalAddBody := dev_mdbahanview.BodyFormBahan( + "", + models.CustomTextFieldv2Prm{Label: "Kode Bahan", + Name: "kodebahan", + Placeholder: "Kode Bahan", + Type: "text"}, + models.CustomTextFieldv2Prm{Label: "Nama Bahan", + Name: "namabahan", + Placeholder: "Nama Bahan", + Type: "text"}, + models.CustomDropdownV2Prm{ + Name: "stationid", + Label: "Sample Station", + ListItem: dev_mdbahanview.ListItemStation(stationList, 0), + }, + dialogAddBodyID, + dev_mdbahanview.JsHideModal("#"+dialogAddID), + ) + + toastSuccess := customtoastv2.CustomToastV2Show("Success", "Success add bahan ", "success") + retval := []templ.Component{toastSuccess, mdBahanTable, mdbahanPagination, modalAddBody} + // time.Sleep(20 * time.Second) + return utils.ViewMulti(c, retval) +} +func (lh *MdBahanHandler) HandleOpenEditMdBahan(c echo.Context) error { + logger, _ := zap.NewProduction() + + id := c.QueryParam("id") + dialogEditID := c.QueryParam("dialogEditID") + dialogEditBodyID := c.QueryParam("dialogEditBodyID") + stationList, err := lh.MdBahanServices.GetListSampleStation(false) + defer logger.Sync() + logger.Info("GET DATA STATION", + zap.Any("err", err), + ) + dataBahan, err := lh.MdBahanServices.GetMdBahanByID(id) + if err != nil { + newForm := dev_mdbahanview.BodyFormBahan( + id, + models.CustomTextFieldv2Prm{Label: "Kode Bahan", + Name: "kodebahan", + Placeholder: "Kode Bahan", + Type: "text"}, + models.CustomTextFieldv2Prm{Label: "Nama Bahan", + Name: "namabahan", + Placeholder: "Nama Bahan", + Type: "text"}, + models.CustomDropdownV2Prm{ + Name: "stationid", + Label: "Sample Station", + ListItem: dev_mdbahanview.ListItemStation(stationList, dataBahan.T_BahanT_SampleStationID), + }, + dialogEditBodyID, + dev_mdbahanview.JsHideModal(""), + ) + return utils.ViewMulti(c, []templ.Component{customtoastv2.CustomToastV2Show("Error", "Get data bahan error", "danger"), newForm}) + } + newForm := dev_mdbahanview.BodyFormBahan( + id, + models.CustomTextFieldv2Prm{Label: "Kode Bahan", + Name: "kodebahan", + Placeholder: "Kode Bahan", + Value: dataBahan.T_BahanCode, + Type: "text"}, + models.CustomTextFieldv2Prm{Label: "Nama Bahan", + Name: "namabahan", + Placeholder: "Nama Bahan", + Value: dataBahan.T_BahanName, + Type: "text"}, + models.CustomDropdownV2Prm{ + Name: "stationid", + Label: "Sample Station", + ListItem: dev_mdbahanview.ListItemStation(stationList, dataBahan.T_BahanT_SampleStationID), + }, + dialogEditBodyID, + dev_mdbahanview.JsShowModal("#"+dialogEditID), + ) + return utils.View(c, newForm) +} +func (lh *MdBahanHandler) HandleCloseFormEditMdBahan(c echo.Context) error { + logger, _ := zap.NewProduction() + stationList, err := lh.MdBahanServices.GetListSampleStation(false) + dialogEditID := c.FormValue("dialogEditID") + dialogEditBodyID := c.FormValue("dialogEditBodyID") + defer logger.Sync() + logger.Info("GET DATA STATION", + zap.Any("err", err), + zap.Any("dialogeditbodyid", dialogEditBodyID), + ) + + modalAddBody := dev_mdbahanview.BodyFormBahan( + "", + models.CustomTextFieldv2Prm{Label: "Kode Bahan", + Name: "kodebahan", + Placeholder: "Kode Bahan", + Type: "text"}, + models.CustomTextFieldv2Prm{Label: "Nama Bahan", + Name: "namabahan", + Placeholder: "Nama Bahan", + Type: "text"}, + models.CustomDropdownV2Prm{ + Name: "stationid", + Label: "Sample Station", + ListItem: dev_mdbahanview.ListItemStation(stationList, 0), + }, + dialogEditBodyID, + dev_mdbahanview.JsHideModal("#"+dialogEditID), + ) + return utils.View(c, modalAddBody) +} +func (lh *MdBahanHandler) HandleEditMdBahan(c echo.Context) error { + logger, _ := zap.NewProduction() + + code := c.FormValue("kodebahan") + name := c.FormValue("namabahan") + id := c.FormValue("bahanid") + stationIDPrm := c.FormValue("stationid") + tableID := c.FormValue("tableID") + paginationID := c.FormValue("paginationID") + filtername := c.FormValue("filtername") + filterstation := c.FormValue("filterstation") + currPagePrm := c.FormValue("currpage" + paginationID) + // dialogAddBodyID := c.FormValue("dialogAddBodyID") + // searchID := c.FormValue("searchID") + dialogEditID := c.FormValue("dialogEditID") + dialogEditBodyID := c.FormValue("dialogEditBodyID") + dialogDeleteBodyID := c.FormValue("dialogDeleteBodyID") + currPage, err := strconv.Atoi(currPagePrm) + if err != nil { + return err + } + stationID, err := strconv.Atoi(stationIDPrm) + if err != nil { + return err + } + formValidation := "" + codeValidation := "" + nameValidation := "" + stationValidation := "" + + if strings.TrimSpace(code) == "" { + formValidation = "Code bahan tidak boleh kosong" + codeValidation = "Code bahan tidak boleh kosong" + nameValidation = "" + stationValidation = "" + } + if strings.TrimSpace(name) == "" { + formValidation = "Nama bahan tidak boleh kosong" + codeValidation = "" + stationValidation = "" + nameValidation = "Nama bahan tidak boleh kosong" + } + if stationID == 0 { + formValidation = "Pilih salah satu station" + codeValidation = "" + nameValidation = "" + stationValidation = "Pilih salah satu station" + } + if strings.TrimSpace(code) == "" && strings.TrimSpace(name) == "" { + formValidation = "Code,nama, dan station bahan tidak boleh kosong" + codeValidation = "Code bahan tidak boleh kosong" + stationValidation = "Pilih salah satu station" + nameValidation = "Nama bahan tidak boleh kosong" + + } + stationList, err := lh.MdBahanServices.GetListSampleStation(false) + defer logger.Sync() + logger.Info("GET DATA STATIOn", + zap.Any("err", err), + ) + if formValidation != "" || codeValidation != "" || nameValidation != "" || stationValidation != "" { + newForm := dev_mdbahanview.BodyFormBahan( + id, + models.CustomTextFieldv2Prm{Label: "Kode Bahan", + Name: "kodebahan", + Placeholder: "Kode Bahan", + Value: code, + ErrorMsg: codeValidation, + Type: "text"}, + models.CustomTextFieldv2Prm{Label: "Nama Bahan", + Name: "namabahan", + Placeholder: "Nama Bahan", + ErrorMsg: nameValidation, + Value: name, + Type: "text"}, + models.CustomDropdownV2Prm{ + Name: "stationid", + Label: "Sample Station", + ErrorMsg: stationValidation, + ListItem: dev_mdbahanview.ListItemStation(stationList, stationID), + }, + dialogEditBodyID, + dev_mdbahanview.JsShowModal(""), + ) + return utils.ViewMulti(c, []templ.Component{customtoastv2.CustomToastV2Show("Warning", formValidation, "warning"), newForm}) + } + _, err = lh.MdBahanServices.EditMdBahan(id, code, name, stationIDPrm) + if err != nil { + newForm := dev_mdbahanview.BodyFormBahan( + id, + models.CustomTextFieldv2Prm{Label: "Kode Bahan", + Name: "kodebahan", + Placeholder: "Kode Bahan", + Value: code, + Type: "text"}, + models.CustomTextFieldv2Prm{Label: "Nama Bahan", + Name: "namabahan", + Placeholder: "Nama Bahan", + Value: name, + Type: "text"}, + models.CustomDropdownV2Prm{ + Name: "stationid", + Label: "Sample Station", + ListItem: dev_mdbahanview.ListItemStation(stationList, int(stationID)), + }, + dialogEditBodyID, + dev_mdbahanview.JsShowModal(""), + ) + return utils.ViewMulti(c, []templ.Component{customtoastv2.CustomToastV2Show("Gagal", err.Error(), "danger"), newForm}) + } + + bahanList, totalPage, err := lh.MdBahanServices.GetListMdBahan(filtername, filterstation, currPage, 5) + defer logger.Sync() + logger.Info("GET DATA BAHAN", + zap.Any("data", bahanList), + zap.Any("err", err), + zap.Any("totalPage", totalPage), + ) + //Bahan Table + mdBahanTable := dev_mdbahanview.TableBahan( + bahanList, + tableID, + "/dev/md/bahan/openedit", + "#"+dialogEditBodyID, + "outerHTML", + "#dialogEditBodyID, #dialogEditID, #dialogDeleteBodyID, #dialogDeleteID", + "/dev/md/bahan/opendelete", + "#"+dialogDeleteBodyID, + "outerHTML", + "#dialogEditBodyID, #dialogEditID, #dialogDeleteBodyID, #dialogDeleteID") + + //Pagination + + mdbahanPagination := pagination.PaginationV3( + totalPage, currPage, + "/dev/md/bahan/pagination", + paginationID, + "#filter-name, #filter-station, #tableID, #paginationID, #dialogAddID, #dialogAddBodyID, #dialogEditID, #dialogEditBodyID, #dialogDeleteBodyID, #dialogDeleteID, #currpage"+paginationID, + "#"+paginationID, + "outerHTML", + "", + "true", + dev_mdbahanview.BeforeRequestContent(), + dev_mdbahanview.AfterRequestContent(), + ) + //Form Add + modalAddBody := dev_mdbahanview.BodyFormBahan( + "", + models.CustomTextFieldv2Prm{Label: "Kode Bahan", + Name: "kodebahan", + Placeholder: "Kode Bahan", + Type: "text"}, + models.CustomTextFieldv2Prm{Label: "Nama Bahan", + Name: "namabahan", + Placeholder: "Nama Bahan", + Type: "text"}, + models.CustomDropdownV2Prm{ + Name: "stationid", + Label: "Sample Station", + ListItem: dev_mdbahanview.ListItemStation(stationList, 0), + }, + dialogEditBodyID, + dev_mdbahanview.JsHideModal("#"+dialogEditID), + ) + + toastSuccess := customtoastv2.CustomToastV2Show("Success", "Success edit bahan ", "success") + retval := []templ.Component{toastSuccess, mdBahanTable, mdbahanPagination, modalAddBody} + // time.Sleep(20 * time.Second) + return utils.ViewMulti(c, retval) +} +func (lh *MdBahanHandler) HandleOpenDeleteMdBahan(c echo.Context) error { + logger, _ := zap.NewProduction() + + id := c.QueryParam("id") + dialogDeleteID := c.QueryParam("dialogDeleteID") + dialogDeleteBodyID := c.QueryParam("dialogDeleteBodyID") + + dataBahan, err := lh.MdBahanServices.GetMdBahanByID(id) + if err != nil { + defer logger.Sync() + logger.Info("GET DATA BAHAN", + zap.Any("err", err), + ) + newForm := dev_mdbahanview.DeleteConfirmationBody( + "", + dialogDeleteBodyID, + "Apakah anda yakin menghapus bahan berikut ?", + []string{"Kode", "Nama Bahan", "Sample Station"}, + []string{"", "", ""}, dev_mdbahanview.JsShowModal("")) + return utils.ViewMulti(c, []templ.Component{customtoastv2.CustomToastV2Show("Error", "Get data bahan error", "danger"), newForm}) + } + newForm := dev_mdbahanview.DeleteConfirmationBody( + strconv.Itoa(dataBahan.T_BahanID), + dialogDeleteBodyID, + "Apakah anda yakin menghapus bahan berikut ?", + []string{"Kode", "Nama Bahan", "Sample Station"}, + []string{dataBahan.T_BahanCode, dataBahan.T_BahanName, dataBahan.T_SampleStationName}, dev_mdbahanview.JsShowModal("#"+dialogDeleteID)) + return utils.View(c, newForm) +} +func (lh *MdBahanHandler) HandleCloseDeleteMdBahan(c echo.Context) error { + + dialogDeleteID := c.FormValue("dialogDeleteID") + dialogDeleteBodyID := c.FormValue("dialogDeleteBodyID") + newForm := dev_mdbahanview.DeleteConfirmationBody( + "", + dialogDeleteBodyID, + "Apakah anda yakin menghapus bahan berikut ?", + []string{"Kode", "Nama Bahan", "Sample Station"}, + []string{"", "", ""}, dev_mdbahanview.JsHideModal("#"+dialogDeleteID)) + return utils.View(c, newForm) +} + +func (lh *MdBahanHandler) HandleDeleteMdBahan(c echo.Context) error { + logger, _ := zap.NewProduction() + + id := c.FormValue("bahanid") + + tableID := c.FormValue("tableID") + paginationID := c.FormValue("paginationID") + filtername := c.FormValue("filtername") + filterstation := c.FormValue("filterstation") + currPagePrm := c.FormValue("currpage" + paginationID) + // dialogAddBodyID := c.FormValue("dialogAddBodyID") + // searchID := c.FormValue("searchID") + dialogDeleteID := c.FormValue("dialogDeleteID") + dialogEditBodyID := c.FormValue("dialogEditBodyID") + dialogDeleteBodyID := c.FormValue("dialogDeleteBodyID") + currPage, err := strconv.Atoi(currPagePrm) + if err != nil { + return err + } + + _, err = lh.MdBahanServices.DeleteMdBahan(id) + if err != nil { + defer logger.Sync() + logger.Info("ERR DELETE MD BAHAN", + zap.Any("err", err), + ) + newForm := dev_mdbahanview.DeleteConfirmationBody( + "", + dialogDeleteBodyID, + "Apakah anda yakin menghapus bahan berikut ?", + []string{"Kode", "Nama Bahan", "Sample Station"}, + []string{"", "", ""}, dev_mdbahanview.JsShowModal("")) + return utils.ViewMulti(c, []templ.Component{customtoastv2.CustomToastV2Show("Error", "Get data bahan error", "danger"), newForm}) + } + bahanList, totalPage, err := lh.MdBahanServices.GetListMdBahan(filtername, filterstation, currPage, 5) + defer logger.Sync() + logger.Info("GET DATA BAHAN", + zap.Any("data", bahanList), + zap.Any("err", err), + zap.Any("totalPage", totalPage), + ) + //Bahan Table + mdBahanTable := dev_mdbahanview.TableBahan( + bahanList, + tableID, + "/dev/md/bahan/openedit", + "#"+dialogEditBodyID, + "outerHTML", + "#dialogEditBodyID, #dialogEditID, #dialogDeleteBodyID, #dialogDeleteID", + "/dev/md/bahan/opendelete", + "#"+dialogDeleteBodyID, + "outerHTML", + "#dialogEditBodyID, #dialogEditID, #dialogDeleteBodyID, #dialogDeleteID") + + //Pagination + + mdbahanPagination := pagination.PaginationV3( + totalPage, currPage, + "/dev/md/bahan/pagination", + paginationID, + "#filter-name, #filter-station, #tableID, #paginationID, #dialogAddID, #dialogAddBodyID, #dialogEditID, #dialogEditBodyID, #dialogDeleteBodyID, #dialogDeleteID, #currpage"+paginationID, + "#"+paginationID, + "outerHTML", + "", + "true", + dev_mdbahanview.BeforeRequestContent(), + dev_mdbahanview.AfterRequestContent(), + ) + + toastSuccess := customtoastv2.CustomToastV2Show("Success", "Berhasil hapus bahan", "success") + newForm := dev_mdbahanview.DeleteConfirmationBody( + "", + dialogDeleteBodyID, + "Apakah anda yakin menghapus bahan berikut ?", + []string{"Kode", "Nama Bahan", "Sample Station"}, + []string{"", "", ""}, dev_mdbahanview.JsHideModal("#"+dialogDeleteID)) + return utils.ViewMulti(c, []templ.Component{toastSuccess, mdBahanTable, mdbahanPagination, newForm}) +} diff --git a/handlers/routes.go b/handlers/routes.go index 25388b1..ed82786 100644 --- a/handlers/routes.go +++ b/handlers/routes.go @@ -297,5 +297,12 @@ func SetupRoutesDev(app *echo.Echo, appStore db.AppStore) { dev.GET("/md/bahan", devMdBahanHandlers.HandleShowMdBahanScreen) dev.GET("/md/bahan/filter", devMdBahanHandlers.HandleFilterMdBahan) dev.GET("/md/bahan/pagination", devMdBahanHandlers.HandlePaginationMdBahan) - + dev.POST("/md/bahan/add", devMdBahanHandlers.HandleAddMdBahan) + dev.POST("/md/bahan/closeaddform", devMdBahanHandlers.HandleCloseFormAddMdBahan) + dev.GET("/md/bahan/openedit", devMdBahanHandlers.HandleOpenEditMdBahan) + dev.POST("/md/bahan/closeeditform", devMdBahanHandlers.HandleCloseFormEditMdBahan) + dev.POST("/md/bahan/edit", devMdBahanHandlers.HandleEditMdBahan) + dev.GET("/md/bahan/opendelete", devMdBahanHandlers.HandleOpenDeleteMdBahan) + dev.POST("/md/bahan/closedeleteform", devMdBahanHandlers.HandleCloseDeleteMdBahan) + dev.POST("/md/bahan/delete", devMdBahanHandlers.HandleDeleteMdBahan) } diff --git a/models/bahan.models.go b/models/bahan.models.go index 047d4dd..5e12ec2 100644 --- a/models/bahan.models.go +++ b/models/bahan.models.go @@ -1,9 +1,11 @@ package models +import "github.com/a-h/templ" + type Bahan struct { T_BahanID int `db:"T_BahanID"` - T_BahanT_SampleStationID string `db:"T_BahanT_SampleStationID"` - T_SampleStationID string `db:"T_SampleStationID"` + T_BahanT_SampleStationID int `db:"T_BahanT_SampleStationID"` + T_SampleStationID int `db:"T_SampleStationID"` T_SampleStationName string `db:"T_SampleStationName"` T_BahanCode string `db:"T_BahanCode"` T_BahanName string `db:"T_BahanName"` @@ -18,6 +20,19 @@ type Bahan struct { } type TmpSampleStation struct { - T_SampleStationID string `db:"T_SampleStationID"` + T_SampleStationID int `db:"T_SampleStationID"` T_SampleStationName string `db:"T_SampleStationName"` } + +type BahanFormComponent struct { + IDComponent string + Link string + HxTarget string + HxSwap string + HxInclude string + ModalID string + ModalTitle string + DialogBody templ.Component + DialogAction templ.Component + ButtonCLose templ.Component +} diff --git a/models/customdropdown.models.go b/models/customdropdown.models.go index 7bc3001..9e2dbe0 100644 --- a/models/customdropdown.models.go +++ b/models/customdropdown.models.go @@ -1,5 +1,7 @@ package models +import "github.com/a-h/templ" + // name string, id string, hxTarget string, hxGet string, hxIndicator string, hxTrigger string, hxInclude string, type CustomDropdownv1Prm struct { @@ -16,3 +18,19 @@ type CustomDropdownv1Prm struct { ErrorMsg string `default:""` ID string } +type CustomDropdownV2Prm struct { + HxTarget string `default:"hxTarget"` + HxGet string `default:"hxGet"` + HxIndicator string `default:"hxIndicator"` + HxInclude string `default:"hxInclude"` + HxTrigger string `default:"hxTrigger"` + HxSwap string `default:"HxSwap"` + Label string `default:"Label"` + Name string `default:"name"` + Placeholder string `default:"Placeholder"` + // Type string `default:"text"` + // Value string `default:""` + ErrorMsg string `default:""` + ID string + ListItem templ.Component +} diff --git a/services/dev/md.bahan.services.go b/services/dev/md.bahan.services.go index 97cdd91..3e697bd 100644 --- a/services/dev/md.bahan.services.go +++ b/services/dev/md.bahan.services.go @@ -7,6 +7,8 @@ import ( "fmt" "math" "strings" + + "go.uber.org/zap" ) func NewMdBahanServices(uStore db.AppStore) *MdBahanServices { @@ -30,6 +32,11 @@ func (su *MdBahanServices) GetListMdBahan( var totalData int offset := (currentPage - 1) * rowPerPage prm := "%" + strings.TrimSpace(search) + "%" + filterStation := "" + if stationID != "0" { + filterStation = "AND T_BahanT_SampleStationID = " + stationID + + } querytotal := ` SELECT COUNT(*) FROM t_bahan @@ -39,9 +46,9 @@ func (su *MdBahanServices) GetListMdBahan( AND T_BahanIsActive = 'Y' AND T_SampleStationIsActive = 'Y' WHERE (T_BahanName LIKE ? OR T_BahanCode LIKE ? ) - AND T_BahanT_SampleStationID = ? - ` - if err := dbx.Handlex.Get(&totalData, querytotal, prm, prm, stationID); err != nil { + + ` + filterStation + if err := dbx.Handlex.Get(&totalData, querytotal, prm, prm); err != nil { return nil, 0, fmt.Errorf("error querying database: %v", err) } query := ` @@ -55,11 +62,11 @@ func (su *MdBahanServices) GetListMdBahan( AND T_BahanIsActive = 'Y' AND T_SampleStationIsActive = 'Y' WHERE (T_BahanName LIKE ? OR T_BahanCode LIKE ? ) - AND T_BahanT_SampleStationID = ? + ` + filterStation + ` LIMIT ? OFFSET ? ` - if err := dbx.Handlex.Select(&bahanList, query, prm, prm, stationID, rowPerPage, offset); err != nil { + if err := dbx.Handlex.Select(&bahanList, query, prm, prm, rowPerPage, offset); err != nil { return nil, 0, fmt.Errorf("error querying database: %v", err) } totalPage := int(math.Ceil(float64(totalData) / float64(rowPerPage))) @@ -90,7 +97,7 @@ func (su *MdBahanServices) GetMdBahanBreadCrumb(title string) (models.BreadCrumb return ret, nil } -func (su *MdBahanServices) GetListSampleStation() ([]models.TmpSampleStation, error) { +func (su *MdBahanServices) GetListSampleStation(isFilter bool) ([]models.TmpSampleStation, error) { var stationList []models.TmpSampleStation query := ` SELECT @@ -104,6 +111,141 @@ func (su *MdBahanServices) GetListSampleStation() ([]models.TmpSampleStation, er if err := dbx.Handlex.Select(&stationList, query); err != nil { return nil, fmt.Errorf("error querying database: %v", err) } + if isFilter { + stationList = append( + []models.TmpSampleStation{{T_SampleStationID: 0, T_SampleStationName: "Semua"}}, stationList...) + } return stationList, nil } +func (su *MdBahanServices) AddMdBahan(code string, name string, stationid string) (bool, error) { + logger, _ := zap.NewProduction() + var datacek []models.Bahan + qryCek := `SELECT T_BahanCode FROM t_bahan WHERE T_BahanCode = ? AND T_BahanIsActive = 'Y'` + err := dbx.Handlex.Select(&datacek, qryCek, code) + + if err != nil { + defer logger.Sync() + logger.Error("Error cek data by code", + zap.String("code", code), + zap.Any("datacek", datacek), + ) + return false, fmt.Errorf("query cek failed") + } + if len(datacek) > 0 { + defer logger.Sync() + logger.Error("Code already taken by another data", + zap.String("code", code), + ) + return false, fmt.Errorf("code sudah dipakai") + } + query := ` + INSERT INTO t_bahan( + T_BahanT_SampleStationID, + T_BahanCode, + T_BahanName, + T_BahanCreated, + T_BahanCreatedUserID) + VALUES(?,?,?, NOW(), 1) + + ` + rst := dbx.Handlex.MustExec(query, stationid, code, name) + _, err = rst.LastInsertId() + if err != nil { + defer logger.Sync() + logger.Error("Error Insert t bahan", + zap.Any("code", err), + ) + return false, fmt.Errorf("insert data failed") + } + + return true, nil +} +func (ug *MdBahanServices) GetMdBahanByID(id string) (models.Bahan, error) { + logger, _ := zap.NewProduction() + + var data models.Bahan + err := dbx.Handlex.Get(&data, + `SELECT t_bahan.*, + T_SampleStationID, + T_SampleStationName + FROM t_bahan + JOIN + t_samplestation + ON T_BahanT_SampleStationID = T_SampleStationID + AND T_BahanIsActive = 'Y' + AND T_SampleStationIsActive = 'Y' + WHERE T_BahanID = ? `, id) + + if err != nil { + defer logger.Sync() + logger.Error("Error get data bahan by id vs", + zap.String("ID", id), + zap.Error(err), + ) + return data, fmt.Errorf("get bahan failed") + } + return data, nil +} +func (su *MdBahanServices) EditMdBahan(id string, code string, name string, stationid string) (bool, error) { + logger, _ := zap.NewProduction() + var datacek []models.Bahan + qryCek := `SELECT T_BahanCode FROM t_bahan WHERE T_BahanCode = ? AND T_BahanIsActive = 'Y' AND T_BahanID <> ?` + err := dbx.Handlex.Select(&datacek, qryCek, code, id) + + if err != nil { + defer logger.Sync() + logger.Error("Error cek data by code", + zap.String("code", code), + zap.Any("datacek", datacek), + ) + return false, fmt.Errorf("query cek failed") + } + if len(datacek) > 0 { + defer logger.Sync() + logger.Error("Code already taken by another data", + zap.String("code", code), + ) + return false, fmt.Errorf("code sudah dipakai") + } + query := ` + UPDATE t_bahan SET + T_BahanCode = ?, + T_BahanName = ?, + T_BahanT_SampleStationID = ? + WHERE T_BahanID = ? + ` + rst := dbx.Handlex.MustExec(query, code, name, stationid, id) + _, err = rst.LastInsertId() + if err != nil { + defer logger.Sync() + logger.Error("Error edit t bahan", + zap.Any("code", err), + ) + return false, fmt.Errorf("edit data failed") + } + + return true, nil +} +func (su *MdBahanServices) DeleteMdBahan(id string) (bool, error) { + logger, _ := zap.NewProduction() + + query := ` + UPDATE t_bahan + SET T_BahanIsActive = 'N', + T_BahanDeleted = NOW(), + T_BahanDeletedUserID = '1' + WHERE T_BahanID = ? + ` + rst := dbx.Handlex.MustExec(query, id) + _, err := rst.LastInsertId() + if err != nil { + defer logger.Sync() + logger.Error("Error edit t bahan", + zap.Any("code", err), + ) + return false, fmt.Errorf("edit data failed") + } + + return true, nil +} diff --git a/views/dev/mdbahan/mdbahan.templ b/views/dev/mdbahan/mdbahan.templ index 1ad1a37..030f8dd 100644 --- a/views/dev/mdbahan/mdbahan.templ +++ b/views/dev/mdbahan/mdbahan.templ @@ -3,16 +3,51 @@ package dev_mdbahanview import "cpone/layout" import "cpone/models" import "cpone/component/customtextfield" +import "cpone/component/customdropdown" +import "strconv" templ MdBahanScreen( tableID string, paginationID string, + dialogAddID string, + dialogAddBodyID string, + dialogEditID string, + dialogEditBodyID string, + dialogDeleteID string, + dialogDeleteBodyID string, breadcrumb templ.Component, tablecontent templ.Component, filterComponent templ.Component, pagination templ.Component, + dialogAddCmp templ.Component, + dialogEditCmp templ.Component, + dialogDeleteCmp templ.Component, ) {
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var25 string + templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(message) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `views\dev\mdbahan\mdbahanformmodal.templ`, Line: 145, Col: 14} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("