Added dynamic support for countries
This commit is contained in:
parent
381444a838
commit
47b9939ead
|
@ -229,6 +229,7 @@ section#results a, section#results button {
|
|||
color: #000;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
dialog {
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
|
|
|
@ -1,14 +1,34 @@
|
|||
CREATE TABLE IF NOT EXISTS "country"
|
||||
(
|
||||
id uuid,
|
||||
iso_name char(2) UNIQUE NOT NULL,
|
||||
name varchar(45) NOT NULL,
|
||||
|
||||
primary key (id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "holiday"
|
||||
(
|
||||
id uuid,
|
||||
country char(2),
|
||||
date date,
|
||||
name varchar(64),
|
||||
country char(2) NOT NULL,
|
||||
date date NOT NULL,
|
||||
name varchar(64) NOT NULL,
|
||||
description varchar(512),
|
||||
is_state boolean,
|
||||
is_religious boolean
|
||||
is_state boolean NOT NULL,
|
||||
is_religious boolean NOT NULL,
|
||||
|
||||
primary key (id),
|
||||
constraint fk_country_id foreign key (country)
|
||||
references country(iso_name) on delete cascade on update cascade
|
||||
);
|
||||
|
||||
INSERT INTO "country" (id, iso_name, name)
|
||||
VALUES
|
||||
('096ca6c4-5c04-47a4-0063-4b4cc6f6b671', 'HR', 'Croatia'),
|
||||
('096ca6c4-5c04-47a4-0063-4b4cc6f6b672', 'US', 'USA'),
|
||||
('096ca6c4-5c04-47a4-0063-4b4cc6f6b673', 'FR', 'France'),
|
||||
('096ca6c4-5c04-47a4-0063-4b4cc6f6b674', 'GB', 'Great Britain');
|
||||
|
||||
INSERT INTO "holiday" (id, country, date, name, description, is_state, is_religious)
|
||||
VALUES
|
||||
('096ca6c4-5c04-47a4-b363-4b4cc6f6b671', 'HR', '2023-01-01', 'Nova godina', '', true, false),
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
func getHolidays(service holiday.Service) gin.HandlerFunc {
|
||||
func getHolidays(service holiday.HolidayService) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
paging := holiday.Paging{PageSize: 50}
|
||||
if err := c.ShouldBindQuery(&paging); err != nil {
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package holiday
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type CountryService struct {
|
||||
DB *sqlx.DB
|
||||
}
|
||||
|
||||
func (s *CountryService) FindById(id uuid.UUID) (Country, error) {
|
||||
var country Country
|
||||
return country, s.DB.Get(&country, `SELECT * FROM "country" WHERE "id" = $1;`, id)
|
||||
}
|
||||
|
||||
func (s *CountryService) Find() ([]Country, error) {
|
||||
var countries []Country
|
||||
return countries, s.DB.Select(&countries, `SELECT * FROM "country";`)
|
||||
}
|
||||
|
||||
func (s *CountryService) Update(country Country) (Country, error) {
|
||||
_, err := s.DB.Exec(`UPDATE country SET "iso_name" = $2, "name" = $3 WHERE "id" = $1`,
|
||||
&country.Id, &country.IsoName, &country.Name,
|
||||
)
|
||||
return country, err
|
||||
}
|
||||
|
||||
func (s *CountryService) Create(country Country) (Country, error) {
|
||||
country.Id = uuid.Must(uuid.NewRandom())
|
||||
_, err := s.DB.Exec(`INSERT INTO country (id, iso_name, name) values ($1, $2, $3)`,
|
||||
&country.Id, &country.IsoName, &country.Name,
|
||||
)
|
||||
return country, err
|
||||
}
|
||||
|
||||
func (s *CountryService) Delete(id uuid.UUID) error {
|
||||
_, err := s.DB.Exec(`DELETE FROM country WHERE "id" = $1`, &id)
|
||||
return err
|
||||
}
|
|
@ -8,11 +8,11 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
type HolidayService struct {
|
||||
DB *sqlx.DB
|
||||
}
|
||||
|
||||
func (s *Service) Find(search Search, paging Paging) ([]Holiday, error) {
|
||||
func (s *HolidayService) Find(search Search, paging Paging) ([]Holiday, error) {
|
||||
var holidays []Holiday
|
||||
var err error
|
||||
if search.Date != nil {
|
||||
|
@ -30,32 +30,32 @@ func (s *Service) Find(search Search, paging Paging) ([]Holiday, error) {
|
|||
return s.paginate(holidays, paging), err
|
||||
}
|
||||
|
||||
func (s *Service) FindById(id uuid.UUID) (Holiday, error) {
|
||||
func (s *HolidayService) FindById(id uuid.UUID) (Holiday, error) {
|
||||
var holiday Holiday
|
||||
return holiday, s.DB.Get(&holiday, `SELECT * FROM "holiday" WHERE "id" = $1;`, id)
|
||||
}
|
||||
|
||||
func (s *Service) findByDate(date time.Time, isState *bool, isReligious *bool, country string) ([]Holiday, error) {
|
||||
func (s *HolidayService) findByDate(date time.Time, isState *bool, isReligious *bool, country string) ([]Holiday, error) {
|
||||
var holidays []Holiday
|
||||
return holidays, s.DB.Select(&holidays, `SELECT * FROM "holiday" WHERE "date" = $1 AND country = $2 `+s.filter(isState, isReligious)+";", date, country)
|
||||
}
|
||||
|
||||
func (s *Service) findForRange(rangeStart time.Time, rangeEnd time.Time, isState *bool, isReligious *bool, country string) ([]Holiday, error) {
|
||||
func (s *HolidayService) findForRange(rangeStart time.Time, rangeEnd time.Time, isState *bool, isReligious *bool, country string) ([]Holiday, error) {
|
||||
var holidays []Holiday
|
||||
return holidays, s.DB.Select(&holidays, `SELECT * FROM "holiday" WHERE "date" BETWEEN $1 AND $2 AND country = $3`+s.filter(isState, isReligious)+";", rangeStart, rangeEnd, country)
|
||||
}
|
||||
|
||||
func (s *Service) findByYear(year int, isState *bool, isReligious *bool, country string) ([]Holiday, error) {
|
||||
func (s *HolidayService) findByYear(year int, isState *bool, isReligious *bool, country string) ([]Holiday, error) {
|
||||
var holidays []Holiday
|
||||
return holidays, s.DB.Select(&holidays, `SELECT * FROM "holiday" WHERE extract(year from "date") = $1 AND country = $2 `+s.filter(isState, isReligious)+";", year, country)
|
||||
}
|
||||
|
||||
func (s *Service) find(isState *bool, isReligious *bool, country string) ([]Holiday, error) {
|
||||
func (s *HolidayService) find(isState *bool, isReligious *bool, country string) ([]Holiday, error) {
|
||||
var holidays []Holiday
|
||||
return holidays, s.DB.Select(&holidays, `SELECT * FROM "holiday" WHERE country = $1 `+s.filter(isState, isReligious)+";", country)
|
||||
}
|
||||
|
||||
func (s *Service) paginate(holidays []Holiday, paging Paging) []Holiday {
|
||||
func (s *HolidayService) paginate(holidays []Holiday, paging Paging) []Holiday {
|
||||
start := paging.Page * paging.PageSize
|
||||
end := (paging.Page + 1) * paging.PageSize
|
||||
if end < len(holidays) {
|
||||
|
@ -67,7 +67,7 @@ func (s *Service) paginate(holidays []Holiday, paging Paging) []Holiday {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *Service) filter(isState *bool, isReligious *bool) string {
|
||||
func (s *HolidayService) filter(isState *bool, isReligious *bool) string {
|
||||
var filters []string
|
||||
if isState != nil {
|
||||
filters = append(filters, "is_state = "+strconv.FormatBool(*isState))
|
||||
|
@ -82,14 +82,14 @@ func (s *Service) filter(isState *bool, isReligious *bool) string {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *Service) Update(holiday Holiday) (Holiday, error) {
|
||||
func (s *HolidayService) Update(holiday Holiday) (Holiday, error) {
|
||||
_, err := s.DB.Exec(`UPDATE holiday SET "country" = $1, "name" = $2, "description" = $3, "date" = $4, "is_state"=$5, "is_religious"=$6 WHERE "id" = $7`,
|
||||
&holiday.Country, &holiday.Name, &holiday.Description, &holiday.Date, &holiday.IsStateHoliday, &holiday.IsReligiousHoliday, &holiday.Id,
|
||||
)
|
||||
return holiday, err
|
||||
}
|
||||
|
||||
func (s *Service) Create(holiday Holiday) (Holiday, error) {
|
||||
func (s *HolidayService) Create(holiday Holiday) (Holiday, error) {
|
||||
holiday.Id = uuid.Must(uuid.NewRandom())
|
||||
_, err := s.DB.Exec(`INSERT INTO holiday (id, country, name, description, date, is_state, is_religious) values ($1, $2, $3, $4, $5, $6, $7)`,
|
||||
&holiday.Id, &holiday.Country, &holiday.Name, &holiday.Description, &holiday.Date, &holiday.IsStateHoliday, &holiday.IsReligiousHoliday,
|
||||
|
@ -97,7 +97,7 @@ func (s *Service) Create(holiday Holiday) (Holiday, error) {
|
|||
return holiday, err
|
||||
}
|
||||
|
||||
func (s *Service) Delete(id uuid.UUID) error {
|
||||
func (s *HolidayService) Delete(id uuid.UUID) error {
|
||||
_, err := s.DB.Exec(`DELETE FROM holiday WHERE "id" = $1`, &id)
|
||||
return err
|
||||
}
|
|
@ -15,6 +15,12 @@ type Holiday struct {
|
|||
IsReligiousHoliday bool `db:"is_religious"`
|
||||
}
|
||||
|
||||
type Country struct {
|
||||
Id uuid.UUID `db:"id"`
|
||||
IsoName string `db:"iso_name"`
|
||||
Name string `db:"name"`
|
||||
}
|
||||
|
||||
type Paging struct {
|
||||
PageSize int `form:"page_size" binging:"min=0"`
|
||||
Page int `form:"page" binging:"min=0"`
|
||||
|
|
101
main.go
101
main.go
|
@ -53,11 +53,12 @@ func main() {
|
|||
|
||||
loadTemplates(g)
|
||||
|
||||
holidayService := holiday.Service{DB: client}
|
||||
holidayService := holiday.HolidayService{DB: client}
|
||||
countryService := holiday.CountryService{DB: client}
|
||||
|
||||
g.GET("/api/v1/holidays", getHolidays(holidayService))
|
||||
|
||||
setupAdminDashboard(g.Group("/admin"), holidayService)
|
||||
setupAdminDashboard(g.Group("/admin"), holidayService, countryService)
|
||||
|
||||
g.GET("/", func(c *gin.Context) {
|
||||
year := time.Now().Year()
|
||||
|
@ -67,10 +68,12 @@ func main() {
|
|||
return
|
||||
}
|
||||
holidays, _ := holidayService.Find(search, holiday.Paging{PageSize: 100})
|
||||
c.HTML(http.StatusOK, "index.gohtml", gin.H{"Search": search, "Holidays": mapHolidays(holidays).Holidays})
|
||||
countries, _ := countryService.Find()
|
||||
c.HTML(http.StatusOK, "index.gohtml", gin.H{"Countries": countries, "Search": search, "Holidays": mapHolidays(holidays).Holidays})
|
||||
})
|
||||
g.GET("/documentation", func(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "documentation.gohtml", nil)
|
||||
countries, _ := countryService.Find()
|
||||
c.HTML(http.StatusOK, "documentation.gohtml", gin.H{"Countries": countries})
|
||||
})
|
||||
g.GET("/search", func(c *gin.Context) {
|
||||
request := holiday.Search{}
|
||||
|
@ -80,10 +83,12 @@ func main() {
|
|||
}
|
||||
search := holiday.Search{Country: request.Country, Date: request.Date}
|
||||
holidays, _ := holidayService.Find(search, holiday.Paging{PageSize: 100})
|
||||
c.HTML(http.StatusOK, "search.gohtml", gin.H{"Search": search, "Holidays": mapHolidays(holidays).Holidays})
|
||||
countries, _ := countryService.Find()
|
||||
c.HTML(http.StatusOK, "search.gohtml", gin.H{"Countries": countries, "Search": search, "Holidays": mapHolidays(holidays).Holidays})
|
||||
})
|
||||
g.GET("/dialogs/check-is-a-holiday", func(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "check-is-a-holiday.gohtml", gin.H{})
|
||||
countries, _ := countryService.Find()
|
||||
c.HTML(http.StatusOK, "check-is-a-holiday.gohtml", gin.H{"Countries": countries})
|
||||
})
|
||||
|
||||
log.Fatal(http.ListenAndServe(":5281", g))
|
||||
|
@ -112,15 +117,19 @@ func loadTemplates(g *gin.Engine) {
|
|||
"templates/documentation.gohtml",
|
||||
|
||||
"templates/admin_dashboard.gohtml",
|
||||
"templates/countries.gohtml",
|
||||
|
||||
"templates/dialogs/add-holiday.gohtml",
|
||||
"templates/dialogs/edit-holiday.gohtml",
|
||||
"templates/dialogs/delete-holiday.gohtml",
|
||||
"templates/dialogs/check-is-a-holiday.gohtml",
|
||||
|
||||
"templates/dialogs/edit-country.gohtml",
|
||||
"templates/dialogs/delete-country.gohtml",
|
||||
)
|
||||
}
|
||||
|
||||
func setupAdminDashboard(adminDashboard *gin.RouterGroup, service holiday.Service) {
|
||||
func setupAdminDashboard(adminDashboard *gin.RouterGroup, service holiday.HolidayService, countryService holiday.CountryService) {
|
||||
adminDashboard.Use(gin.BasicAuth(loadAuth()))
|
||||
|
||||
adminDashboard.GET("/", func(c *gin.Context) {
|
||||
|
@ -132,14 +141,15 @@ func setupAdminDashboard(adminDashboard *gin.RouterGroup, service holiday.Servic
|
|||
}
|
||||
holidays, _ := service.Find(search, holiday.Paging{PageSize: 100})
|
||||
holidayResponse := mapHolidays(holidays)
|
||||
countries, _ := countryService.Find()
|
||||
|
||||
response := map[string]any{}
|
||||
response["holidays"] = holidayResponse
|
||||
response["search"] = search
|
||||
response["Holidays"] = holidayResponse
|
||||
response["Search"] = search
|
||||
response["Countries"] = countries
|
||||
|
||||
c.HTML(http.StatusOK, "admin_dashboard.gohtml", response)
|
||||
})
|
||||
|
||||
adminDashboard.POST("/holidays", func(c *gin.Context) {
|
||||
request := struct {
|
||||
Id *string `form:"id"`
|
||||
|
@ -190,8 +200,56 @@ func setupAdminDashboard(adminDashboard *gin.RouterGroup, service holiday.Servic
|
|||
}
|
||||
c.Redirect(http.StatusSeeOther, "/admin?country="+hol.Country+"&year="+strconv.FormatInt(int64(hol.Date.Year()), 10))
|
||||
})
|
||||
adminDashboard.GET("/countries", func(c *gin.Context) {
|
||||
countries, _ := countryService.Find()
|
||||
c.HTML(http.StatusOK, "countries.gohtml", gin.H{"Countries": countries})
|
||||
})
|
||||
adminDashboard.POST("/countries", func(c *gin.Context) {
|
||||
request := struct {
|
||||
Id *string `form:"id"`
|
||||
IsoName string `form:"iso_name" binding:"required,min=2,max=2"`
|
||||
Name string `form:"name" binding:"required,min=1,max=45"`
|
||||
}{}
|
||||
if err := c.ShouldBind(&request); err != nil {
|
||||
c.AbortWithError(http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
country := holiday.Country{
|
||||
IsoName: request.IsoName,
|
||||
Name: request.Name,
|
||||
}
|
||||
|
||||
var err error
|
||||
if request.Id != nil {
|
||||
country.Id = uuid.MustParse(*request.Id)
|
||||
country, err = countryService.Update(country)
|
||||
} else {
|
||||
country, err = countryService.Create(country)
|
||||
}
|
||||
if err != nil {
|
||||
c.AbortWithError(http.StatusInternalServerError, err)
|
||||
} else {
|
||||
c.Redirect(http.StatusSeeOther, "/admin/countries")
|
||||
}
|
||||
})
|
||||
adminDashboard.POST("/countries/:id/delete", func(c *gin.Context) {
|
||||
id := uuid.MustParse(c.Param("id"))
|
||||
_, err := countryService.FindById(id)
|
||||
if err != nil {
|
||||
c.AbortWithError(http.StatusNotFound, err)
|
||||
return
|
||||
}
|
||||
if err := countryService.Delete(id); err != nil {
|
||||
c.AbortWithError(http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
c.Redirect(http.StatusSeeOther, "/admin/countries")
|
||||
})
|
||||
|
||||
adminDashboard.GET("/dialogs/add-holiday", func(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "add-holiday.gohtml", gin.H{})
|
||||
countries, _ := countryService.Find()
|
||||
c.HTML(http.StatusOK, "add-holiday.gohtml", gin.H{"Countries": countries})
|
||||
})
|
||||
adminDashboard.GET("/dialogs/edit-holiday", func(c *gin.Context) {
|
||||
id := uuid.MustParse(c.Query("id"))
|
||||
|
@ -200,7 +258,17 @@ func setupAdminDashboard(adminDashboard *gin.RouterGroup, service holiday.Servic
|
|||
c.AbortWithError(http.StatusNotFound, err)
|
||||
return
|
||||
}
|
||||
c.HTML(http.StatusOK, "edit-holiday.gohtml", gin.H{"Holiday": hol})
|
||||
countries, _ := countryService.Find()
|
||||
c.HTML(http.StatusOK, "edit-holiday.gohtml", gin.H{"Countries": countries, "Holiday": hol})
|
||||
})
|
||||
adminDashboard.GET("/dialogs/edit-country", func(c *gin.Context) {
|
||||
id := uuid.MustParse(c.Query("id"))
|
||||
country, err := countryService.FindById(id)
|
||||
if err != nil {
|
||||
c.AbortWithError(http.StatusNotFound, err)
|
||||
return
|
||||
}
|
||||
c.HTML(http.StatusOK, "edit-country.gohtml", gin.H{"Country": country})
|
||||
})
|
||||
adminDashboard.GET("/dialogs/delete-holiday", func(c *gin.Context) {
|
||||
id := uuid.MustParse(c.Query("id"))
|
||||
|
@ -211,6 +279,15 @@ func setupAdminDashboard(adminDashboard *gin.RouterGroup, service holiday.Servic
|
|||
}
|
||||
c.HTML(http.StatusOK, "delete-holiday.gohtml", gin.H{"Holiday": hol})
|
||||
})
|
||||
adminDashboard.GET("/dialogs/delete-country", func(c *gin.Context) {
|
||||
id := uuid.MustParse(c.Query("id"))
|
||||
country, err := countryService.FindById(id)
|
||||
if err != nil {
|
||||
c.AbortWithError(http.StatusNotFound, err)
|
||||
return
|
||||
}
|
||||
c.HTML(http.StatusOK, "delete-country.gohtml", gin.H{"Country": country})
|
||||
})
|
||||
}
|
||||
|
||||
func loadAuth() map[string]string {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
<nav>
|
||||
<section class="container">
|
||||
<a class="selected" href="#">Search</a>
|
||||
<a href="/admin/countries">Countries</a>
|
||||
<button data-type="dialog" data-trigger="#create-card" data-url="/admin/dialogs/add-holiday">Add new holiday</button>
|
||||
</section>
|
||||
</nav>
|
||||
|
@ -27,23 +28,22 @@
|
|||
<section>
|
||||
<label for="country">Country:</label>
|
||||
<select id="country" name="country">
|
||||
<option value="HR" {{if eq .search.Country "HR"}}selected{{end}}>Croatia</option>
|
||||
<option value="GB" {{if eq .search.Country "GB"}}selected{{end}}>Great Britain</option>
|
||||
<option value="US" {{if eq .search.Country "US"}}selected{{end}}>USA</option>
|
||||
<option value="FR" {{if eq .search.Country "FR"}}selected{{end}}>France</option>
|
||||
{{range $entry := .Countries}}
|
||||
<option {{if eq $.Search.Country $entry.IsoName}}selected{{end}} value="{{$entry.IsoName}}">{{$entry.Name}}</option>
|
||||
{{end}}
|
||||
</select>
|
||||
</section>
|
||||
<section>
|
||||
<label for="year">Year:</label>
|
||||
<select id="year" name="year">
|
||||
<option value="2020" {{if eq (deferint .search.Year) 2020}}selected{{end}}>2020</option>
|
||||
<option value="2021" {{if eq (deferint .search.Year) 2021}}selected{{end}}>2021</option>
|
||||
<option value="2022" {{if eq (deferint .search.Year) 2022}}selected{{end}}>2022</option>
|
||||
<option value="2023" {{if eq (deferint .search.Year) 2023}}selected{{end}}>2023</option>
|
||||
<option value="2024" {{if eq (deferint .search.Year) 2024}}selected{{end}}>2024</option>
|
||||
<option value="2025" {{if eq (deferint .search.Year) 2025}}selected{{end}}>2025</option>
|
||||
<option value="2026" {{if eq (deferint .search.Year) 2026}}selected{{end}}>2026</option>
|
||||
<option value="2027" {{if eq (deferint .search.Year) 2027}}selected{{end}}>2027</option>
|
||||
<option value="2020" {{if eq (deferint .Search.Year) 2020}}selected{{end}}>2020</option>
|
||||
<option value="2021" {{if eq (deferint .Search.Year) 2021}}selected{{end}}>2021</option>
|
||||
<option value="2022" {{if eq (deferint .Search.Year) 2022}}selected{{end}}>2022</option>
|
||||
<option value="2023" {{if eq (deferint .Search.Year) 2023}}selected{{end}}>2023</option>
|
||||
<option value="2024" {{if eq (deferint .Search.Year) 2024}}selected{{end}}>2024</option>
|
||||
<option value="2025" {{if eq (deferint .Search.Year) 2025}}selected{{end}}>2025</option>
|
||||
<option value="2026" {{if eq (deferint .Search.Year) 2026}}selected{{end}}>2026</option>
|
||||
<option value="2027" {{if eq (deferint .Search.Year) 2027}}selected{{end}}>2027</option>
|
||||
</select>
|
||||
</section>
|
||||
<section class="radio-group">
|
||||
|
@ -53,7 +53,7 @@
|
|||
</label><input type="radio" value="false" name="sh" id="sh_false"><label for="sh_false">False
|
||||
</label><input type="radio" value="" name="sh" id="sh_any"><label for="sh_any">All</label>
|
||||
</div>
|
||||
<input type="hidden" value="{{.search.StateHoliday}}" name="state_holiday">
|
||||
<input type="hidden" value="{{.Search.StateHoliday}}" name="state_holiday">
|
||||
</section>
|
||||
<section class="radio-group">
|
||||
<label>Is religious holiday:</label>
|
||||
|
@ -62,7 +62,7 @@
|
|||
</label><input type="radio" value="false" name="rh" id="rh_false"><label for="rh_false">False
|
||||
</label><input type="radio" value="" name="rh" id="rh_any"><label for="rh_any">All</label>
|
||||
</div>
|
||||
<input type="hidden" value="{{.search.ReligiousHoliday}}" name="religious_holiday">
|
||||
<input type="hidden" value="{{.Search.ReligiousHoliday}}" name="religious_holiday">
|
||||
</section>
|
||||
<section class="actions">
|
||||
<button class="icon primary" type="submit">
|
||||
|
@ -86,7 +86,7 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
|
||||
{{range $entry := .holidays.Holidays}}
|
||||
{{range $entry := .Holidays.Holidays}}
|
||||
<tr>
|
||||
<td>{{$entry.Name}}</td>
|
||||
<td>{{$entry.Date.Format "2006-01-02"}}</td>
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Holiday-api | Admin dashboard</title>
|
||||
<link rel="stylesheet" href="/assets/style.css">
|
||||
<script src="/assets/global.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="dialog-container"></div>
|
||||
<header>
|
||||
<section class="container">
|
||||
<h1><a href="/">Holiday-api | Countries</a></h1>
|
||||
</section>
|
||||
</header>
|
||||
<nav>
|
||||
<section class="container">
|
||||
<a href="/admin">Search</a>
|
||||
<a class="selected" href="#">Countries</a>
|
||||
<button data-type="dialog" data-trigger="#create-card" data-url="/admin/dialogs/add-holiday">Add new holiday</button>
|
||||
</section>
|
||||
</nav>
|
||||
<main>
|
||||
|
||||
<section style="margin: 1em; flex-grow: 1">
|
||||
<form action="/admin/countries" method="post">
|
||||
<table style="width: 100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Iso name</th>
|
||||
<th>Name</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr>
|
||||
<td><section><input minlength="2" maxlength="2" required id="iso_name" type="text" name="iso_name"></section></td>
|
||||
<td><section><input minlength="1" maxlength="45" required id="name" type="text" name="name"></section></td>
|
||||
<td><button>Create country</button></td>
|
||||
</tr>
|
||||
|
||||
{{range $entry := .Countries}}
|
||||
<tr>
|
||||
<td>{{$entry.IsoName}}</td>
|
||||
<td>{{$entry.Name}}</td>
|
||||
<td>
|
||||
<button type="button" data-type="dialog" data-trigger="#update-card" data-url="/admin/dialogs/edit-country?id={{$entry.Id}}" class="clean icon"><img class="icon" src="/assets/images/edit.svg"></button>
|
||||
<button type="button" data-type="dialog" data-trigger="#delete-card" data-url="/admin/dialogs/delete-country?id={{$entry.Id}}" class="clean icon"><img class="icon" src="/assets/images/trash-delete.svg"></button>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
|
@ -4,10 +4,9 @@
|
|||
<section>
|
||||
<label for="country">Country:</label>
|
||||
<select id="country" required name="country">
|
||||
<option value="HR">Croatia</option>
|
||||
<option value="US">United states</option>
|
||||
<option value="FR">France</option>
|
||||
<option value="GB">Great Britain</option>
|
||||
{{range $entry := .Countries}}
|
||||
<option value="{{$entry.IsoName}}">{{$entry.Name}}</option>
|
||||
{{end}}
|
||||
</select>
|
||||
</section>
|
||||
<section>
|
||||
|
|
|
@ -7,10 +7,9 @@
|
|||
<section>
|
||||
<label for="country">Country:</label>
|
||||
<select id="country" name="country">
|
||||
<option value="HR">Croatia</option>
|
||||
<option value="US">United states</option>
|
||||
<option value="FR">France</option>
|
||||
<option value="GB">Great Britain</option>
|
||||
{{range $entry := .Countries}}
|
||||
<option value="{{$entry.IsoName}}">{{$entry.Name}}</option>
|
||||
{{end}}
|
||||
</select>
|
||||
</section>
|
||||
<section>
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
<dialog class="card" id="delete-card">
|
||||
<h3 class="card-title">Delete country</h3>
|
||||
<p>Are you sure you want to delete "{{.Country.Name}}"?<br>All holidays for given country will be deleted!</p>
|
||||
<form method="post" action="/admin/countries/{{.Country.Id}}/delete">
|
||||
<section class="actions">
|
||||
<button type="submit">Delete</button>
|
||||
<button type="button" onclick="closeDialog('#delete-card')">Cancel</button>
|
||||
</section>
|
||||
</form>
|
||||
</dialog>
|
|
@ -0,0 +1,18 @@
|
|||
<dialog class="card" id="update-card">
|
||||
<h3 class="card-title">Edit country</h3>
|
||||
<form method="post" action="/admin/countries">
|
||||
<input type="hidden" name="id" value="{{.Country.Id}}">
|
||||
<section>
|
||||
<label for="name">Iso name:</label>
|
||||
<input required minlength="2" maxlength="2" id="iso_name" value="{{.Country.IsoName}}" name="iso_name" type="text">
|
||||
</section>
|
||||
<section>
|
||||
<label for="name">Name:</label>
|
||||
<input required minlength="1" maxlength="45" id="name" value="{{.Country.Name}}" name="name" type="text">
|
||||
</section>
|
||||
<section class="actions">
|
||||
<button type="submit">Update</button>
|
||||
<button type="button" onclick="closeDialog('#update-card')">Cancel</button>
|
||||
</section>
|
||||
</form>
|
||||
</dialog>
|
|
@ -5,10 +5,9 @@
|
|||
<section>
|
||||
<label for="country">Country:</label>
|
||||
<select id="country" required name="country">
|
||||
<option {{if eq .Holiday.Country "HR"}}selected{{end}} value="HR">Croatia</option>
|
||||
<option {{if eq .Holiday.Country "US"}}selected{{end}} value="US">United states</option>
|
||||
<option {{if eq .Holiday.Country "FR"}}selected{{end}} value="FR">France</option>
|
||||
<option {{if eq .Holiday.Country "GB"}}selected{{end}} value="GB">Great Britain</option>
|
||||
{{range $entry := .Countries}}
|
||||
<option {{if eq $.Holiday.Country $entry.IsoName}}selected{{end}} value="{{$entry.IsoName}}">{{$entry.Name}}</option>
|
||||
{{end}}
|
||||
</select>
|
||||
</section>
|
||||
<section>
|
||||
|
|
|
@ -29,10 +29,9 @@
|
|||
<section>
|
||||
<label for="country">Country</label>
|
||||
<select id="country" name="country">
|
||||
<option value="HR">Croatia</option>
|
||||
<option value="GB">Great Britain</option>
|
||||
<option value="US">USA</option>
|
||||
<option value="FR">France</option>
|
||||
{{range $entry := .Countries}}
|
||||
<option value="{{$entry.IsoName}}">{{$entry.Name}}</option>
|
||||
{{end}}
|
||||
</select>
|
||||
</section>
|
||||
|
||||
|
|
|
@ -28,10 +28,9 @@
|
|||
<section>
|
||||
<label for="country">Country:</label>
|
||||
<select id="country" name="country">
|
||||
<option {{if eq .Search.Country "HR"}}selected{{end}} value="HR">Croatia</option>
|
||||
<option {{if eq .Search.Country "US"}}selected{{end}} value="US">United states</option>
|
||||
<option {{if eq .Search.Country "FR"}}selected{{end}} value="FR">France</option>
|
||||
<option {{if eq .Search.Country "GB"}}selected{{end}} value="GB">Great Britain</option>
|
||||
{{range $entry := .Countries}}
|
||||
<option {{if eq $.Search.Country $entry.IsoName}}selected{{end}} value="{{$entry.IsoName}}">{{$entry.Name}}</option>
|
||||
{{end}}
|
||||
</select>
|
||||
</section>
|
||||
<section>
|
||||
|
|
|
@ -29,10 +29,9 @@
|
|||
<section>
|
||||
<label for="country">Country:</label>
|
||||
<select id="country" name="country">
|
||||
<option {{if eq .Search.Country "HR"}}selected{{end}} value="HR">Croatia</option>
|
||||
<option {{if eq .Search.Country "US"}}selected{{end}} value="US">United states</option>
|
||||
<option {{if eq .Search.Country "FR"}}selected{{end}} value="FR">France</option>
|
||||
<option {{if eq .Search.Country "GB"}}selected{{end}} value="GB">Great Britain</option>
|
||||
{{range $entry := .Countries}}
|
||||
<option {{if eq $.Search.Country $entry.IsoName}}selected{{end}} value="{{$entry.IsoName}}">{{$entry.Name}}</option>
|
||||
{{end}}
|
||||
</select>
|
||||
</section>
|
||||
<section>
|
||||
|
|
Loading…
Reference in New Issue