ready to go
This commit is contained in:
parent
195e4c7e02
commit
c76a8a5f56
40
README.md
40
README.md
@ -1,38 +1,20 @@
|
|||||||
# create-svelte
|
# [ngn13.fun](https://ngn13.fun) | my personal website
|
||||||
|
This is the frontend application for my personal website, it's written in SvelteKit and vanilla CSS
|
||||||
Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte).
|
|
||||||
|
|
||||||
## Creating a project
|
|
||||||
|
|
||||||
If you're seeing this, you've probably already done this step. Congrats!
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# create a new project in the current directory
|
|
||||||
npm create svelte@latest
|
|
||||||
|
|
||||||
# create a new project in my-app
|
|
||||||
npm create svelte@latest my-app
|
|
||||||
```
|
|
||||||
|
|
||||||
## Developing
|
|
||||||
|
|
||||||
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
|
||||||
|
|
||||||
|
## development setup
|
||||||
```bash
|
```bash
|
||||||
|
git clone https://github.com/ngn13/ngn13.fun && cd ngn13.fun
|
||||||
|
npm i
|
||||||
npm run dev
|
npm run dev
|
||||||
|
|
||||||
# or start the server and open the app in a new browser tab
|
|
||||||
npm run dev -- --open
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Building
|
## build setup
|
||||||
|
|
||||||
To create a production version of your app:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
git clone https://github.com/ngn13/ngn13.fun && cd ngn13.fun
|
||||||
|
npm i
|
||||||
npm run build
|
npm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
You can preview the production build with `npm run preview`.
|
## license
|
||||||
|
you cannot publish my website or parts of it on any server/domain without my permission
|
||||||
> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.
|
if you want to do this (for some reason) [contact me](mailto:ngn13proton@proton.me)
|
||||||
|
57
package-lock.json
generated
57
package-lock.json
generated
@ -7,6 +7,11 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "website",
|
"name": "website",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/dompurify": "^3.0.2",
|
||||||
|
"dompurify": "^3.0.5",
|
||||||
|
"marked": "^7.0.4"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/adapter-auto": "^2.0.0",
|
"@sveltejs/adapter-auto": "^2.0.0",
|
||||||
"@sveltejs/kit": "^1.20.4",
|
"@sveltejs/kit": "^1.20.4",
|
||||||
@ -527,12 +532,25 @@
|
|||||||
"integrity": "sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g==",
|
"integrity": "sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/dompurify": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-YBL4ziFebbbfQfH5mlC+QTJsvh0oJUrWbmxKMyEdL7emlHJqGR2Qb34TEFKj+VCayBvjKy3xczMFNhugThUsfQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/trusted-types": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/estree": {
|
"node_modules/@types/estree": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
|
||||||
"integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
|
"integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/trusted-types": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g=="
|
||||||
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.10.0",
|
"version": "8.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
|
||||||
@ -651,6 +669,11 @@
|
|||||||
"integrity": "sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==",
|
"integrity": "sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/dompurify": {
|
||||||
|
"version": "3.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.5.tgz",
|
||||||
|
"integrity": "sha512-F9e6wPGtY+8KNMRAVfxeCOHU0/NPWMSENNq4pQctuXRqqdEPW7q3CrLbR5Nse044WwacyjHGOMlvNsBe1y6z9A=="
|
||||||
|
},
|
||||||
"node_modules/esbuild": {
|
"node_modules/esbuild": {
|
||||||
"version": "0.18.17",
|
"version": "0.18.17",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.17.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.17.tgz",
|
||||||
@ -763,6 +786,17 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/marked": {
|
||||||
|
"version": "7.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/marked/-/marked-7.0.4.tgz",
|
||||||
|
"integrity": "sha512-t8eP0dXRJMtMvBojtkcsA7n48BkauktUKzfkPSCq85ZMTJ0v76Rke4DYz01omYpPTUh4p/f7HePgRo3ebG8+QQ==",
|
||||||
|
"bin": {
|
||||||
|
"marked": "bin/marked.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 16"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mdn-data": {
|
"node_modules/mdn-data": {
|
||||||
"version": "2.0.30",
|
"version": "2.0.30",
|
||||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
|
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
|
||||||
@ -1338,12 +1372,25 @@
|
|||||||
"integrity": "sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g==",
|
"integrity": "sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/dompurify": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-YBL4ziFebbbfQfH5mlC+QTJsvh0oJUrWbmxKMyEdL7emlHJqGR2Qb34TEFKj+VCayBvjKy3xczMFNhugThUsfQ==",
|
||||||
|
"requires": {
|
||||||
|
"@types/trusted-types": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/estree": {
|
"@types/estree": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz",
|
||||||
"integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
|
"integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/trusted-types": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g=="
|
||||||
|
},
|
||||||
"acorn": {
|
"acorn": {
|
||||||
"version": "8.10.0",
|
"version": "8.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
|
||||||
@ -1433,6 +1480,11 @@
|
|||||||
"integrity": "sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==",
|
"integrity": "sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"dompurify": {
|
||||||
|
"version": "3.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.5.tgz",
|
||||||
|
"integrity": "sha512-F9e6wPGtY+8KNMRAVfxeCOHU0/NPWMSENNq4pQctuXRqqdEPW7q3CrLbR5Nse044WwacyjHGOMlvNsBe1y6z9A=="
|
||||||
|
},
|
||||||
"esbuild": {
|
"esbuild": {
|
||||||
"version": "0.18.17",
|
"version": "0.18.17",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.17.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.17.tgz",
|
||||||
@ -1521,6 +1573,11 @@
|
|||||||
"@jridgewell/sourcemap-codec": "^1.4.15"
|
"@jridgewell/sourcemap-codec": "^1.4.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"marked": {
|
||||||
|
"version": "7.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/marked/-/marked-7.0.4.tgz",
|
||||||
|
"integrity": "sha512-t8eP0dXRJMtMvBojtkcsA7n48BkauktUKzfkPSCq85ZMTJ0v76Rke4DYz01omYpPTUh4p/f7HePgRo3ebG8+QQ=="
|
||||||
|
},
|
||||||
"mdn-data": {
|
"mdn-data": {
|
||||||
"version": "2.0.30",
|
"version": "2.0.30",
|
||||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
|
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
|
||||||
|
@ -13,5 +13,10 @@
|
|||||||
"svelte": "^4.0.5",
|
"svelte": "^4.0.5",
|
||||||
"vite": "^4.4.2"
|
"vite": "^4.4.2"
|
||||||
},
|
},
|
||||||
"type": "module"
|
"type": "module",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/dompurify": "^3.0.2",
|
||||||
|
"dompurify": "^3.0.5",
|
||||||
|
"marked": "^7.0.4"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=1024">
|
||||||
%sveltekit.head%
|
%sveltekit.head%
|
||||||
</head>
|
</head>
|
||||||
<body data-sveltekit-preload-data="hover">
|
<body data-sveltekit-preload-data="hover">
|
||||||
|
67
src/lib/card_link.svelte
Normal file
67
src/lib/card_link.svelte
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<script>
|
||||||
|
export let title
|
||||||
|
export let url
|
||||||
|
let audio
|
||||||
|
|
||||||
|
let current = ""
|
||||||
|
let i = 0
|
||||||
|
|
||||||
|
while (title.length > i) {
|
||||||
|
let c = title[i]
|
||||||
|
setTimeout(()=>{
|
||||||
|
current += c
|
||||||
|
}, 100*(i+1))
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function epicSound() {
|
||||||
|
audio.play()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<a on:click={epicSound} data-sveltekit-preload-data href={url}>
|
||||||
|
<audio bind:this={audio} preload="auto">
|
||||||
|
<source src="/click.wav" type="audio/mpeg" />
|
||||||
|
</audio>
|
||||||
|
<div class="title">
|
||||||
|
{current}
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
a {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
background: var(--dark-three);
|
||||||
|
border-radius: 7px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: .4s;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
box-shadow: var(--box-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
background: var(--dark-two);
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 7px 7px 0px 0px;
|
||||||
|
font-size: 20px;
|
||||||
|
font-family: Consolas,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New, monospace;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
background: var(--dark-three);
|
||||||
|
padding: 40px;
|
||||||
|
padding-top: 30px;
|
||||||
|
color: white;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 25px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -9,8 +9,7 @@
|
|||||||
<style>
|
<style>
|
||||||
header {
|
header {
|
||||||
background:
|
background:
|
||||||
linear-gradient(rgba(1, 1, 1, 0.96),
|
linear-gradient(rgba(11, 11, 11, 0.808), rgba(1, 1, 1, 0.96)),
|
||||||
rgba(11, 11, 11, 0.808)),
|
|
||||||
url("https://files.ngn13.fun/banner.png");
|
url("https://files.ngn13.fun/banner.png");
|
||||||
background-size: 50%;
|
background-size: 50%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
<div>
|
<div>
|
||||||
<NavbarLink link="/">home</NavbarLink>
|
<NavbarLink link="/">home</NavbarLink>
|
||||||
<NavbarLink link="/projects">projects</NavbarLink>
|
<NavbarLink link="/projects">projects</NavbarLink>
|
||||||
<NavbarLink link="/resources">resources</NavbarLink>
|
|
||||||
<NavbarLink link="/blog">blog</NavbarLink>
|
<NavbarLink link="/blog">blog</NavbarLink>
|
||||||
<NavbarLink link="https://github.com/ngn13/ngn13.fun">source</NavbarLink>
|
<NavbarLink link="https://github.com/ngn13/ngn13.fun">source</NavbarLink>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,10 +1,18 @@
|
|||||||
<script>
|
<script>
|
||||||
import { page } from "$app/stores"
|
import { page } from "$app/stores"
|
||||||
export let link
|
export let link
|
||||||
|
let audio
|
||||||
|
|
||||||
|
function epicSound() {
|
||||||
|
audio.play()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<a href="{link}"><slot></slot></a>
|
<audio bind:this={audio} preload="auto">
|
||||||
|
<source src="/click.wav" type="audio/mpeg" />
|
||||||
|
</audio>
|
||||||
|
<a data-sveltekit-preload-data on:click={epicSound} href="{link}"><slot></slot></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@ -19,9 +27,9 @@ a {
|
|||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
|
text-shadow: 3px 4px 7px rgba(81, 67, 21, 0.8);
|
||||||
animation-name: underlineAnimation;
|
animation-name: underlineAnimation;
|
||||||
animation-duration: 5s;
|
animation-duration: 5s;
|
||||||
animation-iteration-count: infinite;
|
animation-iteration-count: infinite;
|
||||||
text-shadow: 3px 4px 7px rgba(81, 67, 21, 0.8);
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
57
src/lib/project.svelte
Normal file
57
src/lib/project.svelte
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<script>
|
||||||
|
import { goto } from "$app/navigation";
|
||||||
|
|
||||||
|
export let desc
|
||||||
|
export let url
|
||||||
|
let audio
|
||||||
|
|
||||||
|
function redirect() {
|
||||||
|
audio.play()
|
||||||
|
goto(url);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<main on:click={redirect}>
|
||||||
|
<audio bind:this={audio} preload="auto">
|
||||||
|
<source src="/click.wav" type="audio/mpeg" />
|
||||||
|
</audio>
|
||||||
|
<h1 class="c"> </h1>
|
||||||
|
<div>
|
||||||
|
<h1><slot></slot></h1>
|
||||||
|
<p>{desc}</p>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
main {
|
||||||
|
display: flex;
|
||||||
|
padding: 40px 60px 40px 60px;
|
||||||
|
background: var(--dark-two);
|
||||||
|
border-radius: 7px 7px 0px 0px;
|
||||||
|
justify-content: center;
|
||||||
|
align-content: center;
|
||||||
|
flex-direction: row;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: .4s;
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main:hover {
|
||||||
|
box-shadow: var(--box-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div h1 {
|
||||||
|
font-size: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div p {
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
8
src/routes/+error.svelte
Normal file
8
src/routes/+error.svelte
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<script>
|
||||||
|
import { onMount } from "svelte"
|
||||||
|
import { goto } from "$app/navigation"
|
||||||
|
|
||||||
|
onMount(()=>{
|
||||||
|
goto("/")
|
||||||
|
})
|
||||||
|
</script>
|
@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<title>[ngn] | homepage</title>
|
<title>[ngn] | homepage</title>
|
||||||
<meta content="[ngn] | Homepage" property="og:title" />
|
<meta content="[ngn] | homepage" property="og:title" />
|
||||||
<meta content="Homepage of my personal website" property="og:description" />
|
<meta content="Homepage of my personal website" property="og:description" />
|
||||||
<meta content="https://ngn13.fun" property="og:url" />
|
<meta content="https://ngn13.fun" property="og:url" />
|
||||||
<meta content="#141414" data-react-helmet="true" name="theme-color" />
|
<meta content="#000000" data-react-helmet="true" name="theme-color" />
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<Header>
|
<Header>
|
||||||
@ -16,6 +16,7 @@
|
|||||||
hello world!
|
hello world!
|
||||||
</Header>
|
</Header>
|
||||||
|
|
||||||
|
<main>
|
||||||
<div class="flexbox">
|
<div class="flexbox">
|
||||||
<Card title="whoami">
|
<Card title="whoami">
|
||||||
👋 Hello! I'm ngn!
|
👋 Hello! I'm ngn!
|
||||||
@ -32,29 +33,84 @@
|
|||||||
You are currently on my personal website, for all you nerds, here is some
|
You are currently on my personal website, for all you nerds, here is some
|
||||||
techinal details you may want to know:
|
techinal details you may want to know:
|
||||||
<ul>
|
<ul>
|
||||||
<li><c> </c> I built the frontend app using SvelteKit
|
<li><c> </c> I built the frontend app using SvelteKit</li>
|
||||||
<li><c> </c> I deploy my app to vecel using Github actions</li>
|
<li><c> </c> I deploy my app to vercel using Github actions</li>
|
||||||
<li><c> </c> Backend server is written in Go and it's hosted on my server</li>
|
<li><c> </c> Backend server is written in Go and it's hosted on my server</li>
|
||||||
<li><c> </c> And yup, I also have other services hosted on it</li>
|
<li><c> </c> And yup, I also have other services hosted on the same server</li>
|
||||||
</ul>
|
</ul>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="flexbox">
|
||||||
|
<Card title="ps -eaf">
|
||||||
|
I usually spend my time...
|
||||||
|
<ul>
|
||||||
|
<li><c> </c> building random projects</li>
|
||||||
|
<li><c> </c> contributing stuff that I like</li>
|
||||||
|
<li><c></c> solving CTFs</li>
|
||||||
|
<li><c> </c> customizing my desktop</li>
|
||||||
|
<li><c> </c> posting random stuff on my blog, which you should definitely check out (it's very active)</li>
|
||||||
|
</ul>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card title="wall">
|
||||||
|
If you want to have a chat, you can find me on the following platforms:
|
||||||
|
<ul>
|
||||||
|
<li><c> </c> <a href="https://github.com/ngn13">Github</a></li>
|
||||||
|
<li><c> </c> <a href="https://mastodon.social/@ngn">Mastodon</a></li>
|
||||||
|
<li><c> </c> <a href="https://discord.com/users/568131907368386565">Discord</a></li>
|
||||||
|
<li><c> </c> <a href="mailto:ngn13proton@proton.me">Email</a></li>
|
||||||
|
</ul>
|
||||||
|
Or you can DM me on matrix:
|
||||||
|
<br>
|
||||||
|
<c>@ngn:matrix.ngn13.fun</c>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<div class="version">
|
||||||
|
<p>v3.0</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.flexbox {
|
main{
|
||||||
padding: 50px;
|
|
||||||
gap: 30px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 35px;
|
||||||
|
padding: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flexbox {
|
||||||
|
display: flex;
|
||||||
|
gap: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
padding-left: 30px;
|
padding-left: 30px;
|
||||||
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
li {
|
li {
|
||||||
padding-top: 15px;
|
padding-top: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.version {
|
||||||
|
color: var(--dark-fife);
|
||||||
|
position: fixed;
|
||||||
|
bottom: 10px;
|
||||||
|
right: 10px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 1076px) {
|
@media only screen and (max-width: 1076px) {
|
||||||
.flexbox {
|
.flexbox {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
9
src/routes/blog/+page.js
Normal file
9
src/routes/blog/+page.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export async function load({ fetch }) {
|
||||||
|
const api = import.meta.env.VITE_API_URL_DEV
|
||||||
|
const res = await fetch(api+"/blog/sum")
|
||||||
|
const data = await res.json()
|
||||||
|
|
||||||
|
return {
|
||||||
|
posts: data["result"]
|
||||||
|
}
|
||||||
|
}
|
87
src/routes/blog/+page.svelte
Normal file
87
src/routes/blog/+page.svelte
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
<script>
|
||||||
|
import Header from "../../lib/header.svelte";
|
||||||
|
import CardLink from "../../lib/card_link.svelte";
|
||||||
|
import { onMount } from "svelte";
|
||||||
|
|
||||||
|
export let data
|
||||||
|
let inpt
|
||||||
|
|
||||||
|
let all = data.posts
|
||||||
|
let posts = all
|
||||||
|
let inputcls = "c"
|
||||||
|
|
||||||
|
function show(term){
|
||||||
|
posts = []
|
||||||
|
for(let i = 0; i < all.length; i++) {
|
||||||
|
if (all[i].title.toLowerCase().includes(term.toLowerCase())){
|
||||||
|
posts.push(all[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (posts.length == 0){
|
||||||
|
inputcls = "nf"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
inputcls = "c"
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
inpt.focus()
|
||||||
|
show(inpt.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
function search(){
|
||||||
|
let term = inpt.value
|
||||||
|
show(term)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>[ngn] | blog</title>
|
||||||
|
<meta content="[ngn] | blog" property="og:title" />
|
||||||
|
<meta content="View my blog posts" property="og:description" />
|
||||||
|
<meta content="https://ngn13.fun" property="og:url" />
|
||||||
|
<meta content="#000000" data-react-helmet="true" name="theme-color" />
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<Header>
|
||||||
|
<c>/dev/</c>blog
|
||||||
|
</Header>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<input on:keyup={search} bind:this={inpt} class="{inputcls}" placeholder="Search for a post">
|
||||||
|
{#each posts as post}
|
||||||
|
<CardLink url="/blog/{post.id}" title="{post.title}">
|
||||||
|
<p>{post.author} | {post.date}</p>
|
||||||
|
<br>
|
||||||
|
{post.content}...
|
||||||
|
</CardLink>
|
||||||
|
{/each}
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
main{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 35px;
|
||||||
|
padding: 15%;
|
||||||
|
padding-top: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
text-align: center;
|
||||||
|
background: var(--dark-two);
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
font-size: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nf {
|
||||||
|
color: rgb(120, 120, 120);
|
||||||
|
}
|
||||||
|
</style>
|
14
src/routes/blog/[id]/+page.server.js
Normal file
14
src/routes/blog/[id]/+page.server.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
export async function load({ fetch, params }) {
|
||||||
|
const id = params.id
|
||||||
|
const api = import.meta.env.VITE_API_URL_DEV
|
||||||
|
const res = await fetch(api+"/blog/get?id="+id)
|
||||||
|
const data = await res.json()
|
||||||
|
|
||||||
|
if (data["error"] != "") {
|
||||||
|
return {
|
||||||
|
error: data["error"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data["result"]
|
||||||
|
}
|
163
src/routes/blog/[id]/+page.svelte
Normal file
163
src/routes/blog/[id]/+page.svelte
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
<script>
|
||||||
|
import Header from "../../../lib/header.svelte"
|
||||||
|
import { goto } from "$app/navigation"
|
||||||
|
import { onMount } from "svelte"
|
||||||
|
import DOMPurify from "dompurify"
|
||||||
|
import { marked } from "marked"
|
||||||
|
|
||||||
|
export let data
|
||||||
|
let sanitized
|
||||||
|
const api = import.meta.env.VITE_API_URL_DEV
|
||||||
|
|
||||||
|
let upvote_status = "inactive"
|
||||||
|
let downvote_status = "inactive"
|
||||||
|
let voted = false
|
||||||
|
let audio
|
||||||
|
|
||||||
|
async function get_status() {
|
||||||
|
const res = await fetch(api+"/blog/vote/status?id="+data.id)
|
||||||
|
const json = await res.json()
|
||||||
|
|
||||||
|
if(json["error"]!= ""){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json["result"] == "upvote") {
|
||||||
|
upvote_status = "active"
|
||||||
|
downvote_status = "inactive"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
downvote_status = "active"
|
||||||
|
upvote_status = "inactive"
|
||||||
|
}
|
||||||
|
|
||||||
|
voted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(async ()=>{
|
||||||
|
if (data.title == undefined)
|
||||||
|
goto("/blog")
|
||||||
|
|
||||||
|
sanitized = DOMPurify.sanitize(
|
||||||
|
marked.parse(data.content, { breaks: true }),
|
||||||
|
{
|
||||||
|
ADD_TAGS: ["iframe"],
|
||||||
|
ADD_ATTR: ["allow", "allowfullscreen", "frameborder", "scrolling"]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
await get_status()
|
||||||
|
})
|
||||||
|
|
||||||
|
async function upvote(){
|
||||||
|
audio.play()
|
||||||
|
const res = await fetch(api+"/blog/vote/set?id="+data.id+"&to=upvote")
|
||||||
|
const json = await res.json()
|
||||||
|
|
||||||
|
if(json["error"] != ""){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (voted){
|
||||||
|
data.vote += 2
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
voted = true
|
||||||
|
data.vote += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
await get_status()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function downvote(){
|
||||||
|
audio.play()
|
||||||
|
const res = await fetch(api+"/blog/vote/set?id="+data.id+"&to=downvote")
|
||||||
|
const json = await res.json()
|
||||||
|
|
||||||
|
if(json["error"] != ""){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (voted){
|
||||||
|
data.vote -= 2
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
voted = true
|
||||||
|
data.vote -= 1
|
||||||
|
}
|
||||||
|
|
||||||
|
await get_status()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>[ngn] | blog</title>
|
||||||
|
<meta content="[ngn] | blog" property="og:title" />
|
||||||
|
<meta content="View my blog posts" property="og:description" />
|
||||||
|
<meta content="https://ngn13.fun" property="og:url" />
|
||||||
|
<meta content="#000000" data-react-helmet="true" name="theme-color" />
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<Header>
|
||||||
|
<c>{data.title}</c>
|
||||||
|
<p>{data.author} | {data.date}</p>
|
||||||
|
</Header>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<audio bind:this={audio} preload="auto">
|
||||||
|
<source src="/click.wav" type="audio/mpeg" />
|
||||||
|
</audio>
|
||||||
|
<div class="content markdown-body">
|
||||||
|
{@html sanitized}
|
||||||
|
</div>
|
||||||
|
<div class="votes">
|
||||||
|
<h3 on:click={async ()=>{upvote()}} class="{upvote_status}"></h3>
|
||||||
|
<p>{data.vote}</p>
|
||||||
|
<h3 on:click={async ()=>{downvote()}} class="{downvote_status}"></h3>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
p {
|
||||||
|
font-size: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
padding: 50px;
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
padding: 30px;
|
||||||
|
background: var(--dark-two);
|
||||||
|
box-shadow: var(--box-shadow);
|
||||||
|
border-radius: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.votes {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
|
text-shadow: var(--text-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.votes h3{
|
||||||
|
font-size: 40px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.votes h3:hover {
|
||||||
|
animation-name: colorAnimation;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-duration: 10s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
animation-name: colorAnimation;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-duration: 10s;
|
||||||
|
}
|
||||||
|
</style>
|
35
src/routes/projects/+page.js
Normal file
35
src/routes/projects/+page.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
export async function load({ fetch }) {
|
||||||
|
const api = import.meta.env.VITE_API_URL_DEV
|
||||||
|
const res = await fetch(api+"/projects/get")
|
||||||
|
const data = await res.json()
|
||||||
|
|
||||||
|
if (data["error"] != ""){
|
||||||
|
return {
|
||||||
|
error: data["error"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let all = data["result"]
|
||||||
|
let counter = 0
|
||||||
|
let currentlist = []
|
||||||
|
let projects = []
|
||||||
|
|
||||||
|
for (let i = 0; i < all.length; i++){
|
||||||
|
currentlist.push(all[i])
|
||||||
|
counter += 1
|
||||||
|
|
||||||
|
if(i == all.length-1 && counter != 3){
|
||||||
|
projects.push(currentlist)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (counter == 3) {
|
||||||
|
projects.push(currentlist)
|
||||||
|
currentlist = []
|
||||||
|
counter = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
projects
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +1,50 @@
|
|||||||
<script>
|
<script>
|
||||||
import Header from "../../lib/header.svelte";
|
import Header from "../../lib/header.svelte";
|
||||||
</script>
|
import Project from "../../lib/project.svelte";
|
||||||
|
|
||||||
|
export let data
|
||||||
|
console.log(data)
|
||||||
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<title>[ngn] | projects</title>
|
<title>[ngn] | projects</title>
|
||||||
<meta content="[ngn] | Projects" property="og:title" />
|
<meta content="[ngn] | projects" property="og:title" />
|
||||||
<meta content="Projects that I work on" property="og:description" />
|
<meta content="Projects that I work on" property="og:description" />
|
||||||
<meta content="https://ngn13.fun" property="og:url" />
|
<meta content="https://ngn13.fun" property="og:url" />
|
||||||
<meta content="#141414" data-react-helmet="true" name="theme-color" />
|
<meta content="#000000" data-react-helmet="true" name="theme-color" />
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
<Header><glitch>ls -l</glitch> projects</Header>
|
<Header><c>ls -l</c> projects</Header>
|
||||||
|
<main>
|
||||||
|
{#each data.projects as projectlist}
|
||||||
|
<div class="flexrow">
|
||||||
|
{#each projectlist as project}
|
||||||
|
<Project url="{project.link}" desc="{project.desc}">{project.name}</Project>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
main {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-content: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 50px;
|
||||||
|
gap: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flexrow {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-content: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
<style></style>
|
@media only screen and (max-width: 1316px) {
|
||||||
|
.flexrow {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
BIN
static/click.wav
Normal file
BIN
static/click.wav
Normal file
Binary file not shown.
@ -47,6 +47,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.markdown-body a {
|
.markdown-body a {
|
||||||
|
animation-name: colorAnimation;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-duration: 10s;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
color: #58a6ff;
|
color: #58a6ff;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
@ -25,17 +25,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
-webkit-touch-callout: none;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-khtml-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
background: var(--dark-one);
|
background: var(--dark-one);
|
||||||
font-family: "Ubuntu", sans-serif;
|
font-family: "Ubuntu", sans-serif;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::selection {
|
||||||
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
width: 10px;
|
width: 10px;
|
||||||
@ -296,7 +294,7 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c {
|
.c, c {
|
||||||
animation-name: colorAnimation;
|
animation-name: colorAnimation;
|
||||||
animation-iteration-count: infinite;
|
animation-iteration-count: infinite;
|
||||||
animation-duration: 10s;
|
animation-duration: 10s;
|
||||||
|
@ -7,7 +7,12 @@ const config = {
|
|||||||
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
|
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
|
||||||
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
|
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
|
||||||
adapter: adapter()
|
adapter: adapter()
|
||||||
}
|
},
|
||||||
|
|
||||||
|
onwarn: (warning, handler) => {
|
||||||
|
if (warning.code === "a11y-click-events-have-key-events") return
|
||||||
|
handler(warning)
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user