diff options
-rw-r--r-- | assets/css/gril.css | 4 | ||||
-rw-r--r-- | modules/grils/grils.go | 37 | ||||
-rw-r--r-- | modules/lists/lists.go | 108 | ||||
-rw-r--r-- | views/gril.html | 21 | ||||
-rw-r--r-- | views/list.html | 26 |
5 files changed, 183 insertions, 13 deletions
diff --git a/assets/css/gril.css b/assets/css/gril.css new file mode 100644 index 0000000..409ef51 --- /dev/null +++ b/assets/css/gril.css | |||
@@ -0,0 +1,4 @@ | |||
1 | h1 > small { | ||
2 | padding-left: 8px; | ||
3 | font-size: 50%; | ||
4 | } \ No newline at end of file | ||
diff --git a/modules/grils/grils.go b/modules/grils/grils.go index 41783a7..047385e 100644 --- a/modules/grils/grils.go +++ b/modules/grils/grils.go | |||
@@ -3,12 +3,14 @@ package grils | |||
3 | import ( | 3 | import ( |
4 | "fagott.pw/charakterin" | 4 | "fagott.pw/charakterin" |
5 | "fagott.pw/grilist/grilist" | 5 | "fagott.pw/grilist/grilist" |
6 | "github.com/julienschmidt/httprouter" | ||
7 | "net/http" | ||
8 | "strconv" | ||
6 | "time" | 9 | "time" |
7 | ) | 10 | ) |
8 | 11 | ||
9 | type GrilsModule struct { | 12 | type GrilsModule struct { |
10 | g *grilist.Grilist | 13 | g *grilist.Grilist |
11 | Test []int | ||
12 | } | 14 | } |
13 | 15 | ||
14 | func (m *GrilsModule) Name() string { | 16 | func (m *GrilsModule) Name() string { |
@@ -17,11 +19,10 @@ func (m *GrilsModule) Name() string { | |||
17 | 19 | ||
18 | func (m *GrilsModule) Init(g *grilist.Grilist) { | 20 | func (m *GrilsModule) Init(g *grilist.Grilist) { |
19 | m.g = g | 21 | m.g = g |
20 | m.Test = append(m.Test, len(m.Test)+1) | 22 | m.g.Router.GET("/gril/:id", m.viewGril) |
21 | } | 23 | } |
22 | 24 | ||
23 | func (m *GrilsModule) Interface() interface{} { | 25 | func (m *GrilsModule) Interface() interface{} { |
24 | m.Test = append(m.Test, len(m.Test)+1) | ||
25 | return m | 26 | return m |
26 | } | 27 | } |
27 | 28 | ||
@@ -29,7 +30,7 @@ func (m *GrilsModule) ProvideDashboardData(user *charakterin.User) []grilist.Das | |||
29 | return []grilist.DashboardCategory{} | 30 | return []grilist.DashboardCategory{} |
30 | } | 31 | } |
31 | 32 | ||
32 | func (m *GrilsModule) FromID(id int) *Gril { | 33 | func (m *GrilsModule) FromID(id int) (*Gril, error) { |
33 | return &Gril{ | 34 | return &Gril{ |
34 | ID: id, | 35 | ID: id, |
35 | KanjiName: "藤林 杏", | 36 | KanjiName: "藤林 杏", |
@@ -38,7 +39,33 @@ func (m *GrilsModule) FromID(id int) *Gril { | |||
38 | Age: 17, | 39 | Age: 17, |
39 | Birthday: time.Now(), | 40 | Birthday: time.Now(), |
40 | Tags: []string{"tsundere", "hair intakes", "hair ribbon", "school uniform", "school crest"}, | 41 | Tags: []string{"tsundere", "hair intakes", "hair ribbon", "school uniform", "school crest"}, |
42 | }, nil | ||
43 | } | ||
44 | |||
45 | func (m *GrilsModule) viewGril(w http.ResponseWriter, r *http.Request, p httprouter.Params) { | ||
46 | loggedIn := false | ||
47 | if user, _ := m.g.Charakterin.GetUserFromRequest(r); user != nil { | ||
48 | loggedIn = true | ||
49 | } | ||
50 | sid := p.ByName("id") | ||
51 | |||
52 | id, err := strconv.Atoi(sid) | ||
53 | if err != nil { | ||
54 | http.Redirect(w, r, "/", 302) | ||
55 | return | ||
41 | } | 56 | } |
57 | |||
58 | gril, err := m.FromID(id) | ||
59 | if err != nil { | ||
60 | http.Redirect(w, r, "/", 302) | ||
61 | return | ||
62 | } | ||
63 | |||
64 | data := make(map[string]interface{}) | ||
65 | data["loggedIn"] = loggedIn | ||
66 | data["gril"] = gril | ||
67 | |||
68 | m.g.Renderer.RenderPage("gril", w, data) | ||
42 | } | 69 | } |
43 | 70 | ||
44 | func New() *GrilsModule { | 71 | func New() *GrilsModule { |
diff --git a/modules/lists/lists.go b/modules/lists/lists.go index 343ba62..519bb36 100644 --- a/modules/lists/lists.go +++ b/modules/lists/lists.go | |||
@@ -2,12 +2,16 @@ package lists | |||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "database/sql" | 4 | "database/sql" |
5 | "errors" | ||
5 | "fagott.pw/charakterin" | 6 | "fagott.pw/charakterin" |
6 | "fagott.pw/grilist/frontend" | 7 | "fagott.pw/grilist/frontend" |
7 | "fagott.pw/grilist/grilist" | 8 | "fagott.pw/grilist/grilist" |
8 | "fagott.pw/grilist/modules/grils" | 9 | "fagott.pw/grilist/modules/grils" |
9 | "fmt" | 10 | "fmt" |
11 | "github.com/julienschmidt/httprouter" | ||
10 | "log" | 12 | "log" |
13 | "net/http" | ||
14 | "strconv" | ||
11 | "time" | 15 | "time" |
12 | ) | 16 | ) |
13 | 17 | ||
@@ -23,8 +27,15 @@ type List struct { | |||
23 | Name string | 27 | Name string |
24 | Description string | 28 | Description string |
25 | Owner *charakterin.User | 29 | Owner *charakterin.User |
26 | ForkOf int | 30 | ForkOf *int |
27 | UpdatedAt time.Time | 31 | UpdatedAt *time.Time |
32 | Grils []*ListGril | ||
33 | } | ||
34 | |||
35 | // ListGril ist ein geranktes Gril | ||
36 | type ListGril struct { | ||
37 | Gril *grils.Gril | ||
38 | Order int | ||
28 | } | 39 | } |
29 | 40 | ||
30 | // Name gibt den Namen des Moduls zurück | 41 | // Name gibt den Namen des Moduls zurück |
@@ -46,6 +57,7 @@ func (m *Module) Init(g *grilist.Grilist) { | |||
46 | log.Fatal("lists: error with grils module") | 57 | log.Fatal("lists: error with grils module") |
47 | } | 58 | } |
48 | m.grils = grilsModule | 59 | m.grils = grilsModule |
60 | m.g.Router.GET("/list/:id", m.viewList) | ||
49 | } | 61 | } |
50 | 62 | ||
51 | // Interface gibt das Modul zurück | 63 | // Interface gibt das Modul zurück |
@@ -53,13 +65,40 @@ func (m *Module) Interface() interface{} { | |||
53 | return m | 65 | return m |
54 | } | 66 | } |
55 | 67 | ||
56 | // GetUserLists gibt die Listen eines Benutzers zurück. | 68 | func (m *Module) getListGrils(list *List) error { |
57 | func (m *Module) GetUserLists(u *charakterin.User) []*List { | 69 | rows, err := m.g.DB.Query(`SELECT gril_id, "order" FROM grilist.lists_grils WHERE list_id = $1`, list.ID) |
70 | if err != nil { | ||
71 | return err | ||
72 | } | ||
73 | |||
74 | defer rows.Close() | ||
75 | for rows.Next() { | ||
76 | var grilID int | ||
77 | lg := &ListGril{} | ||
78 | |||
79 | if err := rows.Scan(&grilID, &lg.Order); err != nil { | ||
80 | log.Println("error scanning row in getListGrils:", err) | ||
81 | continue | ||
82 | } | ||
83 | |||
84 | gril, err := m.grils.FromID(grilID) | ||
85 | if err != nil { | ||
86 | log.Println("error getting listGril:", err) | ||
87 | continue | ||
88 | } | ||
89 | lg.Gril = gril | ||
90 | |||
91 | list.Grils = append(list.Grils, lg) | ||
92 | } | ||
93 | return nil | ||
94 | } | ||
95 | |||
96 | func (m *Module) getLists(whereClause string, params ...interface{}) ([]*List, error) { | ||
58 | var lists []*List | 97 | var lists []*List |
59 | 98 | ||
60 | rows, err := m.g.DB.Query(`SELECT id, name, description, fork_of, updated_at FROM grilist.lists WHERE user_id = $1`, u.ID) | 99 | rows, err := m.g.DB.Query(fmt.Sprintf(`SELECT id, name, description, fork_of, updated_at FROM grilist.lists WHERE %s`, whereClause), params...) |
61 | if err != nil { | 100 | if err != nil { |
62 | return lists | 101 | return nil, err |
63 | } | 102 | } |
64 | 103 | ||
65 | defer rows.Close() | 104 | defer rows.Close() |
@@ -67,16 +106,43 @@ func (m *Module) GetUserLists(u *charakterin.User) []*List { | |||
67 | list := &List{} | 106 | list := &List{} |
68 | 107 | ||
69 | if err := rows.Scan(&list.ID, &list.Name, &list.Description, &list.ForkOf, &list.UpdatedAt); err != nil { | 108 | if err := rows.Scan(&list.ID, &list.Name, &list.Description, &list.ForkOf, &list.UpdatedAt); err != nil { |
70 | log.Println("error scanning row", err) | 109 | log.Println("error scanning row in getLists:", err) |
110 | continue | ||
111 | } | ||
112 | |||
113 | if err := m.getListGrils(list); err != nil { | ||
114 | log.Println(err) | ||
71 | continue | 115 | continue |
72 | } | 116 | } |
73 | 117 | ||
74 | lists = append(lists, list) | 118 | lists = append(lists, list) |
75 | } | 119 | } |
76 | 120 | ||
121 | return lists, nil | ||
122 | } | ||
123 | |||
124 | // GetUserLists gibt die Listen eines Benutzers zurück. | ||
125 | func (m *Module) GetUserLists(u *charakterin.User) []*List { | ||
126 | lists, err := m.getLists(`user_id = $1`, u.ID) | ||
127 | if err != nil { | ||
128 | log.Println(err) | ||
129 | } | ||
77 | return lists | 130 | return lists |
78 | } | 131 | } |
79 | 132 | ||
133 | // FromID sucht nach der Liste mit der gegebenen ID und gibt sie, falls sie existiert, zurück. | ||
134 | func (m *Module) FromID(id int) (*List, error) { | ||
135 | lists, err := m.getLists(`id = $1`, id) | ||
136 | if err != nil { | ||
137 | return nil, err | ||
138 | } | ||
139 | |||
140 | if len(lists) == 0 { | ||
141 | return nil, errors.New("no list found") | ||
142 | } | ||
143 | return lists[0], nil | ||
144 | } | ||
145 | |||
80 | func mkCard(title, description string, actions ...frontend.Action) frontend.Card { | 146 | func mkCard(title, description string, actions ...frontend.Action) frontend.Card { |
81 | card := frontend.Card{ | 147 | card := frontend.Card{ |
82 | Title: title, | 148 | Title: title, |
@@ -102,7 +168,7 @@ func rowsToCard(rows *sql.Rows) []frontend.Card { | |||
102 | continue | 168 | continue |
103 | } | 169 | } |
104 | 170 | ||
105 | cards = append(cards, mkCard(title, description, frontend.Action{"anguckieren", fmt.Sprintf("/lists/%d", id)})) | 171 | cards = append(cards, mkCard(title, description, frontend.Action{"anguckieren", fmt.Sprintf("/list/%d", id)})) |
106 | } | 172 | } |
107 | return cards | 173 | return cards |
108 | } | 174 | } |
@@ -140,6 +206,32 @@ func (m *Module) ProvideDashboardData(user *charakterin.User) []grilist.Dashboar | |||
140 | return categories | 206 | return categories |
141 | } | 207 | } |
142 | 208 | ||
209 | func (m *Module) viewList(w http.ResponseWriter, r *http.Request, p httprouter.Params) { | ||
210 | loggedIn := false | ||
211 | if user, _ := m.g.Charakterin.GetUserFromRequest(r); user != nil { | ||
212 | loggedIn = true | ||
213 | } | ||
214 | sid := p.ByName("id") | ||
215 | |||
216 | id, err := strconv.Atoi(sid) | ||
217 | if err != nil { | ||
218 | http.Redirect(w, r, "/", 302) | ||
219 | return | ||
220 | } | ||
221 | |||
222 | list, err := m.FromID(id) | ||
223 | if err != nil { | ||
224 | http.Redirect(w, r, "/", 302) | ||
225 | return | ||
226 | } | ||
227 | |||
228 | data := make(map[string]interface{}) | ||
229 | data["loggedIn"] = loggedIn | ||
230 | data["list"] = list | ||
231 | |||
232 | m.g.Renderer.RenderPage("list", w, data) | ||
233 | } | ||
234 | |||
143 | // New erstellt eine neue Instanz des Modules | 235 | // New erstellt eine neue Instanz des Modules |
144 | func New() *Module { | 236 | func New() *Module { |
145 | return &Module{} | 237 | return &Module{} |
diff --git a/views/gril.html b/views/gril.html new file mode 100644 index 0000000..d62fc75 --- /dev/null +++ b/views/gril.html | |||
@@ -0,0 +1,21 @@ | |||
1 | {{ define "gril" }} | ||
2 | {{ $gril := .gril }} | ||
3 | <html> | ||
4 | <head> | ||
5 | {{ template "materialize" }} | ||
6 | <title>grilist</title> | ||
7 | <link rel="stylesheet" href="/assets/css/gril.css" /> | ||
8 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> | ||
9 | </head> | ||
10 | <body> | ||
11 | <div class="container"> | ||
12 | {{ if .loggedIn }} | ||
13 | <div class="row right-align"> | ||
14 | <a class="waves-effect waves-teal btn-flat large" style="top: 24px; font-size: 18px" href="/logout">Ausloggen</a> | ||
15 | </div> | ||
16 | {{ end }} | ||
17 | <h1>{{ $gril.RomajiName }}<small>{{ $gril.KanjiName }}</small></h1> | ||
18 | </div> | ||
19 | </body> | ||
20 | </html> | ||
21 | {{ end }} \ No newline at end of file | ||
diff --git a/views/list.html b/views/list.html new file mode 100644 index 0000000..63cfd9c --- /dev/null +++ b/views/list.html | |||
@@ -0,0 +1,26 @@ | |||
1 | {{ define "list" }} | ||
2 | {{ $list := .list }} | ||
3 | <html> | ||
4 | <head> | ||
5 | {{ template "materialize" }} | ||
6 | <title>grilist</title> | ||
7 | <link rel="stylesheet" href="/assets/css/gril.css" /> | ||
8 | <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> | ||
9 | </head> | ||
10 | <body> | ||
11 | <div class="container"> | ||
12 | {{ if .loggedIn }} | ||
13 | <div class="row right-align"> | ||
14 | <a class="waves-effect waves-teal btn-flat large" style="top: 24px; font-size: 18px" href="/logout">Ausloggen</a> | ||
15 | </div> | ||
16 | {{ end }} | ||
17 | <h1>{{ $list.Name }}<small>von xyz</small></h1><br /> | ||
18 | <ul> | ||
19 | {{ range $lg := $list.Grils }} | ||
20 | <li><a href="/gril/{{ $lg.Gril.ID }}">{{ $lg.Gril.RomajiName }}</a></li> | ||
21 | {{ end }} | ||
22 | </ul> | ||
23 | </div> | ||
24 | </body> | ||
25 | </html> | ||
26 | {{ end }} \ No newline at end of file | ||