first commit
This commit is contained in:
commit
15d5df3227
13
.editorconfig
Normal file
13
.editorconfig
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
94
.gitignore
vendored
Normal file
94
.gitignore
vendored
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
# Created by .ignore support plugin (hsz.mobi)
|
||||||
|
### Node template
|
||||||
|
# Logs
|
||||||
|
/logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# TypeScript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# next.js build output
|
||||||
|
.next
|
||||||
|
|
||||||
|
# nuxt.js build output
|
||||||
|
.nuxt
|
||||||
|
|
||||||
|
# Nuxt generate
|
||||||
|
dist
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless
|
||||||
|
|
||||||
|
# IDE / Editor
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# Service worker
|
||||||
|
sw.*
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Vim swap files
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
# db file
|
||||||
|
db.json
|
||||||
|
pass
|
12
README.md
Normal file
12
README.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# My Website - [ngn13.fun](https://ngn13.fun)
|
||||||
|
This repo contains the source code of my personal website.
|
||||||
|
It's written NuxtJS and supports full SSR.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
```
|
||||||
|
git clone https://github.com/ngn13/my-website.git
|
||||||
|
cd my-website && npm i
|
||||||
|
echo "password" > pass
|
||||||
|
npm run build
|
||||||
|
npm run start
|
||||||
|
```
|
78
api/db.js
Normal file
78
api/db.js
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
const fs = require("fs");
|
||||||
|
|
||||||
|
class Database {
|
||||||
|
constructor() {
|
||||||
|
this.path = "db.json";
|
||||||
|
this.json = {};
|
||||||
|
this.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
write() {
|
||||||
|
fs.writeFileSync(this.path, JSON.stringify(this.json));
|
||||||
|
}
|
||||||
|
|
||||||
|
read() {
|
||||||
|
try {
|
||||||
|
const data = fs.readFileSync(this.path, "utf8");
|
||||||
|
this.json = JSON.parse(data);
|
||||||
|
} catch (error) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
find_all(key, check, ...args) {
|
||||||
|
try {
|
||||||
|
const ret = [];
|
||||||
|
for (const d of this.json[key]) {
|
||||||
|
if (check(d, ...args)) {
|
||||||
|
ret.push(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
} catch (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
find(key, check, ...args) {
|
||||||
|
try {
|
||||||
|
for (const d of this.json[key]) {
|
||||||
|
if (check(d, ...args)) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} catch (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get(key) {
|
||||||
|
const res = this.json[key]
|
||||||
|
if(res===undefined)
|
||||||
|
return []
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
push(key, data) {
|
||||||
|
try {
|
||||||
|
this.json[key].push(data);
|
||||||
|
} catch (error) {
|
||||||
|
this.json[key] = [];
|
||||||
|
this.json[key].push(data);
|
||||||
|
}
|
||||||
|
this.write();
|
||||||
|
}
|
||||||
|
|
||||||
|
pop(key, data) {
|
||||||
|
try {
|
||||||
|
const indx = this.json[key].indexOf(data);
|
||||||
|
this.json[key].splice(indx, 1);
|
||||||
|
} catch (error) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.write();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Database;
|
136
api/index.js
Normal file
136
api/index.js
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
const express = require("express");
|
||||||
|
const fs = require("fs");
|
||||||
|
const Database = require("./db");
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
const db = new Database();
|
||||||
|
|
||||||
|
app.use(express.json());
|
||||||
|
app.use(express.urlencoded({ extended: false }));
|
||||||
|
|
||||||
|
function gimmeToken() {
|
||||||
|
var result = ""
|
||||||
|
var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||||
|
var charactersLength = characters.length
|
||||||
|
for ( var i = 0; i < 32; i++ ) {
|
||||||
|
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
let TOKEN = gimmeToken();
|
||||||
|
const PASS = fs.readFileSync("pass", "utf-8")
|
||||||
|
|
||||||
|
/*
|
||||||
|
* error: 0 -> no error
|
||||||
|
* error: 1 -> parameter error
|
||||||
|
* error: 2 -> auth error
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// PATH: /api/login
|
||||||
|
// METHOD: GET
|
||||||
|
// PARAMETERS: pass
|
||||||
|
app.get("/login", (req,res)=>{
|
||||||
|
let pass = req.query.pass;
|
||||||
|
|
||||||
|
if (pass === undefined)
|
||||||
|
return res.json({error: 1})
|
||||||
|
|
||||||
|
if (pass !== PASS)
|
||||||
|
return res.json({error: 2})
|
||||||
|
|
||||||
|
res.json({error: 0, token:TOKEN})
|
||||||
|
})
|
||||||
|
|
||||||
|
// PATH: /api/logout
|
||||||
|
// METHOD: GET
|
||||||
|
// PARAMETERS: token
|
||||||
|
app.get("/logout", (req,res)=>{
|
||||||
|
let token = req.query.token;
|
||||||
|
|
||||||
|
if (token === undefined)
|
||||||
|
return res.json({error: 1})
|
||||||
|
|
||||||
|
if (token !== TOKEN)
|
||||||
|
return res.json({error: 2})
|
||||||
|
|
||||||
|
TOKEN = gimmeToken()
|
||||||
|
res.json({error: 0})
|
||||||
|
})
|
||||||
|
|
||||||
|
// PATH: /api/add_project
|
||||||
|
// METHOD: GET
|
||||||
|
// PARAMETERS: token, name, desc, url
|
||||||
|
app.get("/add_project", (req, res) => {
|
||||||
|
let token = req.query.token;
|
||||||
|
let name = req.query.name;
|
||||||
|
let desc = req.query.desc;
|
||||||
|
let url = req.query.url;
|
||||||
|
|
||||||
|
if (
|
||||||
|
token === undefined ||
|
||||||
|
name === undefined ||
|
||||||
|
desc === undefined ||
|
||||||
|
url === undefined
|
||||||
|
)
|
||||||
|
return res.json({error: 1})
|
||||||
|
|
||||||
|
if (token !== TOKEN)
|
||||||
|
return res.json({error: 2})
|
||||||
|
|
||||||
|
db.push("projects", {"name":name, "desc":desc, "url":url})
|
||||||
|
res.json({error: 0})
|
||||||
|
});
|
||||||
|
|
||||||
|
// PATH: /api/add_resource
|
||||||
|
// METHOD: GET
|
||||||
|
// PARAMETERS: token, name, tags, url
|
||||||
|
app.get("/add_resource", (req, res) => {
|
||||||
|
let token = req.query.token;
|
||||||
|
let name = req.query.name;
|
||||||
|
let tags = req.query.tags;
|
||||||
|
let url = req.query.url;
|
||||||
|
|
||||||
|
if (
|
||||||
|
token === undefined ||
|
||||||
|
name === undefined ||
|
||||||
|
tags === undefined ||
|
||||||
|
url === undefined
|
||||||
|
)
|
||||||
|
return res.json({error: 1})
|
||||||
|
|
||||||
|
if (token !== TOKEN)
|
||||||
|
return res.json({error: 2})
|
||||||
|
|
||||||
|
db.push("resources", {"name":name, "tags":tags.split(","), "url":url})
|
||||||
|
res.json({error: 0})
|
||||||
|
});
|
||||||
|
|
||||||
|
// PATH: /api/get_projects
|
||||||
|
// METHOD: GET
|
||||||
|
// PARAMETERS: NONE
|
||||||
|
app.get("/get_projects", (req, res) => {
|
||||||
|
let projects = db.get("projects")
|
||||||
|
res.json({error: 0, projects:projects})
|
||||||
|
});
|
||||||
|
|
||||||
|
// PATH: /api/get_resources
|
||||||
|
// METHOD: GET
|
||||||
|
// PARAMETERS: NONE
|
||||||
|
app.get("/get_resources", (req, res) => {
|
||||||
|
let resources = db.get("resources")
|
||||||
|
res.json({error: 0, resources:resources})
|
||||||
|
});
|
||||||
|
|
||||||
|
// PATH: /api/ping
|
||||||
|
// METHOD: GET
|
||||||
|
// PARAMETERS: NONE
|
||||||
|
app.get("/ping", (req, res) => {
|
||||||
|
res.send({ error: 0 });
|
||||||
|
});
|
||||||
|
|
||||||
|
export default {
|
||||||
|
path: "/api",
|
||||||
|
handler: app,
|
||||||
|
};
|
29
components/Button.vue
Normal file
29
components/Button.vue
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<button @click="click"><slot></slot></button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: ["click"]
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
button {
|
||||||
|
text-align: center;
|
||||||
|
width: 540px;
|
||||||
|
font-size: 25px;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 20px;
|
||||||
|
background: var(--dark-two);
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
outline: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: .4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
box-shadow: var(--def-shadow);
|
||||||
|
}
|
||||||
|
</style>
|
56
components/Card.vue
Normal file
56
components/Card.vue
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
div {
|
||||||
|
box-shadow: var(--def-shadow);
|
||||||
|
background: var(--dark-two);
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
padding: 50px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
text-shadow: 3px 4px 7px rgba(81, 67, 21, 0.8);
|
||||||
|
font-size: 50px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
animation-name: colorAnimation;
|
||||||
|
animation-duration: 10s;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 30px;
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 40px;
|
||||||
|
line-height: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-size: 40px;
|
||||||
|
color: white;
|
||||||
|
line-height: 60px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
</style>
|
31
components/Header.vue
Normal file
31
components/Header.vue
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<template>
|
||||||
|
<div class="header">
|
||||||
|
<h1>
|
||||||
|
<slot></slot>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
div {
|
||||||
|
background: linear-gradient(rgba(3, 3, 3, 0.706), rgba(22, 22, 22, 0.808)), url("https://www.sketchappsources.com/resources/source-image/tv-glitch-sureshmurali29.png");
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 7.5vw;
|
||||||
|
padding: 150px;
|
||||||
|
text-align: center;
|
||||||
|
color: white;
|
||||||
|
text-shadow: 3px 4px 7px rgba(81, 67, 21, 0.8);
|
||||||
|
text-size-adjust: 80%;
|
||||||
|
}
|
||||||
|
</style>
|
27
components/Input.vue
Normal file
27
components/Input.vue
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<template>
|
||||||
|
<input v-on:keyup="keyup" :placeholder="placeholder" :type="type">
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props:["keyup", "placeholder", "type"]
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
input {
|
||||||
|
width: 500px;
|
||||||
|
font-size: 25px;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 20px;
|
||||||
|
background: var(--dark-two);
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
outline: none;
|
||||||
|
transition: .4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus {
|
||||||
|
box-shadow: var(--def-shadow);
|
||||||
|
}
|
||||||
|
</style>
|
41
components/Logout.vue
Normal file
41
components/Logout.vue
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1>Currently logged in</h1>
|
||||||
|
<Button :click="click">Logout</Button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import axios from 'axios';
|
||||||
|
import Button from './Button.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
async click(e) {
|
||||||
|
await axios.get(`/api/logout?token=${localStorage.getItem("token")}`)
|
||||||
|
localStorage.clear()
|
||||||
|
location.reload()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
h1{
|
||||||
|
color: var(--white);
|
||||||
|
font-size: 50px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
div{
|
||||||
|
background-color: var(--dark-three);
|
||||||
|
padding: 50px;
|
||||||
|
margin-top: 50px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
</style>
|
53
components/Navbar.vue
Normal file
53
components/Navbar.vue
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<template>
|
||||||
|
<nav>
|
||||||
|
<div>
|
||||||
|
<h3>[ngn]</h3>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<NavbarLink :out="false" url="/">Home</NavbarLink>
|
||||||
|
<NavbarLink :out="false" url="/projects">Projects</NavbarLink>
|
||||||
|
<NavbarLink :out="false" url="/resources">Resources</NavbarLink>
|
||||||
|
<!--<NavbarLink :out="false" url="/stats">Stats</NavbarLink>-->
|
||||||
|
<NavbarLink :out="true" url="http://github.com/ngn13/my-website">Source</NavbarLink>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import NavbarLink from "./NavbarLink.vue";
|
||||||
|
|
||||||
|
export default {}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
nav {
|
||||||
|
background: var(--dark-two);
|
||||||
|
padding: 25px 35px 30px 35px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
border-bottom: solid 3px black;
|
||||||
|
animation-name: borderAnimation;
|
||||||
|
animation-duration: 10s;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
box-shadow: var(--def-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: 30px;
|
||||||
|
color: red;
|
||||||
|
animation-name: colorAnimation;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-duration: 10s;
|
||||||
|
}
|
||||||
|
</style>
|
60
components/NavbarLink.vue
Normal file
60
components/NavbarLink.vue
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<nuxt-link v-if="!out" :class="cname" id="link" :to="url">
|
||||||
|
<slot></slot>
|
||||||
|
</nuxt-link>
|
||||||
|
<a v-if="out" :class="cname" id="link" :href="url">
|
||||||
|
<slot></slot>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: ["url", "out"],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
cname: "notcurrent"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted(){
|
||||||
|
let url = window.location.pathname
|
||||||
|
if(url===this.url){
|
||||||
|
this.cname = "current"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.notcurrent {
|
||||||
|
margin-left: 20px;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 25px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notcurrent:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
animation-name: underlineAnimation;
|
||||||
|
animation-duration: 5s;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
text-shadow: 3px 4px 7px rgba(81, 67, 21, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.current{
|
||||||
|
margin-left: 20px;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 25px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: underline;
|
||||||
|
animation-name: underlineAnimation;
|
||||||
|
animation-duration: 10s;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
text-shadow: 3px 4px 7px rgba(81, 67, 21, 0.8);
|
||||||
|
}
|
||||||
|
</style>
|
51
components/NewProject.vue
Normal file
51
components/NewProject.vue
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1>Add Project</h1>
|
||||||
|
<Input :keyup="function() { }" id="name" placeholder="Project Name" type="text"/>
|
||||||
|
<Input :keyup="function() { }" id="desc" placeholder="Project Desc" type="text"/>
|
||||||
|
<Input :keyup="function() { }" id="url" placeholder="Project URL" type="text"/>
|
||||||
|
<Button :click="click">Post</Button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import axios from 'axios';
|
||||||
|
import Input from './Input.vue';
|
||||||
|
import Button from './Button.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
async click(e) {
|
||||||
|
const name = document.getElementById("name").value
|
||||||
|
const desc = document.getElementById("desc").value
|
||||||
|
const url = document.getElementById("url").value
|
||||||
|
const token = localStorage.getItem("token")
|
||||||
|
const res = await axios.get(`/api/add_project?token=${token}&name=${name}&desc=${desc}&url=${url}`)
|
||||||
|
if(res.data["error"]!==0)
|
||||||
|
return alert("Error!")
|
||||||
|
alert("Project added!")
|
||||||
|
location.reload()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
h1{
|
||||||
|
color: var(--white);
|
||||||
|
font-size: 50px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
div{
|
||||||
|
background-color: var(--dark-three);
|
||||||
|
padding: 50px;
|
||||||
|
margin-top: 50px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
</style>
|
51
components/NewResource.vue
Normal file
51
components/NewResource.vue
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1>Add Resource</h1>
|
||||||
|
<Input :keyup="function(){}" id="name" placeholder="Resource Name" type="text"/>
|
||||||
|
<Input :keyup="function(){}" id="tags" placeholder="Resource Tags (comma seperated)" type="text"/>
|
||||||
|
<Input :keyup="function(){}" id="url" placeholder="Resource URL" type="text"/>
|
||||||
|
<Button :click="click">Post</Button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Input from './Input.vue';
|
||||||
|
import Button from './Button.vue';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
async click(e) {
|
||||||
|
const name = document.getElementById("name").value
|
||||||
|
const tags = document.getElementById("tags").value
|
||||||
|
const url = document.getElementById("url").value
|
||||||
|
const token = localStorage.getItem("token")
|
||||||
|
const res = await axios.get(`/api/add_resource?token=${token}&name=${name}&tags=${tags}&url=${url}`)
|
||||||
|
if(res.data["error"]!==0)
|
||||||
|
return alert("Error!")
|
||||||
|
alert("Resource added!")
|
||||||
|
location.reload()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
h1{
|
||||||
|
color: var(--white);
|
||||||
|
font-size: 50px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
div{
|
||||||
|
background-color: var(--dark-three);
|
||||||
|
padding: 50px;
|
||||||
|
margin-top: 50px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
</style>
|
63
components/Project.vue
Normal file
63
components/Project.vue
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<template>
|
||||||
|
<main @click="redirect()">
|
||||||
|
<i class='bx bx-code-alt'></i>
|
||||||
|
<div>
|
||||||
|
<h1>{{ name }}</h1>
|
||||||
|
<h2>{{ desc }}</h2>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: ["name", "desc", "url"],
|
||||||
|
methods: {
|
||||||
|
redirect(e) {
|
||||||
|
location.href = this.url
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
main {
|
||||||
|
color: var(--white);
|
||||||
|
background: var(--dark-two);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 20px;
|
||||||
|
padding: 40px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: .4s;
|
||||||
|
height: 13%;
|
||||||
|
width: 27%;
|
||||||
|
}
|
||||||
|
|
||||||
|
main:hover{
|
||||||
|
box-shadow: var(--def-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
i{
|
||||||
|
font-size: 65px;
|
||||||
|
animation-name: colorAnimation;
|
||||||
|
animation-duration: 10s;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1{
|
||||||
|
font-size: 35px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2{
|
||||||
|
font-size: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1121px) {
|
||||||
|
main{
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
28
components/ProjectList.vue
Normal file
28
components/ProjectList.vue
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
div{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
padding: 20px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1121px) {
|
||||||
|
div {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
66
components/Resource.vue
Normal file
66
components/Resource.vue
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<template>
|
||||||
|
<main @click="redirect()" class="mn">
|
||||||
|
<div class="resource">
|
||||||
|
<h1>{{ name }}</h1>
|
||||||
|
<div class="tags">
|
||||||
|
<Tag v-for="tag in tags" :key="tag">{{ tag }}</Tag>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<i class='bx bx-right-arrow-alt' ></i>
|
||||||
|
</main>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Tag from './Tag.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: ["tags", "name", "url"],
|
||||||
|
methods: {
|
||||||
|
redirect(e){
|
||||||
|
location.href = this.url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
main{
|
||||||
|
background: var(--dark-two);
|
||||||
|
padding: 30px 40px 30px 40px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
color: var(--white);
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
transition: .4s;
|
||||||
|
width: 80%;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
main:hover{
|
||||||
|
box-shadow: var(--def-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mn:hover i{
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resource{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
i{
|
||||||
|
font-size: 70px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--dark-two);
|
||||||
|
transition: .4s;
|
||||||
|
}
|
||||||
|
</style>
|
24
components/Tag.vue
Normal file
24
components/Tag.vue
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<template>
|
||||||
|
<p>
|
||||||
|
#<slot></slot>
|
||||||
|
</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
p{
|
||||||
|
background: var(--dark-three);
|
||||||
|
color: white;
|
||||||
|
text-shadow: 1px 1px 2px white;
|
||||||
|
padding: 5px 10px 5px 10px;
|
||||||
|
font-size: 25px;
|
||||||
|
border-radius: 7px;
|
||||||
|
margin-top: 10px;
|
||||||
|
transition: .4s;
|
||||||
|
}
|
||||||
|
</style>
|
31
nuxt.config.js
Normal file
31
nuxt.config.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
export default {
|
||||||
|
head: {
|
||||||
|
title: "[ngn]",
|
||||||
|
htmlAttrs: {
|
||||||
|
lang: "en",
|
||||||
|
},
|
||||||
|
meta: [
|
||||||
|
{ charset: "utf-8" },
|
||||||
|
{ name: "viewport", content: "width=device-width, initial-scale=1" },
|
||||||
|
{ hid: "description", name: "description", content: "" },
|
||||||
|
{ name: "format-detection", content: "telephone=no" },
|
||||||
|
{ hid: "og:title", content: "[ngn]" },
|
||||||
|
{ hid: "og:description", content: "ngn's (very cool) personal website" },
|
||||||
|
{ hid: "og:url", content: "https://ngn13.fun" },
|
||||||
|
{ name: "theme-color", content: "#0c16d1", "data-react-helmet":"true"},
|
||||||
|
],
|
||||||
|
link: [{ rel: "stylesheet", href: "https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css" }]
|
||||||
|
},
|
||||||
|
css: ["@/static/global.css"],
|
||||||
|
plugins: [],
|
||||||
|
components: true,
|
||||||
|
buildModules: [],
|
||||||
|
modules: ["@nuxtjs/axios"],
|
||||||
|
axios: {
|
||||||
|
baseURL: "/",
|
||||||
|
},
|
||||||
|
build: {},
|
||||||
|
serverMiddleware: {
|
||||||
|
"/api": "~/api",
|
||||||
|
},
|
||||||
|
};
|
25913
package-lock.json
generated
Normal file
25913
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
20
package.json
Normal file
20
package.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "my-website",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "nuxt",
|
||||||
|
"build": "nuxt build",
|
||||||
|
"start": "nuxt start",
|
||||||
|
"generate": "nuxt generate"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@nuxtjs/axios": "^5.13.6",
|
||||||
|
"core-js": "^3.25.3",
|
||||||
|
"express": "^4.18.2",
|
||||||
|
"nuxt": "^2.15.8",
|
||||||
|
"vue": "^2.7.10",
|
||||||
|
"vue-server-renderer": "^2.7.10",
|
||||||
|
"vue-template-compiler": "^2.7.10"
|
||||||
|
}
|
||||||
|
}
|
86
pages/index.vue
Normal file
86
pages/index.vue
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<Navbar />
|
||||||
|
<Header>
|
||||||
|
<glitch>echo</glitch> hello world!
|
||||||
|
</Header>
|
||||||
|
<div class="info">
|
||||||
|
<Card>
|
||||||
|
<h1>👋 Welcome to my website!</h1>
|
||||||
|
<h2>
|
||||||
|
I am a high school student who is interested in
|
||||||
|
<br>
|
||||||
|
• cyber security
|
||||||
|
<br>
|
||||||
|
• coding
|
||||||
|
<br>
|
||||||
|
• electronics
|
||||||
|
<br>
|
||||||
|
• simply: everything about computers!
|
||||||
|
</h2>
|
||||||
|
</Card>
|
||||||
|
<Card>
|
||||||
|
<h1>👉 Checkout my socials</h1>
|
||||||
|
<h2>Here you can find my socials for following platforms:</h2>
|
||||||
|
<br>
|
||||||
|
<a href="https://discord.com/users/568131907368386565"><i class='bx bxl-discord-alt'></i> Discord</a>
|
||||||
|
<br>
|
||||||
|
<a href="https://github.com/ngn13"><i class='bx bxl-github'></i> Github</a>
|
||||||
|
<br>
|
||||||
|
<a href="https://www.reddit.com/user/_ngn"><i class='bx bxl-reddit'></i> Reddit</a>
|
||||||
|
<br>
|
||||||
|
<a href="https://fosstodon.org/@ngn"><i class='bx bxl-mastodon'></i> Fosstodon</a>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
<Logout v-if="logged"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Navbar from "../components/Navbar.vue";
|
||||||
|
import Header from "../components/Header.vue";
|
||||||
|
import Card from "../components/Card.vue"
|
||||||
|
import Logout from "../components/Logout.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
head() {
|
||||||
|
return {
|
||||||
|
title: "[ngn]",
|
||||||
|
meta: [
|
||||||
|
{
|
||||||
|
hid: "description",
|
||||||
|
name: "description",
|
||||||
|
content: "ngn's Personal Website | Home Page"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
logged: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted(){
|
||||||
|
if(localStorage.getItem("token"))
|
||||||
|
this.logged = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.info {
|
||||||
|
padding: 50px;
|
||||||
|
gap: 30px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1076px) {
|
||||||
|
.info {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.info div {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
51
pages/login.vue
Normal file
51
pages/login.vue
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h1>Login Page</h1>
|
||||||
|
<Input :keyup="function() { }" placeholder="Password" type="password" id="pass"/>
|
||||||
|
<Button :click="click">Login</Button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Input from '../components/Input.vue';
|
||||||
|
import Button from '../components/Button.vue';
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
async click(e) {
|
||||||
|
const pass = document.getElementById("pass").value
|
||||||
|
const res = await axios.get(`/api/login?pass=${pass}`)
|
||||||
|
if(res.data["error"]===0){
|
||||||
|
localStorage.setItem("token", res.data["token"])
|
||||||
|
return location.href="/"
|
||||||
|
}
|
||||||
|
alert("Incorrect password!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
div {
|
||||||
|
padding: 50px;
|
||||||
|
background: var(--dark-three);
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
margin: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 20px;
|
||||||
|
color: var(--white);
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1{
|
||||||
|
font-size: 70px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
73
pages/projects.vue
Normal file
73
pages/projects.vue
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<Navbar />
|
||||||
|
<Header>
|
||||||
|
<glitch>ls -la</glitch> projects
|
||||||
|
</Header>
|
||||||
|
<div class="projects">
|
||||||
|
<ProjectList v-for="project in projects" :key="project">
|
||||||
|
<Project v-for="p in project" :key="p" :name="p.name" :desc="p.desc" :url="p.url"/>
|
||||||
|
</ProjectList>
|
||||||
|
</div>
|
||||||
|
<NewProject v-if="logged"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ProjectList from "../components/ProjectList.vue";
|
||||||
|
import Project from "../components/Project.vue";
|
||||||
|
import NewProject from "../components/NewProject.vue";
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
head() {
|
||||||
|
return {
|
||||||
|
title: "[ngn]",
|
||||||
|
meta: [
|
||||||
|
{
|
||||||
|
hid: "description",
|
||||||
|
name: "description",
|
||||||
|
content: "ngn's Personal Website | Projects Page"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
logged: false,
|
||||||
|
projects: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted: async function(){
|
||||||
|
if(localStorage.getItem("token"))
|
||||||
|
this.logged = true
|
||||||
|
|
||||||
|
const res = await axios.get("/api/get_projects")
|
||||||
|
|
||||||
|
let all = res.data["projects"]
|
||||||
|
let projects = []
|
||||||
|
let project = []
|
||||||
|
for(let i = 0; i<all.length; i++){
|
||||||
|
if(project.length!==3)
|
||||||
|
project.push(all[i])
|
||||||
|
else{
|
||||||
|
projects.push(project)
|
||||||
|
project = []
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i===all.length-1){
|
||||||
|
projects.push(project)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.projects = projects
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.projects{
|
||||||
|
margin-top: 20px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
</style>
|
76
pages/resources.vue
Normal file
76
pages/resources.vue
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<template>
|
||||||
|
<main>
|
||||||
|
<Navbar />
|
||||||
|
<Header>
|
||||||
|
<glitch>cat</glitch> {{ header }}
|
||||||
|
</Header>
|
||||||
|
<div class="resources">
|
||||||
|
<Input :keyup="keyup" placeholder="Search resource" type="text"/>
|
||||||
|
<Resource v-for="resource in resources" :key="resource" :name="resource.name" :tags="resource.tags" :url="resource.url" />
|
||||||
|
</div>
|
||||||
|
<NewResource v-if="logged"/>
|
||||||
|
</main>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import axios from 'axios';
|
||||||
|
import Resource from '../components/Resource.vue';
|
||||||
|
import Input from '../components/Input.vue';
|
||||||
|
import NewResource from '../components/NewResource.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
header: "resources",
|
||||||
|
logged: false,
|
||||||
|
resources: [],
|
||||||
|
all: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
keyup(e) {
|
||||||
|
let val = e.target.value
|
||||||
|
if(e.key==="Backspace" && val===""){
|
||||||
|
this.header = "resources"
|
||||||
|
this.resources = this.all
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(e.key==="OS")
|
||||||
|
return
|
||||||
|
this.header = `resources | grep ${val}`
|
||||||
|
|
||||||
|
// dirty asf search alg
|
||||||
|
this.resources = []
|
||||||
|
for(let i = 0; i < this.all.length; i++){
|
||||||
|
if(this.all[i].name.toLowerCase().includes(val.toLowerCase()))
|
||||||
|
this.resources.push(this.all[i])
|
||||||
|
|
||||||
|
for(let e = 0; e < this.all[i].tags.length; e++){
|
||||||
|
if(this.all[i].tags[e].toLowerCase().includes(val.toLowerCase())){
|
||||||
|
if(this.resources.indexOf(this.all[i])===-1)
|
||||||
|
this.resources.push(this.all[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted: async function(){
|
||||||
|
if(localStorage.getItem("token"))
|
||||||
|
this.logged = true
|
||||||
|
|
||||||
|
const res = await axios.get("/api/get_resources")
|
||||||
|
this.resources = res.data["resources"]
|
||||||
|
this.all = res.data["resources"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.resources {
|
||||||
|
padding: 50px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 40px
|
||||||
|
}
|
||||||
|
</style>
|
BIN
static/Minecraft.ttf
Normal file
BIN
static/Minecraft.ttf
Normal file
Binary file not shown.
315
static/global.css
Normal file
315
static/global.css
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
@import url("https://fonts.googleapis.com/css2?family=Ubuntu:wght@300&display=swap");
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--white: white;
|
||||||
|
--dark-one: #141414;
|
||||||
|
--dark-two: #18191a;
|
||||||
|
--dark-three: #282828;
|
||||||
|
--dark-four: #242526;
|
||||||
|
--dark-fife: #3a3b3c;
|
||||||
|
--border-rad: 30px;
|
||||||
|
--def-shadow: rgba(0, 0, 0, 0.25) 0px 54px 55px,
|
||||||
|
rgba(0, 0, 0, 0.12) 0px -12px 30px, rgba(0, 0, 0, 0.12) 0px 4px 6px,
|
||||||
|
rgba(0, 0, 0, 0.17) 0px 12px 13px, rgba(0, 0, 0, 0.09) 0px -3px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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: #141414;
|
||||||
|
font-family: "Ubuntu", sans-serif;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
border-radius: 10px;
|
||||||
|
width: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #181818;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #282828;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes colorAnimation {
|
||||||
|
100%,
|
||||||
|
0% {
|
||||||
|
color: rgb(255, 0, 0);
|
||||||
|
}
|
||||||
|
8% {
|
||||||
|
color: rgb(255, 127, 0);
|
||||||
|
}
|
||||||
|
16% {
|
||||||
|
color: rgb(255, 255, 0);
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
color: rgb(127, 255, 0);
|
||||||
|
}
|
||||||
|
33% {
|
||||||
|
color: rgb(0, 255, 0);
|
||||||
|
}
|
||||||
|
41% {
|
||||||
|
color: rgb(0, 255, 127);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
color: rgb(0, 255, 255);
|
||||||
|
}
|
||||||
|
58% {
|
||||||
|
color: rgb(0, 127, 255);
|
||||||
|
}
|
||||||
|
66% {
|
||||||
|
color: rgb(0, 0, 255);
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
color: rgb(127, 0, 255);
|
||||||
|
}
|
||||||
|
83% {
|
||||||
|
color: rgb(255, 0, 255);
|
||||||
|
}
|
||||||
|
91% {
|
||||||
|
color: rgb(255, 0, 127);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes borderAnimation {
|
||||||
|
100%,
|
||||||
|
0% {
|
||||||
|
border-bottom-color: rgb(255, 0, 0);
|
||||||
|
}
|
||||||
|
8% {
|
||||||
|
border-bottom-color: rgb(255, 127, 0);
|
||||||
|
}
|
||||||
|
16% {
|
||||||
|
border-bottom-color: rgb(255, 255, 0);
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
border-bottom-color: rgb(127, 255, 0);
|
||||||
|
}
|
||||||
|
33% {
|
||||||
|
border-bottom-color: rgb(0, 255, 0);
|
||||||
|
}
|
||||||
|
41% {
|
||||||
|
border-bottom-color: rgb(0, 255, 127);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
border-bottom-color: rgb(0, 255, 255);
|
||||||
|
}
|
||||||
|
58% {
|
||||||
|
border-bottom-color: rgb(0, 127, 255);
|
||||||
|
}
|
||||||
|
66% {
|
||||||
|
border-bottom-color: rgb(0, 0, 255);
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
border-bottom-color: rgb(127, 0, 255);
|
||||||
|
}
|
||||||
|
83% {
|
||||||
|
border-bottom-color: rgb(255, 0, 255);
|
||||||
|
}
|
||||||
|
91% {
|
||||||
|
border-bottom-color: rgb(255, 0, 127);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fullBorderAnimation {
|
||||||
|
100%,
|
||||||
|
0% {
|
||||||
|
border-color: rgb(255, 0, 0);
|
||||||
|
}
|
||||||
|
8% {
|
||||||
|
border-color: rgb(255, 127, 0);
|
||||||
|
}
|
||||||
|
16% {
|
||||||
|
border-color: rgb(255, 255, 0);
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
border-color: rgb(127, 255, 0);
|
||||||
|
}
|
||||||
|
33% {
|
||||||
|
border-color: rgb(0, 255, 0);
|
||||||
|
}
|
||||||
|
41% {
|
||||||
|
border-color: rgb(0, 255, 127);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
border-color: rgb(0, 255, 255);
|
||||||
|
}
|
||||||
|
58% {
|
||||||
|
border-color: rgb(0, 127, 255);
|
||||||
|
}
|
||||||
|
66% {
|
||||||
|
border-color: rgb(0, 0, 255);
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
border-color: rgb(127, 0, 255);
|
||||||
|
}
|
||||||
|
83% {
|
||||||
|
border-color: rgb(255, 0, 255);
|
||||||
|
}
|
||||||
|
91% {
|
||||||
|
border-color: rgb(255, 0, 127);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes gayShadowAnimation {
|
||||||
|
100%,
|
||||||
|
0% {
|
||||||
|
box-shadow: rgba(255, 0, 0, 0.07) 0px 1px 2px,
|
||||||
|
rgba(255, 0, 0, 0.07) 0px 2px 4px, rgba(255, 0, 0, 0.07) 0px 4px 8px,
|
||||||
|
rgba(255, 0, 0, 0.07) 0px 8px 16px, rgba(255, 0, 0, 0.07) 0px 16px 32px,
|
||||||
|
rgba(255, 0, 0, 0.07) 0px 32px 64px;
|
||||||
|
}
|
||||||
|
8% {
|
||||||
|
box-shadow: rgba(255, 127, 0, 0.07) 0px 1px 2px,
|
||||||
|
rgba(255, 127, 0, 0.07) 0px 2px 4px, rgba(255, 127, 0, 0.07) 0px 4px 8px,
|
||||||
|
rgba(255, 127, 0, 0.07) 0px 8px 16px,
|
||||||
|
rgba(255, 127, 0, 0.07) 0px 16px 32px,
|
||||||
|
rgba(255, 127, 0, 0.07) 0px 32px 64px;
|
||||||
|
}
|
||||||
|
16% {
|
||||||
|
box-shadow: rgba(255, 255, 0, 0.07) 0px 1px 2px,
|
||||||
|
rgba(255, 255, 0, 0.07) 0px 2px 4px, rgba(255, 255, 0, 0.07) 0px 4px 8px,
|
||||||
|
rgba(255, 255, 0, 0.07) 0px 8px 16px,
|
||||||
|
rgba(255, 255, 0, 0.07) 0px 16px 32px,
|
||||||
|
rgba(255, 255, 0, 0.07) 0px 32px 64px;
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
box-shadow: rgba(127, 255, 0, 0.07) 0px 1px 2px,
|
||||||
|
rgba(127, 255, 0, 0.07) 0px 2px 4px, rgba(127, 255, 0, 0.07) 0px 4px 8px,
|
||||||
|
rgba(127, 255, 0, 0.07) 0px 8px 16px,
|
||||||
|
rgba(127, 255, 0, 0.07) 0px 16px 32px,
|
||||||
|
rgba(127, 255, 0, 0.07) 0px 32px 64px;
|
||||||
|
}
|
||||||
|
33% {
|
||||||
|
box-shadow: rgba(0, 255, 0, 0.07) 0px 1px 2px,
|
||||||
|
rgba(0, 255, 0, 0.07) 0px 2px 4px, rgba(0, 255, 0, 0.07) 0px 4px 8px,
|
||||||
|
rgba(0, 255, 0, 0.07) 0px 8px 16px, rgba(0, 255, 0, 0.07) 0px 16px 32px,
|
||||||
|
rgba(0, 255, 0, 0.07) 0px 32px 64px;
|
||||||
|
}
|
||||||
|
41% {
|
||||||
|
box-shadow: rgba(0, 255, 127, 0.07) 0px 1px 2px,
|
||||||
|
rgba(0, 255, 127, 0.07) 0px 2px 4px, rgba(0, 255, 127, 0.07) 0px 4px 8px,
|
||||||
|
rgba(0, 255, 127, 0.07) 0px 8px 16px,
|
||||||
|
rgba(0, 255, 127, 0.07) 0px 16px 32px,
|
||||||
|
rgba(0, 255, 127, 0.07) 0px 32px 64px;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
box-shadow: rgba(0, 255, 255, 0.07) 0px 1px 2px,
|
||||||
|
rgba(0, 255, 255, 0.07) 0px 2px 4px, rgba(0, 255, 255, 0.07) 0px 4px 8px,
|
||||||
|
rgba(0, 255, 255, 0.07) 0px 8px 16px,
|
||||||
|
rgba(0, 255, 255, 0.07) 0px 16px 32px,
|
||||||
|
rgba(0, 255, 255, 0.07) 0px 32px 64px;
|
||||||
|
}
|
||||||
|
58% {
|
||||||
|
box-shadow: rgba(0, 127, 255, 0.07) 0px 1px 2px,
|
||||||
|
rgba(0, 127, 255, 0.07) 0px 2px 4px, rgba(0, 127, 255, 0.07) 0px 4px 8px,
|
||||||
|
rgba(0, 127, 255, 0.07) 0px 8px 16px,
|
||||||
|
rgba(0, 127, 255, 0.07) 0px 16px 32px,
|
||||||
|
rgba(0, 127, 255, 0.07) 0px 32px 64px;
|
||||||
|
}
|
||||||
|
66% {
|
||||||
|
box-shadow: rgba(0, 0, 255, 0.07) 0px 1px 2px,
|
||||||
|
rgba(0, 0, 255, 0.07) 0px 2px 4px, rgba(0, 0, 255, 0.07) 0px 4px 8px,
|
||||||
|
rgba(0, 0, 255, 0.07) 0px 8px 16px, rgba(0, 0, 255, 0.07) 0px 16px 32px,
|
||||||
|
rgba(0, 0, 255, 0.07) 0px 32px 64px;
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
box-shadow: rgba(127, 0, 255, 0.07) 0px 1px 2px,
|
||||||
|
rgba(127, 0, 255, 0.07) 0px 2px 4px, rgba(127, 0, 255, 0.07) 0px 4px 8px,
|
||||||
|
rgba(127, 0, 255, 0.07) 0px 8px 16px,
|
||||||
|
rgba(127, 0, 255, 0.07) 0px 16px 32px,
|
||||||
|
rgba(127, 0, 255, 0.07) 0px 32px 64px;
|
||||||
|
}
|
||||||
|
83% {
|
||||||
|
box-shadow: rgba(255, 0, 255, 0.07) 0px 1px 2px,
|
||||||
|
rgba(255, 0, 255, 0.07) 0px 2px 4px, rgba(255, 0, 255, 0.07) 0px 4px 8px,
|
||||||
|
rgba(255, 0, 255, 0.07) 0px 8px 16px,
|
||||||
|
rgba(255, 0, 255, 0.07) 0px 16px 32px,
|
||||||
|
rgba(255, 0, 255, 0.07) 0px 32px 64px;
|
||||||
|
}
|
||||||
|
91% {
|
||||||
|
box-shadow: rgba(255, 0, 127, 0.07) 0px 1px 2px,
|
||||||
|
rgba(255, 0, 127, 0.07) 0px 2px 4px, rgba(255, 0, 127, 0.07) 0px 4px 8px,
|
||||||
|
rgba(255, 0, 127, 0.07) 0px 8px 16px,
|
||||||
|
rgba(255, 0, 127, 0.07) 0px 16px 32px,
|
||||||
|
rgba(255, 0, 127, 0.07) 0px 32px 64px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes underlineAnimation {
|
||||||
|
100%,
|
||||||
|
0% {
|
||||||
|
text-decoration-color: rgb(255, 0, 0);
|
||||||
|
}
|
||||||
|
8% {
|
||||||
|
text-decoration-color: rgb(255, 127, 0);
|
||||||
|
}
|
||||||
|
16% {
|
||||||
|
text-decoration-color: rgb(255, 255, 0);
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
text-decoration-color: rgb(127, 255, 0);
|
||||||
|
}
|
||||||
|
33% {
|
||||||
|
text-decoration-color: rgb(0, 255, 0);
|
||||||
|
}
|
||||||
|
41% {
|
||||||
|
text-decoration-color: rgb(0, 255, 127);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
text-decoration-color: rgb(0, 255, 255);
|
||||||
|
}
|
||||||
|
58% {
|
||||||
|
text-decoration-color: rgb(0, 127, 255);
|
||||||
|
}
|
||||||
|
66% {
|
||||||
|
text-decoration-color: rgb(0, 0, 255);
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
text-decoration-color: rgb(127, 0, 255);
|
||||||
|
}
|
||||||
|
83% {
|
||||||
|
text-decoration-color: rgb(255, 0, 255);
|
||||||
|
}
|
||||||
|
91% {
|
||||||
|
text-decoration-color: rgb(255, 0, 127);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes minecraftAnimation {
|
||||||
|
0%{
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
50%{
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
|
100%{
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Minecraft";
|
||||||
|
src: url("/Minecraft.ttf") format("opentype");
|
||||||
|
}
|
||||||
|
|
||||||
|
glitch {
|
||||||
|
animation-name: colorAnimation;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-duration: 10s;
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user