diff --git a/public/education/compilers.jpg b/public/education/compilers.jpg new file mode 100644 index 0000000..cbe2cd4 Binary files /dev/null and b/public/education/compilers.jpg differ diff --git a/public/education/networking.jpg b/public/education/networking.jpg new file mode 100644 index 0000000..ec8f9db Binary files /dev/null and b/public/education/networking.jpg differ diff --git a/public/education/time.jpg b/public/education/time.jpg new file mode 100644 index 0000000..5518238 Binary files /dev/null and b/public/education/time.jpg differ diff --git a/public/style.css b/public/style.css index 704651b..e3d2af4 100644 --- a/public/style.css +++ b/public/style.css @@ -7394,7 +7394,7 @@ article code { border-color: #aaa; border-color: var(--theme-color-dim); } -.c--dimmer, footer .list li:not(:last-child)::after { +.c--dimmer, footer .list li:not(:last-child)::after, .edu-course .edu-article.coming-soon { color: #999; color: var(--dimmer-color); } @@ -8306,6 +8306,27 @@ nav.timecodes { text-align: center; margin: 10px 0; } +.edu-course .edu-article.coming-soon { + font-style: italic; } + +.edu-course .edu-article::after { + content: ''; + position: absolute; + width: 1rem; + height: 10rem; + border-width: 0 0 1px 1px; + border-style: solid; + border-color: #bbb; + border-color: var(--dimmest-color); + left: -1.5rem; + top: -9rem; + border-bottom-left-radius: 0.5rem; } + +.edu-topic img { + width: 100%; + height: 14rem; + object-fit: cover; } + .edu-article .note { color: red; } diff --git a/src/rawdata/scss/_education.scss b/src/rawdata/scss/_education.scss index e1493ba..c51dc42 100644 --- a/src/rawdata/scss/_education.scss +++ b/src/rawdata/scss/_education.scss @@ -1,3 +1,32 @@ +.edu-course { + .edu-article.coming-soon { + @extend .c--dimmer; + font-style: italic; + } + + .edu-article::after { + $height: 10rem; + content: ''; + position: absolute; + width: 1rem; + height: $height; + border-width: 0 0 1px 1px; + border-style: solid; + @include usevar(border-color, dimmest-color); + left: -1.5rem; + top: 1rem - $height; + border-bottom-left-radius: 0.5rem; + } +} + +.edu-topic { + img { + width: 100%; + height: 14rem; + object-fit: cover; + } +} + .edu-article { .note { color: red; diff --git a/src/templates/src/education_article.html b/src/templates/src/education_article.html index df1b929..f289298 100644 --- a/src/templates/src/education_article.html +++ b/src/templates/src/education_article.html @@ -41,7 +41,7 @@ {{ end }} {{ define "content" }} -
+

{{ .Title }}

{{ if and .User .User.IsEduAuthor }}
diff --git a/src/templates/src/education_index.html b/src/templates/src/education_index.html index a57aa34..5876855 100644 --- a/src/templates/src/education_index.html +++ b/src/templates/src/education_index.html @@ -1,28 +1,44 @@ {{ template "base.html" . }} {{ define "content" }} +

Learn the Handmade way.

-

Guides

+

Dive into one of these topics and start learning.

- {{ if and .User .User.IsEduAuthor }} - - {{ end }} - -
- {{ range .Articles }} - - -
{{ .Description }}
-
- {{ end }} +

What makes us different?

-
+

Real material.

@@ -40,10 +56,34 @@
- {{ if and .User .User.IsEduAuthor }} -
- SECRET AUTHOR MAINTENANCE COMMANDS: - Rerender all content +

All Topics

+ + {{ range .Courses }} +
+

{{ .Name }}

+
+
+ {{ range .Articles }} +
+ {{ if or (and $.User $.User.IsEduTester) .Published }} +

{{ .Title }}

+ {{ else }} +

{{ .Title }} (coming soon)

+ {{ end }} +
{{ .Description }}
+
+ {{ end }} +
+
{{ end }} + + {{ if and .User .User.IsEduAuthor }} +
+ SECRET AUTHOR COMMANDS: + + +
+ {{ end }} +
{{ end }} diff --git a/src/templates/types.go b/src/templates/types.go index 74b508f..d6c2f7d 100644 --- a/src/templates/types.go +++ b/src/templates/types.go @@ -395,6 +395,12 @@ type TextEditor struct { UploadUrl string } +type EduCourse struct { + Name string + Slug string + Articles []EduArticle +} + type EduArticle struct { Title string Slug string diff --git a/src/website/education.go b/src/website/education.go index dba231a..4118031 100644 --- a/src/website/education.go +++ b/src/website/education.go @@ -23,24 +23,68 @@ import ( func EducationIndex(c *RequestContext) ResponseData { type indexData struct { templates.BaseData - Articles []templates.EduArticle + Courses []templates.EduCourse NewArticleUrl string RerenderUrl string } - articles, err := fetchEduArticles(c, c.Conn, models.EduArticleTypeArticle, c.CurrentUser) - if err != nil { - panic(err) - } + // TODO: Someday this can be dynamic again? Maybe? Or not? Who knows?? + // articles, err := fetchEduArticles(c, c.Conn, models.EduArticleTypeArticle, c.CurrentUser) + // if err != nil { + // panic(err) + // } - var tmplArticles []templates.EduArticle - for _, article := range articles { - tmplArticles = append(tmplArticles, templates.EducationArticleToTemplate(&article)) + // var tmplArticles []templates.EduArticle + // for _, article := range articles { + // tmplArticles = append(tmplArticles, templates.EducationArticleToTemplate(&article)) + // } + + article := func(slug string) templates.EduArticle { + if article, err := fetchEduArticle(c, c.Conn, slug, models.EduArticleTypeArticle, c.CurrentUser); err == nil { + return templates.EducationArticleToTemplate(article) + } else if errors.Is(err, db.NotFound) { + return templates.EduArticle{ + Title: "", + } + } else { + panic(err) + } } tmpl := indexData{ - BaseData: getBaseData(c, "Handmade Education", nil), - Articles: tmplArticles, + BaseData: getBaseData(c, "Handmade Education", nil), + Courses: []templates.EduCourse{ + { + Name: "Compilers", + Slug: "compilers", + Articles: []templates.EduArticle{ + article("compilers"), + { + Title: "Baby's first language theory", + Description: "State machines, abstract datatypes, type theory...", + }, + }, + }, + { + Name: "Networking", + Slug: "networking", + Articles: []templates.EduArticle{ + article("networking"), + { + Title: "Internet infrastructure", + Description: "How does the internet actually work? How does your ISP know where to send your data? What happens to the internet if physical communication breaks down?", + }, + }, + }, + { + Name: "Time", + Slug: "time", + Articles: []templates.EduArticle{ + article("time"), + article("ntp"), + }, + }, + }, NewArticleUrl: hmnurl.BuildEducationArticleNew(), RerenderUrl: hmnurl.BuildEducationRerender(), }