import {
Form,
SubmitButton,
FormField,
} from "../components/forms";
import React, { useState, useEffect, useContext } from "react";
import {
StyleSheet,
View,
Text,
TouchableNativeFeedback,
ScrollView,
} from "react-native";
import Screen from "../components/Screen";
import { dimensions } from "../config/dimensions";
import { MaterialCommunityIcons } from "@expo/vector-icons";
import colors from "../config/colors";
import * as Yup from "yup";
import FormDatePicker from "../components/forms/FormDatePicker";
import moment from "moment";
import SearchablePicker from "../components/SearchablePicker";
import { states, statesToCities } from "../assets/cities_states";
import { useFormikContext } from "formik";
import {
signup,
login,
userPersonalData,
existUsername,
existNickname,
} from "../api/auth";
import { AuthContext } from "../auth/context";
import authStorage from "../auth/storage";
import ConfirmationModal from "../components/ConfirmationModal";
import PasswordFormField from "../components/forms/PasswordFormField";
import constants from "../config/constants";
import CheckBox from "../components/forms/CheckBox";
import defaultStyles from "../config/styles";
import PhoneNumberFormField from "../components/forms/PhoneNumberFormField";
import { unMask, mask } from "react-native-mask-text";
import { getInstitutions } from "../api/fetchInstutions";
const phoneRegex = RegExp(
/^\(?[\(]?([0-9]{2})?\)?[)\b]?([0-9]{4,5})[-. ]?([0-9]{4})$/
);
const validationSchema = Yup.object().shape({
name: Yup.string()
.required("O nome é obrigatório")
.matches(/[a-zA-Z]/, "O nome e só pode conter letras"),
number: Yup.string()
.matches(phoneRegex, "Número inválido")
.required("O número de telefone é obrigatório"),
password: Yup.string()
.required("A senha é obrigatória")
.min(8, "Senha muito curta, minimo 8 caracteres")
.matches(/[a-zA-Z]/, "A senha só pode conter letras"),
confirmPassword: Yup.string()
.required("A senha é obrigatória")
.min(8, "Senha muito curta, minimo 8 caracteres")
.matches(/[a-zA-Z]/, "A senha só pode conter letras"),
state: Yup.string().required("O estado é obrigatório"),
city: Yup.string().required("A cidade é obrigatória"),
institutionName: Yup.string(),
secQuestion: Yup.string().required("Escolha a pergunta de segurança"),
secQuestionAns: Yup.string()
.required("A resposta da pergunta de segurança é obrigatória")
.max(255),
consent: Yup.bool().equals([true], "Este campo é obrigatório"),
role: Yup.string(),
});
function LocalDatePicker({ date, setDate, _moment }) {
const formatDate = () => date.format("DD/MM/YYYY");
return (
setDate(value)}
minimumDate={new Date(moment().subtract(110, "year"))}
date={date}
>
{date != _moment
? formatDate()
: "Selecione a data de nascimento"}
);
}
function GenderPicker({ name }) {
const [items, setItems] = useState([
{ value: "F", label: "Feminino" },
{ value: "M", label: "Masculino" },
{ value: "N", label: "Prefiro não dizer" },
]);
return (
);
}
function InstitutionPicker({ name }) {
const [items, setItems] = useState([
{ value: "SCHOOL", label: "Escola" },
{ value: "CIVIL_DEFENSE", label: "Defesa civil" },
{ value: "NGO", label: "Não governamental" },
{ value: "OTHER", label: "Outra" },
{ value: "X", label: "Nenhuma" },
]);
return (
);
}
function StatePicker({ name }) {
const [items, setItems] = useState(states);
return (
);
}
function CityPicker({ name }) {
const { values, setValues } = useFormikContext();
const state = values["state"];
useEffect(() => {
state && setItems(statesToCities[state].cities);
setValues({ ...values, city: "" });
}, [state]);
const [items, setItems] = useState([]);
return (
);
}
function InstitutionNamePicker({ name }) {
const { values } = useFormikContext();
const state = values["state"];
const city = values["city"];
const instType = values["institution"];
const [items, setItems] = useState([]);
const [institutions, setInstitutions] = useState([]);
useEffect(() => {
getInstitutions().then((data) => {
setInstitutions(data);
})
.catch((error) => {
console.error(error);
});
}, []);
useEffect(() => {
try {
if (state && city && instType) {
const insts = institutions[state] && institutions[state][city] && institutions[state][city][instType];
insts ? setItems(insts) : setItems([]);
}
} catch (e) {
console.log(e);
}
}, [state,city, instType, institutions]);
return (
);
}
function SecQuestionPicker({ name }) {
const [items, setItems] = useState([
{ value: "Qual a sua cor predileta?", label: "Qual a sua cor predileta?" },
{
value: "Qual é seu livro predileto?",
label: "Qual é seu livro predileto?",
},
{
value: "Qual o nome da rua em que você cresceu?",
label: "Qual o nome da rua em que você cresceu?",
},
{
value: "Qual o nome do seu bicho de estimação predileto?",
label: "Qual o nome do seu bicho de estimação predileto?",
},
{
value: "Qual a sua comida predileta?",
label: "Qual a sua comida predileta?",
},
{
value: "Qual é o seu país preferido?",
label: "Qual é o seu país preferido?",
},
{
value: "Qual é a sua marca de carro predileto?",
label: "Qual é a sua marca de carro predileto?",
},
]);
return (
);
}
function RolePicker({ name }) {
const [items, setItems] = useState([
{ value: "ROLE_INSTITUTION", label: "Responsável" },
{ value: "ROLE_CLIENT", label: "Não responsável" },
]);
return (
);
}
function MaterialCommunityIconsCustom({
name,
color = colors.primary,
size = 25,
}) {
return (
);
}
export default function RegisterScreen(props) {
const authContext = useContext(AuthContext);
const _moment = moment();
const [date, setDate] = useState(_moment);
const [scroll, setScroll] = useState();
const [showLog, setShowLog] = useState({ show: false, message: "" });
const [showModal, setShowModal] = useState({
show: false,
message: "",
form: null,
});
const comparePassword = (password, confirmPassword) => {
return password !== confirmPassword;
};
const automaticLogin = async (form) => {
const result = await login(form.number, form.password);
if (!result.ok) return;
authStorage.setToken(result.data);
const user = await userPersonalData();
user.ok && authContext.setUser(user.data);
};
const handleSubmit = async (form) => {
console.log(form);
const formDate =
date.format("DD/MM/yyyy") === moment().format("DD/MM/yyyy") ? "" : date;
const result = await signup({ ...form, dateofborn: formDate });
switch (result.status) {
case 200:
automaticLogin(form);
break;
case 422:
setShowLog({
show: true,
message: "Campo obrigatório não informado",
});
break;
default:
setShowLog({
show: true,
message: "Um erro inesperado ocorreu. Tente novamente mais tarde",
});
}
};
const fieldsAreNotInUse = async (form, actions) => {
var inUse = false;
const ru = await existUsername(form.number);
if (ru.data) {
actions.setFieldError("number", "Este número de telefone já está em uso");
inUse = true;
}
const rn = await existNickname(form.name);
if (rn.data) {
actions.setFieldError("name", "Este apelido de usuário já está em uso");
inUse = true;
}
if (!ru.ok || !rn.ok)
setShowLog({
show: true,
message: "Um erro inesperado ocorreu. Tente novamente mais tarde",
});
inUse &&
setShowLog({
show: true,
message: "Apelido de usuário ou telefone em uso",
});
return !inUse;
};
const copnfirmations = (form, actions) => {
var current_mask =
form.number.length >= 11 ? "(99) 99999-9999" : "(99) 9999-9999";
const psw_match = comparePassword(form.password, form.confirmPassword);
if (psw_match) {
actions.setFieldError("confirmPassword", "As senhas não correspondem");
scroll.scrollTo({ x: 0, y: 0, animated: true });
} else {
fieldsAreNotInUse(form, actions).then((isNotUsed) => {
if (isNotUsed) {
setShowModal({
show: true,
form: form,
message:
'Você está cadastrando o apelido "' +
form.name +
'" e o número ' + mask(form.number, current_mask) +
'. Deseja continuar o cadastro?',
});
} else {
console.log("scrolll");
scroll.scrollTo({ x: 0, y: 0, animated: true });
}
});
}
};
return (
setShowLog({ ...showLog, show: false })}
/>
{
handleSubmit(showModal.form);
}}
onDecline={() => {
setShowModal({ ...showModal, show: false, message: "" });
}}
/>
);
}
const styles = StyleSheet.create({
containter: {
flex: 1,
justifyContent: "center",
textAlign: "center",
paddingHorizontal: 10,
},
labelStyle: {
fontSize: dimensions.text.secondary,
fontWeight: "bold",
textAlign: "left",
color: colors.secondary,
},
iconField: {
alignItems: "center",
width: "100%",
flex: 1,
flexDirection: "row",
marginTop: 12,
marginBottom: 24,
},
dateInput: {
paddingLeft: 16,
},
warningText: {
color: colors.primary,
fontSize: dimensions.text.primary,
textAlign: "left",
marginBottom: 24,
},
});