import React , { useState , useEffect , useCallback , useMemo } from 'react' ; import Icon from 'react-native-vector-icons/Feather' ; import { format } from 'date-fns' ; import DateTimePicker from '@react-native-community/datetimepicker' ; import { Platform , Alert } from 'react-native' ; import { useRoute , useNavigation } from '@react-navigation/native' ; import api from '../../services/api' ; import { useAuth } from '../../hooks/auth' ; import { Container , Header , BackButton , HeaderTitle , UserAvatar , ProvidersListContainer , ProvidersList , ProviderContainer , ProviderAvatar , ProviderName , Calendar , Title , Schedule , Section , SectionTitle , SectionContent , Hour , HourText , CreateAppointmentButton , CreateAppointmentButtonText , OpenDatePickerButton , OpenDatePickerButtonText , } from './styles' ; export interface Provider { id : string ; name : string ; avatar_url : string ; } interface RouteParams { providerId : string ; } interface AvailabilityItem { hour : number ; available : boolean ; } const AppointmentDatePicker = ( ) => { const { user } = useAuth ( ) ; const route = useRoute ( ) ; const navigation = useNavigation ( ) ; const params = route . params as RouteParams ; const [ selectedProvider , setSelectedProvider ] = useState < string > ( params . providerId ) ; const minimumDate = useMemo ( ( ) => { const today = new Date ( ) ; if ( today . getHours ( ) >= 17 ) { return new Date ( today . setDate ( today . getDate ( ) + 1 ) ) ; } return today ; } , [ ] ) ; const [ showDatePicker , setShowDatePicker ] = useState ( false ) ; const [ selectedDate , setSelectedDate ] = useState ( minimumDate ) ; const [ selectedHour , setSelectedHour ] = useState ( 0 ) ; const [ providers , setProviders ] = useState < Provider [ ] > ( [ ] ) ; const [ availability , setAvailability ] = useState < AvailabilityItem [ ] > ( [ ] ) ; useEffect ( ( ) => { api . get ( '/api/v1/providers' ) . then ( response => { setProviders ( response . data ) ; } ) ; } , [ ] ) ; useEffect ( ( ) => { api . get ( `/api/v1/providers/${ selectedProvider }/day-availability` , { params : { year : selectedDate . getFullYear ( ) , month : selectedDate . getMonth ( ) + 1 , day : selectedDate . getDate ( ) , } , } ) . then ( response => { setAvailability ( response . data ) ; setSelectedHour ( 0 ) ; } ) ; } , [ selectedProvider , selectedDate ] ) ; const handleSelectProvider = useCallback ( ( providerId ) => { setSelectedProvider ( providerId ) ; } , [ ] ) ; const handleCreateAppointment = useCallback ( async ( ) => { try { const date = new Date ( selectedDate ) ; if ( ! selectedHour ) { Alert . alert ( 'Erro ao criar agendamento' , 'Selecione um horário e tente novamente!' ) ; return ; } date . setHours ( selectedHour ) ; date . setMinutes ( 0 ) ; await api . post ( '/api/v1/appointments' , { provider_id : selectedProvider , date , } ) ; navigation . navigate ( 'AppointmentCreated' , { date : date . getTime ( ) } ) ; } catch ( err ) { Alert . alert ( 'Erro ao criar agendamento' , 'Ocorreu um erro ao tentar criar o agendamento, tente novamente!' ) ; } } , [ selectedProvider , selectedDate , selectedHour , navigation ] ) ; const morningAvailability = useMemo ( ( ) => { return availability . filter ( ( { hour } ) => hour < 12 ) . map ( ( { hour , available } ) => ( { hour , hourFormatted : format ( new Date ( ) . setHours ( hour ) , 'HH:00' ) , available , } ) ) ; } , [ availability ] ) ; const afternoonAvailability = useMemo ( ( ) => { return availability . filter ( ( { hour } ) => hour >= 12 ) . map ( ( { hour , available } ) => ( { hour , hourFormatted : format ( new Date ( ) . setHours ( hour ) , 'HH:00' ) , available , } ) ) ; } , [ availability ] ) ; const handleToggleDatePicker = useCallback ( ( ) => { setShowDatePicker ( state => ! state ) ; } , [ ] ) ; const handleDateChanged = useCallback ( ( event , date ? ) => { if ( Platform . OS === 'android' ) { setShowDatePicker ( false ) ; } if ( date ) { setSelectedDate ( date ) ; } } , [ ] ) ; return ( < > < Header > < BackButton onPress = { ( ) => navigation . goBack ( ) } > < Icon name = 'chevron-left' size = { 24 } color = '#808080' / > < /BackButton> < HeaderTitle > Cabeleireiros < /HeaderTitle> < UserAvatar source = { { uri : user . avatar_url } } /> < /Header> < Container > < ProvidersListContainer > < ProvidersList data = { providers } keyExtractor = { provider => provider . id } renderItem = { ( { item : provider } ) => ( < ProviderContainer selected = { provider . id === selectedProvider } onPress = { ( ) => handleSelectProvider ( provider . id ) } > < ProviderAvatar source = { { uri : provider . avatar_url } } /> < ProviderName selected = { provider . id === selectedProvider } > { provider . name } < /ProviderName> < /ProviderContainer>)}/ > < /ProvidersListContainer> < Calendar > < Title > Escolha a data < /Title> < OpenDatePickerButton onPress = { handleToggleDatePicker } > < OpenDatePickerButtonText > Selecionar outra data < /OpenDatePickerButtonText> < /OpenDatePickerButton> { showDatePicker && ( < DateTimePicker { ... ( Platform . OS === 'ios' && { textColor : '#ffffff' } ) } locale = { 'pt-br' } is24Hour mode = 'date' display = { `${ Platform . OS === 'android' ? 'calendar' : 'inline' }` } value = { selectedDate } onChange = { handleDateChanged } minimumDate = { minimumDate } / > ) } < /Calendar> < Schedule > < Title > Escolha o horário < /Title> < Section > < SectionTitle > Manhã < /SectionTitle> < SectionContent > { morningAvailability . map ( ( { hourFormatted , hour , available } ) => ( < Hour available = { available } selected = { hour === selectedHour } onPress = { ( ) => setSelectedHour ( hour ) } key = { hourFormatted } > < HourText selected = { hour === selectedHour } > { hourFormatted } < /HourText> < /Hour>))} < /SectionContent> < /Section> < Section > < SectionTitle > Tarde < /SectionTitle> < SectionContent > { afternoonAvailability . map ( ( { hourFormatted , hour , available } ) => ( < Hour available = { available } selected = { hour === selectedHour } onPress = { ( ) => setSelectedHour ( hour ) } key = { hourFormatted } > < HourText selected = { hour === selectedHour } > { hourFormatted } < /HourText> < /Hour>))} < /SectionContent> < /Section> < /Schedule> < CreateAppointmentButton onPress = { handleCreateAppointment } > < CreateAppointmentButtonText > Agendar < /CreateAppointmentButtonText> < /CreateAppointmentButton> < /Container> < />); } ; export default AppointmentDatePicker ;