Author SHA1 Message Date
Raymonzut 120d6b6941 Merge branch 'beta' into 'master' 2020-07-01 21:02:49 +02:00
Raymonzut b4440c8cc9 Swap /urls for /rss; complete RSS feed 2020-06-29 23:33:31 +02:00
Raymonzut da9024548d Change <loc> format from /posts/:id to /posts?post=:id 2020-06-29 19:16:31 +02:00
Raymonzut bb923a69e7 Create robots.txt 2020-06-29 17:59:41 +02:00
Raymonzut faaf082c8b Preload main page scripts 2020-06-21 14:42:50 +02:00
Raymonzut 79c9398981 Fix #10 2020-06-21 14:40:18 +02:00
Raymonzut bc785a0077 Add meta descriptions 2020-06-20 21:48:21 +02:00
Raymonzut 1a5bc59a99 Move async modules to the body 2020-06-20 21:34:34 +02:00
Raymonzut f4f9092fe8 Preload imported libs 2020-06-20 21:34:01 +02:00
Raymonzut 3e85246344 Async scripts instead of defer; defer is default for modules 2020-06-20 21:03:38 +02:00
Raymonzut 740c584378 Speed-up DNS time by prefetching it 2020-06-20 20:51:31 +02:00
Raymonzut 376f8099b9 Move themes.css into general.css as it is used on every page 2020-06-20 19:55:58 +02:00
Raymonzut c8789bc39e Fix #9 2020-06-20 16:57:00 +02:00
Raymonzut db3c56cfd8 Fix #8 2020-06-17 12:29:33 +02:00
Raymonzut 25b90a3432 Merge branch 'beta' into 'master' 2020-06-16 22:29:25 +02:00
Raymonzut 0cab1479f2 Sync server package(-lock).json to 1.3.0 2020-06-16 22:29:06 +02:00
Raymonzut 8acedc284b Merge branch 'simplify/front-end' into beta
- Ditched node_modules aka the blackhole in the client
2020-06-16 22:20:15 +02:00
Raymonzut ec8bc54437 Remove vue remnants 2020-06-16 22:17:54 +02:00
Raymonzut 1904301eae Make posts links to the post content 2020-06-16 22:15:36 +02:00
Raymonzut b879a4d400 Remove unneeded script imports 2020-06-16 21:39:44 +02:00
Raymonzut c096acdf7d Add dynamic post loading 2020-06-16 21:37:05 +02:00
Raymonzut b0cd041fd9 Readd remote 2020-06-16 21:30:50 +02:00
Raymonzut df3ff8f27c Add questions and answers on qa page 2020-06-16 19:20:21 +02:00
Raymonzut bb7e8f9c89 Fix newline in nginx.conf 2020-06-16 19:11:03 +02:00
Raymonzut 04957ad2fc Add empty posts and qa pages 2020-06-16 19:10:10 +02:00
Raymonzut 914e700056 Remove noscript warning for index.html 2020-06-16 19:09:45 +02:00
Raymonzut 777339c3e1 Allow requesting without .html 2020-06-16 19:07:02 +02:00
Raymonzut 62128bd65b Rename index.css to general.css 2020-06-16 19:01:03 +02:00
Raymonzut d23db35657 Remove old me.js node module 2020-06-16 18:53:22 +02:00
Raymonzut d966729f7e Defer stylesheets 2020-06-16 18:51:57 +02:00
Raymonzut 1a42c6ef77 Add deferred scripts for dynamic age 2020-06-16 18:51:45 +02:00
Raymonzut 318ab4c6ca Fill homepage 2020-06-16 18:49:00 +02:00
Raymonzut 2c7f327892 Add me.mjs with age() 2020-06-16 18:48:26 +02:00
Raymonzut 7506909670 Add /js location nginx 2020-06-16 18:45:46 +02:00
Raymonzut 037c638427 Add mjs mime type 2020-06-16 18:45:16 +02:00
Raymonzut 78c7ef8809 Remove all testing (yes, all) 2020-06-16 18:44:01 +02:00
Raymonzut a93722a356 Style with dragondesign (thx @jelle619) 2020-06-16 17:35:00 +02:00
Raymonzut a6bf99c945 Position the navbar 2020-06-16 17:13:47 +02:00
Raymonzut a910feda62 Reroute /api route to the back-end 2020-06-16 17:13:47 +02:00
Raymonzut cf1ef4257c Add basic 404 page 2020-06-16 17:13:47 +02:00
Raymonzut fb5fc2ede2 Move styling into assets/styling as /css 2020-06-16 17:13:46 +02:00
Raymonzut ce4d17974b Add navbar 2020-06-16 17:13:46 +02:00
Raymonzut 0c566af9a7 Clean index.html 2020-06-16 14:14:26 +02:00
Raymonzut d6c920bf86 Remove redundant babel.config.js 2020-06-16 13:56:31 +02:00
Raymonzut f9f9f7010c Simplify docker to only use nginx 2020-06-16 13:52:44 +02:00
Raymonzut fd991f3dcc Remove all client npm dependencies 2020-06-16 13:52:44 +02:00
Raymonzut 89e22861af Merge branch 'beta' into 'master' 2020-06-16 12:29:09 +02:00
raymonanddependabot[bot] 3d93b6ddb8 Bump websocket-extensions from 0.1.3 to 0.1.4 in /client (#7)
Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-node) from 0.1.3 to 0.1.4.
- [Release notes](https://github.com/faye/websocket-extensions-node/releases)
- [Changelog](https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-06-08 21:46:12 +02:00
raymon 418fc1fad4 Merge pull request #6 from Raymonzut/dependabot/npm_and_yarn/client/websocket-extensions-0.1.4
Bump websocket-extensions from 0.1.3 to 0.1.4 in /client
2020-06-08 20:09:41 +02:00
dependabot[bot] 7f0d95b870 Bump websocket-extensions from 0.1.3 to 0.1.4 in /client
Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-node) from 0.1.3 to 0.1.4.
- [Release notes](https://github.com/faye/websocket-extensions-node/releases)
- [Changelog](https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md)
- [Commits](https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-06-08 06:47:52 +00:00
Raymonzut a8736826bf Respond status 200 application/xml /api/posts/urls 2020-06-02 21:14:06 +02:00
35 changed files with 1278 additions and 13640 deletions
-32
View File
@@ -1,32 +0,0 @@
name: Node.js CI
on:
push:
branches: [ master, beta ]
pull_request:
branches: [ master ]
jobs:
build:
env:
CLIENT_DIR: ./client
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [10.x, 12.x, 13.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
working-directory: ${{env.CLIENT_DIR}}
- run: npm run build --if-present
working-directory: ${{env.CLIENT_DIR}}
- run: npm test
working-directory: ${{env.CLIENT_DIR}}
env:
CI: true
-1
View File
@@ -1,2 +1 @@
**/node_modules **/node_modules
**/dist
+1 -8
View File
@@ -1,11 +1,4 @@
FROM node:latest as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY ./ .
RUN npm run build
FROM nginx as production-stage FROM nginx as production-stage
RUN mkdir /app RUN mkdir /app
COPY --from=build-stage /app/dist /app COPY /public /app
COPY nginx.conf /etc/nginx/nginx.conf COPY nginx.conf /etc/nginx/nginx.conf
-3
View File
@@ -1,3 +0,0 @@
module.exports = {
presets: ['@vue/cli-plugin-babel/preset'],
}
+23 -2
View File
@@ -7,7 +7,10 @@ events {
} }
http { http {
include /etc/nginx/mime.types; include /etc/nginx/mime.types;
default_type application/octet-stream; types {
application/javascript mjs;
}
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" ' '$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'; '"$http_user_agent" "$http_x_forwarded_for"';
@@ -20,8 +23,26 @@ http {
location / { location / {
root /app; root /app;
index index.html; index index.html;
try_files $uri $uri/ /index.html; try_files $uri $uri/ $uri.html $uri/index.html =404;
} }
location /css {
alias /app/assets/styling;
}
location /js {
alias /app/lib;
}
location /api {
proxy_pass https://raymon.dev/api;
proxy_buffering on;
}
error_page 404 /404.html;
location = /404.html {
root /app/error;
}
error_page 500 502 503 504 /50x.html; error_page 500 502 503 504 /50x.html;
location = /50x.html { location = /50x.html {
root /usr/share/nginx/html; root /usr/share/nginx/html;
-13023
View File
File diff suppressed because it is too large Load Diff
-56
View File
@@ -1,56 +0,0 @@
{
"name": "personal-website",
"version": "1.1.0",
"private": true,
"description": "A nice introduction to my chaos",
"main": "src/main.js",
"scripts": {
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"serve": "vue-cli-service serve",
"test": "node test_runner"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Raymonzut/Personal-Website.git"
},
"author": "Raymonzut",
"license": "ISC",
"bugs": {
"url": "https://github.com/Raymonzut/Personal-Website/issues"
},
"homepage": "https://github.com/Raymonzut/Personal-Website#readme",
"dependencies": {
"core-js": "^3.6.5",
"vue": "^2.6.11",
"vue-resource": "^1.5.1",
"vue-router": "^3.1.6"
},
"devDependencies": {
"babel-eslint": "^10.0.3",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.1.2",
"@vue/cli-plugin-babel": "~4.2.0",
"@vue/cli-plugin-eslint": "~4.2.0",
"@vue/cli-service": "~4.2.0",
"vue-template-compiler": "^2.6.11"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}
+36
View File
@@ -0,0 +1,36 @@
:root {
--primary-color: #272736;
--text-color: #ffffeb;
/* Overriding DP DS */
--body-background: var(--primary-color);
--body-color: var(--text-color);
--nav-color: var(--primary-color);
--nav-background: var(--text-color);
--a-color: var(--text-color);
}
nav {
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
}
.question {
font-style: italic;
}
@media (prefers-color-scheme: light) {
:root {
--primary-color: #ffffeb;
--text-color: #272736;
}
}
@media (max-width: 420px) {
#app {
margin-left: 0vw;
margin-right: 0vw;
}
}
+10
View File
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>404</title>
</head>
<body>
This page could not be found, sorry for the inconvenience
</body>
</html>
+44 -16
View File
@@ -1,26 +1,54 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE-edge"> <meta
name="description"
content="Raymon's personal website about his life and projects with a blog.">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Personal Website</title> <title>Raymon Zutekouw</title>
<link rel="preload" href="./lib/me.mjs" as="script" crossorigin="anonymous" type="application/javascript">
<link rel="preload" href="index.mjs" as="script" crossorigin="anonymous" type="application/javascript">
<link rel="dns-prefetch" href="https://cdn.statically.io">
<link defer
rel="stylesheet"
href="https://cdn.statically.io/gh/dragonprojects/dragondesign/master/main.min.css"
media="all"
>
<link defer rel="stylesheet" href="css/general.css" media="all">
<style>
body, html {
padding: 0;
margin: 0;
width: 100%;
}
</style>
</head> </head>
<body> <body>
<noscript> <div id="app">
<strong>This site doesn't work properly without JavaScript enabled. Please enable to continue.</strong> <nav>
</noscript> <a href="/">Home</a>|
<div id="app"></div> <a href="/posts">Posts</a>|
</body> <a href="/qa">QA</a>
</nav>
<h1>Home</h1>
<div>
<h2>Who am I?</h2>
<p>
Hi there, good to see you on my website.
My name is Raymon Zutekouw (<span id="age">born on 29-08-2002</span>)
</p>
<p>
Building software and exploring the wide variety of tools (or making them) is my passion.
To see it in action, checkout the stuff I make on
<a href='https://github.com/Raymonzut'>GitHub</a>.
</p>
<p>
The projects that may be useful to others are open source; for inspiring others and improving each others work.
That is why I am a huge fan of
<a href='https://www.gnu.org/philosophy/free-sw.en.html'>free software</a>.
</p>
</div>
</div>
<script async type="module" src="index.mjs"></script>
</body>
</html> </html>
+4
View File
@@ -0,0 +1,4 @@
import { age } from "./lib/me.mjs"
const age_span = document.getElementById("age")
age_span.textContent = age().toString()
@@ -1,8 +1,4 @@
module.exports = { export function age() {
age: age,
}
function age() {
let birthdate = new Date(2002, 8, 29) let birthdate = new Date(2002, 8, 29)
let now = new Date() let now = new Date()
+24
View File
@@ -0,0 +1,24 @@
export async function getPosts(id) {
const BASE_URL = 'https://raymon.dev'
const BASE_ENDPOINT = '/api/posts'
const URL = BASE_URL + BASE_ENDPOINT + (id ? `/${id}` : '?sort=-1')
let posts = []
return await fetch(URL)
.then(res => res.json())
.then(res => {
if (id !== undefined) {
if (res === undefined) {
throw Error("Response body empty")
}
return [res]
}
else {
return res
}
})
.catch(err => {
console.log(`Error: ${err}`)
})
}
+41
View File
@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta
name="description"
content="Raymon typing nonsense on his blog">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Raymon Zutekouw</title>
<link rel="preload" href="./lib/remote.mjs" as="script" crossorigin="anonymous" type="application/javascript">
<link rel="preload" href="posts.mjs" as="script" crossorigin="anonymous" type="application/javascript">
<link defer
rel="stylesheet"
href="https://cdn.statically.io/gh/dragonprojects/dragondesign/master/main.min.css"
media="all"
>
<link defer rel="stylesheet" href="css/general.css" media="all">
</head>
<body>
<noscript>
<p>
This page isn't as fancy without JavaScript.
Some parts will not load, but this will be minimal.
</p>
</noscript>
<div id="app">
<nav>
<a href="/">Home</a>|
<a href="/posts">Posts</a>|
<a href="/qa">QA</a>
</nav>
<!-- Placeholder for posts -->
<div id="posts"></div>
<script async type="module" src="posts.mjs"></script>
</div>
</body>
</html>
+61
View File
@@ -0,0 +1,61 @@
import { getPosts } from "./lib/remote.mjs"
function toMonthYearString(str) {
const date = new Date(str)
return `${date.toLocaleString('default', { month: 'long' })} ${date.getFullYear()}`
}
async function showPost(id) {
const post_list = await getPosts(id)
const post = post_list[0]
const title = document.createElement("h1")
title.textContent = post.title
const postsDOM = document.getElementById("posts")
postsDOM.appendChild(title)
post.content.split('\n').forEach(paragraph => {
const p = document.createElement("p")
p.innerHTML = paragraph
postsDOM.appendChild(p)
});
}
async function updatePosts() {
const posts = await getPosts()
const months = posts.map(post => toMonthYearString(post.date))
const uniques = Array.from(new Set(posts.map(post => toMonthYearString(post.date))))
const month_lists = uniques.map(month =>
posts.filter(
post => toMonthYearString(post.date) === month
)
)
const postsDOM = document.getElementById("posts")
uniques.forEach((month, i) => {
const month_DOM = document.createElement("h1")
month_DOM.textContent = month
month_lists[i].forEach((post, i) => {
const post_DOM = document.createElement("h6")
post_DOM.textContent = `${post.date.substring(0, 10)} - `
const post_link = document.createElement("a")
post_link.href = 'posts?post=' + post._id
post_link.textContent = post.title
post_DOM.appendChild(post_link)
month_DOM.appendChild(post_DOM)
})
postsDOM.appendChild(month_DOM)
})
}
// Check if a specific post is requested
let url = new URL(document.location.href);
url.searchParams.sort();
let post_id = url.searchParams.values().next().value;
const reg = /([0-9]|[a-f]){24}/
if (post_id && reg.test(post_id)) showPost(post_id)
else updatePosts()
+35
View File
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta
name="description"
content="Raymon answering common questions">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Raymon Zutekouw</title>
<link defer
rel="stylesheet"
href="https://cdn.statically.io/gh/dragonprojects/dragondesign/master/main.min.css"
media="all"
>
<link defer rel="stylesheet" href="css/general.css" media="all">
</head>
<body>
<div id="app">
<nav>
<a href="/">Home</a>|
<a href="/posts">Posts</a>|
<a href="/qa">QA</a>
</nav>
<div>
<h4 class="question">What is this site about?</h4>
<h4>This site is about me and the stuff I make</h4>
<h4 class="question">Why is it still so empty?</h4>
<h4>Because I am framework hopping and now ditching frameworks all together</h4>
</div>
</div>
</body>
</html>
+1
View File
@@ -0,0 +1 @@
User-agent: *
-87
View File
@@ -1,87 +0,0 @@
<template>
<div id="app" :class="theme">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/posts">Posts</router-link> |
<router-link to="/qa">QA</router-link>
</div>
<div>
<button id="toggleThemeButton" @click="toggleTheme">{{ themeToggleVerb }} my eyes</button>
</div>
<router-view />
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
theme: 'dark'
}
},
computed: {
themeToggleVerb: function() {
return this.theme === 'light' ? "Save" : "Hurt"
}
},
methods: {
toggleTheme() {
const themes = ['light', 'dark']
this.theme = themes[(themes.indexOf(this.theme) + 1) % themes.length]
}
},
}
</script>
<style>
.light {
--primary-color: #ffffeb;
--text-color: #272736;
}
.dark {
--primary-color: #272736;
--text-color: #ffffeb;
}
.dark a {
color: #7e7e8f;
}
body {
background-color: var(--primary-color);
}
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: var(--text-color);
padding-top: 60px;
background-color: var(--primary-color);
min-height: 100vh;
}
#toggleThemeButton {
background: var(--primary-color);
border: 0px;
color: var(--text-color);
margin: 0 auto;
margin-right: 0px;
}
@media (min-width:420px) {
#toggleThemeButton {
float:right;
margin-right: 10px;
}
}
</style>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

-40
View File
@@ -1,40 +0,0 @@
<template>
<div>
<h2>Who am I?</h2>
<p>
Hi there, good to see you on my website.
My name is Raymon Zutekouw({{ age }}).
</p>
<p>
Building software and exploring the wide variety of tools (or making them) is my passion.
To see it in action, checkout the stuff I make on
<a href='https://github.com/Raymonzut'>GitHub</a>.
</p>
<p>
The projects that may be useful to others are open source; for inspiring others and improving each others work.
That is why I am a huge fan of
<a href='https://www.gnu.org/philosophy/free-sw.en.html'>free software</a>.
</p>
</div>
</template>
<script>
import me from '../me.js'
export default {
name: 'AboutMe',
computed: {
age: me.age
}
};
</script>
<style scoped>
p {
--margin-side: 12vw;
margin-left: var(--margin-side);
margin-right: var(--margin-side);
}
</style>
-18
View File
@@ -1,18 +0,0 @@
<template>
<div>
{{ a }}
</div>
</template>
<script>
export default {
name: 'Answer',
props: {
a: {
type: String,
required: true,
}
}
}
</script>
-38
View File
@@ -1,38 +0,0 @@
<template>
<div id='qa'>
<Question :q='q'></Question>
<Answer :a='a'></Answer>
</div>
</template>
<script>
import Question from './Question.vue'
import Answer from './Answer.vue'
export default {
name: 'QA',
components: {
Question,
Answer,
},
props: {
q: {
type: String,
required: true,
},
a: {
type: String,
required: true,
}
}
}
</script>
<style scoped>
#qa {
--block-spacing: 7.5em;
margin-top: var(--block-spacing);
margin-bottom: var(--block-spacing);
}
</style>
-27
View File
@@ -1,27 +0,0 @@
<template>
<div id='question_box'>
{{ q }}
</div>
</template>
<script>
export default {
name: 'Question',
props: {
q: {
type: String,
required: true,
}
}
}
</script>
<style scoped>
#question_box {
--text-spacing: 0.75em;
font-style: italic;
margin-top: var(--text-spacing);
margin-bottom: var(--text-spacing);
}
</style>
-14
View File
@@ -1,14 +0,0 @@
import Vue from 'vue'
import VueResource from 'vue-resource'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
Vue.use(VueResource)
new Vue({
render: h => h(App),
router,
}).$mount('#app')
-23
View File
@@ -1,23 +0,0 @@
module.exports = {
getPosts: function(id) {
const BASE_URL = '/api/posts'
const URL = BASE_URL + (id ? `/${id}` : '?sort=-1')
this.$http
.get(URL)
.then(res => {
if (id) {
if (res.body.length === 0) {
throw Error("Response body empty")
}
this.post = res.body
}
else {
this.posts = res.body
}
})
.catch(err => {
console.log(`Error: ${err}`)
})
},
}
-46
View File
@@ -1,46 +0,0 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Posts from '../views/Posts.vue'
import Post from '../views/Post.vue'
import QAPage from '../views/QAPage'
Vue.use(VueRouter)
const routes = [
{
path: "/",
name: "Home",
component: Home,
},
{
path: "/posts",
name: "Posts",
component: Posts,
},
{
path: "/posts/:id",
name: "Post",
component: Post,
props: true,
},
{
path: "/qa",
name: "QA",
component: QAPage
},
]
const exclude_routes = [
{
path: "/api"
}
]
const router = new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes: routes.concat(exclude_routes),
})
export default router
-19
View File
@@ -1,19 +0,0 @@
<template>
<div id="home">
<h1>Home</h1>
<AboutMe></AboutMe>
</div>
</template>
<script>
import AboutMe from '@/components/AboutMe'
export default {
name: "Home",
components: {
AboutMe
},
}
</script>
<style scoped></style>
-45
View File
@@ -1,45 +0,0 @@
<template>
<div id="Post">
<div v-if="Object.keys(post).length">
<h1>{{ post.title }}</h1>
<h5>Written on {{ post.date.substring(0,10)}}</h5>
<p v-for="(p, i) in post.content.split('\n')" :key="i">{{ p }}</p>
</div>
<h2 v-else>Waiting for post</h2>
<br>
Read other <a href="/posts">posts</a>
<br>
</div>
</template>
<script>
import { getPosts } from '../remote'
export default {
name: "Post",
data() {
return {
post: {},
}
},
methods: {
getPosts
},
mounted() {
getPosts.call(this, this._props.id)
},
props: {
id: {
type: String,
name: "id",
validator: val => {
const reg = /([0-9]|[a-f]){24}/
return reg.test(val)
},
}
}
}
</script>
<style scoped></style>
-68
View File
@@ -1,68 +0,0 @@
<template>
<div id="posts" v-if="months.length >= 0">
<h3 class="month" v-for="(month, i) in months" :key="i">
{{ month }}
<div>
<ul>
<li v-for="(postItem, j) in getPostItems(month)" :key="j">
{{ getPostItemDate(postItem) }} –
<a :href="/posts/ + postItem._id">{{ postItem.title }}</a>
</li>
</ul>
</div>
<br>
</h3>
</div>
<h2 v-else>There are no posts yet, but don't worry they will be added soon</h2>
</template>
<script>
import { getPosts } from '../remote'
export default {
name: "Posts",
computed: {
months: function () {
const dates = this.posts.map(post => new Date(post.date))
// Contains the month followed by the year
const months = dates.map(date => `${date.toLocaleString('default', { month: 'long' })} ${date.getFullYear()}`)
const uniques = Array.from(new Set(months))
return uniques
}
},
data() {
return {
posts: []
}
},
methods: {
getPosts,
getPostItems: function (month) {
const month_index = new Date(`1 ${month}`).getMonth()
return this.posts.filter((post) => (new Date(post.date)).getMonth() === month_index)
},
getPostItemDate: function (postItem) {
const date = new Date(postItem.date)
return `${date.getFullYear()} ${date.toLocaleString('default', { month: 'short' })} ${date.getDate()}`
}
},
mounted() {
getPosts.call(this)
},
}
</script>
<style scoped>
ul {
text-align: left;
}
@media (min-width: 420px) {
.month {
text-indent: 1em;
text-align: left;
}
}
</style>
-25
View File
@@ -1,25 +0,0 @@
<template>
<div id="QAPage">
<QA
q="What is this site about? "
a="This site is about me and the stuff I make "
></QA>
<QA
q="Why is it still so empty?"
a="Because I am framework hopping "
></QA>
</div>
</template>
<script>
import QA from '@/components/QA'
export default {
name: "QAPAge",
components: { QA }
}
</script>
<style scoped></style>
-4
View File
@@ -1,4 +0,0 @@
const assert = require('assert').strict
const me = require('../src/me')
assert(me.age() > 0, 'age should return a positive number')
-22
View File
@@ -1,22 +0,0 @@
const { spawn } = require('child_process')
const fs = require('fs')
const dirs = ['./test', './tests']
if (!dirs.some(fs.existsSync)) {
throw Error("Could not find any test directories, looked for: " + dirs)
}
const test_dirs = dirs.filter(fs.existsSync)
test_dirs.forEach(test_dir => {
const files = fs.readdirSync(test_dir)
if (files.length === 0) {
throw Error("Could not find test files in " + test_dir)
}
const childs = files.map(file =>
spawn('node', [`${test_dir}/${file}`], { stdio: 'inherit' })
)
})
+968 -1
View File
File diff suppressed because it is too large Load Diff
+5 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "server", "name": "server",
"version": "1.2.0", "version": "1.3.0",
"description": "The API for the website", "description": "The API for the website",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
@@ -8,10 +8,13 @@
"dev": "nodemon server/index.js" "dev": "nodemon server/index.js"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "Raymonzut",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"fastify": "^2.14.1", "fastify": "^2.14.1",
"fastify-cors": "^3.0.3" "fastify-cors": "^3.0.3"
},
"devDependencies": {
"nodemon": "^2.0.4"
} }
} }
+22 -13
View File
@@ -56,9 +56,9 @@ routes.set('/:id', async (req, res) => {
else res.send(results[0]) else res.send(results[0])
}) })
// For the sitemap.xml, will be listed in the XML Sitemap Index // Dynamic RSS feed
routes.set('/urls', async (req, res) => { routes.set('/rss.xml', async (req, res) => {
const re = /(\/api\/)?(.*)\/urls/g const re = /(\/api\/)?(.*)\/rss/g
const result = [...req.raw.originalUrl.matchAll(re)] const result = [...req.raw.originalUrl.matchAll(re)]
if (!result) { if (!result) {
notFoundResponse(res) notFoundResponse(res)
@@ -68,17 +68,26 @@ routes.set('/urls', async (req, res) => {
const endpoint = result [1] ? result[1][2] : result[0][2] const endpoint = result [1] ? result[1][2] : result[0][2]
// Assumes https // Assumes https
const BASE_URL = 'https://' + req.raw.hostname + endpoint const BASE_URL = 'https://' + req.raw.hostname + endpoint
const urls = posts.map(post => const ITEMS = posts.map(post =>
`\n <url> `\r\n <item>
<loc>${BASE_URL}/${post._id}</loc> <title>${post.title}</title>
<lastmod>${post.date}</lastmod> <link>https://${req.raw.hostname}/posts?post=${post._id}</link>
<changefreq>never</changefreq> <guid>https://${req.raw.hostname}/posts?post=${post._id}</guid>
<priority>0.9</priority> <description>${post.content}</description>
</url>` </item>`
).join("\n") ).join("\n")
const xml = `<?xml version="1.0" encoding="UTF-8"?>\r<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> const xml = `<?xml version="1.0" encoding="UTF-8" ?>\n<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
${urls}\n\r</urlset>` <channel>
res.send(xml) <atom:link href="https://${req.raw.hostname}/api/posts/rss.xml" rel="self" type="application/rss+xml" />
<title>Posts</title>
<link>https://${req.raw.hostname}</link>
<description>Personal blog</description>
<language>en-us</language>
${ITEMS}
</channel>\n</rss>`
res.header('Content-Type', 'application/xml')
res.status(200).send(xml)
}) })
module.exports = routes module.exports = routes