First commit of the new app
This commit is contained in:
126
assets/components/reserva/PassageiroCard.tsx
Normal file
126
assets/components/reserva/PassageiroCard.tsx
Normal file
@@ -0,0 +1,126 @@
|
||||
import { colors } from '@/assets/styles/colors';
|
||||
import { Passageiro } from '@/assets/types';
|
||||
import styles from '@/styles/screens/reserva/detail.styles';
|
||||
import { FontAwesome } from '@expo/vector-icons';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Pressable, Text, View } from 'react-native';
|
||||
import Animated, {
|
||||
Easing,
|
||||
useAnimatedStyle,
|
||||
useSharedValue,
|
||||
withTiming,
|
||||
} from 'react-native-reanimated';
|
||||
import { DashedDivider } from './DashedDivider';
|
||||
import { FieldBox } from './FieldBox';
|
||||
|
||||
type Props = {
|
||||
passageiro: Passageiro;
|
||||
index: number;
|
||||
isOpen: boolean;
|
||||
isFirst: boolean;
|
||||
onToggle: () => void;
|
||||
};
|
||||
|
||||
const ANIM_DURATION = 280;
|
||||
|
||||
export function PassageiroCard({ passageiro, index, isOpen, onToggle }: Props) {
|
||||
const progress = useSharedValue(isOpen ? 1 : 0);
|
||||
const contentHeight = useSharedValue(0);
|
||||
const [measuredHeight, setMeasuredHeight] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (measuredHeight > 0) {
|
||||
contentHeight.value = measuredHeight;
|
||||
}
|
||||
}, [measuredHeight, contentHeight]);
|
||||
|
||||
useEffect(() => {
|
||||
progress.value = withTiming(isOpen ? 1 : 0, {
|
||||
duration: ANIM_DURATION,
|
||||
easing: Easing.out(Easing.cubic),
|
||||
});
|
||||
}, [isOpen, progress]);
|
||||
|
||||
const bodyAnimatedStyle = useAnimatedStyle(() => ({
|
||||
height: contentHeight.value * progress.value,
|
||||
opacity: progress.value,
|
||||
}));
|
||||
|
||||
const chevronAnimatedStyle = useAnimatedStyle(() => ({
|
||||
transform: [{ rotate: `${progress.value * 180}deg` }],
|
||||
}));
|
||||
|
||||
return (
|
||||
<View>
|
||||
<View style={styles.passageiroContainer}>
|
||||
<Pressable onPress={onToggle} style={styles.passageiroHeaderRow}>
|
||||
<View>
|
||||
<Text style={styles.passageiroSubtitle}>Passageiro {index + 1}</Text>
|
||||
<Text style={styles.passageiroName}>
|
||||
{passageiro.nome} {passageiro.sobrenome}
|
||||
</Text>
|
||||
</View>
|
||||
<Animated.View style={chevronAnimatedStyle}>
|
||||
<FontAwesome name="chevron-down" size={14} color={colors.vermelho} />
|
||||
</Animated.View>
|
||||
</Pressable>
|
||||
|
||||
<Animated.View
|
||||
style={[styles.passageiroBodyWrap, bodyAnimatedStyle]}
|
||||
pointerEvents={isOpen ? 'auto' : 'none'}>
|
||||
<View
|
||||
style={styles.passageiroBodyMeasure}
|
||||
onLayout={(e) => {
|
||||
const h = Math.ceil(e.nativeEvent.layout.height);
|
||||
if (h > 0) setMeasuredHeight(h);
|
||||
}}>
|
||||
<View style={styles.passageiroBody}>
|
||||
<View style={styles.twoCol}>
|
||||
<View style={styles.twoColItem}>
|
||||
<FieldBox label="Nome" value={passageiro.nome} />
|
||||
</View>
|
||||
<View style={styles.twoColItem}>
|
||||
<FieldBox label="Apelido" value={passageiro.sobrenome} />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.twoCol}>
|
||||
<View style={styles.twoColItem}>
|
||||
<FieldBox label="Data de Nasc." value={passageiro.dataNascimento} />
|
||||
</View>
|
||||
<View style={styles.twoColItem}>
|
||||
<FieldBox label="Género" value={passageiro.genero} />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.twoCol}>
|
||||
<View style={styles.twoColItem}>
|
||||
<FieldBox label="Nacionalidade" value={passageiro.nacionalidade} />
|
||||
</View>
|
||||
<View style={styles.twoColItem}>
|
||||
<FieldBox label="Telemóvel" value={passageiro.telemovel} />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<FieldBox label="Morada" value={passageiro.morada} />
|
||||
<FieldBox label="Nacionalidade Doc." value={passageiro.paisEmissao} />
|
||||
<FieldBox label="Nr Doc Identificação" value={passageiro.numeroDocumento} />
|
||||
|
||||
<View style={styles.twoCol}>
|
||||
<View style={styles.twoColItem}>
|
||||
<FieldBox label="Data Emissão" value={passageiro.dataDeEmissao} />
|
||||
</View>
|
||||
<View style={styles.twoColItem}>
|
||||
<FieldBox label="Data Val./Exp." value={passageiro.dataDeValidade} />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<FieldBox label="Email" value={passageiro.email} />
|
||||
</View>
|
||||
</View>
|
||||
</Animated.View>
|
||||
</View>
|
||||
<DashedDivider width={1} borderStyle="dashed" />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user