diff options
Diffstat (limited to 'cmd/web/templates')
45 files changed, 979 insertions, 0 deletions
diff --git a/cmd/web/templates/articles/htmx-article-page.tmpl b/cmd/web/templates/articles/htmx-article-page.tmpl new file mode 100644 index 0000000..9380c0a --- /dev/null +++ b/cmd/web/templates/articles/htmx-article-page.tmpl @@ -0,0 +1,3 @@ +{{ template "articles/show" . }} +{{ template "components/navbar" . }} +{{ template "components/head" . }}
\ No newline at end of file diff --git a/cmd/web/templates/articles/htmx-post-comments.tmpl b/cmd/web/templates/articles/htmx-post-comments.tmpl new file mode 100644 index 0000000..742b339 --- /dev/null +++ b/cmd/web/templates/articles/htmx-post-comments.tmpl @@ -0,0 +1,2 @@ +{{ template "articles/partials/comments-card" . }} +{{ template "articles/partials/comments-form" . }}
\ No newline at end of file diff --git a/cmd/web/templates/articles/htmx-show.tmpl b/cmd/web/templates/articles/htmx-show.tmpl new file mode 100644 index 0000000..9021bb2 --- /dev/null +++ b/cmd/web/templates/articles/htmx-show.tmpl @@ -0,0 +1,3 @@ +{{ template "articles/partials/detail-title" . }} +{{ template "articles/partials/detail-post-meta" . }} +{{ template "articles/partials/detail-post-content" . }}
\ No newline at end of file diff --git a/cmd/web/templates/articles/partials/comments-card.tmpl b/cmd/web/templates/articles/partials/comments-card.tmpl new file mode 100644 index 0000000..1e6062a --- /dev/null +++ b/cmd/web/templates/articles/partials/comments-card.tmpl @@ -0,0 +1,25 @@ +<div class="card"> + <div class="card-block"> + <p class="card-text">{{ .Comment.Body }}</p> + </div> + <div class="card-footer"> + <a href="/users/{{ .Comment.User.Username }}" + hx-push-url="/users/{{ .Comment.User.Username }}" + hx-get="/htmx/users/{{ .Comment.User.Username }}" + hx-target="#app-body" + class="comment-author" + > + <img src="{{ .Comment.User.Image }}" class="comment-author-img" /> + </a> + + <a href="/users/{{ .Comment.User.Username }}" + hx-push-url="/users/{{ .Comment.User.Username }}" + hx-get="/htmx/users/{{ .Comment.User.Username }}" + hx-target="#app-body" + class="comment-author" + > + {{ .Comment.User.Name }} + </a> + <span class="date-posted">{{ .Comment.GetFormattedCreatedAt }}</span> + </div> +</div>
\ No newline at end of file diff --git a/cmd/web/templates/articles/partials/comments-form.tmpl b/cmd/web/templates/articles/partials/comments-form.tmpl new file mode 100644 index 0000000..09f9697 --- /dev/null +++ b/cmd/web/templates/articles/partials/comments-form.tmpl @@ -0,0 +1,18 @@ +<form id="article-comment-form" class="card comment-form" + hx-post="/htmx/articles/{{ .Article.Slug }}/comments" + hx-target="#article-comments-wrapper" hx-swap="afterbegin show:top" + + {{ if .IsOob }} + hx-swap-oob="true" + {{ end }} +> + <div class="card-block"> + <textarea class="form-control" placeholder="Write a comment..." rows="3" name="comment"></textarea> + </div> + <div class="card-footer"> + <img src="{{ .Article.User.Image }}" class="comment-author-img" /> + <button class="btn btn-sm btn-primary"> + Post Comment + </button> + </div> +</form>
\ No newline at end of file diff --git a/cmd/web/templates/articles/partials/comments-wrapper.tmpl b/cmd/web/templates/articles/partials/comments-wrapper.tmpl new file mode 100644 index 0000000..266b4e5 --- /dev/null +++ b/cmd/web/templates/articles/partials/comments-wrapper.tmpl @@ -0,0 +1,26 @@ +<div id="article-comments-wrapper"> + {{ range $comment := .Article.Comments }} + {{ template "articles/partials/comments-card" Dict "Comment" $comment }} + {{ end }} +</div> + +{{ if .IsAuthenticated }} + <div id="form-message"></div> + + {{ template "articles/partials/comments-form" . }} +{{ else }} + <div> + <a href="/htmx/sign-in" hx-get="/htmx/sign-in" hx-target="#app-body" + hx-push-url="/sign-in" + > + Sign in + </a> + or + <a href="/htmx/sign-up" hx-get="/htmx/sign-up" hx-target="#app-body" + hx-push-url="/sign-up" + > + sign up + </a> + to add comments on this article. + </div> +{{ end }}
\ No newline at end of file diff --git a/cmd/web/templates/articles/partials/detail-post-meta.tmpl b/cmd/web/templates/articles/partials/detail-post-meta.tmpl new file mode 100644 index 0000000..a871b44 --- /dev/null +++ b/cmd/web/templates/articles/partials/detail-post-meta.tmpl @@ -0,0 +1,42 @@ +<div class="post-meta"> + <a href="#"><img src="{{ .Article.User.Image }}" /></a> + <div class="info"> + <a href="/users/{{ .Article.User.Username }}" + hx-push-url="/users/{{ .Article.User.Username }}" + hx-get="/htmx/users/{{ .Article.User.Username }}" + hx-target="#app-body" + class="author" + > + {{ .Article.User.Name }} + </a> + <span class="date">{{ .Article.GetFormattedCreatedAt }}</span> + </div> + + {{ if .IsSelf }} + + <button class="btn btn-outline-secondary btn-sm edit-button" + hx-get="/htmx/editor/{{ .Article.Slug }}" + hx-target="#app-body" + hx-push-url="/editor/{{ .Article.Slug }}" + > + <i class="ion-edit"></i> + Edit Article + </button> + + <button class="btn btn-outline-danger btn-sm delete-button" + hx-delete="/htmx/articles/{{ .Article.Slug }}" + hx-target="#app-body" + hx-confirm="Are you sure you wish to delete the article?" + > + <i class="ion-trash-a"></i> + Delete Article + </button> + + {{ else }} + + {{ template "articles/partials/follow-button" . }} + + {{ template "articles/partials/favorite-button" . }} + + {{ end }} +</div>
\ No newline at end of file diff --git a/cmd/web/templates/articles/partials/favorite-button.tmpl b/cmd/web/templates/articles/partials/favorite-button.tmpl new file mode 100644 index 0000000..3146830 --- /dev/null +++ b/cmd/web/templates/articles/partials/favorite-button.tmpl @@ -0,0 +1,15 @@ +<button class="btn btn-outline-primary btn-sm {{ if .IsArticleFavorited }} active {{ end }} favorite-button" + hx-post="/htmx/articles/{{ .Article.Slug }}/favorite" + + {{ if .IsOob }} + hx-swap-oob="outerHTML:.favorite-button" + {{ end }} +> + <i class="ion-heart"></i> + {{ if .IsArticleFavorited }} + Unfavorite Post + {{ else }} + Favorite Post + {{ end }} + ({{ .Article.GetFavoriteCount }}) +</button>
\ No newline at end of file diff --git a/cmd/web/templates/articles/partials/follow-button.tmpl b/cmd/web/templates/articles/partials/follow-button.tmpl new file mode 100644 index 0000000..7184278 --- /dev/null +++ b/cmd/web/templates/articles/partials/follow-button.tmpl @@ -0,0 +1,17 @@ +<button class="btn btn-sm btn-outline-secondary follow-button" + hx-post="/htmx/articles/follow-user/{{ .Article.Slug }}" + + {{ if .IsOob }} + hx-swap-oob="outerHTML:.follow-button" + {{ end }} +> + {{ if .IsFollowed }} + <i class="ion-minus-round"></i> + Unfollow + {{ else }} + <i class="ion-plus-round"></i> + Follow + {{ end }} + {{ .Article.User.Name }} + <span class="counter">({{ .Article.User.FollowersCount }})</span> +</button>
\ No newline at end of file diff --git a/cmd/web/templates/articles/show.tmpl b/cmd/web/templates/articles/show.tmpl new file mode 100644 index 0000000..364444e --- /dev/null +++ b/cmd/web/templates/articles/show.tmpl @@ -0,0 +1,38 @@ +<div class="post-page"> + + <div class="banner"> + <div class="container"> + <h1 id="article-detail__title"> + {{ .Article.Title }} + </h1> + + {{ template "articles/partials/detail-post-meta" . }} + </div> + </div> + + <div class="article-detail container page"> + <div class="row post-content"> + <div class="col-md-12"> + {{ .Article.Body }} + </div> + <div class="col-md-12 m-t-2"> + <ul class="tag-list"> + {{ range $tag := .Article.Tags }} + <li class="tag-default tag-pill tag-outline">{{ $tag.Name }}</li> + {{ end }} + </ul> + </div> + </div> + + <hr /> + + <div class="post-actions"> + {{ template "articles/partials/detail-post-meta" . }} + </div> + + <div class="row"> + <div class="col-md-8 col-md-offset-2" hx-get="/htmx/articles/{{ .Article.Slug }}/comments" hx-trigger="load"></div> + </div> + + </div> +</div>
\ No newline at end of file diff --git a/cmd/web/templates/components/error-message.tmpl b/cmd/web/templates/components/error-message.tmpl new file mode 100644 index 0000000..e4a913e --- /dev/null +++ b/cmd/web/templates/components/error-message.tmpl @@ -0,0 +1,15 @@ +<div id="form-message" + {{ if .IsOob }} + hx-swap-oob="true" + {{ end }} +> + {{ if .Errors }} + <div class="alert alert-danger"> + <ul> + {{ range $error := .Errors }} + <li>{{ $error }}</li> + {{ end }} + </ul> + </div> + {{ end }} +</div>
\ No newline at end of file diff --git a/cmd/web/templates/components/head.tmpl b/cmd/web/templates/components/head.tmpl new file mode 100644 index 0000000..235ae63 --- /dev/null +++ b/cmd/web/templates/components/head.tmpl @@ -0,0 +1,5 @@ +<head> + {{ if ne .PageTitle "" }} + <title>{{ .PageTitle }} — Projecty</title> + {{ end }} +</head> diff --git a/cmd/web/templates/components/navbar.tmpl b/cmd/web/templates/components/navbar.tmpl new file mode 100644 index 0000000..f9cdc2a --- /dev/null +++ b/cmd/web/templates/components/navbar.tmpl @@ -0,0 +1,90 @@ +<ul id="navbar" class="nav navbar-nav pull-xs-right" + hx-swap-oob="true" +> + <li class="nav-item"> + <a id="nav-link-home" + {{ if ne .NavBarActive "home" }} + href="/" + hx-get="/htmx/home" + hx-target="#app-body" + hx-push-url="/" + {{ end }} + class="nav-link{{ if eq .NavBarActive "home" }} active {{ end }}" + > + Home + </a> + </li> + + {{ if not (IsAuthenticated .FiberCtx) }} + <li class="nav-item"> + <a id="nav-link-sign-in" + {{ if ne .NavBarActive "sign-in" }} + href="/sign-in" + hx-get="/htmx/sign-in" + hx-target="#app-body" + hx-push-url="/sign-in" + {{ end }} + class="nav-link {{ if eq .NavBarActive "sign-in" }} active {{ end }}" + > + Sign in + </a> + </li> + <li class="nav-item"> + <a id="nav-link-sign-up" + {{ if ne .NavBarActive "sign-up" }} + href="/sign-up" + hx-get="/htmx/sign-up" + hx-target="#app-body" + hx-push-url="/sign-up" + {{ end }} + class="nav-link {{ if eq .NavBarActive "sign-up" }} active {{ end }}" + > + Sign up + </a> + </li> + {{ end }} + + {{ if IsAuthenticated .FiberCtx }} + <li class="nav-item"> + <a id="nav-link-editor" + {{ if ne .NavBarActive "editor" }} + href="/editor" + hx-get="/htmx/editor" + hx-target="#app-body" + hx-push-url="/editor" + {{ end }} + class="nav-link {{ if eq .NavBarActive "editor" }} active {{ end }}" + > + <i class="ion-compose"></i> + New Article + </a> + </li> + <li class="nav-item"> + <a id="nav-link-settings" + {{ if ne .NavBarActive "settings" }} + href="/settings" + hx-get="/htmx/settings" + hx-target="#app-body" + hx-push-url="/settings" + {{ end }} + class="nav-link {{ if eq .NavBarActive "settings" }} active {{ end }}" + > + Settings + </a> + </li> + <li class="nav-item"> + <a id="nav-link-profile" + {{ if ne .NavBarActive "profile" }} + href="/users/{{ .AuthenticatedUser.Username }}" + hx-get="/htmx/users/{{ .AuthenticatedUser.Username }}" + hx-target="#app-body" + hx-push-url="/users/{{ .AuthenticatedUser.Username }}" + {{ end }} + class="nav-link {{ if eq .NavBarActive "profile" }} active {{ end }}" + > + <img class="user-pic" src="{{ .AuthenticatedUser.Image }}"> + {{ .AuthenticatedUser.Name }} + </a> + </li> + {{ end }} +</ul>
\ No newline at end of file diff --git a/cmd/web/templates/components/redirect.tmpl b/cmd/web/templates/components/redirect.tmpl new file mode 100644 index 0000000..1a706db --- /dev/null +++ b/cmd/web/templates/components/redirect.tmpl @@ -0,0 +1,6 @@ +<div id="htmx-redirect" + hx-target="{{ .HXTarget }}" + hx-trigger="{{ .HXTrigger }}" + hx-get="{{ .HXGet }}" + hx-swap-oob="true" +></div>
\ No newline at end of file diff --git a/cmd/web/templates/editor/form-message.tmpl b/cmd/web/templates/editor/form-message.tmpl new file mode 100644 index 0000000..1707e78 --- /dev/null +++ b/cmd/web/templates/editor/form-message.tmpl @@ -0,0 +1,19 @@ + {{ if .Errors }} + <div class="alert alert-danger"> + <ul> + {{ range $error := .Errors }} + <li>{{ $error }}</li> + {{ end }} + </ul> + </div> + {{ end }} + + {{ if .SuccessMessages }} + <div class="alert alert-success"> + <ul> + {{ range $message := .SuccessMessages }} + <li>{{ $message }}</li> + {{ end }} + </ul> + </div> + {{ end }}
\ No newline at end of file diff --git a/cmd/web/templates/editor/form.tmpl b/cmd/web/templates/editor/form.tmpl new file mode 100644 index 0000000..e735f75 --- /dev/null +++ b/cmd/web/templates/editor/form.tmpl @@ -0,0 +1,48 @@ +<div class="editor-page"> + <div class="container page"> + <div class="row"> + + <div class="col-md-10 col-md-offset-1 col-xs-12"> + + <div id="form-message"> + {{ template "editor/form-message" . }} + </div> + + <form method="post" + + {{ if .HasArticle }} + hx-patch="/htmx/editor/{{ .Article.Slug }}" + {{ else }} + hx-post="/htmx/editor" + {{ end }} + + hx-target="#app-body" + > + <fieldset class="form-group"> + <input type="text" name="title" class="form-control form-control-lg" placeholder="Post Title" + value="{{ .Article.Title }}" + > + </fieldset> + <fieldset class="form-group"> + <input type="text" name="description" class="form-control form-control-md" placeholder="What's this article about?" + value="{{ .Article.Description }}" + > + </fieldset> + <fieldset class="form-group"> + <textarea rows="8" name="content" class="form-control" placeholder="Write your post (in markdown)">{{ .Article.Body }}</textarea> + </fieldset> + <fieldset class="form-group"> + <input type="text" name="tags" class="form-control tagify--outside" placeholder="Enter tags" + {{ if .HasArticle }} + value="{{ .Article.GetTagsAsCommaSeparated }}" + {{ end }} + > + </fieldset> + <button class="btn btn-lg btn-primary pull-xs-right"> + Publish Article + </button> + </form> + </div> + </div> + </div> +</div>
\ No newline at end of file diff --git a/cmd/web/templates/editor/htmx-editor-page.tmpl b/cmd/web/templates/editor/htmx-editor-page.tmpl new file mode 100644 index 0000000..ef5d8cd --- /dev/null +++ b/cmd/web/templates/editor/htmx-editor-page.tmpl @@ -0,0 +1,3 @@ +{{ template "editor/form" . }} +{{ template "components/navbar" . }} +{{ template "components/head" . }}
\ No newline at end of file diff --git a/cmd/web/templates/home/htmx-home-feed.tmpl b/cmd/web/templates/home/htmx-home-feed.tmpl new file mode 100644 index 0000000..eb24863 --- /dev/null +++ b/cmd/web/templates/home/htmx-home-feed.tmpl @@ -0,0 +1,3 @@ +{{ template "home/partials/post-preview" . }} +{{ template "home/partials/feed-navigation" . }} +{{ template "home/partials/pagination" . }}
\ No newline at end of file diff --git a/cmd/web/templates/home/htmx-home-page.tmpl b/cmd/web/templates/home/htmx-home-page.tmpl new file mode 100644 index 0000000..575f328 --- /dev/null +++ b/cmd/web/templates/home/htmx-home-page.tmpl @@ -0,0 +1,3 @@ +{{ template "home/index" . }} +{{ template "components/navbar" . }} +{{ template "components/head" . }}
\ No newline at end of file diff --git a/cmd/web/templates/home/index.tmpl b/cmd/web/templates/home/index.tmpl new file mode 100644 index 0000000..65fee1d --- /dev/null +++ b/cmd/web/templates/home/index.tmpl @@ -0,0 +1,45 @@ +<div class="home-page"> + <div class="banner"> + <div class="container"> + <h1 class="logo-font">Projecty</h1> + <p>A place to share your projects.</p> + </div> + </div> + + <div class="container page"> + <div class="row"> + + <div class="col-md-9"> + <div class="feed-toggle"> + <ul id="feed-navigation" class="nav nav-pills outline-active"></ul> + </div> + + <div id="feed-post-preview" + hx-trigger="load" + + {{ if .Tag }} + hx-get="/htmx/home/tag-feed/{{ .TagSlug }}?page={{ .CurrentPage }}" + {{ else if .Personal }} + hx-get="/htmx/home/your-feed?page={{ .CurrentPage }}" + {{ else }} + hx-get="/htmx/home/global-feed?page={{ .CurrentPage }}" + {{ end }} + ></div> + + <nav id="feed-pagination"></nav> + </div> + + <div class="col-md-3"> + <div class="sidebar"> + <p>Popular Tags</p> + + <div id="popular-tag-list" class="tag-list" + hx-trigger="load" + hx-get="/htmx/home/tag-list" + ></div> + </div> + </div> + + </div> + </div> +</div> diff --git a/cmd/web/templates/home/partials/article-favorite-button.tmpl b/cmd/web/templates/home/partials/article-favorite-button.tmpl new file mode 100644 index 0000000..c26226a --- /dev/null +++ b/cmd/web/templates/home/partials/article-favorite-button.tmpl @@ -0,0 +1,6 @@ +<button class="btn btn-outline-primary btn-sm pull-xs-right {{ if .IsFavorited }} active {{ end }}" + hx-post="/htmx/home/articles/{{ .Slug }}/favorite" + hx-swap="outerHTML" +> + <i class="ion-heart"></i> {{ .GetFavoriteCount }} +</button>
\ No newline at end of file diff --git a/cmd/web/templates/home/partials/feed-navigation.tmpl b/cmd/web/templates/home/partials/feed-navigation.tmpl new file mode 100644 index 0000000..0a2356a --- /dev/null +++ b/cmd/web/templates/home/partials/feed-navigation.tmpl @@ -0,0 +1,17 @@ +<ul id="feed-navigation" class="nav nav-pills outline-active" hx-swap-oob="true"> + {{ range $item := .FeedNavbarItems }} + <li class="nav-item"> + <a class="nav-link {{ if $item.IsActive }} active {{ end }}" + {{ if not $item.IsActive }} + href="{{ $item.HXPushURL }}" + hx-get="{{ $item.HXGetURL }}" + hx-trigger="click" + hx-target="#feed-post-preview" + hx-push-url="{{ $item.HXPushURL }}" + {{ end }} + > + {{ $item.Title }} + </a> + </li> + {{ end }} +</ul>
\ No newline at end of file diff --git a/cmd/web/templates/home/partials/pagination.tmpl b/cmd/web/templates/home/partials/pagination.tmpl new file mode 100644 index 0000000..2ca4042 --- /dev/null +++ b/cmd/web/templates/home/partials/pagination.tmpl @@ -0,0 +1,18 @@ +<nav id="feed-pagination" hx-swap-oob="true"> + {{ if .HasPagination }} + {{ $CurrentPagination := .CurrentPagination }} + {{ $PathPagination := .PathPagination }} + {{ $PushPathPagination := .PushPathPagination }} + <ul class="pagination"> + {{ range $index := Iterate 1 .TotalPagination }} + <li class="page-item {{ if eq $CurrentPagination $index }} active {{ end }}"> + <a class="page-link" + href="/{{ $PathPagination }}?page={{ $index }}" + hx-push-url="/{{ $PushPathPagination }}?page={{ $index }}" + hx-get="/htmx/home/{{ $PathPagination }}?page={{ $index }}" + >{{ $index }}</a> + </li> + {{ end }} + </ul> + {{ end }} +</nav> diff --git a/cmd/web/templates/home/partials/post-preview.tmpl b/cmd/web/templates/home/partials/post-preview.tmpl new file mode 100644 index 0000000..7ef2111 --- /dev/null +++ b/cmd/web/templates/home/partials/post-preview.tmpl @@ -0,0 +1,60 @@ +<div id="feed-post-preview" hx-swap-oob="true"> + {{ if .HasArticles }} + {{ range $article := .Articles }} + + <div class="post-preview"> + <div class="post-meta"> + <a href="/users/{{ $article.User.Username }}" + hx-push-url="/users/{{ $article.User.Username }}" + hx-get="/htmx/users/{{ $article.User.Username }}" + hx-target="#app-body" + > + <img src="{{ $article.User.Image }}" /> + </a> + + <div class="info"> + <a href="/users/{{ $article.User.Username }}" + hx-push-url="/users/{{ $article.User.Username }}" + hx-get="/htmx/users/{{ $article.User.Username }}" + hx-target="#app-body" + class="author" + > + {{ $article.User.Name }} + </a> + <span class="date">{{ $article.GetFormattedCreatedAt }}</span> + </div> + + {{ template "home/partials/article-favorite-button" $article }} + + </div> + <a href="/articles/{{ $article.Slug }}" + hx-push-url="/articles/{{ $article.Slug }}" + hx-get="/htmx/articles/{{ $article.Slug }}" + hx-target="#app-body" + class="preview-link" + > + <h1>{{ $article.Title }}</h1> + <p>{{ $article.Description }}</p> + + <div class="m-t-1"> + <span>Read more...</span> + + <ul class="tag-list"> + {{ range $tag := $article.Tags }} + <li class="tag-default tag-pill tag-outline">{{ $tag.Name }}</li> + {{ end }} + </ul> + </div> + </a> + </div> + {{ end }} + {{ end }} + + {{ if not .HasArticles }} + <div class="post-preview"> + <div class="alert alert-warning" role="alert"> + No articles are here... yet. + </div> + </div> + {{ end }} +</div>
\ No newline at end of file diff --git a/cmd/web/templates/home/partials/tag-item-list.tmpl b/cmd/web/templates/home/partials/tag-item-list.tmpl new file mode 100644 index 0000000..eac4e53 --- /dev/null +++ b/cmd/web/templates/home/partials/tag-item-list.tmpl @@ -0,0 +1,12 @@ +<div id="popular-tag-list" class="tag-list" hx-swap-oob="true"> + {{ if .HasTags }} + {{ range $tag := .Tags }} + <a class="label label-pill label-default" + href="/tag-feed/{{ $tag.Name }}" + hx-get="/htmx/home/tag-feed/{{ $tag.Name }}" + hx-target="#feed-post-preview" + hx-push-url="/tag-feed/{{ $tag.Name }}" + >{{ $tag.Name }}</a> + {{ end }} + {{ end }} +</div>
\ No newline at end of file diff --git a/cmd/web/templates/layouts/app-htmx.tmpl b/cmd/web/templates/layouts/app-htmx.tmpl new file mode 100644 index 0000000..fa6e6dc --- /dev/null +++ b/cmd/web/templates/layouts/app-htmx.tmpl @@ -0,0 +1 @@ +{{ embed }}
\ No newline at end of file diff --git a/cmd/web/templates/layouts/app.tmpl b/cmd/web/templates/layouts/app.tmpl new file mode 100644 index 0000000..986f458 --- /dev/null +++ b/cmd/web/templates/layouts/app.tmpl @@ -0,0 +1,93 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>{{ .PageTitle }}</title> + <link rel="stylesheet" href="/static/css/style.css"> + <link rel="stylesheet" href="/static/css/tagify.css"> + + <style> + .tagify--outside{ + border: 0; + } + + .tagify--outside .tagify__input{ + order: -1; + flex: 100%; + border: 1px solid var(--tags-border-color); + margin-bottom: 1em; + transition: .1s; + } + + .tagify--outside .tagify__input:hover{ border-color:var(--tags-hover-border-color); } + .tagify--outside.tagify--focus .tagify__input{ + transition:0s; + border-color: var(--tags-focus-border-color); + } + + .tagify__input { border-radius: 4px; margin: 0; padding: 10px 12px; } + </style> + + <link href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css" rel="stylesheet" type="text/css"> + <link href="https://fonts.googleapis.com/css?family=Titillium+Web:700|Source+Serif+Pro:400,700|Merriweather+Sans:400,700|Source+Sans+Pro:400,300,600,700,300italic,400italic,600italic,700italic" rel="stylesheet" type="text/css"> + </head> + <body hx-ext="head-support"> + <nav class="navbar navbar-light"> + <div class="container"> + <a class="navbar-brand" + href="/" + hx-push-url="/" + hx-get="/htmx/home" + hx-target="#app-body">Projecty</a> + + {{ template "components/navbar" . }} + </div> + </nav> + + <div id="app-body"> + {{ embed }} + </div> + + <footer> + <div class="container"> + <a href="/" class="logo-font">Projecty</a> + <span class="attribution"> + An interactive personal project development and sharing website. + </span> + </div> + </footer> + + <div id="htmx-redirect"></div> + + <script src="/static/js/tagify.js"></script> + <script src="/static/js/htmx.js"></script> + <script src="/static/js/htmx-head-support.js"></script> + + <script> + var isTagify = null; + + window.addEventListener('DOMContentLoaded', function() { + renderTagify(); + }); + + document.body.addEventListener("htmx:afterSwap", function(evt) { + renderTagify(); + }); + + function renderTagify() { + const input = document.querySelector('input[name=tags]'); + const tagify = document.querySelector('tags[class="tagify form-control tagify--outside"]'); + + if (input && !tagify) { + new Tagify(input, { + whitelist: [], + dropdown: { + position: "input", + enabled : 0 // always opens dropdown when input gets focus + } + }) + } + } + </script> + </body> +</html> diff --git a/cmd/web/templates/settings/htmx-setting-page.tmpl b/cmd/web/templates/settings/htmx-setting-page.tmpl new file mode 100644 index 0000000..618c17f --- /dev/null +++ b/cmd/web/templates/settings/htmx-setting-page.tmpl @@ -0,0 +1,3 @@ +{{ template "settings/index" . }} +{{ template "components/navbar" . }} +{{ template "components/head" . }}
\ No newline at end of file diff --git a/cmd/web/templates/settings/index.tmpl b/cmd/web/templates/settings/index.tmpl new file mode 100644 index 0000000..321b169 --- /dev/null +++ b/cmd/web/templates/settings/index.tmpl @@ -0,0 +1,22 @@ +<div class="settings-page"> + <div class="container page"> + <div class="row"> + + <div class="col-md-6 col-md-offset-3 col-xs-12"> + <h1 class="text-xs-center">Your Settings</h1> + + {{ template "settings/partials/form-message" }} + + {{ template "settings/partials/form" . }} + </div> + + <div class="col-md-6 col-md-offset-3"> + <hr> + <button class="btn btn-outline-danger" hx-post="/htmx/sign-out"> + Or click here to logout. + </button> + </div> + + </div> + </div> +</div>
\ No newline at end of file diff --git a/cmd/web/templates/settings/partials/form-message.tmpl b/cmd/web/templates/settings/partials/form-message.tmpl new file mode 100644 index 0000000..44b855f --- /dev/null +++ b/cmd/web/templates/settings/partials/form-message.tmpl @@ -0,0 +1,25 @@ +<div id="settings-form-messages" + {{ if .IsOob }} + hx-swap-oob="true" + {{ end }} +> + {{ if .Errors }} + <div class="alert alert-danger"> + <ul> + {{ range $error := .Errors }} + <li>{{ $error }}</li> + {{ end }} + </ul> + </div> + {{ end }} + + {{ if .SuccessMessages }} + <div class="alert alert-success"> + <ul> + {{ range $message := .SuccessMessages }} + <li>{{ $message }}</li> + {{ end }} + </ul> + </div> + {{ end }} +</div>
\ No newline at end of file diff --git a/cmd/web/templates/settings/partials/form.tmpl b/cmd/web/templates/settings/partials/form.tmpl new file mode 100644 index 0000000..c0d8c4a --- /dev/null +++ b/cmd/web/templates/settings/partials/form.tmpl @@ -0,0 +1,25 @@ +<form + action="/settings" + method="POST" + hx-post="/htmx/settings" + id="settings-form" +> + <fieldset class="form-group"> + <input class="form-control" type="text" placeholder="URL of profile picture" value="{{ .AuthenticatedUser.Image }}" name="image_url"> + </fieldset> + <fieldset class="form-group"> + <input class="form-control form-control-lg" type="text" placeholder="Your Name" value="{{ .AuthenticatedUser.Name }}" name="name"> + </fieldset> + <fieldset class="form-group"> + <textarea class="form-control form-control-lg" rows="8" placeholder="Short bio about you" name="bio">{{ .AuthenticatedUser.Bio }}</textarea> + </fieldset> + <fieldset class="form-group"> + <input class="form-control form-control-lg" type="email" placeholder="Email" value="{{ .AuthenticatedUser.Email }}" name="email"> + </fieldset> + <fieldset class="form-group"> + <input class="form-control form-control-lg" type="password" placeholder="Password" name="password"> + </fieldset> + <button class="btn btn-lg btn-primary pull-xs-right" hx-post="/htmx/settings" hx-swap="none"> + Update Settings + </button> +</form>
\ No newline at end of file diff --git a/cmd/web/templates/settings/partials/htmx-form-message.tmpl b/cmd/web/templates/settings/partials/htmx-form-message.tmpl new file mode 100644 index 0000000..1e5f5bc --- /dev/null +++ b/cmd/web/templates/settings/partials/htmx-form-message.tmpl @@ -0,0 +1,2 @@ +{{ template "settings/partials/form-message" . }} +{{ template "components/navbar" . }}
\ No newline at end of file diff --git a/cmd/web/templates/sign-in/htmx-sign-in-page.tmpl b/cmd/web/templates/sign-in/htmx-sign-in-page.tmpl new file mode 100644 index 0000000..3201ee8 --- /dev/null +++ b/cmd/web/templates/sign-in/htmx-sign-in-page.tmpl @@ -0,0 +1,3 @@ +{{ template "sign-in/index" . }} +{{ template "components/navbar" . }} +{{ template "components/head" . }}
\ No newline at end of file diff --git a/cmd/web/templates/sign-in/index.tmpl b/cmd/web/templates/sign-in/index.tmpl new file mode 100644 index 0000000..8f6806d --- /dev/null +++ b/cmd/web/templates/sign-in/index.tmpl @@ -0,0 +1,23 @@ +<div class="auth-page"> + <div class="container page"> + <div class="row"> + + <div class="col-md-6 col-md-offset-3 col-xs-12"> + <h1 class="text-xs-center">Sign in</h1> + <p class="text-xs-center"> + <a + href="/sign-up" + hx-push-url="/sign-up" + hx-get="/htmx/sign-up" + hx-target="#app-body" + > + Need an account? + </a> + </p> + + {{ template "sign-in/partials/sign-in-form" }} + </div> + + </div> + </div> +</div>
\ No newline at end of file diff --git a/cmd/web/templates/sign-in/partials/sign-in-form.tmpl b/cmd/web/templates/sign-in/partials/sign-in-form.tmpl new file mode 100644 index 0000000..21f2c84 --- /dev/null +++ b/cmd/web/templates/sign-in/partials/sign-in-form.tmpl @@ -0,0 +1,27 @@ +<div id="sign-in-form-messages" + {{ if .IsOob }} + hx-swap-oob="true" + {{ end }} +> + {{ if .Errors }} + <div class="alert alert-danger"> + <ul> + {{ range $error := .Errors }} + <li>{{ $error }}</li> + {{ end }} + </ul> + </div> + {{ end }} +</div> + +<form method="POST" hx-post="/htmx/sign-in"> + <fieldset class="form-group"> + <input type="text" id="sign-in-email" class="form-control form-control-lg" name="email" placeholder="Email"> + </fieldset> + <fieldset class="form-group"> + <input type="password" id="sign-in-password" class="form-control form-control-lg" name="password" placeholder="Password"> + </fieldset> + <button class="btn btn-lg btn-primary pull-xs-right"> + Sign in + </button> +</form>
\ No newline at end of file diff --git a/cmd/web/templates/sign-up/htmx-sign-up-page.tmpl b/cmd/web/templates/sign-up/htmx-sign-up-page.tmpl new file mode 100644 index 0000000..a4cf3d7 --- /dev/null +++ b/cmd/web/templates/sign-up/htmx-sign-up-page.tmpl @@ -0,0 +1,3 @@ +{{ template "sign-up/index" . }} +{{ template "components/navbar" . }} +{{ template "components/head" . }}
\ No newline at end of file diff --git a/cmd/web/templates/sign-up/index.tmpl b/cmd/web/templates/sign-up/index.tmpl new file mode 100644 index 0000000..2c0992e --- /dev/null +++ b/cmd/web/templates/sign-up/index.tmpl @@ -0,0 +1,23 @@ +<div class="auth-page"> + <div class="container page"> + <div class="row"> + + <div class="col-md-6 col-md-offset-3 col-xs-12"> + <h1 class="text-xs-center">Sign up</h1> + <p class="text-xs-center"> + <a + href="/sign-in" + hx-push-url="/sign-in" + hx-get="/htmx/sign-in" + hx-target="#app-body" + > + Have an account? + </a> + </p> + + {{ template "sign-up/partials/sign-up-form" }} + </div> + + </div> + </div> +</div>
\ No newline at end of file diff --git a/cmd/web/templates/sign-up/partials/sign-up-form.tmpl b/cmd/web/templates/sign-up/partials/sign-up-form.tmpl new file mode 100644 index 0000000..be34243 --- /dev/null +++ b/cmd/web/templates/sign-up/partials/sign-up-form.tmpl @@ -0,0 +1,30 @@ +<div id="sign-up-form-messages" + {{ if .IsOob }} + hx-swap-oob="true" + {{ end }} +> + {{ if .Errors }} + <div class="alert alert-danger"> + <ul> + {{ range $error := .Errors }} + <li>{{ $error }}</li> + {{ end }} + </ul> + </div> + {{ end }} +</div> + +<form method="POST" hx-post="/htmx/sign-up"> +<fieldset class="form-group"> + <input id="sign-up-username" class="form-control form-control-lg" type="text" name="username" placeholder="Username"> +</fieldset> +<fieldset class="form-group"> + <input id="sign-up-email" class="form-control form-control-lg" type="text" name="email" placeholder="Email"> +</fieldset> +<fieldset class="form-group"> + <input id="sign-up-password" class="form-control form-control-lg" type="password" name="password" placeholder="Password"> +</fieldset> +<button class="btn btn-lg btn-primary pull-xs-right"> + Sign up +</button> +</form>
\ No newline at end of file diff --git a/cmd/web/templates/users/htmx-users-articles.tmpl b/cmd/web/templates/users/htmx-users-articles.tmpl new file mode 100644 index 0000000..d002097 --- /dev/null +++ b/cmd/web/templates/users/htmx-users-articles.tmpl @@ -0,0 +1,2 @@ +{{ template "users/partials/post-preview" . }} +{{ template "users/partials/feed-navigation" . }}
\ No newline at end of file diff --git a/cmd/web/templates/users/htmx-users-page.tmpl b/cmd/web/templates/users/htmx-users-page.tmpl new file mode 100644 index 0000000..020649e --- /dev/null +++ b/cmd/web/templates/users/htmx-users-page.tmpl @@ -0,0 +1,3 @@ +{{ template "users/show" . }} +{{ template "components/navbar" . }} +{{ template "components/head" . }}
\ No newline at end of file diff --git a/cmd/web/templates/users/partials/article-favorite-button.tmpl b/cmd/web/templates/users/partials/article-favorite-button.tmpl new file mode 100644 index 0000000..c63182a --- /dev/null +++ b/cmd/web/templates/users/partials/article-favorite-button.tmpl @@ -0,0 +1,12 @@ +<button class="btn btn-outline-primary btn-sm pull-xs-right {{ if .Article.IsFavorited }} active {{ end }}" + hx-post="/htmx/users/articles/{{ .Article.Slug }}/favorite" + + {{ if .IsSelf }} + hx-swap="delete" + hx-target="closest .post-preview" + {{ else }} + hx-swap="outerHTML" + {{ end }} +> + <i class="ion-heart"></i> {{ .Article.GetFavoriteCount }} +</button>
\ No newline at end of file diff --git a/cmd/web/templates/users/partials/feed-navigation.tmpl b/cmd/web/templates/users/partials/feed-navigation.tmpl new file mode 100644 index 0000000..00629d9 --- /dev/null +++ b/cmd/web/templates/users/partials/feed-navigation.tmpl @@ -0,0 +1,17 @@ +<ul id="user-feed-navigation" class="nav nav-pills outline-active" hx-swap-oob="true"> + {{ range $item := .FeedNavbarItems }} + <li class="nav-item"> + <a class="nav-link {{ if $item.IsActive }} active {{ end }}" + {{ if not $item.IsActive }} + href="{{ $item.HXPushURL }}" + hx-get="{{ $item.HXGetURL }}" + hx-trigger="click" + hx-target="#user-post-preview" + hx-push-url="{{ $item.HXPushURL }}" + {{ end }} + > + {{ $item.Title }} + </a> + </li> + {{ end }} +</ul>
\ No newline at end of file diff --git a/cmd/web/templates/users/partials/follow-button.tmpl b/cmd/web/templates/users/partials/follow-button.tmpl new file mode 100644 index 0000000..d893ea0 --- /dev/null +++ b/cmd/web/templates/users/partials/follow-button.tmpl @@ -0,0 +1,14 @@ +<button class="btn btn-sm btn-outline-secondary follow-button action-btn" + hx-post="/htmx/users/{{ .User.Username }}/follow" + hx-swap="outerHTML" +> + {{ if .IsFollowed }} + <i class="ion-minus-round"></i> + Unfollow + {{ else }} + <i class="ion-plus-round"></i> + Follow + {{ end }} + {{ .User.Name }} + <span class="counter">({{ .User.FollowersCount }})</span> +</button>
\ No newline at end of file diff --git a/cmd/web/templates/users/partials/post-preview.tmpl b/cmd/web/templates/users/partials/post-preview.tmpl new file mode 100644 index 0000000..4e00357 --- /dev/null +++ b/cmd/web/templates/users/partials/post-preview.tmpl @@ -0,0 +1,61 @@ +<div id="user-post-preview"> + {{ if .HasArticles }} + {{ $isSelf := .IsSelf }} + {{ range $article := .Articles }} + + <div class="post-preview"> + <div class="post-meta"> + <a href="/users/{{ $article.User.Username }}" + hx-push-url="/users/{{ $article.User.Username }}" + hx-get="/htmx/users/{{ $article.User.Username }}" + hx-target="#app-body" + > + <img src="{{ $article.User.Image }}" /> + </a> + + <div class="info"> + <a href="/users/{{ $article.User.Username }}" + hx-push-url="/users/{{ $article.User.Username }}" + hx-get="/htmx/users/{{ $article.User.Username }}" + hx-target="#app-body" + class="author" + > + {{ $article.User.Name }} + </a> + <span class="date">{{ $article.GetFormattedCreatedAt }}</span> + </div> + + {{ template "users/partials/article-favorite-button" Dict "Article" $article "IsSelf" $isSelf }} + + </div> + <a href="/articles/{{ $article.Slug }}" + hx-push-url="/articles/{{ $article.Slug }}" + hx-get="/htmx/articles/{{ $article.Slug }}" + hx-target="#app-body" + class="preview-link" + > + <h1>{{ $article.Title }}</h1> + <p>{{ $article.Description }}</p> + + <div class="m-t-1"> + <span>Read more...</span> + + <ul class="tag-list"> + {{ range $tag := $article.Tags }} + <li class="tag-default tag-pill tag-outline">{{ $tag.Name }}</li> + {{ end }} + </ul> + </div> + </a> + </div> + {{ end }} + {{ end }} + + {{ if not .HasArticles }} + <div class="post-preview"> + <div class="alert alert-warning" role="alert"> + No articles are here... yet. + </div> + </div> + {{ end }} +</div>
\ No newline at end of file diff --git a/cmd/web/templates/users/show.tmpl b/cmd/web/templates/users/show.tmpl new file mode 100644 index 0000000..cf9f1d7 --- /dev/null +++ b/cmd/web/templates/users/show.tmpl @@ -0,0 +1,51 @@ +<div class="profile-page"> + <div class="user-info"> + <div class="container"> + <div class="row"> + + <div class="col-md-10 col-md-offset-1"> + <img src="{{ .User.Image }}" class="user-img" /> + <h4>{{ .User.Name }}</h4> + <p>{{ .User.Bio }}</p> + + {{ if .IsSelf }} + <a class="btn btn-sm btn-outline-secondary action-btn" + href="/settings" + hx-push-url="/settings" + hx-get="/htmx/settings" + hx-target="#app-body" + > + <i class="ion-ios-gear"></i> + + Edit Profile Settings</span> + </a> + {{ else }} + + {{ template "users/partials/follow-button" . }} + + {{ end }} + </div> + + </div> + </div> + </div> + + <div class="container"> + <div class="row"> + <div class="col-md-10 col-md-offset-1"> + <div class="posts-toggle"> + <ul id="user-feed-navigation" class="nav nav-pills outline-active"></ul> + </div> + + <div id="user-post-preview" + {{ if .IsLoadFavorites }} + hx-get="/htmx/users/{{ .User.Username }}/favorites" + {{ else }} + hx-get="/htmx/users/{{ .User.Username }}/articles" + {{ end }} + hx-trigger="load" + ></div> + </div> + </div> + </div> +</div>
\ No newline at end of file |