Merge pull request #1 from ngn13/dev

merging dev
This commit is contained in:
ngn 2023-06-11 20:20:55 +03:00 committed by GitHub
commit 16838bf256
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 380 additions and 386 deletions

4
.gitignore vendored
View File

@ -88,7 +88,3 @@ sw.*
# Vim swap files # Vim swap files
*.swp *.swp
# db file
db.json
pass

View File

@ -1,16 +1,7 @@
const express = require("express"); const express = require("express")
const {gimmeToken} = require("./util.js") const { MongoClient } = require("mongodb")
const { MongoClient } = require("mongodb");
require("dotenv").config() require("dotenv").config()
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
const client = new MongoClient(process.env.DATABASE);
const PASS = process.env.PASS
let TOKEN = gimmeToken();
/* /*
* error: 0 -> no error * error: 0 -> no error
* error: 1 -> parameter error * error: 1 -> parameter error
@ -18,205 +9,35 @@ let TOKEN = gimmeToken();
* error: 3 -> not found error * error: 3 -> not found error
*/ */
// PATH: /api/login const db = new MongoClient(process.env.DATABASE);
// METHOD: GET const app = express()
// PARAMETERS: pass app.use(express.json())
app.get("/login", (req,res)=>{ app.use(express.urlencoded({ extended: false }));
let pass = req.query.pass; app.use((req,res,next)=>{
req.db = db
if (pass === undefined) next()
return res.json({error: 1})
if (pass !== PASS)
return res.json({error: 2})
res.json({error: 0, token:TOKEN})
}) })
// PATH: /api/logout const { auth, authware } = require("./routes/auth.js")
// METHOD: GET // anything starts with "add"
// PARAMETERS: token // requires admin privs
app.get("/logout", (req,res)=>{ app.use("/*/a*", authware)
let token = req.query.token; const resources = require("./routes/resources.js")
const projects = require("./routes/projects.js")
const blog = require("./routes/blog.js")
const routes = [
resources,
projects,
blog,
auth,
]
if (token === undefined) routes.forEach(route=>{
return res.json({error: 1}) app.use(route.path, route)
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", async (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})
await client.connect()
const db = await client.db("ngn13")
const col = await db.collection("projects")
await col.insertOne({"name":name, "desc":desc, "url":url, "click":0})
await client.close()
res.json({error: 0})
});
// PATH: /api/add_resource
// METHOD: GET
// PARAMETERS: token, name, tags, url
app.get("/add_resource", async (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})
await client.connect()
const db = await client.db("ngn13")
const col = await db.collection("resources")
await col.insertOne({"name":name, "tags":tags.split(","), "url":url})
await client.close()
res.json({error: 0})
});
// PATH: /api/get_projects
// METHOD: GET
// PARAMETERS: NONE
app.get("/get_projects", async (req, res) => {
await client.connect()
const db = await client.db("ngn13")
const col = await db.collection("projects")
const array = await col.find().toArray()
await client.close()
res.json({error: 0, projects:array})
});
// PATH: /api/get_resources
// METHOD: GET
// PARAMETERS: NONE
app.get("/get_resources", async (req, res) => {
await client.connect()
const db = await client.db("ngn13")
const col = await db.collection("resources")
const array = await col.find().toArray()
await client.close()
res.json({error: 0, resources:array})
});
// PATH: /api/add_post
// METHOD: POST
// PARAMETERS: token, title, author, content
app.post("/add_post", async (req, res) => {
let token = req.body.token;
let title = req.body.title;
let author = req.body.author;
let content = req.body.content;
if (
token === undefined ||
title === undefined ||
author === undefined ||
content === undefined
)
return res.json({error: 1})
if (token !== TOKEN)
return res.json({error: 2})
await client.connect()
const db = await client.db("ngn13")
const col = await db.collection("posts")
await col.insertOne({
"title":title,
"author":author,
"date": new Date().toLocaleDateString(),
"content":content
})
await client.close()
res.json({error: 0})
});
// PATH: /api/get_posts
// METHOD: POST
// PARAMETERS: NONE
app.get("/get_posts", async (req, res) => {
await client.connect()
const db = await client.db("ngn13")
const col = await db.collection("posts")
const array = await col.find().toArray()
await client.close()
let newarray = []
for(let i = 0;i<array.length;i++){
newarray.push({
"title":array[i]["title"],
"desc":array[i]["content"]["en"].substring(0, 140) + "...",
"info":`${array[i]["author"]} | ${array[i]["date"]}`
})
}
res.json({error: 0, posts:newarray})
});
// PATH: /api/get_post
// METHOD: POST
// PARAMETERS: id
app.get("/get_post", async (req, res) => {
let id = req.query.id;
await client.connect()
const db = await client.db("ngn13")
const col = await db.collection("posts")
const array = await col.find().toArray()
await client.close()
for(let i = 0;i<array.length;i++){
if(array[i]["title"].toLowerCase().replaceAll(" ", "")===id){
return res.json({error: 0, post:{
"title": array[i]["title"],
"info": `${array[i]["author"]} | ${array[i]["date"]}`,
"content": array[i]["content"],
}})
}
}
res.json({error: 3})
});
// PATH: /api/ping
// METHOD: GET
// PARAMETERS: NONE
app.get("/ping", (req, res) => {
res.send({ error: 0 });
});
export default { export default {
path: "/api", path: "/api",
handler: app, handler: app,
}; }

39
api/routes/auth.js Normal file
View File

@ -0,0 +1,39 @@
const express = require("express")
const { gimmeToken } = require("../util.js")
const auth = express.Router()
auth.path = "/auth"
const PASS = process.env.PASS
let TOKEN = gimmeToken();
function authware(req,res,next){
const token = req.query.token ? req.query.token : req.body.token
if(!token)
return res.json({ error: 1 })
if(token!==TOKEN)
return res.json({ error: 2 })
next()
}
auth.use("/logout", authware)
auth.get("/login", async (req,res)=>{
const pass = req.query.pass
if(!pass)
return res.json({ error: 1 })
if(pass!==PASS)
return res.json({ error: 2 })
res.json({ error: 0, token: TOKEN })
})
auth.get("/logout", async (req,res)=>{
TOKEN = gimmeToken()
res.json({ error: 0 })
})
module.exports = { auth, authware }

93
api/routes/blog.js Normal file
View File

@ -0,0 +1,93 @@
const express = require("express")
const { makeID } = require("../util.js")
const blog = express.Router()
blog.path = "/blog"
blog.get("/sum", async (req,res)=>{
await req.db.connect()
const db = await req.db.db("ngn13")
const col = await db.collection("posts")
const results = await col.find({priv: {$eq: false}}).toArray()
await req.db.close()
let posts = []
for(let i = 0;i<results.length;i++){
posts.push({
"title":results[i]["title"],
"desc":results[i]["content"]
.substring(0, 140) // a short desc
.replaceAll("#", "") // remove all the markdown stuff
.replaceAll("*", "")
.replaceAll("`", "")
.replaceAll("-", "")
+ "...", // add "..." to make it look like desc
"info":`${results[i]["author"]} | ${results[i]["date"]}`
})
}
// reversing so we can get
// the latest posts on the top
res.json({ error: 0, posts: posts.reverse() })
})
blog.get("/get", async (req,res)=>{
const id = req.query.id
await req.db.connect()
const db = await req.db.db("ngn13")
const col = await db.collection("posts")
const results = await col.find().toArray()
await req.db.close()
for(let i = 0;i<results.length;i++){
// id is basically the title of the post
// but ve remove the whitespace
// and make it lowerspace
// for example:
// Online Privacy Guide -> onlineprivacyguide
if(makeID(results[i]["title"])===id){
return res.json(
{
error: 0,
post:{
"title": results[i]["title"],
// info is the subtitle, for example:
// ngn | 01/06/2023
"info": `${results[i]["author"]} | ${results[i]["date"]}`,
"content": results[i]["content"],
}
}
)
}
}
res.json({ error: 3 })
})
blog.post("/add", async (req,res)=>{
console.log("heyy")
const title = req.body.title
const author = req.body.author
const content = req.body.content
const priv = req.body.priv
console.log(title, author, content, priv)
if ( !title || !author || !content || !priv )
return res.json({ error: 1 })
await req.db.connect()
const db = await req.db.db("ngn13")
const col = await db.collection("posts")
await col.insertOne({
"title":title,
"author":author,
"date": new Date().toLocaleDateString(),
"content":content,
"priv": priv
})
await req.db.close()
res.json({ error: 0 })
})
module.exports = blog

35
api/routes/projects.js Normal file
View File

@ -0,0 +1,35 @@
const express = require("express")
const projects = express.Router()
projects.path = "/projects"
projects.get("/get", async (req,res)=>{
await req.db.connect()
const db = await req.db.db("ngn13")
const col = await db.collection("projects")
const results = await col.find().toArray()
await req.db.close()
res.json({ error: 0, projects: results })
})
projects.get("/add", async (req,res)=>{
let name = req.query.name;
let desc = req.query.desc;
let url = req.query.url;
if (!name || !desc || !url )
return res.json({ error: 1 })
await req.db.connect()
const db = await req.db.db("ngn13")
const col = await db.collection("projects")
await col.insertOne({
"name":name,
"desc":desc,
"url":url,
"click":0
})
await req.db.close()
res.json({ error: 0 })
})
module.exports = projects

34
api/routes/resources.js Normal file
View File

@ -0,0 +1,34 @@
const express = require("express")
const resources = express.Router()
resources.path = "/resources"
resources.get("/get", async (req,res)=>{
await req.db.connect()
const db = await req.db.db("ngn13")
const col = await db.collection("resources")
let results = []
if(req.query.sum)
results = await col.find().limit(10).toArray()
else
results = await col.find().toArray()
await req.db.close()
res.json({ error: 0, resources: results })
})
resources.get("/add", async (req,res)=>{
let name = req.query.name;
let tags = req.query.tags;
let url = req.query.url;
if(!name || !tags || !url)
return res.json({"error":1})
await req.db.connect()
const db = await req.db.db("ngn13")
const col = await db.collection("resources")
await col.insertOne({"name":name, "tags":tags.split(","), "url":url})
await req.db.close()
res.json({error: 0})
})
module.exports = resources

View File

@ -8,5 +8,15 @@ function gimmeToken() {
return result; return result;
} }
module.exports = {gimmeToken} function makeID(title){
// this is used in blog.js
// id is basically the title of the post
// but ve remove the whitespace
// and make it lowerspace
// for example:
// Online Privacy Guide -> onlineprivacyguide
return title.toLowerCase().replaceAll(" ", "")
}
module.exports = { gimmeToken, makeID }

View File

@ -12,7 +12,7 @@ import Button from './Button.vue';
export default { export default {
methods: { methods: {
async click(e) { async click(e) {
await axios.get(`/api/logout?token=${localStorage.getItem("token")}`) await axios.get(`/api/auth/logout?token=${localStorage.getItem("token")}`)
localStorage.clear() localStorage.clear()
location.reload() location.reload()
} }

View File

@ -4,11 +4,12 @@
<div class="textareas"> <div class="textareas">
<Input :keyup="function() { }" id="title" placeholder="Post Title" type="text"/> <Input :keyup="function() { }" id="title" placeholder="Post Title" type="text"/>
<Input :keyup="function() { }" id="author" placeholder="Author" type="text"/> <Input :keyup="function() { }" id="author" placeholder="Author" type="text"/>
<h2>
Make the post private
<input id="private" type="checkbox"/>
</h2>
</div> </div>
<div class="textareas"> <textarea name="content" id="content" cols="30" rows="10" placeholder="Content"></textarea>
<textarea nor name="contenten" id="contenten" cols="30" rows="10" placeholder="Content (EN)"></textarea>
<textarea name="contenttr" id="contenttr" cols="30" rows="10" placeholder="Content (TR)"></textarea>
</div>
<Button :click="click">Post</Button> <Button :click="click">Post</Button>
</main> </main>
</template> </template>
@ -23,17 +24,15 @@ export default {
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 contenten = document.getElementById("contenten").value const content = document.getElementById("content").value
const contenttr = document.getElementById("contenttr").value const priv = document.getElementById("private").value
const token = localStorage.getItem("token") const token = localStorage.getItem("token")
const res = await axios.post("/api/add_post", { const res = await axios.post("/api/blog/add", {
token: token, token: token,
title: title, title: title,
author: author, author: author,
content: { content: content,
tr: contenttr, priv: priv==="on"
en: contenten
},
}) })
if(res.data["error"]!==0) if(res.data["error"]!==0)
return alert("Error!") return alert("Error!")
@ -52,9 +51,29 @@ h1{
text-align: center; text-align: center;
} }
h2{
background: var(--dark-two);
font-size: 25px;
border-radius: 20px;
border: none;
padding: 20px;
color: var(--white);
display: flex;
justify-content: space-between;
}
input[type="checkbox"] {
-ms-transform: scale(2);
-moz-transform: scale(2);
-webkit-transform: scale(2);
-o-transform: scale(2);
transform: scale(2);
padding: 10px;
}
textarea{ textarea{
width: 500px; width: 500px;
font-size: 15px; font-size: 20px;
padding: 20px; padding: 20px;
border-radius: 20px; border-radius: 20px;
background: var(--dark-two); background: var(--dark-two);
@ -67,7 +86,7 @@ textarea{
} }
.textareas { .textareas {
flex-direction: row; flex-direction: column;
display: flex; display: flex;
gap: 20px; gap: 20px;
} }

View File

@ -20,7 +20,7 @@ export default {
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/add_project?token=${token}&name=${name}&desc=${desc}&url=${url}`) const res = await axios.get(`/api/projects/add?token=${token}&name=${name}&desc=${desc}&url=${url}`)
if(res.data["error"]!==0) if(res.data["error"]!==0)
return alert("Error!") return alert("Error!")
alert("Project added!") alert("Project added!")

View File

@ -20,7 +20,7 @@ export default {
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/add_resource?token=${token}&name=${name}&tags=${tags}&url=${url}`) const res = await axios.get(`/api/resources/add?token=${token}&name=${name}&tags=${tags}&url=${url}`)
if(res.data["error"]!==0) if(res.data["error"]!==0)
return alert("Error!") return alert("Error!")
alert("Resource added!") alert("Resource added!")

View File

@ -30,8 +30,8 @@ main {
padding: 40px; padding: 40px;
cursor: pointer; cursor: pointer;
transition: .4s; transition: .4s;
height: 13%; height: 100px;
width: 27%; width: 80%;
} }
main:hover{ main:hover{
@ -56,7 +56,7 @@ h2{
@media only screen and (max-width: 1121px) { @media only screen and (max-width: 1121px) {
main{ main{
width: auto; width: 80%;
} }
} }
</style> </style>

View File

@ -15,6 +15,7 @@ div{
display: flex; display: flex;
flex-direction: row; flex-direction: row;
padding: 15px; padding: 15px;
align-items: center;
justify-content: center; justify-content: center;
gap: 30px; gap: 30px;
} }

View File

@ -1,5 +1,6 @@
const express = require("express"); const express = require("express");
const { MongoClient } = require("mongodb"); const { MongoClient } = require("mongodb");
const { makeID } = require("../api/util.js")
require("dotenv").config() require("dotenv").config()
const app = express(); const app = express();
@ -19,11 +20,11 @@ app.get("/:id", async (req,res)=>{
console.log(projects) console.log(projects)
for(let i=0; i<projects.length;i++){ for(let i=0; i<projects.length;i++){
if(projects[i]["name"].toLowerCase().replaceAll(" ", "")===id){ if(makeID(projects[i]["name"])===id){
res.redirect(projects[i]["url"]) res.redirect(projects[i]["url"])
await col.updateOne({name:projects[i]["name"]}, {"$set": {"click": projects[i]["click"]+1}}) await col.updateOne({ name: projects[i]["name"] }, { "$set":
{ "click": projects[i]["click"]+1 }})
return await client.close() return await client.close()
} }
} }
await client.close() await client.close()
@ -33,4 +34,4 @@ app.get("/:id", async (req,res)=>{
export default { export default {
path: "/l", path: "/l",
handler: app, handler: app,
}; }

View File

@ -17,7 +17,6 @@ export default {
link: [ link: [
{ rel: "stylesheet", href: "https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css" }, { rel: "stylesheet", href: "https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css" },
{ rel: "stylesheet", href: "https://cdn.jsdelivr.net/gh/lipis/flag-icons@6.6.6/css/flag-icons.min.css" }
] ]
}, },
css: ["@/static/global.css"], css: ["@/static/global.css"],

View File

@ -1,6 +1,6 @@
{ {
"name": "my-website", "name": "my-website",
"version": "2.2.0", "version": "2.3.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "nuxt", "dev": "nuxt",

View File

@ -6,14 +6,7 @@
<p>{{ post.info }}</p> <p>{{ post.info }}</p>
</Header> </Header>
<div class="postcontain"> <div class="postcontain">
<div class="lang"> <main class="markdown-body" v-html="content"></main>
<button v-if="lang==='en'" class="bl bs">EN <span class="fi fi-gb"></span></button>
<button v-on:click="toggle_lang" v-else class="bl">EN <span class="fi fi-gb"></span></button>
<button v-if="lang==='tr'" class="br bs">TR <span class="fi fi-tr"></span></button>
<button v-on:click="toggle_lang" v-else class="br">TR <span class="fi fi-tr"></span></button>
</div>
<main class="postself" v-if="lang==='en'" v-html="en"></main>
<main class="postself" v-else v-html="tr"></main>
</div> </div>
</div> </div>
</template> </template>
@ -39,30 +32,24 @@ export default {
}; };
}, },
methods: {
toggle_lang(){
this.lang = this.lang==="tr" ? "en" : "tr"
localStorage.setItem("lang", this.lang)
}
},
data() { data() {
return { return {
post: {}, post: {},
lang: "", lang: "",
en: "", content: "",
tr: "",
} }
}, },
async created() { async created() {
const res = await axios.get(`/api/get_post?id=${this.$route.params.id}`) const res = await axios.get(`/api/blog/get?id=${this.$route.params.id}`)
if (res.data["error"] === 3) if (res.data["error"] === 3)
return this.$router.push({ path: "/blog" }) return this.$router.push({ path: "/blog" })
this.post = res.data["post"] this.post = res.data["post"]
this.en = DOMPurify.sanitize(marked.parse(this.post["content"]["en"])) this.content = DOMPurify.sanitize(
this.tr = DOMPurify.sanitize(marked.parse(this.post["content"]["tr"])) marked.parse(this.post["content"], { breaks: true }),
this.lang = localStorage.getItem("lang")!==undefined&&(localStorage.getItem("lang")==="tr"||localStorage.getItem("lang")==="en") ? localStorage.getItem("lang") : "en" { ADD_TAGS: ["iframe"], ADD_ATTR: ['allow', 'allowfullscreen', 'frameborder', 'scrolling'] }
)
} }
} }
@ -77,11 +64,6 @@ p {
font-size: 30px; font-size: 30px;
} }
span{
width: 30px;
border-radius: 5px;
}
.info { .info {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@ -89,90 +71,39 @@ span{
justify-content: center; justify-content: center;
} }
.lang {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-top: 20px;
}
button{
padding: 10px 30px 10px 30px;
font-size: 20px;
background-color: var(--dark-two);
border: none;
cursor: pointer;
color: white
}
.bs{
background-color: var(--dark-three);
}
.bl{
border-radius: 15px 0px 0px 0px;
}
.br{
border-radius: 0px 15px 0px 0px;
}
.postcontain{ .postcontain{
padding: 50px; padding: 50px;
} }
.postself { .markdown-body {
text-align: left; font-size: 25px;
font-size: 30px; padding: 50px;
color: white;
padding: 20px 40px 70px 40px;
line-height: 40px;
border-radius: 15px; border-radius: 15px;
background-color: var(--dark-three); background-color: var(--dark-three);
} }
</style> </style>
<style> <style>
.postself code { @import url("https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.2.0/github-markdown-dark.css");
background: var(--dark-two);
border-radius: 5px; .markdown-body{
font-size: 18px; font-family: "Ubuntu", sans-serif;
padding: 5px;
font-style: italic;
} }
.postself h1{ .markdown-body h1{
margin-top: 70px; border-bottom: 1px solid #505050;
margin-bottom: 20px;
} }
.postself h2{ .markdown-body iframe{
margin-top: 60px; display: block;
margin-bottom: 20px; margin: 20px 0px;
} }
.postself h3{ .markdown-body a{
margin-top: 50px; animation-name: colorAnimation;
margin-bottom: 20px; animation-iteration-count: infinite;
animation-duration: 10s;
text-shadow: none;
} }
.postself h4{
margin-top: 40px;
margin-bottom: 20px;
}
.postself h5{
margin-top: 60px;
margin-bottom: 30px;
}
.postself a{
animation-name: colorAnimation;
animation-iteration-count: infinite;
animation-duration: 10s;
text-shadow: none;
}
li{
list-style-type: none;
}
</style> </style>

View File

@ -6,7 +6,7 @@
</Header> </Header>
<div class="blogs"> <div class="blogs">
<Input :keyup="keyup" placeholder="Search post" type="text"/> <Input :keyup="keyup" placeholder="Search post" type="text"/>
<PostPreview v-for="post in posts" :key="post" :title="post.title" :desc="post.desc" :info="post.info" :url="post.url"> <PostPreview v-for="post in posts" :key="post.title" :title="post.title" :desc="post.desc" :info="post.info" :url="post.url">
{{ post.desc }} {{ post.desc }}
</PostPreview> </PostPreview>
</div> </div>
@ -44,22 +44,20 @@ export default {
mounted: async function () { mounted: async function () {
if (localStorage.getItem("token")) if (localStorage.getItem("token"))
this.logged = true; this.logged = true;
const res = await axios.get("/api/get_posts"); const res = await axios.get("/api/blog/sum");
let posts = []
let array = res.data["posts"] res.data["posts"].forEach(post=>{
let newarray = [] posts.push({
title: post.title,
for(let i=0;i<array.length;i++){ desc: post.desc,
newarray.push({ info: post.info,
title: array[i].title, url: `/blog/${post.title.toLowerCase().replaceAll(" ", "")}`
desc: array[i].desc,
info: array[i].info,
url: `/blog/${array[i].title.toLowerCase().replaceAll(" ", "")}`
}) })
} })
this.posts = newarray; this.posts = posts
this.all = newarray; this.all = posts
}, },
methods: { methods: {
keyup(e) { keyup(e) {

View File

@ -29,15 +29,17 @@
<br> <br>
<a href="https://github.com/ngn13"><i class='bx bxl-github'></i> Github</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>
<br>
<a href="mailto:ngn13proton@proton.me"><i class='bx bxs-envelope'></i> Mail</a> <a href="mailto:ngn13proton@proton.me"><i class='bx bxs-envelope'></i> Mail</a>
<br> <br>
<h2>or private message me on </h2> <h2>or private message me on matrix:</h2>
<a><i>[matrix]</i> @ngn:matrix.ngn13.fun</a> <a><i>[matrix]</i> @ngn:matrix.ngn13.fun</a>
</Card> </Card>
</div> </div>
<Logout v-if="logged"/> <Logout v-if="logged"/>
<div class="version"> <div class="version">
<p>v2.2</p> <p>v2.3</p>
</div> </div>
</div> </div>
</template> </template>

View File

@ -15,7 +15,7 @@ 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/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="/"

View File

@ -35,15 +35,15 @@ export default {
}, },
data() { data() {
return { return {
logged: false, logged: false,
projects: [] projects: []
} }
}, },
mounted: async function(){ mounted: async function(){
if(localStorage.getItem("token")) if(localStorage.getItem("token"))
this.logged = true this.logged = true
const res = await axios.get("/api/get_projects") const res = await axios.get("/api/projects/get")
let all = res.data["projects"] let all = res.data["projects"]
let projects = [] let projects = []

View File

@ -6,7 +6,7 @@
</Header> </Header>
<div class="resources"> <div class="resources">
<Input :keyup="keyup" placeholder="Search resource" type="text"/> <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" /> <Resource v-for="res in show_resources" :key="res.name" :name="res.name" :tags="res.tags" :url="res.url" />
</div> </div>
<NewResource v-if="logged"/> <NewResource v-if="logged"/>
</main> </main>
@ -35,44 +35,59 @@ export default {
return { return {
header: "resources", header: "resources",
logged: false, logged: false,
resources: [], sum_resources: [],
all: [] all_resources: [],
show_resources: []
} }
}, },
methods: { methods: {
keyup(e) { keyup(e) {
let val = e.target.value let search = e.target.value
if(e.key==="Backspace" && val===""){ if(e.key==="Backspace" && search===""){
this.header = "resources" this.header = "resources"
this.resources = this.all this.show_resources = this.sum_resources
return return
} }
if(e.key==="OS") if(e.key==="OS")
return return
this.header = `resources | grep ${val}` this.header = `resources | grep ${search}`
// dirty asf search alg // dirty asf search alg
this.resources = [] this.show_resources = []
for(let i = 0; i < this.all.length; i++){ for(let i = 0; i < this.all_resources.length; i++){
if(this.all[i].name.toLowerCase().includes(val.toLowerCase())) if(this.all_resources[i].name
this.resources.push(this.all[i]) .toLowerCase()
.includes(search.toLowerCase())
){
this.show_resources.push(this.all_resources[i])
continue
}
for(let e = 0; e < this.all[i].tags.length; e++){ for(let e = 0; e < this.all_resources[i].tags.length; e++){
if(this.all[i].tags[e].toLowerCase().includes(val.toLowerCase())){ if(this.all_resources[i].tags[e].toLowerCase()
if(this.resources.indexOf(this.all[i])===-1) .includes(search.toLowerCase())
this.resources.push(this.all[i]) ){
this.show_resources.push(this.all_resources[i])
break
} }
} }
} }
} }
}, },
mounted: async function(){ mounted: async function(){
if(localStorage.getItem("token")) if(localStorage.getItem("token"))
this.logged = true this.logged = true
const res = await axios.get("/api/get_resources") // request top 10 resources so we can
this.resources = res.data["resources"] // render the DOM as fast as possible
this.all = res.data["resources"] 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"]
console.log(res.data["resources"])
} }
} }
</script> </script>