this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

✨ Add /contact

+145 -1
+1 -1
Justfile
··· 3 3 REMOVE_UNUSED_MESSAGES=1 ENV=static ./tmp/main 4 4 5 5 dev: 6 - ENV=development air 6 + MAIL_PASSWORD=$(rbw get mail.ewen.works) ENV=development air 7 7 8 8 start: 9 9 just build
+2
go.mod
··· 15 15 github.com/ortfo/gettext v1.0.3 16 16 golang.org/x/net v0.17.0 17 17 golang.org/x/text v0.14.0 18 + gopkg.in/mail.v2 v2.3.1 18 19 gopkg.in/yaml.v3 v3.0.1 19 20 ) 20 21 ··· 53 54 github.com/xeipuuv/gojsonschema v1.2.0 // indirect 54 55 golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 // indirect 55 56 golang.org/x/sys v0.13.0 // indirect 57 + gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect 56 58 gopkg.in/yaml.v2 v2.4.0 // indirect 57 59 )
+4
go.sum
··· 169 169 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 170 170 golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= 171 171 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 172 + gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= 173 + gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= 172 174 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 173 175 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 174 176 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 175 177 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 178 + gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk= 179 + gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw= 176 180 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 177 181 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 178 182 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+15
i18n/fr.po
··· 216 216 msgid "contact" 217 217 msgstr "contact" 218 218 219 + msgid "Contact me" 220 + msgstr "Contactez-moi" 221 + 219 222 msgid "cover arts" 220 223 msgstr "pochettes" 221 224 ··· 309 312 msgid "math" 310 313 msgstr "maths" 311 314 315 + msgid "Message" 316 + msgstr "Message" 317 + 312 318 msgid "motion design" 313 319 msgstr "motion design" 314 320 ··· 369 375 msgid "Search" 370 376 msgstr "Rechercher" 371 377 378 + msgid "Send" 379 + msgstr "Envoyer" 380 + 372 381 msgid "Set of glyphs (letters, punctuation marks and more) that define how text looks." 373 382 msgstr "Ensemble de glyphes (lettres, signes de ponctuation et plus encore) qui définissent l'apparence du texte." 374 383 ··· 380 389 381 390 msgid "Source code" 382 391 msgstr "Code source" 392 + 393 + msgid "Subject" 394 + msgstr "Objet" 383 395 384 396 msgid "The Intuitive Vue Framework" 385 397 msgstr "Le Framework Vue Intuitif" ··· 441 453 msgid "works" 442 454 msgstr "projets" 443 455 456 + msgid "Your e-mail address" 457 + msgstr "Votre adresse mail" 458 +
+26
mail.go
··· 1 + package main 2 + 3 + import ( 4 + "fmt" 5 + "os" 6 + 7 + "gopkg.in/mail.v2" 8 + ) 9 + 10 + func SendMailToSelf(from, subject, body string) error { 11 + // fmt.Println("setting auth") 12 + // auth := smtp.PlainAuth("", "hey@ewen.works", os.Getenv("MAIL_PASSWORD"), "mail.ewen.works:465") 13 + // fmt.Printf("sending mail with %#v\n", auth) 14 + // return smtp.SendMail("mail.ewen.works:465", auth, "contact-form@ewen.works", []string{"contact@ewen.works"}, []byte(body)) 15 + fmt.Printf("[%s] %s -> %s\n", subject, body, from) 16 + envelope := mail.NewMessage() 17 + envelope.SetHeader("From", "contact-form@ewen.works") 18 + envelope.SetHeader("To", "contact@ewen.works") 19 + envelope.SetHeader("Reply-To", from) 20 + envelope.SetHeader("Subject", subject) 21 + envelope.SetBody("text/plain", body) 22 + dialer := mail.NewDialer("mail.ewen.works", 465, "hey@ewen.works", os.Getenv("MAIL_PASSWORD")) 23 + dialer.StartTLSPolicy = mail.MandatoryStartTLS 24 + 25 + return dialer.DialAndSend(envelope) 26 + }
+21
main.go
··· 101 101 102 102 handlePage("about", pages.AboutPage(translations.language)) 103 103 104 + handlePage("contact", pages.ContactPage(false)) 105 + handlePage("contact/sent", pages.ContactPage(true)) 106 + 107 + server.HandleFunc("/mail", func(w http.ResponseWriter, r *http.Request) { 108 + if r.Method != http.MethodPost { 109 + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) 110 + } 111 + 112 + subject := strings.TrimSpace(r.FormValue("subject")) 113 + body := strings.TrimSpace(r.FormValue("body")) 114 + from := strings.TrimSpace(r.FormValue("from")) 115 + 116 + err := SendMailToSelf(from, subject, body) 117 + if err != nil { 118 + color.Red("Could not send mail: %s", err) 119 + http.Error(w, "Could not send mail", 500) 120 + } else { 121 + http.Redirect(w, r, "/contact/sent", http.StatusSeeOther) 122 + } 123 + }) 124 + 104 125 go http.ListenAndServe(":"+fmt.Sprint(port), server) 105 126 fmt.Printf("[%s] Server started on http://localhost:%d\n", translations.language, port) 106 127
+73
pages/contact.templ
··· 1 + package pages 2 + 3 + import "github.com/ewen-lbh/portfolio/shared" 4 + import "github.com/ewen-lbh/portfolio/components" 5 + 6 + css contactPage() { 7 + max-width: 600px; 8 + margin: 3rem auto 0; 9 + } 10 + 11 + css contactForm() { 12 + } 13 + 14 + css submitButton() { 15 + display: block; 16 + margin: 1.5rem auto 0; 17 + padding: 1rem 2rem; 18 + color: var(--secondary, white); 19 + background-color: var(--primary, black); 20 + border: 2px solid var(--primary, black); 21 + box-shadow: none; 22 + font-size: 1.2em; 23 + font-family: Manrope; 24 + font-weight: bold; 25 + cursor: pointer; 26 + } 27 + 28 + css formEntry() { 29 + border: 2px solid var(--primary, black); 30 + padding: 0.75rem 1rem; 31 + font-family: Manrope; 32 + font-weight: 400; 33 + font-size: 1.1em; 34 + display: block; 35 + margin-bottom: 1rem; 36 + box-sizing: border-box; 37 + width: 100%; 38 + } 39 + 40 + css formLabel() { 41 + font-size: 1.2em; 42 + } 43 + 44 + css mailSentBanner() { 45 + padding: 1rem 2rem; 46 + background: green; 47 + color: white; 48 + margin-bottom: 2rem; 49 + } 50 + 51 + templ ContactPage(sent bool) { 52 + @components.IntroWith("", "Contact me", true) 53 + <section class={ contactPage() }> 54 + @shared.OnHover(submitButton(), shared.Declarations{ 55 + "background-color": "var(--secondary, white)", 56 + "color": "var(--primary, black)", 57 + }) 58 + <form class={ contactForm() } method="post" action="/mail"> 59 + if sent { 60 + <section class={ mailSentBanner() }> 61 + Mail envoyé! 62 + </section> 63 + } 64 + <label class={ formLabel() } i18n>Your e-mail address</label> 65 + <input class={ formEntry() } required type="email" name="from"/> 66 + <label class={ formLabel() } i18n>Subject</label> 67 + <input class={ formEntry() } required type="text" name="subject"/> 68 + <label class={ formLabel() } i18n>Message </label> 69 + <textarea rows="10" class={ formEntry() } required name="body"></textarea> 70 + <button class={ submitButton() } i18n type="submit">Send</button> 71 + </form> 72 + </section> 73 + }
+3
pages/layout.templ
··· 175 175 </li> 176 176 } 177 177 <li class={ navigationItem() }> 178 + <a class={ navigationLink() } href="/contact" i18n>contact</a> 179 + </li> 180 + <li class={ navigationItem() }> 178 181 <a class={ navigationLink() } href={ pathInOtherLanguage(lang, currentPath) }> 179 182 switch otherLocale(lang) { 180 183 case "fr":