Skip to content

Commit

Permalink
feat: drops detail page (#6)
Browse files Browse the repository at this point in the history
* feat: add drops item page

* feat: add drop detail contents

* feat: flip countdown

* chore: bump version to 0.4.3

* fix: init route name
  • Loading branch information
CraftyDragon678 authored Aug 4, 2021
1 parent b9ba49d commit e66a3bc
Show file tree
Hide file tree
Showing 9 changed files with 274 additions and 13 deletions.
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ android {
applicationId "com.ast.mvp"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 16
versionName "0.4.2"
versionCode 17
versionName "0.4.3"
multiDexEnabled true
}
splits {
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rn",
"version": "0.4.2",
"version": "0.4.3",
"private": true,
"scripts": {
"android": "react-native run-android",
Expand All @@ -27,9 +27,11 @@
"@react-navigation/native": "^5.9.2",
"@react-navigation/stack": "^5.14.2",
"axios": "^0.21.1",
"dayjs": "^1.10.6",
"react": "16.13.1",
"react-native": "0.63.4",
"react-native-collapsible-tab-view": "^4.2.1",
"react-native-flip-countdown-timer": "^0.0.3",
"react-native-gesture-handler": "^1.9.0",
"react-native-nfc-manager": "^2.2.1",
"react-native-pager-view": "^5.1.9",
Expand Down
80 changes: 80 additions & 0 deletions src/@types/react-native-flip-countdown-timer.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
declare module 'react-native-flip-countdown-timer' {
import React from 'react';
import { TextStyle, ViewStyle } from 'react-native';

interface FlipNumberProps {
/**
* Number Input
*/
number: string | number;

/**
* Number Input Unit
* @default 'seconds'
*/
unit?: 'hours' | 'minutes' | 'seconds';

/**
* size (default is `Dimention.width / 6`)
*/
size?: number;

/**
* perspective
* @default 250
*/
perspective?: number;

/**
* Wrapper Style
* @default {}
*/
numberWrapperStyle?: ViewStyle;

/**
* Card Style
* @default {}
*/
cardStyle?: ViewStyle;

/**
* Flip Card Style
* @default {}
*/
flipCardStyle?: ViewStyle;

/**
* Number style
* @default {}
*/
numberStyle?: TextStyle;
}

interface CountdownTimerProps {
/**
* Time (in seconds)
*/
time: string | number;

/**
* Play the timer
* @default true
*/
play?: boolean;

/**
* Wrapper for the CountdownTimer
* @default {}
*/
wrapperStyle?: ViewStyle;

/**
* Flip Number Props
*/
flipNumberProps?: FlipNumberProps;
}

export const CountdownTimer: React.ComponentClass<CountdownTimerProps>;

export const FlipNumber: React.FC<FlipNumberProps>;
}
4 changes: 4 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import React from 'react';
import 'react-native-gesture-handler';
import styled from '@emotion/native';
import { GoogleSignin } from '@react-native-community/google-signin';
import dayjs from 'dayjs';
import duration from 'dayjs/plugin/duration';

import Router from './router';
import { ProvideAuth } from './hooks/user';
Expand All @@ -15,6 +17,8 @@ GoogleSignin.configure({
'51227550156-72gpdjmbedgn18n066r6g22a1kjp2k2m.apps.googleusercontent.com',
});

dayjs.extend(duration);

const TopBackground = styled.SafeAreaView<Theme>`
flex: 0;
background-color: ${({ backgroundColor, topColor }) =>
Expand Down
6 changes: 4 additions & 2 deletions src/components/DropItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import styled from '@emotion/native';
import { GestureResponderEvent, ImageSourcePropType, View } from 'react-native';
import Button from './Button';

const Container = styled.View`
const Container = styled.TouchableOpacity`
padding: 20px;
flex-direction: row;
justify-content: space-between;
Expand Down Expand Up @@ -56,6 +56,7 @@ interface DropItemProps {
price: number;
description: string;
onClickNotify: (event: GestureResponderEvent) => void;
onClickProduct: (event: GestureResponderEvent) => void;
}

const DropItem: React.FC<DropItemProps> = ({
Expand All @@ -66,8 +67,9 @@ const DropItem: React.FC<DropItemProps> = ({
price,
description,
onClickNotify,
onClickProduct,
}) => (
<Container>
<Container onPress={onClickProduct}>
<ProductImage source={productImage} />
<View>
<LogoImage source={logoImage} resizeMode="contain" />
Expand Down
134 changes: 134 additions & 0 deletions src/pages/DropDetail.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import React from 'react';
import { StyleSheet } from 'react-native';
import { FlipNumber } from 'react-native-flip-countdown-timer';
import { useState } from 'react';
import styled from '@emotion/native';
import { RouteProp } from '@react-navigation/native';
import { DropsStackParamList } from '@src/router/navigator';
import dayjs from 'dayjs';
import productImage from '../assets/images/productImageTemp.jpg';
import logoImage from '../assets/images/logoImageTemp.jpg';
import { useLayoutEffect } from 'react';
import { useCallback } from 'react';

type Props = {
route: RouteProp<DropsStackParamList, 'DropDetail'>;
};

const styles = StyleSheet.create({
card: {
backgroundColor: '#fff',
borderColor: '#9a9a9a',
borderWidth: 0.5,
padding: 0,
},
number: {
color: '#000',
fontFamily: 'Gong Gothic OTF',
},
numberWrapper: {
shadowOpacity: 0,
elevation: 0,
borderColor: '#9a9a9a',
borderWidth: 1,
borderRadius: 5,
overflow: 'hidden',
},
});

const Container = styled.View`
align-items: center;
`;

const ProductImage = styled.Image`
width: 100%;
height: 390px;
margin-bottom: 20px;
`;

const LogoImage = styled.Image`
width: 30px;
height: 30px;
margin-bottom: 15px;
`;

const SubTitle = styled.Text`
font-family: 'NEXON Lv1 Gothic OTF Bold';
font-size: 12px;
margin-bottom: 5px;
`;

const Title = styled.Text`
font-family: 'NEXON Lv1 Gothic OTF Bold';
font-size: 30px;
margin-bottom: 30px;
`;

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

const CountDownText = styled.Text`
font-family: 'NEXON Lv1 Gothic OTF Bold';
font-size: 10px;
margin: 0 10px;
`;

const DropDetail = ({
route: {
params: { product },
},
}: Props) => {
const [time, setTime] = useState(61773);
const duration = dayjs.duration(time, 's');

useLayoutEffect(
useCallback(() => {
const timer = setInterval(() => setTime((t) => t - 1), 1e3);
return () => {
clearInterval(timer);
};
}, []),
);

return (
<Container>
<ProductImage source={productImage} />
<LogoImage source={logoImage} />
<SubTitle>{'조던 자이언 1'}</SubTitle>
<Title>{product.nfcID}</Title>
<CountDownContainer>
<FlipNumber
number={duration.hours() + 1}
size={45}
cardStyle={styles.card}
flipCardStyle={styles.card}
numberStyle={styles.number}
numberWrapperStyle={styles.numberWrapper}
/>
<CountDownText>H</CountDownText>
<FlipNumber
number={duration.minutes() + 1}
size={45}
cardStyle={styles.card}
flipCardStyle={styles.card}
numberStyle={styles.number}
numberWrapperStyle={styles.numberWrapper}
/>
<CountDownText>M</CountDownText>
<FlipNumber
number={duration.seconds()}
size={45}
cardStyle={styles.card}
flipCardStyle={styles.card}
numberStyle={styles.number}
numberWrapperStyle={styles.numberWrapper}
/>
<CountDownText>남음</CountDownText>
</CountDownContainer>
</Container>
);
};

export default DropDetail;
27 changes: 22 additions & 5 deletions src/pages/Drops.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import { Product } from '@src/constants/types';
import logoImage from '../assets/images/logoImageTemp.jpg';
import productImage from '../assets/images/productImageTemp.jpg';
import moveToTopImage from '../assets/images/move-top.png';
import { DropsStack, navigate } from '@src/router/navigator';
import DropDetail from './DropDetail';

const styles = StyleSheet.create({
indicator: {
Expand Down Expand Up @@ -114,14 +116,15 @@ const Ongoing = (props: Partial<FlatListProps<Product>>) => {
description="5월 12일 오전 11시 출시 예정"
price={139000}
onClickNotify={() => {}}
onClickProduct={() => navigate('DropDetail', { product: item })}
/>
)}
{...props}
/>
);
};

const Drop = () => {
const DropsList = () => {
const ref = useRef<CollapsibleRef>();
const [showingMoveToTop, setShowingMoveToTop] = useState(false);
const moveToTop = useCallback(() => {
Expand All @@ -139,9 +142,6 @@ const Drop = () => {
);
return (
<Container>
<HeaderContainer>
<HeaderTitle>AST</HeaderTitle>
</HeaderContainer>
<BodyContainer>
<Tabs.Container
renderHeader={Header}
Expand Down Expand Up @@ -187,4 +187,21 @@ const Drop = () => {
</Container>
);
};
export default Drop;

const Drops = () => {
return (
<>
<HeaderContainer>
<HeaderTitle>AST</HeaderTitle>
</HeaderContainer>
<DropsStack.Navigator
initialRouteName="DropsList"
headerMode="none"
screenOptions={{ cardStyle: { backgroundColor: 'white' } }}>
<DropsStack.Screen name="DropsList" component={DropsList} />
<DropsStack.Screen name="DropDetail" component={DropDetail} />
</DropsStack.Navigator>
</>
);
};
export default Drops;
18 changes: 15 additions & 3 deletions src/router/navigator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createRef } from 'react';
import { Product } from '@src/constants/types';

export type RootStackParamList = {
Root: undefined;
Expand All @@ -29,15 +30,26 @@ export type MainTabParamList = {
Profile: undefined;
};

export type DropsStackParamList = {
DropsList: undefined;
DropDetail: {
product: Product;
};
};

export const Stack = createStackNavigator<RootStackParamList>();

export const Tab = createBottomTabNavigator<MainTabParamList>();

export const DropsStack = createStackNavigator<DropsStackParamList>();

export const navigationRef = createRef<NavigationContainerRef>();

export const navigate = <K extends keyof RootStackParamList>(
type ParamList = RootStackParamList & MainTabParamList & DropsStackParamList;

export const navigate = <K extends keyof ParamList>(
routeName: K,
params?: RootStackParamList[K],
...[params]: ParamList[K] extends undefined ? [undefined?] : [ParamList[K]]
) => {
if (!navigationRef.current) {
throw new Error('navigator is not defined');
Expand All @@ -50,7 +62,7 @@ export const navigate = <K extends keyof RootStackParamList>(
);
};

export const reset = <K extends keyof RootStackParamList>(routeName: K) => {
export const reset = <K extends keyof ParamList>(routeName: K) => {
if (!navigationRef.current) {
throw new Error('navigator is not defined');
}
Expand Down
Loading

0 comments on commit e66a3bc

Please sign in to comment.