modified: web/assets/css/styles.css

modified:   web/components/base/input.templ
	modified:   web/components/base/input_templ.go
	modified:   web/components/base/range.templ
	modified:   web/components/base/range_templ.go
	modified:   web/components/base/select.templ
	modified:   web/components/base/select_templ.go
	modified:   web/components/base/textarea.templ
	modified:   web/components/base/textarea_templ.go
	modified:   web/components/icons.templ
	modified:   web/components/icons_templ.go
	modified:   web/components/issue.templ
	modified:   web/components/issue_templ.go
	modified:   web/components/layout.templ
	modified:   web/components/layout_templ.go
	new file:   web/components/sidebar.templ
	new file:   web/components/sidebar_templ.go
	new file:   web/components/status.templ
	new file:   web/components/status_templ.go
	modified:   web/handler/issues.go
	new file:   web/handler/task.go
	modified:   web/input.css
	deleted:    web/package-lock.json
	deleted:    web/package.json
	modified:   web/routes/layout.templ
	modified:   web/routes/layout_templ.go
	modified:   web/server/routes.go
	modified:   web/server/server.go
	modified:   web/web.go
This commit is contained in:
viljarb
2026-02-18 20:41:52 +01:00
parent ed8a0d02ec
commit 1d92041538
29 changed files with 1050 additions and 5847 deletions

View File

@@ -6,15 +6,19 @@ templ Layout(props LayoutProps) {
<head>
<meta charset="UTF-8"/>
<title>{ props.Title }</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="description" content={ props.Description }/>
@Head(props.Head)
</head>
<body class="min-h-screen bg-base-200 text-base-content">
<body class="min-h-screen bg-base-200 text-base-content flex flex-col">
@Header(props.Header)
<main class="p-4 bg-base-100 min-h-[calc(100vh-4rem)]">
<div class="flex flex-1 min-h-0">
@Sidebar(props.Routes)
<main class="flex-1 p-4 bg-base-100 min-h-0 overflow-auto">
{ children... }
</main>
</div>
</body>
</html>
}
@@ -24,7 +28,21 @@ type LayoutProps struct {
Description string
Head HeadProps
Header HeaderProps
Footer FooterProps
Routes []NavRoutes
}
type NavRoutes struct {
Name string
Path string
Icon templ.Component
}
templ Head(props HeadProps) {
for _, link := range props.Links {
<link href={ link.Href } rel={ link.Rel } as={ link.As }/>
}
for _, script := range props.Scripts {
<script src={ script.Src } defer={ script.Defer }></script>
}
}
type HeadProps struct {
@@ -35,6 +53,7 @@ type HeadProps struct {
type Link struct {
Href string
Rel string
As string
}
type Script struct {
@@ -42,101 +61,27 @@ type Script struct {
Defer bool
}
templ Head(props HeadProps) {
for _, link := range props.Links {
<link href={ link.Href } rel={ link.Rel }/>
}
for _, script := range props.Scripts {
<script src={ script.Src } defer={ script.Defer }></script>
}
}
templ Header(props HeaderProps) {
@Topbar() {
<div class="navbar-start gap-4">
@TopbarBrand(props.BrandName)
@TopbarCreateButton(props.CreateLabel, props.CreateHref)
<header class="navbar bg-primary text-primary-content px-6">
<div class="navbar-start">
<span class="font-semibold mr-5">{ props.Title }</span>
</div>
<div class="navbar-center flex-1 min-w-[32rem] max-w-4xl mx-auto px-2">
@TopbarSearch(props.SearchPlaceholder)
<div class="navbar-center">
if props.NavbarCenter != nil {
@props.NavbarCenter
}
</div>
<div class="navbar-end">
@TopbarIconButton("Notifications") {
@IconBell()
}
@TopbarIconButton("User menu") {
@IconUser()
if props.NavbarEnd != nil {
@props.NavbarEnd
}
</div>
}
}
templ Topbar() {
<header class="navbar sticky top-0 z-10 bg-primary text-primary-content shadow-sm min-h-12 px-6">
{ children... }
</header>
}
templ TopbarLeft() {
<div class="navbar-start">
{ children... }
</div>
}
templ TopbarBrand(brandName string) {
<span class="font-semibold text-base whitespace-nowrap">{ brandName }</span>
}
templ TopbarCreateButton(label string, href string) {
if href != "" {
<a href={ href } class="btn btn-sm bg-base-100 text-primary border-none hover:opacity-90 rounded-btn">{ label }</a>
} else {
<button type="button" class="btn btn-sm bg-base-100 text-primary border-none hover:opacity-90 rounded-btn">{ label }</button>
}
}
templ TopbarCenter() {
<div class="navbar-center">
{ children... }
</div>
}
templ TopbarSearch(placeholder string) {
<input
type="search"
placeholder={ placeholder }
aria-label="Search"
class="input input-md w-full bg-base-100 text-base-content placeholder-opacity-90 border border-base-content/20"
/>
}
templ TopbarRight() {
<div class="navbar-end">
{ children... }
</div>
}
templ TopbarIconButton(ariaLabel string) {
<button type="button" aria-label={ ariaLabel } class="btn btn-ghost btn-sm btn-square text-primary-content hover:bg-primary-content/20">
{ children... }
</button>
}
type HeaderProps struct {
BrandName string
CreateLabel string
CreateHref string
SearchPlaceholder string
Routes []NavRoute
}
type NavRoute struct {
Name string
Path string
}
templ Footer(props FooterProps) {
}
type FooterProps struct {
Title string
NavbarStart templ.Component
NavbarCenter templ.Component
NavbarEnd templ.Component
}