style web pages

This commit is contained in:
Guilherme Rugai Freire 2024-07-10 16:02:03 -03:00
parent f1190e9892
commit 52b3fa61ca
No known key found for this signature in database
GPG Key ID: AC1D9B6E48E16AC1
7 changed files with 307 additions and 28 deletions

View File

@ -0,0 +1,13 @@
package main
templ header(rcpt_addr string) {
<div class="header">
<h3>
nthmail.xyz
</h3>
<div class="header-addr">
<p>inbox: </p>
<span>{ rcpt_addr }</span>
</div>
</div>
}

View File

@ -13,26 +13,35 @@ templ inbox_body(rcpt_addr string, ms []mail_utils.Mail_obj) {
<title>nthmail.xyz</title>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="description" content="A temporary mail service"/>
@styles()
</head>
<body>
<h1>Emails for { rcpt_addr }:</h1>
<ul>
for _, m := range ms {
<li>
@mail_comp(m, rcpt_addr)
</li>
<body class="inbox">
@header(rcpt_addr)
<div class="inbox-main">
if len(ms) != 0 {
<ul>
for _, m := range ms {
<li>
@mail_comp(m, rcpt_addr)
</li>
}
</ul>
} else {
<div class="inbox-empty">
<h3>inbox empty</h3>
</div>
}
</ul>
</div>
</body>
</html>
}
templ mail_comp(m mail_utils.Mail_obj, rcpt_addr string) {
<a href={ templ.SafeURL(fmt.Sprintf("/%s/%d", rcpt_addr, m.Id)) }>
<div>
<p><b>{ m.Subject }</b></p>
<p>From { m.From }</p>
<div class="content">
<p class="inbox-mail-subj"><b>{ m.Subject }</b></p>
<p class="inbox-mail-from">{ m.From }</p>
</div>
<p>{ m.Date }</p>
<p class="inbox-mail-date">{ m.Date.Format("3:04 PM") }</p>
</a>
}

View File

@ -8,15 +8,16 @@ templ index_page() {
<title>nthmail.xyz</title>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="description" content="A temporary mail service"/>
@styles()
</head>
<body>
<body class="index">
<h1>nthmail.xyz</h1>
<p>
A disposable, temporary and private mail address!
</p>
<form action="random" >
<button type="submit">Get one now!</button>
</form>
<div class="random">
<a href="random">Get one now!</a>
</div>
</body>
</html>
}

View File

@ -13,12 +13,24 @@ templ mail_body_comp(rcpt_addr string, m mail_utils.Mail_obj) {
<title>nthmail.xyz</title>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="description" content="A temporary mail service"/>
@styles()
</head>
<body>
<header>
<h3>{m.Subject}</h3>
<h3>{m.From}</h3>
</header>
<body class="mail">
@header(rcpt_addr)
<div class="mail-header">
<div class="mail-from">
<span>From: </span>
<h3>{ m.From }</h3>
</div>
<div class="mail-subject">
<span>Subject: </span>
<h3>{ m.Subject }</h3>
</div>
<div class="mail-date">
<span>At: </span>
<h3>{ m.Date.Format("15:04:05 02/01/2006") }</h3>
</div>
</div>
<main>
@mime_type(m.Body[m.PreferedBodyIndex])
</main>
@ -40,16 +52,21 @@ templ mime_type(b mail_utils.Mail_body) {
}
templ body_plain(s string) {
<p>{ s }</p>
<div class="content-text">
<pre>
{ s }
</pre>
</div>
}
templ body_html(s string) {
<p>
<div class="content-html">
@templ.Raw(s)
</p>
</div>
}
templ body_markdown(s string) {
@body_html(string(blackfriday.Run([]byte(s))))
)
<div class="content-md">
{ string(blackfriday.Run([]byte(s))) }
</div>
}

View File

@ -7,6 +7,7 @@ import (
"net/http"
"os"
"strconv"
"time"
"github.com/GRFreire/nthmail/pkg/mail_utils"
"github.com/GRFreire/nthmail/pkg/rig"
@ -133,6 +134,7 @@ func (sr ServerResouces) handleInbox(res http.ResponseWriter, req *http.Request)
}
mail_obj, err := mail_utils.Parse_mail(m.Data, true)
mail_obj.Date = time.Unix(m.Arrived_at, 0)
mail_obj.Id = m.Id
if err != nil {
res.WriteHeader(500)
@ -198,6 +200,7 @@ func (sr ServerResouces) handleMail(res http.ResponseWriter, req *http.Request)
}
mail_obj, err := mail_utils.Parse_mail(m.Data, false)
mail_obj.Date = time.Unix(m.Arrived_at, 0)
mail_obj.Id = m.Id
if err != nil {
res.WriteHeader(500)

236
cmd/web_server/styles.templ Normal file
View File

@ -0,0 +1,236 @@
package main
templ styles() {
<style>
html {
box-sizing: border-box;
font-size: 16px;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
background-color: #181818 !important;
color: #FEFEFE;
}
body, h1, h2, h3, h4, h5, h6, p, ol, ul {
margin: 0;
padding: 0;
font-weight: normal;
}
ol, ul {
list-style: none;
}
img {
max-width: 100%;
height: auto;
}
/* INDEX */
body.index {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 100vh;
margin-top: -100px;
}
body.index h1 {
font-size: 4rem;
margin: 16px;
}
body.index p {
font-size: 1.4rem;
font-family: monospace, "sans-serif";
}
body.index .random {
margin: 64px;
}
body.index .random a {
text-decoration: none;
font-size: 1.4rem;
font-family: monospace, "sans-serif";
height: 80px;
padding: 18px;
border-style: solid;
border-width: 2px;
border-radius: 4px;
border-color: #FEFEFE;
color: #FEFEFE;
background-color: #181818;
cursor: pointer;
}
/* HEADER */
.header {
display: flex;
flex-direction: row;
justify-content: space-between;
width: 65%;
border-style: none none solid none;
border-color: #FEFEFEFE;
border-width: 2px;
padding: 4px;
font-size: 1.4rem;
font-family: monospace, "sans-serif";
}
.header h3 {
font-weight: bold;
}
.header .header-addr {
display: flex;
flex-direction: row;
}
.header .header-addr span {
margin-left: 18px;
font-style: italic;
}
/* INBOX */
body.inbox {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
body.inbox .inbox-main {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 65%;
}
body.inbox .inbox-main .inbox-empty {
margin-top: 64px;
display: flex;
justify-content: center;
align-items: center;
padding-bottom: 32px;
}
body.inbox .inbox-main .inbox-empty h3 {
font-size: 2rem;
font-family: monospace, "sans-serif";
color: #CECECE;
}
body.inbox .inbox-main ul {
width: 100%;
margin: 16px 0;
border: solid 1px #2E2E2E;
}
body.inbox .inbox-main li {
width: 100%;
padding: 8px;
background: #1F1F1F;
}
body.inbox .inbox-main li:nth-child(odd) {
background: #262626;
}
body.inbox .inbox-main li a {
text-decoration: none;
color: #FEFEFE;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
flex-grow: 0;
flex-basis: 100%;
width: 100%;
}
body.inbox .inbox-main li a div {
max-width: calc(100% - (1.1rem * 8));
display: block;
}
body.inbox .inbox-main li a .inbox-mail-subj {
font-size: 1.4rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
body.inbox .inbox-main li a .inbox-mail-from {
margin-top: 8px;
}
body.inbox .inbox-main li a .inbox-mail-date {
margin-top: -4px;
margin-left: 32px;
font-size: 1.1rem;
}
/* MAIL */
body.mail {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
body.mail .mail-header {
width: 65%;
margin-top: 16px;
border: solid 1px #CECECE;
background: #262626;
}
body.mail .mail-header div {
margin: 4px 0;
background: #262626;
padding: 8px;
}
body.mail .mail-header div:nth-child(odd) {
background: #1F1F1F;
}
body.mail .mail-header div span {
color: #CECECE;
}
body.mail main {
width: 65%;
margin: 16px 0;
min-height: 20vh;
}
body.mail main div {
min-width: 100px;
}
body.mail main div pre {
white-space: pre-wrap;
}
</style>
}

View File

@ -11,6 +11,7 @@ import (
"net/mail"
"slices"
"strings"
"time"
)
type MIMEType uint8
@ -36,7 +37,7 @@ type Mail_body struct {
type Mail_obj struct {
Id int
From string
Date string
Date time.Time
To string
Bcc string
Subject string
@ -78,7 +79,6 @@ func Parse_mail(m_data []byte, header_only bool) (Mail_obj, error) {
// HEADERS
dec := new(mime.WordDecoder)
m.From, _ = dec.DecodeHeader(mail_msg.Header.Get("From"))
m.Date, _ = dec.DecodeHeader(mail_msg.Header.Get("Date"))
m.To, _ = dec.DecodeHeader(mail_msg.Header.Get("To"))
m.Bcc, _ = dec.DecodeHeader(mail_msg.Header.Get("Bcc"))
m.Subject, _ = dec.DecodeHeader(mail_msg.Header.Get("Subject"))