전체적인 앱 구조 설계
앱 설계 아이디어
DateP 앱은 간단하면서 직관적인 구조로 구성됩니다. 아래는 앱의 전체적인 설계 개요입니다.
탭 네비게이션 사용
- Home 탭: 사용자 입력 (취미, 나이, 데이트 코스 선택 등).
- Result 탭: 이전에 추천받은 결과를 확인하고 저장할 예정(아직 개발 중).
각 화면의 역할
- Home 화면:
- 데이트 추천을 위한 입력값을 수집하고, 결과를 반환하는 주요 인터페이스.
- 사용자 입력 필드와 Select 컴포넌트를 활용하여 동적인 UI 제공.
- Result 화면:
- 추천받은 결과의 히스토리를 저장하고 다시 볼 수 있는 기능 제공 예정.
설계 목표
- 직관적이고 사용하기 쉬운 UI를 제공.
- Gluestack UI의 컴포넌트를 최대한 활용하여 일관성 있는 디자인 구현.
- 사용자가 추천 결과를 쉽게 볼 수 있도록 모달을 활용하여 데이터를 표시할 계획.
구현 방법
탭 네비게이션
- 앱의 주요 화면 전환은 탭 네비게이션을 통해 이루어집니다.
- expo-router 또는 React-Navigation의 BottomTabNavigator를 사용하여 구현.
추천 결과 표시
- 현재 Result 화면은 개발 중이며, 추천 결과는 **모달(Modal)**을 활용해 사용자에게 표시할 예정.
탭 구조 코드
import React from 'react';
import { Tabs } from 'expo-router';
export default function Layout() {
return (
<Tabs
screenOptions={{
tabBarActiveTintColor: '#2D9CDB',
headerShown: false,
}}
>
{/* Home 화면 */}
<Tabs.Screen
name="home"
options={{
title: 'Home',
tabBarIcon: ({ color }) => (
<IconSymbol size={28} name="house.fill" color={color} />
),
}}
/>
{/* Result 화면 (개발 예정) */}
<Tabs.Screen
name="result"
options={{
title: 'Result',
tabBarIcon: ({ color }) => (
<IconSymbol size={28} name="checkmark.seal.fill" color={color} />
),
}}
/>
</Tabs>
);
}
현재 진행 상황
- Home 화면 작업
- 사용자가 입력할 수 있는 Input과 Select 컴포넌트를 배치.
- 입력값을 기반으로 추천 결과를 생성하는 "추천받기" 버튼 제공.
- 전체적인 화면의 레이아웃은 Gluestack UI의 Box, Input, Select 컴포넌트로 구성.
- Result 화면
- 아직 구현되지 않았으나, 사용자가 추천받은 결과를 확인할 수 있도록 리스트 형태로 제공할 예정.
- 추천 결과 표시
- 사용자가 추천받은 결과는 **모달(Modal)**을 통해 보여줄 계획.
- Gluestack UI와 React-Native의 Modal을 활용해 간단하고 시각적으로 깔끔한 UI를 제공할 예정.
코드 스니펫: Home 화면 기초
import React from 'react';
import { Box, Heading, Input, InputField, Button, ButtonText } from '@/components/ui';
import CustomSelect from '@/components/CustomSelect';
import { selectOptions } from '@/src/data/optionsData';
export default function HomeScreen() {
const [select1, setSelect1] = React.useState('');
const [select1Sub, setSelect1Sub] = React.useState('');
return (
<Box className="flex-1 p-4 bg-gray-50">
<Heading className="text-center mb-4" size="lg">
데이트 플랜 추천
</Heading>
{/* 메뉴 선택 */}
<CustomSelect
options={selectOptions.menu}
placeholder="메뉴 선택"
selectedValue={select1}
onValueChange={(value) => {
setSelect1(value);
setSelect1Sub('');
}}
/>
{select1 && (
<CustomSelect
options={selectOptions[select1]}
placeholder="세부 옵션 선택"
selectedValue={select1Sub}
onValueChange={setSelect1Sub}
/>
)}
{/* 추천받기 버튼 */}
<Button className="mt-4 bg-blue-500">
<ButtonText className="text-white">추천받기</ButtonText>
</Button>
</Box>
);
}
Gluestack UI 컴포넌트 분리 작업
Home 화면에서 Gluestack UI의 Select 컴포넌트를 반복적으로 호출하면서 코드가 길어지는 문제를 해결하기 위해, CustomSelect.tsx라는 별도 컴포넌트를 생성하여 사용했습니다. 이를 통해 재사용 가능하고 간결한 코드를 유지할 수 있습니다.
CustomSelect.tsx 코드
import React from 'react';
import {
Select,
SelectTrigger,
SelectInput,
SelectIcon,
SelectPortal,
SelectBackdrop,
SelectContent,
SelectItem,
SelectDragIndicator,
SelectDragIndicatorWrapper,
} from '@/components/ui/select';
import { ChevronDownIcon } from './ui/icon';
import { ScrollView, StyleSheet } from 'react-native';
type CustomSelectProps = {
options: { label: string; value: string }[];
placeholder: string;
onValueChange: (value: string) => void;
selectedValue: string;
};
export default function CustomSelect({
options,
placeholder,
onValueChange,
selectedValue,
}: CustomSelectProps) {
return (
<Select onValueChange={onValueChange} selectedValue={selectedValue}>
<SelectTrigger
variant="outline"
size="xl"
style={{
width: '100%',
paddingHorizontal: 10,
alignItems: 'center',
}}
>
<SelectInput
placeholder={placeholder}
style={{
textAlign: 'left',
width: '85%',
paddingRight: 10,
fontSize: 14,
overflow: 'hidden',
textOverflow: 'ellipsis',
}}
/>
<SelectIcon
as={ChevronDownIcon}
style={{
position: 'absolute',
right: 10,
}}
/>
</SelectTrigger>
<SelectPortal>
<SelectBackdrop />
<SelectContent style={styles.selectContent}>
<ScrollView
style={styles.scrollContainer}
contentContainerStyle={styles.scrollContent}
>
<SelectDragIndicatorWrapper>
<SelectDragIndicator />
</SelectDragIndicatorWrapper>
{options.map((option) => (
<SelectItem
key={option.value}
label={option.label}
value={option.value}
style={styles.selectItem}
/>
))}
</ScrollView>
</SelectContent>
</SelectPortal>
</Select>
);
}
const styles = StyleSheet.create({
selectContent: {
width: '100%',
alignSelf: 'center',
borderRadius: 8,
backgroundColor: '#fff',
},
scrollContainer: {
width: '100%',
maxHeight: 400,
},
scrollContent: {
flexGrow: 1,
},
selectItem: {
paddingVertical: 10,
borderBottomWidth: 1,
borderBottomColor: '#ccc',
},
});
결과물
- 앱이 탭 네비게이션을 통해 Home 화면을 중심으로 동작.
- CustomSelect.tsx로 Select 컴포넌트를 모듈화하여 코드 재사용성을 높임.
- 현재 Result 화면은 개발 중이며, 추천 결과는 **모달(Modal)**을 통해 사용자에게 표시할 예정.
주요 내용 요약
- 앱 구조 설계: Gluestack UI와 React-Navigation을 활용하여 Home 화면 구성.
- 코드 재사용성 개선: CustomSelect.tsx로 Select 컴포넌트를 분리하여 코드 간결화.
- 추천 결과는 모달로 표시하여 사용자 경험을 개선할 예정.
'DateP' 카테고리의 다른 글
| 📌 Google Places API 비용 절감 및 최적화: 구조 개선 & Firebase Functions 적용 계획 (0) | 2025.02.04 |
|---|---|
| 🔥 Firebase Functions & Google Places API 연동 및 React Native 연결 과정 정리 (0) | 2025.02.03 |
| google place api 사용법 (0) | 2025.01.27 |
| 옵션 데이터 관리 (0) | 2025.01.09 |
| DateP 프로젝트 초기 설정 (0) | 2025.01.09 |