add a new reusable component - Modal | add QualificationModal

This commit is contained in:
Dawid Wysokiński 2021-04-05 09:33:35 +02:00
parent e91100f53e
commit a7a37ccba1
6 changed files with 219 additions and 19 deletions

View File

@ -24,6 +24,7 @@
"graphql": "^15.5.0",
"lodash": "^4.17.21",
"native-base": "^2.15.2",
"polish-plurals": "^1.1.0",
"react": "17.0.1",
"react-native": "0.64.0",
"react-native-bootsplash": "^3.2.0",

View File

@ -0,0 +1,45 @@
import React from 'react';
import {
Modal as RNModal,
ModalProps as RNModalProps,
StyleSheet,
TouchableWithoutFeedback,
View,
} from 'react-native';
export type ModalProps = RNModalProps & {
backdrop?: boolean;
onPressBackdrop?: () => void;
children?: React.ReactNode;
};
const Modal = ({
backdrop = true,
onPressBackdrop,
children,
...rest
}: ModalProps) => {
return (
<RNModal {...rest}>
{backdrop && (
<TouchableWithoutFeedback onPress={onPressBackdrop}>
<View style={styles.backdrop} />
</TouchableWithoutFeedback>
)}
{children}
</RNModal>
);
};
const styles = StyleSheet.create({
backdrop: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'rgba(0,0,0,.4)',
},
});
export default Modal;

View File

@ -1,20 +1,28 @@
import React from 'react';
import { Profession } from 'libs/graphql';
import { Profession, Qualification } from 'libs/graphql';
import { Icon, Left, ListItem, Right, Text, View } from 'native-base';
export interface ItemProps {
profession: Profession;
onPress?: (qualification: Qualification) => void;
}
const Item = ({ profession }: ItemProps) => {
const Item = ({ profession, onPress }: ItemProps) => {
return (
<View>
<ListItem itemHeader itemDivider>
<Text>{profession.name}</Text>
</ListItem>
{profession.qualifications.map(qualification => (
<ListItem key={qualification.id}>
<ListItem
key={qualification.id}
onPress={() => {
if (onPress) {
onPress(qualification);
}
}}
>
<Left>
<Text>
{qualification.name} ({qualification.code})

View File

@ -1,9 +1,10 @@
import React from 'react';
import React, { useState } from 'react';
import { FlatListProps, RefreshControl } from 'react-native';
import { Profession } from 'libs/graphql';
import { Maybe, Profession, Qualification } from 'libs/graphql';
import { List } from 'native-base';
import { List, View } from 'native-base';
import Item from './Item';
import QualificationModal from './QualificationModal';
export interface ProfessionsProps
extends Pick<FlatListProps<Profession>, 'refreshing' | 'onRefresh'> {
@ -15,20 +16,40 @@ const Professions = ({
refreshing,
onRefresh,
}: ProfessionsProps) => {
const [selectedQualification, setSelectedQualification] = useState<
Maybe<Qualification>
>(null);
const [showModal, setShowModal] = useState(false);
return (
<List
dataArray={professions}
renderItem={({ item }: { item: Profession }) => {
return <Item profession={item} />;
}}
keyExtractor={item => item.id}
refreshControl={
<RefreshControl
refreshing={refreshing ?? false}
onRefresh={onRefresh ?? (() => {})}
/>
}
/>
<View style={{ flex: 1 }}>
<List
dataArray={professions}
renderItem={({ item }: { item: Profession }) => {
return (
<Item
profession={item}
onPress={qualification => {
setSelectedQualification(qualification);
setShowModal(true);
}}
/>
);
}}
keyExtractor={item => item.id}
refreshControl={
<RefreshControl
refreshing={refreshing ?? false}
onRefresh={onRefresh ?? (() => {})}
/>
}
/>
<QualificationModal
onPressBackdrop={() => setShowModal(false)}
qualification={selectedQualification}
visible={showModal}
/>
</View>
);
};

View File

@ -0,0 +1,120 @@
import React from 'react';
import { Maybe, Qualification } from 'libs/graphql';
import { QUESTIONS } from 'config/app';
import { StyleSheet } from 'react-native';
import {
Body,
Button,
Card,
CardItem,
Left,
Text,
View,
Icon,
Right,
} from 'native-base';
import Modal, { ModalProps } from 'common/Modal/Modal';
import { polishPlurals } from 'polish-plurals';
export interface QualificationModalProps
extends Pick<ModalProps, 'visible' | 'onPressBackdrop'> {
qualification: Maybe<Qualification>;
}
const QualificationModal = ({
qualification,
onPressBackdrop,
visible,
}: QualificationModalProps) => {
return (
<Modal
animationType="fade"
transparent
visible={visible}
onPressBackdrop={onPressBackdrop}
>
<View style={styles.modalContentContainer}>
<Card>
<CardItem header bordered style={styles.cardHeader}>
<Body style={{ flex: 3, alignSelf: 'center' }}>
<Text>
{qualification?.name} ({qualification?.code})
</Text>
</Body>
<Right>
<Button small transparent>
<Icon
type="Entypo"
name={true ? 'star' : 'star-outlined'}
style={{ fontSize: 30 }}
/>
</Button>
</Right>
</CardItem>
<CardItem>
<Body>
<View style={styles.buttonContainer}>
<Button
full
style={[styles.button, styles.marginRight]}
onPress={onPressBackdrop}
>
<Text>Anuluj</Text>
</Button>
{QUESTIONS.map((question, index) => (
<Button
style={[
styles.button,
index === QUESTIONS.length - 1 ? {} : styles.marginRight,
]}
key={question}
>
<Text style={styles.buttonText}>
Test {question}{' '}
{polishPlurals('pytanie', 'pytania', 'pytań', question)}
</Text>
</Button>
))}
</View>
</Body>
</CardItem>
</Card>
</View>
</Modal>
);
};
const styles = StyleSheet.create({
modalContentContainer: {
justifyContent: 'center',
flexGrow: 1,
paddingHorizontal: 15,
maxWidth: 420,
},
buttonContainer: {
display: 'flex',
flexDirection: 'row',
alignSelf: 'flex-end',
},
buttonText: {
textAlign: 'center',
textAlignVertical: 'center',
},
button: {
flex: 1,
height: 'auto',
},
marginRight: {
marginRight: 6,
},
cardHeader: {
display: 'flex',
flexDirection: 'row',
},
star: {
flex: 1,
},
});
export default QualificationModal;

View File

@ -7743,6 +7743,11 @@ pngjs@^3.0.0, pngjs@^3.3.3:
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
polish-plurals@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/polish-plurals/-/polish-plurals-1.1.0.tgz#c512cc06df8881c7f199dd12aba197552c3dada8"
integrity sha512-Sect6u4dScUC15pUZGhbfr7Q5o6CRAIpBj/KdkYf27EUa5Ls6+MkK5LXUH3PQL5aPAmFGnmJMXhdXzNLGc5V5A==
posix-character-classes@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"