so much stuff
This commit is contained in:
parent
3d18f2d89b
commit
c0137247b7
10 changed files with 153 additions and 25 deletions
21
h/app.go
21
h/app.go
|
|
@ -55,6 +55,27 @@ func HtmlView(c *fiber.Ctx, page *Page) error {
|
|||
)
|
||||
}
|
||||
|
||||
func PartialViewWithHeaders(c *fiber.Ctx, headers *Headers, partial *Partial) error {
|
||||
c.Set(fiber.HeaderContentType, fiber.MIMETextHTML)
|
||||
if partial.Headers != nil {
|
||||
for s, a := range *partial.Headers {
|
||||
c.Set(s, a)
|
||||
}
|
||||
}
|
||||
|
||||
if headers != nil {
|
||||
for s, a := range *headers {
|
||||
c.Set(s, a)
|
||||
}
|
||||
}
|
||||
|
||||
return c.SendString(
|
||||
Render(
|
||||
partial.Root,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
func PartialView(c *fiber.Ctx, partial *Partial) error {
|
||||
c.Set(fiber.HeaderContentType, fiber.MIMETextHTML)
|
||||
if partial.Headers != nil {
|
||||
|
|
|
|||
12
h/tag.go
12
h/tag.go
|
|
@ -251,13 +251,13 @@ func Input(inputType string, children ...*Node) *Node {
|
|||
}
|
||||
}
|
||||
|
||||
func List[T any](items []T, mapper func(item T) *Node) *Node {
|
||||
func List[T any](items []T, mapper func(item T, index int) *Node) *Node {
|
||||
node := &Node{
|
||||
tag: "",
|
||||
children: make([]*Node, len(items)),
|
||||
}
|
||||
for index, value := range items {
|
||||
node.children[index] = mapper(value)
|
||||
node.children[index] = mapper(value, index)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
|
@ -298,6 +298,10 @@ func P(text string, children ...*Node) *Node {
|
|||
}
|
||||
}
|
||||
|
||||
func Form(children ...*Node) *Node {
|
||||
return Tag("form", children...)
|
||||
}
|
||||
|
||||
func A(text string, children ...*Node) *Node {
|
||||
return &Node{
|
||||
tag: "a",
|
||||
|
|
@ -374,6 +378,10 @@ func Children(children []*Node) *Node {
|
|||
}
|
||||
}
|
||||
|
||||
func Label(text string) *Node {
|
||||
return Tag("label", Text(text))
|
||||
}
|
||||
|
||||
func If(condition bool, node *Node) *Node {
|
||||
if condition {
|
||||
return node
|
||||
|
|
|
|||
19
main.go
19
main.go
|
|
@ -4,9 +4,11 @@ import (
|
|||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/google/uuid"
|
||||
"log"
|
||||
"mhtml/database"
|
||||
"mhtml/h"
|
||||
"mhtml/pages"
|
||||
"mhtml/partials"
|
||||
"mhtml/partials/sheet"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
|
@ -50,6 +52,23 @@ func main() {
|
|||
|
||||
pages.RegisterPages(f)
|
||||
|
||||
f.Post("/api/patients", func(ctx *fiber.Ctx) error {
|
||||
name := ctx.FormValue("name")
|
||||
reason := ctx.FormValue("reason-for-visit")
|
||||
location := ctx.FormValue("location-name")
|
||||
|
||||
database.HSet("patients", uuid.New().String(), partials.Patient{
|
||||
Name: name,
|
||||
ReasonForVisit: reason,
|
||||
AppointmentDate: time.Now(),
|
||||
LocationName: location,
|
||||
})
|
||||
|
||||
return h.PartialViewWithHeaders(ctx, &map[string]string{
|
||||
"HX-Trigger": "patient-added",
|
||||
}, sheet.Close(ctx))
|
||||
})
|
||||
|
||||
h.Start(f, h.App{
|
||||
LiveReload: true,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ func StoryList() *h.Node {
|
|||
}
|
||||
|
||||
return h.Fragment(
|
||||
h.Div(h.List(*posts, func(item Post) *h.Node {
|
||||
h.Div(h.List(*posts, func(item Post, index int) *h.Node {
|
||||
return StoryCard(item)
|
||||
})),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,12 +10,15 @@ import (
|
|||
func PatientsIndex(ctx *fiber.Ctx) *h.Page {
|
||||
return h.NewPage(base.RootPage(
|
||||
h.Div(
|
||||
h.Class("flex flex-col p-4"),
|
||||
h.Class("flex flex-col p-4 w-full"),
|
||||
h.Div(
|
||||
h.Class("flex justify-between items-center"),
|
||||
h.P("Manage Patients", h.Class("text-lg font-bold")),
|
||||
partials.AddPatientButton()),
|
||||
h.ViewWithTriggers(partials.PatientList, "load", "every 3s"),
|
||||
h.Div(
|
||||
h.Class("flex justify-between items-center"),
|
||||
h.P("Manage Patients", h.Class("text-lg font-bold")),
|
||||
partials.AddPatientButton(),
|
||||
),
|
||||
h.ViewWithTriggers(partials.PatientList, "load", "patient-added from:body"),
|
||||
),
|
||||
),
|
||||
))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ func GetPartialFromContext(ctx *fiber.Ctx) *h.Partial {
|
|||
if path == "PatientList" || path == "/mhtml/partials.PatientList" {
|
||||
return PatientList(ctx)
|
||||
}
|
||||
if path == "AddPatientForm" || path == "/mhtml/partials.AddPatientForm" {
|
||||
return AddPatientForm(ctx)
|
||||
if path == "AddPatientSheet" || path == "/mhtml/partials.AddPatientSheet" {
|
||||
return AddPatientSheet(ctx)
|
||||
}
|
||||
if path == "Close" || path == "/mhtml/partials/sheet.Close" {
|
||||
return sheet.Close(ctx)
|
||||
|
|
|
|||
|
|
@ -34,21 +34,59 @@ func PatientList(ctx *fiber.Ctx) *h.Partial {
|
|||
}
|
||||
|
||||
return h.NewPartial(h.Div(
|
||||
h.Class("mt-8"),
|
||||
h.Id("patient-list"),
|
||||
h.List(patients, PatientRow),
|
||||
))
|
||||
}
|
||||
|
||||
func AddPatientForm(ctx *fiber.Ctx) *h.Partial {
|
||||
return h.NewPartial(sheet.Opened(h.Div(
|
||||
h.Class("flex flex-col gap-4"),
|
||||
h.P("Add Patient", h.Class("text-lg font-bold")),
|
||||
)))
|
||||
func AddPatientSheet(ctx *fiber.Ctx) *h.Partial {
|
||||
return h.NewPartial(sheet.Opened(
|
||||
sheet.Props{
|
||||
ClassName: "w-[400px] bg-gray-100 p-4",
|
||||
Root: h.Div(
|
||||
h.Class("flex flex-col gap-4"),
|
||||
h.P("Add Patient", h.Class("text-lg font-bold")),
|
||||
addPatientForm(),
|
||||
),
|
||||
}))
|
||||
}
|
||||
|
||||
func PatientRow(patient *Patient) *h.Node {
|
||||
return h.Div(
|
||||
func addPatientForm() *h.Node {
|
||||
return h.Form(
|
||||
h.Post("/api/patients"),
|
||||
h.Class("flex flex-col gap-2"),
|
||||
ui.Input(ui.InputProps{
|
||||
Type: "text",
|
||||
Label: "Name",
|
||||
Name: "name",
|
||||
}),
|
||||
ui.Input(ui.InputProps{
|
||||
Type: "text",
|
||||
Label: "Reason for visit",
|
||||
Name: "reason-for-visit",
|
||||
}),
|
||||
ui.Input(ui.InputProps{
|
||||
Type: "date",
|
||||
Label: "Appointment Date",
|
||||
Name: "appointment-date",
|
||||
}),
|
||||
ui.Input(ui.InputProps{
|
||||
Type: "text",
|
||||
Label: "Location Name",
|
||||
Name: "location-name",
|
||||
}),
|
||||
ui.PrimaryButton(ui.ButtonProps{
|
||||
Text: "Add Patient",
|
||||
Class: "rounded p-2",
|
||||
Type: "submit",
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
func PatientRow(patient *Patient, index int) *h.Node {
|
||||
return h.Div(
|
||||
h.Class("flex flex-col gap-2 rounded p-4", h.Ternary(index%2 == 0, "bg-red-100", "")),
|
||||
h.Pf("Name: %s", patient.Name),
|
||||
h.Pf("Reason for visit: %s", patient.ReasonForVisit),
|
||||
)
|
||||
|
|
@ -59,7 +97,7 @@ func AddPatientButton() *h.Node {
|
|||
Id: "add-patient",
|
||||
Text: "Add Patient",
|
||||
Class: "bg-blue-700 text-white rounded p-2 h-12",
|
||||
Target: "#active-modal",
|
||||
Get: h.GetPartialPath(AddPatientForm),
|
||||
Target: sheet.Id,
|
||||
Get: h.GetPartialPath(AddPatientSheet),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,17 +5,25 @@ import (
|
|||
"mhtml/h"
|
||||
)
|
||||
|
||||
func Opened(children ...*h.Node) *h.Node {
|
||||
type Props struct {
|
||||
ClassName string
|
||||
Root *h.Node
|
||||
}
|
||||
|
||||
var Id = "#active-modal"
|
||||
|
||||
func Opened(props Props) *h.Node {
|
||||
return h.Fragment(h.Div(
|
||||
h.Class(`fixed top-0 right-0 h-full w-96 bg-gray-100 shadow-lg z-50`),
|
||||
CloseButton(),
|
||||
h.Class(`fixed top-0 right-0 h-full shadow-lg z-50`,
|
||||
h.Ternary(props.ClassName != "", props.ClassName, "w-96 bg-gray-100")),
|
||||
closeButton(),
|
||||
h.Div(
|
||||
children...,
|
||||
props.Root,
|
||||
)))
|
||||
}
|
||||
|
||||
func Closed() *h.Node {
|
||||
return h.Div(h.Id("active-modal"))
|
||||
return h.Div(h.Id(Id))
|
||||
}
|
||||
|
||||
func Close(ctx *fiber.Ctx) *h.Partial {
|
||||
|
|
@ -24,7 +32,7 @@ func Close(ctx *fiber.Ctx) *h.Partial {
|
|||
)
|
||||
}
|
||||
|
||||
func CloseButton() *h.Node {
|
||||
func closeButton() *h.Node {
|
||||
return h.Div(
|
||||
h.Class("absolute top-0 right-0 p-3"),
|
||||
h.Button(
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ type ButtonProps struct {
|
|||
Id string
|
||||
Text string
|
||||
Target string
|
||||
Type string
|
||||
Trigger string
|
||||
Get string
|
||||
Class string
|
||||
|
|
@ -35,6 +36,7 @@ func Button(props ButtonProps) *h.Node {
|
|||
h.Class("flex gap-1 items-center border p-4 rounded cursor-hover", props.Class),
|
||||
h.If(props.Get != "", h.Get(props.Get)),
|
||||
h.If(props.Target != "", h.Target(props.Target)),
|
||||
h.IfElse(props.Type != "", h.Type(props.Type), h.Type("button")),
|
||||
text,
|
||||
)
|
||||
|
||||
|
|
|
|||
29
ui/input.go
Normal file
29
ui/input.go
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package ui
|
||||
|
||||
import "mhtml/h"
|
||||
|
||||
type InputProps struct {
|
||||
Id string
|
||||
Label string
|
||||
Name string
|
||||
Type string
|
||||
DefaultValue string
|
||||
}
|
||||
|
||||
func Input(props InputProps) *h.Node {
|
||||
input := h.Input(
|
||||
props.Type,
|
||||
h.Class("border p-2 rounded"),
|
||||
h.If(props.Id != "", h.Id(props.Id)),
|
||||
h.If(props.Name != "", h.Name(props.Name)),
|
||||
h.If(props.DefaultValue != "", h.Attribute("defaultValue", props.DefaultValue)),
|
||||
)
|
||||
if props.Label != "" {
|
||||
return h.Div(
|
||||
h.Class("flex flex-col gap-1"),
|
||||
h.Label(props.Label),
|
||||
input,
|
||||
)
|
||||
}
|
||||
return input
|
||||
}
|
||||
Loading…
Reference in a new issue