dev #3

Merged
keyemail merged 5 commits from dev into master 2024-07-26 13:04:40 +00:00
59 changed files with 1115 additions and 33 deletions
Showing only changes of commit 2ced1ed9ca - Show all commits

12
.gitignore vendored
View file

@ -1,12 +1,2 @@
# local env files build/
.env.local
.env.*.local
# Editor directories and files
.idea
.vscode .vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

45
README.md Normal file
View file

@ -0,0 +1,45 @@
# keyemail.dev
Welcome to the official repo for the site https://keyemail.dev! This site is to display all about the user `Keyemail`, it displays the About Me, Gallery Photos, Socials, and Videos! This project is done under Go, but was orginally made in Vue.
## Installation
### Automatic (Easy Way)
Make the `build.sh` an executable by:
```console
chmod +x ./build.sh
```
and then run:
```console
./build.sh
```
After that, go into the build folder and run the executable that is in there.
### Manual (Hard Way)
First create the directory:
```console
mkdir build/
```
then, copy src to ./build using:
```console
cp -r src/ ./build
```
then, build using Go:
```console
go build -o ./build
```
Your done! Go into the build folder and run the executable.
## Support
No support is offered on this package, this is a personal project to learn Go.
## Credits
Built by `keyemail`, `kuubeu` helped inspire this project, as well as some svg work.

13
build.sh Executable file
View file

@ -0,0 +1,13 @@
#! /bin/bash
echo "Building.."
echo "Making build folder"
mkdir build/
echo "Copying files into build folder"
cp -r src/ ./build/
echo "Building executable"
go build -o ./build/
echo "Done building!"

2
go.mod
View file

@ -1,3 +1,3 @@
module serve module keyemail-dev-v1.0
go 1.22.3 go 1.22.3

197
main.go
View file

@ -5,31 +5,184 @@ import (
"os" "os"
"log" "log"
"html/template" "html/template"
"strings"
"strconv"
) )
type Index struct { type Index struct {
WebpageTitle string WebpageTitle string
WebpageIcon string
WebpageKeywords string
WebpageDescription string
GalleryItems []GalleryItems
SocialItems []SocialItems
VideoItems []VideoItems
GalleryPhoto *GalleryItems
VideoContent *VideoItems
Nav bool
}
type GalleryItems struct {
URL string
ID int
Title string
}
type SocialItems struct {
URL string
Name string
Username string
Icon string
Color string
}
type VideoItems struct {
URL string
ID int
Title string
Description string
Thumbnail string
}
var data = &Index {
WebpageTitle: "Keyemail",
WebpageIcon: "/src/assets/main/favicon.ico",
WebpageKeywords: "keyemail",
WebpageDescription: "Welcome to keyemail.dev! A profile based on Keyemail.",
GalleryItems: galleryItems,
SocialItems: socialItems,
VideoItems: videoItems,
}
var currentData = &Index{}
var galleryItems = []GalleryItems {
{"/src/assets/gallery/2_cats.jpg", 1, "Resting Day"},
{"/src/assets/gallery/friend_cat.jpg", 2, "Orange Furr"},
{"/src/assets/gallery/miku_poster.jpg", 3, "Miku Spotted"},
{"/src/assets/gallery/networking.jpg", 4, "Wires of Networking"},
{"/src/assets/gallery/another_friend_cat.jpg", 5, "Night Cat"},
{"/src/assets/gallery/pc_case_stickers.jpg", 6, "I use arch BTW"},
{"/src/assets/gallery/movie_picture_1.jpg", 7, "Prime Cut Cafe"},
{"/src/assets/gallery/movie_picture_2.jpg", 8, "Big Fountain"},
{"/src/assets/gallery/bird.jpg", 9, "Birds Eye"},
{"/src/assets/gallery/japanese_garden_1.jpg", 10, "Pond of Fishes"},
{"/src/assets/gallery/japanese_garden_2.jpg", 11, "Waterfall Pond"},
{"/src/assets/gallery/japanese_garden_3.jpg", 12, "Bridge of Faith"},
{"/src/assets/gallery/japanese_garden_4.jpg", 13, "Little Rocks"},
{"/src/assets/gallery/japanese_garden_5.jpg", 14, "Arc over Pond"},
{"/src/assets/gallery/japanese_garden_6.jpg", 15, "Beautiful Pond"},
}
var socialItems = []SocialItems {
{"https://discord.gg/VTEn4zuh", "Discord", "keyemail", "/src/assets/icons/discord.svg", "5865F2"},
{"https://github.com/Keyemail", "GitHub", "Keyemail", "/src/assets/icons/github.svg", "171515"},
{"https://steamcommunity.com/id/keyemail/", "Steam", "Keyemail", "/src/assets/icons/steam.svg", "000000"},
{"https://open.spotify.com/user/316yuurxrw3zcprxsnrvgamxktp4", "Spotify", "Keyemail", "/src/assets/icons/spotify.svg", "1DB954"},
{"https://www.youtube.com/channel/UCCNkKG8XoZCh52vLCbXYy7g", "YouTube", "Keyemail", "/src/assets/icons/youtube.svg", "CD201F"},
{"https://www.instagram.com/keyemail1?igsh=OGQ5ZDc2ODk2ZA%3D%3D&utm_source=qr", "Instagram", "keyemail1", "/src/assets/icons/instagram.svg", "C13584"},
}
var videoItems = []VideoItems {
{"/src/assets/videos/JP-Installing-Windows-Project.mp4", 1, "JP Installing Windows Project", "This is a guide in japanese where I teach you how to install windows completely. This was made because of a JP Project I had to do.", "/src/assets/video_thumbnails/JP-Installing-Windows-Project.png"},
{"/src/assets/videos/orange-cat.mp4", 2, "Orange Cat", "Cute little orange cat that my friend has!! Hes so cute lol.", "/src/assets/video_thumbnails/orange-cat.png"},
}
func renderTemplate(w http.ResponseWriter, tmpl string, data *Index, nav bool) {
var templateFiles[]string
templateFiles = append(templateFiles, "src/pages/" + tmpl + ".tmpl", "src/index.tmpl", "src/components/navbar.tmpl")
templates, err := template.ParseFiles(templateFiles...)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
data.Nav = nav
err = templates.ExecuteTemplate(w, "base", data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
log.Println("GET /" + tmpl)
}
func galleryContentHandler(w http.ResponseWriter, req *http.Request) {
parts := strings.Split(req.URL.Path, "/")
if len(parts) == 3 && parts[1] == "gallery" {
idStr := parts[2]
id, err := strconv.Atoi(idStr)
if err != nil || id < 1 || id > len(galleryItems) {
renderTemplate(w, "404", data, true)
return
}
var item GalleryItems
for _, gi := range galleryItems {
if gi.ID == id {
item = gi
break
}
}
*currentData = *data
currentData.GalleryPhoto = &item
currentData.GalleryItems = nil
renderTemplate(w, "gallery_content", currentData, true)
return
}
renderTemplate(w, "404", data, true)
}
func videoContentHandler(w http.ResponseWriter, req *http.Request) {
parts := strings.Split(req.URL.Path, "/")
if len(parts) == 3 && parts[1] == "videos" {
idStr := parts[2]
id, err := strconv.Atoi(idStr)
if err!= nil || id < 1 || id > len(videoItems) {
renderTemplate(w, "404", data, true)
return
}
var item VideoItems
for _, gi := range videoItems {
if gi.ID == id {
item = gi
break
}
}
*currentData = *data
currentData.VideoContent = &item
currentData.VideoItems = nil
renderTemplate(w, "video_content", currentData, true)
return
}
renderTemplate(w, "404", data, true)
}
func videoHandler(w http.ResponseWriter, req *http.Request) {
renderTemplate(w, "video", data, true);
}
func socialsHandler(w http.ResponseWriter, req *http.Request) {
renderTemplate(w, "socials", data, true);
}
func galleryHandler(w http.ResponseWriter, req *http.Request) {
renderTemplate(w, "gallery", data, true);
} }
func indexHandler(w http.ResponseWriter, req *http.Request) { func indexHandler(w http.ResponseWriter, req *http.Request) {
tmpl, err := template.ParseFiles("src/index.tmpl") renderTemplate(w, "home", data, true);
if err != nil {
http.Error(w, "Error loading template", http.StatusInternalServerError)
log.Println("Error parsing template:", err)
return
}
data := &Index{
WebpageTitle: "Keyemail",
}
err = tmpl.Execute(w, data)
if err != nil {
http.Error(w, "Error loading template", http.StatusInternalServerError)
log.Println("Error executing template:", err)
return
}
} }
func main() { func main() {
@ -37,9 +190,17 @@ func main() {
log.Fatal("Template file does not exist:\n", err) log.Fatal("Template file does not exist:\n", err)
} }
fs := http.FileServer(http.Dir("./src"))
http.Handle("/src/", http.StripPrefix("/src/", fs))
port := ":3939" port := ":3939"
http.HandleFunc("/", indexHandler) http.HandleFunc("/", indexHandler)
http.HandleFunc("/socials", socialsHandler)
http.HandleFunc("/gallery", galleryHandler)
http.HandleFunc("/videos", videoHandler)
http.HandleFunc("/gallery/", galleryContentHandler)
http.HandleFunc("/videos/", videoContentHandler)
log.Println("Server running at http://localhost" + port) log.Println("Server running at http://localhost" + port)
http.ListenAndServe(port, nil) http.ListenAndServe(port, nil)
} }

BIN
serve

Binary file not shown.

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="none" stroke="#06d3d3" stroke-width="64" stroke-linecap="round" stroke-linejoin="round" d="M144 144 32 256 144 368M256 480 384 32M496 144 608 256 496 368"/></svg>

Before

Width:  |  Height:  |  Size: 236 B

After

Width:  |  Height:  |  Size: 236 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path fill="#264de4" d="M34.9 427.8 192 480l157.1-52.2L384 32H0m313.1 80-4.8 47.3-115.6 49.4h111.5l-12.8 146.6-98.2 28.7-98.8-29.2-6.4-73.9h48.9l3.2 38.3 52.6 13.3 54.7-15.4 3.7-61.6h-166.3l-3.6-46.3 118.6-49.4H76.7L70.9 112"/></svg>

Before

Width:  |  Height:  |  Size: 295 B

After

Width:  |  Height:  |  Size: 295 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="#00add8" d="M400.1 194.8C389.2 197.6 380.2 199.1 371 202.4C363.7 204.3 356.3 206.3 347.8 208.5L347.2 208.6C343 209.8 342.6 209.9 338.7 205.4C334 200.1 330.6 196.7 324.1 193.5C304.4 183.9 285.4 186.7 267.7 198.2C246.5 211.9 235.6 232.2 235.9 257.4C236.2 282.4 253.3 302.9 277.1 306.3C299.1 309.1 316.9 301.7 330.9 285.8C333 283.2 334.9 280.5 337 277.5V277.5L337 277.5C337.8 276.5 338.5 275.4 339.3 274.2H279.2C272.7 274.2 271.1 270.2 273.3 264.9C277.3 255.2 284.8 239 289.2 230.9C290.1 229.1 292.3 225.1 296.1 225.1H397.2C401.7 211.7 409 198.2 418.8 185.4C441.5 155.5 468.1 139.9 506 133.4C537.8 127.8 567.7 130.9 594.9 149.3C619.5 166.1 634.7 188.9 638.8 218.8C644.1 260.9 631.9 295.1 602.1 324.4C582.4 345.3 557.2 358.4 528.2 364.3C522.6 365.3 517.1 365.8 511.7 366.3C508.8 366.5 506 366.8 503.2 367.1C474.9 366.5 449 358.4 427.2 339.7C411.9 326.4 401.3 310.1 396.1 291.2C392.4 298.5 388.1 305.6 382.1 312.3C360.5 341.9 331.2 360.3 294.2 365.2C263.6 369.3 235.3 363.4 210.3 344.7C187.3 327.2 174.2 304.2 170.8 275.5C166.7 241.5 176.7 210.1 197.2 184.2C219.4 155.2 248.7 136.8 284.5 130.3C313.8 124.1 341.8 128.4 367.1 145.6C383.6 156.5 395.4 171.4 403.2 189.5C405.1 192.3 403.8 193.9 400.1 194.8zM48.3 200.4C47.1 200.4 46.7 199.8 47.4 198.8L53.9 190.4C54.5 189.5 56.1 188.9 57.3 188.9H168.6C169.8 188.9 170.1 189.8 169.5 190.7L164.2 198.8C163.6 199.8 162 200.7 161.1 200.7L48.3 200.4zM1.2 229.1C0 229.1-.3 228.4 .3 227.5L6.9 219.1C7.5 218.2 9 217.5 10.3 217.5H152.4C153.6 217.5 154.2 218.5 153.9 219.4L151.4 226.9C151.1 228.1 149.9 228.8 148.6 228.8L1.2 229.1zM75.7 255.9C75.1 256.8 75.4 257.7 76.7 257.7L144.6 258C145.5 258 146.8 257.1 146.8 255.9L147.4 248.4C147.4 247.1 146.8 246.2 145.5 246.2H83.2C82 246.2 80.7 247.1 80.1 248.1L75.7 255.9zM577.2 237.9C577 235.3 576.9 233.1 576.5 230.9C570.9 200.1 542.5 182.6 512.9 189.5C483.9 196 465.2 214.4 458.4 243.7C452.8 268 464.6 292.6 487 302.6C504.2 310.1 521.3 309.2 537.8 300.7C562.4 287.1 575.8 268 577.4 241.2C577.3 240 577.3 238.9 577.2 237.9z"/></svg>

After

Width:  |  Height:  |  Size: 2 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path fill="#e34c26" d="M35 428l156.5 52L349 428 384 32H0M308.2 159.9H124.4l4.1 49.4h175.6l-13.6 148.4-99 27.3-98.7-27.3-6-75.8h47.7L138 320l53.5 14.5 53.7-14.5 6-62.2H84.3L71.5 112.2h241.1"/></svg>

Before

Width:  |  Height:  |  Size: 260 B

After

Width:  |  Height:  |  Size: 260 B

1
src/assets/badges/js.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="#f0db4f" d="M0 480H448V32H0M243.8 381.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6s22.6-5.4 22.6-26.5V237.7h42.1m99.6 207.2c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L368 290c-7.2-12.9-15-18-27.1-18s-20.1 7.8-20.1 18c0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6"/></svg>

Before

Width:  |  Height:  |  Size: 602 B

After

Width:  |  Height:  |  Size: 602 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="#3fb27f" d="M0 64H176l48 89 56-89h168L224 448m0-63L392 96H338L224 295 109 96H55"/></svg>

Before

Width:  |  Height:  |  Size: 162 B

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

BIN
src/assets/gallery/bird.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="#ffffff" d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.2 288 416 288c17.7 0 32-14.3 32-32s-14.3-32-32-32l-306.7 0L214.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z"/></svg>

After

Width:  |  Height:  |  Size: 316 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path fill="#ffffff" d="M524.5 69.8a1.5 1.5 0 0 0 -.8-.7A485.1 485.1 0 0 0 404.1 32a1.8 1.8 0 0 0 -1.9 .9 337.5 337.5 0 0 0 -14.9 30.6 447.8 447.8 0 0 0 -134.4 0 309.5 309.5 0 0 0 -15.1-30.6 1.9 1.9 0 0 0 -1.9-.9A483.7 483.7 0 0 0 116.1 69.1a1.7 1.7 0 0 0 -.8 .7C39.1 183.7 18.2 294.7 28.4 404.4a2 2 0 0 0 .8 1.4A487.7 487.7 0 0 0 176 479.9a1.9 1.9 0 0 0 2.1-.7A348.2 348.2 0 0 0 208.1 430.4a1.9 1.9 0 0 0 -1-2.6 321.2 321.2 0 0 1 -45.9-21.9 1.9 1.9 0 0 1 -.2-3.1c3.1-2.3 6.2-4.7 9.1-7.1a1.8 1.8 0 0 1 1.9-.3c96.2 43.9 200.4 43.9 295.5 0a1.8 1.8 0 0 1 1.9 .2c2.9 2.4 6 4.9 9.1 7.2a1.9 1.9 0 0 1 -.2 3.1 301.4 301.4 0 0 1 -45.9 21.8 1.9 1.9 0 0 0 -1 2.6 391.1 391.1 0 0 0 30 48.8 1.9 1.9 0 0 0 2.1 .7A486 486 0 0 0 610.7 405.7a1.9 1.9 0 0 0 .8-1.4C623.7 277.6 590.9 167.5 524.5 69.8zM222.5 337.6c-29 0-52.8-26.6-52.8-59.2S193.1 219.1 222.5 219.1c29.7 0 53.3 26.8 52.8 59.2C275.3 311 251.9 337.6 222.5 337.6zm195.4 0c-29 0-52.8-26.6-52.8-59.2S388.4 219.1 417.9 219.1c29.7 0 53.3 26.8 52.8 59.2C470.7 311 447.5 337.6 417.9 337.6z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path fill="#ffffff" d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3 .3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5 .3-6.2 2.3zm44.2-1.7c-2.9 .7-4.9 2.6-4.6 4.9 .3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3 .7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3 .3 2.9 2.3 3.9 1.6 1 3.6 .7 4.3-.7 .7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3 .7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3 .7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="#ffffff" d="M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"/></svg>

After

Width:  |  Height:  |  Size: 1,018 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path fill="#ffffff" d="M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm100.7 364.9c-4.2 0-6.8-1.3-10.7-3.6-62.4-37.6-135-39.2-206.7-24.5-3.9 1-9 2.6-11.9 2.6-9.7 0-15.8-7.7-15.8-15.8 0-10.3 6.1-15.2 13.6-16.8 81.9-18.1 165.6-16.5 237 26.2 6.1 3.9 9.7 7.4 9.7 16.5s-7.1 15.4-15.2 15.4zm26.9-65.6c-5.2 0-8.7-2.3-12.3-4.2-62.5-37-155.7-51.9-238.6-29.4-4.8 1.3-7.4 2.6-11.9 2.6-10.7 0-19.4-8.7-19.4-19.4s5.2-17.8 15.5-20.7c27.8-7.8 56.2-13.6 97.8-13.6 64.9 0 127.6 16.1 177 45.5 8.1 4.8 11.3 11 11.3 19.7-.1 10.8-8.5 19.5-19.4 19.5zm31-76.2c-5.2 0-8.4-1.3-12.9-3.9-71.2-42.5-198.5-52.7-280.9-29.7-3.6 1-8.1 2.6-12.9 2.6-13.2 0-23.3-10.3-23.3-23.6 0-13.6 8.4-21.3 17.4-23.9 35.2-10.3 74.6-15.2 117.5-15.2 73 0 149.5 15.2 205.4 47.8 7.8 4.5 12.9 10.7 12.9 22.6 0 13.6-11 23.3-23.2 23.3z"/></svg>

After

Width:  |  Height:  |  Size: 885 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path fill="#ffffff" d="M496 256c0 137-111.2 248-248.4 248-113.8 0-209.6-76.3-239-180.4l95.2 39.3c6.4 32.1 34.9 56.4 68.9 56.4 39.2 0 71.9-32.4 70.2-73.5l84.5-60.2c52.1 1.3 95.8-40.9 95.8-93.5 0-51.6-42-93.5-93.7-93.5s-93.7 42-93.7 93.5v1.2L176.6 279c-15.5-.9-30.7 3.4-43.5 12.1L0 236.1C10.2 108.4 117.1 8 247.6 8 384.8 8 496 119 496 256zM155.7 384.3l-30.5-12.6a52.8 52.8 0 0 0 27.2 25.8c26.9 11.2 57.8-1.6 69-28.4 5.4-13 5.5-27.3 .1-40.3-5.4-13-15.5-23.2-28.5-28.6-12.9-5.4-26.7-5.2-38.9-.6l31.5 13c19.8 8.2 29.2 30.9 20.9 50.7-8.3 19.9-31 29.2-50.8 21zm173.8-129.9c-34.4 0-62.4-28-62.4-62.3s28-62.3 62.4-62.3 62.4 28 62.4 62.3-27.9 62.3-62.4 62.3zm.1-15.6c25.9 0 46.9-21 46.9-46.8 0-25.9-21-46.8-46.9-46.8s-46.9 21-46.9 46.8c.1 25.8 21.1 46.8 46.9 46.8z"/></svg>

After

Width:  |  Height:  |  Size: 827 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="#ffffff" d="M549.7 124.1c-6.3-23.7-24.8-42.3-48.3-48.6C458.8 64 288 64 288 64S117.2 64 74.6 75.5c-23.5 6.3-42 24.9-48.3 48.6-11.4 42.9-11.4 132.3-11.4 132.3s0 89.4 11.4 132.3c6.3 23.7 24.8 41.5 48.3 47.8C117.2 448 288 448 288 448s170.8 0 213.4-11.5c23.5-6.3 42-24.2 48.3-47.8 11.4-42.9 11.4-132.3 11.4-132.3s0-89.4-11.4-132.3zm-317.5 213.5V175.2l142.7 81.2-142.7 81.2z"/></svg>

After

Width:  |  Height:  |  Size: 452 B

BIN
src/assets/main/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 KiB

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,22 @@
{{ define "navbar" }}
<nav>
<h1>Keyemail</h1>
<ul>
<li>
<a href="/">Home</a>
</li>
<li>
<a href="/gallery">Gallery</a>
</li>
<li>
<a href="/socials">Socials</a>
</li>
<li>
<a href="/videos">Videos</a>
</li>
<li>
<a href="https://git.keyemail.dev/explore/">Git</a>
</li>
</ul>
</nav>
{{ end }}

View file

@ -1,9 +1,25 @@
<!doctype html> {{ define "base" }}
<html> <!DOCTYPE html>
<html lang="en">
<head> <head>
{{ template "head" . }} {{ template "head" . }}
<title></title> <meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta property="og:title" content="{{ .WebpageTitle }}"/>
<meta property="og:type" content="website">
<meta property="og:url" content="https://keyemail.dev">
<meta property="keywords" content="{{ .WebpageKeywords }}"/>
<meta name="theme-color" content="#192236">
<title>{{ .WebpageTitle }}</title>
<link rel="icon" type="image/x-icon" href="{{ .WebpageIcon }}">
<link rel="stylesheet" href="/src/styles/main.css">
<script src="https://kit.fontawesome.com/d18ce6e9fb.js" crossorigin="anonymous"></script>
</head> </head>
<body> <body>
{{ if .Nav }}
{{ template "navbar" . }}
{{ end }}
{{ template "body" . }}
</body> </body>
</html> </html>
{{ end }}

15
src/pages/404.tmpl Normal file
View file

@ -0,0 +1,15 @@
<head>
{{ define "head" }}
<link rel="stylesheet" href="/src/styles/404.css">
<meta property="description" content="{{ .WebpageDescription }}"/>
<meta property="og:description" content="{{ .WebpageDescription }}">
{{ end }}
</head>
<body>
{{ define "body" }}
<div id="notFound">
<h1>404 Page</h1>
<p>This page has not been found, <a href="/">click here</a> to return back home.</p>
</div>
{{ end }}
</body>

24
src/pages/gallery.tmpl Normal file
View file

@ -0,0 +1,24 @@
<head>
{{ define "head" }}
<link rel="stylesheet" href="/src/styles/gallery.css">
<meta property="description" content="{{ .WebpageDescription }}"/>
<meta property="og:description" content="{{ .WebpageDescription }}">
{{ end }}
</head>
<body>
{{ define "body" }}
<div class="galleryBGAlt">
<h1>My Gallery!</h1>
<ul id="galleryGrid">
{{ range .GalleryItems }}
<a href="/gallery/{{ .ID }}">
<li>
<img src="{{ .URL }}" alt="{{ .Title }}"/>
<h2>{{ .Title }}</h2>
</li>
</a>
{{ end }}
</li>
</div>
{{ end }}
</body>

View file

@ -0,0 +1,22 @@
<head>
{{ define "head" }}
<link rel="stylesheet" href="/src/styles/gallery.css">
<meta property="og:image" content="https://keyemail.dev/{{ .GalleryPhoto.URL }}"/>
<meta name="twitter:card" content="summary_large_image"/>
{{ end }}
</head>
<body>
{{ define "body" }}
<div id="galleryContent" class="galleryBGAlt">
<div>
<a href="/gallery">
<img src="/src/assets/icons/arrow-left.svg"/>
</a>
<h1>{{ .GalleryPhoto.Title }}</h1>
</div>
<a href="{{ .GalleryPhoto.URL }}" target="_blank" id="galleryPhoto">
<img src="{{ .GalleryPhoto.URL }}" alt="{{ .GalleryPhoto.Title }}"/>
</a>
</div>
{{ end }}
</body>

View file

@ -0,0 +1,56 @@
<head>
{{ define "head" }}
<link rel="stylesheet" href="/src/styles/home.css"/>
<meta property="description" content="{{ .WebpageDescription }}"/>
<meta property="og:description" content="{{ .WebpageDescription }}">
{{ end }}
</head>
<body>
{{ define "body" }}
<header>
<a class="pfp" href="https://www.pixiv.net/en/artworks/118037520">
<img src="/src/assets/profile/profile.jpg"/>
</a>
<div id="name">
<h1>Keyemail</h1>
<ul>
<li>
<img src="/src/assets/badges/code.svg" aria-label="CODE"/>
<div>Active Developer</div>
</li>
<li>
<img src="/src/assets/badges/html.svg" aria-label="HTML5"/>
<div>HTML</div>
</li>
<li>
<img src="/src/assets/badges/css.svg" aria-label="CSS3"/>
<div>CSS</div>
</li>
<li>
<img src="/src/assets/badges/js.svg" aria-label="JS"/>
<div>Javascript</div>
</li>
<li>
<img src="/src/assets/badges/vue.svg" aria-label="VUE3"/>
<div>Vue 3</div>
</li>
<li>
<img src="/src/assets/badges/golang.svg" aria-label="GOLANG"/>
<div>Go</div>
</li>
</ul>
</div>
</header>
<div id="intro">
<h1>Hi, I'm Keyemail or Patrick.</h1>
<p>I specialize in IT and web development-related stuff, but I also love doing a variety of different hobbies such as Flight Simulator, or learning Japanese. I daily run an Arch Linux machine as my main system and support Linux in every way. I'm glad to meet you! </p>
</div>
<i class="fa-solid fa-arrow-down" id="moreArrow" onclick="quack()">
<div>Nothing...</div>
</i>
<script src="/src/scripts/home.js"></script>
{{ end }}
</body>

25
src/pages/socials.tmpl Normal file
View file

@ -0,0 +1,25 @@
<head>
{{ define "head" }}
<link rel="stylesheet" href="/src/styles/socials.css">
<meta property="description" content="{{ .WebpageDescription }}"/>
<meta property="og:description" content="{{ .WebpageDescription }}">
{{ end }}
</head>
<body>
{{ define "body" }}
<div id="socialBGAlt">
<h1>My Socials!</h1>
<ul id="socialsGrid">
{{ range .SocialItems }}
<a href="{{ .URL }}">
<li style="background-color: #{{ .Color }}">
<h2>{{ .Name }}</h2>
<p>{{ .Username }}</p>
<img src="{{ .Icon }}">
</li>
</a>
{{ end }}
</ul>
</div>
{{ end }}
</body>

26
src/pages/video.tmpl Normal file
View file

@ -0,0 +1,26 @@
<head>
{{ define "head" }}
<link rel="stylesheet" href="/src/styles/video.css"/>
<meta property="description" content="{{ .WebpageDescription }}"/>
<meta property="og:description" content="{{ .WebpageDescription }}">
{{ end }}
</head>
<body>
{{ define "body" }}
<div id="videosBGAlt">
<h1>My Videos</h1>
<ul id="videoGrid">
{{ range .VideoItems }}
<a href="/videos/{{ .ID }}">
<li>
<img src="{{ .Thumbnail }}" alt="{{ .Title }}"/>
<div id="content">
<h2>{{ .Title }}</h2>
</div>
</li>
</a>
{{ end }}
</ul>
</div>
{{ end }}
</body>

View file

@ -0,0 +1,20 @@
<head>
{{ define "head" }}
<link rel="stylesheet" href="/src/styles/video.css"/>
<link property=og:image" content="https://keyemail.dev/{{ .VideoContent.URL }}"/>
<meta name="twitter:card" content="summary_large_image"/>
{{ end }}
</head>
<body>
{{ define "body" }}
<div id="contentBGAlt">
<video controls>
<source src="{{ .VideoContent.URL }}" type="video/mp4">
</video>
<div id="info">
<h1>{{ .VideoContent.Title }}</h1>
<p>{{ .VideoContent.Description }}</p>
</div>
</div>
{{ end }}
</body>

0
src/scripts/gallery.js Normal file
View file

6
src/scripts/home.js Normal file
View file

@ -0,0 +1,6 @@
function quack() {
const moreArrow = document.getElementById('moreArrow')
moreArrow.innerHTML = '🦆';
moreArrow.classList.remove('fa-arrow-down');
}

0
src/scripts/main.js Normal file
View file

0
src/scripts/video.js Normal file
View file

26
src/styles/404.css Normal file
View file

@ -0,0 +1,26 @@
#notFound {
background-color: var(--bg-alt-color);
display: flex;
flex-direction: column;
color: white;
font-family: 'Rubik', sans-serif;
align-items: center;
margin-top: 20px;
text-align: center;
padding: 40px;
border-radius: 20px;
h1 {
font-size: 70px;
}
p {
font-size: 30px;
}
a {
color: #ADD8E6;
transition: 0.3s color;
}
a:hover {
color: #74d2f1;
}
}

82
src/styles/gallery.css Normal file
View file

@ -0,0 +1,82 @@
.galleryBGAlt {
margin-top: 20px;
background-color: var(--bg-alt-color);
color: white;
font-family: 'Rubik', sans-serif;
padding: 20px;
border-radius: 20px;
h1 {
font-weight: 500;
font-size: 3.5rem;
text-align: center;
}
}
#galleryGrid {
display: grid;
list-style: none;
grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
gap: 40px;
margin-top: 30px;
width: 100%;
img {
width: 100%;
height: 550px;
border-radius: 15px;
object-fit: cover;
object-position: center;
cursor: pointer;
transition: 0.4s filter;
}
img:hover {
filter: brightness(70%);
}
}
#galleryContent {
display: flex;
align-items: center;
flex-direction: column;
div {
width: 100%;
display: inherit;
flex-direction: row;
align-items: inherit;
justify-content: space-between;
h1 {
font-size: 3rem;
width: 100%;
text-align: center;
margin-right: 30px;
}
img {
height: 30px;
width: 30px;
user-select: none;
pointer-events: none;
}
}
}
#galleryPhoto {
margin-top: 20px;
img{
max-height: calc(100vh - 199px);
width: auto;
max-width: 100%;
border-radius: 15px;
user-select: none;
pointer-events: none;
}
}
@media screen and (max-width: 480px) {
#galleryGrid {
grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
}
}

181
src/styles/home.css Normal file
View file

@ -0,0 +1,181 @@
header {
display: flex;
align-items: center;
margin-top: 20px;
background: repeating-linear-gradient(
-45deg,
#200080,
#200080 20px,
#090069 20px,
#090069 40px
);
height: 180px;
width: 100%;
border-radius: 10px;
font-family: 'Rubik', sans-serif;
h1 {
color: white;
font-size: 3rem;
}
}
.pfp {
height: 130px !important;
width: 130px !important;
border: solid;
border-width: 4px;
border-radius: 50%;
border-color: white;
overflow: hidden;
margin-left: 20px;
user-select: none;
img {
width:100%;
height:100%;
object-fit: cover;
background-color: #afb5c8;
}
}
#name {
margin-left: 20px;
div {
display: none;
top: calc(100% + 5px);
left: 50%;
pointer-events: none;
position: absolute;
translate: -50%;
z-index: 1;
white-space: nowrap;
padding: 5px;
height: 20px;
background-color: #151d2f;
color: white;
font-family: 'Rubik', sans-serif;
box-sizing: content-box;
border-radius: 5px;
}
img {
pointer-events: none;
width: 100%;
height: 100%;
}
ul {
display: flex;
flex-direction: row;
width: fit-content;
gap: 5px;
user-select: none;
}
li {
position: relative;
display: inherit;
text-decoration: none;
background-color: var(--bg-alt-color);
height: 30px;
width: 30px;
padding: 3px;
border-radius: 5px;
cursor: pointer;
}
li:hover div {
display: block;
}
}
#intro {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 40px;
width: 100%;
color: white;
font-family: 'Rubik', sans-serif;
background-color: var(--bg-alt-color);
border-radius: 10px;
padding: 20px;
text-align: center;
box-sizing: border-box;
h1 {
font-size: 3.5rem;
font-weight: 500;
}
p {
margin-top: 15px;
font-size: 1.8rem;
font-weight: 400;
max-width: 800px;
}
}
#moreArrow {
position: relative;
cursor: pointer;
font-size: 40px;
color: white;
margin: 40px auto;
margin-top: 80px;
div {
display: none;
align-items: center;
top: calc(100% + 5px);
left: 50%;
pointer-events: none;
position: absolute;
translate: -50%;
z-index: 1;
white-space: nowrap;
padding: 5px;
height: 20px;
background-color: #151d2f;
color: white;
font-family: 'Rubik', sans-serif;
font-size: 1rem;
font-weight: 200;
box-sizing: content-box;
border-radius: 5px;
}
}
#moreArrow:hover div {
display: flex;
}
@media screen and (max-width: 450px){
header {
flex-direction: column;
height: 240px;
justify-content: center;
}
#name {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-left: 0;
}
header h1 {
margin-left: 0px;
}
#intro h1 {
font-size: 3rem;
}
#intro p {
font-size: 1.8rem;
}
.pfp{
margin-left: 0px;
}
}

141
src/styles/main.css Normal file
View file

@ -0,0 +1,141 @@
@import url('https://fonts.googleapis.com/css2?family=Rubik:wght@400;500&display=swap');
:root {
--bg-color: #192236;
--bg-alt-color: #151d2f;
--bg-alt-hover-color: #111726;
--fg-color: #fff;
--padding: 20px;
}
body {
background-color: var(--bg-color)
}
html, body {
scroll-behavior: smooth;
}
body {
display: flex;
flex-direction: column;
max-width: 1920px;
margin: auto;
padding: var(--padding);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
a {
color: inherit;
text-decoration: none;
}
nav {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
color: white;
font-family: 'Rubik', sans-serif;
font-weight: 500;
h1 {
width: fit-content;
z-index: 10;
}
ul {
list-style: none;
float: right;
}
ul li{
display: inline;
cursor: pointer;
margin-left: 10px;
font-weight: 400;
transition: color 0.3s;
}
ul a {
text-decoration: none;
color: inherit;
}
ul li:hover{
color: #8ee8fc;
}
i {
float: right;
font-size: 35px;
cursor: pointer;
transition: 0.3s color;
z-index: 10;
}
i:hover {
color: #74d2f1;
}
}
#mobileNav {
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.9);
left: 0;
top: 0;
z-index: 9;
i {
float: right;
font-size: 35px;
cursor: pointer;
transition: 0.3s color;
}
div {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
div li {
cursor: pointer;
margin-left: 10px;
font-weight: 400;
transition: color 0.3s;
font-size: 40px;
text-align: center;
font-family: 'Rubik', sans-serif;
margin: 10px;
}
div a {
color: white;
text-decoration: none;
transition: 0.3s color;
}
div a:hover {
color: #74d2f1;
}
}
@media screen and (max-width: 390px) {
nav {
justify-content: center;
h1 {
display: none;
}
}
}

83
src/styles/socials.css Normal file
View file

@ -0,0 +1,83 @@
#socialBGAlt {
background-color: var(--bg-alt-color);
display: flex;
align-items: center;
margin-top: 20px;
flex-direction: column;
color: white;
font-family: 'Rubik', sans-serif;
padding: 20px;
border-radius: 20px;
h1 {
margin-bottom: 20px;
font-size: 50px;
}
}
#socialsGrid {
display: grid;
grid-template-columns: auto auto auto;
align-content: start;
grid-gap: 10px;
li {
margin: 5px;
width: 275px;
height: 170px;
border-radius: 20px;
padding: 10px;
display: flex;
justify-content: space-between;
flex-direction: column;
border-color: white;
box-sizing: border-box;
border: 4px solid transparent;
transition: 0.4s border;
}
li:hover {
cursor: pointer;
border: 4px;
border-style: solid;
}
h2 {
font-size: 30px;
}
img {
width: 35px;
height: 35px;
margin-top: auto;
align-self: flex-end;
}
}
@media only screen and (max-width: 905px){
#socialsGrid{
grid-template-columns: auto auto;
}
}
@media only screen and (max-width: 615px){
#socialsGrid{
grid-template-columns: auto;
width: 80%;
li {
width: 100%;
margin-left: 0px;
}
}
#socials {
margin-top: 80px;
justify-content: unset;
}
}
@media only screen and (max-height: 720px){
#socials {
display: flex;
justify-content: unset;
margin-top: 80px;
}
}

115
src/styles/video.css Normal file
View file

@ -0,0 +1,115 @@
#videosBGAlt {
margin-top: 20px;
background-color: var(--bg-alt-color);
color: white;
font-family: 'Rubik', sans-serif;
padding: 20px;
border-radius: 20px;
h1 {
font-weight: 500;
font-size: 3.5rem;
text-align: center;
}
}
#videoGrid {
display: grid;
list-style: none;
grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
gap: 40px;
margin-top: 30px;
width: 100%;
li {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
padding: 10px;
border-radius: 10px;
width: 350px;
cursor: pointer;
transition: 0.3s background-color;
h2 {
color: white;
font-family: 'Rubik', sans-serif;
font-weight: 500;
font-size: 1.5rem;
text-align: center;
}
}
li:hover {
background-color: var(--bg-alt-hover-color);
}
img {
max-width: 100%;
aspect-ratio: 16 / 9;
pointer-events: none;
user-select: none;
}
}
#contentBGAlt {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
margin-top: 20px;
background-color: var(--bg-alt-color);
color: white;
font-family: 'Rubik', sans-serif;
padding: 20px;
border-radius: 20px;
video {
max-height: calc(100vh - 330px);
max-width: calc(100vw - 40px);
width: max-content;
aspect-ratio: 16 / 9;
margin-top: 20px;
border-radius: 20px;
background-color: black;
}
}
#info {
display: flex;
flex-direction: column;
gap: 10px;
margin-top: 30px;
border-radius: 10px;
background-color: var(--bg-alt-color);
max-width: 1052px;
h1 {
color: white;
font-family: 'Rubik', sans-serif;
font-weight: 500;
font-size: 2rem;
}
p {
font-family: 'Rubik', sans-serif;
font-weight: 200;
font-size: 1.3rem;
color: white;
}
}
@media only screen and (max-width: 779px) {
#videoGrid{
display: flex;
flex-direction: column;
li {
width: 100%;
}
a {
max-width: 100%;
}
}
}