📸 AvatarUpload - Upload e Pré-visualização de Imagem
Este componente permite que o usuário envie uma imagem e visualize a prévia antes de salvar. Ele utiliza o React com o hook useState
para armazenar a imagem selecionada.
🛠 Estrutura do Componente
Começamos importando os pacotes necessários:
import React, { useState } from "react";
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
useState
📌 → Gerencia o estado da imagem carregada.Avatar
,AvatarImage
eAvatarFallback
🖼 → Exibe a imagem carregada ou um texto de fallback caso nenhuma imagem tenha sido enviada.Input
📂 → Campo para upload do arquivo.Label
🏷 → Rótulo para o campo de upload.
🎨 Estado da Imagem
Criamos um estado (image
) para armazenar a URL da imagem carregada:
const [image, setImage] = useState(null);
Agora, precisamos de uma função que trate a seleção do arquivo e converta a imagem em base64 para pré-visualização.
📂 Manipulação do Arquivo
A função handleFileChange
é responsável por processar a imagem enviada pelo usuário:
const handleFileChange = (event) => {
const file = event.target.files[0]; // Obtém o arquivo selecionado
const reader = new FileReader();
reader.onloadend = () => {
setImage(reader.result); // Atualiza o estado com a imagem em base64
};
if (file) {
reader.readAsDataURL(file); // Converte a imagem para base64
}
};
- FileReader 📖 → Converte a imagem em um formato que o navegador pode exibir.
reader.onloadend
→ Quando a conversão termina, atualizamos o estadoimage
.
🏗 Renderizando o Componente
Agora, montamos a interface do componente:
return (
<div className="flex flex-col items-center space-y-2">
<Label htmlFor="avatar" className="mb-2">Foto de Perfil</Label>
{/* 📸 Avatar com fallback caso não tenha imagem */}
<Avatar className="w-32 h-32">
{image ? (
<AvatarImage src={image} alt="User Avatar" />
) : (
<AvatarFallback>Sem imagem</AvatarFallback>
)}
</Avatar>
{/* 📂 Input para upload da imagem */}
<div className="grid w-full max-w-sm items-center gap-1.5">
<Label htmlFor="avatar">Foto</Label>
<Input
type="file"
id="avatar"
accept="image/*"
onChange={handleFileChange}
/>
</div>
</div>
);
- Se a imagem foi carregada, exibimos a prévia (
AvatarImage
). - Caso contrário, mostramos o texto
"Sem imagem"
(AvatarFallback
). - O campo de upload (
Input
) aceita apenas arquivos do tipo imagem (accept="image/*"
).
📌 Código Completo
import React, { useState } from "react";
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
const AvatarUpload = () => {
const [image, setImage] = useState(null);
const handleFileChange = (event) => {
const file = event.target.files[0];
const reader = new FileReader();
reader.onloadend = () => {
setImage(reader.result);
};
if (file) {
reader.readAsDataURL(file);
}
};
return (
<div className="flex flex-col items-center space-y-2">
<Label htmlFor="avatar" className="mb-2">Foto de Perfil</Label>
<Avatar className="w-32 h-32">
{image ? (
<AvatarImage src={image} alt="User Avatar" />
) : (
<AvatarFallback>Sem imagem</AvatarFallback>
)}
</Avatar>
<div className="grid w-full max-w-sm items-center gap-1.5">
<Label htmlFor="avatar">Foto</Label>
<Input
type="file"
id="avatar"
accept="image/*"
onChange={handleFileChange}
/>
</div>
</div>
);
};
export default AvatarUpload;