Better edu home page

This commit is contained in:
Ben Visness 2022-10-27 00:20:59 -05:00
parent 4e44ba0b45
commit 48af5e650d
9 changed files with 171 additions and 31 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

BIN
public/education/time.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

View File

@ -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; }

View File

@ -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;

View File

@ -41,7 +41,7 @@
{{ end }}
{{ define "content" }}
<div class="ph2 ph0-ns">
<div class="ph3 ph0-ns">
<h1>{{ .Title }}</h1>
{{ if and .User .User.IsEduAuthor }}
<div class="mb3">

View File

@ -1,28 +1,44 @@
{{ template "base.html" . }}
{{ define "content" }}
<div class="ph3 ph0-ns">
<h1>Learn the Handmade way.</h1>
<h2>Guides</h2>
<p>Dive into one of these topics and start learning.</p>
{{ if and .User .User.IsEduAuthor }}
<div class="mb2">
<a href="{{ .NewArticleUrl }}"><span class="big pr1">+</span> New Article</a>
</div>
{{ end }}
<div class="flex flex-column g3 mb3">
{{ range .Articles }}
<a class="c--inherit flex flex-column pa3 bg--dim br2" href="{{ .Url }}" >
<h3 class="mb1 link">{{ .Title }}</h3>
<div>{{ .Description }}</div>
</a>
{{ end }}
<div class="flex flex-column flex-row-ns g3 mt3 mb4">
<a href="#compilers" class="edu-topic db flex-fair-ns bg--dim br3 overflow-hidden c--inherit flex flex-column">
<img src="{{ static "education/compilers.jpg" }}">
<div class="pa3">
<h2>Compilers</h2>
<div>
Learn how programming languages are made.
</div>
</div>
</a>
<a href="#networking" class="edu-topic db flex-fair-ns bg--dim br3 overflow-hidden c--inherit flex flex-column">
<img src="{{ static "education/networking.jpg" }}">
<div class="pa3">
<h2>Networking</h2>
<div>
Learn how computers communicate, and how the internet actually works.
</div>
</div>
</a>
<a href="#time" class="edu-topic db flex-fair-ns bg--dim br3 overflow-hidden c--inherit flex flex-column">
<img src="{{ static "education/time.jpg" }}">
<div class="pa3">
<h2>Time</h2>
<div>
Get better at handling time, from calendars to timezones to clock sync.
</div>
</div>
</a>
</div>
<h2>What makes us different?</h2>
<div class="flex flex-column flex-row-ns g3">
<div class="flex flex-column flex-row-ns g3 mb4">
<div class="flex-fair bg--dim pa3 br2">
<h3>Real material.</h3>
@ -40,10 +56,34 @@
</div>
</div>
{{ if and .User .User.IsEduAuthor }}
<div class="mt3">
<b>SECRET AUTHOR MAINTENANCE COMMANDS:</b>
<a href="{{ .RerenderUrl }}">Rerender all content</a>
<h2>All Topics</h2>
{{ range .Courses }}
<div id="{{ .Slug }}" class="edu-course mv3 bg--dim pa3 br3">
<h3>{{ .Name }}</h3>
<div class="overflow-hidden">
<div class="edu-articles ml3 pl3">
{{ range .Articles }}
<div class="edu-article mt3 relative {{ if not .Published }}coming-soon{{ end }}">
{{ if or (and $.User $.User.IsEduTester) .Published }}
<a href="{{ .Url }}"><h4>{{ .Title }}</h4></a>
{{ else }}
<h4>{{ .Title }} (coming soon)</h4>
{{ end }}
<div>{{ .Description }}</div>
</div>
{{ end }}
</div>
</div>
</div>
{{ end }}
{{ if and .User .User.IsEduAuthor }}
<div class="mt3">
<b>SECRET AUTHOR COMMANDS:</b>
<div><a href="{{ .RerenderUrl }}">Rerender all content</a></div>
<div><a href="{{ .NewArticleUrl }}"><span class="big pr1">+</span> New Article</a></div>
</div>
{{ end }}
</div>
{{ end }}

View File

@ -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

View File

@ -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: "<UNKNOWN ARTICLE>",
}
} 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(),
}