so much stuff

This commit is contained in:
maddalax 2024-09-11 13:09:55 -05:00
parent 3d18f2d89b
commit c0137247b7
10 changed files with 153 additions and 25 deletions

View file

@ -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 {

View file

@ -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
View file

@ -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,
})

View file

@ -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)
})),
)

View file

@ -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.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"),
partials.AddPatientButton(),
),
h.ViewWithTriggers(partials.PatientList, "load", "patient-added from:body"),
),
),
))
}

View file

@ -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)

View file

@ -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(
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),
})
}

View file

@ -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(

View file

@ -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
View 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
}