initial commit

This commit is contained in:
xuu
2023-07-15 08:35:45 -06:00
commit 976ce36be2
26 changed files with 1272 additions and 0 deletions

View File

@@ -0,0 +1,127 @@
{{define "main"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Mail Admin.">
<title>mailadm</title>
<script src="/htmx.org@1.9.2.js" integrity="sha384-L6OqL9pRWyyFU3+/bjdSri+iIphTN/bvYyM37tICVyOJkWZLpP2vGn6VUEXgzg6h" crossorigin="anonymous"></script>
<link rel="stylesheet" href="/pure-min@3.0.0.css" integrity="sha384-X38yfunGUhNzHpBaEBsWLO+A0HDYOQi8ufWDkZ0k9e0eXz/tH3II7uKZ9msv++Ls" crossorigin="anonymous">
<link rel="stylesheet" href="/layout.css" crossorigin="anonymous">
<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>
<body id="layout" class="content pure-g">
<nav id="nav" class="pure-u">
<input id="menu-toggle" type="checkbox" />
<label class='menu-button-container' for="menu-toggle">
<div class='menu-button'></div>
<div class="nav-inner">
<button class="primary-button pure-button">Compose</button>
<div class="pure-menu">
<ul class="pure-menu-list">
<li class="pure-menu-item"><a href="#" class="pure-menu-link">Inbox <span class="email-count">(2)</span></a></li>
<li class="pure-menu-item"><a href="#" class="pure-menu-link">Important</a></li>
<li class="pure-menu-item"><a href="#" class="pure-menu-link">Sent</a></li>
<li class="pure-menu-item"><a href="#" class="pure-menu-link">Drafts</a></li>
<li class="pure-menu-item"><a href="#" class="pure-menu-link">Trash</a></li>
<li class="pure-menu-heading">Labels</li>
<li class="pure-menu-item"><a href="#" class="pure-menu-link"><span class="email-label-personal"></span>Personal</a></li>
<li class="pure-menu-item"><a href="#" class="pure-menu-link"><span class="email-label-work"></span>Work</a></li>
<li class="pure-menu-item"><a href="#" class="pure-menu-link"><span class="email-label-travel"></span>Travel</a></li>
</ul>
</div>
</div>
</nav>
<div id="list" class="pure-u-1">
<div class="email-item email-item-selected pure-g">
<div class="pure-u">
<img width="64" height="64" alt="Tilo Mitra&#x27;s avatar" class="email-avatar" src="/img/common/tilo-avatar.png">
</div>
<div class="pure-u-3-4">
<h5 class="email-name">Tilo Mitra</h5>
<h4 class="email-subject">Hello from Toronto</h4>
<p class="email-desc">
Hey, I just wanted to check in with you from Toronto. I got here earlier today.
</p>
</div>
</div>
<div class="email-item email-item-unread pure-g">
<div class="pure-u">
<img width="64" height="64" alt="Eric Ferraiuolo&#x27;s avatar" class="email-avatar" src="/img/common/ericf-avatar.png">
</div>
<div class="pure-u-3-4">
<h5 class="email-name">Eric Ferraiuolo</h5>
<h4 class="email-subject">Re: Pull Requests</h4>
<p class="email-desc">
Hey, I had some feedback for pull request #51. We should center the menu so it looks better on mobile.
</p>
</div>
</div>
<div class="email-item pure-g">
<div class="pure-u">
<img width="64" height="64" alt="Reid Burke&#x27;s avatar" class="email-avatar" src="/img/common/reid-avatar.png">
</div>
<div class="pure-u-3-4">
<h5 class="email-name">Reid Burke</h5>
<h4 class="email-subject">Re: Design Language</h4>
<p class="email-desc">
Excepteur sint occaecat cupidatat non proident, sunt in culpa.
</p>
</div>
</div>
<div class="email-item pure-g">
<div class="pure-u">
<img width="64" height="64" alt="Yahoo! Finance&#x27;s Avatar" class="email-avatar" src="/img/common/yfinance-avatar.png">
</div>
<div class="pure-u-3-4">
<h5 class="email-name">Yahoo! Finance</h5>
<h4 class="email-subject">How to protect your finances from winter storms</h4>
<p class="email-desc">
Mauris tempor mi vitae sem aliquet pharetra. Fusce in dui purus, nec malesuada mauris.
</p>
</div>
</div>
<div class="email-item pure-g">
<div class="pure-u">
<img width="64" height="64" alt="Yahoo! News&#x27; avatar" class="email-avatar" src="/img/common/ynews-avatar.png">
</div>
<div class="pure-u-3-4">
<h5 class="email-name">Yahoo! News</h5>
<h4 class="email-subject">Summary for April 3rd, 2021</h4>
<p class="email-desc">
We found 10 news articles that you may like.
</p>
</div>
</div>
</div>
<secton id="main" class="pure-u-1">
{{template "content" .}}
</section>
</body>
</html>
{{end}}

74
app/mailadm/mailadm.go Normal file
View File

@@ -0,0 +1,74 @@
package mailadm
import (
"embed"
"io/fs"
"log"
"net/http"
"strconv"
"text/template"
"go.sour.is/pkg/lg"
)
var (
//go:embed pages/* layouts/*
files embed.FS
templates map[string]*template.Template
)
type mailadm struct{}
func New() *mailadm {
return &mailadm{}
}
func (s *mailadm) RegisterHTTP(mux *http.ServeMux) {
mux.Handle("/mailadm/", lg.Htrace(s, "mailadm"))
s.loadTemplates()
}
func (s *mailadm) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/mailadm/clicked" {
templates["edit.go.tpl"].Execute(w, r.URL.Query())
return
}
templates["home.go.tpl"].Execute(w, nil)
}
var funcMap = map[string]any{
"addone": func(s string) string {
if i, err := strconv.Atoi(s); err == nil {
return strconv.Itoa(i + 1)
}
return s
},
}
func (s *mailadm) loadTemplates() error {
if templates != nil {
return nil
}
templates = make(map[string]*template.Template)
tmplFiles, err := fs.ReadDir(files, "pages")
if err != nil {
return err
}
for _, tmpl := range tmplFiles {
if tmpl.IsDir() {
continue
}
pt := template.New(tmpl.Name())
pt.Funcs(funcMap)
pt, err = pt.ParseFS(files, "pages/"+tmpl.Name(), "layouts/*.go.tpl")
if err != nil {
log.Println(err)
return err
}
templates[tmpl.Name()] = pt
}
return nil
}

View File

@@ -0,0 +1,3 @@
<button hx-get="/mailadm/clicked?times={{ addone ( .Get "times" ) }}" hx-swap="outerHTML">
Clicked {{ .Get "times" }} times!
</button>

View File

@@ -0,0 +1,8 @@
{{template "main" .}}
{{define "content"}}
<h2>What is this?</h2>
<button hx-get="/mailadm/clicked?times=1" hx-swap="outerHTML">
Click Me!
</button>
{{end}}

View File

@@ -0,0 +1,6 @@
This favicon was generated using the following graphics from Twitter Twemoji:
- Graphics Title: 2699.svg
- Graphics Author: Copyright 2020 Twitter, Inc and other contributors (https://github.com/twitter/twemoji)
- Graphics Source: https://github.com/twitter/twemoji/blob/master/assets/svg/2699.svg
- Graphics License: CC-BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
app/root/assets/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>tools</title>
<script src="/htmx.org@1.9.2.js" integrity="sha384-L6OqL9pRWyyFU3+/bjdSri+iIphTN/bvYyM37tICVyOJkWZLpP2vGn6VUEXgzg6h" crossorigin="anonymous"></script>
<link rel="stylesheet" href="/pure-min.css" integrity="sha384-X38yfunGUhNzHpBaEBsWLO+A0HDYOQi8ufWDkZ0k9e0eXz/tH3II7uKZ9msv++Ls" crossorigin="anonymous">
<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>
<body>
<nav>
<ol>
<li><a href="/mailadm/">mailadm</a></li>
</ol>
</nav>
</body>
</html>

274
app/root/assets/layout.css Normal file
View File

@@ -0,0 +1,274 @@
/*
* -- BASE STYLES --
* Most of these are inherited from Base, but I want to change a few.
*/
body {
color: #333;
}
a {
text-decoration: none;
color: #1b98f8;
}
/*
* -- HELPER STYLES --
* Over-riding some of the .pure-button styles to make my buttons look unique
*/
.primary-button,
.secondary-button {
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
border-radius: 20px;
}
.primary-button {
color: #fff;
background: #1b98f8;
margin: 1em 0;
}
.secondary-button {
background: #fff;
border: 1px solid #ddd;
color: #666;
padding: 0.5em 2em;
font-size: 80%;
}
/*
* -- LAYOUT STYLES --
* This layout consists of three main elements, `#nav` (navigation bar), `#list` (email list), and `#main` (email content). All 3 elements are within `#layout`
*/
#layout, #nav, #list, #main {
margin: 0;
padding: 0;
}
/* Make the navigation 100% width on phones */
#nav {
width: 100%;
height: 40px;
position: relative;
background: rgb(37, 42, 58);
text-align: center;
}
/* Show the "Menu" button on phones */
#nav .nav-menu-button {
display: block;
top: 0.5em;
right: 0.5em;
position: absolute;
}
/* When "Menu" is clicked, the navbar should be 80% height */
#nav.active {
height: 80%;
}
/* Don't show the navigation items... */
.nav-inner {
display: none;
}
/* ...until the "Menu" button is clicked */
#nav.active .nav-inner {
display: block;
padding: 2em 0;
}
/*
* -- NAV BAR STYLES --
* Styling the default .pure-menu to look a little more unique.
*/
#nav .pure-menu {
background: transparent;
border: none;
text-align: left;
}
#nav .pure-menu-link:hover,
#nav .pure-menu-link:focus {
background: rgb(55, 60, 90);
}
#nav .pure-menu-link {
color: #fff;
margin-left: 0.5em;
}
#nav .pure-menu-heading {
border-bottom: none;
font-size:110%;
color: rgb(75, 113, 151);
}
/*
* -- EMAIL STYLES --
* Styles relevant to the email messages, labels, counts, and more.
*/
.email-count {
color: rgb(75, 113, 151);
}
.email-label-personal,
.email-label-work,
.email-label-travel {
width: 15px;
height: 15px;
display: inline-block;
margin-right: 0.5em;
border-radius: 3px;
}
.email-label-personal {
background: #ffc94c;
}
.email-label-work {
background: #41ccb4;
}
.email-label-travel {
background: #40c365;
}
/* Email Item Styles */
.email-item {
padding: 0.9em 1em;
border-bottom: 1px solid #ddd;
border-left: 6px solid transparent;
}
.email-avatar {
border-radius: 3px;
margin-right: 0.5em;
}
.email-name,
.email-subject {
margin: 0;
}
.email-name {
text-transform: uppercase;
color: #999;
}
.email-desc {
font-size: 80%;
margin: 0.4em 0;
}
.email-item-selected {
background: #eee;
}
.email-item-unread {
border-left: 6px solid #1b98f8;
}
/* Email Content Styles */
.email-content-header, .email-content-body, .email-content-footer {
padding: 1em 2em;
}
.email-content-header {
border-bottom: 1px solid #ddd;
}
.email-content-title {
margin: 0.5em 0 0;
}
.email-content-subtitle {
font-size: 1em;
margin: 0;
font-weight: normal;
}
.email-content-subtitle span {
color: #999;
}
.email-content-controls {
margin-top: 2em;
text-align: right;
}
.email-content-controls .secondary-button {
margin-bottom: 0.3em;
}
.email-avatar {
width: 40px;
height: 40px;
}
/*
* -- TABLET (AND UP) MEDIA QUERIES --
* On tablets and other medium-sized devices, we want to customize some
* of the mobile styles.
*/
@media (min-width: 40em) {
/* Move the layout over so we can fit the nav + list in on the left */
#layout {
padding-left:500px; /* "left col (nav + list)" width */
position: relative;
}
/* These are position:fixed; elements that will be in the left 500px of the screen */
#nav, #list {
position: fixed;
top: 0;
bottom: 0;
overflow: auto;
}
#nav {
margin-left:-500px; /* "left col (nav + list)" width */
width:150px;
height: 100%;
}
/* Show the menu items on the larger screen */
.nav-inner {
display: block;
padding: 2em 0;
}
/* Hide the "Menu" button on larger screens */
#nav .nav-menu-button {
display: none;
}
#list {
margin-left: -350px;
width: 100%;
height: 33%;
border-bottom: 1px solid #ddd;
}
#main {
position: fixed;
top: 33%;
right: 0;
bottom: 0;
left: 150px;
overflow: auto;
width: auto; /* so that it's not 100% */
}
}
/*
* -- DESKTOP (AND UP) MEDIA QUERIES --
* On desktops and other large-sized devices, we want to customize some
* of the mobile styles.
*/
@media (min-width: 60em) {
/* This will take up the entire height, and be a little thinner */
#list {
margin-left: -350px;
width:350px;
height: 100%;
border-right: 1px solid #ddd;
}
/* This will now take up it's own column, so don't need position: fixed; */
#main {
position: static;
margin: 0;
padding: 0;
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}

27
app/root/root.go Normal file
View File

@@ -0,0 +1,27 @@
package root
import (
"embed"
"io/fs"
"net/http"
"go.sour.is/pkg/lg"
)
var (
//go:embed assets/*
files embed.FS
)
type root struct{}
func New() *root {
return &root{}
}
func (s *root) RegisterHTTP(mux *http.ServeMux) {
a, _ := fs.Sub(files, "assets")
assets := http.StripPrefix("/", http.FileServer(http.FS(a)))
mux.Handle("/", lg.Htrace(assets, "mailadm-assets"))
}