Nós iremos agora fazer a chamada das informações do backend para a nossa página de usuário. Nós iremos começar criando um service dentro da pasta “service” chamado “profileService.ts”
Iremos começar importando a api
import api from "./api";
Agora nós iremos criar um “userParams”, nós iremos buscar as informações que vamos usar no formulário.
interface UserParams {
firstName: string;
lastName: string;
phone: string;
email: string;
created_at: string;
}
Vamos agora criar o serviço em si
const profileService = {};
export default profileService;
Nós vamos fazer um método que vai pegar algumas informações do usuário atual, chamado “fetchCurrent”, ele será usado apenas na senha, pois as outras informações usaremos do “currentUser” que criamos no hook
fetchCurrent: async () => {
const token = sessionStorage.getItem("onebitflix-token");
const res = await api
.get("/users/current", {
headers: {
Authorization: `Bearer ${token}`,
},
})
.catch((error) => {
console.log(error.response.data.message);
return error.response;
});
return res.data;
},
Nós vamos começar fazendo um método para fazer o update das informações do usuário. Nós iremos usar um método put, passando a url de usuário atual.
userUpdate: async (params: UserParams) => {
const token = sessionStorage.getItem("onebitflix-token");
const res = await api
.put("/users/current", params, {
headers: {
Authorization: `Bearer ${token}`,
},
})
.catch((error) => {
if (error.response.status === 400 || error.response.status === 401) {
return error.response;
}
return error;
});
return res.status;
},
Agora nós iremos pegar todas as infomações vindas do “fetchCurrent”, e vamos setas nos estados que criamos.
useEffect(() => {
profileService.fetchCurrent().then((user) => {
setFirstName(user.firstName);
setLastName(user.lastName);
setPhone(user.phone);
setEmail(user.email);
setChangeEmail(user.email);
setCreatedAt(user.created_at);
});
}, []);
Agora, nós iremos fazer a chamada deles valores, iremos então substituir os valores fixos que criamos por esses que estamos pegando.
<FormGroup>
<Label className={styles.label} for="firstName">
NOME
</Label>
<Input
name="firstName"
type="text"
id="firstName"
placeholder="Qual o seu primeiro nome?"
required
maxLength={20}
className={styles.inputFlex}
value={firstName}
/>
</FormGroup>
<FormGroup>
<Label className={styles.label} for="lastName">
SOBRENOME
</Label>
<Input
name="lastName"
type="text"
id="lastName"
placeholder="Qual o seu último nome?"
required
maxLength={20}
className={styles.inputFlex}
value={lastName}
/>
</FormGroup>
<FormGroup>
<Label className={styles.label} for="phone">
WHATSAPP / TELEGRAM
</Label>
<Input
name="phone"
type="tel"
id="phone"
placeholder="(xx) 9xxxx-xxxx"
required
className={styles.input}
value={phone}
/>
</FormGroup>
<FormGroup>
<Label className={styles.label} for="email">
E-MAIL
</Label>
<Input
name="email"
type="email"
id="email"
placeholder="Coloque o seu email"
required
className={styles.input}
value={email}
/>
</FormGroup>
Agora, nós faremos um handle para fazermos o update, será semelhante ao handle que fizemos para o nosso registro. Mas antes, nós iremos fazer o import e configuração do toast.
Para usarmos o toast, nós teremos que criar 3 novos useState, para a cor, para saber se está aberto e também para a mensagem.
const [color, setColor] = useState("");
const [toastIsOpen, setToastIsOpen] = useState(false);
const [errorMessage, setErrorMessage] = useState("");
<ToastComponent color={color} isOpen={toastIsOpen} message={errorMessage}/>
Agora, nós podemos criar o handle de update. Nós iremos modificar um pouco a passagem dos parâmetros, pois não podemos fazer os parâmetros ficarem iguais aos que fizemos em registro, pois aqui estamos usando useState.
const handleUserUpdate = async function (event: FormEvent<HTMLFormElement>) {
event.preventDefault();
const res = await profileService.userUpdate({
firstName,
lastName,
phone,
email,
created_at,
});
if (res === 200) {
setToastIsOpen(true);
setErrorMessage("Informações alteradas com sucesso!");
setColor("bg-success");
setTimeout(() => setToastIsOpen(false), 1000 * 3);
} else {
setToastIsOpen(true);
setErrorMessage("Você não pode mudar para esse email!");
setColor("bg-danger");
setTimeout(() => setToastIsOpen(false), 1000 * 3);
}
};
Agora, para concluirmos a manipulação de alteração, nós precisamos criar um “onChange” para cada input, para que o nosso useState seja alterado assim que a pessoa mudar o que está escrito.
<FormGroup>
<Label className={styles.label} for="firstName">
NOME
</Label>
<Input
name="firstName"
type="text"
id="firstName"
placeholder="Qual o seu primeiro nome?"
required
maxLength={20}
className={styles.inputFlex}
value={firstName}
onChange={(event) => { setFirstName(event.target.value) }}
/>
</FormGroup>
<FormGroup>
<Label className={styles.label} for="lastName">
SOBRENOME
</Label>
<Input
name="lastName"
type="text"
id="lastName"
placeholder="Qual o seu último nome?"
required
maxLength={20}
className={styles.inputFlex}
value={lastName}
onChange={(event) => { setLastName(event.target.value) }}
/>
</FormGroup>
<FormGroup>
<Label className={styles.label} for="phone">
WHATSAPP / TELEGRAM
</Label>
<Input
name="phone"
type="tel"
id="phone"
placeholder="(xx) 9xxxx-xxxx"
required
className={styles.input}
value={phone}
onChange={(event) => { setPhone(event.target.value) }}
/>
</FormGroup>
<FormGroup>
<Label className={styles.label} for="email">
E-MAIL
</Label>
<Input
name="email"
type="email"
id="email"
placeholder="Coloque o seu email"
required
className={styles.input}
value={email}
onChange={(event) => { setEmail(event.target.value) }}
/>
</FormGroup>
Agora, nós iremos colocar esse handle no form e também botar o botão como “submit”
<Form className={styles.form} onSubmit={handleUserUpdate}>
<Button type="submit" className={styles.formBtn} outline>
Salvar Alterações
</Button>
Agora o formulário está funcional. Vamos então fazer a parte do retorno de nome.
<div className={styles.formName}>
<p className={styles.nameAbbreviation}>NT</p>
<p className={styles.userName}>
`${firstName} ${lastName}`}
</p>
</div>
Agora iremos pegar a primeira letra do primeiro e do segundo nome e passar na abreviação.
<div className={styles.formName}>
<p className={styles.nameAbbreviation}>
firstName.slice(0, 1)}
lastName.slice(0, 1)}
</p>
<p className={styles.userName}>
`${firstName} ${lastName}`}
</p>
</div>
Agora, nós iremos pegar os dados de quando a pessoa fez o seu cadastro. Nós iremos primeiro criar métodos para pegar as datas do “created_at” e depois iremos jogar tudo isso em um template string dentro da nossa data.
const date = new Date(created_at);
const month = date.toLocaleDateString("default", { month: "long" });
<div className={styles.memberTime}>
<img
src="/profile/iconProfileTime.svg"
alt="iconProfile"
className={styles.memberTimeImg}
/>
<p className={styles.memberTimeText}>
Membro desde <br />
{`${date.getDate()} de ${month} de ${date.getFullYear()}`}
</p>
</div>
Nós iremos criar um useState que vai começar sendo uma string vazia.
const [initials, setInitials] = useState("");
Depois iremos fazer a criação de um useEffect , onde iremos fazer o usdo do fetchCurrent novamente para pegar o “firstName” e “lastName”
useEffect(() => {
profileService.fetchCurrent().then((user) => {
const firstNameInitial = user.firstName.slice(0, 1);
const lastNameInitial = user.lastName.slice(0, 1);
setInitials(firstNameInitial + lastNameInitial);
});
}, []);
Agora iremos colocar o “initials” no lugar das letras fixas.
<p className={styles.userProfile} onClick={handleOpenModal}>
{initials}
</p>