package html_components import ( "fmt" . "github.com/labstack/echo/v4" "time" ) const tablePrototypePath = "/table-prototype" type Profession string const ( Developer Profession = "Developer" Designer Profession = "Designer" ) type PersonStruct struct { Id int Name string Age int Profession Profession MemberSince time.Time } func AddTablePrototype(e *Echo) { items := getPrototypeStructs() e.GET(tablePrototypePath, func(c Context) error { table := Table{ Headers: []string{"Name", "Age", "Profession", "Member Since"}, Rows: prototypeStructsToTableRows(items), EntityUrl: tablePrototypePath, } return RenderGoHtmlPage(c, "table-prototype", table) }) e.GET(createTablePrototypePath("/create"), func(c Context) error { inputs := []EditItemModalInputs{ {Label: "Name", Value: "", Name: "name", Type: InputTypeText}, {Label: "Age", Value: "", Name: "age", Type: InputTypeInt}, {Label: "Profession", Value: "", Name: "profession", Type: InputTypeEnum, Options: []SelectInputOption{ {Label: "Developer", Value: "Developer", Selected: false}, {Label: "Designer", Value: "Designer", Selected: false}, }, }, {Label: "Member Since", Value: "", Name: "memberSince", Type: InputTypeDateTime}, } modal := EditItemModal{ Id: "", Title: "Create person", Url: tablePrototypePath, IsCreate: true, SubmitButtonLabel: "Create", Inputs: inputs, } return RenderGoHtmlComponent(c, "editItemModal", modal) }) e.POST(tablePrototypePath, func(c Context) error { name := c.FormValue("name") age := c.FormValue("age") profession := c.FormValue("profession") memberSince := c.FormValue("memberSince") item := PersonStruct{ Id: len(items) + 1, Name: name, Age: ParseIntWithDefault(age, 0), Profession: Profession(profession), MemberSince: ParseDateTime(memberSince), } items = append(items, item) return returnRenderTable(c, items) }) e.GET(createTablePrototypePath("/:id"), func(c Context) error { id := ParseIntWithDefault(c.Param("id"), 1) row := items[id-1] inputs := []EditItemModalInputs{ {Label: "Name", Value: row.Name, Name: "name", Type: InputTypeText}, {Label: "Age", Value: fmt.Sprint(row.Age), Name: "age", Type: InputTypeInt}, {Label: "Profession", Value: "", Name: "profession", Type: InputTypeEnum, Options: []SelectInputOption{ {Label: "Developer", Value: string(Developer), Selected: row.Profession == Developer}, {Label: "Designer", Value: string(Designer), Selected: row.Profession == Designer}, }, }, {Label: "Member Since", Value: formatDateRangeInputTimeStamp(row.MemberSince), Name: "memberSince", Type: InputTypeDateTime}, } modal := EditItemModal{ Id: fmt.Sprint(id), Title: "Update person", Url: tablePrototypePath, IsCreate: false, SubmitButtonLabel: "Update", Inputs: inputs, } return RenderGoHtmlComponent(c, "editItemModal", modal) }) e.PUT(createTablePrototypePath("/:id"), func(c Context) error { id := ParseIntWithDefault(c.Param("id"), 1) name := c.FormValue("name") age := c.FormValue("age") profession := c.FormValue("profession") row := items[id-1] row.Name = name row.Age = ParseIntWithDefault(age, 0) row.Profession = Profession(profession) row.MemberSince = ParseDateTime(c.FormValue("memberSince")) return RenderGoHtmlComponent(c, "tableRow", prototypeStructToRow(row)) }) e.DELETE(createTablePrototypePath("/:id"), func(c Context) error { id := ParseIntWithDefault(c.Param("id"), 1) items = append(items[:id-1], items[id:]...) return returnRenderTable(c, items) }) } func ParseDateTime(since string) time.Time { t, err := time.Parse("2006-01-02T15:04", since) if err != nil { return time.Now() } return t } func returnRenderTable(c Context, items []PersonStruct) error { table := Table{ Headers: []string{"Name", "Age", "Profession", "Member Since"}, Rows: prototypeStructsToTableRows(items), EntityUrl: tablePrototypePath, } return RenderGoHtmlComponent(c, "table", table) } func getPrototypeStructs() []PersonStruct { return []PersonStruct{ {Id: 1, Name: "John", Age: 25, Profession: Developer, MemberSince: time.Now()}, {Id: 2, Name: "Jane", Age: 23, Profession: Designer, MemberSince: time.Now()}, {Id: 3, Name: "Doe", Age: 30, Profession: Developer, MemberSince: time.Now()}, } } func prototypeStructsToTableRows(items []PersonStruct) []TableRow { var rows []TableRow for _, item := range items { rows = append(rows, prototypeStructToRow(item)) } return rows } func prototypeStructToRow(person PersonStruct) TableRow { return TableRow{ Id: fmt.Sprint(person.Id), Columns: []TableColumn{ TableColumn{Value: person.Name, Type: TableColumnTypeText}, TableColumn{Value: fmt.Sprint(person.Age), Type: TableColumnTypeText}, TableColumn{Value: string(person.Profession), Type: TableColumnTypeText}, TableColumn{Value: dateDisplay(person.MemberSince), Type: TableColumnTypeText}}, EntityUrl: tablePrototypePath, } } func createTablePrototypePath(path string) string { return tablePrototypePath + path } func formatDateRangeInputTimeStamp(time time.Time) string { return time.Format("2006-01-02T15:04") } func dateDisplay(time time.Time) string { return time.Format("2006-01-02 15:04:05") }