Skip to content

Commit

Permalink
sdp-tech#11 feat: apply collapsible tab view on market page
Browse files Browse the repository at this point in the history
  • Loading branch information
SJ-Kwak committed Jan 29, 2024
1 parent bf4e8fd commit e67d699
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 76 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
"axios": "^1.6.3",
"react": "18.2.0",
"react-native": "0.73.2",
"react-native-collapsible-tab-view": "^6.2.1",
"react-native-dotenv": "^3.4.9",
"react-native-gesture-handler": "^2.14.0",
"react-native-keychain": "^8.1.2",
"react-native-pager-view": "^6.2.3",
"react-native-reanimated": "^3.6.2",
"react-native-safe-area-context": "^4.8.2",
"react-native-safearea-height": "^1.0.6",
"react-native-screens": "^3.29.0",
"react-native-snap-carousel": "git+https://github.com/SJ-Kwak/react-native-snap-carousel.git",
"react-native-svg": "^14.1.0",
Expand Down
2 changes: 1 addition & 1 deletion src/assets/common/Arrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/components/Home/Market/DetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const DetailPageMainScreen = ({ navigation }: StackScreenProps<DetailPageStackPa
<TouchableOpacity onPress={() => {
navigation.goBack();
}}>
<Arrow/>
<Arrow color='black' />
</TouchableOpacity>
</View>
<CardView // 데이터 들어오면 렌더링
Expand Down
6 changes: 4 additions & 2 deletions src/components/Home/Market/InfoPage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useState, useEffect } from 'react';
import { View, SafeAreaView, FlatList, Text } from 'react-native';
import { Tabs } from 'react-native-collapsible-tab-view';
import styled from 'styled-components/native';
import { Body14R, Body16B } from '../../../styles/GlobalText';

Expand All @@ -14,7 +15,7 @@ const InfoPage = () => {
]

return (
<FlatList
<Tabs.FlatList
data={data}
renderItem={({item}:any) => {
return (
Expand All @@ -23,7 +24,8 @@ const InfoPage = () => {
<Body14R style={{textAlign: 'right'}}>{item.data}</Body14R>
</InfoSection>
)
} }
}}
keyExtractor={(item, index) => index.toString()}
/>
)
}
Expand Down
79 changes: 43 additions & 36 deletions src/components/Home/Market/MarketTabView.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { useState } from 'react';
import { SafeAreaView, ScrollView, View, FlatList, Text, TouchableOpacity, useWindowDimensions } from 'react-native';
import React, { useState } from 'react';
import { SafeAreaView, ScrollView, View, FlatList, Text, TouchableOpacity, Image, ImageBackground } from 'react-native';
import styled from 'styled-components/native';
import { TabView, TabBar, SceneMap } from "react-native-tab-view";
import { Tabs, MaterialTabBar } from 'react-native-collapsible-tab-view';
import { getStatusBarHeight } from 'react-native-safearea-height';
import { Title20B, Body14R, Caption11M } from '../../../styles/GlobalText.tsx';

import { StackScreenProps } from '@react-navigation/stack';
Expand All @@ -14,11 +15,23 @@ import Footer from '../../../common/Footer.tsx';
import Arrow from '../../../assets/common/Arrow.svg';
import Hashtag from '../../../common/Hashtag.tsx';

const ProfileSection = () => {
const ProfileSection = ({ navigation }: {navigation: any}) => {
const filter = ['스포티', '영캐주얼', '깔끔']
return (
<View style={{alignItems: 'center'}}>
<View style={{backgroundColor: '#BDBDBD', width: 90, height: 90, borderRadius: 180}} />
<BackButton onPress={() => navigation.goBack()}>
<Arrow color={'white'} />
</BackButton>
<ImageBackground
style={{width: '100%', height: 200}}
imageStyle={{height: 160}}
source={{uri: 'https://image.made-in-china.com/2f0j00efRbSJMtHgqG/Denim-Bag-Youth-Fashion-Casual-Small-Mini-Square-Ladies-Shoulder-Bag-Women-Wash-Bags.webp'}}>
<View style={{width: '100%', height: 160, backgroundColor: '#00000066', opacity: 0.7}} />
<Image
style={{alignSelf: 'center', width: 90, height: 90, borderRadius: 180, position: 'absolute', top: 110}}
source={{uri: 'https://image.made-in-china.com/2f0j00efRbSJMtHgqG/Denim-Bag-Youth-Fashion-Casual-Small-Mini-Square-Ladies-Shoulder-Bag-Women-Wash-Bags.webp'}}
/>
</ImageBackground>
<Title20B style={{marginTop: 8}}>이하늘의 마켓</Title20B>
<View style={{flexDirection: 'row', alignItems: 'center'}}>
<Body14R>안녕하세요 리폼러 이하늘입니다!</Body14R>
Expand Down Expand Up @@ -48,44 +61,27 @@ const ReviewPage = () => {
)
}

const statusBarHeight = getStatusBarHeight(true);

const MarketTabView = ({ navigation, route } : StackScreenProps<HomeStackParams, 'Market'>) => {
const layout = useWindowDimensions();
const [index, setIndex] = useState<number>(0);
const [routes] = useState([
{ key: 'info', title: '정보'},
{ key: 'product', title: '상품' },
{ key: 'review', title: '리뷰' }
]);

const renderScene = ({ route }: any) => {
switch (route.key) {
case 'info':
return <InfoPage />;
case 'product':
return <ProductPage />;
case 'review':
return <ReviewPage />;
}
}

return (
<SafeAreaView style={{flex: 1}}>
<BackButton onPress={() => navigation.goBack()}>
<Arrow />
</BackButton>
<ProfileSection />
<TabView
navigationState={{ index, routes }}
renderScene={renderScene}
onIndexChange={setIndex}
initialLayout={{ width: layout.width }}
<View style={{flex: 1}}>
<Tabs.Container
renderHeader={props => <ProfileSection navigation={navigation} />}
headerContainerStyle={{
shadowOpacity: 0,
borderBottomWidth: 1,
borderColor: '#D9D9D9'
}}
renderTabBar={props => (
<TabBar
<MaterialTabBar
{...props}
indicatorContainerStyle={{
borderBottomColor: '#DFDFDF',
borderBottomWidth: 1
}}
indicatorStyle={{
backgroundColor: '#BDBDBD',
height: 2
Expand All @@ -96,17 +92,28 @@ const MarketTabView = ({ navigation, route } : StackScreenProps<HomeStackParams,
labelStyle={{
color: 'black'
}}
pressColor='black'
/>
)}
/>
>
{routes.map(route =>
(<Tabs.Tab key={route.key} name={route.title}>
{route.key === 'info' && <InfoPage />}
{route.key === 'product' && <ProductPage />}
{route.key === 'review' && <ReviewPage />}
</Tabs.Tab>)
)}
</Tabs.Container>
<Footer />
</SafeAreaView>
</View>
)
}

const BackButton = styled.TouchableOpacity`
padding: 10px;
position: absolute;
left: 0px;
top: ${statusBarHeight-10}px;
z-index: 1;
`

export default MarketTabView;
71 changes: 37 additions & 34 deletions src/components/Home/Market/ProductPage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useState } from 'react';
import { View, TouchableOpacity, ScrollView, FlatList, Dimensions } from 'react-native';
import { Tabs } from 'react-native-collapsible-tab-view';
import styled from 'styled-components/native';
import { Subtitle18B } from '../../../styles/GlobalText';
import Carousel from '../../../common/Carousel';
Expand All @@ -8,7 +9,7 @@ import ServiceItem from '../components/ServiceItem';
import ProductItem from '../components/ProductItem';

import Arrow from '../../../assets/common/Arrow.svg';
import { LIGHTGRAY } from '../../../styles/GlobalColor';
import { BLACK, LIGHTGRAY } from '../../../styles/GlobalColor';

const ProductPage = () => {
// 한 줄에 2개씩 상품 아이템 배치
Expand All @@ -25,39 +26,41 @@ const ProductPage = () => {
const splitProduct = splitArrayIntoPairs(product, 2);

return (
<ScrollView style={{marginBottom: 60}}>
<LabelButton>
<Subtitle18B>리폼러의 서비스</Subtitle18B>
<Arrow transform={[{ rotate: '180deg' }]} />
</LabelButton>
<Carousel
data={[...new Array(6).keys()]}
renderItem={({item}: any) => {
return (
<ServiceItem onPress={() => {}} />
)
}}
slider
/>
<View style={{height: 1, backgroundColor: LIGHTGRAY, marginTop: 10 }} />
<LabelButton>
<Subtitle18B>리폼러의 판매상품</Subtitle18B>
<Arrow transform={[{ rotate: '180deg' }]} />
</LabelButton>
<Carousel
data={splitProduct}
renderItem={({item}: any) => {
return (
<View style={{ flexDirection: 'row' }}>
{item.map((subItem: any) => (
<ProductItem key={subItem.id} onPress={() => {}} />
))}
</View>
)
}}
dot
/>
</ScrollView>
<Tabs.ScrollView>
<View>
<LabelButton>
<Subtitle18B>리폼러의 서비스</Subtitle18B>
<Arrow transform={[{ rotate: '180deg' }]} color={BLACK} />
</LabelButton>
<Carousel
data={[...new Array(6).keys()]}
renderItem={({item}: any) => {
return (
<ServiceItem onPress={() => {}} />
)
}}
slider
/>
<View style={{height: 1, backgroundColor: LIGHTGRAY, marginTop: 10 }} />
<LabelButton>
<Subtitle18B>리폼러의 판매상품</Subtitle18B>
<Arrow transform={[{ rotate: '180deg' }]} color={BLACK} />
</LabelButton>
<Carousel
data={splitProduct}
renderItem={({item}: any) => {
return (
<View style={{ flexDirection: 'row' }}>
{item.map((subItem: any) => (
<ProductItem key={subItem.id} onPress={() => {}} />
))}
</View>
)
}}
dot
/>
</View>
</Tabs.ScrollView>
)
}

Expand Down
34 changes: 32 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3341,7 +3341,7 @@ deprecated-react-native-prop-types@^5.0.0:
invariant "^2.2.4"
prop-types "^15.8.1"

dequal@^2.0.3:
dequal@2.0.3, dequal@^2.0.3:
version "2.0.3"
resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz"
integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==
Expand Down Expand Up @@ -6197,7 +6197,7 @@ prompts@^2.0.1, prompts@^2.4.2:
kleur "^3.0.3"
sisteransi "^1.0.5"

prop-types@^15.6.1, prop-types@^15.7.2, prop-types@^15.8.1:
prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
Expand Down Expand Up @@ -6284,6 +6284,13 @@ react-is@^18.0.0, react-is@^18.2.0:
resolved "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz"
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==

react-native-collapsible-tab-view@^6.2.1:
version "6.2.1"
resolved "https://registry.yarnpkg.com/react-native-collapsible-tab-view/-/react-native-collapsible-tab-view-6.2.1.tgz#b48760cd98c0156bc89300516ae10ff55f7df298"
integrity sha512-pgmpZYSg6TPYmhv3Dw/czFJHk4AzcYN2df3EMlKwFqbu1ifmlA866hBUVDX3mlbRaros75U5S1wpGCwlqqXLTQ==
dependencies:
use-deep-compare "^1.1.0"

react-native-dotenv@^3.4.9:
version "3.4.9"
resolved "https://registry.npmjs.org/react-native-dotenv/-/react-native-dotenv-3.4.9.tgz"
Expand Down Expand Up @@ -6327,6 +6334,13 @@ react-native-safe-area-context@^4.8.2:
resolved "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.8.2.tgz"
integrity sha512-ffUOv8BJQ6RqO3nLml5gxJ6ab3EestPiyWekxdzO/1MQ7NF8fW1Mzh1C5QE9yq573Xefnc7FuzGXjtesZGv7cQ==

react-native-safearea-height@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/react-native-safearea-height/-/react-native-safearea-height-1.0.6.tgz#ece54ae953ff08efe9eee7aa96581a3a9e76c930"
integrity sha512-cO58Ew/NG7XcxwcSMNc0PxKiPEXYt3Fzql9UshXWXmPZ+XFXWEifYwKKqwaKExHvep8mk8wCbY0qy00pmfciIg==
dependencies:
react "^16.9.0"

react-native-screens@^3.29.0:
version "3.29.0"
resolved "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.29.0.tgz"
Expand Down Expand Up @@ -6439,6 +6453,15 @@ [email protected]:
dependencies:
loose-envify "^1.1.0"

react@^16.9.0:
version "16.14.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d"
integrity sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.2"

readable-stream@^3.4.0:
version "3.6.2"
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz"
Expand Down Expand Up @@ -7365,6 +7388,13 @@ uri-js@^4.2.2:
dependencies:
punycode "^2.1.0"

use-deep-compare@^1.1.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/use-deep-compare/-/use-deep-compare-1.2.1.tgz#076c9865868d98509e619206e27bc8eff0b8ed7c"
integrity sha512-JTnOZAr0fq1ix6CQ4XANoWIh03xAiMFlP/lVAYDdAOZwur6nqBSdATn1/Q9PLIGIW+C7xmFZBCcaA4KLDcQJtg==
dependencies:
dequal "2.0.3"

use-latest-callback@^0.1.5, use-latest-callback@^0.1.7:
version "0.1.9"
resolved "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.1.9.tgz"
Expand Down

0 comments on commit e67d699

Please sign in to comment.