Skip to content

Commit ece0166

Browse files
authored
merge: 랜딩 페이지 추가 (#34)
2 parents 4a12e76 + df4d366 commit ece0166

File tree

9 files changed

+225
-0
lines changed

9 files changed

+225
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { View } from 'react-native';
2+
3+
export default function MockUp() {
4+
return (
5+
<View
6+
style={{
7+
width: 330,
8+
backgroundColor: '#FFFFFF',
9+
borderRadius: 30,
10+
height: 700,
11+
alignItems: 'center',
12+
justifyContent: 'center',
13+
}}
14+
>
15+
<View
16+
style={{
17+
width: 310,
18+
backgroundColor: '#EAEAEC',
19+
borderRadius: 20,
20+
height: 680,
21+
}}
22+
/>
23+
</View>
24+
);
25+
}

packages/react-native/src/pages/Home.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ export default function Home({ navigation }: HomeScreenProps) {
7676
<Button onPress={() => navigation.navigate('Camera')}>
7777
<Text className="text-SPOT-white">카메라</Text>
7878
</Button>
79+
{/* FIXME: 추후 삭제 */}
80+
<Button onPress={() => navigation.navigate('Landing')}>
81+
<Text className="text-SPOT-white">랜딩</Text>
82+
</Button>
7983
</View>
8084
<View>
8185
<SearchBar
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import { useState } from 'react';
2+
import {
3+
Dimensions,
4+
NativeScrollEvent,
5+
NativeSyntheticEvent,
6+
ScrollView,
7+
TouchableOpacity,
8+
View,
9+
} from 'react-native';
10+
import { Font } from 'design-system';
11+
import BackGroundGradient from '@/layouts/BackGroundGradient';
12+
import Header from '@/components/common/Header';
13+
import Landing1 from './Landing/Landing1';
14+
import Landing2 from './Landing/Landing2';
15+
import Landing3 from './Landing/Landing3';
16+
import Landing4 from './Landing/Landing4';
17+
import { DEFAULT_COLOR } from '@/constants/DEFAULT_COLOR';
18+
import { StackNavigation } from '@/types/navigation';
19+
20+
function FinishButton({ onPress }: { onPress: () => void }) {
21+
return (
22+
<TouchableOpacity onPress={onPress}>
23+
<Font type="body1" color="white">
24+
완료
25+
</Font>
26+
</TouchableOpacity>
27+
);
28+
}
29+
30+
const landingPageList: (() => React.ReactNode)[] = [
31+
Landing1,
32+
Landing2,
33+
Landing3,
34+
Landing4,
35+
];
36+
37+
interface LandingScreenProps {
38+
navigation: StackNavigation<'Landing'>;
39+
}
40+
41+
export default function Landing({ navigation }: LandingScreenProps) {
42+
const [itemWidth, setItemWidth] = useState(0);
43+
const [currentPage, setCurrentPage] = useState(0);
44+
45+
const onScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
46+
const scrollPosition = event.nativeEvent.contentOffset.x;
47+
const index = Math.round(scrollPosition / Dimensions.get('window').width);
48+
setCurrentPage(index);
49+
};
50+
51+
return (
52+
<BackGroundGradient withoutScroll>
53+
<Header
54+
title="사용 가이드"
55+
RightActionButton={
56+
currentPage === landingPageList.length - 1 ? (
57+
<FinishButton onPress={() => navigation.navigate('Home/Main')} />
58+
) : undefined
59+
}
60+
/>
61+
<View className="flex-row gap-2 items-center justify-center mt-0.5">
62+
{landingPageList.map((_, index) => (
63+
<View
64+
className="w-2 h-2 rounded-full"
65+
style={{
66+
backgroundColor:
67+
currentPage === index
68+
? DEFAULT_COLOR.SPOT_RED
69+
: DEFAULT_COLOR.SPOT_GRAY,
70+
}}
71+
/>
72+
))}
73+
</View>
74+
<ScrollView
75+
style={{ flex: 1, marginTop: 10 }}
76+
horizontal
77+
pagingEnabled
78+
contentContainerStyle={{ width: `${100 * landingPageList.length}%` }}
79+
scrollEventThrottle={200}
80+
decelerationRate="fast"
81+
showsHorizontalScrollIndicator={false}
82+
onContentSizeChange={(width) =>
83+
setItemWidth(width / landingPageList.length)
84+
}
85+
onScroll={onScroll}
86+
>
87+
<View className="flex-row">
88+
{landingPageList.map((Page, index) => (
89+
<View style={{ width: itemWidth, height: '100%', padding: 20 }}>
90+
<Page key={index} />
91+
</View>
92+
))}
93+
</View>
94+
</ScrollView>
95+
</BackGroundGradient>
96+
);
97+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Font } from 'design-system';
2+
import { View } from 'react-native';
3+
import MockUp from '@/components/landing/MockUp';
4+
5+
export default function Landing1() {
6+
return (
7+
<View className="flex-1 items-center">
8+
<Font.Bold type="mainTitle" color="red">
9+
Spot! (촬영지) 검색
10+
</Font.Bold>
11+
<View className="mt-3 items-center">
12+
<Font type="body2" color="white">
13+
Travel Log를 만들어
14+
</Font>
15+
<Font type="body2" color="white">
16+
함께 여행하는 사람들을 초대해보세요!
17+
</Font>
18+
</View>
19+
<View className="mt-7">
20+
<MockUp />
21+
</View>
22+
</View>
23+
);
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Font } from 'design-system';
2+
import { View } from 'react-native';
3+
import MockUp from '@/components/landing/MockUp';
4+
5+
export default function Landing2() {
6+
return (
7+
<View className="flex-1 items-center">
8+
<Font.Bold type="mainTitle" color="red">
9+
Spot! (촬영지) 검색
10+
</Font.Bold>
11+
<View className="mt-3 items-center">
12+
<Font type="body2" color="white">
13+
Travel Log를 만들어
14+
</Font>
15+
<Font type="body2" color="white">
16+
함께 여행하는 사람들을 초대해보세요!
17+
</Font>
18+
</View>
19+
<View className="mt-7">
20+
<MockUp />
21+
</View>
22+
</View>
23+
);
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Font } from 'design-system';
2+
import { View } from 'react-native';
3+
import MockUp from '@/components/landing/MockUp';
4+
5+
export default function Landing3() {
6+
return (
7+
<View className="flex-1 items-center">
8+
<Font.Bold type="mainTitle" color="red">
9+
Spot! (촬영지) 검색
10+
</Font.Bold>
11+
<View className="mt-3 items-center">
12+
<Font type="body2" color="white">
13+
Travel Log를 만들어
14+
</Font>
15+
<Font type="body2" color="white">
16+
함께 여행하는 사람들을 초대해보세요!
17+
</Font>
18+
</View>
19+
<View className="mt-7">
20+
<MockUp />
21+
</View>
22+
</View>
23+
);
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Font } from 'design-system';
2+
import { View } from 'react-native';
3+
import MockUp from '@/components/landing/MockUp';
4+
5+
export default function Landing4() {
6+
return (
7+
<View className="flex-1 items-center">
8+
<Font.Bold type="mainTitle" color="red">
9+
Spot! (촬영지) 검색
10+
</Font.Bold>
11+
<View className="mt-3 items-center">
12+
<Font type="body2" color="white">
13+
Travel Log를 만들어
14+
</Font>
15+
<Font type="body2" color="white">
16+
함께 여행하는 사람들을 초대해보세요!
17+
</Font>
18+
</View>
19+
<View className="mt-7">
20+
<MockUp />
21+
</View>
22+
</View>
23+
);
24+
}

packages/react-native/src/routes/StackNavigator.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import CameraPage from '@/pages/CameraPage';
55
import SignupStackNavigator from './SignupStackNavigator';
66
import { StackParamList } from '@/types/navigation';
77
import SettingStackNavigator from './SettingStackNavigator';
8+
import Landing from '@/pages/Landing';
89

910
const Stack = createStackNavigator<StackParamList>();
1011

@@ -25,6 +26,7 @@ export default function StackNavigator() {
2526
<Stack.Screen name="Main" component={TabScreens} />
2627
<Stack.Screen name="Camera" component={CameraPage} />
2728
<Stack.Screen name="Setting/Main" component={SettingStackNavigator} />
29+
<Stack.Screen name="Landing" component={Landing} />
2830
</Stack.Navigator>
2931
);
3032
}

packages/react-native/src/types/navigation.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export type StackParamList = {
77
Main: undefined;
88
Signup: undefined;
99
Camera: undefined;
10+
Landing: undefined;
1011

1112
'Signup/Nickname': undefined;
1213
'Signup/Profile': { nickname: string };

0 commit comments

Comments
 (0)