add a new reusable component - Modal | add QualificationModal
This commit is contained in:
parent
e91100f53e
commit
a7a37ccba1
|
@ -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",
|
||||
|
|
|
@ -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;
|
|
@ -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})
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
|
@ -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"
|
||||
|
|
Reference in New Issue