Files: c570701c242c9ea977861c585348b6ea930a6194 / views / new.js
2578 bytesRaw
1 | const { h, Struct, Array: MutantArray, when, computed } = require('mutant') |
2 | const Marama = require('marama') |
3 | |
4 | module.exports = function ScryNew (opts) { |
5 | const state = Struct({ |
6 | monthIndex: new Date().getMonth(), |
7 | days: MutantArray([]), |
8 | pristine: true |
9 | }) |
10 | |
11 | const page = h('ScryNew', [ |
12 | h('div.cal-picker', [ |
13 | h('div.month-picker', [ |
14 | h('button', { 'ev-click': () => setMonth(-1) }, '<'), |
15 | MonthTitle(state.monthIndex), |
16 | h('button', { 'ev-click': () => setMonth(+1) }, '>') |
17 | ]), |
18 | computed(state, ({ monthIndex, days }) => { |
19 | return Marama({ |
20 | monthIndex, |
21 | events: days, |
22 | onSelect, |
23 | styles: { |
24 | weekFormat: 'rows', |
25 | showNumbers: true, |
26 | tileRadius: 16, |
27 | tileGap: 8 |
28 | } |
29 | }) |
30 | }) |
31 | ]), |
32 | when(state.pristine, |
33 | h('div.time-picker-pristine', [ |
34 | h('label', 'Dates and Times'), |
35 | h('div.instruction', 'Select one or multiple dates') |
36 | ]), |
37 | h('div.time-picker', [ |
38 | h('label', computed(state.days, days => `Same times for all dates (${days.length})`)), |
39 | h('div.picker'), |
40 | h('div.timezone', [ |
41 | h('label', 'Timezone of your scry is'), |
42 | h('div.zone', [ |
43 | getTimezone(), |
44 | h('span', ['(UTC ', getTimezoneOffset(), ')']) |
45 | ]) |
46 | ]) |
47 | ]) |
48 | ) |
49 | ]) |
50 | |
51 | return page |
52 | |
53 | function setMonth (d) { |
54 | state.monthIndex.set(state.monthIndex() + d) |
55 | } |
56 | |
57 | function MonthTitle (monthIndex) { |
58 | const MONTHS = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] |
59 | |
60 | return computed(monthIndex, mi => { |
61 | const view = new Date() |
62 | view.setMonth(mi) |
63 | |
64 | return `${MONTHS[view.getMonth()]} ${view.getFullYear()}` |
65 | |
66 | // while (monthIndex < 0) { monthIndex += 12 } |
67 | // return `${MONTHS[(monthIndex) % 12]} ${year}` |
68 | }) |
69 | } |
70 | |
71 | function onSelect ({ gte, lt, events: days }) { |
72 | if (!days.length) addEmptyEvent() |
73 | else clearDay() |
74 | |
75 | state.pristine.set(false) |
76 | |
77 | function addEmptyEvent () { |
78 | state.days.push({ |
79 | date: gte, |
80 | data: {attending: true} |
81 | }) |
82 | } |
83 | function clearDay () { |
84 | const filteredEvents = state.days().filter(e => !days.includes(e)) |
85 | state.days.set(filteredEvents) |
86 | } |
87 | } |
88 | } |
89 | |
90 | function getTimezone () { |
91 | try { |
92 | return Intl.DateTimeFormat().resolvedOptions().timeZone |
93 | } catch (e) { |
94 | return '??' |
95 | } |
96 | } |
97 | |
98 | function getTimezoneOffset () { |
99 | return new Date().getTimezoneOffset() / 60 |
100 | } |
101 |
Built with git-ssb-web