diff --git a/authmiddleware/authmiddleware.go b/auth/authmiddleware/authmiddleware.go similarity index 100% rename from authmiddleware/authmiddleware.go rename to auth/authmiddleware/authmiddleware.go diff --git a/authmiddleware/const.go b/auth/authmiddleware/const.go similarity index 100% rename from authmiddleware/const.go rename to auth/authmiddleware/const.go diff --git a/authmiddleware/must.go b/auth/authmiddleware/must.go similarity index 100% rename from authmiddleware/must.go rename to auth/authmiddleware/must.go diff --git a/authmiddleware/must_test.go b/auth/authmiddleware/must_test.go similarity index 100% rename from authmiddleware/must_test.go rename to auth/authmiddleware/must_test.go diff --git a/authmiddleware/session.go b/auth/authmiddleware/session.go similarity index 100% rename from authmiddleware/session.go rename to auth/authmiddleware/session.go diff --git a/authmiddleware/util_test.go b/auth/authmiddleware/util_test.go similarity index 100% rename from authmiddleware/util_test.go rename to auth/authmiddleware/util_test.go diff --git a/authmiddleware/validation_test.go b/auth/authmiddleware/validation_test.go similarity index 100% rename from authmiddleware/validation_test.go rename to auth/authmiddleware/validation_test.go diff --git a/auth/discordauth.go b/auth/discordauth.go new file mode 100644 index 0000000..e69de29 diff --git a/interactions/interactions_test.go b/interactions/interactions_test.go index 1abfcb6..0aac146 100644 --- a/interactions/interactions_test.go +++ b/interactions/interactions_test.go @@ -7,7 +7,7 @@ import ( "net/http" "testing" - "git.sapphic.engineer/roleypoly/v4/authmiddleware" + "git.sapphic.engineer/roleypoly/v4/auth/authmiddleware" "git.sapphic.engineer/roleypoly/v4/discord" "git.sapphic.engineer/roleypoly/v4/interactions" "git.sapphic.engineer/roleypoly/v4/roleypoly" diff --git a/justfile b/justfile index 6e7217e..268eea8 100644 --- a/justfile +++ b/justfile @@ -12,10 +12,13 @@ run-container: docker load -i result docker run -it --rm -p 8169:8169 localhost/roleypoly/roleypoly -precommit: fmt tidy update-vendor-hash test +precommit: fmt prettier tidy update-vendor-hash test fmt: go fmt ./... + +prettier: + prettier -w -c **/*.{css,html,json,md} tidy: go mod tidy @@ -27,4 +30,7 @@ test: go test ./... clean-repo: - rm -rf tmp result \ No newline at end of file + rm -rf tmp result + +open-chromium path="/testing/t/picker": + nix-shell -p chromium --command "chromium http://localhost:8170{{path}}" \ No newline at end of file diff --git a/presentation/role.go b/presentation/role.go new file mode 100644 index 0000000..c320b99 --- /dev/null +++ b/presentation/role.go @@ -0,0 +1,58 @@ +package presentation + +import ( + "fmt" + + "git.sapphic.engineer/roleypoly/v4/types" + "git.sapphic.engineer/roleypoly/v4/utils" +) + +type InputType string + +const ( + InputCheckbox InputType = "checkbox" + InputRadio InputType = "radio" +) + +type PresentableRole struct { + ID string + CategoryID string + Name string + Selected bool + InputType InputType + Colors PresentableRoleColors +} + +func Role(category *types.Category, role *types.Role, selected bool) PresentableRole { + inputType := InputCheckbox + if category.Type == types.CategorySingle { + inputType = InputRadio + } + + colors := GetColors(role.Color) + + return PresentableRole{ + ID: role.ID, + CategoryID: category.ID, + Name: role.Name, + Selected: selected, + InputType: inputType, + Colors: colors, + } +} + +type PresentableRoleColors struct { + Main string + IsDark bool +} + +func GetColors(roleColor uint32) PresentableRoleColors { + // TODO: no color + + r, g, b := utils.IntToRgb(roleColor) + + return PresentableRoleColors{ + Main: fmt.Sprintf("#%x", roleColor), + IsDark: utils.IsDarkColor(r, g, b), + } +} diff --git a/presentation/role_test.go b/presentation/role_test.go new file mode 100644 index 0000000..fdc1c14 --- /dev/null +++ b/presentation/role_test.go @@ -0,0 +1,33 @@ +package presentation_test + +import ( + "testing" + + "git.sapphic.engineer/roleypoly/v4/presentation" + "git.sapphic.engineer/roleypoly/v4/types/fixtures" + "github.com/stretchr/testify/assert" +) + +func TestRole(t *testing.T) { + r := presentation.Role(&fixtures.CategoryMulti, &fixtures.RoleWithDarkColor, true) + assert.Equal(t, fixtures.RoleWithDarkColor.ID, r.ID) + assert.Equal(t, fixtures.RoleWithDarkColor.Name, r.Name) + assert.Equal(t, presentation.InputCheckbox, r.InputType) + assert.Equal(t, "#a20000", r.Colors.Main) + assert.True(t, r.Colors.IsDark) + assert.True(t, r.Selected) + + r = presentation.Role(&fixtures.CategorySingle, &fixtures.RoleWithDarkColor, false) + assert.Equal(t, presentation.InputRadio, r.InputType) + assert.False(t, r.Selected) + + r = presentation.Role(&fixtures.CategorySingle, &fixtures.RoleWithLightColor, true) + assert.False(t, r.Colors.IsDark) + assert.True(t, r.Selected) +} + +func TestGetColors(t *testing.T) { + c := presentation.GetColors(0xa20000) + assert.Equal(t, "#a20000", c.Main) + assert.True(t, c.IsDark) +} diff --git a/roleypoly/fiber.go b/roleypoly/fiber.go index d546d41..669ee6e 100644 --- a/roleypoly/fiber.go +++ b/roleypoly/fiber.go @@ -13,7 +13,7 @@ import ( "github.com/gofiber/fiber/v3/middleware/static" "github.com/gofiber/template/html/v2" - "git.sapphic.engineer/roleypoly/v4/authmiddleware" + "git.sapphic.engineer/roleypoly/v4/auth/authmiddleware" "git.sapphic.engineer/roleypoly/v4/discord" "git.sapphic.engineer/roleypoly/v4/interactions" staticfs "git.sapphic.engineer/roleypoly/v4/static" diff --git a/shell.nix b/shell.nix index 944bef8..49c0e43 100644 --- a/shell.nix +++ b/shell.nix @@ -4,5 +4,7 @@ just nil air + nodePackages.prettier + pre-commit ]; } diff --git a/static/images/check.svg b/static/images/check.svg new file mode 100644 index 0000000..7c56d2f --- /dev/null +++ b/static/images/check.svg @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/static/main.css b/static/main.css index c0c10b1..409d3de 100644 --- a/static/main.css +++ b/static/main.css @@ -1,3 +1,94 @@ +:root { + --taupe100: #332d2d; + --taupe200: #453e3d; + --taupe300: #5d5352; + --taupe400: #756867; + --taupe500: #ab9b9a; + --taupe600: #ebd6d4; + + --discord100: #23272a; + --discord200: #2c2f33; + --discord400: #7289da; + --discord500: #99aab5; + + --green400: #46b646; + --green200: #1d8227; + + --red400: #e95353; + --red200: #f14343; + + --gold400: #efcf24; + + --grey100: #1c1010; + --grey500: #dbd9d9; + --grey600: #f2efef; +} + +* { + box-sizing: border-box; +} + body { font-family: "Atkinson Hyperlegible", sans-serif; + background-color: var(--taupe200); + color: var(--taupe600); +} + +.role { + /* TODO: dont do this, don't remember why?? (^aki) */ + display: inline-flex; + align-items: center; + border: 2px solid var(--role-color); + border-radius: 3px; + user-select: none; + padding: 0.217rem; /* this is silly number pls ignore :3 (^noe) */ + gap: 0.215rem; + + input { + appearance: none; + position: relative; + width: 1.216rem; + height: 1.216rem; + margin: 0; + padding: 0; + border: 2px solid var(--role-color); + transition: all 0.35s ease-in-out; + border-radius: 1.216rem; + + &::before { + transition: all 0.35s ease-in-out; + content: ""; + mask-image: url(/static/images/check.svg); + mask-size: cover; + mask-position: center center; + background-color: var(--role-color); + opacity: 0; + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 1.216rem; + } + } + + label { + } + + &:has(input:checked) { + background-color: var(--role-color); + + input { + border-color: var(--contrast-color); + opacity: 1; + + &::before { + opacity: 1; + background-color: var(--contrast-color); + } + } + + label { + color: var(--contrast-color); + } + } } diff --git a/templates/components/nav.html b/templates/components/nav.html new file mode 100644 index 0000000..d44dbac --- /dev/null +++ b/templates/components/nav.html @@ -0,0 +1,4 @@ + diff --git a/templates/components/role.html b/templates/components/role.html new file mode 100644 index 0000000..40f0963 --- /dev/null +++ b/templates/components/role.html @@ -0,0 +1,10 @@ +{{ $for := printf "category-%s_role-%s" .CategoryID .ID }} +