diff --git a/index.html b/index.html index bd15748..bb77844 100644 --- a/index.html +++ b/index.html @@ -8,7 +8,7 @@ -
{{ msg }}
+ diff --git a/server.js b/server.js index 6a6dbc4..63257c0 100644 --- a/server.js +++ b/server.js @@ -5,13 +5,43 @@ const app = express(); const path = require('path'); const fs = require('fs'); const http = require('http'); +const moment = require('moment-timezone'); +moment.tz.setDefault('UTC'); +const serialize = require('serialize-javascript'); app.use('/public', express.static(path.join(__dirname, 'public'))); +let events = [ + { description: 'Random event 1', date: moment('2017-02-06', 'YYYY-MM-DD') }, + { description: 'Random event 2', date: moment('2017-02-15', 'YYYY-MM-DD') }, + { description: 'Random event 3', date: moment('2017-03-14', 'YYYY-MM-DD') } +]; + +let renderer; + app.get('/', (req, res) => { let template = fs.readFileSync(path.resolve('./index.html'), 'utf-8'); - res.send(template); + let contentMarker = ''; + if (renderer) { + renderer.renderToString({ events }, (err, html) => { + if (err) { + console.log(err); + } else { + res.send(template.replace(contentMarker, `\n${html}`)); + } + }); + } else { + res.send('

Awaiting compilation..

'); + } +}); +app.use(require('body-parser').json()); +app.post('/add_event', (req, res) => { + events.push({ + description: req.body.description, + date: moment(req.body.date) + }); + res.sendStatus(200); }); const server = http.createServer(app); @@ -20,6 +50,13 @@ if (process.env.NODE_ENV === 'development') { const reload = require('reload'); const reloadServer = reload(app); require('./webpack-dev-middleware').init(app); + require('./webpack-server-compiler').init(function(bundle) { + let needsReload = (renderer === undefined); + renderer = require('vue-server-renderer').createBundleRenderer(bundle); + if (needsReload) { + reloadServer.reload(); + } + }); } server.listen(process.env.PORT, function () { diff --git a/src/components/App.vue b/src/components/App.vue new file mode 100644 index 0000000..f3a7481 --- /dev/null +++ b/src/components/App.vue @@ -0,0 +1,98 @@ + + diff --git a/src/components/CalendarDay.vue b/src/components/CalendarDay.vue new file mode 100644 index 0000000..c27521b --- /dev/null +++ b/src/components/CalendarDay.vue @@ -0,0 +1,36 @@ + + diff --git a/src/components/CurrentMonth.vue b/src/components/CurrentMonth.vue new file mode 100644 index 0000000..ff1e308 --- /dev/null +++ b/src/components/CurrentMonth.vue @@ -0,0 +1,42 @@ + + diff --git a/src/components/EventForm.vue b/src/components/EventForm.vue new file mode 100644 index 0000000..2721a95 --- /dev/null +++ b/src/components/EventForm.vue @@ -0,0 +1,56 @@ + + diff --git a/src/entry.js b/src/entry.js new file mode 100644 index 0000000..17721df --- /dev/null +++ b/src/entry.js @@ -0,0 +1,34 @@ +import Vue from 'vue'; + +import store from './store'; + +import moment from 'moment-timezone'; +moment.tz.setDefault('UTC'); +Object.defineProperty(Vue.prototype, '$moment', { get() { return this.$root.moment } }); + +import App from './components/App.vue'; + +export default function(events) { + + let initialState = Object.assign({}, store.state, { events }); + store.replaceState(initialState); + + return new Vue({ + data: { + moment + }, + components: { + App + }, + store, + render(createElement) { + return createElement( + 'div', + { attrs: { id: 'app'} }, + [ + createElement('app') + ] + ); + } + }); +} diff --git a/src/node.entry.js b/src/node.entry.js new file mode 100644 index 0000000..7189283 --- /dev/null +++ b/src/node.entry.js @@ -0,0 +1,5 @@ +import VueCalendar from './entry'; + +export default function(context) { + return VueCalendar(context.events); +} diff --git a/src/store/index.js b/src/store/index.js new file mode 100644 index 0000000..b811d2c --- /dev/null +++ b/src/store/index.js @@ -0,0 +1,59 @@ +import Vue from 'vue'; +import Vuex from 'vuex'; +Vue.use(Vuex); + +import moment from 'moment-timezone'; +moment.tz.setDefault('UTC'); + +import Axios from 'axios'; + +export default new Vuex.Store({ + state: { + currentYear: 2017, + currentMonth: 2, + eventFormPosX: 0, + eventFormPosY: 0, + eventFormActive: false, + events: [], + eventFormDate: moment() + }, + mutations: { + setCurrentMonth(state, payload) { + state.currentMonth = payload; + }, + setCurrentYear(state, payload) { + state.currentYear = payload; + }, + eventFormPos(state, payload) { + state.eventFormPosX = payload.x; + state.eventFormPosY = payload.y; + }, + eventFormActive(state, payload) { + state.eventFormActive = payload; + }, + addEvent(state, payload) { + state.events.push(payload); + }, + eventFormDate(state, payload) { + state.eventFormDate = payload + } + }, + actions: { + addEvent(context, payload) { + return new Promise((resolve, reject) => { + let obj = { + description: payload, + date: context.state.eventFormDate + }; + Axios.post('/add_event', obj).then(response => { + if (response.status === 200) { + context.commit('addEvent', obj); + resolve(); + } else { + reject(); + } + }); + }); + } + } +}); diff --git a/src/web.entry.js b/src/web.entry.js index bb38317..ccd859c 100644 --- a/src/web.entry.js +++ b/src/web.entry.js @@ -1,8 +1,17 @@ -import Vue from 'vue' +import './style.scss'; -new Vue({ - el: '#app', - data: { - msg: 'Hello World' +import moment from 'moment-timezone'; +moment.tz.setDefault('UTC'); + +let events = window.__INITIAL_STATE__.map(event => { + return { + description: event.description, + date: moment(event.date) } }); + +import VueCalendar from './entry'; + +setTimeout(function() { + VueCalendar(events).$mount('#app'); +}, 2000);