Skip to content

Commit

Permalink
#11 feat: add market product page
Browse files Browse the repository at this point in the history
* #11 feat: add product & service item

* #11 feat: add carousel module

* #11 feat: add market product page
  • Loading branch information
SJ-Kwak authored Jan 28, 2024
1 parent e2fb451 commit 5807566
Show file tree
Hide file tree
Showing 20 changed files with 600 additions and 277 deletions.
1 change: 1 addition & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ module.exports = {
allowUndefined: true,
},
],
'react-native-reanimated/plugin'
],
};
9 changes: 9 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1123,6 +1123,11 @@ PODS:
- React-Core
- RNKeychain (8.1.2):
- React-Core
- RNReanimated (3.6.2):
- glog
- RCT-Folly (= 2022.05.16.00)
- React-Core
- ReactCommon/turbomodule/core
- RNScreens (3.29.0):
- glog
- RCT-Folly (= 2022.05.16.00)
Expand Down Expand Up @@ -1209,6 +1214,7 @@ DEPENDENCIES:
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- RNKeychain (from `../node_modules/react-native-keychain`)
- RNReanimated (from `../node_modules/react-native-reanimated`)
- RNScreens (from `../node_modules/react-native-screens`)
- RNSVG (from `../node_modules/react-native-svg`)
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
Expand Down Expand Up @@ -1333,6 +1339,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-gesture-handler"
RNKeychain:
:path: "../node_modules/react-native-keychain"
RNReanimated:
:path: "../node_modules/react-native-reanimated"
RNScreens:
:path: "../node_modules/react-native-screens"
RNSVG:
Expand Down Expand Up @@ -1404,6 +1412,7 @@ SPEC CHECKSUMS:
ReactCommon: 45b5d4f784e869c44a6f5a8fad5b114ca8f78c53
RNGestureHandler: 61bfdfc05db9b79dd61f894dcd29d3dcc6db3c02
RNKeychain: a65256b6ca6ba6976132cc4124b238a5b13b3d9c
RNReanimated: 5589be82dc26b3f94738eb7c6b1f942787532b25
RNScreens: b582cb834dc4133307562e930e8fa914b8c04ef2
RNSVG: ba3e7232f45e34b7b47e74472386cf4e1a676d0a
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
"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-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",
"react-native-tab-view": "^3.5.2",
"styled-components": "^6.1.8",
Expand All @@ -39,6 +41,7 @@
"@react-native/typescript-config": "0.73.1",
"@types/react": "^18.2.6",
"@types/react-native-dotenv": "^0.2.2",
"@types/react-native-snap-carousel": "^3.8.10",
"@types/react-test-renderer": "^18.0.0",
"@types/styled-components": "^5.1.34",
"@types/styled-components-react-native": "^5.2.5",
Expand Down
File renamed without changes
4 changes: 2 additions & 2 deletions src/common/BottomButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import styled from 'styled-components/native';
import { Body16M } from '../styles/GlobalText';
import { PURPLE, GREEN } from '../styles/GlobalColor';

interface BottomButtonParams {
interface BottomButtonProps {
value: string;
pressed: boolean;
onPress: () => void;
}

const BottomButton = ({ value, pressed, onPress }: BottomButtonParams) => {
const BottomButton = ({ value, pressed, onPress }: BottomButtonProps) => {
return (
<ButtonContainer pressed={pressed} onPress={onPress}>
<Body16M style={{color: pressed ? PURPLE : 'white'}}>{value}</Body16M>
Expand Down
65 changes: 65 additions & 0 deletions src/common/Carousel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { useState } from 'react';
import { View, Dimensions } from 'react-native';
import CarouselModule from 'react-native-snap-carousel';
import Slider from './Slider';
import styled from 'styled-components/native';
import { LIGHTGRAY, PURPLE } from '../styles/GlobalColor';

interface CarouselProps {
data: any[];
renderItem: any;
dot?: boolean;
slider?: boolean;
}

const Carousel = ({ data, renderItem, dot, slider }: CarouselProps) => {
const { width } = Dimensions.get('window');
const [page, setPage] = useState<number>(0);
return (
<>
<CarouselModule
data={data}
renderItem={renderItem}
sliderWidth={width}
itemWidth={width}
onSnapToItem={(index: number) => setPage(index)}
keyExtractor={(item, index) => index.toString()}
/>
{dot ? (
<DotContainer>
{Array.from({length: data.length}, (_, i) => i).map((i) => (
<Dot key={i} focused={i === page ? true : false} />
))}
</DotContainer>
):(<></>)}
{slider ? (
<SliderContainer>
<Slider total={data.length-1} page={page} />
</SliderContainer>
):(<></>)}
</>
)
}

const Dot = styled.View<{ focused: boolean }>`
width: ${(props: { focused: boolean; }) => props.focused ? 10 : 7}px;
height: ${(props: { focused: boolean; }) => props.focused ? 10 : 7}px;
margin: 0px 6px;
border-radius: 16px;
background: ${(props: { focused: boolean; }) => props.focused ? PURPLE : LIGHTGRAY};
opacity: ${(props: { focused: boolean; }) => props.focused ? 1 : 0.5};
`

const DotContainer = styled.View`
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
`

const SliderContainer = styled.View`
display: flex;
padding: 5px 20px;
`

export default Carousel;
32 changes: 15 additions & 17 deletions src/common/CustomHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,23 +56,21 @@ const Toggletag = ({pressable} : ToggleButtonParams) => {

const CustomHeader = ({ onSearch, onAlarm }: CustomHeaderProps) => {
return (
<TouchableOpacity>
<FrameBox>
<Logo />
<View style={{flex: 1}}>
<ToggleBox>
<ToggleButton>
<Text style={{ fontSize: 16, fontWeight: '500', marginRight: 5 }}>상품</Text>
</ToggleButton>
<ToggleButton>
<Text style={{ fontSize: 16, fontWeight: '500', marginRight: 5 }}>마켓</Text>
</ToggleButton>
</ToggleBox>
</View>
<Search />
<Bell />
</FrameBox>
</TouchableOpacity>
<FrameBox>
<Logo />
<View style={{flex: 1}}>
<ToggleBox>
<ToggleButton>
<Text style={{ fontSize: 16, fontWeight: '500', marginRight: 5 }}>상품</Text>
</ToggleButton>
<ToggleButton>
<Text style={{ fontSize: 16, fontWeight: '500', marginRight: 5 }}>마켓</Text>
</ToggleButton>
</ToggleBox>
</View>
<Search />
<Bell />
</FrameBox>
)
}

Expand Down
2 changes: 1 addition & 1 deletion src/common/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const Footer = () => {
const [pressed, setPressed] = useState<boolean>(false);
return (
<FooterContainer>
<HeartButton like={like} onPress={() => setLike(!like)} />
<HeartButton like={like} onPress={() => setLike(!like)} blank />
<BottomButton value={'견적서 보내기'} pressed={pressed} onPress={() => setPressed(!pressed)} />
</FooterContainer>
)
Expand Down
4 changes: 2 additions & 2 deletions src/common/Hashtag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import styled from 'styled-components/native';
import { Filter14M } from '../styles/GlobalText';
import { PURPLE } from '../styles/GlobalColor';

interface HashtagParams {
interface HashtagProps {
value: string;
pressable?: boolean;
pressed?: boolean;
onPress?: () => void;
}

const Hashtag = ({value, pressable, pressed, onPress} : HashtagParams) => {
const Hashtag = ({value, pressable, pressed, onPress} : HashtagProps) => {
return (
<HashtagContainer pressed={pressed} onPress={onPress} disabled={!pressable}>
<Filter14M style={{color: pressed ? PURPLE : 'white'}}>{value}</Filter14M>
Expand Down
9 changes: 5 additions & 4 deletions src/common/HeartButton.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import React from 'react';
import { TouchableOpacity } from 'react-native';
import Heart from '../assets/common/Heart.svg';
import { PURPLE } from '../styles/GlobalColor';
import { PURPLE, PURPLE2, PURPLE3 } from '../styles/GlobalColor';

interface HeartProps {
like: boolean;
onPress: () => void;
blank?: boolean;
}

const HeartButton = ({ like, onPress }: HeartProps) => {
const HeartButton = ({ like, onPress, blank }: HeartProps) => {
return (
<TouchableOpacity onPress={onPress} style={{display:'flex', alignItems:'center'}}>
<Heart color={like ? '#FF0000' : PURPLE} fill={like ? '#FF0000' : 'none'} />
<TouchableOpacity onPress={onPress} style={{display:'flex', alignItems:'center', padding: 5}}>
<Heart color={blank || like ? PURPLE : PURPLE2} fill={like ? PURPLE : blank ? 'none': PURPLE3} />
</TouchableOpacity>
)
}
Expand Down
53 changes: 53 additions & 0 deletions src/common/Slider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { useState, useEffect, useRef } from 'react';
import { View, Animated } from 'react-native';
import styled from 'styled-components/native';
import { BLACK, BLACK2 } from '../styles/GlobalColor';

interface SliderProps {
total: number;
page: number;
}

const Slider = ({ total, page }: SliderProps) => {
const loaderValue = useRef(new Animated.Value(0)).current;

const load = (count: number) => {
Animated.timing(loaderValue, {
toValue: (count / total) * 100,
duration: 500,
useNativeDriver: false,
}).start();
};

const width = loaderValue.interpolate({
inputRange: [0, 100],
outputRange: ['10%', '100%'],
extrapolate: 'clamp'
});

useEffect(() => {
load(page)
}, [page]);

return (
<>
<SliderBar>
<Animated.View
style={{
backgroundColor: BLACK,
width,
height: 3
}}
/>
</SliderBar>
</>
)
}

const SliderBar = styled.View`
width: 100%;
height: 3px;
background: ${BLACK2};
`

export default Slider;
26 changes: 26 additions & 0 deletions src/common/ThumbnailHashtag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import styled from 'styled-components/native';
import { PURPLE3 } from '../styles/GlobalColor';
import { Caption11M } from '../styles/GlobalText';

interface ThumbnailHashtagProps {
value: string;
}

const ThumbnailHashtag = ({ value }: ThumbnailHashtagProps) => {
return (
<Container>
<Caption11M>{value}</Caption11M>
</Container>
)
}

const Container = styled.View`
display: flex;
padding: 4px 8px;
justify-content: center;
align-items: center;
border-radius: 4px;
background: ${PURPLE3};
`

export default ThumbnailHashtag;
4 changes: 2 additions & 2 deletions src/components/Home/Market/DetailPage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Dimensions, SafeAreaView, ScrollView, Text, TextInput, TouchableOpacity, View, StyleSheet } from 'react-native';
import { StackScreenProps, createStackNavigator } from '@react-navigation/stack';
import { HomeStackParams } from '../../../pages/Home';
import LeftArrow from '../../../assets/common/LeftArrow.svg';
import Arrow from '../../../assets/common/Arrow.svg';
import UnFilledLike from '../../../assets/common/UnFilledLike.svg';
import Search from '../../../assets/common/Search.svg';
import styled from "styled-components/native";
Expand Down Expand Up @@ -73,7 +73,7 @@ const DetailPageMainScreen = ({ navigation }: StackScreenProps<DetailPageStackPa
<TouchableOpacity onPress={() => {
navigation.goBack();
}}>
<LeftArrow/>
<Arrow/>
</TouchableOpacity>
</View>
<ScrollView>
Expand Down
15 changes: 4 additions & 11 deletions src/components/Home/Market/MarketTabView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import { StackScreenProps } from '@react-navigation/stack';
import { HomeStackParams } from '../../../pages/Home';

import InfoPage from './InfoPage.tsx';
import ProductPage from './ProductPage.tsx';
import Footer from '../../../common/Footer.tsx';

import LeftArrow from '../../../assets/common/LeftArrow.svg';
import Arrow from '../../../assets/common/Arrow.svg';
import Hashtag from '../../../common/Hashtag.tsx';

const ProfileSection = () => {
Expand Down Expand Up @@ -39,14 +40,6 @@ const ProfileSection = () => {
)
}

const ProductPage = () => {
return (
<View>
<Text>상품</Text>
</View>
)
}

const ReviewPage = () => {
return (
<View>
Expand Down Expand Up @@ -78,7 +71,7 @@ const MarketTabView = ({ navigation, route } : StackScreenProps<HomeStackParams,
return (
<SafeAreaView style={{flex: 1}}>
<BackButton onPress={() => navigation.goBack()}>
<LeftArrow />
<Arrow />
</BackButton>
<ProfileSection />
<TabView
Expand All @@ -91,7 +84,7 @@ const MarketTabView = ({ navigation, route } : StackScreenProps<HomeStackParams,
{...props}
indicatorContainerStyle={{
borderBottomColor: '#DFDFDF',
borderBottomWidth: 2
borderBottomWidth: 1
}}
indicatorStyle={{
backgroundColor: '#BDBDBD',
Expand Down
Loading

0 comments on commit 5807566

Please sign in to comment.