· 6 years ago · Dec 09, 2019, 06:36 AM
1import React, { Component } from 'react';
2import { StyleSheet, TouchableOpacity, RefreshControl } from 'react-native';
3import { Text, StyleProvider, Icon, View, Card, CardItem, Body, Content,Container } from 'native-base';
4import {SafeAreaView} from 'react-navigation';
5
6
7// css
8
9// constant
10
11// api
12import CalendarService from '@services/CalendarService'
13
14// css
15import getTheme from '@theme/components';
16import material from '@theme/variables/material';
17
18// library
19import moment from 'moment';
20import SkeletonPlaceholder from "react-native-skeleton-placeholder"
21import { Agenda } from 'react-native-calendars';
22import Modal from "react-native-modal";
23
24// component
25
26// screen
27
28// var
29const Entities = require('html-entities').XmlEntities; // npm install html-entities
30const entities = new Entities(); //untuk replace html-entities
31
32export class LoadingSkeleton extends Component {
33 render() {
34 var loadContent = [];
35 for (let i = 1; i <= 6; i++) {
36 loadContent.push(
37 <View key={i} style={{ flexDirection: "row", paddingTop: 10 }}>
38 <View style={{ width: 45, height: 60, marginLeft: 10, borderRadius: 10 }} />
39 <View style={{ marginLeft: 10, flex: 1 }} >
40 <View style={{ width: "97%", height: 60, marginBottom: 10, borderRadius: 10 }} />
41 <View style={{ width: "97%", height: 40, marginBottom: 10, borderRadius: 10 }} />
42 </View>
43 </View>
44 )
45 }
46 return (
47 <View>
48 <SkeletonPlaceholder>
49 <View style={{ width: '100%', height: 103 }} />
50 {loadContent}
51 </SkeletonPlaceholder>
52 </View>
53 );
54 }
55}
56
57export default class SCalendar extends Component {
58 constructor(props) {
59 super(props)
60 this.state = {
61 dataAgenda: [],
62 dataAgenda2: [],
63 loading: false,
64 refreshing: false,
65 };
66 }
67
68 static navigationOptions = {
69 header: null
70 }
71
72 componentDidMount() {
73 this.getAgenda();
74 }
75
76 async getAgenda() {
77 var month = new Date().getMonth() + 1; //Current Month
78 var year = new Date().getFullYear(); //Current Year
79 ApiAgenda = await CalendarService.getAgenda(month, year)
80 await this.setState({
81 dataAgenda: ApiAgenda.result,
82 dataAgenda2: ApiAgenda.result2,
83 loading: false,
84 refreshing: false,
85 })
86 }
87
88 async loadItems(day) {
89 ApiAgenda = await CalendarService.getAgenda(day.month, day.year)
90 await this.setState({
91 dataAgenda: ApiAgenda.result,
92 dataAgenda2: ApiAgenda.result2,
93 loading: false,
94 refreshing: false,
95 })
96 }
97
98 renderItem(item, firstItemInDay) {
99 var calendarTitle = entities.decode(item.agenda)
100 var calendarDesc = entities.decode(item.description)
101 var startDate = moment(item.start_date).format("HH:mm")
102 var endDate = moment(item.end_date).format("HH:mm")
103 return (
104 <TouchableOpacity activeOpacity={0.8} onPress={() => this.props.navigation.navigate('CalendarDetail', { DataId: item.agenda_id })}>
105 <Card transparent style={{ flex: 1, margin: 0, padding: 0, borderWidth: 1, borderColor: '#a8a8a8', marginRight: 10 }}>
106 <CardItem style={{ borderBottomWidth: 1, borderBottomColor: '#f5f5f5', margin: 0, padding: 10, borderTopLeftRadius: 10, borderTopRightRadius: 10 }}>
107 <Body style={{ flexDirection: 'row' }}>
108 <View style={{ flex: 11 }}>
109 <Text numberOfLines={2} style={{ fontWeight: 'bold', fontSize: 16, color: '#3d3d3d', textAlign: 'left' }}>{calendarTitle}</Text>
110 <Text style={{ fontSize: 14, color: '#a8a8a8' }}>{startDate} - {endDate} </Text>
111 </View>
112 <View style={{ flex: 1 }}>
113 <View style={{ width: 15, height: 15, borderRadius: 100, backgroundColor: item.color ? item.color : '#ffffff' }} />
114 </View>
115 </Body>
116 </CardItem>
117 <CardItem style={{ margin: 0, padding: 0, borderBottomLeftRadius: 10, borderBottomRightRadius: 10 }}>
118 <Body>
119 <Text numberOfLines={3} style={{ fontSize: 14, color: '#a8a8a8' }}>{calendarDesc}</Text>
120 </Body>
121 </CardItem>
122 </Card>
123 </TouchableOpacity>
124 );
125 }
126
127 renderEmptyDate() {
128 return (
129 <View
130 style={{
131 marginTop:50,
132 borderBottomColor: '#444444',
133 borderBottomWidth: 1,
134 }}
135 />
136 );
137 }
138
139 renderEmptyData(item, firstItemInDay) {
140 return (
141 <Content
142 refreshControl={
143 <RefreshControl
144 refreshing={this.state.refreshing}
145 onRefresh={this._onRefresh.bind(this)}
146 />
147 }
148 >
149 <Card transparent style={{ borderWidth: 1, borderColor: '#a8a8a8'}}>
150 <CardItem style={{ margin: 10, padding: 10, borderRadius: 10 }}>
151 <Body>
152 <View>
153 <Text numberOfLines={2} style={{ fontSize: 16, color: '#a8a8a8', textAlign: 'left' }}>No Event</Text>
154 </View>
155 </Body>
156 </CardItem>
157 </Card>
158 </Content>
159 );
160 }
161
162 rowHasChanged(r1, r2) {
163 return r1.name !== r2.name;
164 }
165
166 timeToString(time) {
167 const date = new Date(time);
168 return date.toISOString().split('T')[0];
169 }
170
171 _onRefresh() {
172 this.setState({
173 loading: true,
174 refreshing: true,
175 });
176 this.getAgenda();
177 }
178
179 getDot(id, color) {
180 dot = { key: id, color: color };
181 return dot;
182 }
183
184 buildAgenda() {
185 var date = new Date().getDate(); //Current Date
186 var month = new Date().getMonth() + 1; //Current Month
187 var year = new Date().getFullYear(); //Current Year
188 var now = year + '-' + month + '-' + date
189 let newEventMarkers = {};
190 // var counter = 1;
191 if (this.state.dataAgenda2 && this.state.dataAgenda2.length > 0) {
192 this.state.dataAgenda2.map((Feeds, index) => {
193 newEventMarkers[Feeds.start_date] = {
194 dots:
195 [this.getDot(index, Feeds.color ? Feeds.color : '#ba0d0d')]
196 }
197 // if (!(Feeds.start_date in newEventMarkers)) {
198 // newEventMarkers[Feeds.start_date] = {
199 // dots:
200 // [this.getDot(index, Feeds.color ? Feeds.color : '#ba0d0d')]
201 // }
202 // counter = 1
203 // } else {
204 // if (counter < 3) {
205 // newEventMarkers[Feeds.start_date]['dots'].push(
206 // this.getDot(index, Feeds.color ? Feeds.color : '#ba0d0d')
207 // )
208 // counter++
209 // }
210 // }
211 });
212 }
213
214
215 return (
216 <Agenda
217 onCalendarToggled={flag => this.setState({ locked: flag })}
218 renderKnob={() => { return (<Text><Icon name='chevron-down' type='MaterialCommunityIcons' /></Text>); }}
219 firstDay={1}
220 current={now}
221 items={this.state.dataAgenda}
222
223 // loadItemsForMonth={day => this.loadItems(day)}
224 loadItemsForMonth={(day) => {
225 if (this.state.locked) {
226 this.loadItems(day);
227 }
228 }}
229
230 markedDates={newEventMarkers}
231 markingType={'multi-dot'}
232
233 renderItem={this.renderItem.bind(this)}
234
235 renderEmptyData={this.renderEmptyData.bind(this)}
236 renderEmptyDate={this.renderEmptyDate.bind(this)}
237 rowHasChanged={this.rowHasChanged.bind(this)}
238
239 refreshControl={
240 <RefreshControl
241 refreshing={this.state.refreshing}
242 onRefresh={this._onRefresh.bind(this)}
243 />
244 }
245
246 theme={{
247 // knob
248 agendaKnobColor: '#ba0d0d',
249
250 // agenda
251 agendaTodayColor: '#ba0d0d',
252
253 // today
254 todayBackgroundColor: '#FFFACD',
255 todayTextColor: '#444444',
256
257 // selected date
258 selectedDayBackgroundColor: '#ba0d0d',
259 selectedDayTextColor: '#ffffff',
260
261 // dot
262 dotColor: '#ba0d0d',
263 selectedDotColor: '#ffffff',
264 }}
265 />
266 );
267 }
268
269 render() {
270 return (
271 <StyleProvider style={getTheme(material)}>
272 <Container>
273 {this.state.loading ? <LoadingSkeleton /> : this.buildAgenda(this.state)}
274 </Container>
275 </StyleProvider>
276 );
277 }
278}
279
280const stylesx = StyleSheet.create({
281 container: {
282 flex: 1,
283 justifyContent: 'center',
284 alignItems: 'center',
285 backgroundColor: '#f8f9fa',
286 padding: 20,
287 },
288 logo: {
289 fontSize: 80,
290 textAlign: 'center',
291 margin: 10,
292 color: 'grey',
293 },
294 welcome: {
295 fontSize: 20,
296 textAlign: 'center',
297 margin: 10,
298 color: 'grey',
299 },
300 instructions: {
301 textAlign: 'center',
302 color: 'grey',
303 margin: 5,
304 },
305 item: {
306 backgroundColor: 'white',
307 flex: 1,
308 borderRadius: 5,
309 padding: 10,
310 marginRight: 10,
311 marginTop: 17
312 },
313 emptyDate: {
314 height: 15,
315 flex: 1,
316 paddingTop: 30
317 }
318});