git ssb

0+

mixmix / marama



Tree: e586183460b048c4129a99bab2a2b74d23041492

Files: e586183460b048c4129a99bab2a2b74d23041492 / index.js

3460 bytesRaw
1const h = require('mutant/h')
2
3const MONTH_NAMES = [ 'Ja', 'Fe', 'Ma', 'Ap', 'Ma', 'Ju', 'Ju', 'Au', 'Se', 'Oc', 'No', 'De' ]
4const DAYS = [ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' ]
5
6module.exports = function Marama (opts = {}) {
7 const d = startOfDay()
8 const {
9 year = d.getFullYear(),
10 month = d.getMonth() + 1, // month number (common defn)
11 today = d,
12 events = [],
13 range,
14 setRange = () => {},
15 monthNames = MONTH_NAMES
16 } = opts
17
18 const monthIndex = month - 1 // month number (Date API defn)
19 const monthLength = new Date(year, monthIndex + 1, 0).getDate()
20 // NOTE Date takes month as a monthIndex i.e. april = 3
21 // and day = 0 goes back a day
22 const days = Array(monthLength).fill().map((_, i) => i + 1)
23
24 var weekday
25 var week
26 const offset = getDay(new Date(year, monthIndex, 1)) - 1
27
28 const setMonthRange = (ev) => {
29 setRange({
30 gte: new Date(year, monthIndex, 1),
31 lt: new Date(year, monthIndex + 1, 1)
32 })
33 }
34
35 return h('Marama', [
36 h('div.month-name', { 'ev-click': setMonthRange }, monthNames[monthIndex]),
37 h('div.days',
38 {
39 style: { display: 'grid' }
40 },
41 [
42 DAYS.map((day, i) => DayName(day, i)),
43 days.map(Day)
44 ]
45 )
46 ])
47
48 function Day (day) {
49 const date = new Date(year, monthIndex, day)
50 const dateEnd = new Date(year, monthIndex, day + 1)
51 weekday = getDay(date)
52 week = Math.ceil((day + offset) / 7)
53
54 const eventsOnDay = events.filter(e => {
55 return e.date >= date && e.date < dateEnd
56 })
57
58 const attending = eventsOnDay.some(e => {
59 return e.data.attending
60 })
61
62 const opts = {
63 attributes: {
64 'title': `${year}-${month}-${day}`,
65 'data-date': `${year}-${month}-${day}`
66 },
67 style: {
68 'grid-row': `${weekday} / ${weekday + 1}`,
69 'grid-column': `${week + 1} / ${week + 2}`
70 // column moved by 1 to make space for labels
71 },
72 classList: [
73 date < today ? '-past' : '-future',
74 eventsOnDay.length ? '-events' : '',
75 inRange(date) ? '-range' : '',
76 attending ? '-attending' : ''
77 ],
78 'ev-click': (ev) => {
79 if (ev.shiftKey) {
80 dateEnd >= range.lt
81 ? setRange({ lt: dateEnd })
82 : setRange({ gte: date })
83 return
84 }
85
86 setRange({
87 gte: date,
88 lt: dateEnd
89 })
90 }
91 }
92
93 if (!eventsOnDay.length) return h('MaramaDay', opts)
94
95 return h('MaramaDay', opts, [
96 // TODO add awareness of whether I'm going to events
97 // TODO try a FontAwesome circle
98 h('div.dot', [
99 // Math.random() > 0.3 ? h('div') : ''
100 ])
101 ])
102 }
103
104 function inRange (date) {
105 if (!range || (!range.gte && !range.lt)) return false
106 return (date >= range.gte) && (date < range.lt)
107 }
108}
109
110function DayName (day, index) {
111 return h('MaramaDayName', {
112 style: {
113 'grid-row': `${index + 1} / ${index + 2}`,
114 'grid-column': '1 / 2'
115 }
116 }, day.substr(0, 1))
117}
118
119function getDay (date) {
120 const dayIndex = date.getDay()
121 return dayIndex === 0 ? 7 : dayIndex
122
123 // Weeks run 0...6 (Sun - Sat)
124 // this shifts those days around by 1
125}
126
127function startOfDay (d = new Date()) {
128 return new Date(d.getFullYear(), d.getMonth(), d.getDate())
129}
130
131// function endOfDay (d = new Date()) {
132// return new Date(d.getFullYear(), d.getMonth(), d.getDate() + 1)
133// }
134

Built with git-ssb-web