Cargando experiencia

1 / 9

Fotografía Profesional · Ciudad de Panamá

Momentos
que duran
para siempre

Captamos la esencia de cada historia — familias, maternidad, graduaciones y marcas — con luz, emoción y arte.

Explorar
FamiliaMaternidadNewbornComercial GraduaciónEventosRetratosMarca Personal FamiliaMaternidadNewbornComercial GraduaciónEventosRetratosMarca Personal

Nuestros servicios

Cada sesión es una experiencia diseñada para ti — con atención, creatividad y los mejores equipos profesionales.

01 👨‍👩‍👧

Retratos & Familia

Sesiones íntimas que capturan la personalidad y el amor de cada familia, en estudio o locación.

Desde $90
02 🤰

Maternidad & Newborn

El regalo más especial: fotografías que preservan los instantes más mágicos de la llegada de tu bebé.

Desde $90
03 🎓

Graduación

Celebra tu logro con imágenes que reflejan el esfuerzo, la alegría y el comienzo de una nueva etapa.

Desde $90
04 📦

Fotografía Comercial

Imágenes de producto, marca personal y contenido para redes que hacen que tu negocio destaque.

Desde $120
05 🎉

Eventos

Cumpleaños, graduaciones corporativas, reuniones — cobertura completa de los momentos que importan.

Desde $150

Portafolio

Niños corriendo en el Casco Viejo
Niños corriendo en el Casco Viejo
Alegría en las calles históricas
Alegría en las calles históricas
Sesión familiar completa
Sesión familiar completa
Familia en el parque
Familia en el parque
Familia en el Casco Antiguo
Familia en el Casco Antiguo
Retrato familiar — Casco Viejo
Retrato familiar — Casco Viejo
Sonrisas en familia
Sonrisas en familia
Retrato — Primera Comunión
Retrato — Primera Comunión
Momento de fe e inocencia
Momento de fe e inocencia
Pura alegría — niños en el Casco
Pura alegría — niños en el Casco
Magia y burbujas
Magia y burbujas
Hermanos en la ciudad
Hermanos en la ciudad
Niño — Primera Comunión
Niño — Primera Comunión
Graduación — mirada sobre el hombro
Graduación — mirada sobre el hombro
Graduación — toga JARC, pose frontal
Graduación — toga JARC, pose frontal
Graduación — sonrisa natural
Graduación — sonrisa natural

Precios transparentes

Todos los precios en USD · Incluye edición profesional · Entrega por galería digital privada

Básico
$90

Ideal para retratos individuales o parejas · 45 min

  • 45 minutos de sesión
  • 1 locación o estudio
  • 10 fotos editadas
  • Galería digital privada
  • Entrega en 7 días
Reservar
Premium
$220

Experiencia completa para familias grandes · 3h

  • 3 horas de sesión
  • Familia completa sin límite
  • 50 fotos editadas
  • 📸 5 fotos impresas 20x30 cm
  • Múltiples locaciones
  • 🎬 Video con drone incluido
  • ✨ Teaser cinematográfico (60s)
  • Entrega prioritaria 3 días
Reservar
Básico
$90

Sesión maternidad individual · 1h

  • 1 hora de sesión
  • Estudio con props incluidos
  • 15 fotos editadas
  • Galería digital privada
  • Entrega en 7 días
Reservar
Premium
$260

Pack maternidad + newborn · 2 sesiones

  • 2 sesiones separadas
  • Maternidad + recién nacido
  • 60 fotos editadas en total
  • 🎁 Regalo premium para mamá
  • 📸 5 fotos impresas 20x30 cm
  • Props y sets exclusivos
  • 🎬 Video con drone incluido
  • ✨ Teaser cinematográfico (60s)
  • Entrega prioritaria
Reservar
Básico
$90

Sesión individual de graduación · 1h

  • 1 hora de sesión
  • Locación o estudio
  • 15 fotos editadas
  • Galería digital privada
  • Entrega en 7 días
Reservar
Premium
$240

Experiencia completa de graduación · 3h

  • 3 horas de sesión
  • Familia y amigos sin límite
  • 50 fotos editadas
  • 📸 5 fotos impresas 20x30 cm
  • Múltiples locaciones icónicas
  • 🎬 Video con drone incluido
  • ✨ Teaser cinematográfico (60s)
  • Entrega prioritaria 3 días
Reservar
Básico
$120

Productos o marca personal · 1h

  • 1 hora de sesión
  • Hasta 10 productos / looks
  • 20 fotos editadas
  • Fondo neutro en estudio
  • Entrega en 5 días
Reservar
Premium
$400

Branding completo · Día de producción

  • Medio día de producción
  • Locación + estudio
  • 80 fotos editadas
  • 📸 Pack de impresiones incluido
  • 🎬 Video con drone incluido
  • ✨ Teaser de marca (60s)
  • Derechos comerciales completos
  • Entrega exprés
Reservar
Básico
$150

Eventos íntimos · Hasta 2h

  • 2 horas de cobertura
  • Eventos de hasta 30 personas
  • 40 fotos editadas
  • Galería digital privada
  • Entrega en 7 días
Reservar
Premium
$500

Cobertura completa · Día entero

  • Cobertura de 8 horas
  • Eventos corporativos / grandes
  • 150+ fotos editadas
  • 📸 10 fotos impresas 20x30 cm
  • 🎬 Video con drone incluido
  • ✨ Teaser del evento (60s)
  • Álbum digital premium
  • Entrega en 3 días
Reservar

Productos físicos

Más allá de la galería digital — convierte tus fotos favoritas en objetos únicos que duran generaciones.

Álbum Clásico PhotoLife Panama
Álbum impreso

Álbum Clásico

El álbum perfecto para guardar los recuerdos de tu sesión. Diseño personalizado, impresión de alta resolución y acabado profesional.

  • Formato 20×20 cm, capa dura
  • 20 páginas en papel mate premium
  • Diseño personalizado incluido
  • Entrega en 2–3 semanas
Pack de Fotos Impresas PhotoLife Panama
Impresiones

Pack de Fotos

Impresiones profesionales en papel fotográfico premium. Ideales para enmarcar y decorar tu hogar con momentos únicos.

  • 10 fotos formato 15×20 cm
  • Papel fotográfico mate o brillante
  • Laminado protector incluido
  • Entrega en 1 semana
🖼
Foto enmarcada
Marco de madera · 20×30 cm
Desde$35
🗓
Calendario
12 meses · Fotos personalizadas
Desde$25
🃏
Tarjetas
Pack 20 und · Navidad / Cumpleaños
Desde$20
🪞
Canvas
Impresión en lienzo · 40×60 cm
Desde$55
Bruno Freitas — Fotógrafo PhotoLife Panama

Fotografía
con alma

Soy Bruno Freitas, fotógrafo brasileño que encontró en Panamá el escenario perfecto para contar historias a través de la fotografía. Mi pasión es encontrar la luz perfecta y el instante auténtico que convierte cada imagen en un recuerdo eterno.

"Timeless Moments.
Real Connections."
Godox AD200 Pro Iluminación profesional Edición artística Video & Drone
Hablemos →

Clientes felices

★★★★★

Bruno capturó cada detalle de nuestra sesión de maternidad con una sensibilidad increíble. Las fotos son un tesoro que guardaremos para siempre.

— María González · Maternidad
★★★★★

Las fotos de la graduación de mi hija quedaron espectaculares. Profesional, puntual y con un ojo artístico muy especial. 100% recomendado.

— Carlos & Ana Rodríguez · Graduación
★★★★★

Contratamos a PhotoLife Panama para las fotos de producto de nuestra tienda y el resultado superó todas las expectativas. Ventas aumentaron notablemente.

— Laura Martínez · Fotografia Comercial
¿Listo para empezar?

Reserva tu sesión

Contáctanos por WhatsApp o Instagram. Respondemos en menos de 24 horas y te asesoramos sin compromiso.

💬 WhatsApp +507 6660-0119 📸 Instagram @photolifepanama ✉️ Email info@photolifepanama.com

Tu espacio
para revisar
tus sesiones

Accede a tu galería privada, descarga tus fotos en alta resolución y sigue de cerca tus próximas sesiones.

500+ Sesiones
5★ Valoración
5 Años
© 2025 PhotoLife Panama
← Volver al sitio

Bienvenido
de vuelta

Accede a tu galería y descarga tus fotos.

o continúa con

Crea tu
cuenta

Accede a tu galería y revive cada momento.

¡Bienvenido a
PhotoLife!

Tu cuenta fue creada con éxito.
Revisa tu correo para confirmar tu registro.

Recupera tu
contraseña

Ingresa tu correo y te enviaremos un enlace para restablecerla.

¡Bienvenido, amigo!

Aquí puedes ver tus sesiones, descargar tus fotos y gestionar tus pedidos.

📸
1
Sesiones
13
Fotos
0
Pedidos
★5
Valoración
Accesos rápidos
Ver fotos
Tus sesiones y galerías
Mis servicios
Sesiones contratadas
Reservar sesión
Habla con Bruno
Última sesión
Cargando sesiones...
Mis sesiones
Cargando sesiones...
📅

¿Listo para tu próxima sesión?

Cuando tengas nuevas fotos, aparecerán aquí ordenadas por sesión y fecha.

Reservar sesión
Mis servicios contratados
📷
Sesión Familiar — Estándar
Casco Viejo · 1h 30min · 25 fotos · Jun 2025
Completado
$120
🗓

Próximas sesiones

Cuando reserves una nueva sesión, podrás seguir su estado aquí.

Reservar nueva sesión
Mis productos
📦

Aún no tienes productos

Aquí aparecerán tus álbumes, impresiones y otros productos físicos.
¡Completa tu experiencia con un álbum de recuerdos!

Ver catálogo
Mi perfil
📸
Cliente PhotoLife Panama
// ── PASSO 2: Cole este bloco inteiro antes do ── (function () { 'use strict'; // ── CONFIGURAÇÃO ───────────────────────────────────────────── var SUPABASE_URL = 'https://tglzryglrdcwjfnbznow.supabase.co'; var SUPABASE_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InRnbHpyeWdsemRjd2pmbnpub3ciLCJyb2xlIjoiYW5vbiIsImlhdCI6MTc0OTM4MDUxMiwiZXhwIjoyMDY0OTU2NTEyfQ.JqyTNJmOJCUj0iANO2tC6_6r9_UhVbZ3VaK89LMc32g'; // anon key pública // Inicializa o cliente Supabase var db = null; window.getDB = function getDB() { if (!db) { if (typeof supabase !== 'undefined') { db = supabase.createClient(SUPABASE_URL, SUPABASE_KEY); } } return db; } // ── REGISTRO DE CLIENTE ─────────────────────────────────────── // // Esta função é chamada quando um novo usuário se registra. // Substitui o setTimeout simulado no handleRegister() original. // window.supabaseRegistrarCliente = async function (nombre, correo, telefono) { var client = getDB(); if (!client) { console.error('Supabase não inicializado'); return false; } var { data, error } = await client .from('clientes') .insert({ nombre: nombre, correo: correo, telefono: telefono || null, // fecha_nac, notas — opcionais, podem ser atualizados depois }) .select() .single(); if (error) { // Erro de chave duplicada = cliente já existe (pode ser re-login) if (error.code === '23505') { console.log('Cliente já existe no banco:', correo); return true; // não é falha, apenas atualização } console.error('Erro ao registrar cliente:', error.message); return false; } console.log('Cliente registrado com sucesso:', data.id); return true; }; // ── BUSCAR SESSÕES DO CLIENTE NO SUPABASE ──────────────────── // // Busca as sessões fotográficas do cliente logado. // Retorna array no mesmo formato que PL_SESSIONS do site original. // window.supabaseBuscarSessoes = async function (correo) { var client = getDB(); if (!client) return []; // 1. Busca o cliente pelo e-mail var { data: clienteData, error: clienteError } = await client .from('clientes') .select('id, nombre') .eq('correo', correo.toLowerCase().trim()) .single(); if (clienteError || !clienteData) { console.log('Cliente não encontrado no banco:', correo); return []; } // 2. Busca as sessões vinculadas ao cliente var { data: sessoes, error: sessoesError } = await client .from('sesiones') .select('*') .eq('cliente_id', clienteData.id) .order('fecha_sesion', { ascending: false }); if (sessoesError) { console.error('Erro ao buscar sessões:', sessoesError.message); return []; } // 3. Converte para o formato esperado pelo site (compatível com PL_SESSIONS) return (sessoes || []).map(function (s) { return { id: s.id, name: clienteData.nombre, subtitle: s.tipo_sesion || '', category: traduzirTipoSessao(s.tipo_sesion), date: formatarData(s.fecha_sesion), allowedEmails: [correo.toLowerCase().trim()], photos: [], // as fotos vêm do Storage separadamente enlaceGaleria: s.enlace_galeria || null, estadoPago: s.estado_pago || 'pendiente', notas: s.notas || '', }; }); }; // ── BUSCAR URLs DAS FOTOS (Storage) ────────────────────────── // // Para cada sessão, busca os arquivos no bucket fotos-clientes/{cliente_id}/ // e gera URLs temporárias (válidas por 1 hora). // window.supabaseGetFotosSessao = async function (clienteId) { var client = getDB(); if (!client) return []; // Lista arquivos da pasta do cliente var { data: arquivos, error } = await client.storage .from('fotos-clientes') .list(clienteId + '/', { limit: 500 }); if (error || !arquivos || arquivos.length === 0) return []; // Filtra apenas imagens (não pastas) var imgs = arquivos.filter(function (f) { return f.name && /\.(jpg|jpeg|png|webp)$/i.test(f.name); }); // Gera URLs assinadas (1 hora = 3600 segundos) var urls = await Promise.all(imgs.map(async function (f) { var caminho = clienteId + '/' + f.name; var { data: signed } = await client.storage .from('fotos-clientes') .createSignedUrl(caminho, 3600); return { src: signed ? signed.signedUrl : '', caption: f.name.replace(/\.[^.]+$/, '').replace(/[-_]/g, ' '), date: f.created_at ? f.created_at.slice(0, 10) : '2025-01-01', fav: false, }; })); return urls.filter(function (u) { return u.src; }); }; // ── UPLOAD DE FOTO (uso pelo admin/Bruno) ──────────────────── // // Sobe uma foto para o bucket fotos-clientes/{clienteId}/ // Exemplo de uso no painel admin: // await supabaseUploadFoto('uuid-do-cliente', arquivo); // window.supabaseUploadFoto = async function (clienteId, arquivo) { var client = getDB(); if (!client) return null; var caminho = clienteId + '/' + Date.now() + '_' + arquivo.name; var { error } = await client.storage .from('fotos-clientes') .upload(caminho, arquivo, { upsert: false }); if (error) { console.error('Erro no upload:', error.message); return null; } return caminho; }; // ── INTEGRAÇÃO COM O SITE EXISTENTE ────────────────────────── // // Intercepta o finishLogin() original para: // 1. Registrar/confirmar o cliente no Supabase // 2. Carregar as sessões do banco em vez do PL_SESSIONS hardcoded // var _originalFinishLogin = window.finishLogin; window.finishLogin = async function (user) { if (!user || !user.email) { if (_originalFinishLogin) _originalFinishLogin(user); return; } // Registra o cliente (se não existir) — sem bloquear o login supabaseRegistrarCliente( user.name || user.email.split('@')[0], user.email, null ).catch(function (e) { console.error('Registro silencioso falhou:', e); }); // Carrega as sessões do Supabase try { var sessoesDB = await supabaseBuscarSessoes(user.email); if (sessoesDB && sessoesDB.length > 0) { // Substitui temporariamente PL_SESSIONS pelas sessões do banco window._supabaseSessoes = sessoesDB; // Adiciona as fotos de cada sessão for (var i = 0; i < sessoesDB.length; i++) { var s = sessoesDB[i]; // Busca fotos somente se não houver enlace_galeria externo if (!s.enlaceGaleria) { try { var fotos = await supabaseGetFotosSessao(s.id); sessoesDB[i].photos = fotos; } catch (e) { // sem fotos — normal para sessões novas } } } // Substitui a função getSessionsForUser temporariamente window._originalGetSessions = window.getSessionsForUser; window.getSessionsForUser = function (email) { if (!email) return []; var lower = email.toLowerCase().trim(); if (lower === (window.ADMIN_EMAIL || 'brunofreitas.oessj@gmail.com').toLowerCase()) { return window._supabaseSessoes || []; } return (window._supabaseSessoes || []).filter(function (s) { return s.allowedEmails.some(function (e) { return e.toLowerCase().trim() === lower; }); }); }; } } catch (e) { console.log('Supabase não disponível, usando dados locais:', e.message); } // Continua o fluxo original de login if (_originalFinishLogin) { _originalFinishLogin(user); } }; // ── INTERCEPTA HANDLEREGISTER ───────────────────────────────── // // Substitui o setTimeout simulado por cadastro real no Supabase. // var _originalHandleRegister = window.handleRegister; window.handleRegister = async function () { var name = document.getElementById('reg-name') ? document.getElementById('reg-name').value.trim() : ''; var email = document.getElementById('reg-email') ? document.getElementById('reg-email').value.trim() : ''; var pw = document.getElementById('reg-password')? document.getElementById('reg-password').value : ''; var confirm = document.getElementById('reg-confirm') ? document.getElementById('reg-confirm').value : ''; var terms = document.getElementById('reg-terms') ? document.getElementById('reg-terms').checked : false; // Validações básicas — mantém o comportamento original var showMsg = window.showMsg || function(){}; if (!name) return showMsg('register-msg','error','Por favor ingresa tu nombre.'); if (!email || !email.includes('@')) return showMsg('register-msg','error','Ingresa un correo válido.'); if (pw.length < 8) return showMsg('register-msg','error','La contraseña debe tener al menos 8 caracteres.'); if (pw !== confirm) return showMsg('register-msg','error','Las contraseñas no coinciden.'); if (!terms) return showMsg('register-msg','error','Debes aceptar los términos y condiciones.'); var btn = document.querySelector('#form-register .btn-submit span'); if (btn) btn.textContent = 'Creando cuenta...'; // Registra no Supabase var ok = await supabaseRegistrarCliente(name, email, null); if (btn) btn.textContent = 'Crear mi cuenta'; if (ok) { // Login automático após registro var user = { name: name, email: email, picture: '' }; window.finishLogin(user); } else { showMsg('register-msg', 'error', 'Error al crear la cuenta. Intenta de nuevo.'); } }; // ── HELPERS ────────────────────────────────────────────────── function traduzirTipoSessao(tipo) { var mapa = { familia: 'Familia', maternidad: 'Maternidad', graduacion: 'Graduación', comercial: 'Comercial', }; return mapa[tipo] || (tipo ? tipo.charAt(0).toUpperCase() + tipo.slice(1) : 'Sesión'); } function formatarData(dateStr) { if (!dateStr) return ''; try { var d = new Date(dateStr + 'T12:00:00'); return d.toLocaleDateString('es-PA', { day:'2-digit', month:'short', year:'numeric' }); } catch (e) { return dateStr; } } console.log('✅ Supabase PhotoLife: integração carregada.'); })(); // ═══════════════════════════════════════════════════════════════ // ONDE INSERIR NO SEU index.html: // // 1. No , ANTES de qualquer outro // // 2. O conteúdo deste arquivo vai dentro de uma tag que fecha // o bloco principal do site (perto da linha 3400 do seu HTML) // // Ficará assim: // ... código existente ... // function finishLogin(user) { ... } // // // // // // ═══════════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════════ // CORREÇÃO: guardarPerfil() — salva nome e telefone no Supabase // Substitui a função original que só mostrava mensagem falsa. // ═══════════════════════════════════════════════════════════════ window.guardarPerfil = async function () { var msg = document.getElementById('perfil-msg'); var nombre = document.getElementById('perfil-nombre') ? document.getElementById('perfil-nombre').value.trim() : ''; var telefono = document.getElementById('perfil-tel') ? document.getElementById('perfil-tel').value.trim() : ''; var correo = document.getElementById('perfil-email') ? document.getElementById('perfil-email').value.trim() : ''; function showPerfilMsg(tipo, texto) { if (!msg) return; var cor = tipo === 'ok' ? 'background:rgba(112,192,144,0.1);border-left:2px solid #70c090;color:#70c090;' : 'background:rgba(220,80,80,0.1);border-left:2px solid #dc5050;color:#dc5050;'; msg.style.cssText = 'display:block;' + cor + 'padding:10px 16px;font-size:12px;margin-top:16px;'; msg.textContent = texto; if (tipo === 'ok') setTimeout(function () { msg.style.display = 'none'; }, 3000); } if (!nombre) return showPerfilMsg('erro', 'El nombre no puede estar vacío.'); if (!correo) return showPerfilMsg('erro', 'No se encontró el correo del usuario.'); var client = getDB ? getDB() : null; if (!client) return showPerfilMsg('erro', 'Sin conexión con la base de datos.'); showPerfilMsg('ok', 'Guardando...'); var { error } = await client .from('clientes') .update({ nombre: nombre, telefono: telefono || null, }) .eq('correo', correo.toLowerCase().trim()); if (error) { console.error('Erro ao salvar perfil:', error.message); return showPerfilMsg('erro', 'Error al guardar. Intenta de nuevo.'); } // Atualiza o nome exibido no dashboard sem recarregar if (window.dbCurrentUser) { window.dbCurrentUser.name = nombre; var dbProfileName = document.getElementById('dbProfileName'); if (dbProfileName) dbProfileName.textContent = nombre; var dbWelcomeName = document.getElementById('dbWelcomeName'); if (dbWelcomeName) dbWelcomeName.textContent = nombre.split(' ')[0]; var dbNameChip = document.getElementById('dbNameChip'); if (dbNameChip) dbNameChip.textContent = nombre.split(' ')[0]; var navName = document.getElementById('navUserDisplayName'); if (navName) navName.textContent = nombre.split(' ')[0]; } showPerfilMsg('ok', '✓ Perfil actualizado correctamente.'); }; // ═══════════════════════════════════════════════════════════════ // CORREÇÃO: carrega o telefone do banco ao abrir o dashboard // ═══════════════════════════════════════════════════════════════ var _originalDbRefreshUserUI = window.dbRefreshUserUI; window.dbRefreshUserUI = async function () { // Executa o refresh original primeiro if (_originalDbRefreshUserUI) _originalDbRefreshUserUI(); // Busca telefone do banco e preenche o campo if (!window.dbCurrentUser || !window.dbCurrentUser.email) return; var client = window.getDB ? window.getDB() : null; if (!client) return; var { data } = await client .from('clientes') .select('telefono, nombre') .eq('correo', window.dbCurrentUser.email.toLowerCase().trim()) .single(); if (data) { var telField = document.getElementById('perfil-tel'); if (telField && data.telefono) telField.value = data.telefono; // Atualiza nome se veio do banco (caso Google login) var nomeField = document.getElementById('perfil-nombre'); if (nomeField && data.nombre) nomeField.value = data.nombre; } };