mirror of
https://github.com/mentos1386/zdravko.git
synced 2024-11-21 23:33:34 +00:00
feat: initial work on tooling and design
This commit is contained in:
parent
3003ed66f7
commit
02a27a89b8
21 changed files with 2984 additions and 1 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
dist/
|
13
README.md
13
README.md
|
@ -4,8 +4,19 @@ Golang selfhosted Status/Healthcheck monitoring app.
|
|||
|
||||
Mostly just a project to test [temporal.io](https://temporal.io/).
|
||||
|
||||
### Expected features
|
||||
### Expected ~features~ things
|
||||
- [ ] SSO or just expect to be run behind a auth proxy.
|
||||
- [ ] Abbility for multiple instances/workers.
|
||||
- Otherwise using a cronjob would do the job, no need for temporal.
|
||||
- [ ] Some nice UI to try out [htmx](https://htmx.org/).
|
||||
|
||||
# Development
|
||||
|
||||
### Dependencies
|
||||
* [devbox](https://www.jetpack.io/devbox)
|
||||
* [justfile](https://github.com/casey/just)
|
||||
|
||||
```sh
|
||||
# Start development environment
|
||||
just run
|
||||
```
|
||||
|
|
23
cmd/server/main.go
Normal file
23
cmd/server/main.go
Normal file
|
@ -0,0 +1,23 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"code.tjo.space/mentos1386/zdravko/internal"
|
||||
"code.tjo.space/mentos1386/zdravko/internal/pages"
|
||||
)
|
||||
|
||||
func main() {
|
||||
r := mux.NewRouter()
|
||||
|
||||
// Server static files
|
||||
r.PathPrefix("/static/").Handler(http.FileServer(http.FS(internal.Static)))
|
||||
|
||||
r.HandleFunc("/", pages.Index).Methods("GET")
|
||||
|
||||
log.Println("Server started on :8000")
|
||||
log.Fatal(http.ListenAndServe(":8000", r))
|
||||
}
|
32
cmd/worker/main.go
Normal file
32
cmd/worker/main.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"go.temporal.io/sdk/client"
|
||||
"go.temporal.io/sdk/worker"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Initialize a Temporal Client
|
||||
// Specify the Namespace in the Client options
|
||||
clientOptions := client.Options{
|
||||
Namespace: "default",
|
||||
}
|
||||
temporalClient, err := client.Dial(clientOptions)
|
||||
if err != nil {
|
||||
log.Fatalln("Unable to create a Temporal Client", err)
|
||||
}
|
||||
defer temporalClient.Close()
|
||||
// Create a new Worker
|
||||
yourWorker := worker.New(temporalClient, "default-boilerplate-task-queue-local", worker.Options{})
|
||||
// Register Workflows
|
||||
//yourWorker.RegisterWorkflow(workflows.default)
|
||||
// Register Activities
|
||||
//yourWorker.RegisterActivity(activities.SSNTraceActivity)
|
||||
// Start the the Worker Process
|
||||
err = yourWorker.Run(worker.InterruptCh())
|
||||
if err != nil {
|
||||
log.Fatalln("Unable to start the Worker Process", err)
|
||||
}
|
||||
}
|
18
devbox.json
Normal file
18
devbox.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"packages": [
|
||||
"go@1.21",
|
||||
"temporal-cli@latest",
|
||||
"watchexec@latest",
|
||||
"tailwindcss@latest"
|
||||
],
|
||||
"shell": {
|
||||
"init_hook": [
|
||||
"echo 'Welcome to devbox!' > /dev/null"
|
||||
],
|
||||
"scripts": {
|
||||
"test": [
|
||||
"echo \"Error: no test specified\" && exit 1"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
85
devbox.lock
Normal file
85
devbox.lock
Normal file
|
@ -0,0 +1,85 @@
|
|||
{
|
||||
"lockfile_version": "1",
|
||||
"packages": {
|
||||
"go@1.21": {
|
||||
"last_modified": "2024-01-27T14:55:31Z",
|
||||
"resolved": "github:NixOS/nixpkgs/160b762eda6d139ac10ae081f8f78d640dd523eb#go",
|
||||
"source": "devbox-search",
|
||||
"version": "1.21.6",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"store_path": "/nix/store/8m3wjb23sfbjpjsj4l82b4zh9xnw62hh-go-1.21.6"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"store_path": "/nix/store/ia1z2slwgdgibad4z42rpd1dib7gk999-go-1.21.6"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"store_path": "/nix/store/dm4s4dfrah5zhl6larnrbh07v76j4pgy-go-1.21.6"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"store_path": "/nix/store/cw9dqybf9w6wp7827h23pb3ym8gs8h47-go-1.21.6"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tailwindcss@latest": {
|
||||
"last_modified": "2024-01-27T14:55:31Z",
|
||||
"resolved": "github:NixOS/nixpkgs/160b762eda6d139ac10ae081f8f78d640dd523eb#tailwindcss",
|
||||
"source": "devbox-search",
|
||||
"version": "3.4.1",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"store_path": "/nix/store/dii6r8cwfav7r8kd779f3ma5bs71ny54-tailwindcss-3.4.1"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"store_path": "/nix/store/b83zqgln5z5wpxiiccrlcmzgvgqj24wq-tailwindcss-3.4.1"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"store_path": "/nix/store/lpgbpk0lpiqp8my34l0agcz26qcdlshq-tailwindcss-3.4.1"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"store_path": "/nix/store/xag8bx7ld2k2ixg52yw5c9knbqw5a3bs-tailwindcss-3.4.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"temporal-cli@latest": {
|
||||
"last_modified": "2024-02-05T02:15:44Z",
|
||||
"resolved": "github:NixOS/nixpkgs/0a254180b4cad6be45aa46dce896bdb8db5d2930#temporal-cli",
|
||||
"source": "devbox-search",
|
||||
"version": "1.18.0",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"store_path": "/nix/store/6897s8ww6fhkiqvqdwfiji7497gvcxj6-temporal-cli-1.18.0"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"store_path": "/nix/store/d0lvc4fq5y9cql0fshy32285ldzyvhjz-temporal-cli-1.18.0"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"store_path": "/nix/store/dxwlx019wah1pj0hr3j50skrbdlb3x9g-temporal-cli-1.18.0"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"store_path": "/nix/store/v6z5knwsyxymnsk1gfmlnm51j22gf1df-temporal-cli-1.18.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"watchexec@latest": {
|
||||
"last_modified": "2024-01-27T14:55:31Z",
|
||||
"resolved": "github:NixOS/nixpkgs/160b762eda6d139ac10ae081f8f78d640dd523eb#watchexec",
|
||||
"source": "devbox-search",
|
||||
"version": "1.25.1",
|
||||
"systems": {
|
||||
"aarch64-darwin": {
|
||||
"store_path": "/nix/store/lmi497mmsgnafrrk4lkas8n7smpsmaxl-watchexec-1.25.1"
|
||||
},
|
||||
"aarch64-linux": {
|
||||
"store_path": "/nix/store/n9j2ri219dqp8hyj6km7n3rhcbnasxqp-watchexec-1.25.1"
|
||||
},
|
||||
"x86_64-darwin": {
|
||||
"store_path": "/nix/store/7ws8nlmazah2bqqhvsfyv6c3y8p5zaxb-watchexec-1.25.1"
|
||||
},
|
||||
"x86_64-linux": {
|
||||
"store_path": "/nix/store/pmji9885k2p6k45c4a36zv4xccvq0m4x-watchexec-1.25.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
38
go.mod
Normal file
38
go.mod
Normal file
|
@ -0,0 +1,38 @@
|
|||
module code.tjo.space/mentos1386/zdravko
|
||||
|
||||
go 1.21.6
|
||||
|
||||
require (
|
||||
github.com/gorilla/mux v1.8.1
|
||||
go.temporal.io/sdk v1.25.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect
|
||||
github.com/gogo/googleapis v1.4.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/gogo/status v1.1.1 // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
|
||||
github.com/pborman/uuid v1.2.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/robfig/cron v1.2.0 // indirect
|
||||
github.com/stretchr/objx v0.5.0 // indirect
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
go.temporal.io/api v1.24.0 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
golang.org/x/net v0.14.0 // indirect
|
||||
golang.org/x/sys v0.11.0 // indirect
|
||||
golang.org/x/text v0.12.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230815205213-6bfd019c3878 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230815205213-6bfd019c3878 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230815205213-6bfd019c3878 // indirect
|
||||
google.golang.org/grpc v1.57.0 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
25
internal/pages/index.go
Normal file
25
internal/pages/index.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
package pages
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"text/template"
|
||||
|
||||
"code.tjo.space/mentos1386/zdravko/internal"
|
||||
)
|
||||
|
||||
func Index(w http.ResponseWriter, r *http.Request) {
|
||||
ts, err := template.ParseFS(internal.Templates,
|
||||
"ui/components/base.tmpl",
|
||||
"ui/components/icon.tmpl",
|
||||
"ui/pages/index.tmpl",
|
||||
)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
err = ts.ExecuteTemplate(w, "base", nil)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
9
internal/static.go
Normal file
9
internal/static.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"embed"
|
||||
)
|
||||
|
||||
//go:generate just tailwindcss-build
|
||||
//go:embed static
|
||||
var Static embed.FS
|
26
internal/static/css/main.css
Normal file
26
internal/static/css/main.css
Normal file
|
@ -0,0 +1,26 @@
|
|||
.feather {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
stroke: currentColor;
|
||||
stroke-width: 2;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
fill: none;
|
||||
}
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
.btn {
|
||||
@apply font-bold py-2 px-4 rounded;
|
||||
}
|
||||
.btn:hover {
|
||||
@apply bg-gray-200 shadow-inner;
|
||||
}
|
||||
.btn-active {
|
||||
@apply bg-gray-300 text-black shadow;
|
||||
}
|
||||
.btn-active:hover {
|
||||
@apply shadow;
|
||||
}
|
749
internal/static/css/tailwind.css
Normal file
749
internal/static/css/tailwind.css
Normal file
|
@ -0,0 +1,749 @@
|
|||
.feather {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
stroke: currentColor;
|
||||
stroke-width: 2;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
fill: none;
|
||||
}
|
||||
|
||||
/*
|
||||
! tailwindcss v3.4.1 | MIT License | https://tailwindcss.com
|
||||
*/
|
||||
|
||||
/*
|
||||
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
|
||||
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
|
||||
*/
|
||||
|
||||
*,
|
||||
::before,
|
||||
::after {
|
||||
box-sizing: border-box;
|
||||
/* 1 */
|
||||
border-width: 0;
|
||||
/* 2 */
|
||||
border-style: solid;
|
||||
/* 2 */
|
||||
border-color: #e5e7eb;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
::before,
|
||||
::after {
|
||||
--tw-content: '';
|
||||
}
|
||||
|
||||
/*
|
||||
1. Use a consistent sensible line-height in all browsers.
|
||||
2. Prevent adjustments of font size after orientation changes in iOS.
|
||||
3. Use a more readable tab size.
|
||||
4. Use the user's configured `sans` font-family by default.
|
||||
5. Use the user's configured `sans` font-feature-settings by default.
|
||||
6. Use the user's configured `sans` font-variation-settings by default.
|
||||
7. Disable tap highlights on iOS
|
||||
*/
|
||||
|
||||
html,
|
||||
:host {
|
||||
line-height: 1.5;
|
||||
/* 1 */
|
||||
-webkit-text-size-adjust: 100%;
|
||||
/* 2 */
|
||||
-moz-tab-size: 4;
|
||||
/* 3 */
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
/* 3 */
|
||||
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
/* 4 */
|
||||
font-feature-settings: normal;
|
||||
/* 5 */
|
||||
font-variation-settings: normal;
|
||||
/* 6 */
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
/* 7 */
|
||||
}
|
||||
|
||||
/*
|
||||
1. Remove the margin in all browsers.
|
||||
2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
/* 1 */
|
||||
line-height: inherit;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
1. Add the correct height in Firefox.
|
||||
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
|
||||
3. Ensure horizontal rules are visible by default.
|
||||
*/
|
||||
|
||||
hr {
|
||||
height: 0;
|
||||
/* 1 */
|
||||
color: inherit;
|
||||
/* 2 */
|
||||
border-top-width: 1px;
|
||||
/* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct text decoration in Chrome, Edge, and Safari.
|
||||
*/
|
||||
|
||||
abbr:where([title]) {
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the default font size and weight for headings.
|
||||
*/
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
/*
|
||||
Reset links to optimize for opt-in styling instead of opt-out.
|
||||
*/
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct font weight in Edge and Safari.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Use the user's configured `mono` font-family by default.
|
||||
2. Use the user's configured `mono` font-feature-settings by default.
|
||||
3. Use the user's configured `mono` font-variation-settings by default.
|
||||
4. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
samp,
|
||||
pre {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
/* 1 */
|
||||
font-feature-settings: normal;
|
||||
/* 2 */
|
||||
font-variation-settings: normal;
|
||||
/* 3 */
|
||||
font-size: 1em;
|
||||
/* 4 */
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct font size in all browsers.
|
||||
*/
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/*
|
||||
Prevent `sub` and `sup` elements from affecting the line height in all browsers.
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
|
||||
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
|
||||
3. Remove gaps between table borders by default.
|
||||
*/
|
||||
|
||||
table {
|
||||
text-indent: 0;
|
||||
/* 1 */
|
||||
border-color: inherit;
|
||||
/* 2 */
|
||||
border-collapse: collapse;
|
||||
/* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
1. Change the font styles in all browsers.
|
||||
2. Remove the margin in Firefox and Safari.
|
||||
3. Remove default padding in all browsers.
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit;
|
||||
/* 1 */
|
||||
font-feature-settings: inherit;
|
||||
/* 1 */
|
||||
font-variation-settings: inherit;
|
||||
/* 1 */
|
||||
font-size: 100%;
|
||||
/* 1 */
|
||||
font-weight: inherit;
|
||||
/* 1 */
|
||||
line-height: inherit;
|
||||
/* 1 */
|
||||
color: inherit;
|
||||
/* 1 */
|
||||
margin: 0;
|
||||
/* 2 */
|
||||
padding: 0;
|
||||
/* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the inheritance of text transform in Edge and Firefox.
|
||||
*/
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Correct the inability to style clickable types in iOS and Safari.
|
||||
2. Remove default button styles.
|
||||
*/
|
||||
|
||||
button,
|
||||
[type='button'],
|
||||
[type='reset'],
|
||||
[type='submit'] {
|
||||
-webkit-appearance: button;
|
||||
/* 1 */
|
||||
background-color: transparent;
|
||||
/* 2 */
|
||||
background-image: none;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Use the modern Firefox focus style for all focusable elements.
|
||||
*/
|
||||
|
||||
:-moz-focusring {
|
||||
outline: auto;
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
|
||||
*/
|
||||
|
||||
:-moz-ui-invalid {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct vertical alignment in Chrome and Firefox.
|
||||
*/
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
/*
|
||||
Correct the cursor style of increment and decrement buttons in Safari.
|
||||
*/
|
||||
|
||||
::-webkit-inner-spin-button,
|
||||
::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Correct the odd appearance in Chrome and Safari.
|
||||
2. Correct the outline style in Safari.
|
||||
*/
|
||||
|
||||
[type='search'] {
|
||||
-webkit-appearance: textfield;
|
||||
/* 1 */
|
||||
outline-offset: -2px;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Remove the inner padding in Chrome and Safari on macOS.
|
||||
*/
|
||||
|
||||
::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Correct the inability to style clickable types in iOS and Safari.
|
||||
2. Change font properties to `inherit` in Safari.
|
||||
*/
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button;
|
||||
/* 1 */
|
||||
font: inherit;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Add the correct display in Chrome and Safari.
|
||||
*/
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
/*
|
||||
Removes the default spacing and border for appropriate elements.
|
||||
*/
|
||||
|
||||
blockquote,
|
||||
dl,
|
||||
dd,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
hr,
|
||||
figure,
|
||||
p,
|
||||
pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
menu {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Reset default styling for dialogs.
|
||||
*/
|
||||
|
||||
dialog {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Prevent resizing textareas horizontally by default.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
|
||||
2. Set the default placeholder color to the user's configured gray 400 color.
|
||||
*/
|
||||
|
||||
input::-moz-placeholder, textarea::-moz-placeholder {
|
||||
opacity: 1;
|
||||
/* 1 */
|
||||
color: #9ca3af;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
input::placeholder,
|
||||
textarea::placeholder {
|
||||
opacity: 1;
|
||||
/* 1 */
|
||||
color: #9ca3af;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Set the default cursor for buttons.
|
||||
*/
|
||||
|
||||
button,
|
||||
[role="button"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/*
|
||||
Make sure disabled buttons don't get the pointer cursor.
|
||||
*/
|
||||
|
||||
:disabled {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/*
|
||||
1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
|
||||
2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
|
||||
This can trigger a poorly considered lint error in some tools but is included by design.
|
||||
*/
|
||||
|
||||
img,
|
||||
svg,
|
||||
video,
|
||||
canvas,
|
||||
audio,
|
||||
iframe,
|
||||
embed,
|
||||
object {
|
||||
display: block;
|
||||
/* 1 */
|
||||
vertical-align: middle;
|
||||
/* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
|
||||
*/
|
||||
|
||||
img,
|
||||
video {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* Make elements with the HTML hidden attribute stay hidden by default */
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
*, ::before, ::after {
|
||||
--tw-border-spacing-x: 0;
|
||||
--tw-border-spacing-y: 0;
|
||||
--tw-translate-x: 0;
|
||||
--tw-translate-y: 0;
|
||||
--tw-rotate: 0;
|
||||
--tw-skew-x: 0;
|
||||
--tw-skew-y: 0;
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
--tw-pan-x: ;
|
||||
--tw-pan-y: ;
|
||||
--tw-pinch-zoom: ;
|
||||
--tw-scroll-snap-strictness: proximity;
|
||||
--tw-gradient-from-position: ;
|
||||
--tw-gradient-via-position: ;
|
||||
--tw-gradient-to-position: ;
|
||||
--tw-ordinal: ;
|
||||
--tw-slashed-zero: ;
|
||||
--tw-numeric-figure: ;
|
||||
--tw-numeric-spacing: ;
|
||||
--tw-numeric-fraction: ;
|
||||
--tw-ring-inset: ;
|
||||
--tw-ring-offset-width: 0px;
|
||||
--tw-ring-offset-color: #fff;
|
||||
--tw-ring-color: rgb(59 130 246 / 0.5);
|
||||
--tw-ring-offset-shadow: 0 0 #0000;
|
||||
--tw-ring-shadow: 0 0 #0000;
|
||||
--tw-shadow: 0 0 #0000;
|
||||
--tw-shadow-colored: 0 0 #0000;
|
||||
--tw-blur: ;
|
||||
--tw-brightness: ;
|
||||
--tw-contrast: ;
|
||||
--tw-grayscale: ;
|
||||
--tw-hue-rotate: ;
|
||||
--tw-invert: ;
|
||||
--tw-saturate: ;
|
||||
--tw-sepia: ;
|
||||
--tw-drop-shadow: ;
|
||||
--tw-backdrop-blur: ;
|
||||
--tw-backdrop-brightness: ;
|
||||
--tw-backdrop-contrast: ;
|
||||
--tw-backdrop-grayscale: ;
|
||||
--tw-backdrop-hue-rotate: ;
|
||||
--tw-backdrop-invert: ;
|
||||
--tw-backdrop-opacity: ;
|
||||
--tw-backdrop-saturate: ;
|
||||
--tw-backdrop-sepia: ;
|
||||
}
|
||||
|
||||
::backdrop {
|
||||
--tw-border-spacing-x: 0;
|
||||
--tw-border-spacing-y: 0;
|
||||
--tw-translate-x: 0;
|
||||
--tw-translate-y: 0;
|
||||
--tw-rotate: 0;
|
||||
--tw-skew-x: 0;
|
||||
--tw-skew-y: 0;
|
||||
--tw-scale-x: 1;
|
||||
--tw-scale-y: 1;
|
||||
--tw-pan-x: ;
|
||||
--tw-pan-y: ;
|
||||
--tw-pinch-zoom: ;
|
||||
--tw-scroll-snap-strictness: proximity;
|
||||
--tw-gradient-from-position: ;
|
||||
--tw-gradient-via-position: ;
|
||||
--tw-gradient-to-position: ;
|
||||
--tw-ordinal: ;
|
||||
--tw-slashed-zero: ;
|
||||
--tw-numeric-figure: ;
|
||||
--tw-numeric-spacing: ;
|
||||
--tw-numeric-fraction: ;
|
||||
--tw-ring-inset: ;
|
||||
--tw-ring-offset-width: 0px;
|
||||
--tw-ring-offset-color: #fff;
|
||||
--tw-ring-color: rgb(59 130 246 / 0.5);
|
||||
--tw-ring-offset-shadow: 0 0 #0000;
|
||||
--tw-ring-shadow: 0 0 #0000;
|
||||
--tw-shadow: 0 0 #0000;
|
||||
--tw-shadow-colored: 0 0 #0000;
|
||||
--tw-blur: ;
|
||||
--tw-brightness: ;
|
||||
--tw-contrast: ;
|
||||
--tw-grayscale: ;
|
||||
--tw-hue-rotate: ;
|
||||
--tw-invert: ;
|
||||
--tw-saturate: ;
|
||||
--tw-sepia: ;
|
||||
--tw-drop-shadow: ;
|
||||
--tw-backdrop-blur: ;
|
||||
--tw-backdrop-brightness: ;
|
||||
--tw-backdrop-contrast: ;
|
||||
--tw-backdrop-grayscale: ;
|
||||
--tw-backdrop-hue-rotate: ;
|
||||
--tw-backdrop-invert: ;
|
||||
--tw-backdrop-opacity: ;
|
||||
--tw-backdrop-saturate: ;
|
||||
--tw-backdrop-sepia: ;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.container {
|
||||
max-width: 640px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.container {
|
||||
max-width: 768px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.container {
|
||||
max-width: 1024px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.container {
|
||||
max-width: 1280px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1536px) {
|
||||
.container {
|
||||
max-width: 1536px;
|
||||
}
|
||||
}
|
||||
|
||||
.col-span-2 {
|
||||
grid-column: span 2 / span 2;
|
||||
}
|
||||
|
||||
.mt-20 {
|
||||
margin-top: 5rem;
|
||||
}
|
||||
|
||||
.mt-6 {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.h-20 {
|
||||
height: 5rem;
|
||||
}
|
||||
|
||||
.w-20 {
|
||||
width: 5rem;
|
||||
}
|
||||
|
||||
.max-w-screen-md {
|
||||
max-width: 768px;
|
||||
}
|
||||
|
||||
.grid-cols-2 {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.flex-col {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.items-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.justify-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.justify-stretch {
|
||||
justify-content: stretch;
|
||||
}
|
||||
|
||||
.justify-items-stretch {
|
||||
justify-items: stretch;
|
||||
}
|
||||
|
||||
.gap-2 {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.space-x-2 > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-space-x-reverse: 0;
|
||||
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
|
||||
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
|
||||
}
|
||||
|
||||
.justify-self-start {
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
.justify-self-end {
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
.overflow-visible {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.rounded {
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.rounded-full {
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.bg-gray-100 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-gray-200 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(229 231 235 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-green-300 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(134 239 172 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-red-300 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(252 165 165 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.p-4 {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.p-5 {
|
||||
padding: 1.25rem;
|
||||
}
|
||||
|
||||
.text-slate-500 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(100 116 139 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.shadow-inner {
|
||||
--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
|
||||
--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
||||
|
||||
.btn {
|
||||
border-radius: 0.25rem;
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(229 231 235 / var(--tw-bg-opacity));
|
||||
--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
|
||||
--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
||||
|
||||
.btn-active {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(209 213 219 / var(--tw-bg-opacity));
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(0 0 0 / var(--tw-text-opacity));
|
||||
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
||||
--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
||||
|
||||
.btn-active:hover {
|
||||
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
||||
--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
1
internal/static/icons/feather-sprite.svg
Normal file
1
internal/static/icons/feather-sprite.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 59 KiB |
1
internal/static/js/htmx.min.js
vendored
Normal file
1
internal/static/js/htmx.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
8
internal/ui.go
Normal file
8
internal/ui.go
Normal file
|
@ -0,0 +1,8 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"embed"
|
||||
)
|
||||
|
||||
//go:embed ui
|
||||
var Templates embed.FS
|
16
internal/ui/components/base.tmpl
Normal file
16
internal/ui/components/base.tmpl
Normal file
|
@ -0,0 +1,16 @@
|
|||
{{define "base"}}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Zdravko - {{template "title" .}}</title>
|
||||
<link rel="stylesheet" href="/static/css/tailwind.css">
|
||||
</head>
|
||||
<body class="bg-gray-100">
|
||||
{{template "main" .}}
|
||||
<script src="/static/js/htmx.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
12
internal/ui/components/icon.tmpl
Normal file
12
internal/ui/components/icon.tmpl
Normal file
|
@ -0,0 +1,12 @@
|
|||
{{ define "icon" }}
|
||||
<svg
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="feather"
|
||||
>
|
||||
<use href="/static/icons/feather-sprite.svg#{{.}}" />
|
||||
</svg>
|
||||
{{ end }}
|
30
internal/ui/pages/index.tmpl
Normal file
30
internal/ui/pages/index.tmpl
Normal file
|
@ -0,0 +1,30 @@
|
|||
{{define "title"}}Home{{end}}
|
||||
|
||||
{{define "main"}}
|
||||
<div class="container max-w-screen-md mt-6 flex flex-col">
|
||||
<nav class="justify-center flex space-x-2">
|
||||
<a href="/" class="btn btn-active">Status</a>
|
||||
<a href="/incidents" class="btn">Incidents</a>
|
||||
<a href="/about" class="btn">About</a>
|
||||
</nav>
|
||||
<div class="flex flex-col items-center mt-20">
|
||||
<svg class="feather h-20 w-20 rounded-full bg-green-300 p-4 overflow-visible"><use href="/static/icons/feather-sprite.svg#check" /></svg>
|
||||
<h1 class="text-slate-500">All services are online</h1>
|
||||
<p class="text-slate-500">Last updated on Feb 10 at 10:55am UTC</p>
|
||||
</div>
|
||||
<div class="flex flex-col items-center mt-20">
|
||||
<svg class="feather h-20 w-20 rounded-full bg-red-300 p-4 overflow-visible"><use href="/static/icons/feather-sprite.svg#alert-triangle" /></svg>
|
||||
<h3 class="text-slate-500">Degraded performance</h3>
|
||||
<p class="text-slate-500">Last updated on Feb 10 at 10:55am UTC</p>
|
||||
</div>
|
||||
<div class="grid justify-items-stretch justify-stretch items-center mt-20 bg-gray-200 shadow-inner p-5 rounded">
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<div class="">foo.bar</div>
|
||||
<div class="justify-self-end">100% uptime</div>
|
||||
<div class="col-span-2">todo: bars showing uptime</div>
|
||||
<div class="text-slate-500 justify-self-start">90 days ago</div>
|
||||
<div class="text-slate-500 justify-self-end">Today</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
37
justfile
Normal file
37
justfile
Normal file
|
@ -0,0 +1,37 @@
|
|||
STATIC_DIR := "./internal/static"
|
||||
|
||||
# Start devbox shell
|
||||
shell:
|
||||
devbox shell
|
||||
|
||||
tailwindcss-build:
|
||||
tailwindcss build -i {{STATIC_DIR}}/css/main.css -o {{STATIC_DIR}}/css/tailwind.css
|
||||
|
||||
htmx-download:
|
||||
mkdir -p {{STATIC_DIR}}/js
|
||||
curl -sLo {{STATIC_DIR}}/js/htmx.min.js https://unpkg.com/htmx.org/dist/htmx.min.js
|
||||
|
||||
feather-icons-download:
|
||||
mkdir -p {{STATIC_DIR}}/icons
|
||||
curl -sLo {{STATIC_DIR}}/icons/feather-sprite.svg https://unpkg.com/feather-icons/dist/feather-sprite.svg
|
||||
|
||||
generate:
|
||||
go generate ./...
|
||||
|
||||
# Start temporal which is accassible at http://localhost:8233/
|
||||
run-temporal:
|
||||
temporal server start-dev
|
||||
|
||||
# Start web server accessible at http://localhost:8080/
|
||||
run-server:
|
||||
go build -o dist/server cmd/server/main.go
|
||||
./dist/server
|
||||
|
||||
# Run worker
|
||||
run-worker:
|
||||
go build -o dist/worker cmd/worker/main.go
|
||||
./dist/worker
|
||||
|
||||
# Run full development environment
|
||||
run:
|
||||
devbox services up
|
19
process-compose.yml
Normal file
19
process-compose.yml
Normal file
|
@ -0,0 +1,19 @@
|
|||
version: "0.5"
|
||||
|
||||
processes:
|
||||
tailwind:
|
||||
command: watchexec -r -e go,tmpl,css just tailwindcss-build
|
||||
availability:
|
||||
restart: "always"
|
||||
server:
|
||||
command: watchexec -r -e go,tmpl,css just run-server
|
||||
availability:
|
||||
restart: "always"
|
||||
worker:
|
||||
command: watchexec -r -e go,tmpl,css just run-worker
|
||||
availability:
|
||||
restart: "always"
|
||||
temporal:
|
||||
command: just run-temporal
|
||||
availability:
|
||||
restart: "always"
|
10
tailwind.config.js
Normal file
10
tailwind.config.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
module.exports = {
|
||||
content: ["./internal/ui/**/*.{tmpl,go}"],
|
||||
theme: {
|
||||
container: {
|
||||
center: true,
|
||||
},
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
Loading…
Reference in a new issue