카테고리 없음
PathDetails.tsx (세부경로)
김딸기*
2024. 12. 16. 02:43
이 코드는 React Native를 사용하여 작성된 화면으로, 사용자가 선택한 경로에 대한 상세 정보를 보여주는 컴포넌트입니다. 이를 코드별로 나누어 더욱 자세히 설명하겠습니다.
1. 상태와 데이터 관리
const PathDetails = () => {
const {selectedPath, selectedTaxi, isTaxi} = usePathContext();
const [expandedSections, setExpandedSections] = useState<boolean[]>([]);
- usePathContext()는 Context API를 통해 다른 컴포넌트에서 전달된 데이터를 가져오는 훅입니다. 이 훅은 selectedPath, selectedTaxi, isTaxi라는 상태 값을 반환합니다:
- selectedPath: 사용자가 선택한 경로의 정보
- selectedTaxi: 택시 관련 정보 (택시를 선택했을 때 제공됨)
- isTaxi: 현재 선택한 교통수단이 "택시"인지 아닌지를 나타내는 값
- expandedSections: 경로의 상세 정보를 펼치고/숨기는 상태 배열로, 각 경로(역별)별로 펼쳤는지 여부를 나타냅니다.
2. 아이콘 표시 함수 (getStationIcon)
-
// 역별 아이콘을 결정하는 함수 (아이콘 반환)const getStationIcon = (tftype: number) => {if (tftype === 1)return <Icon name="directions-subway" size={20} color="#28cadc" />;if (tftype === 2)return <Icon name="directions-bus" size={20} color="#4CAF50" />;if (tftype === 3)return <Icon name="directions-walk" size={20} color="#fcbb41" />;if (tftype === 4) return <Icon name="local-taxi" size={20} color="#000" />;};
- 지하철(type 1): directions-subway
- 버스(type 2): directions-bus
- 도보(type 3): directions-walk
- 택시(type 4): local-taxi
- 이를 통해 경로에 있는 각 교통수단에 적합한 아이콘을 표시할 수 있습니다.
3. 시간 포맷 함수
const formatBusTime = (busMinutes: any) => Math.floor(busMinutes / 60);
const formatBusTime2 = (busMinutes: any) => Math.floor(busMinutes / 60000);
- formatBusTime: 주어진 시간을 시간 단위로 변환합니다.
- formatBusTime2: 주어진 시간을 분 단위로 변환합니다.
4. 경로 상세보기 토글 함수 (toggleExpand)
const toggleExpand = (index: number) => {
setExpandedSections(prev => {
const updated = [...prev];
updated[index] = !updated[index];
return updated;
});
};
- toggleExpand는 각 경로(역별)의 상세 정보를 펼치거나 숨기도록 합니다.
- expandedSections 배열에서 해당 인덱스의 값을 토글하여, 해당 경로의 상세 정보가 펼쳐지거나 닫힙니다.
5. 택시 에코 점수 팝업
const showPopup = () => {
if (isTaxi === '택시') {
Alert.alert(
`${selectedTaxi.ecoScore}kWh 적립!`,
`환경 보호를 위한 적립 완료!`,
[{text: '확인', style: 'default'}],
);
}
};
- showPopup 함수는 사용자가 택시를 선택했을 때 에코 점수를 보여주는 팝업을 띄웁니다.
- 택시를 이용했을 경우 selectedTaxi.ecoScore에 저장된 값을 kWh 단위로 화면에 표시하며, 환경 보호를 위한 적립이 완료되었음을 알립니다.
6. 경로 정보가 없을 경우
if (!selectedPath) {
return (
<View style={styles.container}>
<Text>경로 데이터를 찾을 수 없습니다.</Text>
</View>
);
}
- selectedPath가 없다면 경로 정보가 없다는 메시지를 화면에 표시합니다.
7. UI 구성
7.1. 상단 공간(지도)
return (
<View style={styles.container}>
{/* 상단 빈 공간에 카카오맵 삽입 */}
<View style={styles.topSection}>
<Text style={styles.header}>지도</Text>
</View>
- 상단에 "지도"라는 제목을 표시하는 부분입니다. 실제 지도 기능은 구현되어 있지 않지만, 지도 화면을 추가할 수 있는 공간이 제공됩니다.
7.2. 하단 경로 정보
{/* 하단 내용 */}
<View style={styles.bottomSection}>
<ScrollView contentContainerStyle={styles.scrollContainer}>
{isTaxi === '택시' && (
<View style={styles.itemContainer}>
{getStationIcon(4)}
<Text style={styles.taxiInfo}> 택시로 이동 </Text>
<Text style={styles.walkInfoTime}>
{formatBusTime2(selectedTaxi.taxi.summary.duration)}분
</Text>
</View>
)}
{selectedPath?.info?.subPath?.map((subPath: any, index: number) => (
<View key={index} style={styles.stationContainer}>
{subPath?.trafficType === 3 ? (
<View style={styles.itemContainer}>
{getStationIcon(3)}
<Text style={styles.walkInfo}>
{' '}
도보 {subPath?.walkRoute?.totalDistance}m{' '}
</Text>
<Text style={styles.walkInfoTime}>
{formatBusTime(subPath?.walkRoute?.totalTime) || 0}분
</Text>
</View>
) : (
<>
<View style={styles.itemContainer}>
{getStationIcon(subPath?.trafficType)}
<Text style={styles.stationName}>
{' '}
{subPath?.startName} 승차 → {subPath?.endName} 하차
</Text>
</View>
<TouchableOpacity onPress={() => toggleExpand(index)}>
<Text style={styles.stationDetail}>
{subPath?.stations?.length}개 이동
</Text>
</TouchableOpacity>
{expandedSections[index] && (
<View style={styles.stationsList}>
{subPath?.stations?.map(
(station: any, stationIndex: number) => (
<Text key={stationIndex} style={styles.stationDetail}>
{station?.stationName}
</Text>
),
)}
</View>
)}
</>
)}
</View>
))}
</ScrollView>
</View>
- 경로에 대한 정보를 스크롤 가능한 뷰(ScrollView)로 구성하였고, 각 경로의 교통수단에 대한 정보는 subPath 배열을 순차적으로 렌더링합니다.
- isTaxi === '택시'일 경우 택시 관련 정보를 먼저 보여줍니다.
- 각 subPath(교통수단)의 정보를 표시하고, 상세 정보 펼치기 기능을 제공합니다. 각 교통수단에 대해 "이동 정류장" 리스트를 보여줍니다.
7.3. 동그란 버튼 (에코 점수)
{/* 동그란 버튼 */}
<TouchableOpacity
style={[
styles.floatingButton,
{backgroundColor: isTaxi === '택시' ? '#4CE5B1' : '#ccc'}, // 택시일 때만 초록색
]}
onPress={showPopup}
disabled={isTaxi !== '택시'} // 택시일 때만 버튼 활성화
>
<Icon name="eco" size={24} color="#fff" />
</TouchableOpacity>
</View>
);
};
- 에코 버튼은 화면 우측 하단에 동그란 버튼으로 배치되며, 택시일 경우만 초록색으로 활성화됩니다.
- 택시일 때만 에코 점수 팝업을 표시하도록 설정되어 있습니다.
8. 스타일링
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f8f8f8',
},
topSection: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
},
map: {
width: '100%',
height: '100%',
},
bottomSection: {
flex: 1,
backgroundColor: '#fff',
borderTopLeftRadius: 15,
borderTopRightRadius: 15,
overflow: 'hidden',
elevation: 5,
},
scrollContainer: {
padding: 15,
},
header: {
fontSize: 24,
fontWeight: 'bold',
},
stationContainer: {
marginBottom: 15,
paddingBottom: 10,
},
stationName: {
fontSize: 16,
fontWeight: 'bold',
},
stationDetail: {
fontSize: 16,
paddingLeft: 20,
color: '#80c6ff',
paddingTop: 5,
},
walkInfo: {
fontWeight: 'bold',
fontSize: 16,
paddingBottom: 10,
},
taxiInfo: {
fontWeight: 'bold',
fontSize: 16,
marginBottom: 15,
paddingBottom: 20,
},
walkInfoTime: {
fontSize: 16,
fontWeight: 'bold',
color: '#555',
paddingBottom: 10,
},
stationsList: {
marginTop: 5,
},
itemContainer: {
flexDirection: 'row',
},
floatingButton: {
position: 'absolute',
bottom: 20,
right: 20,
backgroundColor: '#4CE5B1',
width: 60,
height: 60,
borderRadius: 30,
justifyContent: 'center',
alignItems: 'center',
elevation: 5,
},
});
- styles 객체는 스타일링을 담당하며, 각 컴포넌트에 적용될 스타일을 정의합니다.
- 주요 스타일로는 버튼, 아이콘, 텍스트와 관련된 스타일들이 포함되어 있습니다.
요약
이 코드는 React Native로 교통 경로와 관련된 정보를 사용자에게 제공하는 컴포넌트입니다. 각 경로의 교통수단에 따라 아이콘을 표시하고, 경로에 대한 상세 정보를 펼치거나 숨기며, 택시를 이용한 경우 에코 점수를 팝업으로 제공합니다.
4o mini