Compare commits

..

No commits in common. "bbe48faab002881ab8cdfa2dde32141dac7eff96" and "9f0acf97649a2a43ed6f1d06b0106410389420fc" have entirely different histories.

69 changed files with 18976 additions and 1109 deletions

4
.browserslistrc Normal file
View file

@ -0,0 +1,4 @@
> 1%
last 2 versions
not dead
not ie 11

17
.eslintrc.js Normal file
View file

@ -0,0 +1,17 @@
module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/vue3-essential',
'eslint:recommended'
],
parserOptions: {
parser: '@babel/eslint-parser'
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
}
}

23
.gitignore vendored
View file

@ -1,2 +1,23 @@
build/
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View file

@ -1,45 +1,12 @@
# keyemail.dev
# keyemail-dev by Keyemail
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.
keyemail-dev is a project site to display about the user Keyemail using Vue v3.0 framework. This project was made by the user `Keyemail` and absolutely no one else.
## Installation
## To Build:
Use this command to build:
`yarn build`
### Automatic (Easy Way)
and use the folder `dist` for production.
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.
## Contact:
Contact `Keyemail` if you have any questions or concerns. ABSOLUTELY NO WARRANTY ON THIS PRODUCT.

5
babel.config.js Normal file
View file

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

View file

@ -1,13 +0,0 @@
#! /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!"

3
go.mod
View file

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

19
jsconfig.json Normal file
View file

@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}

219
main.go
View file

@ -1,219 +0,0 @@
package main
import (
"net/http"
"os"
"log"
"html/template"
"strings"
"strconv"
)
type Index struct {
WebpageTitle string
WebpageIcon string
WebpageKeywords string
WebpageDescription string
WebpageURL string
GalleryItems []GalleryItems
SocialItems []SocialItems
VideoItems []VideoItems
GalleryPhoto *GalleryItems
VideoContent *VideoItems
Nav bool
}
type responseWriter struct {
http.ResponseWriter
status int
}
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.",
WebpageURL: "https://keyemail.dev",
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) {
if req.URL.Path != "/" {
renderTemplate(w, "404", data, true)
return
}
renderTemplate(w, "home", data, true)
}
func main() {
if _, err := os.Stat("src/index.tmpl"); os.IsNotExist(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"
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)
http.ListenAndServe(port, nil)
}

11515
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

25
package.json Normal file
View file

@ -0,0 +1,25 @@
{
"name": "keyemail-dev",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.8.3",
"vue": "^3.2.13",
"vue-router": "^4.0.3"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-plugin-router": "~5.0.0",
"@vue/cli-service": "^5.0.8",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3"
}
}

BIN
public/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

17
public/index.html Normal file
View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.png">
<title><%= htmlWebpackPlugin.options.title %></title>
<script src="https://kit.fontawesome.com/d18ce6e9fb.js" crossorigin="anonymous"></script>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
</body>
</html>

48
src/App.vue Normal file
View file

@ -0,0 +1,48 @@
<template>
<navbar></navbar>
<RouterView></RouterView>
</template>
<script>
import navbar from './components/NavBar.vue'
export default {
components: {
navbar,
},
}
</script>
<style>
@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, #app {
scroll-behavior: smooth;
}
#app {
display: flex;
flex-direction: column;
max-width: 1920px;
margin: auto;
padding: var(--padding);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>

View file

@ -1 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 432 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 457 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 480 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 484 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 KiB

View file

@ -1 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 316 B

View file

@ -1 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -1 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -1 +0,0 @@
<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>

Before

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

View file

@ -1 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 885 B

View file

@ -1 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 827 B

View file

@ -1 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

BIN
src/assets/no-picture.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 431 KiB

Binary file not shown.

184
src/components/NavBar.vue Normal file
View file

@ -0,0 +1,184 @@
<template>
<nav>
<h1>Keyemail</h1>
<ul v-if="!(isMobile() || smallScreen)">
<li>
<router-link to="/">Home</router-link>
</li>
<li>
<router-link to="/gallery">Gallery</router-link>
</li>
<li>
<router-link to="/socials">Socials</router-link>
</li>
<li>
<router-link to="/videos">Videos</router-link>
</li>
<li>
<a href="https://git.keyemail.dev/explore/">Git</a>
</li>
</ul>
<i class="fa-solid fa-x" @click="mobileUI(); handleResize();" v-else-if="turnOnMobileUI"></i>
<i class="fas fa-bars" @click="mobileUI();" v-else></i>
</nav>
<div id="mobileNav" v-if="turnOnMobileUI">
<div>
<ul>
<li>
<router-link to="/" @click="mobileUI()">Home</router-link>
</li>
<li>
<router-link to="/gallery" @click="mobileUI()">Gallery</router-link>
</li>
<li>
<router-link to="/socials" @click="mobileUI()">Socials</router-link>
</li>
<li>
<router-link to="/videos" @click="mobileUI()">Videos</router-link>
</li>
<li>
<a href="https://git.keyemail.dev/explore/">Git</a>
</li>
</ul>
</div>
</div>
<template v-else/>
</template>
<script>
export default {
data(){
return {
turnOnMobileUI: false,
smallScreen: false
}
},
mounted() {
window.addEventListener('resize', this.handleResize);
this.handleResize();
},
methods: {
mobileUI() {
if(this.turnOnMobileUI == false) {
this.turnOnMobileUI = true;
document.body.style.overflow = 'hidden';
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
} else {
this.turnOnMobileUI = false;
document.body.style.overflow = 'auto';
}
},
isMobile(){
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
},
handleResize() {
if(window.innerWidth < 450) {
this.smallScreen = true;
} else if(this.turnOnMobileUI === true) {
return;
} else {
this.smallScreen = false;
}
}
}
}
</script>
<style scoped>
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;
}
}
</style>

View file

@ -1,22 +0,0 @@
{{ 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 }}

42
src/data/gallery.js Normal file
View file

@ -0,0 +1,42 @@
export default [
{
name: "2 cats",
id: "1",
path: "gallery/2_cats.jpg"
},
{
name: "Friends Cat",
id: "2",
path: "gallery/friend_cat.jpg"
},
{
name: "Miku Poster",
id: "3",
path: "gallery/miku_poster.jpg"
},
{
name: "Networking",
id: "4",
path: "gallery/networking.jpg"
},
{
name: "Another Friends Cat",
id: "5",
path: "gallery/another_friend_cat.jpg"
},
{
name: "PC Stickers",
id: "6",
path: "gallery/pc_case_stickers.jpg"
},
{
name: "Movie Theater Picture 1",
id: "7",
path: "gallery/movie_picture_1.jpg"
},
{
name: "Movie Theater Picture 2",
id: "8",
path: "gallery/movie_picture_2.jpg"
}
]

9
src/data/videos.js Normal file
View file

@ -0,0 +1,9 @@
export default [
{
"videoName": "JP Installing Windows Project",
"videoDescription": "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.",
"videoID": "1",
"path": "videos/JP-Installing-Windows-Project.mp4",
"thumbnail": "video_thumbnails/JP-Installing-Windows-Project.png"
}
]

View file

@ -1,25 +0,0 @@
{{ define "base" }}
<!DOCTYPE html>
<html lang="en">
<head>
{{ template "head" . }}
<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>
<body>
{{ if .Nav }}
{{ template "navbar" . }}
{{ end }}
{{ template "body" . }}
</body>
</html>
{{ end }}

5
src/main.js Normal file
View file

@ -0,0 +1,5 @@
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
createApp(App).use(router).mount('#app')

View file

@ -1,15 +0,0 @@
<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>

View file

@ -1,24 +0,0 @@
<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

@ -1,22 +0,0 @@
<head>
{{ define "head" }}
<link rel="stylesheet" href="/src/styles/gallery.css">
<meta property="og:image" content="{{ .WebpageURL }}{{ .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

@ -1,56 +0,0 @@
<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>

View file

@ -1,25 +0,0 @@
<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>

View file

@ -1,26 +0,0 @@
<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

@ -1,20 +0,0 @@
<head>
{{ define "head" }}
<link rel="stylesheet" href="/src/styles/video.css"/>
<meta property="og:image" content="{{ .WebpageURL }}{{ .VideoContent.Thumbnail }}"/>
<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>

48
src/router/index.js Normal file
View file

@ -0,0 +1,48 @@
import { createRouter, createWebHistory } from 'vue-router'
import homeView from '../views/HomePage.vue'
import galleryView from '../views/GalleryPage.vue'
import socialView from '../views/SocialsPage.vue'
import notFoundPage from '../views/404Page.vue'
import videoView from '../views/VideoPage.vue'
import videosView from '../views/VideosPage.vue'
const routes = [
{
path: '/',
name: 'home',
component: homeView
},
{
path: '/gallery',
name: 'gallery',
component: galleryView
},
{
path: '/socials',
name: 'socials',
component: socialView
},
{
path: '/:pathMatch(.*)',
name: '404',
component: notFoundPage
},
{
path: '/videos',
name: 'video',
component: videoView
},
{
path: '/videos/:id',
name: 'videos',
component: videosView
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router

View file

View file

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

View file

View file

View file

@ -1,26 +0,0 @@
#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;
}
}

View file

@ -1,82 +0,0 @@
.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));
}
}

View file

@ -1,181 +0,0 @@
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;
}
}

View file

@ -1,95 +0,0 @@
@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;
}
}
@media screen and (max-width: 430px) {
nav {
justify-content: center;
h1 {
display: none;
}
}
}

View file

@ -1,83 +0,0 @@
#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;
}
}

View file

@ -1,116 +0,0 @@
#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;
justify-items: center;
li {
display: flex;
align-items: center;
flex-direction: column;
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%;
}
}
}

38
src/views/404Page.vue Normal file
View file

@ -0,0 +1,38 @@
<template>
<div class="notFound">
<h1>404 Page</h1>
<p>This page has not been found, <router-link to="/">click here</router-link> to return back home.</p>
</div>
</template>
<style>
.notFound {
display: flex;
flex-direction: column;
color: white;
font-family: 'Rubik', sans-serif;
align-items: center;
margin-top: 100px;
height: 100%;
text-align: center;
}
.notFound h1 {
font-size: 70px;
padding: 20px;
}
.notFound p {
font-size: 30px;
}
.notFound a {
text-decoration: none;
color: #ADD8E6;
transition: 0.3s color;
}
.notFound a:hover {
color: #74d2f1;
}
</style>

76
src/views/GalleryPage.vue Normal file
View file

@ -0,0 +1,76 @@
<template>
<div class="gallery">
<h1>Gallery</h1>
<div class="galleryGrid">
<a v-for="gallery in gallerys" :key="gallery.id" :href="require('@/assets/' + gallery.path)" target="_blank">
<img :src="require('@/assets/' + gallery.path)" :title="gallery.name"/>
</a>
</div>
</div>
</template>
<script>
import galleryData from '../data/gallery.js'
export default {
data(){
return {
gallerys: galleryData
}
}
}
</script>
<style scoped>
.gallery {
color: white;
font-family: 'Rubik', sans-serif;
margin-top: 60px;
}
.gallery h1 {
font-weight: 500;
font-size: 3rem;
}
.galleryGrid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
row-gap: 32px;
margin-top: 10px;
}
.galleryGrid a {
width: max-content;
}
.galleryGrid img {
width: 320px;
height: 480px;
border-radius: 16px;
object-fit: cover;
object-position: center;
cursor: pointer;
border: 4px solid transparent;
transition: 0.4s border;
}
.galleryGrid img:hover{
border: 4px;
border-style: solid;
border-color: white;
}
@media only screen and (max-width: 739px) {
.gallery {
margin: auto;
margin-top: 50px;
display: flex;
flex-direction: column;
align-items: center;
}
.galleryGrid {
width: 330px;
}
}
</style>

223
src/views/HomePage.vue Normal file
View file

@ -0,0 +1,223 @@
<template>
<header>
<a class="pfp" href="https://www.pixiv.net/en/artworks/118037520">
<img src="@/assets/profile.jpg"/>
</a>
<div id="name">
<h1>Keyemail</h1>
<ul>
<li @mouseover="showActiveBadge = true" @mouseleave="showActiveBadge = false">
<img src="@/assets/badges/code.svg" aria-label="CODE"/>
<div v-if="showActiveBadge">Active Developer</div>
<template v-else/>
</li>
<li @mouseover="showHTMLBadge = true" @mouseleave="showHTMLBadge = false">
<img src="@/assets/badges/html.svg" aria-label="HTML5"/>
<div v-if="showHTMLBadge">HTML</div>
<template v-else/>
</li>
<li @mouseover="showCSSBadge = true" @mouseleave="showCSSBadge = false">
<img src="@/assets/badges/css.svg" aria-label="CSS3"/>
<div v-if="showCSSBadge">CSS</div>
<template v-else/>
</li>
<li @mouseover="showJavascriptBadge = true" @mouseleave="showJavascriptBadge = false">
<img src="@/assets/badges/js.svg" aria-label="JS"/>
<div v-if="showJavascriptBadge">Javascript</div>
<template v-else/>
</li>
<li @mouseover="showVue3Badge = true" @mouseleave="showVue3Badge = false">
<img src="@/assets/badges/vue.svg" aria-label="VUE3"/>
<div v-if="showVue3Badge">Vue 3</div>
<template v-else/>
</li>
</ul>
</div>
</header>
<div class="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 morearrow" @click="downArrow()" title="Nothing.."></i>
</template>
<script>
export default {
data () {
return {
showActiveBadge: false,
showHTMLBadge: false,
showCSSBadge: false,
showJavascriptBadge: false,
showVue3Badge: false
}
},
methods: {
downArrow(){
if(counter >= 4){
var quack = new Audio(require('@/assets/sounds/duck-quack.mp3'));
quack.play();
alert('You just got quacked!');
counter = 0;
} else {
alert('Nothing to scroll down to, may come useful later though..');
counter++;
}
}
}
}
var counter = 0;
</script>
<style scoped>
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 {
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;
}
}
.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 {
cursor: pointer;
font-size: 40px;
color: white;
margin: 40px auto;
margin-top: 80px;
}
@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;
}
}
</style>

159
src/views/SocialsPage.vue Normal file
View file

@ -0,0 +1,159 @@
<template>
<div class="socials">
<h1>My Socials!</h1>
<div class="socialsgrid">
<div class="discord">
<h2>Discord</h2>
<p>keyemail</p>
<i class="fa-brands fa-discord"></i>
</div>
<a href="https://github.com/Keyemail" target="_blank">
<div class="github">
<h2>GitHub</h2>
<p>Keyemail</p>
<i class="fa-brands fa-github"></i>
</div>
</a>
<a href="https://steamcommunity.com/id/keyemail/" target="_blank">
<div class="steam">
<h2>Steam</h2>
<p>Keyemail</p>
<i class="fa-brands fa-steam"></i>
</div>
</a>
<a href="https://open.spotify.com/user/316yuurxrw3zcprxsnrvgamxktp4" target="_blank">
<div class="spotify">
<h2>Spotify</h2>
<p>Keyemail</p>
<i class="fa-brands fa-spotify"></i>
</div>
</a>
<a href="https://www.youtube.com/channel/UCCNkKG8XoZCh52vLCbXYy7g" target="_blank">
<div class="youtube">
<h2>YouTube</h2>
<p>Keyemail</p>
<i class="fa-brands fa-youtube"></i>
</div>
</a>
<a href="https://www.instagram.com/keyemail1?igsh=OGQ5ZDc2ODk2ZA%3D%3D&utm_source=qr" target="_blank">
<div class="instagram">
<h2>Instagram</h2>
<p>keyemail1</p>
<i class="fa-brands fa-instagram"></i>
</div>
</a>
</div>
</div>
</template>
<style scoped>
.socials {
display: flex;
align-items: center;
margin-top: 100px;
flex-direction: column;
color: white;
font-family: 'Rubik', sans-serif;
height: 100%;
}
.socials h1 {
margin-bottom: 20px;
font-size: 50px;
}
.socialsgrid {
display: grid;
grid-template-columns: auto auto auto;
align-content: start;
grid-gap: 10px;
}
.socialsgrid a {
color: inherit;
text-decoration: none;
}
.socialsgrid div{
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;
}
.socialsgrid div:hover {
cursor: pointer;
border: 4px;
border-style: solid;
}
.socialsgrid i {
font-size: 35px;
margin-top: auto;
align-self: flex-end;
}
.socialsgrid h2 {
font-size: 30px;
}
.discord {
background-color: #5865F2;
}
.github {
background-color: #171515;
}
.steam {
background-color: #000000;
}
.spotify {
background-color: #1DB954;
}
.youtube {
background-color: #CD201F;
}
.instagram {
background-color: #C13584;
}
@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%
}
.socials {
margin-top: 80px;
justify-content: unset;
}
.socialsgrid div {
width: 100%;
margin-left: 0px;
}
}
@media only screen and (max-height: 720px){
.socials {
display: flex;
justify-content: unset;
margin-top: 80px;
}
}
</style>

95
src/views/VideoPage.vue Normal file
View file

@ -0,0 +1,95 @@
<template>
<h1>Videos</h1>
<ul>
<router-link v-for="video in videos" :key="video.videoID" :to="'/videos/' + video.videoID">
<li>
<img :src="require('@/assets/' + video.thumbnail)" alt="Video Thumbnail"/>
<div id="content">
<h2>{{ video.videoName }}</h2>
</div>
</li>
</router-link>
</ul>
</template>
<script>
import videoData from '../data/videos.js'
export default {
data () {
return {
videos: videoData
}
}
}
</script>
<style scoped>
h1 {
color: white;
font-family: 'Rubik', sans-serif;
font-weight: 500;
font-size: 3rem;
margin-top: 20px;
}
a {
max-width: fit-content;
}
ul {
margin-top: 10px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(370px, 1fr));
row-gap: 32px;
li {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
background-color: var(--bg-alt-color);
padding: 10px;
border-radius: 10px;
width: 370px;
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: 350px;
aspect-ratio: 16 / 9;
pointer-events: none;
user-select: none;
}
}
@media only screen and (max-width: 779px) {
a {
max-width: 100%;
}
ul {
display: flex;
flex-direction: column;
li {
width: 100%;
}
}
}
</style>

69
src/views/VideosPage.vue Normal file
View file

@ -0,0 +1,69 @@
<template>
<notfound v-if="!(video)"></notfound>
<template v-else>
<video controls>
<source :src="require('@/assets/' + video.path)" type="video/mp4">
</video>
<div id="info">
<h1>{{ video.videoName }}</h1>
<p>{{ video.videoDescription }}</p>
</div>
</template>
</template>
<script>
import videoData from '../data/videos.js'
import notfound from '../views/404Page.vue'
export default {
components: {
notfound
},
data () {
return {
video: null
}
},
created() {
let videoID = this.$route.params.id;
this.video = videoData.find(v => v.videoID === videoID);
}
}
</script>
<style scoped>
video {
max-height: calc(100vh - 420px);
max-width: calc(100vw - 40px);
width: max-content;
aspect-ratio: 16 / 9;
margin-top: 20px;
}
#info {
display: flex;
flex-direction: column;
gap: 10px;
margin-top: 30px;
padding: 20px;
border-radius: 10px;
background-color: var(--bg-alt-color);
max-width: 600px;
}
#info h1 {
color: white;
font-family: 'Rubik', sans-serif;
font-weight: 500;
font-size: 2rem;
}
#info p {
font-family: 'Rubik', sans-serif;
font-weight: 200;
font-size: 1.3rem;
color: white;
}
</style>

16
vue.config.js Normal file
View file

@ -0,0 +1,16 @@
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true
})
module.exports = {
chainWebpack: config => {
config
.plugin('html')
.tap(args => {
args[0].title = "Keyemail's Profile"
return args;
})
}
}

6332
yarn.lock Normal file

File diff suppressed because it is too large Load diff