add favicon and breadcumbs
This commit is contained in:
@ -44,6 +44,11 @@ func parsePaginationFromQuery(r *http.Request) (out pagination, err error) {
|
||||
return out, nil
|
||||
}
|
||||
|
||||
const (
|
||||
LearningTypePathParam = "learning_type"
|
||||
ThematicTypePathParam = "thematic_type"
|
||||
)
|
||||
|
||||
func parseListCoursesParams(r *http.Request) (out listCoursesParams, err error) {
|
||||
out.pagination, err = parsePaginationFromQuery(r)
|
||||
if err != nil {
|
||||
@ -51,8 +56,8 @@ func parseListCoursesParams(r *http.Request) (out listCoursesParams, err error)
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
out.learningType = vars["learning_type"]
|
||||
out.courseThematic = vars["thematic_type"]
|
||||
out.learningType = vars[LearningTypePathParam]
|
||||
out.courseThematic = vars[ThematicTypePathParam]
|
||||
|
||||
return out, nil
|
||||
}
|
||||
@ -82,9 +87,23 @@ type subcategoryInfo struct {
|
||||
Courses []domain.Course
|
||||
}
|
||||
|
||||
type IDNamePair struct {
|
||||
ID string
|
||||
Name string
|
||||
IsActive bool
|
||||
}
|
||||
|
||||
type listCoursesTemplateParams struct {
|
||||
Categories []categoryInfo
|
||||
NextPageToken string
|
||||
Categories []categoryInfo
|
||||
NextPageToken string
|
||||
AvailableLearningTypes []IDNamePair
|
||||
AvailableCourseThematics []IDNamePair
|
||||
|
||||
ActiveLearningType string
|
||||
LearningTypeName string
|
||||
|
||||
ActiveCourseThematic string
|
||||
CourseThematicName string
|
||||
}
|
||||
|
||||
func mapDomainCourseToTemplate(in ...domain.Course) listCoursesTemplateParams {
|
||||
@ -149,6 +168,45 @@ func (c courseServer) List(w http.ResponseWriter, r *http.Request) {
|
||||
templateCourses := mapDomainCourseToTemplate(courses...)
|
||||
templateCourses.NextPageToken = result.NextPageToken
|
||||
|
||||
learningTypeList, err := c.app.Queries.ListLearningTypes.Handle(ctx, query.ListLearningTypes{})
|
||||
if handleError(ctx, err, w, c.log, "unable to list learning types") {
|
||||
return
|
||||
}
|
||||
|
||||
templateCourses.AvailableLearningTypes = xslices.Map(learningTypeList.LearningTypes, func(in query.LearningType) IDNamePair {
|
||||
if in.ID == params.learningType {
|
||||
templateCourses.LearningTypeName = in.Name
|
||||
}
|
||||
return IDNamePair{
|
||||
ID: in.ID,
|
||||
Name: in.Name,
|
||||
IsActive: in.ID == params.learningType,
|
||||
}
|
||||
})
|
||||
|
||||
templateCourses.ActiveLearningType = params.learningType
|
||||
templateCourses.ActiveCourseThematic = params.courseThematic
|
||||
|
||||
if params.learningType != "" {
|
||||
courseThematicsResult, err := c.app.Queries.ListCourseThematics.Handle(ctx, query.ListCourseThematics{
|
||||
LearningTypeID: params.learningType,
|
||||
})
|
||||
if handleError(ctx, err, w, c.log, "unable to list course thematics") {
|
||||
return
|
||||
}
|
||||
|
||||
templateCourses.AvailableCourseThematics = xslices.Map(courseThematicsResult.CourseThematics, func(in query.CourseThematic) IDNamePair {
|
||||
if in.ID == params.courseThematic {
|
||||
templateCourses.CourseThematicName = in.Name
|
||||
}
|
||||
return IDNamePair{
|
||||
ID: in.ID,
|
||||
Name: in.Name,
|
||||
IsActive: in.ID == params.courseThematic,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
err = getCoreTemplate(ctx, c.log).ExecuteTemplate(w, "courses", templateCourses)
|
||||
if handleError(ctx, err, w, c.log, "unable to execute template") {
|
||||
return
|
||||
|
||||
@ -8,6 +8,11 @@
|
||||
<script src="https://unpkg.com/htmx.org/dist/ext/json-enc.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
|
||||
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||
<link rel="manifest" href="/site.webmanifest">
|
||||
|
||||
</head>
|
||||
{{ end }}
|
||||
|
||||
|
||||
@ -34,6 +34,45 @@
|
||||
<div class="section">
|
||||
<div class="container">
|
||||
<h1>Welcome to the Course Aggregator</h1>
|
||||
<nav class="breadcrumb" aria-label="breadcrumbs">
|
||||
<ul>
|
||||
<li><a href="/courses">Courses</a></li>
|
||||
{{ if ne .LearningTypeName "" }}
|
||||
<li><a href="/courses/{{.ActiveLearningType}}">{{ .LearningTypeName }}</a></li>
|
||||
{{ end }}
|
||||
{{ if ne .CourseThematicName "" }}
|
||||
<li><a href="/courses/{{.ActiveLearningType}}/{{.ActiveCourseThematic}}">{{ .CourseThematicName }}</a></li>
|
||||
{{ end }}
|
||||
<!-- <li class="is-active"><a href="#" aria-current="page">Breadcrumb</a></li> -->
|
||||
</ul>
|
||||
</nav>
|
||||
<form id="filter-form">
|
||||
<div class="select columns">
|
||||
<select id="learning-type-filter" name="learning_type">
|
||||
<option
|
||||
value=""
|
||||
>All Learning Types</option>
|
||||
{{ range $t := .AvailableLearningTypes }}
|
||||
<option
|
||||
value="{{$t.ID}}"
|
||||
{{ if eq $t.ID $.ActiveLearningType }}selected{{ end }}
|
||||
>{{ $t.Name }}</option>
|
||||
{{ end }}
|
||||
</select>
|
||||
<select id="course-thematic-filter" name="learning_type">
|
||||
<option
|
||||
value=""
|
||||
>All Course Thematics</option>
|
||||
{{ range $t := .AvailableCourseThematics }}
|
||||
<option
|
||||
value="{{$t.ID}}"
|
||||
{{ if eq $t.ID $.ActiveCourseThematic }}selected{{ end }}
|
||||
>{{ $t.Name }}</option>
|
||||
{{ end }}
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div id="category-course-list">
|
||||
{{ range $category := .Categories }}
|
||||
<div class="title">{{ $category.Name }}</div>
|
||||
|
||||
Reference in New Issue
Block a user