Last active
December 1, 2016 05:03
-
-
Save samcorcos/69c57728cae1b7b0a1b3a2f548d98935 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react' | |
import { View, Text, TouchableOpacity, } from 'react-native' | |
import style from './style' | |
const pipe = (fns, init) => fns.reduce((acc, fn) => fn(acc), init) | |
const monthLabels = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] | |
const getDaysInMonth = (month, year) => { | |
if (month === 1) { | |
if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) { | |
return 29 | |
} | |
} | |
const daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] | |
return daysInMonth[month] | |
} | |
const dateValues = (c) => { | |
const month = c.getMonth() | |
const year = c.getFullYear() | |
const daysInMonth = getDaysInMonth(month, year) | |
return { | |
month, | |
firstDay: new Date(year, month, 1).getDay(), | |
daysInMonth, | |
} | |
} | |
const renderDayLabels = () => { | |
const dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] | |
return dayLabels.map((day) => { | |
return ( | |
<View | |
key={day} | |
style={style.dayLabel}> | |
<Text> | |
{day} | |
</Text> | |
</View> | |
) | |
}) | |
} | |
/** | |
creates array based on number of days in current month | |
*/ | |
const createArray = d => Array(d).fill(1).map((v, i) => v + i) | |
/** | |
takes in the day of the week of the first day (as an index) and returns a new | |
array with null values for each day that comes before the first day | |
*/ | |
const addEmptyValues = (firstDay) => (a) => { | |
const l = (firstDay + a.length) % 7 | |
// TODO need to add values to the end (should be 3 for November) | |
return [...Array((firstDay)).fill(null), ...a, ...Array((l)).fill(null)] | |
} | |
const splitRows = (arr) => { | |
return arr.map((d, i) => { | |
if (i % 7 === 0) return arr.slice(i, (i + 7)) | |
return undefined | |
}).filter(e => e !== undefined) | |
} | |
/** | |
takes in an array | |
=> [null, null, 1, 2...30] | |
*/ | |
const renderWeek = (arr) => { | |
const daysArray = arr.map((day) => { | |
if (day === null) return (<View style={style.emptyCalendarItem} />) | |
return (<Text style={style.calendarItem}>{day}</Text>) | |
}) | |
return ( | |
<View style={style.calendarRow}> | |
{daysArray} | |
</View> | |
) | |
} | |
/** | |
takes in an array of arrays | |
=> [ [null, null, 1...4], [5...11], ... ] | |
*/ | |
const renderAllWeeks = (arr) => { | |
return arr.map((week) => { | |
return renderWeek(week) | |
}) | |
} | |
const renderCalendarRows = (firstDay, daysInMonth) => { | |
return pipe([ | |
createArray, // => [1, 2...30] | |
addEmptyValues(firstDay), // => [null, null, 1, 2...30, null, null, null] | |
splitRows, // => [ [null, null, 1...4], [5...11], ... ] | |
renderAllWeeks, // => JSX | |
], daysInMonth) | |
} | |
const Calendar = (props) => { | |
const { month, firstDay, daysInMonth, } = dateValues(props.date) | |
return ( | |
<View> | |
<Text style={{ textAlign: 'center', }}>{monthLabels[month]}</Text> | |
<View | |
style={style.dayLabelRow}> | |
{renderDayLabels()} | |
</View> | |
<View | |
style={style.calendar}> | |
{renderCalendarRows(firstDay, daysInMonth)} | |
</View> | |
</View> | |
) | |
} | |
Calendar.propTypes = { | |
date: React.PropTypes.shape({ | |
// TODO how to represent this as proptypes? date type? | |
}), | |
} | |
export default Calendar |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment