Skip to content

Commit 5fe3204

Browse files
GluekGluek
authored andcommitted
add webview2, switch from gorm to raw sql first steps
1 parent 31ab700 commit 5fe3204

File tree

10 files changed

+787
-101
lines changed

10 files changed

+787
-101
lines changed

.vscode/launch.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": []
7+
}

Taskfile.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,7 @@ tasks:
1717
desc: Run the application
1818
cmds:
1919
- go run ./cmd/server/...
20+
build:
21+
desc: Run the application
22+
cmds:
23+
- go build -ldflags -H=windowsgui ./cmd/server/...

cmd/server/main.go

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,40 @@
11
package main
22

33
import (
4-
"fmt"
4+
"html/template"
55
"local/timetracker/internal/database"
66
"log"
77
"mime"
88
"net/http"
9+
"os"
910

1011
"github.com/gorilla/mux"
12+
"github.com/jchv/go-webview2"
1113
)
1214

15+
var (
16+
pwd, _ = os.Getwd()
17+
)
18+
19+
type PageData struct {
20+
Title string
21+
Entries []database.Timeframe
22+
}
23+
1324
func main() {
25+
go webServer()
26+
27+
webView()
28+
}
29+
30+
func webServer() {
1431
database.Connect()
15-
database.Migrate()
32+
1633
router := mux.NewRouter()
1734

18-
http.Handle("/", http.FileServer(http.Dir("D:\\Dev\\Go\\TimeTracker\\internal\\templates\\")))
35+
http.Handle("/", http.FileServer(http.Dir(pwd+"/internal/templates/")))
1936
http.Handle("/api/", router)
37+
//http.HandleFunc("/layout", TemplateHandler)
2038
RegisterEntryRoutes(router)
2139

2240
// Windows may be missing this
@@ -26,14 +44,42 @@ func main() {
2644
}
2745

2846
func RegisterEntryRoutes(router *mux.Router) {
29-
router.HandleFunc("/api/hello", h1).Methods("GET")
3047
router.HandleFunc("/api/timeframes", database.CreateEntry).Methods("POST")
3148
router.HandleFunc("/api/timeframes", database.GetEntries).Methods("GET")
3249
router.HandleFunc("/api/timeframes/{id}", database.GetEntryByID).Methods("GET")
3350
router.HandleFunc("/api/timeframes/{id}", database.UpdateEntry).Methods("PUT")
3451
router.HandleFunc("/api/timeframes/{id}", database.DeleteEntry).Methods("DELETE")
3552
}
3653

37-
func h1(w http.ResponseWriter, r *http.Request) {
38-
fmt.Println("Test!")
54+
func TemplateHandler(w http.ResponseWriter, r *http.Request) {
55+
var entries []database.Timeframe
56+
//database.Instance.Find(&entries)
57+
tmpl := template.Must(template.ParseFiles(pwd + "/internal/templates/templtest.html"))
58+
data := PageData{
59+
Title: "My Title",
60+
Entries: entries,
61+
}
62+
tmpl.Execute(w, data)
63+
}
64+
65+
func webView() {
66+
w := webview2.NewWithOptions(webview2.WebViewOptions{
67+
Debug: true, // To display the development tools
68+
AutoFocus: true,
69+
WindowOptions: webview2.WindowOptions{
70+
Title: "Time Tracker",
71+
Width: 200,
72+
Height: 200,
73+
IconId: 2, // icon resource id
74+
Center: true,
75+
},
76+
})
77+
if w == nil {
78+
log.Fatalln("Failed to load webview.")
79+
}
80+
defer w.Destroy()
81+
82+
w.SetSize(600, 600, webview2.HintNone)
83+
w.Navigate("http://localhost:34115/")
84+
w.Run()
3985
}

go.mod

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,28 @@ require (
99
)
1010

1111
require (
12+
github.com/dustin/go-humanize v1.0.1 // indirect
13+
github.com/google/uuid v1.3.0 // indirect
14+
github.com/jchv/go-webview2 v0.0.0-20221223143126-dc24628cff85 // indirect
15+
github.com/jchv/go-winloader v0.0.0-20200815041850-dec1ee9a7fd5 // indirect
1216
github.com/jinzhu/inflection v1.0.0 // indirect
1317
github.com/jinzhu/now v1.1.5 // indirect
18+
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
19+
github.com/mattn/go-isatty v0.0.16 // indirect
1420
github.com/mattn/go-sqlite3 v1.14.18 // indirect
21+
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
22+
golang.org/x/mod v0.3.0 // indirect
23+
golang.org/x/sys v0.9.0 // indirect
24+
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78 // indirect
25+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
26+
lukechampine.com/uint128 v1.2.0 // indirect
27+
modernc.org/cc/v3 v3.40.0 // indirect
28+
modernc.org/ccgo/v3 v3.16.13 // indirect
29+
modernc.org/libc v1.29.0 // indirect
30+
modernc.org/mathutil v1.6.0 // indirect
31+
modernc.org/memory v1.7.2 // indirect
32+
modernc.org/opt v0.1.3 // indirect
33+
modernc.org/sqlite v1.27.0 // indirect
34+
modernc.org/strutil v1.1.3 // indirect
35+
modernc.org/token v1.0.1 // indirect
1536
)

go.sum

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,75 @@
1+
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
2+
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
3+
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
4+
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
15
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
26
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
7+
github.com/jchv/go-webview2 v0.0.0-20221223143126-dc24628cff85 h1:t6lhRbwURcdWgp8OsJlq6sOfWMOXP21YuiCicjutHv4=
8+
github.com/jchv/go-webview2 v0.0.0-20221223143126-dc24628cff85/go.mod h1:/BNVc0Sw3Wj6Sz9uSxPwhCEUhhWs92hPde75K2YV24A=
9+
github.com/jchv/go-winloader v0.0.0-20200815041850-dec1ee9a7fd5 h1:pdFFlHXY9tZXmJz+tRSm1DzYEH4ebha7cffmm607bMU=
10+
github.com/jchv/go-winloader v0.0.0-20200815041850-dec1ee9a7fd5/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs=
311
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
412
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
513
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
614
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
15+
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
16+
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
17+
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
18+
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
719
github.com/mattn/go-sqlite3 v1.14.18 h1:JL0eqdCOq6DJVNPSvArO/bIV9/P7fbGrV00LZHc+5aI=
820
github.com/mattn/go-sqlite3 v1.14.18/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
21+
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
22+
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
23+
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
24+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
25+
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
26+
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
27+
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
28+
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
29+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
30+
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
31+
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
32+
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
33+
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
34+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
35+
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
36+
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
37+
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
38+
golang.org/x/sys v0.0.0-20210218145245-beda7e5e158e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
39+
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
40+
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
41+
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
42+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
43+
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
44+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
45+
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
46+
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78 h1:M8tBwCtWD/cZV9DZpFYRUgaymAYAr+aIUTWzDaM3uPs=
47+
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
48+
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
49+
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
50+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
51+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
952
gorm.io/driver/sqlite v1.5.4 h1:IqXwXi8M/ZlPzH/947tn5uik3aYQslP9BVveoax0nV0=
1053
gorm.io/driver/sqlite v1.5.4/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed+4=
1154
gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls=
1255
gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
56+
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
57+
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
58+
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
59+
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
60+
modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
61+
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
62+
modernc.org/libc v1.29.0 h1:tTFRFq69YKCF2QyGNuRUQxKBm1uZZLubf6Cjh/pVHXs=
63+
modernc.org/libc v1.29.0/go.mod h1:DaG/4Q3LRRdqpiLyP0C2m1B8ZMGkQ+cCgOIjEtQlYhQ=
64+
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
65+
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
66+
modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=
67+
modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
68+
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
69+
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
70+
modernc.org/sqlite v1.27.0 h1:MpKAHoyYB7xqcwnUwkuD+npwEa0fojF0B5QRbN+auJ8=
71+
modernc.org/sqlite v1.27.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0=
72+
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
73+
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
74+
modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
75+
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=

internal/database/client.go

Lines changed: 43 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,22 @@ package database
22

33
import (
44
"encoding/json"
5+
"fmt"
56
"log"
67
"net/http"
8+
"os"
79
"time"
810

9-
"github.com/gorilla/mux"
10-
"gorm.io/driver/sqlite"
11-
"gorm.io/gorm"
11+
"database/sql"
12+
13+
_ "modernc.org/sqlite"
1214
)
1315

14-
var Instance *gorm.DB
16+
var DB *sql.DB
1517
var err error
18+
var (
19+
pwd, _ = os.Getwd()
20+
)
1621

1722
type Timeframe struct {
1823
ID string `json:"id"`
@@ -30,76 +35,61 @@ type Config struct {
3035
}
3136

3237
func Connect() {
33-
Instance, err = gorm.Open(sqlite.Open("./internal/database/timetrack.sqlite"), &gorm.Config{})
38+
DB, err = sql.Open("sqlite", pwd+"/timetrack.sqlite")
3439
if err != nil {
3540
log.Fatal(err)
3641
panic("Cannot connect to DB")
3742
}
3843
log.Println("Connected to Database...")
3944
}
4045

41-
func Migrate() {
42-
Instance.AutoMigrate(&Timeframe{})
43-
log.Println("Database Migration Completed...")
44-
}
45-
4646
func checkIfEntryExists(entryID string) bool {
47-
var entry Timeframe
48-
Instance.First(&entry, entryID)
49-
return entry.ID != ""
47+
return true
5048
}
5149

5250
func CreateEntry(w http.ResponseWriter, r *http.Request) {
53-
w.Header().Set("Content-Type", "application/json")
54-
var entry Timeframe
55-
json.NewDecoder(r.Body).Decode(&entry)
56-
Instance.Create(&entry)
57-
json.NewEncoder(w).Encode(entry)
51+
5852
}
5953

6054
func GetEntryByID(w http.ResponseWriter, r *http.Request) {
61-
entryID := mux.Vars(r)["id"]
62-
if !checkIfEntryExists(entryID) {
63-
json.NewEncoder(w).Encode("Entry Not Found!")
64-
return
65-
}
66-
var entry Timeframe
67-
Instance.First(&entry, entryID)
68-
w.Header().Set("Content-Type", "application/json")
69-
json.NewEncoder(w).Encode(entry)
55+
7056
}
7157

7258
func GetEntries(w http.ResponseWriter, r *http.Request) {
73-
var entries []Timeframe
74-
Instance.Find(&entries)
75-
w.Header().Set("Content-Type", "application/json")
76-
w.WriteHeader(http.StatusOK)
77-
json.NewEncoder(w).Encode(entries)
59+
var timeframes []Timeframe = []Timeframe{}
60+
var timef Timeframe
61+
62+
rows, _ := DB.Query("SELECT * FROM timeframes")
63+
64+
for rows.Next() {
65+
timef = Timeframe{}
66+
rows.Scan(&timef.ID, &timef.Year, &timef.Month, &timef.Day,
67+
&timef.Start, &timef.End, &timef.Duration, &timef.Project)
68+
timeframes = append(timeframes, timef)
69+
log.Printf("ID: %s", timef.ID)
70+
}
71+
72+
err = json.NewEncoder(w).Encode(&timeframes)
73+
if err != nil {
74+
fmt.Print(err)
75+
}
7876
}
7977

80-
func UpdateEntry(w http.ResponseWriter, r *http.Request) {
81-
entryID := mux.Vars(r)["id"]
82-
if !checkIfEntryExists(entryID) {
83-
json.NewEncoder(w).Encode("Entry Not Found!")
84-
return
78+
func GetVersion() {
79+
var version string
80+
err = DB.QueryRow("SELECT SQLITE_VERSION()").Scan(&version)
81+
82+
if err != nil {
83+
log.Fatal(err)
8584
}
86-
var entry Timeframe
87-
Instance.First(&entry, entryID)
88-
json.NewDecoder(r.Body).Decode(&entry)
89-
Instance.Save(&entry)
90-
w.Header().Set("Content-Type", "application/json")
91-
json.NewEncoder(w).Encode(entry)
85+
86+
fmt.Println(version)
87+
}
88+
89+
func UpdateEntry(w http.ResponseWriter, r *http.Request) {
90+
9291
}
9392

9493
func DeleteEntry(w http.ResponseWriter, r *http.Request) {
95-
w.Header().Set("Content-Type", "application/json")
96-
entryID := mux.Vars(r)["id"]
97-
if !checkIfEntryExists(entryID) {
98-
w.WriteHeader(http.StatusNotFound)
99-
json.NewEncoder(w).Encode("Entry Not Found!")
100-
return
101-
}
102-
var entry Timeframe
103-
Instance.Delete(&entry, entryID)
104-
json.NewEncoder(w).Encode("Entry Deleted Succesfully!")
94+
10595
}

internal/templates/index.html

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,37 @@
77
<link rel="stylesheet" href="/tailwind.css"/>
88
</head>
99
<body>
10-
<h1 class="text-3xl font-bold text-teal-500">Hello World!</h1>
11-
<button class="btn btn-primary">Button</button>
12-
</body>
10+
<div class="navbar bg-base-100">
11+
<div class="flex-1">
12+
<a class="text-3xl font-bold px-3">TimeTracker</a>
13+
<a class="btn btn-ghost text-xl">Days</a>
14+
<a class="btn btn-ghost text-xl">Projects</a>
15+
<a class="btn btn-ghost text-xl" href="/layout">Template Test</a>
16+
</div>
17+
</div>
18+
<div class="container p-5">
19+
<form>
20+
<div class="join p-2 border-2 border-slate-500">
21+
<div class="join-item px-2">
22+
<a class="text-xl">Start</a>
23+
<input type="time" id="start" name="start" min="06:00" max="20:00" required />
24+
</div>
25+
<div class="join-item px-2">
26+
<a class="text-xl">End</a>
27+
<input type="time" id="end" name="end" min="06:00" max="20:00" required />
28+
</div>
29+
<select class="join-item select w-full max-w-xs" name="project">
30+
<option disabled selected>Pick your project</option>
31+
<option>Homer</option>
32+
<option>Marge</option>
33+
<option>Bart</option>
34+
<option>Lisa</option>
35+
<option>Maggie</option>
36+
</select>
37+
<button class="btn join-item">Add</button>
38+
</div>
39+
</form>
40+
41+
</div>
42+
</body>
1343
</html>

0 commit comments

Comments
 (0)