Skip to content

Instantly share code, notes, and snippets.

@gidox
Created October 15, 2019 15:43
Show Gist options
  • Save gidox/e01cfe8b302acdf05e4b4321c43902ec to your computer and use it in GitHub Desktop.
Save gidox/e01cfe8b302acdf05e4b4321c43902ec to your computer and use it in GitHub Desktop.
import React from 'react';
import PropTypes from 'prop-types';
import { Animated, View, StyleSheet, Dimensions, TouchableOpacity } from 'react-native';
import moment from 'moment';
import { Thumbnail } from 'native-base';
import Text from '../theme/Text';
import CountDownTimer from './CountDownReact';
import i18n from '../translations/i18n';
const locale = i18n.currentLocale().split('-')[0];
const name = locale === 'es' ? 'service_name_spanish' : 'service_name';
const DEVICE_HEIGHT = Dimensions.get('window').height;
const CARD_HEIGHT = 400;
const CARD_VISIBLE_HEIGHT = 50;
const CARD_VISIBLE_HEIGHT_COLLAPSED = 30;
const CARD_VISIBLE_DELTA = CARD_VISIBLE_HEIGHT - CARD_VISIBLE_HEIGHT_COLLAPSED;
const TOP_OFFSET = 0;
class AppointmentCard extends React.Component {
constructor(props) {
super(props);
this.offsetY = 0;
this.state = {
scrollY: new Animated.Value(0),
CARD_AMOUNT: props.data.length,
STACK_HEIGHT: CARD_VISIBLE_DELTA * props.data.length - CARD_VISIBLE_DELTA,
SCROLL_HEIGHT: DEVICE_HEIGHT + CARD_VISIBLE_DELTA * props.data.length - CARD_VISIBLE_DELTA,
};
}
onPress = e => {
console.log("ASdasd", e);
const offsetY = this.offsetY
const pressY = e.nativeEvent.pageY
const currentStackHeight = this.state.STACK_HEIGHT - offsetY + CARD_HEIGHT + (this.state.CARD_AMOUNT - 1) * CARD_VISIBLE_HEIGHT_COLLAPSED
let y = TOP_OFFSET
if (pressY < y || pressY > currentStackHeight + TOP_OFFSET) {
return false
}
const collapsedCount = Math.floor(offsetY / CARD_VISIBLE_DELTA)
const expanedCount = this.state.CARD_AMOUNT - collapsedCount - 2
for (let i = 0; i <= this.state.CARD_AMOUNT; i++) {
// if a collapsed card
if (i < collapsedCount) y += CARD_VISIBLE_HEIGHT_COLLAPSED
// if the last card
else if (i === this.state.CARD_AMOUNT - 1) y += CARD_HEIGHT
// if a collapsing card
else if (i === collapsedCount) y += currentStackHeight - CARD_HEIGHT - collapsedCount * CARD_VISIBLE_HEIGHT_COLLAPSED - expanedCount * CARD_VISIBLE_HEIGHT
// if an expanded card
else y += CARD_VISIBLE_HEIGHT
if (pressY < y) {
console.log(this.props.data[i]);
return this.setState({ pressed: i })
}
}
}
render() {
const { data } = this.props;
let { scrollY } = this.state;
let cardTransform = i => {
if (!i) return { transform: [{ translateY: TOP_OFFSET }] }
const translateY = scrollY.interpolate({
inputRange: [
-100,
0,
CARD_VISIBLE_DELTA * i,
this.state.STACK_HEIGHT,
this.state.STACK_HEIGHT + 100
],
outputRange: [
TOP_OFFSET + i * 100,
TOP_OFFSET,
TOP_OFFSET - CARD_VISIBLE_DELTA * i,
TOP_OFFSET - CARD_VISIBLE_DELTA * i,
TOP_OFFSET - CARD_VISIBLE_DELTA * i - i * 5
],
})
return { transform: [{ translateY }] }
}
let cards = [];
for (let i = 0; i < this.state.CARD_AMOUNT; i++) {
cards.push(
<Animated.View
key={`card-${i}`}
style={[styles.card, cardTransform(i), {
top: i * CARD_VISIBLE_HEIGHT,
backgroundColor: data[i].backgroundColor,
}]}
>
<View style={{ flexDirection: 'row', justifyContent: 'space-between', marginBottom: 20 }}>
<Text style={{ color: data[i].color }} semiBold size={14}>
{data[i][name]}
</Text>
<Text style={{ color: data[i].color }} size={12}>
{moment(data[i].dayDate).format('DD / MMM / YY | hh:mm a')}
</Text>
</View>
<View style={{ flexDirection: 'row', justifyContent: 'center' }}>
<Thumbnail large source={{ uri: data[i].profile_image }} />
</View>
<View style={{ flexDirection: 'row', justifyContent: 'center', marginVertical: 30 }}>
<Text semiBold size={16} style={{ color: data[i].color, textAlign: 'center' }}>
{data[i].stylist_name}
</Text>
</View>
<View style={{ flexDirection: 'row', justifyContent: 'center', marginBottom: 30 }}>
<Text size={12} style={{ color: data[i].lightColor, textAlign: 'center' }}>
{data[i].address}
</Text>
</View>
{data[i].status === 0 && (
<View>
<View style={{ flexDirection: 'row', justifyContent: 'center', marginBottom: 20 }}>
<View style={{ flex: 0.3 }}>
<CountDownTimer
//date={new Date(parseInt(this.props.appointment.endDate))}
date={data.endDate}
// onEnd={() => {
// this.props.endTimer(this.props.appointment);
// }}
hours=""
mins=""
segs=" : "
containerStyle={{
flexDirection: 'row',
justifyContent: 'center',
borderWidth: 1,
borderColor: data[i].color,
borderRadius: 30,
paddingHorizontal: 0,
paddingTop: 0,
paddingBottom: 5,
}}
secondColonStyle={{ color: data[i].color, paddingTop: 10 }}
firstColonStyle={{ backgroundColor: 'transparent' }}
minsStyle={{ color: data[i].color, paddingTop: 10 }}
secsStyle={{ color: data[i].color, paddingTop: 10 }}
/>
</View>
</View>
<View style={{ flexDirection: 'row' }}>
<View style={{ flex: 3, marginHorizontal: 3, flexDirection: 'row', }}>
<TouchableOpacity
style={{
flex: 1,
borderWidth: 1,
borderColor: data[i].color,
borderRadius: 5,
}}
>
<Text size={14} style={{ textAlign: 'center', color: data[i].color }}>+ 5 min</Text>
</TouchableOpacity>
</View>
<View style={{ flex: 3, marginHorizontal: 3, flexDirection: 'row', }}>
<TouchableOpacity
onPress={() => alert("asddd")}
style={{
elevation: 10,
zIndex: 9999,
flex: 1,
borderWidth: 1,
borderColor: data[i].color,
borderRadius: 5,
}}
>
<Text size={14} style={{ textAlign: 'center', color: data[i].color }}>+ 5 min</Text>
</TouchableOpacity>
</View>
<View style={{ flex: 3, marginHorizontal: 3, flexDirection: 'row', }}>
<TouchableOpacity
style={{
flex: 1,
borderWidth: 1,
borderColor: data[i].color,
borderRadius: 5,
}}
>
<Text size={14} style={{ textAlign: 'center', color: data[i].color }}>+ 5 min</Text>
</TouchableOpacity>
</View>
</View>
</View>
)}
</Animated.View>
)
}
return (
<View style={{ flex: 1, backgroundColor: '#F5F5F5' }}>
<View style={StyleSheet.absoluteFill}>{cards}</View>
<Animated.ScrollView
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: scrollY } } }],
{
useNativeDriver: true,
listener: e => this.offsetY = e.nativeEvent.contentOffset.y
},
)}
scrollEventThrottle={24}
showsVerticalScrollIndicator={false}
style={[StyleSheet.absoluteFill]}
>
<TouchableOpacity onPress={this.onPress} style={[{ height: this.state.SCROLL_HEIGHT, zIndex: 2 }]}></TouchableOpacity>
</Animated.ScrollView>
</View>
)
}
}
const styles = StyleSheet.create({
card: {
position: 'absolute',
borderColor: 'black',
backgroundColor: 'white',
paddingHorizontal: 15,
paddingVertical: 15,
left: 20,
right: 20,
height: CARD_HEIGHT,
borderRadius: 25,
},
});
AppointmentCard.propTypes = {
data: PropTypes.array.isRequired,
};
export default AppointmentCard;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment