Skip to content

Commit

Permalink
sdp-tech#11 feat: add market review page
Browse files Browse the repository at this point in the history
* sdp-tech#11 feat: add review item

* sdp-tech#11 feat: add market review page
  • Loading branch information
SJ-Kwak authored Jan 30, 2024
1 parent d83fe66 commit 4b971e7
Show file tree
Hide file tree
Showing 12 changed files with 270 additions and 19 deletions.
3 changes: 3 additions & 0 deletions src/assets/common/Star.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions src/common/Carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ interface CarouselProps {
slider?: boolean;
}

const { width } = Dimensions.get('window');

const Carousel = ({ data, renderItem, dot, slider }: CarouselProps) => {
const { width } = Dimensions.get('window');
const [page, setPage] = useState<number>(0);
return (
<>
Expand Down Expand Up @@ -59,7 +60,7 @@ const DotContainer = styled.View`

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

export default Carousel;
12 changes: 7 additions & 5 deletions src/common/Slider.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { useState, useEffect, useRef } from 'react';
import { View, Animated } from 'react-native';
import styled from 'styled-components/native';
import { BLACK, BLACK2 } from '../styles/GlobalColor';
import { BLACK, BLACK2, LIGHTGRAY, PURPLE } from '../styles/GlobalColor';

interface SliderProps {
total: number;
page: number;
rating?: boolean;
}

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

const load = (count: number) => {
Expand All @@ -31,12 +32,13 @@ const Slider = ({ total, page }: SliderProps) => {

return (
<>
<SliderBar>
<SliderBar style={{borderRadius: rating ? 2 : 0, backgroundColor: rating ? LIGHTGRAY : BLACK2}}>
<Animated.View
style={{
backgroundColor: BLACK,
backgroundColor: rating ? PURPLE : BLACK,
width,
height: 3
height: 3,
borderRadius: rating ? 2 : 0
}}
/>
</SliderBar>
Expand Down
36 changes: 36 additions & 0 deletions src/common/StarRating.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { useState } from 'react';
import { View, FlatList, TouchableOpacity } from 'react-native';
import StarIcon from '../assets/common/Star.svg';
import { LIGHTGRAY, PURPLE } from '../styles/GlobalColor';

interface StarProps {
index: number;
pressed: boolean;
onPress: (index: number) => void;
}

const Star = ({ index, pressed, onPress }: StarProps) => {
return (
<TouchableOpacity onPress={() => onPress(index)}>
<StarIcon color={pressed ? PURPLE : LIGHTGRAY} />
</TouchableOpacity>
);
};

const StarRating = () => {
const [rating, setRating] = useState<number>(0);

return (
<FlatList
horizontal
scrollEnabled={false}
data={[...new Array(5).keys()]}
renderItem={({ item, index }) => (
<Star index={index} pressed={index < rating} onPress={() => setRating(index+1)} />
)}
keyExtractor={(item, index) => index.toString()}
/>
);
};

export default StarRating;
19 changes: 8 additions & 11 deletions src/components/Home/Market/MarketTabView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@ import styled from 'styled-components/native';
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 { BLACK, BLACK2 } from '../../../styles/GlobalColor.tsx';

import { StackScreenProps } from '@react-navigation/stack';
import { HomeStackParams } from '../../../pages/Home';

import InfoPage from './InfoPage.tsx';
import ProductPage from './ProductPage.tsx';
import ReviewPage from './ReviewPage.tsx';

import Hashtag from '../../../common/Hashtag.tsx';
import Footer from '../../../common/Footer.tsx';

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

const ProfileSection = ({ navigation }: {navigation: any}) => {
const filter = ['스포티', '영캐주얼', '깔끔']
Expand All @@ -36,7 +39,7 @@ const ProfileSection = ({ navigation }: {navigation: any}) => {
<View style={{flexDirection: 'row', alignItems: 'center'}}>
<Body14R>안녕하세요 리폼러 이하늘입니다!</Body14R>
<TouchableOpacity>
<Caption11M style={{opacity: 0.5, marginLeft: 5}}>...더보기</Caption11M>
<Caption11M style={{color: BLACK2, marginLeft: 5}}>...더보기</Caption11M>
</TouchableOpacity>
</View>
<FlatList
Expand All @@ -53,14 +56,6 @@ const ProfileSection = ({ navigation }: {navigation: any}) => {
)
}

const ReviewPage = () => {
return (
<View>
<Text>리뷰</Text>
</View>
)
}

const statusBarHeight = getStatusBarHeight(true);

const MarketTabView = ({ navigation, route } : StackScreenProps<HomeStackParams, 'Market'>) => {
Expand Down Expand Up @@ -90,7 +85,9 @@ const MarketTabView = ({ navigation, route } : StackScreenProps<HomeStackParams,
backgroundColor: 'white',
}}
labelStyle={{
color: 'black'
color: BLACK,
fontWeight: '700',
fontSize: 16
}}
/>
)}
Expand Down
71 changes: 71 additions & 0 deletions src/components/Home/Market/ReviewPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { View, Text } from 'react-native';
import { Tabs } from 'react-native-collapsible-tab-view';
import styled from 'styled-components/native';
import StarRating from '../../../common/StarRating';
import ReviewComment from '../components/ReviewComment';
import ReviewItem from '../components/ReviewItem';
import { Body14B, Caption11M } from '../../../styles/GlobalText';
import { BLACK, LIGHTGRAY } from '../../../styles/GlobalColor';
import ReviewSummary from '../components/ReviewSummary';
import Slider from '../../../common/Slider';

const SummarySection = () => {


return (
<View style={{paddingVertical: 20, paddingHorizontal: 40, borderBottomColor: LIGHTGRAY, borderBottomWidth: 1}}>
<ItemContainer style={{marginBottom: 20}}>
<View style={{alignItems: 'center', justifyContent: 'center', paddingVertical: 15}}>
<Text style={{color: BLACK, fontSize: 40, fontWeight: '700'}}>4.0</Text>
<StarRating />
</View>
<View style={{paddingHorizontal: 40, flex: 1}}>
{[1, 2, 3, 4, 5].map((idx) => {
return (
<ItemContainer style={{alignItems: 'center'}}>
<Caption11M style={{marginRight: 5}}>{idx}</Caption11M>
<Slider total={20} page={3} rating />
<Caption11M style={{marginLeft: 5}}>3</Caption11M>
</ItemContainer>
);
})}
</View>
</ItemContainer>
<ItemContainer>
<Body14B>거래</Body14B>
<ReviewComment value='상담이 친절해요' />
<ReviewComment value='약속을 잘 지켜요' />
</ItemContainer>
<ItemContainer>
<Body14B>디자인</Body14B>
<ReviewComment value='마무리가 꼼꼼해요' />
<ReviewComment value='트렌디해요' />
</ItemContainer>
</View>
)
}

const ItemContainer = styled.View`
display: flex;
flex-direction: row;
padding: 5px;
`

const ReviewPage = () => {

return (
<Tabs.FlatList
data={[...new Array(3).keys()]}
ListHeaderComponent={SummarySection}
renderItem={({item}:any) => {
return (
<ReviewItem onPress={() => {}} />
)
}}
keyExtractor={(item, index) => index.toString()}
style={{marginBottom: 60}}
/>
)
}

export default ReviewPage;
27 changes: 27 additions & 0 deletions src/components/Home/components/ReviewComment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import styled from 'styled-components/native';
import { GREEN } from '../../../styles/GlobalColor';
import { Caption11M } from '../../../styles/GlobalText';

interface ReviewCommentProps {
value: string;
}

const ReviewComment = ({ value }: ReviewCommentProps) => {
return (
<ReviewContainer>
<Caption11M>{value}</Caption11M>
</ReviewContainer>
)
}

const ReviewContainer = styled.View`
display: flex;
padding: 5px 12px;
margin: 0px 5px;
justify-content: center;
align-items: center;
border-radius: 12px;
background: ${GREEN};
`

export default ReviewComment;
76 changes: 76 additions & 0 deletions src/components/Home/components/ReviewItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { View, Image, ImageBackground } from 'react-native';
import Carousel from '../../../common/Carousel';
import StarRating from '../../../common/StarRating';
import ReviewComment from './ReviewComment';
import { BLACK2, GRAY, LIGHTGRAY } from '../../../styles/GlobalColor';
import styled from 'styled-components/native';
import { Body14B, Body14R, Body16M, Caption11M } from '../../../styles/GlobalText';

interface ReviewItemProps {
onPress: () => void;
}

const ReviewItem = ({ onPress }: ReviewItemProps) => {
// 한 줄에 2개씩 아이템 배치
const product = [...new Array(6).keys()]
const splitArrayIntoPairs = (arr: any[], pairSize: number) => {
return arr.reduce((result, item, index) => {
if (index % pairSize === 0) {
result.push([]);
}
result[result.length - 1].push(item);
return result;
}, []);
};
const splitProduct = splitArrayIntoPairs(product, 2);
return (
<View style={{ borderBottomWidth: 1, borderBottomColor: LIGHTGRAY }}>
<ItemContainer style={{marginVertical: 10}}>
<View style={{width: 40, height: 40, backgroundColor: GRAY, borderRadius: 180, marginRight: 10}} />
<View>
<View style={{flexDirection: 'row', justifyContent: 'center', alignItems: 'center'}}>
<Body16M>닉네임</Body16M>
<Caption11M style={{color: BLACK2, marginLeft: 5}}>2024-01-01</Caption11M>
</View>
<StarRating />
</View>
</ItemContainer>
<Carousel
data={splitProduct}
renderItem={({item}: any) => {
return (
<View style={{ flexDirection: 'row' }}>
{item.map((subItem: any) => (
<View style={{width: '50%', paddingHorizontal: 20}}>
<ImageBackground
key={subItem.id}
source={{uri:'https://image.made-in-china.com/2f0j00efRbSJMtHgqG/Denim-Bag-Youth-Fashion-Casual-Small-Mini-Square-Ladies-Shoulder-Bag-Women-Wash-Bags.webp'}}
style={{width: '100%', height: 170 }}
/>
</View>
))}
</View>
)
}}
slider
/>
<ItemContainer style={{marginTop: 10}}>
<Body14B>거래</Body14B>
<ReviewComment value='약속을 잘 지켜요' />
</ItemContainer>
<ItemContainer style={{marginTop: 5}}>
<Body14B>디자인</Body14B>
<ReviewComment value='마무리가 꼼꼼해요' />
</ItemContainer>
<Body14R style={{paddingHorizontal: 20, paddingVertical: 10}}>후기 내용이 들어가는 칸입니다 옷이 친절하고 사장님이 멋있어요 어쩌고저쩌고</Body14R>
</View>
)
}

const ItemContainer = styled.View`
display: flex;
flex-direction: row;
padding: 5px 20px;
`

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

interface ReviewSummary {

}

const ReviewSummary = () => {
return (
<Container>
<Caption11M></Caption11M>
</Container>
)
}

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

export default ReviewSummary;
2 changes: 1 addition & 1 deletion src/components/Home/components/ServiceItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ interface ServiceItemProps {
const ServiceItem = ({ onPress }: ServiceItemProps) => {
const [like, setLike] = useState<boolean>(false);
return (
<TouchableOpacity style={{paddingHorizontal: 20, paddingVertical: 5}} onPress={onPress}>
<TouchableOpacity style={{paddingHorizontal: 20, paddingVertical: 10}} onPress={onPress}>
<ImageBackground
style={{width: '100%', height: 180, justifyContent: 'flex-end', alignItems: 'flex-end'}}
source={{uri: 'https://image.made-in-china.com/2f0j00efRbSJMtHgqG/Denim-Bag-Youth-Fashion-Casual-Small-Mini-Square-Ladies-Shoulder-Bag-Women-Wash-Bags.webp'}}
Expand Down
1 change: 1 addition & 0 deletions src/styles/GlobalColor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export const PURPLE3 = '#E7E0FD';
export const GREEN = '#DBFC72';
export const BLACK = '#222222';
export const BLACK2 = '#929292';
export const GRAY = '#BDBDBD';
export const LIGHTGRAY = '#DFDFDF';
Loading

0 comments on commit 4b971e7

Please sign in to comment.