- Ditched node_modules aka the blackhole in the clientmaster
commit
8acedc284b
32 changed files with 266 additions and 13622 deletions
@ -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,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 |
||||||
|
@ -1,3 +0,0 @@ |
|||||||
module.exports = { |
|
||||||
presets: ['@vue/cli-plugin-babel/preset'], |
|
||||||
} |
|
File diff suppressed because it is too large
Load Diff
@ -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" |
|
||||||
] |
|
||||||
} |
|
@ -0,0 +1,15 @@ |
|||||||
|
nav { |
||||||
|
border-bottom-left-radius: 5px; |
||||||
|
border-bottom-right-radius: 5px; |
||||||
|
} |
||||||
|
|
||||||
|
@media (max-width: 420px) { |
||||||
|
#app { |
||||||
|
margin-left: 0vw; |
||||||
|
margin-right: 0vw; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.question { |
||||||
|
font-style: italic; |
||||||
|
} |
@ -0,0 +1,18 @@ |
|||||||
|
: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); |
||||||
|
} |
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) { |
||||||
|
:root { |
||||||
|
--primary-color: #ffffeb; |
||||||
|
--text-color: #272736; |
||||||
|
} |
||||||
|
} |
@ -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> |
@ -1,26 +1,49 @@ |
|||||||
<!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="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> |
||||||
|
|
||||||
<style> |
<link defer |
||||||
body, html { |
rel="stylesheet" |
||||||
padding: 0; |
href="https://cdn.statically.io/gh/dragonprojects/dragondesign/master/main.min.css" |
||||||
margin: 0; |
media="all" |
||||||
width: 100%; |
> |
||||||
} |
<link defer rel="stylesheet" href="css/themes.css" media="all"> |
||||||
</style> |
<link defer rel="stylesheet" href="css/general.css" media="all"> |
||||||
</head> |
|
||||||
|
|
||||||
|
<script defer type="module" src="index.mjs"></script> |
||||||
|
|
||||||
|
</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> |
||||||
|
</body> |
||||||
</html> |
</html> |
||||||
|
@ -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() |
||||||
|
|
@ -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}`) |
||||||
|
}) |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8"> |
||||||
|
<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/themes.css" media="all"> |
||||||
|
<link defer rel="stylesheet" href="css/general.css" media="all"> |
||||||
|
|
||||||
|
<script defer type="module" src="posts.mjs"></script> |
||||||
|
|
||||||
|
</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> |
||||||
|
</div> |
||||||
|
</body> |
||||||
|
</html> |
@ -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.textContent = 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() |
@ -0,0 +1,33 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8"> |
||||||
|
<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/themes.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,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> |
|
||||||
|
|
Before Width: | Height: | Size: 6.7 KiB |
@ -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> |
|
@ -1,18 +0,0 @@ |
|||||||
<template> |
|
||||||
<div> |
|
||||||
{{ a }} |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
export default { |
|
||||||
name: 'Answer', |
|
||||||
props: { |
|
||||||
a: { |
|
||||||
type: String, |
|
||||||
required: true, |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
</script> |
|
||||||
|
|
@ -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> |
|
@ -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> |
|
@ -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') |
|
@ -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}`) |
|
||||||
}) |
|
||||||
}, |
|
||||||
} |
|
@ -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 |
|
@ -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> |
|
@ -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> |
|
@ -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> |
|
@ -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> |
|
@ -1,4 +0,0 @@ |
|||||||
const assert = require('assert').strict |
|
||||||
const me = require('../src/me') |
|
||||||
|
|
||||||
assert(me.age() > 0, 'age should return a positive number') |
|
@ -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' })
|
|
||||||
) |
|
||||||
}) |
|
Loading…
Reference in new issue