Added a basic homepage
This commit is contained in:
parent
d40640a648
commit
12fd3c04ca
113 changed files with 414 additions and 506 deletions
268
internal/ui/components/form.go
Normal file
268
internal/ui/components/form.go
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
package components
|
||||
|
||||
import (
|
||||
"github.com/camzawacki/personal-site/internal/form"
|
||||
"github.com/camzawacki/personal-site/internal/ui"
|
||||
. "maragu.dev/gomponents"
|
||||
. "maragu.dev/gomponents/html"
|
||||
)
|
||||
|
||||
type (
|
||||
InputFieldParams struct {
|
||||
Form form.Form
|
||||
FormField string
|
||||
Name string
|
||||
InputType string
|
||||
Label string
|
||||
Value string
|
||||
Placeholder string
|
||||
Help string
|
||||
}
|
||||
|
||||
FileFieldParams struct {
|
||||
Name string
|
||||
Label string
|
||||
Help string
|
||||
}
|
||||
|
||||
OptionsParams struct {
|
||||
Form form.Form
|
||||
FormField string
|
||||
Name string
|
||||
Label string
|
||||
Value string
|
||||
Options []Choice
|
||||
Help string
|
||||
}
|
||||
|
||||
Choice struct {
|
||||
Value string
|
||||
Label string
|
||||
}
|
||||
|
||||
TextareaFieldParams struct {
|
||||
Form form.Form
|
||||
FormField string
|
||||
Name string
|
||||
Label string
|
||||
Value string
|
||||
Help string
|
||||
}
|
||||
|
||||
CheckboxParams struct {
|
||||
Form form.Form
|
||||
FormField string
|
||||
Name string
|
||||
Label string
|
||||
Checked bool
|
||||
}
|
||||
)
|
||||
|
||||
func ControlGroup(controls ...Node) Node {
|
||||
return Div(
|
||||
Class("mt-2 flex gap-2"),
|
||||
Group(controls),
|
||||
)
|
||||
}
|
||||
|
||||
func TextareaField(el TextareaFieldParams) Node {
|
||||
return Fieldset(
|
||||
el.Label,
|
||||
Textarea(
|
||||
Class("textarea h-24 w-2/3 "+formFieldStatusClass(el.Form, el.FormField)),
|
||||
ID(el.Name),
|
||||
Name(el.Name),
|
||||
Text(el.Value),
|
||||
),
|
||||
Help(el.Help),
|
||||
formFieldErrors(el.Form, el.FormField),
|
||||
)
|
||||
}
|
||||
|
||||
func Radios(el OptionsParams) Node {
|
||||
buttons := make(Group, len(el.Options))
|
||||
for i, opt := range el.Options {
|
||||
id := "radio-" + el.Name + "-" + opt.Value
|
||||
buttons[i] = Div(
|
||||
Class("mb-2"),
|
||||
Input(
|
||||
ID(id),
|
||||
Type("radio"),
|
||||
Name(el.Name),
|
||||
Value(opt.Value),
|
||||
Class("radio mr-1 "+formFieldStatusClass(el.Form, el.FormField)),
|
||||
If(el.Value == opt.Value, Checked()),
|
||||
),
|
||||
Label(
|
||||
Text(opt.Label),
|
||||
For(id),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
return Fieldset(
|
||||
el.Label,
|
||||
buttons,
|
||||
formFieldErrors(el.Form, el.FormField),
|
||||
)
|
||||
}
|
||||
|
||||
func SelectList(el OptionsParams) Node {
|
||||
buttons := make(Group, len(el.Options))
|
||||
for i, opt := range el.Options {
|
||||
buttons[i] = Option(
|
||||
Text(opt.Label),
|
||||
Value(opt.Value),
|
||||
If(opt.Value == el.Value, Attr("selected")),
|
||||
)
|
||||
}
|
||||
|
||||
return Fieldset(
|
||||
el.Label,
|
||||
Select(
|
||||
Class("select "+formFieldStatusClass(el.Form, el.FormField)),
|
||||
Name(el.Name),
|
||||
buttons,
|
||||
),
|
||||
Help(el.Help),
|
||||
formFieldErrors(el.Form, el.FormField),
|
||||
)
|
||||
}
|
||||
|
||||
func Checkbox(el CheckboxParams) Node {
|
||||
return Div(
|
||||
Label(
|
||||
Class("label"),
|
||||
Input(
|
||||
Class("checkbox"),
|
||||
Type("checkbox"),
|
||||
Name(el.Name),
|
||||
If(el.Checked, Checked()),
|
||||
Value("true"),
|
||||
),
|
||||
Text(" "+el.Label),
|
||||
),
|
||||
formFieldErrors(el.Form, el.FormField),
|
||||
)
|
||||
}
|
||||
|
||||
func InputField(el InputFieldParams) Node {
|
||||
return Fieldset(
|
||||
el.Label,
|
||||
Input(
|
||||
ID(el.Name),
|
||||
Name(el.Name),
|
||||
Type(el.InputType),
|
||||
Class("input "+formFieldStatusClass(el.Form, el.FormField)),
|
||||
Value(el.Value),
|
||||
If(el.Placeholder != "", Placeholder(el.Placeholder)),
|
||||
),
|
||||
Help(el.Help),
|
||||
formFieldErrors(el.Form, el.FormField),
|
||||
)
|
||||
}
|
||||
|
||||
func Help(text string) Node {
|
||||
return If(len(text) > 0, Div(
|
||||
Class("label"),
|
||||
Text(text),
|
||||
))
|
||||
}
|
||||
|
||||
func Fieldset(label string, els ...Node) Node {
|
||||
return FieldSet(
|
||||
Class("fieldset"),
|
||||
If(len(label) > 0, Legend(
|
||||
Class("fieldset-legend"),
|
||||
Text(label),
|
||||
)),
|
||||
Group(els),
|
||||
)
|
||||
}
|
||||
|
||||
func FileField(el FileFieldParams) Node {
|
||||
return Fieldset(
|
||||
el.Label,
|
||||
Input(
|
||||
Type("file"),
|
||||
Class("file-input"),
|
||||
Name(el.Name),
|
||||
),
|
||||
Help(el.Help),
|
||||
)
|
||||
}
|
||||
|
||||
func formFieldStatusClass(fm form.Form, formField string) string {
|
||||
switch {
|
||||
case fm == nil:
|
||||
return ""
|
||||
case !fm.IsSubmitted():
|
||||
return ""
|
||||
case fm.FieldHasErrors(formField):
|
||||
return "input-error"
|
||||
default:
|
||||
return "input-success"
|
||||
}
|
||||
}
|
||||
|
||||
func formFieldErrors(fm form.Form, field string) Node {
|
||||
if fm == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
errs := fm.GetFieldErrors(field)
|
||||
if len(errs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
g := make(Group, len(errs))
|
||||
for i, err := range errs {
|
||||
g[i] = Div(
|
||||
Class("text-error"),
|
||||
Text(err),
|
||||
)
|
||||
}
|
||||
|
||||
return g
|
||||
}
|
||||
|
||||
func CSRF(r *ui.Request) Node {
|
||||
return Input(
|
||||
Type("hidden"),
|
||||
Name("csrf"),
|
||||
Value(r.CSRF),
|
||||
)
|
||||
}
|
||||
|
||||
func FormButton(color Color, label string) Node {
|
||||
return Button(
|
||||
Class("btn "+buttonColor(color)),
|
||||
Text(label),
|
||||
)
|
||||
}
|
||||
|
||||
func ButtonLink(color Color, href, label string) Node {
|
||||
return A(
|
||||
Href(href),
|
||||
Class("btn "+buttonColor(color)),
|
||||
Text(label),
|
||||
)
|
||||
}
|
||||
|
||||
func buttonColor(color Color) string {
|
||||
// Only colors being used are included so unused styles are not compiled.
|
||||
switch color {
|
||||
case ColorPrimary:
|
||||
return "btn-primary"
|
||||
case ColorInfo:
|
||||
return "btn-info"
|
||||
case ColorAccent:
|
||||
return "btn-accent"
|
||||
case ColorError:
|
||||
return "btn-error"
|
||||
case ColorLink:
|
||||
return "btn-link"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue