Skip to content

Commit

Permalink
Merge pull request #14 from williamjayjay/step11-add-inputCustom-empt…
Browse files Browse the repository at this point in the history
…yListCP-and-hooks

feat: add components inputCustom and emptyList cp and more hooks
  • Loading branch information
williamjayjay authored Jul 27, 2024
2 parents e15ff91 + 7de5686 commit 7763966
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 9 deletions.
Binary file modified bun.lockb
Binary file not shown.
77 changes: 77 additions & 0 deletions src/presentation/ui/components/InputCustom/inputCustom.index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import classNames from 'classnames';
import { useCallback, useState, type FC } from 'react';
import {
TextInput as RNTextInput,
Text,
View,
type NativeSyntheticEvent,
type TextInputFocusEventData,
} from 'react-native';

import { type IInput } from './types/input.type';

import colors from '@/presentation/ui/styles/colors.json';

export const InputCustom: FC<IInput.Input> = ({
onFocus,
onBlur,
inputInternalClassName,
inputClassName,
containerClassName,
...textInputProps
}) => {

const [isFocus, setIsFocus] = useState(false);

const handleFocus = useCallback(
(_e: NativeSyntheticEvent<TextInputFocusEventData>) => {
onBlur?.(_e);
setIsFocus(true);
},
[onBlur],
);
const handleBlur = useCallback(
(_e: NativeSyntheticEvent<TextInputFocusEventData>) => {
onFocus?.(_e);
setIsFocus(false);
},
[onFocus],
);
const testID = textInputProps.testID ?? 'input';

return (
<View
testID={`${testID}-warp`}
className={classNames(containerClassName ? containerClassName : 'w-full pb-4')}>

<View
className={classNames(
' border border-neutral-300 rounded-md flex-row items-center',
inputClassName ? inputClassName : 'h-11',
{
'border-neutral-50 ': !isFocus,
'border-main-300': isFocus,
'opacity-50': textInputProps.editable === false,
},
)}>
<RNTextInput
className={classNames(
'flex flex-1 h-full rounded-md px-3 bg-transparent text-neutral-300 ',
inputInternalClassName ? inputInternalClassName : '',
{
'bg-light': textInputProps.standardTitleAndBgDisabled,
},
)}
autoCorrect={false}
placeholderTextColor={colors.neutral[100]}
onBlur={handleBlur}
onFocus={handleFocus}
autoCapitalize="none"
{...textInputProps}
testID={testID}
/>
</View>

</View>
);
};
25 changes: 25 additions & 0 deletions src/presentation/ui/components/InputCustom/types/input.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { type TextInputProps } from 'react-native';

export namespace IInput {

export enum InputTypeDefault {
TEXT = 'text',
PASSWORD = 'password',
}

export interface Input extends TextInputProps {
errorMessage?: string;
label?: string;
options?: any;
typeProps?: any;
leftChild?: any;
rightChild?: any;
containerClassName?: string;
inputInternalClassName?: string;
inputClassName?: string;
textAddExists?: string;
standardTitleAndBgDisabled?: boolean;
textAddExistsOnPress?: () => void;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { View , Text} from "react-native";

export const ListEmptyComponent = () => (
<View className="py-6 w-full items-center gap-y-2 " >
<Text className=" font-karla700Bold text-lg text-neutral-300 leading-[20px] ">Nenhum dado disponível</Text>
</View>
);
40 changes: 35 additions & 5 deletions src/presentation/ui/screens/HomeScreen/home.index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,49 @@
import { useHomeViewModel } from "@/presentation/viewmodels/HomeViewModel/hooks/home.hook";
import { FC } from "react";
import { Text } from "react-native";
import { IHome } from "./types/home.type";
import { Text, TouchableOpacity, View } from "react-native";
import { IHome } from "@/presentation/ui/screens/HomeScreen/types/home.type";
import { SafeAreaContainer } from "@/presentation/ui/components/SafeAreaContainer/safeAreaContainer.index";
import { Feather } from '@expo/vector-icons';
import { InputCustom } from "@/presentation/ui/components/InputCustom/inputCustom.index";
import { ListEmptyComponent } from "@/presentation/ui/components/ListEmptyComponent/listEmptyComponent.index";

const HomeScreen: FC<IHome.Input> = () => {

const { students } = useHomeViewModel({})
const { students, searchTerm, handleSearch, filteredData } = useHomeViewModel({})

console.log('students', students.length)

return (
<SafeAreaContainer haveKeyboard >
<Text className="font-karla600SemiBold" >Ola mundo</Text>
<Text className="font-karla200ExtraLight" >Ola mundo</Text>
<Text className="font-karla600SemiBold" >Ola mundo</Text>
<Text className="font-karla200ExtraLight" >Ola mundo</Text>

<View className="flex-row items-center mb-1" >
<InputCustom
placeholder="nome ou sobrenome..."
containerClassName="w-[90%] text-[30px] pr-[4px]"
inputClassName='h-[50px]'
// inputInternalClassName='text-[18px]'
// value={searchTerm}
value={'teste'}
// onChangeText={(value: string) => handleSearch(data, value)}
onChangeText={(value: string) => { }}
/>


<TouchableOpacity onPress={() => { }} >
{/* add funcao para alterar cor do filtro */}
<Feather name="filter" size={30} color='#000' />
</TouchableOpacity>
</View>

{
!filteredData?.[0] && searchTerm.length > 1 &&
<ListEmptyComponent />
}



</SafeAreaContainer>
);
};
Expand Down
57 changes: 53 additions & 4 deletions src/presentation/viewmodels/HomeViewModel/hooks/home.hook.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,65 @@
import { useCallback } from "react";
import { useCallback, useState } from "react";
import { useHomeContext } from "../contexts/useHome.context";
import { InfiniteData } from "@tanstack/react-query";
import { StudentServerEntity } from "@/@core/domains/server-entities/student.server-entity";

export const useHomeViewModel = ({ }) => {

const homeContext = useHomeContext();
const { students } = useHomeContext();
const [searchTerm, setSearchTerm] = useState('');
const [filteredData, setFilteredData] = useState<any[]>([]);


// -- estados acima

// todo [ ] - criar logica ao incializar o app, no contexto, verificar se existe valor no storage, se tiver irá popular o useState lá do context, e caso contrário irá fazer o fetch com o useQuery.

const handleSearch = useCallback(
(data: InfiniteData<StudentServerEntity[] | [], unknown> | undefined, value: string) => {

setSearchTerm(value)

if (data && value) {
const allStudents = data.pages.flatMap((page: any) => page);

const filteredStudents = allStudents.filter((student: any) =>
(student.firstName.toLowerCase().includes(value) || student.lastName.toLowerCase().includes(value))
);

return setFilteredData(filteredStudents);
}

if (students && !data && value) {
const allStudents = students

const filteredStudents = allStudents.filter((student: any) =>
(student.firstName.toLowerCase().includes(value) || student.lastName.toLowerCase().includes(value))
);
return setFilteredData(filteredStudents);
}
else if (value === '' && !data) {
setFilteredData(students)
}
else if (value === '' && data) {
const allStudents = data.pages.flatMap((page: any) => page);

setFilteredData(allStudents)
}

},
[searchTerm],
)


// const callBackNotUsed = useCallback(async () => {

// }, []);


return {
students: homeContext.students,
students: students,
searchTerm,
handleSearch,
filteredData
};
};

0 comments on commit 7763966

Please sign in to comment.