Skip to content

Commit

Permalink
Merge pull request #1 from polijrorg/Progressive-Screens
Browse files Browse the repository at this point in the history
Progressive screens
  • Loading branch information
pedrogomes18 authored Mar 23, 2024
2 parents 7e5ee76 + 3dc0a08 commit 13c1382
Show file tree
Hide file tree
Showing 25 changed files with 1,105 additions and 120 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@expo/vector-icons": "^14.0.0",
"@expo/webpack-config": "~19.0.1",
"@react-native-async-storage/async-storage": "1.21.0",
"@react-native-community/slider": "^4.5.0",
"@react-native-picker/picker": "2.6.1",
"@react-navigation/bottom-tabs": "^6.5.12",
"@react-navigation/material-top-tabs": "^6.6.6",
Expand Down
Binary file added public/assets/img/slider.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions src/components/Breadcrumb/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import * as S from './styles';

interface BreadcrumbProps {
path: { name: string; path: string }[];
handleNavigation: (index: number) => void;
}

const Breadcrumb: React.FC<BreadcrumbProps> = ({ path, handleNavigation }) => {
return (
<S.Container>
{path.map((screen, index) => (
<S.ItemContainer key={index}>
<S.Button onPress={() => handleNavigation(index)}>
<S.Crumb>{screen.name}</S.Crumb>
</S.Button>
{index !== path.length - 1 && <S.Separator>{'>'}</S.Separator>}
</S.ItemContainer>
))}
</S.Container>
);
};

export default Breadcrumb;
38 changes: 38 additions & 0 deletions src/components/Breadcrumb/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { TouchableOpacity, View, Text } from 'react-native';
import styled from 'styled-components/native';

export const Container = styled(View)`
width: 100%;
height: auto;
flex-direction: row;
align-items: center;
justify-content: center;
border-radius: 8px;
`;

export const Button = styled(TouchableOpacity)`
width: 16px;
height: 16px;
padding: 0px;
border-radius: 8px;
background-color: #c1c8cd;
display: flex;
align-items: center;
justify-content: center;
`;

export const ItemContainer = styled(View)`
flex-direction: row;
align-items: center;
`;

export const Crumb = styled(Text)`
font-size: 10px;
color: #333;
`;

export const Separator = styled(Text)`
font-size: 16px;
margin: 0 5px;
color: #999;
`;
9 changes: 8 additions & 1 deletion src/components/ContainerActions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ const ContainerActions: React.FC = () => {
}
};

const handleEnviarEvaluateVisit = () => {
navigation.navigate('EvaluateVisit' as never);
};

const getButtonText = (buttonType: string) => {
const userTypeConfig = buttonConfig[user.job] || buttonConfig.default;
return userTypeConfig[buttonType];
Expand All @@ -44,7 +48,10 @@ const ContainerActions: React.FC = () => {
text={getButtonText('mentorado')}
duty={handleEnviarEvaluateMentoring}
/>
<ButtonWhite text={getButtonText('visita')} />
<ButtonWhite
text={getButtonText('visita')}
duty={handleEnviarEvaluateVisit}
/>
</S.DivActions>
</S.ContainerActions>
);
Expand Down
72 changes: 56 additions & 16 deletions src/components/ContainerCards/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/* eslint-disable react-native/no-inline-styles */

import Card from '@components/Cards';
import * as S from './styles';
import React, { useEffect, useState } from 'react';
Expand All @@ -8,37 +7,51 @@ import ISupervisor from '@interfaces/Supervisor';
import useAuth from '@hooks/useAuth';
import SellerServices from '@services/SellerServices';
import SupervisorServices from '@services/SupervisorServices';
import { View, Text } from 'react-native';
import { View, Text, ActivityIndicator } from 'react-native';
import { useIsFocused } from '@react-navigation/native';
import ModulesServices from '@services/ModuleServices';

type IContainer = {
search?: string;
};

/*IMPORTANTE: AQUI EU FIZ UM CONTAINER PARA VENDEDORES E PARA SUPERVISORES */

const SellersContainer: React.FC<IContainer> = ({ search }) => {
const { user } = useAuth();
const [sellers, setSellers] = useState<ISeller[]>([]);
const [media, setMedia] = useState<{ [key: string]: number }>({});
const [loading, setLoading] = useState(true);

const isFocused = useIsFocused();

useEffect(() => {
const fetchData = async () => {
try {
if (user.job === 'Supervisor') {
const sellersData = await SellerServices.getAllSellerFromSupervisor(
user.id
setLoading(true);
const sellersData: ISeller[] =
user.job === 'Supervisor'
? await SellerServices.getAllSellerFromSupervisor(user.id)
: await SellerServices.getAllSellerFromManager(user.id);

const mediaData: { [key: string]: number } = {};
for (const seller of sellersData) {
const moduleGrades = await ModulesServices.getModuleGradesByIdSeller(
seller.id
);
setSellers(sellersData);
} else if (user.job === 'Gerente') {
const sellersData = await SellerServices.getAllSellerFromManager(
user.id
const totalGrade = moduleGrades.reduce(
(sum, grade) => sum + grade.media,
0
);
setSellers(sellersData);
const averageGrade =
moduleGrades.length > 0 ? totalGrade / moduleGrades.length : 0;
mediaData[seller.id] = averageGrade;
}

setSellers(sellersData);
setMedia(mediaData);
} catch (error) {
console.error('Erro ao buscar dados de vendedores:', error);
} finally {
setLoading(false);
}
};

Expand All @@ -64,11 +77,21 @@ const SellersContainer: React.FC<IContainer> = ({ search }) => {
<S.DivWrapper>
<S.TitleSlider>{'Vendedores'}</S.TitleSlider>
<S.Cards>
{filteredSellers.length > 0 ? (
{loading ? (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
margin: 24,
}}
>
<ActivityIndicator size="large" color="#0000ff" />
</View>
) : filteredSellers.length > 0 ? (
filteredSellers.map((seller, index) => {
const fullName = seller.name || 'Usuário';
const nameParts = fullName.split(' ');

let displayName = '';
if (nameParts.length > 1) {
const firstName = nameParts[0];
Expand All @@ -78,6 +101,8 @@ const SellersContainer: React.FC<IContainer> = ({ search }) => {
displayName = fullName;
}

const sellerMedia = media[seller.id] || 0;

return (
<Card
key={index}
Expand All @@ -86,7 +111,7 @@ const SellersContainer: React.FC<IContainer> = ({ search }) => {
cargo={seller.job}
supervisorId={seller.supervisorId}
companyId={seller.companyId}
nota={3.2} // Ajuste isso para obter a nota correta de cada tipo de dados (supervisor ou vendedor)
nota={sellerMedia} // Aqui exibimos a média do vendedor
/>
);
})
Expand All @@ -113,15 +138,19 @@ const SupervisorsContainer: React.FC<IContainer> = ({ search }) => {
const { user } = useAuth();
const isFocused = useIsFocused();
const [supervisors, setSupervisors] = useState<ISupervisor[]>([]);
const [loading, setLoading] = useState(true);

useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
const supervisorsData =
await SupervisorServices.getAllSupervisorsFromManager(user.id);
setSupervisors(supervisorsData);
} catch (error) {
console.error('Erro ao buscar dados de supervisores:', error);
} finally {
setLoading(false);
}
};

Expand All @@ -147,7 +176,18 @@ const SupervisorsContainer: React.FC<IContainer> = ({ search }) => {
<S.DivWrapper>
<S.TitleSlider>{'Supervisores'}</S.TitleSlider>
<S.Cards>
{filteredSupervisors.length > 0 ? (
{loading ? (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
margin: 24,
}}
>
<ActivityIndicator size="large" color="#0000ff" />
</View>
) : filteredSupervisors.length > 0 ? (
filteredSupervisors.map((supervisor, index) => {
const fullName = supervisor.name || 'Usuário';
const nameParts = fullName.split(' ');
Expand Down
11 changes: 7 additions & 4 deletions src/components/Dropdown/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,26 @@ const Dropdown: React.FC<IDropdownProps> = ({

return (
<View>
<S.DivFileds>
<S.DivFields>
<S.CustomDropdown isOpen={isOpen} setIsOpen={setIsOpen}>
<S.DropDownButton onPress={() => setIsOpen(!isOpen)}>
<S.Selected>
{selectedSupervisor?.name ||
selectedSeller?.name ||
'Selecione o responsável'}
</S.Selected>

<FontAwesome
name={isOpen ? 'caret-up' : 'caret-down'}
size={20}
color="#687076"
/>
</S.DropDownButton>
{isOpen && (
<S.DropdownList>
<S.DropdownList
maxHeight={
supervisors?.list.length > 1 || sellers?.length > 1 ? 300 : null
}
>
{(supervisors?.list.length > 0 &&
supervisors?.list.map((supervisor, index) => (
<S.DropdownItem
Expand Down Expand Up @@ -86,7 +89,7 @@ const Dropdown: React.FC<IDropdownProps> = ({
</S.DropdownList>
)}
</S.CustomDropdown>
</S.DivFileds>
</S.DivFields>
</View>
);
};
Expand Down
10 changes: 7 additions & 3 deletions src/components/Dropdown/styles.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { View, Text, TouchableOpacity, ScrollView } from 'react-native';
import styled from 'styled-components/native';

export const DivFileds = styled(View)`
export const DivFields = styled(View)`
width: 100%;
height: auto;
`;
Expand All @@ -27,10 +27,14 @@ export const DropDownButton = styled(TouchableOpacity)`
border-color: #d7dbdf;
`;

export const DropdownList = styled(ScrollView)`
interface DropdownListProps {
maxHeight?: number;
}

export const DropdownList = styled(ScrollView)<DropdownListProps>`
position: absolute;
width: 100%;
height: 300px;
max-height: ${({ maxHeight }) => (maxHeight ? `${maxHeight}px` : 'auto')};
background-color: #f1f3f5;
top: 100%;
z-index: 1;
Expand Down
59 changes: 59 additions & 0 deletions src/components/InputRage/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React, { useState } from 'react';
import * as S from './styles';
import { StyleSheet, Text } from 'react-native';
import Slider from '@react-native-community/slider';

interface askProps {
textAsk: string;
moduleId: string;
onChangeValue: (moduleId: string, newValue: number) => void;
initialValue?: number; // Propriedade para receber o valor inicial
}

const InputRange: React.FC<askProps> = ({
textAsk,
moduleId,
onChangeValue,
initialValue = 1, // Atribui o valor 1 caso initialValue não seja fornecido
}) => {
const [value, setValue] = useState(initialValue); // Usa initialValue como valor inicial

return (
<S.Container>
<S.Title>{textAsk}</S.Title>
<S.SliderContainer>
<S.TextLimt>1</S.TextLimt>
<Slider
style={styles.slider}
thumbImage={require('@assets/img/slider.png')}
minimumValue={1}
maximumValue={5}
minimumTrackTintColor="#3E63DD"
maximumTrackTintColor="#D9E2FC"
thumbTintColor="#3E63DD"
value={value}
step={1}
onValueChange={(newValue) => {
setValue(newValue);
onChangeValue(moduleId, newValue);
}}
/>
<Text style={styles.sliderValue}>
{value.toFixed(0).replace('.', ',')}
</Text>
</S.SliderContainer>
</S.Container>
);
};

const styles = StyleSheet.create({
slider: {
minWidth: '80%',
height: 40,
},
sliderValue: {
marginLeft: 10,
},
});

export default InputRange;
25 changes: 25 additions & 0 deletions src/components/InputRage/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { View, Text } from 'react-native';
import styled from 'styled-components/native';

export const Title = styled(Text)`
font-family: Poppins;
color: black;
`;
export const Container = styled(View)`
flex: 1;
`;

export const SliderContainer = styled(View)`
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 4px 16px;
align-items: center;
gap: 8px;
`;

export const TextLimt = styled(Text)`
font-family: Poppins;
font-size: 12px;
`;
Loading

0 comments on commit 13c1382

Please sign in to comment.