Calendar.js 5.73 KB
Newer Older
Choi Ga Young's avatar
Choi Ga Young committed
1
2
import React, { useState, useEffect } from 'react';
import { SafeAreaView, StyleSheet, View, Text, FlatList, TouchableOpacity } from 'react-native';
Choi Ga Young's avatar
Choi Ga Young committed
3
import { Button } from 'react-native-elements';
Choi Ga Young's avatar
Choi Ga Young committed
4
import Ionicons from 'react-native-vector-icons/Ionicons';
Choi Ga Young's avatar
Choi Ga Young committed
5
6

const DateItem = ({ dateitem, textColor, onPress, flatListHeight }) => {
Choi Ga Young's avatar
Choi Ga Young committed
7
  return (
Choi Ga Young's avatar
Choi Ga Young committed
8
    <TouchableOpacity onPress={onPress}
Choi Ga Young's avatar
Choi Ga Young committed
9
      style={[style.dateContainer, { height: flatListHeight }]}>
Choi Ga Young's avatar
Choi Ga Young committed
10
      <Text style={textColor}>{dateitem.date.getDate()}</Text>
Choi Ga Young's avatar
Choi Ga Young committed
11
12
13
14
15
16
17
      {
        dateitem.type &&
        <View>
          <Text style={{ color: '#1E90FF' }}>{dateitem.type.input ? dateitem.type.input : null}</Text>
          <Text style={{ color: '#DC143C' }}>{dateitem.type.output ? dateitem.type.output : null}</Text>
        </View>
      }
Choi Ga Young's avatar
Choi Ga Young committed
18
19
20
    </TouchableOpacity>
  );
};
Choi Ga Young's avatar
Choi Ga Young committed
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
const INIT_Data = [
  {
    date: "2021-06-28",
    type: { 'input': 10000, 'output': 1000 },
  },
  {
    date: "2021-07-01",
    type: { 'input': 50000, 'output': 3500 },
  },
  {
    date: "2021-07-11",
    type: { 'input': 100000, 'output': 2000 },
  },
  {
    date: "2021-08-14",
    type: { 'input': 15000, 'output': 2010 },
  },
];
Choi Ga Young's avatar
Choi Ga Young committed
39

Choi Ga Young's avatar
Choi Ga Young committed
40
function Calendar() {
Choi Ga Young's avatar
Choi Ga Young committed
41
42
43
44
45
  const date = new Date();
  const [year, setYear] = useState(date.getFullYear());
  const [month, setMonth] = useState(date.getMonth());
  const todayM = date.getMonth();
  const todayY = date.getFullYear();
Choi Ga Young's avatar
Choi Ga Young committed
46
  const [flatListHeight, setFlatListHeight] = useState(400)
Choi Ga Young's avatar
Choi Ga Young committed
47
48
49
50
51
52
53
54
55
56
57

  const prevLast = new Date(year, month, 0); //이전 달의 마지막 날
  const thisFirst = new Date(year, month, 1); //이번 달의 첫째 날
  const thisLast = new Date(year, month + 1, 0); //이번 달의 마지막 날

  const thisFirstDay = thisFirst.getDay(); //이번 달 첫번 째 요일
  const prevLastDate = prevLast.getDate(); //이전 달 마지막 날짜
  const thisLastDate = thisLast.getDate(); //이번 달 마지막 날짜
  const thisLastDay = thisLast.getDay(); //이번 달 마지막 요일

  // 이번 달 달력에 쓰일 날짜들. 이전달 다음달 전부 포함
Choi Ga Young's avatar
Choi Ga Young committed
58
59
  const Dates = [];
  const DBDates = [];
Choi Ga Young's avatar
Choi Ga Young committed
60
61
  if (thisFirstDay != 0) { // 첫째 날이 일요일이 아니라면
    for (let i = 0; i < thisFirstDay; i++) {
Choi Ga Young's avatar
Choi Ga Young committed
62
      Dates.unshift({ date: new Date(year, month - 1, prevLastDate - i) })
Choi Ga Young's avatar
Choi Ga Young committed
63
    }
Choi Ga Young's avatar
Choi Ga Young committed
64
65
  }
  for (let i = 1; i <= thisLastDate; i++) { //이번 달 날짜 
Choi Ga Young's avatar
Choi Ga Young committed
66
    Dates.push({ date: new Date(year, month, i) })
Choi Ga Young's avatar
Choi Ga Young committed
67
68
  }
  for (let i = 1; i <= 6 - thisLastDay; i++) {
Choi Ga Young's avatar
Choi Ga Young committed
69
    Dates.push({ date: new Date(year, month + 1, i) })
Choi Ga Young's avatar
Choi Ga Young committed
70
  }
Choi Ga Young's avatar
Choi Ga Young committed
71

Choi Ga Young's avatar
Choi Ga Young committed
72
73
74
75
  //DB 데이터와 날짜 비교
  for (let i = 0; i < INIT_Data.length; i++) {
    const str = INIT_Data[i].date
    DBDates.push({ date: new Date(Number(str.slice(0, 4)), Number(str.slice(5, 7)) - 1, Number(str.slice(8, 10))), type: INIT_Data[i].type })
Choi Ga Young's avatar
Choi Ga Young committed
76
77
  }

Choi Ga Young's avatar
Choi Ga Young committed
78
79
80
81
82
83
  for (let i = 0; i < Dates.length; i++) {
    const idx = DBDates.findIndex(obj => obj.date.getTime() == Dates[i].date.getTime())
    if (idx !== -1) {
      Dates[i] = DBDates[idx]
    }
  }
Choi Ga Young's avatar
Choi Ga Young committed
84
85
86
87
88

  let istoday = false;

  const renderDate = ({ item }) => {
    let color = '#000000';
Choi Ga Young's avatar
Choi Ga Young committed
89
    if (item.date.getDate() === date.getDate() && month === todayM && year === todayY) {
Choi Ga Young's avatar
Choi Ga Young committed
90
91
92
93
94
95
      istoday = true;
    }
    if (istoday) {
      color = '#6495ed'
      istoday = false;
    }
Choi Ga Young's avatar
Choi Ga Young committed
96
    if (!(item.date.getMonth() === month)) {
Choi Ga Young's avatar
Choi Ga Young committed
97
98
99
      color = '#a9a9a9'
    }
    return (
Choi Ga Young's avatar
Choi Ga Young committed
100
      <DateItem dateitem={item} textColor={{ color }} flatListHeight={flatListHeight / (Dates.length/ 7)} />
Choi Ga Young's avatar
Choi Ga Young committed
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
    )
  }
  const prevBtn = () => {
    if (month < 1) {
      setYear(year - 1)
      setMonth(11)
    } else {
      setMonth(month - 1)
    }
  };
  const nextBtn = () => {
    if (month > 10) {
      setYear(year + 1)
      setMonth(0)
    } else {
      setMonth(month + 1)
    }
  }
  useEffect(() => {
    setMonth(todayM)
    setYear(todayY)
  }, [])

Choi Ga Young's avatar
Choi Ga Young committed
124
125
  const onLayout = (event) => {
    const { x, y, height, width } = event.nativeEvent.layout;
Choi Ga Young's avatar
Choi Ga Young committed
126
127
    setFlatListHeight(height)
  }
Choi Ga Young's avatar
Choi Ga Young committed
128
129
  return (
    <>
Choi Ga Young's avatar
Choi Ga Young committed
130
      <SafeAreaView style={style.EntContainer}>
Choi Ga Young's avatar
Choi Ga Young committed
131
132
133
134
135
136
137
138
139
140
141
142
        <View style={style.Container}>
          <Text style={style.Head}>{year}  {month + 1} </Text>
          <View style={style.Buttons}>
            <Button icon={
              <Ionicons name='chevron-back-sharp' onPress={prevBtn} size={15} color='black' />
            } type='clear' />
            <Button title='Today' onPress={() => { setMonth(todayM); setYear(todayY) }} type='clear' />
            <Button icon={
              <Ionicons name='chevron-forward-sharp' onPress={nextBtn} size={15} color='black' />
            } type='clear' />
          </View>
        </View>
Choi Ga Young's avatar
Choi Ga Young committed
143
144
145
146
147
148
149
150
151
        <View style={style.Days}>
          <Text style={style.DayText}></Text>
          <Text style={style.DayText}></Text>
          <Text style={style.DayText}></Text>
          <Text style={style.DayText}></Text>
          <Text style={style.DayText}></Text>
          <Text style={style.DayText}></Text>
          <Text style={style.DayText}></Text>
        </View>
Choi Ga Young's avatar
Choi Ga Young committed
152
153
        <FlatList
          onLayout={onLayout}
Choi Ga Young's avatar
Choi Ga Young committed
154
          data={Dates}
Choi Ga Young's avatar
Choi Ga Young committed
155
156
          numColumns={7}
          renderItem={renderDate}
Choi Ga Young's avatar
Choi Ga Young committed
157
          keyExtractor={item => item.date}
Choi Ga Young's avatar
Choi Ga Young committed
158
        />
Choi Ga Young's avatar
Choi Ga Young committed
159
160
161
      </SafeAreaView>
    </>
  )
Choi Ga Young's avatar
Choi Ga Young committed
162
};
Choi Ga Young's avatar
Choi Ga Young committed
163
164

const style = StyleSheet.create({
Choi Ga Young's avatar
Choi Ga Young committed
165
166
167
168
169
  EntContainer: { //전체 (SafeAreaView)
    flex: 1,
    padding: 20
  },
  Head: { //00년00월
Choi Ga Young's avatar
Choi Ga Young committed
170
171
    fontSize: 24,
  },
Choi Ga Young's avatar
Choi Ga Young committed
172
  Container: { //년월, 버튼 뷰에 적용
Choi Ga Young's avatar
Choi Ga Young committed
173
174
175
    justifyContent: "center",
    alignItems: "center",
  },
Choi Ga Young's avatar
Choi Ga Young committed
176
177
178
179
  dateContainer: { //각 date에 적용 (Text 태그), DateItem 컴포넌트에 적용
    flex: 1,
    borderWidth: 0.8,
    borderColor: '#DCDCDC'
Choi Ga Young's avatar
Choi Ga Young committed
180
181
182
183
184
185
  },
  Buttons: {
    flexDirection: 'row',
    margin: 10
  },
  Days: {
Choi Ga Young's avatar
Choi Ga Young committed
186
187
    flexDirection: 'row',
    backgroundColor: '#6495ED'
Choi Ga Young's avatar
Choi Ga Young committed
188

Choi Ga Young's avatar
Choi Ga Young committed
189
  },
Choi Ga Young's avatar
Choi Ga Young committed
190
191
  DayText: {
    flex: 1,
Choi Ga Young's avatar
Choi Ga Young committed
192
193
    textAlign: 'center',
    color: '#FFFFFF'
Choi Ga Young's avatar
Choi Ga Young committed
194
  },
Choi Ga Young's avatar
Choi Ga Young committed
195
196
197
});

export default Calendar;