Skip to content

Commit 57c3da8

Browse files
committed
feature (#1): Migrate data from VuePress.org
1 parent f59947f commit 57c3da8

35 files changed

+6178
-3219
lines changed

.editorconfig

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
indent_style = tab
6+
end_of_line = lf
7+
insert_final_newline = true
8+
trim_trailing_whitespace = true

.gitignore

+19-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1-
node_modules
21
.DS_Store
3-
src/.vuepress/dist
2+
node_modules
3+
/dist
4+
5+
# local env files
6+
.env.local
7+
.env.*.local
8+
9+
# Log files
10+
npm-debug.log*
11+
yarn-debug.log*
12+
yarn-error.log*
13+
14+
# Editor directories and files
15+
.idea
16+
.vscode
17+
*.suo
18+
*.ntvs*
19+
*.njsproj
20+
*.sln

.prettierignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/node_modules/**
2+
/dist/**
3+
/tests/unit/coverage/**

.prettierrc.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module.exports = {
2+
printWidth: 80,
3+
semi: false,
4+
singleQuote: true,
5+
trailingComma: 'none',
6+
bracketSpacing: true,
7+
jsxBracketSameLine: false,
8+
arrowParens: 'avoid',
9+
proseWrap: 'preserve'
10+
}

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
### Added
9+
- Migrate data from VueMeetups.org
810

911
## 0.1.0-alpha - 2019.01.29
1012
### Added

README.md

+17-10
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
# Vue.js Events
22

3-
This site is built with [VuePress](https://vuepress.vuejs.org).
3+
This repo contains the site for Vue.js Events in an effort to centralize all Vue.js community efforts (e.g., meetups, conferences and workshops).
44

5-
## Setup
5+
Please check out the [Issues board](https://github.com/vuejs/events/issues) for discussions and tracking progress.
66

7-
```bash
8-
# Install dependencies
9-
yarn
7+
## Getting Setup
108

11-
# Run local server
12-
yarn dev
9+
### Requirements
1310

14-
# Build production files
15-
yarn build
16-
```
11+
1. [Node.js](https://nodejs.org/en/) v8.0+
12+
1. [yarn](https://yarnpkg.com/en/) - Strongly recommended
13+
14+
### Instructions
15+
16+
1. Fork the repo
17+
1. Clone the repo
18+
1. Run `yarn` or `npm install`
19+
1. Run `yarn dev` or `npm run dev`
20+
21+
## Contributing
22+
23+
This site is built on [VuePress](https://vuepress.vuejs.org/). Please see their [Guide](https://vuepress.vuejs.org/guide/) for more information on how it works.

generate-events.js

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
const fs = require('fs');
2+
const axios = require('axios');
3+
4+
const eventsTimeline = {};
5+
6+
function getYearFromFile(fileName) {
7+
return fileName.replace('.json', '');
8+
}
9+
10+
function getGetOrdinal(n) {
11+
const s = ['th', 'st', 'nd', 'rd'],
12+
v = n % 100;
13+
14+
return `${n}${(s[(v-20)%10]||s[v]||s[0])}`;
15+
}
16+
17+
function addEvent(event) {
18+
const date = new Date(event.startDate);
19+
20+
const year = date.getFullYear();
21+
const locale = 'en-us';
22+
const month = date.toLocaleString(locale, { month: 'long' });
23+
24+
if (!eventsTimeline[year][month]) {
25+
eventsTimeline[year][month] = [];
26+
}
27+
28+
eventsTimeline[year][month].push(event);
29+
}
30+
31+
function removeVueVixensEvents(staticEventsData) {
32+
for (const fileName of staticEventsData) {
33+
const year = getYearFromFile(fileName);
34+
35+
Object.keys(eventsTimeline[year]).forEach((month) => {
36+
const vvEvents = eventsTimeline[year][month]
37+
.filter((event) => event.tag && event.tag === 'vuevixens');
38+
if (vvEvents) {
39+
vvEvents.forEach((event) => {
40+
const existingIndex = eventsTimeline[year][month].findIndex((item) => item.id === event.id);
41+
eventsTimeline[year][month].splice(existingIndex, 1);
42+
});
43+
}
44+
});
45+
}
46+
}
47+
48+
async function getVueVixensEvents() {
49+
let response = await axios.get(`https://api.storyblok.com/v1/cdn/stories/upcoming?version=published&cv=1541163074263&token=${process.env.VV_TOKEN}`);
50+
51+
return response.data.story.content.body.map((event) => ({
52+
id: `vm-${event._uid}`,
53+
date: getGetOrdinal(new Date(event.date).getDate()),
54+
startDate: event.date,
55+
endDate: event.date,
56+
organiser: 'Vue Vixens',
57+
organiserLink: 'https://vuevixens.org',
58+
name: event.name,
59+
eventLink: `https://vuevixens.org/${event.link.cached_url}`,
60+
type: 'workshop',
61+
tag: 'vuevixens',
62+
location: event.location,
63+
}));
64+
}
65+
66+
function getEvents(asyncEvents) {
67+
asyncEvents.forEach((event) => {
68+
addEvent(event)
69+
});
70+
}
71+
72+
function readEventsFromFile(staticEventsData) {
73+
for (const fileName of staticEventsData) {
74+
const year = getYearFromFile(fileName);
75+
const fileNamePath = `./docs/.vuepress/data/${fileName}`;
76+
const data = fs.readFileSync(fileNamePath);
77+
eventsTimeline[year] = JSON.parse(data);
78+
}
79+
}
80+
81+
function writeEventsToFile(staticEventsData) {
82+
for (const fileName of staticEventsData) {
83+
const year = getYearFromFile(fileName);
84+
const fileNamePath = `./docs/.vuepress/data/${fileName}`;
85+
86+
fs.writeFile(fileNamePath, JSON.stringify(eventsTimeline[year], null, 2), () => {});
87+
}
88+
}
89+
90+
async function main() {
91+
const staticEventsData = fs.readdirSync('./docs/.vuepress/data/').filter((fileName) => /.+\.json$/.test(fileName));
92+
93+
console.log('Generating events...')
94+
let asyncEvents = await getVueVixensEvents();
95+
96+
readEventsFromFile(staticEventsData);
97+
removeVueVixensEvents(staticEventsData);
98+
getEvents(asyncEvents);
99+
writeEventsToFile(staticEventsData);
100+
console.log('All events saved to JSON');
101+
}
102+
103+
main();
+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<template>
2+
<div class="event">
3+
<div>
4+
<span class="event__type">{{ event.type }}</span>
5+
<img
6+
v-if="event.tag === 'vuevixens'"
7+
src="/vue-vixens-logo-sm.png"
8+
title="Vue Vixens"
9+
alt="Vue vixens logo"
10+
class="event__logo"/>
11+
<h5 class="event__title">
12+
<a
13+
:href="event.eventLink"
14+
target="_blank"
15+
rel="noopener noreferrer">
16+
{{ event.name }}
17+
</a>
18+
</h5>
19+
<p
20+
v-if="event.organiser"
21+
class="event__organiser">
22+
by
23+
<a
24+
:href="event.organiserLink"
25+
target="_blank"
26+
rel="noopener noreferrer">
27+
{{ event.organiser }}
28+
</a>
29+
</p>
30+
</div>
31+
<footer>
32+
<p class="event__info">
33+
<img
34+
class="event__icon"
35+
src="/calendar.svg"
36+
aria-hidden="true"/>
37+
{{ month }} {{event.date }} {{ event.time }}
38+
</p>
39+
<p class="event__info" v-if="event.location">
40+
<img
41+
class="event__icon"
42+
src="/pin.svg"
43+
aria-hidden="true"/>
44+
{{ event.location }}
45+
</p>
46+
</footer>
47+
</div>
48+
</template>
49+
50+
<script>
51+
export default {
52+
props: {
53+
event: {
54+
type: Object,
55+
required: true,
56+
},
57+
month: {
58+
type: String,
59+
required: true,
60+
}
61+
},
62+
}
63+
</script>
64+
65+
<style>
66+
.event {
67+
display: flex;
68+
flex-direction: column;
69+
justify-content: space-between;
70+
border: 1px solid #eaecef;
71+
padding: 1rem 1.5rem;
72+
margin: 0 0 2rem;
73+
border-radius: 5px;
74+
}
75+
76+
.event__type {
77+
background: #eaecef;
78+
padding: 0.2rem;
79+
border-radius: 5px;
80+
font-size: 12px;
81+
text-transform: uppercase;
82+
margin: 0 0 .5rem;
83+
display: inline-block;
84+
}
85+
86+
.event__title {
87+
font-size: 1.1rem;
88+
margin: 10px 0 5px;
89+
}
90+
91+
.event__organiser {
92+
margin-top: 0;
93+
}
94+
95+
.event__info {
96+
font-size: 0.9rem;
97+
margin: 0;
98+
font-weight: 700;
99+
}
100+
101+
.content:not(.custom) .event__logo {
102+
max-width: 60px;
103+
vertical-align: middle;
104+
float: right;
105+
}
106+
107+
.content:not(.custom) .event__icon {
108+
max-width: 20px;
109+
vertical-align: middle;
110+
}
111+
</style>

0 commit comments

Comments
 (0)