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

Choi Ga Young's avatar
Choi Ga Young committed
6
const DateItem = ({ dateitem, onPress, backgroundColor, textColor, flatListHeight }) => {
Choi Ga Young's avatar
Choi Ga Young committed
7
  return (
Choi Ga Young's avatar
Choi Ga Young committed
8
9
    <TouchableOpacity onPress={onPress}
     style={[style.dateContainer, backgroundColor, {height: flatListHeight}]}>
Choi Ga Young's avatar
Choi Ga Young committed
10
      <Text style={textColor}>{dateitem}</Text>
Choi Ga Young's avatar
Choi Ga Young committed
11
      <Text style={{color:'blue'}}>100,000</Text>
Choi Ga Young's avatar
Choi Ga Young committed
12
13
14
15
16
17
18
19
20
21
    </TouchableOpacity>
  );
};

function Calendar() {
  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
22
  const [flatListHeight, setFlatListHeight] = useState(400)
Choi Ga Young's avatar
Choi Ga Young committed
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

  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(); //이번 달 마지막 요일

  // 이번 달 달력에 쓰일 날짜들. 이전달 다음달 전부 포함
  const tempDates = [];
  if (thisFirstDay != 0) { // 첫째 날이 일요일이 아니라면
    for (let i = 0; i < thisFirstDay; i++) {
      tempDates.unshift(prevLastDate - i);
    } // 이전 달의 마지막 날짜부터 1씩 감소시켜서 배열에 값 추가.
  }
  for (let i = 1; i <= thisLastDate; i++) { //이번 달 날짜 
    tempDates.push(i);
  }
  for (let i = 1; i <= 6 - thisLastDay; i++) {
    tempDates.push(i);
  }
  const dates = tempDates.map((element, index) => ({ key: `${index}`, idates: element }));

  const thisfirstID = tempDates.indexOf(1); // 이번 달 1일
  const thislastID = tempDates.lastIndexOf(thisLastDate); // 이번 달 마지막 날짜 인덱스

  let istoday = false;

  const [selectedKey, setSelectedKey] = useState(null);

  const renderDate = ({ item }) => {
Choi Ga Young's avatar
Choi Ga Young committed
56
    const backgroundColor = item.key === selectedKey ? '#87ceeb' : '#FFFAFA';
Choi Ga Young's avatar
Choi Ga Young committed
57
58
59
60
61
62
63
64
65
66
67
68
    let color = '#000000';
    if (item.idates === date.getDate() && month === todayM && year === todayY) {
      istoday = true;
    }
    if (istoday) {
      color = '#6495ed'
      istoday = false;
    }
    if (!(item.key >= thisfirstID && item.key < thislastID + 1)) {
      color = '#a9a9a9'
    }
    return (
Choi Ga Young's avatar
Choi Ga Young committed
69
      <DateItem dateitem={item.idates} onPress={() => setSelectedKey(item.key)} backgroundColor={{ backgroundColor }} textColor={{ color }} flatListHeight={flatListHeight / 5} />
Choi Ga Young's avatar
Choi Ga Young committed
70
71
72
73
    )
  }

  const prevBtn = () => {
Choi Ga Young's avatar
Choi Ga Young committed
74
    setSelectedKey(null)
Choi Ga Young's avatar
Choi Ga Young committed
75
76
77
78
79
80
81
82
83
    if (month < 1) {
      setYear(year - 1)
      setMonth(11)
    } else {
      setMonth(month - 1)
    }
  };

  const nextBtn = () => {
Choi Ga Young's avatar
Choi Ga Young committed
84
    setSelectedKey(null)
Choi Ga Young's avatar
Choi Ga Young committed
85
86
87
88
89
90
91
92
93
94
95
96
97
98
    if (month > 10) {
      setYear(year + 1)
      setMonth(0)
    } else {
      setMonth(month + 1)
    }
  }

  useEffect(() => {
    setMonth(todayM)
    setYear(todayY)
    setSelectedKey(null)
  }, [])

Choi Ga Young's avatar
Choi Ga Young committed
99
100
101
102
  const onLayout=(event)=> {
    const {x, y, height, width} = event.nativeEvent.layout;
    setFlatListHeight(height)
  }
Choi Ga Young's avatar
Choi Ga Young committed
103
104
  return (
    <>
Choi Ga Young's avatar
Choi Ga Young committed
105
      <SafeAreaView style={style.EntContainer}>
Choi Ga Young's avatar
Choi Ga Young committed
106
107
108
109
110
111
112
113
114
115
116
117
        <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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
        <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>
        <FlatList style={style.ListContainer}
        onLayout={onLayout}
          contentContainerStyle={style.wrapper}
          data={dates}
          numColumns={7}
          renderItem={renderDate}
          extraData={selectedKey} />
Choi Ga Young's avatar
Choi Ga Young committed
134
135
136
137
138
139
      </SafeAreaView>
    </>
  )
}

const style = StyleSheet.create({
Choi Ga Young's avatar
Choi Ga Young committed
140
141
142
143
144
145
146
147
148
  wrapper: {
    alignItems: 'stretch',
    alignContent: 'stretch'
  },
  EntContainer: { //전체 (SafeAreaView)
    flex: 1,
    padding: 20
  },
  Head: { //00년00월
Choi Ga Young's avatar
Choi Ga Young committed
149
150
    fontSize: 24,
  },
Choi Ga Young's avatar
Choi Ga Young committed
151
  Container: { //년월, 버튼 뷰에 적용
Choi Ga Young's avatar
Choi Ga Young committed
152
153
154
    justifyContent: "center",
    alignItems: "center",
  },
Choi Ga Young's avatar
Choi Ga Young committed
155
156
157
158
  dateContainer: { //각 date에 적용 (Text 태그), DateItem 컴포넌트에 적용
    flex: 1,
    borderWidth: 0.8,
    borderColor: '#DCDCDC'
Choi Ga Young's avatar
Choi Ga Young committed
159
160
161
162
163
164
165
166
  },
  Buttons: {
    flexDirection: 'row',
    margin: 10
  },
  Days: {
    flexDirection: 'row'
  },
Choi Ga Young's avatar
Choi Ga Young committed
167
168
169
170
  DayText: {
    flex: 1,
    textAlign: 'center'
  },
Choi Ga Young's avatar
Choi Ga Young committed
171
172
173
});

export default Calendar;