-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* [enhancement]: add placeholder color and type * [feat] disable default header, use header in page * Feedback banner svg component * FeedBack page initial markup and styles * feat: inital modal setup * [chore]: confetti asset * add extra styles and types - feedback input border color - feedback header background color * add Feedback Banner Svg * [feat]: add feedback button component * [feat]: Feedback Rating button test * [feat]: add Feedback page component * [feat]: add feedback modal. * [fix] move submit button to component * [fix] move back button to component * [feat] add onSelected styling * [fix] move pressables to components * [fix] use correct padding size * [fix] use corrct text size * [fix] use space component to add spacing * [fix] add onSelected prop * [chore] style cleanup and refactor * [feat] add test for button components - BackNavigationButton - SubmitFeedbackButton * [refactor] add onselected prop * [fix] use expo image component * [fix] change styling to camelcase * [fix] use stack screen header component * [feat] add modal tint * [feat] add Banner Images * [fix] use image background component * [fix] improve styling and add image properties * [chore] * fixed feedback page imagebackground --------- Co-authored-by: Tony Kharioki <antolisah@gmail.com>
- Loading branch information
Showing
15 changed files
with
461 additions
and
22 deletions.
There are no files selected for viewing
18 changes: 18 additions & 0 deletions
18
__tests__/components/buttons/BackNavigationButton.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { fireEvent, render, screen } from '@testing-library/react-native'; | ||
import React from 'react'; | ||
|
||
import BackNavigationButton from '../../../components/buttons/BackNavigationButton'; | ||
|
||
describe('<BackNavigationButton/>', () => { | ||
it('Renders back navigation button component', () => { | ||
render(<BackNavigationButton text="Go back" onPress={() => console.log('back')} />); | ||
expect(screen.getByText('Go back')).toBeDefined(); | ||
}); | ||
it('calls the function provided by onPress prop after pressing the button', () => { | ||
const onPress = jest.fn(); | ||
render(<BackNavigationButton text="Go back" onPress={onPress} />); | ||
fireEvent.press(screen.getByText('Go back')); | ||
|
||
expect(onPress).toHaveBeenCalledTimes(1); | ||
}); | ||
}); |
26 changes: 26 additions & 0 deletions
26
__tests__/components/buttons/FeedbackRatingButton.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { fireEvent, render, screen } from '@testing-library/react-native'; | ||
import React from 'react'; | ||
|
||
import FeedBackRatingButton from '../../../components/buttons/FeedBackRatingButton'; | ||
|
||
describe('<FeedbackRatingButton/>', () => { | ||
it('Renders feedback rating button component', () => { | ||
render( | ||
<FeedBackRatingButton | ||
rating={{ icon: '', text: 'Ok', value: 0 }} | ||
onPress={() => console.log('Feedback gotten succesfully')} | ||
testID="btn1" | ||
onSelected={true} | ||
/>, | ||
); | ||
expect(screen.getByText('Ok')).toBeDefined(); | ||
}); | ||
|
||
it('calls the function provided by onPress prop after pressing the button', () => { | ||
const onPress = jest.fn(); | ||
render(<FeedBackRatingButton rating={{ icon: '', text: 'Ok', value: 0 }} onPress={onPress} onSelected={true} />); | ||
fireEvent.press(screen.getByText('Ok')); | ||
|
||
expect(onPress).toHaveBeenCalledTimes(1); | ||
}); | ||
}); |
25 changes: 25 additions & 0 deletions
25
__tests__/components/buttons/SubmitFeedBackButton.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { fireEvent, render, screen } from '@testing-library/react-native'; | ||
import React from 'react'; | ||
|
||
import SubmitFeedbackButton from '../../../components/buttons/SubmitFeedbackButton'; | ||
|
||
describe('<SubmitFeedbackButton/>', () => { | ||
it('Renders submit feedback button component', () => { | ||
render( | ||
<SubmitFeedbackButton | ||
openModal={() => { | ||
console.log('hello'); | ||
}} | ||
text="SUBMIT FEEDBACK" | ||
/>, | ||
); | ||
expect(screen.getByText('SUBMIT FEEDBACK')).toBeDefined(); | ||
}); | ||
it('calls the function provided by onPress prop after pressing the button', () => { | ||
const onPress = jest.fn(); | ||
render(<SubmitFeedbackButton openModal={onPress} text="SUBMIT FEEDBACK" />); | ||
fireEvent.press(screen.getByText('SUBMIT FEEDBACK')); | ||
|
||
expect(onPress).toHaveBeenCalledTimes(1); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,135 @@ | ||
import React from 'react'; | ||
import { useTheme } from '@react-navigation/native'; | ||
import React, { useState } from 'react'; | ||
import { ImageBackground, StyleSheet, View } from 'react-native'; | ||
import { TextInput } from 'react-native-gesture-handler'; | ||
import FeedBackRatingButton from '../../components/buttons/FeedBackRatingButton'; | ||
import SubmitFeedbackButton from '../../components/buttons/SubmitFeedbackButton'; | ||
import Space from '../../components/common/Space'; | ||
import StyledText from '../../components/common/StyledText'; | ||
import MainContainer from '../../components/container/MainContainer'; | ||
import FeedbackSentModal from '../../components/modals/FeedbackSentModal'; | ||
import { typography } from '../../config/typography'; | ||
|
||
// TODO: implement feedback page | ||
/** | ||
* TASKS: | ||
* Implement feedback page | ||
* Should include a reactions component, a textarea and button | ||
*/ | ||
export type TypeRatingStates = { | ||
icon: string; | ||
text: string; | ||
value: number; | ||
}; | ||
|
||
const Feedback = () => { | ||
const { colors, dark } = useTheme(); | ||
const [showModal, setShowModal] = useState(false); | ||
const [selectedRating, setSelectedRating] = useState(2); | ||
const [description, setDescription] = useState(''); | ||
const ratingStates: Array<TypeRatingStates> = [ | ||
{ icon: '😔', text: 'Bad', value: 0 }, | ||
{ icon: '😐', text: 'Okay', value: 1 }, | ||
{ icon: '😊', text: 'Great', value: 2 }, | ||
]; | ||
const openModal = () => { | ||
setShowModal(true); | ||
}; | ||
|
||
const feedback = () => { | ||
return ( | ||
<MainContainer preset="scroll"> | ||
<StyledText>feedback</StyledText> | ||
<View style={styles.main}> | ||
<ImageBackground | ||
source={dark ? require('../../assets/images/bannerDark.png') : require('../../assets/images/bannerLight.png')} | ||
style={styles.feedBackBanner} | ||
resizeMode="cover" | ||
/> | ||
<Space size={10} /> | ||
<View style={styles.feedBackFormContainer}> | ||
<StyledText | ||
size="lg" | ||
font="bold" | ||
variant="text" | ||
style={[styles.FeedBackFormTitle, { color: colors.primary }]} | ||
> | ||
Your feedback helps us improve | ||
</StyledText> | ||
<Space size={29} /> | ||
<View style={[styles.feedBackForm, { backgroundColor: colors.background, borderColor: colors.border }]}> | ||
<StyledText style={styles.feedBackFormLabel} size="base"> | ||
How is/was the event | ||
</StyledText> | ||
<View style={styles.feedBackFormRatingContainer}> | ||
{ratingStates.map((rating, index) => { | ||
return ( | ||
<FeedBackRatingButton | ||
rating={rating} | ||
key={index} | ||
onPress={setSelectedRating} | ||
onSelected={rating.value === selectedRating} | ||
/> | ||
); | ||
})} | ||
</View> | ||
</View> | ||
<Space size={30} /> | ||
<TextInput | ||
style={[ | ||
styles.feedbackInput, | ||
{ backgroundColor: colors.bg, borderColor: colors.borderColor, color: colors.bgInverse }, | ||
]} | ||
placeholder="Type message here" | ||
placeholderTextColor={colors.placeHolder} | ||
value={description} | ||
onChangeText={setDescription} | ||
/> | ||
<Space size={26} /> | ||
<SubmitFeedbackButton openModal={openModal} text="SUBMIT FEEDBACK" /> | ||
</View> | ||
|
||
<FeedbackSentModal showModal={showModal} /> | ||
</View> | ||
</MainContainer> | ||
); | ||
}; | ||
|
||
export default feedback; | ||
const styles = StyleSheet.create({ | ||
main: { | ||
flex: 1, | ||
width: '100%', | ||
}, | ||
feedBackBanner: { | ||
height: 179, | ||
flex: 1, | ||
width: '100%', | ||
}, | ||
feedBackForm: { | ||
flex: 1, | ||
paddingTop: 17, | ||
borderRadius: 10, | ||
borderWidth: 1, | ||
}, | ||
feedBackFormContainer: { | ||
flex: 1, | ||
paddingVertical: 10, | ||
paddingHorizontal: 16, | ||
}, | ||
feedBackFormLabel: { | ||
textAlign: 'center', | ||
paddingBottom: 30, | ||
}, | ||
feedBackFormRatingContainer: { | ||
flex: 1, | ||
flexDirection: 'row', | ||
justifyContent: 'space-evenly', | ||
paddingBottom: 27, | ||
}, | ||
FeedBackFormTitle: { | ||
textAlign: 'center', | ||
}, | ||
feedbackInput: { | ||
paddingLeft: 20, | ||
paddingTop: 12, | ||
minHeight: 115, | ||
textAlignVertical: 'top', | ||
borderRadius: 7, | ||
borderWidth: 1, | ||
fontFamily: typography.primary.light, | ||
}, | ||
}); | ||
|
||
export default Feedback; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { useTheme } from '@react-navigation/native'; | ||
import React from 'react'; | ||
import { StyleSheet, View } from 'react-native'; | ||
import type { SvgProps } from 'react-native-svg'; | ||
import Svg, { ClipPath, Defs, G, Path } from 'react-native-svg'; | ||
|
||
export interface ISvgProps extends SvgProps { | ||
xmlns?: string; | ||
xmlnsXlink?: string; | ||
xmlSpace?: string; | ||
} | ||
|
||
const FeedBackBanner = (props: ISvgProps) => { | ||
const { colors } = useTheme(); | ||
const originalWidth = 412; | ||
const originalHeight = 179; | ||
const aspectRatio = originalWidth / originalHeight; | ||
return ( | ||
<View style={styles(aspectRatio).svgContainer}> | ||
<Svg | ||
data-name="Group 384" | ||
width="100%" | ||
height="100%" | ||
viewBox={`0 0 ${originalWidth} ${originalHeight}`} | ||
{...props} | ||
> | ||
<Defs> | ||
<ClipPath id="a"> | ||
<Path | ||
data-name="Rectangle 693" | ||
transform="translate(232 -402)" | ||
fill={colors.assetAccent} | ||
d="M0 0H412V179H0z" | ||
/> | ||
</ClipPath> | ||
</Defs> | ||
<G data-name="Group 383"> | ||
<G data-name="Group 382"> | ||
<Path data-name="Rectangle 691" fill={colors.assetAccent} d="M0 0H412V179H0z" /> | ||
<G data-name="Mask Group 1" transform="translate(-232 402)" clipPath="url(#a)"> | ||
<G transform="translate(338.688 -465.155)"> | ||
<Path | ||
data-name="Rectangle 692" | ||
transform="rotate(45 -140.229 182.44)" | ||
fill="#ff6e4d" | ||
d="M0 0H91.444V124.36H0z" | ||
/> | ||
<Path | ||
data-name="Path 163" | ||
d="M217.194 152.59l87.938-87.938L240.479 0l-87.938 87.938L64.733.129.08 64.782 240.592 305.31l64.669-64.669z" | ||
transform="translate(.051)" | ||
fill="#00e2c3" | ||
/> | ||
</G> | ||
</G> | ||
</G> | ||
</G> | ||
</Svg> | ||
</View> | ||
); | ||
}; | ||
const styles = (aspectRatio: number) => { | ||
return StyleSheet.create({ | ||
svgContainer: { | ||
width: '100%', | ||
aspectRatio, | ||
}, | ||
}); | ||
}; | ||
|
||
export default FeedBackBanner; |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { AntDesign } from '@expo/vector-icons'; | ||
import { useTheme } from '@react-navigation/native'; | ||
import React from 'react'; | ||
import { Pressable, StyleSheet } from 'react-native'; | ||
import StyledText from '../common/StyledText'; | ||
|
||
type BackNavigationButtonProps = { | ||
text: string; | ||
onPress: () => void; | ||
}; | ||
|
||
const BackNavigationButton = ({ text, onPress }: BackNavigationButtonProps) => { | ||
const { colors } = useTheme(); | ||
return ( | ||
<Pressable style={styles.headerTitle} onPress={onPress}> | ||
<AntDesign name="arrowleft" size={24} color={'white'} /> | ||
<StyledText style={[{ color: colors.whiteConstant }]} size="lg"> | ||
{text} | ||
</StyledText> | ||
</Pressable> | ||
); | ||
}; | ||
|
||
const styles = StyleSheet.create({ | ||
headerTitle: { | ||
paddingLeft: 23, | ||
flexDirection: 'row', | ||
columnGap: 22, | ||
position: 'absolute', | ||
width: '100%', | ||
paddingTop: 26, | ||
paddingBottom: 20, | ||
}, | ||
}); | ||
|
||
export default BackNavigationButton; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { useTheme } from '@react-navigation/native'; | ||
import React from 'react'; | ||
import { Pressable, StyleSheet, Text } from 'react-native'; | ||
import type { TypeRatingStates } from '../../app/(app)/feedback'; | ||
import StyledText from '../common/StyledText'; | ||
|
||
type Props = { | ||
onPress: (value: number) => void; | ||
rating: TypeRatingStates; | ||
onSelected: boolean; | ||
testID?: string; | ||
}; | ||
|
||
const FeedBackRatingButton = ({ onPress, rating, onSelected }: Props) => { | ||
const { colors } = useTheme(); | ||
const { icon, text, value } = rating; | ||
|
||
return ( | ||
<Pressable | ||
style={[ | ||
styles.pressableEmoji, | ||
{ backgroundColor: colors.bg, borderColor: colors.bg }, | ||
onSelected && { borderColor: colors.primary }, | ||
]} | ||
onPress={() => onPress(value)} | ||
> | ||
<Text style={styles.formRatingText}>{icon}</Text> | ||
<StyledText font="bold" size="sm"> | ||
{text} | ||
</StyledText> | ||
</Pressable> | ||
); | ||
}; | ||
const styles = StyleSheet.create({ | ||
formRatingText: { | ||
fontSize: 30, | ||
}, | ||
pressableEmoji: { | ||
minWidth: 67, | ||
minHeight: 67, | ||
justifyContent: 'center', | ||
alignItems: 'center', | ||
borderRadius: 4, | ||
borderWidth: 1, | ||
}, | ||
}); | ||
|
||
export default FeedBackRatingButton; |
Oops, something went wrong.