From 313548cd999fbae818ccbebe57f5f34f2a8ba33e Mon Sep 17 00:00:00 2001 From: kokopi-dev Date: Tue, 10 Mar 2026 19:06:17 +0900 Subject: [PATCH] add:badges --- README.md | 4 + components/badge.templ | 47 ++++++++++++ components/icons/icons.templ | 16 ++++ components/layout.templ | 37 +-------- components/navbar.templ | 39 ++++++++++ constants/projects.go | 34 +++++++++ helpers/ui.go | 8 ++ main.go | 23 +----- pages/projects.templ | 144 ++++++++++++++++++----------------- 9 files changed, 225 insertions(+), 127 deletions(-) create mode 100644 README.md create mode 100644 components/badge.templ create mode 100644 components/navbar.templ create mode 100644 helpers/ui.go diff --git a/README.md b/README.md new file mode 100644 index 0000000..c61457c --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +# Personal Site + +Ideas: + - dynamic metadata insertion, for ogcards diff --git a/components/badge.templ b/components/badge.templ new file mode 100644 index 0000000..47b4a8b --- /dev/null +++ b/components/badge.templ @@ -0,0 +1,47 @@ +package components + +type BadgeVariant string + +const ( + BadgeInProgress BadgeVariant = "in-progress" + BadgeDeployed BadgeVariant = "deployed" +) + +type badgeConfig struct { + label string + dot string + class string +} + +func badgeProps(variant BadgeVariant) badgeConfig { + switch variant { + case BadgeDeployed: + return badgeConfig{ + label: "Deployed", + dot: "bg-teal-500", + class: "bg-teal-100 text-teal-700 ring-teal-600/20", + } + default: // in-progress + return badgeConfig{ + label: "In Progress", + dot: "bg-violet-400", + class: "bg-violet-100 text-violet-700 ring-violet-600/20", + } + } +} + +templ Badge(variant BadgeVariant) { + {{ props := badgeProps(variant) }} + + if props.label == "Deployed" { + + + + } else { + + } + { props.label } + +} diff --git a/components/icons/icons.templ b/components/icons/icons.templ index 1d510ca..108ec8f 100644 --- a/components/icons/icons.templ +++ b/components/icons/icons.templ @@ -1,5 +1,21 @@ package icons +templ Ban(className string) { + + + + +} + templ ArrowUpRight(className string) { -
- - { params.NavTitle } - - -
- -} templ MainLayout(params *constants.LayoutParams) { @@ -53,7 +18,7 @@ templ MainLayout(params *constants.LayoutParams) {
- @navbar(params) + @Navbar(params) // base container
{ children... } diff --git a/components/navbar.templ b/components/navbar.templ new file mode 100644 index 0000000..8273d06 --- /dev/null +++ b/components/navbar.templ @@ -0,0 +1,39 @@ +package components + +import "personal-site/constants" +import "personal-site/components/icons" + +templ Navbar(params *constants.LayoutParams) { +
+ +
+} diff --git a/constants/projects.go b/constants/projects.go index edce5ea..fad1a62 100644 --- a/constants/projects.go +++ b/constants/projects.go @@ -8,4 +8,38 @@ type Project struct { LinkGitea string LinkGithub string HostedOn string + IsWIP bool +} + +var AllProjects = []Project{ + { + Url: "https://derrickgee.dev/projects/support-ticket-demo", + Name: "Support Ticket System", + Description: "A sample of a robust support ticket system with the option to OAuth for database access. Authenticated users will be able to see other user created tickets. Guest mode will store tickets locally in your browser.", + HostedOn: "Home Server", + LinkGitea: "https://git.kokopi.dev/kokopi/personal-support-ticket-system", + LinkGithub: "https://github.com/kokopi-dev/personal-support-ticket-system", + TechTags: []string{"typescript", "react", "fastify", "tailwindcss", "sqlite", "vite", "bun"}, + IsWIP: false, + }, + { + Url: "/projects/dotfiles", + Name: "Linux Dotfiles", + Description: "Dotfile configurations for specific linux applications.", + HostedOn: "", + LinkGitea: "https://git.kokopi.dev/kokopi/dotfiles", + LinkGithub: "https://github.com/kokopi-dev/dotfiles", + TechTags: []string{"linux", "lua", "bash", "python"}, + IsWIP: false, + }, + { + Url: "/projects/dotfiles", + Name: "Koko-chan", + Description: "Paid discord bot service for handling schedules.", + HostedOn: "", + LinkGitea: "", + LinkGithub: "", + TechTags: []string{"golang", "templ", "tailwindcss"}, + IsWIP: true, + }, } diff --git a/helpers/ui.go b/helpers/ui.go new file mode 100644 index 0000000..faeb8ff --- /dev/null +++ b/helpers/ui.go @@ -0,0 +1,8 @@ +package helpers + +func TemplIf[T any](cond bool, a, b T) T { + if cond { + return a + } + return b +} diff --git a/main.go b/main.go index c24fb23..1badf50 100644 --- a/main.go +++ b/main.go @@ -23,28 +23,9 @@ func setupRoutesAndMiddleware() *gin.Engine { page := pages.Index() page.Render(c.Request.Context(), c.Writer) }) - var projects = []constants.Project{ - { - Url: "https://derrickgee.dev/projects/support-ticket-demo", - Name: "Support Ticket System", - Description: "A sample of a robust support ticket system with the option to OAuth for database access. Authenticated users will be able to see other user created tickets. Guest mode will store tickets locally in your browser.", - HostedOn: "Home Server", - LinkGitea: "https://git.kokopi.dev/kokopi/personal-support-ticket-system", - LinkGithub: "https://github.com/kokopi-dev/personal-support-ticket-system", - TechTags: []string{"typescript", "react", "fastify", "tailwindcss", "sqlite", "vite", "bun"}, - }, - { - Url: "/projects/dotfiles", - Name: "Linux Dotfiles", - Description: "Configurations for Linux", - HostedOn: "", - LinkGitea: "https://git.kokopi.dev/kokopi/dotfiles", - LinkGithub: "https://github.com/kokopi-dev/dotfiles", - TechTags: []string{"Linux", "Lua", "Bash", "Python"}, - }, - } + // projects defined in constants r.GET("/projects", func(c *gin.Context) { - page := pages.ProjectPage(projects) + page := pages.ProjectPage(constants.AllProjects) page.Render(c.Request.Context(), c.Writer) }) r.GET("/projects/dotfiles", func(c *gin.Context) { diff --git a/pages/projects.templ b/pages/projects.templ index e757eaf..99f8d12 100644 --- a/pages/projects.templ +++ b/pages/projects.templ @@ -4,79 +4,83 @@ import "personal-site/constants" import "fmt" import "personal-site/components" import "personal-site/components/icons" +import "personal-site/helpers" templ projectCard(idx int, project constants.Project) { -
- -
-
- { project.Name } -
-

{ project.Description }

-
- for _, tag := range project.TechTags { - { tag } - } -
- if project.HostedOn != "" { -

- hosted on { project.HostedOn } -

- } - if project.LinkGitea != "" || project.LinkGithub != "" { - - } -
-
- @icons.ArrowUpRight("size-4") -
-
+
+ +
+
+ { project.Name } + + if project.IsWIP { + @components.Badge(components.BadgeInProgress) + } else { + @components.Badge(components.BadgeDeployed) + } + +
+

{ project.Description }

+
+ for _, tag := range project.TechTags { + { tag } + } +
+ if project.HostedOn != "" { +

+ hosted on { project.HostedOn } +

+ } + if project.LinkGitea != "" || project.LinkGithub != "" { + + } else { +
+ @icons.Ban("size-4") + Closed Source +
+ } +
+
+ @icons.ArrowUpRight("size-4") +
+
} templ ProjectPage(projects []constants.Project) { - {{ params := constants.NewLayoutParams("Home") }} - @components.MainLayout(params) { -
-
-

derrickgee.dev/projects

-

Projects Directory

-

- A collection of projects built across different languages and frameworks. - Each runs as an independent service. -

-
-
- for idx, p := range projects { - @projectCard(idx, p) - } -
- } +{{ params := constants.NewLayoutParams("Home") }} +@components.MainLayout(params) { +
+
+

derrickgee.dev/projects

+

Projects Directory

+

+ A collection of projects built across different languages and frameworks. + Each runs as an independent service. +

+
+
+ for idx, p := range projects { + @projectCard(idx, p) + } +
+} }