This commit is contained in:
JACS 2026-05-01 19:39:45 -05:00
parent eec9697a71
commit 65f7715b05
7 changed files with 242 additions and 3 deletions

View file

@ -10,7 +10,6 @@ import (
"git.smarteching.com/goffee/core" "git.smarteching.com/goffee/core"
) )
// TablerDemo1 renders a Tabler-themed demo page // TablerDemo1 renders a Tabler-themed demo page
func TablerDemo1(c *core.Context) *core.Response { func TablerDemo1(c *core.Context) *core.Response {
@ -70,6 +69,25 @@ func TablerNavbar(c *core.Context) *core.Response {
return c.Response.Template("tabler_default.html", data) return c.Response.Template("tabler_default.html", data)
} }
// TablerTables renders a page with table components
func TablerTables(c *core.Context) *core.Response {
data := TablerPageData{
PageTitle: "Tables",
PageDescription: "Table demo page",
ShowTopbar: true,
Sidebar: false,
PageHeader: "Tables",
PagePretitle: "Components",
UserName: "Jane Doe",
UserRole: "Administrator",
NavbarMenu: SampleNavbarMenu(),
TableHeaders: SampleTableHeaders(),
TableRows: SampleTableRows(),
Content: template.HTML(""),
}
return c.Response.Template("tabler_tables.html", data)
}
// TablerHome renders the homepage/dashboard layout // TablerHome renders the homepage/dashboard layout
func TablerHome(c *core.Context) *core.Response { func TablerHome(c *core.Context) *core.Response {
data := TablerPageData{ data := TablerPageData{

View file

@ -43,3 +43,134 @@ func SampleNavbarMenu() TablerMenu {
}, },
} }
} }
// SampleTableRows returns sample data for table demos
// Migrated from liquid/data/people.json
func SampleTableRows() []TableRow {
return []TableRow{
{
ID: "1",
Name: "Paweł Kuna",
AvatarID: "000m",
Email: "paweluna@howstuffworks.com",
City: "Peimei",
Country: "China",
Status: "VIP",
JobTitle: "UI Designer",
Department: "Training",
Date: "2025-04-07",
Tags: []string{"High Volume"},
Category: "Training",
},
{
ID: "2",
Name: "Jeffie Lewzey",
AvatarID: "052f",
Email: "jlewzey1@seesaa.net",
City: "Indaial",
Country: "Brazil",
Status: "New",
JobTitle: "Chemical Engineer",
Department: "Support",
Date: "2024-12-12",
Tags: []string{"No Refunds"},
Category: "Support",
},
{
ID: "3",
Name: "Mallory Hulme",
AvatarID: "002m",
Email: "mhulme2@domainmarket.com",
City: "Cimuncang",
Country: "Indonesia",
Status: "VIP",
JobTitle: "Geologist IV",
Department: "Support",
Date: "2025-01-09",
Tags: []string{"High Value", "No Refunds", "Loyal"},
Category: "Support",
},
{
ID: "4",
Name: "Dunn Slane",
AvatarID: "003m",
Email: "dslane3@epa.gov",
City: "Liutang",
Country: "China",
Status: "Regular",
JobTitle: "Research Nurse",
Department: "Sales",
Date: "2022-10-01",
Tags: []string{"No Refunds"},
Category: "Sales",
},
{
ID: "5",
Name: "Emmy Levet",
AvatarID: "000f",
Email: "elevet4@senate.gov",
City: "Kaliprak",
Country: "Indonesia",
Status: "Regular",
JobTitle: "VP Product Management",
Department: "Accounting",
Date: "2025-05-18",
Tags: []string{"Standard"},
Category: "Accounting",
},
{
ID: "6",
Name: "Maryjo Lebarree",
AvatarID: "001f",
Email: "mlebarree5@unc.edu",
City: "Hantai",
Country: "China",
Status: "Regular",
JobTitle: "Civil Engineer",
Department: "Product Management",
Date: "2025-06-06",
Tags: []string{"No Refunds", "Loyal"},
Category: "Product Management",
},
{
ID: "7",
Name: "Egan Poetz",
AvatarID: "004m",
Email: "epoetz6@free.fr",
City: "Villaguay",
Country: "Argentina",
Status: "New",
JobTitle: "Research Nurse",
Department: "Engineering",
Date: "2024-08-21",
Tags: []string{"No Refunds"},
Category: "Engineering",
},
{
ID: "8",
Name: "Kellie Skingley",
AvatarID: "002f",
Email: "kskingley7@columbia.edu",
City: "Sidon",
Country: "Lebanon",
Status: "VIP",
JobTitle: "Teacher",
Department: "Services",
Date: "2025-02-23",
Tags: []string{"No Refunds", "Loyal"},
Category: "Services",
},
}
}
// SampleTableHeaders returns headers for the advanced table
func SampleTableHeaders() []TableHeader {
return []TableHeader{
{Name: "Name", Sort: "sort-name"},
{Name: "City", Sort: "sort-city"},
{Name: "Status", Sort: "sort-status"},
{Name: "Start date", Sort: "sort-date"},
{Name: "Tags", Sort: "sort-tags"},
{Name: "Category", Sort: "sort-category"},
}
}

View file

@ -17,6 +17,29 @@ type TablerMenuItem struct {
// TablerMenu is a map of menu sections keyed by identifier // TablerMenu is a map of menu sections keyed by identifier
type TablerMenu map[string]*TablerMenuItem type TablerMenu map[string]*TablerMenuItem
// TableHeader represents a column header
type TableHeader struct {
Name string
Sort string
Width string
}
// TableRow represents a single row of mock data
type TableRow struct {
ID string
Name string
AvatarID string
Email string
City string
Country string
Status string
JobTitle string
Department string
Date string
Tags []string
Category string
}
// TablerPageData holds the common data for all tabler pages // TablerPageData holds the common data for all tabler pages
type TablerPageData struct { type TablerPageData struct {
PageTitle string PageTitle string
@ -37,4 +60,8 @@ type TablerPageData struct {
UserRole string UserRole string
NavbarMenu TablerMenu NavbarMenu TablerMenu
CurrentPage string CurrentPage string
// Table data
TableHeaders []TableHeader
TableRows []TableRow
PerPageOptions []string
} }

View file

@ -69,5 +69,6 @@ func registerRoutes() {
controller.Get("/tablerdefault", controllers.TablerDefault) controller.Get("/tablerdefault", controllers.TablerDefault)
controller.Get("/tablerhome", controllers.TablerHome) controller.Get("/tablerhome", controllers.TablerHome)
controller.Get("/tablernavmenu", controllers.TablerNavbar) controller.Get("/tablernavmenu", controllers.TablerNavbar)
controller.Get("/tablertable", controllers.TablerTables)
} }

View file

@ -0,0 +1,55 @@
{{define "tabler_table"}}
<div class="table-responsive">
<table class="table table-vcenter card-table">
<thead>
<tr>
{{range .TableHeaders}}
<th{{if .Sort}} data-sort="{{.Sort}}"{{end}}>{{.Name}}</th>
{{end}}
<th class="w-1"></th>
</tr>
</thead>
<tbody>
{{range .TableRows}}
<tr>
<td>
<div class="d-flex py-1 align-items-center">
<span class="avatar me-2" style="background-image: url(/static/avatars/{{.AvatarID}}.jpg)"></span>
<div class="flex-fill">
<div class="font-weight-medium">{{.Name}}</div>
<div class="text-secondary"><a href="#" class="text-reset">{{.Email}}</a></div>
</div>
</div>
</td>
<td>
<div>{{.City}}</div>
<div class="text-secondary">{{.Country}}</div>
</td>
<td>
<span class="status-dot {{if eq .Status "active"}}status-dot-animated bg-green{{else if eq .Status "inactive"}}bg-muted{{else}}bg-blue{{end}}"></span>
{{.Status}}
</td>
<td>{{.Date}}</td>
<td>
<div class="row g-1">
{{range .Tags}}
<div class="col-auto">
<span class="badge bg-green-lt text-uppercase">{{.}}</span>
</div>
{{end}}
</div>
</td>
<td>
<span class="badge {{if eq .Category "Design"}}bg-purple-lt{{else if eq .Category "Engineering"}}bg-blue-lt{{else if eq .Category "Sales"}}bg-green-lt{{else if eq .Category "Marketing"}}bg-orange-lt{{else if eq .Category "Finance"}}bg-yellow-lt{{else}}bg-muted-lt{{end}}">{{.Category}}</span>
</td>
<td>
<a href="#" class="btn btn-ghost btn-icon btn-sm" data-bs-toggle="dropdown">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon"><path d="M12 12m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" /><path d="M12 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" /><path d="M12 5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0" /></svg>
</a>
</td>
</tr>
{{end}}
</tbody>
</table>
</div>
{{end}}

View file

@ -24,7 +24,13 @@
{{.Content}} {{.Content}}
{{else}} {{else}}
<div class="container-xl{{if .ContainerCentered}} my-auto{{end}}{{if .ContainerClass}} {{.ContainerClass}}{{end}}"> <div class="container-xl{{if .ContainerCentered}} my-auto{{end}}{{if .ContainerClass}} {{.ContainerClass}}{{end}}">
{{if .TableRows}}
<div class="card">
{{template "tabler_table" .}}
</div>
{{else}}
{{.Content}} {{.Content}}
{{end}}
</div> </div>
{{end}} {{end}}
</main> </main>

View file

@ -0,0 +1 @@
{{template "default_layout" .}}