Objetivo Principal:
Crie uma aplicação web de página única (SPA) responsiva e com tema escuro chamada "AI Product Photo Generator". Esta aplicação permite aos usuários enviar a URL de uma imagem de produto e gerar fotos de e-commerce profissionais e estilizadas usando a API Gemini. A interface do usuário deve ser limpa, moderna e intuitiva, com um layout de duas colunas em telas maiores.
Pilha de Tecnologia e Estrutura:
Framework: React com Hooks (useState, useCallback).
Linguagem: TypeScript.
Estilo: Tailwind CSS para todos os estilos. Garanta que a aplicação seja totalmente responsiva e inclua um modo escuro.
API AI: Use a biblioteca @google/genai para interagir com a API Gemini do Google. A chave da API deve ser obtida exclusivamente de process.env.API_KEY.
Estrutura de Arquivos: Organize o código em uma estrutura lógica:
App.tsx: Componente raiz que gerencia o estado e o layout principal.
components/: Diretório para componentes de UI reutilizáveis (Header.tsx, ImageInput.tsx, OptionsPanel.tsx, GeneratedImages.tsx).
services/: Diretório para a lógica de comunicação com a API (geminiService.ts).
types.ts: Para definições de tipos compartilhados (por exemplo, AppOptions).
constants.ts: Para dados estáticos como categorias de produtos.
Layout e Design Visual:
Layout Principal:
Use um fundo cinza claro no modo claro e um fundo cinza escuro no modo escuro.
Em telas grandes (desktops), implemente um layout de grade de duas colunas:
Coluna da Esquerda (Controles): Com uma largura de 1/3 (lg:col-span-4), esta coluna contém o painel de entrada e opções. Deve ser "sticky" para que permaneça visível ao rolar.
Coluna da Direita (Resultados): Com uma largura de 2/3 (lg:col-span-8), esta coluna exibe as imagens geradas, mensagens de estado e carregadores.
Em telas menores (dispositivos móveis), as colunas devem empilhar verticalmente.
Estilo Geral:
Use o Indigo como cor de destaque para botões, links e destaques.
Utilize cantos arredondados (rounded-lg, rounded-2xl) e sombras sutis (shadow-lg) para criar um efeito de profundidade e uma aparência moderna.
Garanta um espaçamento consistente em toda a aplicação.
Detalhes dos Componentes:
Header.tsx:
Um cabeçalho simples com um fundo branco/cinza escuro e uma sombra.
Contém o título principal "AI Product Photo Generator" em uma fonte grande e em negrito na cor de destaque.
Inclui um subtítulo descritivo abaixo, como "Crie fotos de e-commerce impressionantes e profissionais em segundos."
Painel de Controles (Coluna da Esquerda):
Deve estar contido em um card bem definido com preenchimento interno.
ImageInput.tsx:
Entrada de URL: Um campo de entrada de texto para o usuário colar a URL da imagem do produto.
Caixa de Visualização: Abaixo do campo de entrada, uma caixa com borda tracejada de 48 de altura que serve como área de visualização.
Estado Padrão: Inicialmente, a caixa de visualização exibe um ícone (por exemplo, um ícone de link) e um texto informativo como "A pré-visualização da imagem aparecerá aqui".
Funcionalidade de Visualização: Quando uma URL válida é inserida (no evento onBlur ou onKeyDown 'Enter'), a imagem é carregada e exibida dentro da caixa de visualização (usando object-contain).
Botão de Limpar: Um ícone 'X' aparece no canto superior direito da imagem de visualização, permitindo que o usuário remova a imagem.
Tratamento de Erros: Exiba mensagens de erro claras e amigáveis para URLs inválidas ou se a imagem não puder ser carregada (por exemplo, devido a erros de CORS).
OptionsPanel.tsx:
Um título "2. Personalize Sua Cena".
Categoria do Produto: Um menu suspenso (<select>) pré-preenchido com categorias de constants.ts (por exemplo, 'Vestuário - Feminino', 'Eletrônicos', 'Eletrodomésticos').
Número de Imagens: Um menu suspenso para selecionar quantas imagens gerar (por exemplo, 1 a 4).
Estilo da Foto: Um grupo de dois botões: 'Apenas Produto' e 'Com Modelo'. O botão selecionado deve ter um estilo ativo (fundo índigo, texto branco).
Descrição da Cena: Uma área de texto (<textarea>) de várias linhas onde os usuários podem opcionalmente descrever a cena desejada (por exemplo, "em uma bancada de mármore ao lado de uma planta").
Estado Desabilitado: Todos os controles neste painel devem ser desabilitados enquanto a geração de imagens estiver em andamento.
Botão Gerar:
Um botão grande, de largura total, com o texto "Gerar Fotos".
Estado de Carregamento: Quando clicado, o texto deve mudar para "Gerando..." e exibir um ícone de spinner animado.
Estado Desabilitado: O botão deve ser desabilitado se nenhuma imagem de produto for fornecida ou durante o processo de geração.
Painel de Resultados (GeneratedImages.tsx, Coluna da Direita):
Este componente deve gerenciar e exibir vários estados:
Estado de Boas-Vindas (Inicial): Antes que qualquer imagem seja fornecida, exiba uma mensagem acolhedora com um ícone de imagem e um texto como "Suas fotos profissionais aparecerão aqui".
Estado de Pronto: Após o usuário fornecer uma imagem, mas antes de clicar em gerar, mostre uma mensagem de prontidão como "Pronto para Gerar! Clique no botão para deixar a IA fazer sua mágica".
Estado de Carregamento: Durante a geração, exiba um título como "Gerando suas imagens..." e uma grade de espaços reservados de esqueleto de carregamento (cards cinza pulsantes) para indicar o progresso.
Estado de Erro: Se ocorrer um erro na API, exiba um componente de alerta proeminente, com estilo de erro (fundo vermelho), contendo a mensagem de erro.
Estado de Sucesso:
Exiba as imagens geradas com sucesso em uma grade responsiva (2 colunas em telas médias, 1 em pequenas).
Cada imagem deve estar em um card. Ao passar o mouse sobre uma imagem, um botão de download deve aparecer suavemente, permitindo que o usuário salve a imagem.
Lógica Principal e Interação com a API:
Gerenciamento de Estado (App.tsx):
Use o hook useState para gerenciar o estado da aplicação: a URL da imagem selecionada, as opções de personalização, as imagens geradas, o estado de carregamento (isLoading) e quaisquer mensagens de erro.
Serviço da API (geminiService.ts):
Crie uma função generateProductImages que aceite a URL da imagem e o objeto de opções.
Busca e Conversão de Imagem: A função deve primeiro buscar a imagem da URL fornecida e convertê-la para uma string base64. Inclua tratamento de erros robusto para falhas de busca ou problemas de CORS.
Construção do Prompt: Crie dinamicamente um prompt de texto detalhado para a API Gemini com base nas opções do usuário (categoria, estilo da foto, descrição da cena).
Chamada da API:
Use o gemini-2.5-flash-image-preview do @google/genai.
Envie a imagem base64 e o prompt de texto como partes de conteúdo (parts).
A configuração da API deve especificar que a saída pode ser tanto Modality.IMAGE quanto Modality.TEXT.
Faça chamadas de API paralelas e simultâneas se o usuário solicitar mais de uma imagem.
Processamento da Resposta: Extraia os dados da imagem base64 da resposta da API, formate-os como URLs de dados (data:image/png;base64,...) e retorne um array de strings de URL de imagem.
Tratamento de Erros: A função deve lançar erros significativos se a API falhar ou não retornar imagens.