- 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 |
||||
RUN mkdir /app |
||||
COPY --from=build-stage /app/dist /app |
||||
COPY /public /app |
||||
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> |
||||
<html lang="en"> |
||||
|
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<meta http-equiv="X-UA-Compatible" content="IE-edge"> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
<title>Personal Website</title> |
||||
<title>Raymon Zutekouw</title> |
||||
|
||||
<style> |
||||
body, html { |
||||
padding: 0; |
||||
margin: 0; |
||||
width: 100%; |
||||
} |
||||
</style> |
||||
</head> |
||||
<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="index.mjs"></script> |
||||
|
||||
</head> |
||||
<body> |
||||
<noscript> |
||||
<strong>This site doesn't work properly without JavaScript enabled. Please enable to continue.</strong> |
||||
</noscript> |
||||
<div id="app"></div> |
||||
</body> |
||||
<div id="app"> |
||||
<nav> |
||||
<a href="/">Home</a>| |
||||
<a href="/posts">Posts</a>| |
||||
<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> |
||||
|
@ -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 = { |
||||
age: age, |
||||
} |
||||
|
||||
function age() { |
||||
export function age() { |
||||
let birthdate = new Date(2002, 8, 29) |
||||
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