Author: Adam <git@apiote.tk>
mark books read and to-read
datastructure/book.go | 10 +++ datastructure/item.go | 1 datastructure/readlist.go | 39 +++++++++++++ db/db.go | 58 ++++++++++++++++++++ front/capnproto.go | 4 + front/html.go | 6 ++ front/renderer.go | 1 i18n/en-GB.toml | 10 +++ i18n/i18n.go | 1 inventaire/book.go | 3 - libamuse/account.go | 15 ++++ libamuse/book.go | 3 + libamuse/common.go | 6 +- libamuse/readlist.go | 54 ++++++++++++++++++ router.go | 45 +++++++++++---- static/style/style.css | 6 +- templates/about.html | 2 templates/book.html | 36 ++++++++++++ templates/bookserie.html | 2 templates/experiences.html | 2 templates/film.html | 14 ++-- templates/index.html | 2 templates/person.html | 2 templates/readlist.html | 115 ++++++++++++++++++++++++++++++++++++++++ templates/search.html | 2 templates/tvqueue.html | 3 templates/tvserie.html | 24 ++++---- templates/watchlist.html | 2 tmdb/common.go | 1 wikidata/book.go | 3 wikidata/bookserie.go | 1
diff --git a/datastructure/book.go b/datastructure/book.go index a03de02a64682e4a3d6f8727c703bcb471d8dabf..5eafb73682580254e4df08dcc025aa39acaeb739 100644 --- a/datastructure/book.go +++ b/datastructure/book.go @@ -1,6 +1,8 @@ package datastructure import ( + "notabug.org/apiote/amuse/i18n" + "strings" "time" ) @@ -57,3 +59,11 @@ func (b *Book) SetOnWantList(isOnList bool) { b.IsOnWantList = isOnList } + +func (b Book) GetLastExperienceFull(strings i18n.Translation) string { + return i18n.FormatDate(b.Experiences[0], strings.Global["date_format_full"], strings.Global) +} + +func (b Book) GetLastExperience(strings i18n.Translation, timezone string) string { + return i18n.FormatDateNice(b.Experiences[0], strings, timezone) +} diff --git a/datastructure/item.go b/datastructure/item.go index 49049f609c6edc1ded63cd8fa5abdb1417e47353..fc6dd7d5be64cce5ddc32638ff8f6b48aad3a0cd 100644 --- a/datastructure/item.go +++ b/datastructure/item.go @@ -41,6 +41,7 @@ type Item interface { GetItemInfo() ItemInfo GetItemType() ItemType + SetOnWantList(isOnList bool) } type ItemType string diff --git a/datastructure/readlist.go b/datastructure/readlist.go new file mode 100644 index 0000000000000000000000000000000000000000..423ba9ba732329e6eff866e4634cc451f350615a --- /dev/null +++ b/datastructure/readlist.go @@ -0,0 +1,39 @@ +package datastructure + +type ReadlistEntry struct { + ItemInfo + Id string + HasPrevious bool +} + +type Readlist struct { + List []ReadlistEntry + Page int + Pages int + Genres map[int]string + Query string +} + +func (w *Readlist) SetGenres(m map[int]string) { + w.Genres = m +} + +func (w *Readlist) GetType() ItemType { + return ItemTypeBook +} + +func (w Readlist) NextPage() int { + if w.Page < w.Pages { + return w.Page + 1 + } else { + return w.Page + } +} + +func (w Readlist) PrevPage() int { + if w.Page > 1 { + return w.Page - 1 + } else { + return w.Page + } +} diff --git a/db/db.go b/db/db.go index a9ebc7135c0c3a8d70f40840f84d62d2aca6f413..c37e984dc5e90c267daa3e95e27d3f607696b47d 100644 --- a/db/db.go +++ b/db/db.go @@ -761,6 +761,64 @@ return watchlist, nil } +func GetReadlist(username, filter string, page int) (datastructure.Readlist, error) { + readlist := datastructure.Readlist{} + db, err := sql.Open("sqlite3", utils.DataHome+"/amuse.db") + if err != nil { + fmt.Fprintf(os.Stderr, "DB open err\n") + return readlist, err + } + defer db.Close() + + if page <= 0 { + page = 1 + } + + var pages float64 + row := db.QueryRow(`select count(*) from wantlist where item_type = 'book' and username = ?`, username) + err = row.Scan(&pages) + if err != nil { + return readlist, err + } + readlist.Pages = int(math.Ceil(pages / 18)) + + offset := (page - 1) * 18 + + //todo filter, order by + + var whereClause string + if filter != "" { + whereClause = "and c1.title like '%" + filter + "%'" + } + + rows, err := db.Query(`select distinct c1.item_id, c1.cover, c1.status, c1.title, c1.year_start, c1.based_on, c1.genres, c1.runtime, c1.part, c2.part from (wantlist w natural join item_cache c1) left join (experiences e natural join item_cache c2) on(c1.part-1 = c2.part and c1.collection = c2.collection and e.username = w.username) where c1.item_type = 'book' and w.username = ? `+whereClause+` order by c1.title limit ?,18`, username, offset) + + if err != nil { + fmt.Fprintf(os.Stderr, "Select err: %v\n", err) + return readlist, err + } + defer rows.Close() + + for rows.Next() { + var ( + entry datastructure.ReadlistEntry + prevPart *int + ) + err := rows.Scan(&entry.Id, &entry.Cover, &entry.Status, &entry.Title, &entry.YearStart, &entry.BasedOn, &entry.Genres, &entry.Runtime, &entry.Part, &prevPart) + if err != nil { + fmt.Println("Scan error") + return datastructure.Readlist{}, err + } + + if entry.Part > 0 && prevPart == nil { + entry.HasPrevious = true + } + readlist.List = append(readlist.List, entry) + } + + return readlist, nil +} + func GetTvQueue(username, filter string, page int) (datastructure.TvQueue, error) { tvQueue := datastructure.TvQueue{} db, err := sql.Open("sqlite3", utils.DataHome+"/amuse.db") diff --git a/front/capnproto.go b/front/capnproto.go index ccf53aafbb7f2be51f7bba9383230f900ab64a24..aa36f5d2c5a4b4df199aa4021eb4070e959e47c8 100644 --- a/front/capnproto.go +++ b/front/capnproto.go @@ -79,6 +79,10 @@ func (CapnprotoRenderer) RenderTvQueue(watchlist datastructure.TvQueue, languages []language.Tag) string { return TODO("implement CapnprotoRenderer.RenderTvQueue").(string) } +func (CapnprotoRenderer) RenderReadlist(readlist datastructure.Readlist, languages []language.Tag) string { + return TODO("implement CapnprotoRenderer.RenderWatchlist").(string) +} + func (CapnprotoRenderer) RenderExperiences(experiences datastructure.Experiences, languages []language.Tag) string { return TODO("implement CapnprotoRenderer.RenderExperiences").(string) } diff --git a/front/html.go b/front/html.go index b34f6b54c61d3565440b502242a099603455b9c2..835e18533188c9a519785fbe51898784701d78d7 100644 --- a/front/html.go +++ b/front/html.go @@ -183,6 +183,12 @@ data.State.User = r.user return render(languages, data, "tvqueue") } +func (r HtmlRenderer) RenderReadlist(readlist datastructure.Readlist, languages []language.Tag) string { + data := RenderData{Data: readlist} + data.State.User = r.user + return render(languages, data, "readlist") +} + func (r HtmlRenderer) RenderExperiences(experiences datastructure.Experiences, languages []language.Tag) string { data := RenderData{Data: experiences} data.State.User = r.user diff --git a/front/renderer.go b/front/renderer.go index 796937f207a207c863cb869122f03669bf77c9da..f5a6543927dc04326e6f2c437f9a3617706c3d6e 100644 --- a/front/renderer.go +++ b/front/renderer.go @@ -35,6 +35,7 @@ RenderSignup([]language.Tag, error, *otp.Key, bool, string, string) string RenderSignedup([]language.Tag, []string) string RenderWatchlist(datastructure.Watchlist, []language.Tag) string RenderTvQueue(datastructure.TvQueue, []language.Tag) string + RenderReadlist(datastructure.Readlist, []language.Tag) string RenderExperiences(datastructure.Experiences, []language.Tag) string } diff --git a/i18n/en-GB.toml b/i18n/en-GB.toml index 408a890f480e3e8ef156d536ddfeb1ff2ad7906c..8f70a295766f96b7652fdc304e473746c5f32090 100644 --- a/i18n/en-GB.toml +++ b/i18n/en-GB.toml @@ -166,6 +166,10 @@ genre = "Genre" source = "Source" serie = "Series" part = "Part" +want_read = "Want to read" +read = "Read" +Readlist = "Readlist" +onReadlist = "You want to read this book" [bookSerie] author = "Author" @@ -250,8 +254,12 @@ mischief = "‘Mischief managed’" see_you = "See You next time…" [watchlist] -title = "Watchilst — a·muse" +title = "Watchlist — a·muse" filter = "filter watchlist" + +[readlist] +title = "Readlist — a·muse" +filter = "filter readlist" [tvqueue] title = "TV queue — a·muse" diff --git a/i18n/i18n.go b/i18n/i18n.go index 91a4b87dbd2f8dabfba142903506a83ac4b57eed..4117b965e7442cc2abd9277e0397de33cea0a345 100644 --- a/i18n/i18n.go +++ b/i18n/i18n.go @@ -34,6 +34,7 @@ Signedup map[string]string Login map[string]string Loggedout map[string]string Watchlist map[string]string + Readlist map[string]string Tvqueue map[string]string Experiences map[string]string Error map[string]string diff --git a/inventaire/book.go b/inventaire/book.go index f115906712404706fd692942eb8c7c7d6bb2fa71..666780db667adaf25842156e2c4b1294a2285b31 100644 --- a/inventaire/book.go +++ b/inventaire/book.go @@ -9,8 +9,6 @@ "encoding/json" "net/http" "strings" - "fmt" - "notabug.org/apiote/gott" ) @@ -70,7 +68,6 @@ book.Title = findByTag(response.Entities[id].Labels, language) // todo book.Article from Sitelinks[tag+"wiki"] book.Description = findByTag(response.Entities[id].Descriptions, language) result.Result = book - fmt.Println(book) return gott.Tuple(args), err } diff --git a/libamuse/account.go b/libamuse/account.go index 9f8ea3ac0c2575b28b4607c0da682bab1e8ffcbb..9243a63e1cd0b24c55f3f740c334759c6de25ce4 100644 --- a/libamuse/account.go +++ b/libamuse/account.go @@ -60,7 +60,8 @@ return gott.Tuple(args), err } func getItem(args ...interface{}) (interface{}, error) { - itemType := args[2].(string) + itemTypeName := args[2].(string) + itemType := datastructure.ItemType(itemTypeName) var arg interface{} var err error switch itemType { @@ -81,8 +82,18 @@ Finish() if err == nil { args = arg.(gott.Tuple) } + case datastructure.ItemTypeBook: + arg, err = gott. + NewResult(gott.Tuple(args)). + Bind(getBook). + //Bind(getDescription). // FIXME + Bind(getCover). + Finish() + if err == nil { + args = arg.(gott.Tuple) + } default: - err = errors.New("Wrong ItemType: " + itemType) + err = errors.New("Wrong ItemType: " + itemTypeName) } return gott.Tuple(args), err } diff --git a/libamuse/book.go b/libamuse/book.go index 50b0f2997b853faac6af0da3026654091b1d3fe7..e8038972a5b2c594f2481faad47e746e2a08371a 100644 --- a/libamuse/book.go +++ b/libamuse/book.go @@ -5,6 +5,7 @@ "notabug.org/apiote/amuse/accounts" "notabug.org/apiote/amuse/datastructure" "notabug.org/apiote/amuse/inventaire" "notabug.org/apiote/amuse/wikidata" + "notabug.org/apiote/amuse/db" "errors" @@ -70,6 +71,8 @@ Bind(verifyToken). Bind(getBook). Bind(getDescription). Bind(getCover). + Bind(getBookExperiences). + Bind(isOnWantList). Bind(createRenderer). Map(renderBook). Finish() diff --git a/libamuse/common.go b/libamuse/common.go index c7e99b35170ee1eee0ff4265af68f13aba7e6314..6e6825ba171a6d71d4369f8c7188504a95535f78 100644 --- a/libamuse/common.go +++ b/libamuse/common.go @@ -107,16 +107,16 @@ func isOnWantList(args ...interface{}) (interface{}, error) { data := args[0].(*RequestData) result := args[1].(*Result) - show := result.result.(tmdb.Show) + item := result.result.(datastructure.Item) if result.user.IsEmpty() { return gott.Tuple(args), nil } - itemType := tmdb.GetItemTypeFromShow(show) + itemType := item.GetItemType() isOnList, err := db.IsOnWantList(result.user.Username, data.id, itemType) - show.SetOnWantList(isOnList) + item.SetOnWantList(isOnList) return gott.Tuple(args), err } diff --git a/libamuse/readlist.go b/libamuse/readlist.go new file mode 100644 index 0000000000000000000000000000000000000000..646240caf1f084b984ba3e89e2d769969e5cfc1e --- /dev/null +++ b/libamuse/readlist.go @@ -0,0 +1,54 @@ +package libamuse + +import ( + "notabug.org/apiote/amuse/accounts" + "notabug.org/apiote/amuse/db" + "notabug.org/apiote/amuse/datastructure" + + "notabug.org/apiote/gott" +) + +func getReadlist(args ...interface{}) (interface{}, error) { + request := args[0].(*RequestData) + result := args[1].(*Result) + page := args[2].(int) + watchlist, err := db.GetReadlist(result.user.Username, request.id, page) + result.result = &watchlist + + return gott.Tuple(args), err +} + +func renderReadlist(args ...interface{}) interface{} { + request := args[0].(*RequestData) + result := args[1].(*Result) + page := args[2].(int) + readlist := result.result.(*datastructure.Readlist) + readlist.Page = page + readlist.Query = request.id + result.page = result.renderer.RenderReadlist(*readlist, result.languages) + + return gott.Tuple(args) +} + +func ShowReadlist(username string, auth accounts.Authentication, languages, mimetype, filter string, page int) (string, error) { + auth.Necessary = true + if page <= 0 { + page = 1 + } + request := &RequestData{id: filter, language: languages, mimetype: mimetype, auth: auth, username: username} + r, err := gott. + NewResult(gott.Tuple{request, &Result{}, page}). + Bind(parseLanguage). + Bind(verifyToken). + Bind(verifyUser). + Bind(getReadlist). + Bind(createRenderer). + Map(renderReadlist). + Finish() + + if err != nil { + return "", err + } else { + return r.(gott.Tuple)[1].(*Result).page, nil + } +} diff --git a/router.go b/router.go index bd59ce9e2c6ee16ca55efb92150eeb3bdb8a8dfb..c79a05a2bcdaeefa1245b6d14568fee8f8fa563a 100644 --- a/router.go +++ b/router.go @@ -361,6 +361,20 @@ w.Header().Set("ETag", avatar.Etag) w.Write(avatar.Data) } +func addToWantlist(w http.ResponseWriter, r *http.Request, username string, auth accounts.Authentication, acceptLanguages, mimetype string) { + r.ParseForm() + itemId := r.PostForm.Get("itemId") + itemType := r.PostForm.Get("itemType") + target := "/" + itemType + "s/" + itemId + err := libamuse.AddToWantlist(username, auth, itemId, itemType, acceptLanguages, mimetype) + if err != nil { + render("", err, w, acceptLanguages, mimetype) + } else { + w.Header().Add("Location", target) + w.WriteHeader(303) + } +} + func userWatchlist(w http.ResponseWriter, r *http.Request, username string, auth accounts.Authentication, acceptLanguages string, mimetype string) { if r.Method == "" || r.Method == "GET" { var page int @@ -370,17 +384,7 @@ fmt.Sscanf(r.Form.Get("page"), "%d", &page) watchlist, err := libamuse.ShowWatchlist(username, auth, acceptLanguages, mimetype, filter, page) render(watchlist, err, w, acceptLanguages, mimetype) } else if r.Method == "POST" { - r.ParseForm() - itemId := r.PostForm.Get("itemId") - itemType := r.PostForm.Get("itemType") - target := "/" + itemType + "s/" + itemId - err := libamuse.AddToWantlist(username, auth, itemId, itemType, acceptLanguages, mimetype) - if err != nil { - render("", err, w, acceptLanguages, mimetype) - } else { - w.Header().Add("Location", target) - w.WriteHeader(303) - } + addToWantlist(w, r, username, auth, acceptLanguages, mimetype) } } @@ -408,6 +412,19 @@ } } } +func userReadlist(w http.ResponseWriter, r *http.Request, username string, auth accounts.Authentication, acceptLanguages string, mimetype string) { + if r.Method == "" || r.Method == "GET" { + var page int + r.ParseForm() + filter := r.Form.Get("filter") + fmt.Sscanf(r.Form.Get("page"), "%d", &page) + readlist, err := libamuse.ShowReadlist(username, auth, acceptLanguages, mimetype, filter, page) + render(readlist, err, w, acceptLanguages, mimetype) + } else if r.Method == "POST" { + addToWantlist(w, r, username, auth, acceptLanguages, mimetype) + } +} + func userExperiences(w http.ResponseWriter, r *http.Request, username string, auth accounts.Authentication, acceptLanguages string, mimetype string) { if r.Method == "" || r.Method == "GET" { var page int @@ -424,8 +441,8 @@ isOtherTime := r.PostForm.Get("isOtherTime") == "true" var datetime string if isOtherTime { - date := r.PostForm.Get("watchedDate") - time := r.PostForm.Get("watchedTime") + date := r.PostForm.Get("experiencedDate") + time := r.PostForm.Get("experiencedTime") datetime = date + "T" + time + ":00" } else { datetime = "" @@ -496,6 +513,8 @@ case "watchlist": userWatchlist(w, r, username, auth, acceptLanguages, mimetype) case "tvqueue": userTvQueue(w, r, username, auth, acceptLanguages, mimetype) + case "readlist": + userReadlist(w, r, username, auth, acceptLanguages, mimetype) case "experiences": userExperiences(w, r, username, auth, acceptLanguages, mimetype) case "sessions": diff --git a/static/style/style.css b/static/style/style.css index cafe4bc437b0b8160a762f2431dd9e33f3b88186..901f02040a9d8386aaa77a1ae5b99c35a3e16700 100644 --- a/static/style/style.css +++ b/static/style/style.css @@ -105,15 +105,15 @@ nav input:checked ~ ul { display: block; } -.watched-box, .watched-box-flex { +.experienced-box, .experienced-box-flex { display: none; } -.watched-datetime-check:checked ~ .watched-box { +.experienced-datetime-check:checked ~ .experienced-box { display: block; } -.watched-datetime-check:checked ~ .watched-box-flex { +.experienced-datetime-check:checked ~ .experienced-box-flex { display: flex; } diff --git a/templates/about.html b/templates/about.html index 0bbda468b00d0ff5f4479384505817f4b1145b0a..468eb7b438fc39590e547f86b7c32d5a0c0cfa1f 100644 --- a/templates/about.html +++ b/templates/about.html @@ -28,7 +28,7 @@
{{.Data.SerieName}}{{if .Data.PartInSerie}}, {{.Strings.Book.part}} {{.Data.PartInSerie}}{{end}}
{{end}} <p class="sans text-grey margin-top-1 margin-bottom-_5"><span class="material-icon"></span> {{$.Strings.Book.source}}</p> <p class="margin-lr-1 sans margin-tb-_5">{{range .Data.Source}}<a href="{{.Url}}">{{.Name}}</a><br/>{{end}}</p> + {{if and (.Data.IsOnWantList) (not .State.User.IsEmpty)}} + <p class="sans text-grey margin-top-1 margin-bottom-_5"><span class="material-icon"></span> {{.Strings.Book.Readlist}}</p> + <p class="margin-lr-1 sans margin-tb-_5">{{.Strings.Book.onReadlist}}</p> + {{end}} + {{if .Data.Experiences}} + <p class="sans text-grey margin-top-1 margin-bottom-_5"><span class="material-icon"></span> {{.Strings.Book.read}}</p> + <p class="margin-lr-1 sans margin-tb-_5">{{len .Data.Experiences}} times<br/> + last time <span title="{{.Data.GetLastExperienceFull .Strings}}">{{.Data.GetLastExperience .Strings .State.User.Timezone}}</p> + {{end}} </div> <div class="desktop-w6 phone-w12 margin-top-10 padding-lr-2 margin-bottom-2"> + <div> + {{if not .State.User.IsEmpty}} + <div class="flex flex-row flex-wrap flex-centre flex-align-centre"> + {{if and (not .Data.IsOnWantList) (not .Data.Experiences)}} + <form action="/users/{{.State.User.Username}}/readlist/" method="POST" class="margin-tb-_5 margin-lr-1"> + <input type="hidden" name="itemId" value="{{.Data.Id}}" /> + <input type="hidden" name="itemType" value="book" /> + <button type="submit" class="border-text hover-bg-grey padding-tb-_25 cursor-hand text font-2"><span class="padding-lr-_5 material-icon font-2"></span><span class="sans padding-lr-_5">{{.Strings.Book.want_read}}</span></button> + </form> + {{end}} + <form action="/users/{{.State.User.Username}}/experiences/" method="POST" class="margin-tb-_5 margin-lr-1"> + <input type="hidden" name="itemId" value="{{.Data.Id}}" /> + <input type="hidden" name="itemType" value="book" /> + <button type="submit" class="border-text hover-bg-dark-accent padding-tb-_25 cursor-hand text-black font-2"><span class="padding-lr-_5 material-icon font-2"></span><span class="sans padding-lr-_5">{{.Strings.Book.read}}</span></button><label for="read-datetime-check" class="cursor-hand bg-accent inline-block font-2 relative top-m_3 height-3_3 text-black"> + <span class="material-icon"></span> + </label> + <input type="checkbox" id="read-datetime-check" class="display-none experienced-datetime-check" name="isOtherTime" value="true"/> + <div class="experienced-box absolute"> + <input type="date" name="experiencedDate" class="margin-lr-_5 margin-tb-_5 text bg-none border-none" /> + <input type="time" name="experiencedTime" class="margin-lr-_5 margin-tb-_5 text bg-none border-none" /> + </div> + </form> + </div> + {{end}} + </div> <p>{{.Data.Description}}</p> <hr class="material-icon text-grey hr-book"/> </div> diff --git a/templates/bookserie.html b/templates/bookserie.html index 9bc78b5024735089dd2a6336d68ba9f7871b96d8..0becd3a4bd58bc244f6d0ea56baa3a6515edb4c3 100644 --- a/templates/bookserie.html +++ b/templates/bookserie.html @@ -31,7 +31,7 @@{{.Strings.Film.source}} <p class="margin-lr-1 sans margin-tb-_5"><a href="{{.Data.Source}}">TheMovieDB</a></p> {{if and (.Data.IsOnWantList) (not .State.User.IsEmpty)}} <p class="sans text-grey margin-top-1 margin-bottom-_5"><span class="material-icon"></span> {{.Strings.Film.Watchlist}}</p> - <p class="margin-lr-1 sans margin-tb-_5">{{.Strings.Film.onWatchlist}}<br/> + <p class="margin-lr-1 sans margin-tb-_5">{{.Strings.Film.onWatchlist}}</p> {{end}} {{if .Data.Experiences}} <p class="sans text-grey margin-top-1 margin-bottom-_5"><span class="material-icon"></span> {{.Strings.Film.watched}}</p> @@ -118,13 +118,13 @@ {{end}} <form action="/users/{{.State.User.Username}}/experiences/" method="POST" class="margin-tb-_5 margin-lr-1"> <input type="hidden" name="itemId" value="{{.Data.Id}}" /> <input type="hidden" name="itemType" value="film" /> - <button type="submit" class="border-text hover-bg-dark-accent padding-tb-_25 cursor-hand text-black font-2"><span class="padding-lr-_5 material-icon font-2"></span><span class="sans padding-lr-_5">{{.Strings.Film.watched}}</span></button><label for="watched-datetime-check" class="cursor-hand bg-accent inline-block font-2 relative top-m_3 height-3_3 text-black"> + <button type="submit" class="border-text hover-bg-dark-accent padding-tb-_25 cursor-hand text-black font-2"><span class="padding-lr-_5 material-icon font-2"></span><span class="sans padding-lr-_5">{{.Strings.Film.watched}}</span></button><label for="experienced-datetime-check" class="cursor-hand bg-accent inline-block font-2 relative top-m_3 height-3_3 text-black"> <span class="material-icon"></span> </label> - <input type="checkbox" id="watched-datetime-check" class="display-none watched-datetime-check" name="isOtherTime" value="true"/> - <div class="watched-box absolute"> - <input type="date" name="watchedDate" class="margin-lr-_5 margin-tb-_5 text bg-none border-none" /> - <input type="time" name="watchedTime" class="margin-lr-_5 margin-tb-_5 text bg-none border-none" /> + <input type="checkbox" id="experienced-datetime-check" class="display-none experienced-datetime-check" name="isOtherTime" value="true"/> + <div class="experienced-box absolute"> + <input type="date" name="experiencedDate" class="margin-lr-_5 margin-tb-_5 text bg-none border-none" /> + <input type="time" name="experiencedTime" class="margin-lr-_5 margin-tb-_5 text bg-none border-none" /> </div> </form> </div> diff --git a/templates/index.html b/templates/index.html index 4482091a8c1345ca945b885c4c417b05736c23de..bcf0ce9f2ef4f60a1c44056e01093b166ac7d003 100644 --- a/templates/index.html +++ b/templates/index.html @@ -28,7 +28,7 @@