fixing database connections and patching possible nosqli
This commit is contained in:
parent
ad6b29be01
commit
d42990db29
1
.prettierignore
Normal file
1
.prettierignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
.nuxt
|
6
.prettierrc.json
Normal file
6
.prettierrc.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"trailingComma": "none",
|
||||||
|
"tabWidth": 2,
|
||||||
|
"semi": false,
|
||||||
|
"singleQuote": false
|
||||||
|
}
|
@ -1,9 +1,11 @@
|
|||||||
# My Website - [ngn13.fun](https://ngn13.fun)
|
# My Website - [ngn13.fun](https://ngn13.fun)
|
||||||
|
|
||||||
This repo contains the source code of my personal website.
|
This repo contains the source code of my personal website.
|
||||||
It's written NuxtJS and supports full SSR. As database,
|
It's written NuxtJS and supports full SSR. As database,
|
||||||
it uses mongodb.
|
it uses mongodb.
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
```
|
```
|
||||||
git clone https://github.com/ngn13/ngn13.fun.git
|
git clone https://github.com/ngn13/ngn13.fun.git
|
||||||
cd ngn13.fun && npm i
|
cd ngn13.fun && npm i
|
||||||
|
31
api/index.js
31
api/index.js
@ -7,15 +7,16 @@ require("dotenv").config()
|
|||||||
* error: 1 -> parameter error
|
* error: 1 -> parameter error
|
||||||
* error: 2 -> auth error
|
* error: 2 -> auth error
|
||||||
* error: 3 -> not found error
|
* error: 3 -> not found error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const db = new MongoClient(process.env.DATABASE);
|
const db = new MongoClient(process.env.DATABASE)
|
||||||
const app = express()
|
const app = express()
|
||||||
app.use(express.json())
|
app.use(express.json())
|
||||||
app.use(express.urlencoded({ extended: false }));
|
app.use(express.urlencoded({ extended: false }))
|
||||||
app.use((req,res,next)=>{
|
app.use(async (req, res, next) => {
|
||||||
req.db = db
|
await db.connect()
|
||||||
next()
|
req.db = db
|
||||||
|
next()
|
||||||
})
|
})
|
||||||
|
|
||||||
const { auth, authware } = require("./routes/auth.js")
|
const { auth, authware } = require("./routes/auth.js")
|
||||||
@ -25,19 +26,21 @@ app.use("/*/a*", authware)
|
|||||||
const resources = require("./routes/resources.js")
|
const resources = require("./routes/resources.js")
|
||||||
const projects = require("./routes/projects.js")
|
const projects = require("./routes/projects.js")
|
||||||
const blog = require("./routes/blog.js")
|
const blog = require("./routes/blog.js")
|
||||||
const routes = [
|
const routes = [resources, projects, blog, auth]
|
||||||
resources,
|
|
||||||
projects,
|
|
||||||
blog,
|
|
||||||
auth,
|
|
||||||
]
|
|
||||||
|
|
||||||
routes.forEach(route=>{
|
routes.forEach((route) => {
|
||||||
app.use(route.path, route)
|
app.use(route.path, route)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
async function pexit() {
|
||||||
|
await db.close()
|
||||||
|
process.exit()
|
||||||
|
}
|
||||||
|
|
||||||
|
process.on("SIGTERM", pexit)
|
||||||
|
process.on("SIGINT", pexit)
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
path: "/api",
|
path: "/api",
|
||||||
handler: app,
|
handler: app
|
||||||
}
|
}
|
||||||
|
@ -4,34 +4,30 @@ const auth = express.Router()
|
|||||||
auth.path = "/auth"
|
auth.path = "/auth"
|
||||||
|
|
||||||
const PASS = process.env.PASS
|
const PASS = process.env.PASS
|
||||||
let TOKEN = gimmeToken();
|
let TOKEN = gimmeToken()
|
||||||
|
|
||||||
function authware(req,res,next){
|
function authware(req, res, next) {
|
||||||
const token = req.query.token ? req.query.token : req.body.token
|
const token = req.query.token ? req.query.token : req.body.token
|
||||||
|
|
||||||
if(!token)
|
if (typeof token !== "string") return res.json({ error: 1 })
|
||||||
return res.json({ error: 1 })
|
|
||||||
|
|
||||||
if(token!==TOKEN)
|
if (token !== TOKEN) return res.json({ error: 2 })
|
||||||
return res.json({ error: 2 })
|
|
||||||
|
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
auth.use("/logout", authware)
|
auth.use("/logout", authware)
|
||||||
|
|
||||||
auth.get("/login", async (req,res)=>{
|
auth.get("/login", async (req, res) => {
|
||||||
const pass = req.query.pass
|
const pass = req.query.pass
|
||||||
|
|
||||||
if(!pass)
|
if (typeof pass !== "string") return res.json({ error: 1 })
|
||||||
return res.json({ error: 1 })
|
|
||||||
|
|
||||||
if(pass!==PASS)
|
if (pass !== PASS) return res.json({ error: 2 })
|
||||||
return res.json({ error: 2 })
|
|
||||||
|
|
||||||
res.json({ error: 0, token: TOKEN })
|
res.json({ error: 0, token: TOKEN })
|
||||||
})
|
})
|
||||||
|
|
||||||
auth.get("/logout", async (req,res)=>{
|
auth.get("/logout", async (req, res) => {
|
||||||
TOKEN = gimmeToken()
|
TOKEN = gimmeToken()
|
||||||
res.json({ error: 0 })
|
res.json({ error: 0 })
|
||||||
})
|
})
|
||||||
|
@ -3,25 +3,23 @@ const { makeID } = require("../util.js")
|
|||||||
const blog = express.Router()
|
const blog = express.Router()
|
||||||
blog.path = "/blog"
|
blog.path = "/blog"
|
||||||
|
|
||||||
blog.get("/sum", async (req,res)=>{
|
blog.get("/sum", async (req, res) => {
|
||||||
await req.db.connect()
|
const db = req.db.db("ngn13")
|
||||||
const db = await req.db.db("ngn13")
|
const col = db.collection("posts")
|
||||||
const col = await db.collection("posts")
|
const results = await col.find({ priv: { $eq: false } }).toArray()
|
||||||
const results = await col.find({priv: {$eq: false}}).toArray()
|
|
||||||
await req.db.close()
|
|
||||||
|
|
||||||
let posts = []
|
let posts = []
|
||||||
for(let i = 0;i<results.length;i++){
|
for (let i = 0; i < results.length; i++) {
|
||||||
posts.push({
|
posts.push({
|
||||||
"title":results[i]["title"],
|
title: results[i]["title"],
|
||||||
"desc":results[i]["content"]
|
desc:
|
||||||
.substring(0, 140) // a short desc
|
results[i]["content"]
|
||||||
.replaceAll("#", "") // remove all the markdown stuff
|
.substring(0, 140) // a short desc
|
||||||
.replaceAll("*", "")
|
.replaceAll("#", "") // remove all the markdown stuff
|
||||||
.replaceAll("`", "")
|
.replaceAll("*", "")
|
||||||
.replaceAll("-", "")
|
.replaceAll("`", "")
|
||||||
+ "...", // add "..." to make it look like desc
|
.replaceAll("-", "") + "...", // add "..." to make it look like desc
|
||||||
"info":`${results[i]["author"]} | ${results[i]["date"]}`
|
info: `${results[i]["author"]} | ${results[i]["date"]}`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,63 +28,59 @@ blog.get("/sum", async (req,res)=>{
|
|||||||
res.json({ error: 0, posts: posts.reverse() })
|
res.json({ error: 0, posts: posts.reverse() })
|
||||||
})
|
})
|
||||||
|
|
||||||
blog.get("/get", async (req,res)=>{
|
blog.get("/get", async (req, res) => {
|
||||||
const id = req.query.id
|
const id = req.query.id
|
||||||
|
|
||||||
await req.db.connect()
|
const db = req.db.db("ngn13")
|
||||||
const db = await req.db.db("ngn13")
|
const col = db.collection("posts")
|
||||||
const col = await db.collection("posts")
|
|
||||||
const results = await col.find().toArray()
|
const results = await col.find().toArray()
|
||||||
await req.db.close()
|
|
||||||
|
|
||||||
for(let i = 0;i<results.length;i++){
|
for (let i = 0; i < results.length; i++) {
|
||||||
// id is basically the title of the post
|
// id is basically the title of the post
|
||||||
// but ve remove the whitespace
|
// but ve remove the whitespace
|
||||||
// and make it lowerspace
|
// and make it lowerspace
|
||||||
// for example:
|
// for example:
|
||||||
// Online Privacy Guide -> onlineprivacyguide
|
// Online Privacy Guide -> onlineprivacyguide
|
||||||
if(makeID(results[i]["title"])===id){
|
if (makeID(results[i]["title"]) === id) {
|
||||||
return res.json(
|
return res.json({
|
||||||
{
|
error: 0,
|
||||||
error: 0,
|
post: {
|
||||||
post:{
|
title: results[i]["title"],
|
||||||
"title": results[i]["title"],
|
// info is the subtitle, for example:
|
||||||
// info is the subtitle, for example:
|
// ngn | 01/06/2023
|
||||||
// ngn | 01/06/2023
|
info: `${results[i]["author"]} | ${results[i]["date"]}`,
|
||||||
"info": `${results[i]["author"]} | ${results[i]["date"]}`,
|
content: results[i]["content"]
|
||||||
"content": results[i]["content"],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json({ error: 3 })
|
res.json({ error: 3 })
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
blog.post("/add", async (req,res)=>{
|
blog.post("/add", async (req, res) => {
|
||||||
console.log("heyy")
|
|
||||||
const title = req.body.title
|
const title = req.body.title
|
||||||
const author = req.body.author
|
const author = req.body.author
|
||||||
const content = req.body.content
|
const content = req.body.content
|
||||||
const priv = req.body.priv
|
const priv = req.body.priv
|
||||||
console.log(title, author, content, priv)
|
|
||||||
|
|
||||||
if ( !title || !author || !content || !priv )
|
if (
|
||||||
|
typeof title !== "string" ||
|
||||||
|
typeof author !== "string" ||
|
||||||
|
typeof content !== "string" ||
|
||||||
|
typeof priv !== "string"
|
||||||
|
)
|
||||||
return res.json({ error: 1 })
|
return res.json({ error: 1 })
|
||||||
|
|
||||||
await req.db.connect()
|
const db = req.db.db("ngn13")
|
||||||
const db = await req.db.db("ngn13")
|
const col = db.collection("posts")
|
||||||
const col = await db.collection("posts")
|
|
||||||
await col.insertOne({
|
await col.insertOne({
|
||||||
"title":title,
|
title: title,
|
||||||
"author":author,
|
author: author,
|
||||||
"date": new Date().toLocaleDateString(),
|
date: new Date().toLocaleDateString(),
|
||||||
"content":content,
|
content: content,
|
||||||
"priv": priv
|
priv: priv
|
||||||
})
|
})
|
||||||
await req.db.close()
|
|
||||||
res.json({ error: 0 })
|
res.json({ error: 0 })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -2,33 +2,33 @@ const express = require("express")
|
|||||||
const projects = express.Router()
|
const projects = express.Router()
|
||||||
projects.path = "/projects"
|
projects.path = "/projects"
|
||||||
|
|
||||||
projects.get("/get", async (req,res)=>{
|
projects.get("/get", async (req, res) => {
|
||||||
await req.db.connect()
|
const db = req.db.db("ngn13")
|
||||||
const db = await req.db.db("ngn13")
|
const col = db.collection("projects")
|
||||||
const col = await db.collection("projects")
|
|
||||||
const results = await col.find().toArray()
|
const results = await col.find().toArray()
|
||||||
await req.db.close()
|
|
||||||
res.json({ error: 0, projects: results })
|
res.json({ error: 0, projects: results })
|
||||||
})
|
})
|
||||||
|
|
||||||
projects.get("/add", async (req,res)=>{
|
projects.get("/add", async (req, res) => {
|
||||||
let name = req.query.name;
|
let name = req.query.name
|
||||||
let desc = req.query.desc;
|
let desc = req.query.desc
|
||||||
let url = req.query.url;
|
let url = req.query.url
|
||||||
|
|
||||||
if (!name || !desc || !url )
|
if (
|
||||||
|
typeof name !== "string" ||
|
||||||
|
typeof desc !== "string" ||
|
||||||
|
typeof url !== "string"
|
||||||
|
)
|
||||||
return res.json({ error: 1 })
|
return res.json({ error: 1 })
|
||||||
|
|
||||||
await req.db.connect()
|
const db = req.db.db("ngn13")
|
||||||
const db = await req.db.db("ngn13")
|
const col = db.collection("projects")
|
||||||
const col = await db.collection("projects")
|
|
||||||
await col.insertOne({
|
await col.insertOne({
|
||||||
"name":name,
|
name: name,
|
||||||
"desc":desc,
|
desc: desc,
|
||||||
"url":url,
|
url: url,
|
||||||
"click":0
|
click: 0
|
||||||
})
|
})
|
||||||
await req.db.close()
|
|
||||||
res.json({ error: 0 })
|
res.json({ error: 0 })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -2,33 +2,31 @@ const express = require("express")
|
|||||||
const resources = express.Router()
|
const resources = express.Router()
|
||||||
resources.path = "/resources"
|
resources.path = "/resources"
|
||||||
|
|
||||||
resources.get("/get", async (req,res)=>{
|
resources.get("/get", async (req, res) => {
|
||||||
await req.db.connect()
|
const db = req.db.db("ngn13")
|
||||||
const db = await req.db.db("ngn13")
|
const col = db.collection("resources")
|
||||||
const col = await db.collection("resources")
|
|
||||||
let results = []
|
let results = []
|
||||||
if(req.query.sum)
|
if (req.query.sum) results = await col.find().limit(10).toArray()
|
||||||
results = await col.find().limit(10).toArray()
|
else results = await col.find().toArray()
|
||||||
else
|
res.json({ error: 0, resources: results.reverse() })
|
||||||
results = await col.find().toArray()
|
|
||||||
await req.db.close()
|
|
||||||
res.json({ error: 0, resources: results })
|
|
||||||
})
|
})
|
||||||
|
|
||||||
resources.get("/add", async (req,res)=>{
|
resources.get("/add", async (req, res) => {
|
||||||
let name = req.query.name;
|
let name = req.query.name
|
||||||
let tags = req.query.tags;
|
let tags = req.query.tags
|
||||||
let url = req.query.url;
|
let url = req.query.url
|
||||||
|
|
||||||
if(!name || !tags || !url)
|
if (
|
||||||
return res.json({"error":1})
|
typeof name !== "string" ||
|
||||||
|
typeof tags !== "string" ||
|
||||||
|
typeof url !== "string"
|
||||||
|
)
|
||||||
|
return res.json({ error: 1 })
|
||||||
|
|
||||||
await req.db.connect()
|
const db = req.db.db("ngn13")
|
||||||
const db = await req.db.db("ngn13")
|
const col = db.collection("resources")
|
||||||
const col = await db.collection("resources")
|
await col.insertOne({ name: name, tags: tags.split(","), url: url })
|
||||||
await col.insertOne({"name":name, "tags":tags.split(","), "url":url})
|
res.json({ error: 0 })
|
||||||
await req.db.close()
|
|
||||||
res.json({error: 0})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
module.exports = resources
|
module.exports = resources
|
||||||
|
18
api/util.js
18
api/util.js
@ -1,14 +1,15 @@
|
|||||||
function gimmeToken() {
|
function gimmeToken() {
|
||||||
var result = ""
|
var result = ""
|
||||||
var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
var characters =
|
||||||
var charactersLength = characters.length
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||||
for ( var i = 0; i < 32; i++ ) {
|
var charactersLength = characters.length
|
||||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
for (var i = 0; i < 32; i++) {
|
||||||
}
|
result += characters.charAt(Math.floor(Math.random() * charactersLength))
|
||||||
return result;
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeID(title){
|
function makeID(title) {
|
||||||
// this is used in blog.js
|
// this is used in blog.js
|
||||||
// id is basically the title of the post
|
// id is basically the title of the post
|
||||||
// but ve remove the whitespace
|
// but ve remove the whitespace
|
||||||
@ -19,4 +20,3 @@ function makeID(title){
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { gimmeToken, makeID }
|
module.exports = { gimmeToken, makeID }
|
||||||
|
|
||||||
|
@ -1,29 +1,29 @@
|
|||||||
<template>
|
<template>
|
||||||
<button @click="click"><slot></slot></button>
|
<button @click="click"><slot></slot></button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: ["click"]
|
props: ["click"]
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
button {
|
button {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 540px;
|
width: 540px;
|
||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
background: var(--dark-two);
|
background: var(--dark-two);
|
||||||
border: none;
|
border: none;
|
||||||
color: white;
|
color: white;
|
||||||
outline: none;
|
outline: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: .4s;
|
transition: 0.4s;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:hover {
|
button:hover {
|
||||||
box-shadow: var(--def-shadow);
|
box-shadow: var(--def-shadow);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -1,56 +1,54 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {}
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
div {
|
div {
|
||||||
box-shadow: var(--def-shadow);
|
box-shadow: var(--def-shadow);
|
||||||
background: var(--dark-two);
|
background: var(--dark-two);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
padding: 50px;
|
padding: 50px;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
text-shadow: 3px 4px 7px rgba(81, 67, 21, 0.8);
|
text-shadow: 3px 4px 7px rgba(81, 67, 21, 0.8);
|
||||||
font-size: 50px;
|
font-size: 50px;
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
i {
|
i {
|
||||||
animation-name: colorAnimation;
|
animation-name: colorAnimation;
|
||||||
animation-duration: 10s;
|
animation-duration: 10s;
|
||||||
animation-iteration-count: infinite;
|
animation-iteration-count: infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
}
|
}
|
||||||
|
|
||||||
i {
|
i {
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
margin-top: 3px;
|
margin-top: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 40px;
|
font-size: 40px;
|
||||||
line-height: 60px;
|
line-height: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
font-size: 40px;
|
font-size: 40px;
|
||||||
color: white;
|
color: white;
|
||||||
line-height: 60px;
|
line-height: 60px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -1,31 +1,30 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<h1>
|
<h1>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {}
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
div {
|
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");
|
background: linear-gradient(rgba(3, 3, 3, 0.706), rgba(22, 22, 22, 0.808)),
|
||||||
width: 100%;
|
url("https://www.sketchappsources.com/resources/source-image/tv-glitch-sureshmurali29.png");
|
||||||
height: 100%;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
font-size: 7.5vw;
|
font-size: 7.5vw;
|
||||||
padding: 150px;
|
padding: 150px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: white;
|
color: white;
|
||||||
text-shadow: 3px 4px 7px rgba(81, 67, 21, 0.8);
|
text-shadow: 3px 4px 7px rgba(81, 67, 21, 0.8);
|
||||||
text-size-adjust: 80%;
|
text-size-adjust: 80%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -1,27 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<input v-on:keyup="keyup" :placeholder="placeholder" :type="type">
|
<input v-on:keyup="keyup" :placeholder="placeholder" :type="type" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props:["keyup", "placeholder", "type"]
|
props: ["keyup", "placeholder", "type"]
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
input {
|
input {
|
||||||
width: 500px;
|
width: 500px;
|
||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
background: var(--dark-two);
|
background: var(--dark-two);
|
||||||
border: none;
|
border: none;
|
||||||
color: white;
|
color: white;
|
||||||
outline: none;
|
outline: none;
|
||||||
transition: .4s;
|
transition: 0.4s;
|
||||||
}
|
}
|
||||||
|
|
||||||
input:focus {
|
input:focus {
|
||||||
box-shadow: var(--def-shadow);
|
box-shadow: var(--def-shadow);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,41 +1,41 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<h1>Currently logged in</h1>
|
<h1>Currently logged in</h1>
|
||||||
<Button :click="click">Logout</Button>
|
<Button :click="click">Logout</Button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import axios from 'axios';
|
import axios from "axios"
|
||||||
import Button from './Button.vue';
|
import Button from "./Button.vue"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
methods: {
|
methods: {
|
||||||
async click(e) {
|
async click(e) {
|
||||||
await axios.get(`/api/auth/logout?token=${localStorage.getItem("token")}`)
|
await axios.get(`/api/auth/logout?token=${localStorage.getItem("token")}`)
|
||||||
localStorage.clear()
|
localStorage.clear()
|
||||||
location.reload()
|
location.reload()
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
h1{
|
h1 {
|
||||||
color: var(--white);
|
color: var(--white);
|
||||||
font-size: 50px;
|
font-size: 50px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
div{
|
div {
|
||||||
background-color: var(--dark-three);
|
background-color: var(--dark-three);
|
||||||
padding: 50px;
|
padding: 50px;
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,53 +1,55 @@
|
|||||||
<template>
|
<template>
|
||||||
<nav>
|
<nav>
|
||||||
<div>
|
<div>
|
||||||
<h3>[ngn]</h3>
|
<h3>[ngn]</h3>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<NavbarLink :out="false" url="/">Home</NavbarLink>
|
<NavbarLink :out="false" url="/">Home</NavbarLink>
|
||||||
<NavbarLink :out="false" url="/projects">Projects</NavbarLink>
|
<NavbarLink :out="false" url="/projects">Projects</NavbarLink>
|
||||||
<NavbarLink :out="false" url="/resources">Resources</NavbarLink>
|
<NavbarLink :out="false" url="/resources">Resources</NavbarLink>
|
||||||
<NavbarLink :out="false" url="/blog">Blog</NavbarLink>
|
<NavbarLink :out="false" url="/blog">Blog</NavbarLink>
|
||||||
<NavbarLink :out="true" url="http://github.com/ngn13/ngn13.fun">Source</NavbarLink>
|
<NavbarLink :out="true" url="http://github.com/ngn13/ngn13.fun"
|
||||||
</div>
|
>Source</NavbarLink
|
||||||
</nav>
|
>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import NavbarLink from "./NavbarLink.vue";
|
import NavbarLink from "./NavbarLink.vue"
|
||||||
|
|
||||||
export default {}
|
export default {}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
nav {
|
nav {
|
||||||
background: var(--dark-two);
|
background: var(--dark-two);
|
||||||
padding: 25px 35px 30px 35px;
|
padding: 25px 35px 30px 35px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
border-bottom: solid 3px black;
|
border-bottom: solid 3px black;
|
||||||
animation-name: borderAnimation;
|
animation-name: borderAnimation;
|
||||||
animation-duration: 10s;
|
animation-duration: 10s;
|
||||||
animation-iteration-count: infinite;
|
animation-iteration-count: infinite;
|
||||||
box-shadow: var(--def-shadow);
|
box-shadow: var(--def-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
div {
|
div {
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
color: red;
|
color: red;
|
||||||
animation-name: colorAnimation;
|
animation-name: colorAnimation;
|
||||||
animation-iteration-count: infinite;
|
animation-iteration-count: infinite;
|
||||||
animation-duration: 10s;
|
animation-duration: 10s;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -1,60 +1,60 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<nuxt-link v-if="!out" :class="cname" id="link" :to="url">
|
<nuxt-link v-if="!out" :class="cname" id="link" :to="url">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
<a v-if="out" :class="cname" id="link" :href="url">
|
<a v-if="out" :class="cname" id="link" :href="url">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: ["url", "out"],
|
props: ["url", "out"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
cname: "notcurrent"
|
cname: "notcurrent"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted(){
|
mounted() {
|
||||||
let url = window.location.pathname
|
let url = window.location.pathname
|
||||||
if(url===this.url){
|
if (url === this.url) {
|
||||||
this.cname = "current"
|
this.cname = "current"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.notcurrent {
|
.notcurrent {
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: white;
|
color: white;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.notcurrent:hover {
|
.notcurrent:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
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);
|
text-shadow: 3px 4px 7px rgba(81, 67, 21, 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
.current{
|
.current {
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: white;
|
color: white;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
animation-name: underlineAnimation;
|
animation-name: underlineAnimation;
|
||||||
animation-duration: 10s;
|
animation-duration: 10s;
|
||||||
animation-iteration-count: infinite;
|
animation-iteration-count: infinite;
|
||||||
text-shadow: 3px 4px 7px rgba(81, 67, 21, 0.8);
|
text-shadow: 3px 4px 7px rgba(81, 67, 21, 0.8);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -1,57 +1,72 @@
|
|||||||
<template>
|
<template>
|
||||||
<main>
|
<main>
|
||||||
<h1>Add New Post</h1>
|
<h1>Add New Post</h1>
|
||||||
<div class="textareas">
|
<div class="textareas">
|
||||||
<Input :keyup="function() { }" id="title" placeholder="Post Title" type="text"/>
|
<Input
|
||||||
<Input :keyup="function() { }" id="author" placeholder="Author" type="text"/>
|
:keyup="function () {}"
|
||||||
<h2>
|
id="title"
|
||||||
Make the post private
|
placeholder="Post Title"
|
||||||
<input id="private" type="checkbox"/>
|
type="text"
|
||||||
</h2>
|
/>
|
||||||
</div>
|
<Input
|
||||||
<textarea name="content" id="content" cols="30" rows="10" placeholder="Content"></textarea>
|
:keyup="function () {}"
|
||||||
<Button :click="click">Post</Button>
|
id="author"
|
||||||
</main>
|
placeholder="Author"
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
<h2>
|
||||||
|
Make the post private
|
||||||
|
<input id="private" type="checkbox" />
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<textarea
|
||||||
|
name="content"
|
||||||
|
id="content"
|
||||||
|
cols="30"
|
||||||
|
rows="10"
|
||||||
|
placeholder="Content"
|
||||||
|
></textarea>
|
||||||
|
<Button :click="click">Post</Button>
|
||||||
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import axios from 'axios';
|
import axios from "axios"
|
||||||
import Input from './Input.vue';
|
import Input from "./Input.vue"
|
||||||
import Button from './Button.vue';
|
import Button from "./Button.vue"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
methods: {
|
methods: {
|
||||||
async click(e) {
|
async click(e) {
|
||||||
const title = document.getElementById("title").value
|
const title = document.getElementById("title").value
|
||||||
const author = document.getElementById("author").value
|
const author = document.getElementById("author").value
|
||||||
const content = document.getElementById("content").value
|
const content = document.getElementById("content").value
|
||||||
const priv = document.getElementById("private").value
|
const priv = document.getElementById("private").value
|
||||||
const token = localStorage.getItem("token")
|
const token = localStorage.getItem("token")
|
||||||
const res = await axios.post("/api/blog/add", {
|
const res = await axios.post("/api/blog/add", {
|
||||||
token: token,
|
token: token,
|
||||||
title: title,
|
title: title,
|
||||||
author: author,
|
author: author,
|
||||||
content: content,
|
content: content,
|
||||||
priv: priv==="on"
|
priv: priv === "on"
|
||||||
})
|
})
|
||||||
if(res.data["error"]!==0)
|
if (res.data["error"] !== 0) return alert("Error!")
|
||||||
return alert("Error!")
|
alert("Post added!")
|
||||||
alert("Post added!")
|
location.reload()
|
||||||
location.reload()
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
h1{
|
h1 {
|
||||||
color: var(--white);
|
color: var(--white);
|
||||||
font-size: 50px;
|
font-size: 50px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2{
|
h2 {
|
||||||
background: var(--dark-two);
|
background: var(--dark-two);
|
||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
@ -71,38 +86,38 @@ input[type="checkbox"] {
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea{
|
textarea {
|
||||||
width: 500px;
|
width: 500px;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
background: var(--dark-two);
|
background: var(--dark-two);
|
||||||
border: none;
|
border: none;
|
||||||
color: white;
|
color: white;
|
||||||
outline: none;
|
outline: none;
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
transition: .4s;
|
transition: 0.4s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.textareas {
|
.textareas {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea:focus {
|
textarea:focus {
|
||||||
box-shadow: var(--def-shadow);
|
box-shadow: var(--def-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
main{
|
main {
|
||||||
background-color: var(--dark-three);
|
background-color: var(--dark-three);
|
||||||
padding: 50px;
|
padding: 50px;
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,51 +1,67 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<h1>Add Project</h1>
|
<h1>Add Project</h1>
|
||||||
<Input :keyup="function() { }" id="name" placeholder="Project Name" type="text"/>
|
<Input
|
||||||
<Input :keyup="function() { }" id="desc" placeholder="Project Desc" type="text"/>
|
:keyup="function () {}"
|
||||||
<Input :keyup="function() { }" id="url" placeholder="Project URL" type="text"/>
|
id="name"
|
||||||
<Button :click="click">Post</Button>
|
placeholder="Project Name"
|
||||||
</div>
|
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>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import axios from 'axios';
|
import axios from "axios"
|
||||||
import Input from './Input.vue';
|
import Input from "./Input.vue"
|
||||||
import Button from './Button.vue';
|
import Button from "./Button.vue"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
methods: {
|
methods: {
|
||||||
async click(e) {
|
async click(e) {
|
||||||
const name = document.getElementById("name").value
|
const name = document.getElementById("name").value
|
||||||
const desc = document.getElementById("desc").value
|
const desc = document.getElementById("desc").value
|
||||||
const url = document.getElementById("url").value
|
const url = document.getElementById("url").value
|
||||||
const token = localStorage.getItem("token")
|
const token = localStorage.getItem("token")
|
||||||
const res = await axios.get(`/api/projects/add?token=${token}&name=${name}&desc=${desc}&url=${url}`)
|
const res = await axios.get(
|
||||||
if(res.data["error"]!==0)
|
`/api/projects/add?token=${token}&name=${name}&desc=${desc}&url=${url}`
|
||||||
return alert("Error!")
|
)
|
||||||
alert("Project added!")
|
if (res.data["error"] !== 0) return alert("Error!")
|
||||||
location.reload()
|
alert("Project added!")
|
||||||
}
|
location.reload()
|
||||||
},
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
h1{
|
h1 {
|
||||||
color: var(--white);
|
color: var(--white);
|
||||||
font-size: 50px;
|
font-size: 50px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
div{
|
div {
|
||||||
background-color: var(--dark-three);
|
background-color: var(--dark-three);
|
||||||
padding: 50px;
|
padding: 50px;
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,51 +1,67 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<h1>Add Resource</h1>
|
<h1>Add Resource</h1>
|
||||||
<Input :keyup="function(){}" id="name" placeholder="Resource Name" type="text"/>
|
<Input
|
||||||
<Input :keyup="function(){}" id="tags" placeholder="Resource Tags (comma seperated)" type="text"/>
|
:keyup="function () {}"
|
||||||
<Input :keyup="function(){}" id="url" placeholder="Resource URL" type="text"/>
|
id="name"
|
||||||
<Button :click="click">Post</Button>
|
placeholder="Resource Name"
|
||||||
</div>
|
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>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Input from './Input.vue';
|
import Input from "./Input.vue"
|
||||||
import Button from './Button.vue';
|
import Button from "./Button.vue"
|
||||||
import axios from 'axios';
|
import axios from "axios"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
methods: {
|
methods: {
|
||||||
async click(e) {
|
async click(e) {
|
||||||
const name = document.getElementById("name").value
|
const name = document.getElementById("name").value
|
||||||
const tags = document.getElementById("tags").value
|
const tags = document.getElementById("tags").value
|
||||||
const url = document.getElementById("url").value
|
const url = document.getElementById("url").value
|
||||||
const token = localStorage.getItem("token")
|
const token = localStorage.getItem("token")
|
||||||
const res = await axios.get(`/api/resources/add?token=${token}&name=${name}&tags=${tags}&url=${url}`)
|
const res = await axios.get(
|
||||||
if(res.data["error"]!==0)
|
`/api/resources/add?token=${token}&name=${name}&tags=${tags}&url=${url}`
|
||||||
return alert("Error!")
|
)
|
||||||
alert("Resource added!")
|
if (res.data["error"] !== 0) return alert("Error!")
|
||||||
location.reload()
|
alert("Resource added!")
|
||||||
}
|
location.reload()
|
||||||
},
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
h1{
|
h1 {
|
||||||
color: var(--white);
|
color: var(--white);
|
||||||
font-size: 50px;
|
font-size: 50px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
div{
|
div {
|
||||||
background-color: var(--dark-three);
|
background-color: var(--dark-three);
|
||||||
padding: 50px;
|
padding: 50px;
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,42 +1,42 @@
|
|||||||
<template>
|
<template>
|
||||||
<nuxt-link :to="url">
|
<nuxt-link :to="url">
|
||||||
<h1>{{ title }}</h1>
|
<h1>{{ title }}</h1>
|
||||||
<p>{{ info }}</p>
|
<p>{{ info }}</p>
|
||||||
<h2>{{ desc }}</h2>
|
<h2>{{ desc }}</h2>
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: ["title", "desc", "info", "url"],
|
props: ["title", "desc", "info", "url"]
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
a{
|
a {
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
color: white;
|
color: white;
|
||||||
background: var(--dark-two);
|
background: var(--dark-two);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: .4s;
|
transition: 0.4s;
|
||||||
width: 70%;
|
width: 70%;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover{
|
a:hover {
|
||||||
box-shadow: var(--def-shadow);
|
box-shadow: var(--def-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
h1{
|
h1 {
|
||||||
font-size: 40px;
|
font-size: 40px;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
animation-name: colorAnimation;
|
animation-name: colorAnimation;
|
||||||
animation-iteration-count: infinite;
|
animation-iteration-count: infinite;
|
||||||
animation-duration: 10s;
|
animation-duration: 10s;
|
||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2{
|
h2 {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -1,62 +1,62 @@
|
|||||||
<template>
|
<template>
|
||||||
<main @click="redirect()">
|
<main @click="redirect()">
|
||||||
<i class='bx bx-code-alt'></i>
|
<i class="bx bx-code-alt"></i>
|
||||||
<div>
|
<div>
|
||||||
<h1>{{ name }}</h1>
|
<h1>{{ name }}</h1>
|
||||||
<h2>{{ desc }}</h2>
|
<h2>{{ desc }}</h2>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: ["name", "desc", "url"],
|
props: ["name", "desc", "url"],
|
||||||
methods: {
|
methods: {
|
||||||
redirect(e) {
|
redirect(e) {
|
||||||
location.href=this.url
|
location.href = this.url
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
main {
|
main {
|
||||||
color: var(--white);
|
color: var(--white);
|
||||||
background: var(--dark-two);
|
background: var(--dark-two);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
padding: 40px;
|
padding: 40px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: .4s;
|
transition: 0.4s;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
width: 450px;
|
width: 450px;
|
||||||
}
|
}
|
||||||
|
|
||||||
main:hover{
|
main:hover {
|
||||||
box-shadow: var(--def-shadow);
|
box-shadow: var(--def-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
i{
|
i {
|
||||||
font-size: 65px;
|
font-size: 65px;
|
||||||
animation-name: colorAnimation;
|
animation-name: colorAnimation;
|
||||||
animation-duration: 10s;
|
animation-duration: 10s;
|
||||||
animation-iteration-count: infinite;
|
animation-iteration-count: infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1{
|
h1 {
|
||||||
font-size: 35px;
|
font-size: 35px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2{
|
h2 {
|
||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 1416px) {
|
@media only screen and (max-width: 1416px) {
|
||||||
main{
|
main {
|
||||||
width: 80%;
|
width: 80%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,28 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {}
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
div{
|
div {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 30px;
|
gap: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 1416px) {
|
@media only screen and (max-width: 1416px) {
|
||||||
div {
|
div {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,66 +1,66 @@
|
|||||||
<template>
|
<template>
|
||||||
<main @click="redirect()" class="mn">
|
<main @click="redirect()" class="mn">
|
||||||
<div class="resource">
|
<div class="resource">
|
||||||
<h1>{{ name }}</h1>
|
<h1>{{ name }}</h1>
|
||||||
<div class="tags">
|
<div class="tags">
|
||||||
<Tag v-for="tag in tags" :key="tag">{{ tag }}</Tag>
|
<Tag v-for="tag in tags" :key="tag">{{ tag }}</Tag>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<i class='bx bx-right-arrow-alt' ></i>
|
<i class="bx bx-right-arrow-alt"></i>
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Tag from './Tag.vue';
|
import Tag from "./Tag.vue"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: ["tags", "name", "url"],
|
props: ["tags", "name", "url"],
|
||||||
methods: {
|
methods: {
|
||||||
redirect(e){
|
redirect(e) {
|
||||||
location.href = this.url
|
location.href = this.url
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
main{
|
main {
|
||||||
background: var(--dark-two);
|
background: var(--dark-two);
|
||||||
padding: 30px 40px 30px 40px;
|
padding: 30px 40px 30px 40px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
color: var(--white);
|
color: var(--white);
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
transition: .4s;
|
transition: 0.4s;
|
||||||
width: 80%;
|
width: 80%;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
main:hover{
|
main:hover {
|
||||||
box-shadow: var(--def-shadow);
|
box-shadow: var(--def-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mn:hover i{
|
.mn:hover i {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.resource{
|
.resource {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tags{
|
.tags {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
i{
|
i {
|
||||||
font-size: 70px;
|
font-size: 70px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: var(--dark-two);
|
color: var(--dark-two);
|
||||||
transition: .4s;
|
transition: 0.4s;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -1,24 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<p>
|
<p>#<slot></slot></p>
|
||||||
#<slot></slot>
|
|
||||||
</p>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {}
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
p{
|
p {
|
||||||
background: var(--dark-three);
|
background: var(--dark-three);
|
||||||
color: white;
|
color: white;
|
||||||
text-shadow: 1px 1px 2px white;
|
text-shadow: 1px 1px 2px white;
|
||||||
padding: 5px 10px 5px 10px;
|
padding: 5px 10px 5px 10px;
|
||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
border-radius: 7px;
|
border-radius: 7px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
transition: .4s;
|
transition: 0.4s;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -1,11 +1,11 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
apps: [
|
apps: [
|
||||||
{
|
{
|
||||||
name: 'My Website',
|
name: "My Website",
|
||||||
exec_mode: 'cluster',
|
exec_mode: "cluster",
|
||||||
instances: 'max', // Or a number of instances
|
instances: "max", // Or a number of instances
|
||||||
script: './node_modules/nuxt/bin/nuxt.js',
|
script: "./node_modules/nuxt/bin/nuxt.js",
|
||||||
args: 'start'
|
args: "start"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
7
layouts/error.vue
Normal file
7
layouts/error.vue
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
mounted() {
|
||||||
|
this.$router.push({ path: "/" })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -1,37 +1,46 @@
|
|||||||
const express = require("express");
|
const express = require("express")
|
||||||
const { MongoClient } = require("mongodb");
|
const { MongoClient } = require("mongodb")
|
||||||
const { makeID } = require("../api/util.js")
|
const { makeID } = require("../api/util.js")
|
||||||
require("dotenv").config()
|
require("dotenv").config()
|
||||||
|
|
||||||
const app = express();
|
const app = express()
|
||||||
app.use(express.json());
|
app.use(express.json())
|
||||||
app.use(express.urlencoded({ extended: false }));
|
app.use(express.urlencoded({ extended: false }))
|
||||||
|
|
||||||
const client = new MongoClient(process.env.DATABASE);
|
const client = new MongoClient(process.env.DATABASE)
|
||||||
|
|
||||||
app.get("/:id", async (req,res)=>{
|
app.get("/:id", async (req, res) => {
|
||||||
const id = req.params.id
|
const id = req.params.id
|
||||||
|
|
||||||
|
if (typeof id !== "string") return res.redirect("/projects")
|
||||||
|
|
||||||
await client.connect()
|
await client.connect()
|
||||||
const db = await client.db("ngn13")
|
const db = client.db("ngn13")
|
||||||
const col = await db.collection("projects")
|
const col = db.collection("projects")
|
||||||
const projects = await col.find().toArray()
|
const projects = await col.find().toArray()
|
||||||
|
|
||||||
console.log(projects)
|
for (let i = 0; i < projects.length; i++) {
|
||||||
|
if (makeID(projects[i]["name"]) === id) {
|
||||||
for(let i=0; i<projects.length;i++){
|
|
||||||
if(makeID(projects[i]["name"])===id){
|
|
||||||
res.redirect(projects[i]["url"])
|
res.redirect(projects[i]["url"])
|
||||||
await col.updateOne({ name: projects[i]["name"] }, { "$set":
|
await col.updateOne(
|
||||||
{ "click": projects[i]["click"]+1 }})
|
{ name: projects[i]["name"] },
|
||||||
return await client.close()
|
{ $set: { click: projects[i]["click"] + 1 } }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await client.close()
|
|
||||||
return res.redirect("/projects")
|
return res.redirect("/projects")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
async function pexit() {
|
||||||
|
await client.close()
|
||||||
|
process.exit()
|
||||||
|
}
|
||||||
|
|
||||||
|
process.on("SIGTERM", pexit)
|
||||||
|
process.on("SIGINT", pexit)
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
path: "/l",
|
path: "/l",
|
||||||
handler: app,
|
handler: app
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ export default {
|
|||||||
head: {
|
head: {
|
||||||
title: "[ngn]",
|
title: "[ngn]",
|
||||||
htmlAttrs: {
|
htmlAttrs: {
|
||||||
lang: "en",
|
lang: "en"
|
||||||
},
|
},
|
||||||
meta: [
|
meta: [
|
||||||
{ charset: "utf-8" },
|
{ charset: "utf-8" },
|
||||||
@ -10,14 +10,24 @@ export default {
|
|||||||
{ hid: "description", name: "description", content: "" },
|
{ hid: "description", name: "description", content: "" },
|
||||||
{ name: "format-detection", content: "telephone=no" },
|
{ name: "format-detection", content: "telephone=no" },
|
||||||
{ hid: "og:title", content: "[ngn]" },
|
{ hid: "og:title", content: "[ngn]" },
|
||||||
{ hid: "og:description", content: "personal website of ngn | read my blogs, check out my projects, discover cool resources" },
|
{
|
||||||
{ hid: "og:url", content: "https://ngn13.fun" },
|
hid: "og:description",
|
||||||
{ name: "theme-color", content: "#141414", "data-react-helmet":"true"},
|
content:
|
||||||
|
"personal website of ngn | read my blogs, check out my projects, discover cool resources"
|
||||||
|
},
|
||||||
|
{ hid: "og:url", content: "https://ngn13.fun" },
|
||||||
|
{ name: "theme-color", content: "#141414", "data-react-helmet": "true" }
|
||||||
],
|
],
|
||||||
|
|
||||||
link: [
|
link: [
|
||||||
{ rel: "stylesheet", href: "https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css" },
|
{
|
||||||
{ rel: "stylesheet", href: "https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.2.0/github-markdown-dark.css" }
|
rel: "stylesheet",
|
||||||
|
href: "https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rel: "stylesheet",
|
||||||
|
href: "https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.2.0/github-markdown-dark.css"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
css: ["@/static/global.css"],
|
css: ["@/static/global.css"],
|
||||||
@ -26,11 +36,11 @@ export default {
|
|||||||
buildModules: [],
|
buildModules: [],
|
||||||
modules: ["@nuxtjs/axios"],
|
modules: ["@nuxtjs/axios"],
|
||||||
axios: {
|
axios: {
|
||||||
baseURL: "/",
|
baseURL: "/"
|
||||||
},
|
},
|
||||||
build: {},
|
build: {},
|
||||||
serverMiddleware: {
|
serverMiddleware: {
|
||||||
"/api": "~/api",
|
"/api": "~/api",
|
||||||
"/l": "~/links",
|
"/l": "~/links"
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "my-website",
|
"name": "my-website",
|
||||||
"version": "2.4.0",
|
"version": "2.5.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "nuxt",
|
"dev": "nuxt",
|
||||||
|
@ -1,108 +1,110 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="all">
|
<div class="all">
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<Header>
|
<Header>
|
||||||
<label class="glitch title">{{ post.title }}</label>
|
<label class="glitch title">{{ post.title }}</label>
|
||||||
<p>{{ post.info }}</p>
|
<p>{{ post.info }}</p>
|
||||||
</Header>
|
</Header>
|
||||||
<div class="postcontain">
|
<div class="postcontain">
|
||||||
<main class="markdown-body" v-html="content"></main>
|
<main class="markdown-body" v-html="content"></main>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Navbar from "../../../components/Navbar.vue";
|
import Navbar from "../../../components/Navbar.vue"
|
||||||
import Header from "../../../components/Header.vue";
|
import Header from "../../../components/Header.vue"
|
||||||
import axios from "axios";
|
import axios from "axios"
|
||||||
import * as DOMPurify from "dompurify";
|
import * as DOMPurify from "dompurify"
|
||||||
import marked from "marked";
|
import marked from "marked"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
head() {
|
head() {
|
||||||
return {
|
return {
|
||||||
title: "[ngn] | " + this.post.title,
|
title: "[ngn] | " + this.post.title,
|
||||||
meta: [
|
meta: [
|
||||||
{
|
{
|
||||||
hid: "description",
|
hid: "description",
|
||||||
name: "description",
|
name: "description",
|
||||||
content: "read my blog posts"
|
content: "read my blog posts"
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
post: {},
|
|
||||||
lang: "",
|
|
||||||
content: "",
|
|
||||||
}
|
}
|
||||||
},
|
]
|
||||||
|
|
||||||
async created() {
|
|
||||||
const res = await axios.get(`/api/blog/get?id=${this.$route.params.id}`)
|
|
||||||
if (res.data["error"] === 3)
|
|
||||||
return this.$router.push({ path: "/blog" })
|
|
||||||
this.post = res.data["post"]
|
|
||||||
this.post["content"] = this.post["content"].replaceAll("\n<br>\n<br>\n", "\n\n")
|
|
||||||
this.content = DOMPurify.sanitize(
|
|
||||||
marked.parse(this.post["content"], { breaks: true }),
|
|
||||||
{ ADD_TAGS: ["iframe"], ADD_ATTR: ['allow', 'allowfullscreen', 'frameborder', 'scrolling'] }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
post: {},
|
||||||
|
lang: "",
|
||||||
|
content: ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async created() {
|
||||||
|
const res = await axios.get(`/api/blog/get?id=${this.$route.params.id}`)
|
||||||
|
if (res.data["error"] === 3) return this.$router.push({ path: "/blog" })
|
||||||
|
this.post = res.data["post"]
|
||||||
|
this.post["content"] = this.post["content"].replaceAll(
|
||||||
|
"\n<br>\n<br>\n",
|
||||||
|
"\n\n"
|
||||||
|
)
|
||||||
|
this.content = DOMPurify.sanitize(
|
||||||
|
marked.parse(this.post["content"], { breaks: true }),
|
||||||
|
{
|
||||||
|
ADD_TAGS: ["iframe"],
|
||||||
|
ADD_ATTR: ["allow", "allowfullscreen", "frameborder", "scrolling"]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
glitch {
|
glitch {
|
||||||
font-size: 80px;
|
font-size: 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.postcontain{
|
.postcontain {
|
||||||
padding: 50px;
|
padding: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown-body {
|
.markdown-body {
|
||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
padding: 50px;
|
padding: 50px;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
background-color: var(--dark-three);
|
background-color: var(--dark-three);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.markdown-body{
|
.markdown-body {
|
||||||
font-family: "Ubuntu", sans-serif;
|
font-family: "Ubuntu", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown-body h1{
|
.markdown-body h1 {
|
||||||
border-bottom: 1px solid #505050;
|
border-bottom: 1px solid #505050;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown-body iframe{
|
.markdown-body iframe {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 20px 0px;
|
margin: 20px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown-body a{
|
.markdown-body a {
|
||||||
animation-name: colorAnimation;
|
animation-name: colorAnimation;
|
||||||
animation-iteration-count: infinite;
|
animation-iteration-count: infinite;
|
||||||
animation-duration: 10s;
|
animation-duration: 10s;
|
||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,89 +1,92 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<Header>
|
<Header> <label class="glitch">/dev/</label>blog </Header>
|
||||||
<label class="glitch">/dev/</label>blog
|
<div class="blogs">
|
||||||
</Header>
|
<Input :keyup="keyup" placeholder="Search post" type="text" />
|
||||||
<div class="blogs">
|
<PostPreview
|
||||||
<Input :keyup="keyup" placeholder="Search post" type="text"/>
|
v-for="post in posts"
|
||||||
<PostPreview v-for="post in posts" :key="post.title" :title="post.title" :desc="post.desc" :info="post.info" :url="post.url">
|
:key="post.title"
|
||||||
{{ post.desc }}
|
:title="post.title"
|
||||||
</PostPreview>
|
:desc="post.desc"
|
||||||
</div>
|
:info="post.info"
|
||||||
<NewPost v-if="logged"/>
|
:url="post.url"
|
||||||
|
>
|
||||||
|
{{ post.desc }}
|
||||||
|
</PostPreview>
|
||||||
</div>
|
</div>
|
||||||
|
<NewPost v-if="logged" />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Navbar from "../../components/Navbar.vue";
|
import Navbar from "../../components/Navbar.vue"
|
||||||
import Header from "../../components/Header.vue";
|
import Header from "../../components/Header.vue"
|
||||||
import NewPost from "../../components/NewPost.vue";
|
import NewPost from "../../components/NewPost.vue"
|
||||||
import PostPreview from "../../components/PostPreview.vue";
|
import PostPreview from "../../components/PostPreview.vue"
|
||||||
import axios from "axios";
|
import axios from "axios"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
head() {
|
head() {
|
||||||
return {
|
return {
|
||||||
title: "[ngn] | blog",
|
title: "[ngn] | blog",
|
||||||
meta: [
|
meta: [
|
||||||
{
|
{
|
||||||
hid: "description",
|
hid: "description",
|
||||||
name: "description",
|
name: "description",
|
||||||
content: "read my blog posts"
|
content: "read my blog posts"
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
logged: false,
|
|
||||||
posts: [],
|
|
||||||
all: []
|
|
||||||
};
|
|
||||||
},
|
|
||||||
mounted: async function () {
|
|
||||||
if (localStorage.getItem("token"))
|
|
||||||
this.logged = true;
|
|
||||||
const res = await axios.get("/api/blog/sum");
|
|
||||||
let posts = []
|
|
||||||
|
|
||||||
res.data["posts"].forEach(post=>{
|
|
||||||
posts.push({
|
|
||||||
title: post.title,
|
|
||||||
desc: post.desc,
|
|
||||||
info: post.info,
|
|
||||||
url: `/blog/${post.title.toLowerCase().replaceAll(" ", "")}`
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
this.posts = posts
|
|
||||||
this.all = posts
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
keyup(e) {
|
|
||||||
let val = e.target.value
|
|
||||||
|
|
||||||
// search looks at name and info
|
|
||||||
this.posts = []
|
|
||||||
for(let i = 0; i < this.all.length; i++){
|
|
||||||
if(this.all[i].title.toLowerCase().includes(val.toLowerCase()))
|
|
||||||
this.posts.push(this.all[i])
|
|
||||||
|
|
||||||
else if(this.all[i].info.toLowerCase().includes(val.toLowerCase()))
|
|
||||||
this.posts.push(this.all[i])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
logged: false,
|
||||||
|
posts: [],
|
||||||
|
all: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted: async function () {
|
||||||
|
if (localStorage.getItem("token")) this.logged = true
|
||||||
|
const res = await axios.get("/api/blog/sum")
|
||||||
|
let posts = []
|
||||||
|
|
||||||
|
res.data["posts"].forEach((post) => {
|
||||||
|
posts.push({
|
||||||
|
title: post.title,
|
||||||
|
desc: post.desc,
|
||||||
|
info: post.info,
|
||||||
|
url: `/blog/${post.title.toLowerCase().replaceAll(" ", "")}`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
this.posts = posts
|
||||||
|
this.all = posts
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
keyup(e) {
|
||||||
|
let val = e.target.value
|
||||||
|
|
||||||
|
// search looks at name and info
|
||||||
|
this.posts = []
|
||||||
|
for (let i = 0; i < this.all.length; i++) {
|
||||||
|
if (this.all[i].title.toLowerCase().includes(val.toLowerCase()))
|
||||||
|
this.posts.push(this.all[i])
|
||||||
|
else if (this.all[i].info.toLowerCase().includes(val.toLowerCase()))
|
||||||
|
this.posts.push(this.all[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.blogs {
|
.blogs {
|
||||||
padding: 50px;
|
padding: 50px;
|
||||||
gap: 35px;
|
gap: 35px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 30px;
|
gap: 30px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
167
pages/index.vue
167
pages/index.vue
@ -1,104 +1,109 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<Header>
|
<Header> <label class="glitch">echo</label> hello world! </Header>
|
||||||
<label class="glitch">echo</label> hello world!
|
<div class="info">
|
||||||
</Header>
|
<Card>
|
||||||
<div class="info">
|
<h1>👋 Welcome to my website!</h1>
|
||||||
<Card>
|
<h2>
|
||||||
<h1>👋 Welcome to my website!</h1>
|
I am a high school student who is interested in
|
||||||
<h2>
|
<br />
|
||||||
I am a high school student who is interested in
|
• cyber security
|
||||||
<br>
|
<br />
|
||||||
• cyber security
|
• coding
|
||||||
<br>
|
<br />
|
||||||
• coding
|
• electronics
|
||||||
<br>
|
<br />
|
||||||
• electronics
|
• gaming
|
||||||
<br>
|
<br />
|
||||||
• gaming
|
• simply: everything about computers!
|
||||||
<br>
|
</h2>
|
||||||
• simply: everything about computers!
|
</Card>
|
||||||
</h2>
|
<Card>
|
||||||
</Card>
|
<h1>👉 Contact me</h1>
|
||||||
<Card>
|
<h2>You can contact me on the following platforms:</h2>
|
||||||
<h1>👉 Contact me</h1>
|
|
||||||
<h2>You can contact me on the following platforms:</h2>
|
|
||||||
|
|
||||||
<a href="https://discord.com/users/568131907368386565"><i class='bx bxl-discord-alt'></i> Discord</a>
|
<a href="https://discord.com/users/568131907368386565"
|
||||||
<br>
|
><i class="bx bxl-discord-alt"></i> Discord</a
|
||||||
<a href="https://github.com/ngn13"><i class='bx bxl-github'></i> Github</a>
|
>
|
||||||
<br>
|
<br />
|
||||||
<a href="https://mastodon.social/@ngn"><i class='bx bxl-mastodon'></i> Mastodon</a>
|
<a href="https://github.com/ngn13"
|
||||||
<br>
|
><i class="bx bxl-github"></i> Github</a
|
||||||
<a href="mailto:ngn13proton@proton.me"><i class='bx bxs-envelope'></i> Mail</a>
|
>
|
||||||
<br>
|
<br />
|
||||||
<h2>or private message me on matrix:</h2>
|
<a href="https://mastodon.social/@ngn"
|
||||||
<a><i>[matrix]</i> @ngn:matrix.ngn13.fun</a>
|
><i class="bx bxl-mastodon"></i> Mastodon</a
|
||||||
</Card>
|
>
|
||||||
</div>
|
<br />
|
||||||
<Logout v-if="logged"/>
|
<a href="mailto:ngn13proton@proton.me"
|
||||||
<div class="version">
|
><i class="bx bxs-envelope"></i> Mail</a
|
||||||
<p>v2.4</p>
|
>
|
||||||
</div>
|
<br />
|
||||||
|
<h2>or private message me on matrix:</h2>
|
||||||
|
<a><i>[matrix]</i> @ngn:matrix.ngn13.fun</a>
|
||||||
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
<Logout v-if="logged" />
|
||||||
|
<div class="version">
|
||||||
|
<p>v2.5</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Navbar from "../components/Navbar.vue";
|
import Navbar from "../components/Navbar.vue"
|
||||||
import Header from "../components/Header.vue";
|
import Header from "../components/Header.vue"
|
||||||
import Card from "../components/Card.vue"
|
import Card from "../components/Card.vue"
|
||||||
import Logout from "../components/Logout.vue";
|
import Logout from "../components/Logout.vue"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
head() {
|
head() {
|
||||||
return {
|
return {
|
||||||
title: "[ngn]",
|
title: "[ngn]",
|
||||||
meta: [
|
meta: [
|
||||||
{
|
{
|
||||||
hid: "description",
|
hid: "description",
|
||||||
name: "description",
|
name: "description",
|
||||||
content: "homepage of my website"
|
content: "homepage of my website"
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
]
|
||||||
data() {
|
}
|
||||||
return {
|
},
|
||||||
logged: false
|
data() {
|
||||||
}
|
return {
|
||||||
},
|
logged: false
|
||||||
mounted(){
|
}
|
||||||
if(localStorage.getItem("token"))
|
},
|
||||||
this.logged = true
|
mounted() {
|
||||||
}
|
if (localStorage.getItem("token")) this.logged = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.info {
|
.info {
|
||||||
padding: 50px;
|
padding: 50px;
|
||||||
gap: 30px;
|
gap: 30px;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
.version{
|
.version {
|
||||||
color: var(--dark-fife);
|
color: var(--dark-fife);
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 10px;
|
bottom: 10px;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
i{
|
i {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 1076px) {
|
@media only screen and (max-width: 1076px) {
|
||||||
.info {
|
.info {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
.info div {
|
.info div {
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,51 +1,56 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<h1>Login Page</h1>
|
<h1>Login Page</h1>
|
||||||
<Input :keyup="function() { }" placeholder="Password" type="password" id="pass"/>
|
<Input
|
||||||
<Button :click="click">Login</Button>
|
:keyup="function () {}"
|
||||||
</div>
|
placeholder="Password"
|
||||||
|
type="password"
|
||||||
|
id="pass"
|
||||||
|
/>
|
||||||
|
<Button :click="click">Login</Button>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Input from '../components/Input.vue';
|
import Input from "../components/Input.vue"
|
||||||
import Button from '../components/Button.vue';
|
import Button from "../components/Button.vue"
|
||||||
import axios from "axios";
|
import axios from "axios"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
methods: {
|
methods: {
|
||||||
async click(e) {
|
async click(e) {
|
||||||
const pass = document.getElementById("pass").value
|
const pass = document.getElementById("pass").value
|
||||||
const res = await axios.get(`/api/auth/login?pass=${pass}`)
|
const res = await axios.get(`/api/auth/login?pass=${pass}`)
|
||||||
if(res.data["error"]===0){
|
if (res.data["error"] === 0) {
|
||||||
localStorage.setItem("token", res.data["token"])
|
localStorage.setItem("token", res.data["token"])
|
||||||
return location.href="/"
|
return (location.href = "/")
|
||||||
}
|
}
|
||||||
alert("Incorrect password!")
|
alert("Incorrect password!")
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
div {
|
div {
|
||||||
padding: 50px;
|
padding: 50px;
|
||||||
background: var(--dark-three);
|
background: var(--dark-three);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
color: var(--white);
|
color: var(--white);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1{
|
h1 {
|
||||||
font-size: 70px;
|
font-size: 70px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,96 +1,105 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<Header>
|
<Header> <label class="glitch">ls -la</label> projects </Header>
|
||||||
<label class="glitch">ls -la</label> projects
|
<div class="projects">
|
||||||
</Header>
|
<ProjectList v-for="project in projects" :key="project.id">
|
||||||
<div class="projects">
|
<Project
|
||||||
<ProjectList v-for="project in projects" :key="project.id">
|
v-if="logged"
|
||||||
<Project v-if="logged" v-for="p in project.list" :key="p.name" :name="`${p.name} (${p.click})`" :desc="p.desc" :url="p.url"/>
|
v-for="p in project.list"
|
||||||
<Project v-if="!logged" v-for="p in project.list" :key="p.desc" :name="p.name" :desc="p.desc" :url="p.url"/>
|
:key="p.name"
|
||||||
</ProjectList>
|
:name="`${p.name} (${p.click})`"
|
||||||
</div>
|
:desc="p.desc"
|
||||||
<NewProject v-if="logged"/>
|
:url="p.url"
|
||||||
|
/>
|
||||||
|
<Project
|
||||||
|
v-if="!logged"
|
||||||
|
v-for="p in project.list"
|
||||||
|
:key="p.desc"
|
||||||
|
:name="p.name"
|
||||||
|
:desc="p.desc"
|
||||||
|
:url="p.url"
|
||||||
|
/>
|
||||||
|
</ProjectList>
|
||||||
</div>
|
</div>
|
||||||
|
<NewProject v-if="logged" />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ProjectList from "../components/ProjectList.vue";
|
import ProjectList from "../components/ProjectList.vue"
|
||||||
import Project from "../components/Project.vue";
|
import Project from "../components/Project.vue"
|
||||||
import NewProject from "../components/NewProject.vue";
|
import NewProject from "../components/NewProject.vue"
|
||||||
import axios from "axios";
|
import axios from "axios"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
head() {
|
head() {
|
||||||
return {
|
return {
|
||||||
title: "[ngn] | projects",
|
title: "[ngn] | projects",
|
||||||
meta: [
|
meta: [
|
||||||
{
|
{
|
||||||
hid: "description",
|
hid: "description",
|
||||||
name: "description",
|
name: "description",
|
||||||
content: "check out my projects"
|
content: "check out my projects"
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
]
|
||||||
data() {
|
}
|
||||||
return {
|
},
|
||||||
logged: false,
|
data() {
|
||||||
projects: []
|
return {
|
||||||
}
|
logged: false,
|
||||||
},
|
projects: []
|
||||||
mounted: async function(){
|
}
|
||||||
if(localStorage.getItem("token"))
|
},
|
||||||
this.logged = true
|
mounted: async function () {
|
||||||
|
if (localStorage.getItem("token")) this.logged = true
|
||||||
|
|
||||||
const res = await axios.get("/api/projects/get")
|
const res = await axios.get("/api/projects/get")
|
||||||
|
|
||||||
let all = res.data["projects"]
|
let all = res.data["projects"]
|
||||||
let pcounter = 0
|
let pcounter = 0
|
||||||
let projects = []
|
let projects = []
|
||||||
let project = {
|
let project = {
|
||||||
|
id: pcounter,
|
||||||
|
list: []
|
||||||
|
}
|
||||||
|
for (let i = 0; i < all.length; i++) {
|
||||||
|
if (project["list"].length === 3) {
|
||||||
|
projects.push(project)
|
||||||
|
pcounter += 1
|
||||||
|
project = {
|
||||||
id: pcounter,
|
id: pcounter,
|
||||||
list: []
|
list: []
|
||||||
}
|
}
|
||||||
for(let i = 0; i<all.length; i++){
|
}
|
||||||
if(project["list"].length===3){
|
|
||||||
projects.push(project)
|
|
||||||
pcounter += 1
|
|
||||||
project = {
|
|
||||||
id: pcounter,
|
|
||||||
list: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
project["list"].push({
|
project["list"].push({
|
||||||
name: all[i]["name"],
|
name: all[i]["name"],
|
||||||
desc: all[i]["desc"],
|
desc: all[i]["desc"],
|
||||||
click: all[i]["click"],
|
click: all[i]["click"],
|
||||||
url: `/l/${all[i]["name"]
|
url: `/l/${all[i]["name"].toLowerCase().replaceAll(" ", "")}`
|
||||||
.toLowerCase()
|
})
|
||||||
.replaceAll(" ", "")}`
|
|
||||||
})
|
|
||||||
|
|
||||||
if(i===all.length-1){
|
if (i === all.length - 1) {
|
||||||
projects.push(project)
|
projects.push(project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.projects = projects
|
this.projects = projects
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.projects{
|
.projects {
|
||||||
padding: 50px;
|
padding: 50px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 1121px) {
|
@media only screen and (max-width: 1121px) {
|
||||||
.projects {
|
.projects {
|
||||||
padding: 50px;
|
padding: 50px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,103 +1,108 @@
|
|||||||
<template>
|
<template>
|
||||||
<main>
|
<main>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<Header>
|
<Header> <label class="glitch">cat</label> {{ header }} </Header>
|
||||||
<label class="glitch">cat</label> {{ header }}
|
<div class="resources">
|
||||||
</Header>
|
<Input :keyup="keyup" placeholder="Search resource" type="text" />
|
||||||
<div class="resources">
|
<Resource
|
||||||
<Input :keyup="keyup" placeholder="Search resource" type="text"/>
|
v-for="res in show_resources"
|
||||||
<Resource v-for="res in show_resources" :key="res.name" :name="res.name" :tags="res.tags" :url="res.url" />
|
:key="res.name"
|
||||||
</div>
|
:name="res.name"
|
||||||
<NewResource v-if="logged"/>
|
:tags="res.tags"
|
||||||
</main>
|
:url="res.url"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<NewResource v-if="logged" />
|
||||||
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import axios from 'axios';
|
import axios from "axios"
|
||||||
import Resource from '../components/Resource.vue';
|
import Resource from "../components/Resource.vue"
|
||||||
import Input from '../components/Input.vue';
|
import Input from "../components/Input.vue"
|
||||||
import NewResource from '../components/NewResource.vue';
|
import NewResource from "../components/NewResource.vue"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
head() {
|
head() {
|
||||||
return {
|
return {
|
||||||
title: "[ngn] | resources",
|
title: "[ngn] | resources",
|
||||||
meta: [
|
meta: [
|
||||||
{
|
{
|
||||||
hid: "description",
|
hid: "description",
|
||||||
name: "description",
|
name: "description",
|
||||||
content: "discover new resources"
|
content: "discover new resources"
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
]
|
||||||
data() {
|
}
|
||||||
return {
|
},
|
||||||
header: "resources",
|
data() {
|
||||||
logged: false,
|
return {
|
||||||
sum_resources: [],
|
header: "resources",
|
||||||
all_resources: [],
|
logged: false,
|
||||||
show_resources: []
|
sum_resources: [],
|
||||||
}
|
all_resources: [],
|
||||||
},
|
show_resources: []
|
||||||
methods: {
|
}
|
||||||
keyup(e) {
|
},
|
||||||
let search = e.target.value
|
methods: {
|
||||||
if(e.key==="Backspace" && search===""){
|
keyup(e) {
|
||||||
this.header = "resources"
|
let search = e.target.value
|
||||||
this.show_resources = this.sum_resources
|
if (e.key === "Backspace" && search === "") {
|
||||||
return
|
this.header = "resources"
|
||||||
}
|
|
||||||
if(e.key==="OS")
|
|
||||||
return
|
|
||||||
this.header = `resources | grep ${search}`
|
|
||||||
|
|
||||||
// dirty asf search alg
|
|
||||||
this.show_resources = []
|
|
||||||
for(let i = 0; i < this.all_resources.length; i++){
|
|
||||||
if(this.all_resources[i].name
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(search.toLowerCase())
|
|
||||||
){
|
|
||||||
this.show_resources.push(this.all_resources[i])
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
for(let e = 0; e < this.all_resources[i].tags.length; e++){
|
|
||||||
if(this.all_resources[i].tags[e].toLowerCase()
|
|
||||||
.includes(search.toLowerCase())
|
|
||||||
){
|
|
||||||
this.show_resources.push(this.all_resources[i])
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted: async function(){
|
|
||||||
if(localStorage.getItem("token"))
|
|
||||||
this.logged = true
|
|
||||||
|
|
||||||
// request top 10 resources so we can
|
|
||||||
// render the DOM as fast as possible
|
|
||||||
let res = await axios.get("/api/resources/get?sum=1")
|
|
||||||
this.sum_resources = res.data["resources"]
|
|
||||||
this.show_resources = this.sum_resources
|
this.show_resources = this.sum_resources
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (e.key === "OS") return
|
||||||
|
this.header = `resources | grep ${search}`
|
||||||
|
|
||||||
// then we can load all the resources
|
// dirty asf search alg
|
||||||
res = await axios.get("/api/resources/get")
|
this.show_resources = []
|
||||||
this.all_resources = res.data["resources"]
|
for (let i = 0; i < this.all_resources.length; i++) {
|
||||||
}
|
if (
|
||||||
|
this.all_resources[i].name
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(search.toLowerCase())
|
||||||
|
) {
|
||||||
|
this.show_resources.push(this.all_resources[i])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let e = 0; e < this.all_resources[i].tags.length; e++) {
|
||||||
|
if (
|
||||||
|
this.all_resources[i].tags[e]
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(search.toLowerCase())
|
||||||
|
) {
|
||||||
|
this.show_resources.push(this.all_resources[i])
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted: async function () {
|
||||||
|
if (localStorage.getItem("token")) this.logged = true
|
||||||
|
|
||||||
|
// request top 10 resources so we can
|
||||||
|
// render the DOM as fast as possible
|
||||||
|
let res = await axios.get("/api/resources/get?sum=1")
|
||||||
|
this.sum_resources = res.data["resources"]
|
||||||
|
this.show_resources = this.sum_resources
|
||||||
|
|
||||||
|
// then we can load all the resources
|
||||||
|
res = await axios.get("/api/resources/get")
|
||||||
|
this.all_resources = res.data["resources"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.resources {
|
.resources {
|
||||||
padding: 50px;
|
padding: 50px;
|
||||||
padding-bottom: 60px;
|
padding-bottom: 60px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 40px
|
gap: 40px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user