-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
adding scenarios and adding screen #19
base: master
Are you sure you want to change the base?
Changes from 4 commits
b5cd8d9
b758f13
f983349
b205869
0a58355
f9064ab
ed2c7b3
767783d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
export default { | ||
useReactotron: __DEV__, | ||
useFixtures: false, | ||
useStorybook: false | ||
useFixtures: true, | ||
useStorybook: false, | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import React from 'react' | ||
import {Text, View} from 'react-native' | ||
|
||
import type { ToDoAdd } from '../Entities/index' | ||
|
||
import Images from '../../../Themes/Images' | ||
|
||
type Props = { | ||
item : ToDoAdd, | ||
onToDos(values: ToDoAdd):void | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Para tipagem de funções, você pode definir assim:
|
||
} | ||
|
||
const AddToDO = ({ item, onToDos}: Props,ref) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. De onde veio esse |
||
return ( | ||
<View> | ||
|
||
</View> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,42 @@ | ||
// @flow | ||
import React, { useCallback, useState, useEffect } from 'react' | ||
import { View, Text, ImageBackground, Image, TouchableOpacity, FlatList } from 'react-native' | ||
import { View, Text, ImageBackground, Image, TouchableOpacity, FlatList, ActivityIndicator, Modal, Picker } from 'react-native' | ||
import { useDispatch, useSelector } from 'react-redux' | ||
|
||
import ToDo from '../Components/ToDo' | ||
import TogglableText from '../Components/TogglableText' | ||
|
||
import { actions as ToDosUIActions } from '../Redux/Ui' | ||
import ToDoEntitySelectors from '../Selectors/Entity' | ||
import ToDoUISelections from '../Selectors/Ui' | ||
import ToDoUISelections, { fetching } from '../Selectors/Ui' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. O termo padrão é There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Além disso, o ideal nesse caso seria utilizar Nada impede você de importar os seletores um por um (no caso de fetching), apenas deixo como sugestão quando fazer isso, renomear para o import para
|
||
|
||
import styles from './ToDoScreen.style' | ||
import { Images } from '../../../Themes' | ||
|
||
import type { StackNavigationProp } from '@react-navigation/stack' | ||
|
||
import moment from 'moment' | ||
import moment from 'moment' //data-hora | ||
import { TextInput } from 'react-native-gesture-handler' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Por que usar o |
||
import colors from '../../../Themes/Colors' | ||
import { values } from 'lodash' | ||
|
||
|
||
|
||
type Props = { | ||
navigation: StackNavigationProp | ||
} | ||
|
||
|
||
const ToDoScreen = ({ navigation }: Props) => { | ||
// Redux Actions | ||
const dispatch = useDispatch() | ||
const getToDos = useCallback(() => dispatch(ToDosUIActions.request())) | ||
|
||
// State | ||
const [selectedFilterIndex, setFilterIndex] = useState(0) | ||
const [selectedFilterIndex, setFilterIndex] = useState(0) | ||
const [add, setAdd] = useState(false) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Com propriedades booleanas, é recomendado seguir o padrão de adicionar um
ou se você preferir (com tipagem do Typescipt):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. E seria interessante também deixar mais claro o que está sendo adicionado, aberto ou o que a data representa, por exemplo:
|
||
const [open, setOpen] = useState(false) | ||
const [date, setDate] = useState(new Date()) | ||
|
||
// Selectors | ||
const sortedToDos = useSelector(ToDoEntitySelectors.sortedToDos) | ||
|
@@ -41,36 +50,49 @@ const ToDoScreen = ({ navigation }: Props) => { | |
|
||
// Consts | ||
const filterList = ['All', 'Today', 'This week', 'This month'] | ||
console.tron.logImportant({sortedToDos,fetching,error}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Numa PR normal, comentários ou |
||
|
||
return ( | ||
<ImageBackground source={Images.appBackground} style={styles.background}> | ||
<HeaderContainer onPressSearch={() => {}} /> | ||
<View style={styles.tasksContainer}> | ||
<FilterListContainer | ||
filterList={filterList} | ||
selectedFilter={selectedFilterIndex} | ||
selectedFilter={selectedFilterIndex} //-- | ||
onPressFilter={setFilterIndex} | ||
/> | ||
{!fetching && !error && !!sortedToDos && ( | ||
<FlatList | ||
style={{ marginLeft: 12 }} | ||
data={sortedToDos} | ||
keyExtractor={(item, index) => `${item.id}-${index}-${item.title}`} | ||
renderItem={({ item }) => ( | ||
<ToDo onPressText={() => {}} toggleToDo={() => {}} text={item.title} toggled={item.isDone} /> | ||
)} | ||
/> | ||
)} | ||
<ListContainer | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gostei dessa decisão de extrair o componente de lista. Isso limpa o código dessa tela, e deixa o propósito do componente bem evidente. |
||
sortedToDos = {sortedToDos} | ||
fetching = {fetching} | ||
error = {error} | ||
/> | ||
</View> | ||
<FloatingButton onPress={() => {}} /> | ||
<FloatingButton onPress={() => setOpen(true)} /> | ||
<Modal transparent={true} visible ={open} animationType="slide"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do mesmo jeito que extraiu o |
||
<View style={styles.container}> | ||
<View style={styles.flexModalContainer}> | ||
<CloseButton onPress = {() => setOpen(false)}/> | ||
<TextInput style={styles.textInput} placeholder='Novo Lembrete' placeholderTextColor ={colors.c600}/> | ||
<AddDate/> | ||
<PriorityList/> | ||
<FloatingButtonAdd onPress = {() => setAdd(true)}/> | ||
</View> | ||
</View> | ||
</Modal> | ||
</ImageBackground> | ||
) | ||
} | ||
|
||
const FloatingButton = ({ onPress }) => ( | ||
<TouchableOpacity onPress={onPress} style={styles.floatingButton}> | ||
<Image source={Images.add['36px']} /> | ||
</TouchableOpacity> | ||
const HeaderContainer = ({ onPressSearch }) => ( | ||
<View style={styles.headerContainer}> | ||
<View> | ||
<Text style={styles.displayDateName}>Today</Text> | ||
<Text style={styles.date}>{moment().format('dddd, DD MMMM')}</Text> | ||
</View> | ||
<TouchableOpacity activeOpacity={0.7} onPress={onPressSearch} style={styles.searchContainer}> | ||
<Image source={Images.search['24px']} /> | ||
</TouchableOpacity> | ||
</View> | ||
) | ||
|
||
const FilterListContainer = ({ filterList, selectedFilter, onPressFilter }) => ( | ||
|
@@ -89,15 +111,78 @@ const FilterListContainer = ({ filterList, selectedFilter, onPressFilter }) => ( | |
</View> | ||
) | ||
|
||
const HeaderContainer = ({ onPressSearch }) => ( | ||
<View style={styles.headerContainer}> | ||
<View> | ||
<Text style={styles.displayDateName}>Today</Text> | ||
<Text style={styles.date}>{moment().format('dddd, DD MMMM')}</Text> | ||
</View> | ||
<TouchableOpacity activeOpacity={0.7} onPress={onPressSearch} style={styles.searchContainer}> | ||
<Image source={Images.search['24px']} /> | ||
</TouchableOpacity> | ||
const ListContainer = ({sortedToDos,fetching,error}) => ( | ||
<> | ||
{!!fetching && | ||
<View style = {styles.fetchingCircle}> | ||
<ActivityIndicator size="large" color = "#000"/> | ||
</View> | ||
} | ||
{Object.entries(sortedToDos).length == 0 ? <EmptyContainer/> : | ||
<> | ||
<FlatList | ||
style={{ marginLeft: 12 }} | ||
data={sortedToDos} | ||
keyExtractor={(item, index) => `${item.id}-${index}-${item.title}`} | ||
renderItem={({ item }) => ( | ||
<ToDo onPressText={() => {}} toggleToDo={() => {console.warn(item.isDone)}} text={item.title} toggled={item.isDone} /> | ||
)} | ||
/> | ||
</> | ||
} | ||
</> | ||
) | ||
|
||
const EmptyContainer = () => ( | ||
<View style={styles.emptyContainer}> | ||
<Image source={Images.sol['36px']} /> | ||
<Text style = {styles.displayEmptyName}>Tudo Limpo!</Text> | ||
<Text style = {styles.displayEmptyText}>Adicione um novo lembrete tocando no '+'.</Text> | ||
</View> | ||
) | ||
|
||
const FloatingButton = ({ onPress }) => ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Esses componentes dentro desse arquivo são bem pequenos, mas ainda assim, merecem seu próprio arquivo, seu próprio arquivo de estilos, seu próprio registro no Storybook, etc. Inclusive, são esses componentes pequenos que são super reutilizáveis e não podem estar perdidos dentro de um arquivo de tela. |
||
<TouchableOpacity onPress={onPress} style={styles.floatingButton}> | ||
<Image source={Images.add['36px']} /> | ||
</TouchableOpacity> | ||
) | ||
|
||
const FloatingButtonAdd = ({ onPress }) => ( | ||
<TouchableOpacity style ={styles.floatingButtonAdd} onPressText={onPress}> | ||
<Text style={styles.textAdd}>Adicionar</Text> | ||
</TouchableOpacity> | ||
) | ||
|
||
const CloseButton = ({ onPress }) => ( | ||
<TouchableOpacity onPress={onPress}> | ||
<Image source={Images.close['24px']} /> | ||
</TouchableOpacity> | ||
) | ||
|
||
const AddDate = ({}) => ( | ||
<View> | ||
<TouchableOpacity onPress={() => {}} style={styles.addDateTouch}> | ||
<Image style={styles.addDateImage} source={Images.bell['24px']} /> | ||
<Text style = {styles.addDateText}>Lembrar-me</Text> | ||
</TouchableOpacity> | ||
</View> | ||
) | ||
|
||
const PriorityList = () =>{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Um erro bastante comum é guardar informações de estado de dados dentro do componente e não da tela. Por exemplo, a tela de "Novo Lembrete" precisa da prioridade, mas esse informação á perdida aqui dentro desse componente. Para isso, a gente geralmente usa o padrão controlled-component, onde a tela controla o componente. Ficaria algo assim:
|
||
const [priorityList, setPriorityList] = useState('Selecionar') | ||
return ( | ||
<View style ={styles.container}> | ||
<Image style={styles.addDateImage} source ={Images.flag['24px']}/> | ||
<Text style={styles.textPicker}>Prioridade</Text> | ||
<Picker style = {styles.picker} priorityList = {priorityList} onValueChange = {(value, index) => setPriorityList(index)}> | ||
<Picker.Item label='Selecionar' value='0'/> | ||
<Picker.Item label='Baixa' value='1'/> | ||
<Picker.Item label='Media' value='2'/> | ||
<Picker.Item label='Alta' value='3'/> | ||
</Picker> | ||
</View> | ||
) | ||
} | ||
|
||
|
||
export default ToDoScreen |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,9 @@ export type ToDoType = { | |
reminder: string, | ||
priority: string | ||
} | ||
|
||
export type ToDoAdd = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Um
|
||
title?: string, | ||
reminder?: string, | ||
priority?: String, | ||
} | null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quando a gente sobe algum código pra develop ou pra master, tentamos sempre subir com fixtures desativadas. Isso evita eventuais erros na hora de gerar versões de produção.