{
if (!locals.variationTypes || locals.variationTypes.length === 0) {
console.warn("No variation types available.");
return;
}
const currencyFormatter = new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' });
// --- 1. Helper to find option for a given set of selections ---
const findOption = (selections) => {
if (!locals.combinedVariations) return null;
// Map selections to a more comparable format for speed if needed,
// but simple iteration is likely fine for small N.
for (const combined of locals.combinedVariations) {
if (!combined.selectedOptions || combined.selectedOptions.length !== selections.length) continue;
let match = true;
for (let i = 0; i < selections.length; i++) {
// Assumes strict order matching or we need to look up by typeID.
// The logic below assumes selections and combined.selectedOptions are sorted by TypeID or constructed in same order.
// Our Go code preserves order from locals.variationTypes, so this should match.
if (combined.selectedOptions[i].typeID !== selections[i].typeID ||
combined.selectedOptions[i].optionID !== selections[i].optionID) {
match = false;
break;
}
}
if (match) return combined;
}
return null;
};
// --- 2. Update Subtitles for ALL options ---
// We want to show what the price *would be* if the user selected that option,
// keeping all OTHER current selections constant.
for (const vt of locals.variationTypes) {
for (const opt of vt.options) {
// Construct hypothetical selection
const hypotheticalSelection = [];
let isComplete = true;
for (const t of locals.variationTypes) {
let selectedOptionID;
if (t.SecureID === vt.SecureID) {
// For the current type being iterated, use the option from the inner loop
selectedOptionID = opt.ID;
} else {
// For other types, use the value currently selected in the form
selectedOptionID = form.variation_ids ? form.variation_ids[t.SecureID] : null;
}
if (!selectedOptionID) {
isComplete = false;
break;
}
hypotheticalSelection.push({
typeID: t.SecureID,
optionID: selectedOptionID
});
}
if (isComplete) {
const optCombo = findOption(hypotheticalSelection);
const price = optCombo ? optCombo.price : null;
if (price) {
if (!opt.Props) opt.Props = {};
opt.Props.subtitle = currencyFormatter.format(Number(price));
} else {
// Price not found (invalid combination?), revert to frequency/default
if (opt.Props) opt.Props.subtitle = opt.Props.frequency_description || "";
}
} else {
// Incomplete selection (e.g. user hasn't picked other types yet)
// Revert to frequency/default
if (opt.Props) opt.Props.subtitle = opt.Props.frequency_description || "";
}
}
}
// --- 3. Update Main Form Price (Existing Logic) ---
// Check if CURRENT actual selection is complete
let allSelected = true;
for (const vt of locals.variationTypes) {
if (!form.variation_ids || !form.variation_ids[vt.SecureID]) {
allSelected = false;
break;
}
}
if (!allSelected) {
form.price = "";
form.rawPrice = 0;
return;
}
const currentSelection = locals.variationTypes.map(vt => ({
typeID: vt.SecureID,
optionID: form.variation_ids[vt.SecureID]
}));
const foundOption = findOption(currentSelection);
if (foundOption) {
const priceNum = Number(foundOption.price);
form.rawPrice = priceNum;
form.price = currencyFormatter.format(priceNum);
if (foundOption.comboPriceFormatted) {
form.combo_price = foundOption.comboPriceFormatted;
} else {
form.combo_price = "";
}
} else {
form.price = "";
form.rawPrice = 0;
form.combo_price = "";
}
/*
// --- 4. Cart Subscription Constraints ---
if (locals.isSubscription && locals.cartSubs && locals.cartSubs.length > 0) {
const cartFreq = locals.cartSubs[0]; // Active freq in cart
let selectedFreq = null;
for (let i = 0; i < locals.variationTypes.length; i++) {
let vt = locals.variationTypes[i];
let isFreqType = false;
for (let j = 0; j < vt.options.length; j++) {
let opt = vt.options[j];
if (opt.Props && opt.Props.frequency !== undefined && opt.Props.frequency !== null) {
isFreqType = true;
if (opt.Props.frequency !== cartFreq) {
opt.Props.disabled = true;
opt.Props.subtitle = opt.Props.frequency_description || (opt.Props.subtitle || "");
} else {
opt.Props.disabled = false;
if (locals.isComboEligible && (!form.variation_ids || form.variation_ids[vt.SecureID] !== opt.ID)) {
if (!form.variation_ids) form.variation_ids = {};
form.variation_ids[vt.SecureID] = opt.ID;
}
}
}
}
if (isFreqType && form.variation_ids) {
const selOptId = form.variation_ids[vt.SecureID];
if (selOptId) {
const selOpt = vt.options.find(o => o.ID === selOptId);
if (selOpt && selOpt.Props && selOpt.Props.frequency !== undefined) {
selectedFreq = selOpt.Props.frequency;
}
}
}
}
// Notice for Combo Price
if (selectedFreq !== null && selectedFreq === cartFreq && allSelected && form.price !== "") {
form.combo_notice = "🎉 Um Desconto Combo será aplicado no carrinho!";
} else {
form.combo_notice = "";
}
} else {
form.combo_notice = "";
// Ensure options are re-enabled if cart gets emptied (dynamic reactivity safety)
if (locals.variationTypes) {
for (const vt of locals.variationTypes) {
for (const opt of vt.options) {
if (opt.Props && opt.Props.disabled !== undefined) {
opt.Props.disabled = false;
}
}
}
}
}
*/
}' :use-debounce='100'>
First Look
Nível
Tamanho da Igreja
Frequência de Pagamento
Adicionar ao CarrinhoComprar agora
História da Semana pronta para contar, 1 jogo e 1 atividade de grupo — toda semana, alinhados ao tema do mês.
Cobrança
R$ 122,00/mês
R$ 109,80/mês
cobrado R$ 1.317,60 /ano
preço fixo — não varia com o tamanho da igreja
✓História da Semana — pronta para contar
✓Jogo da semana
✓Atividade de grupo
✕Guia do Comunicador completo
✕Roteiro de Pequeno Grupo
✕Devocional Diário das famílias
✕Materiais do mês e plano anual
Você pode mudar para o Premium a qualquer momento — o conteúdo do mês é liberado na hora.
Cada currículo Essencial é cobrado individualmente. Precisa de mais currículos e do material do mês? O Premium tem combos com desconto.
Premium
Quer o mês inteiro planejado — e as famílias junto?
O First Look Premium soma ao Essencial o Guia do Comunicador completo, pequeno grupo, devocional das famílias e todos os materiais do mês: kit visual, pôsteres, carta às famílias, playbook e plano anual.
✓Kit visual + pôsteres do mês
✓Pacote de mídias sociais
✓Carta às famílias
a partir de
R$ 198,00/mês
o upgrade libera o mês na hora
Sobre este produto
Você acredita que ...
O material usado na pré-escola de 0-5 anos (First Look) é desenvolvido para conectar as crianças com Deus de forma simples mas profunda.
Por isso, 3 verdades básicas são sempre apresentadas durante todo o ano:
O Currículo desenvolvido para os pré-escolares “Abraçarem” a fé.
Como líder do ministério infantil, você deseja que suas crianças cresçam entendendo que:
Deus as criou. Deus as ama. E Jesus quer ser amigo delas para sempre.
O First Look combina desenvolvimento infantil e teologia para criar um currículo abrangente e uma estratégia para cada fase da vida da criança para influenciar sua fé desde o nascimento até a faculdade.
First Look
O material usado na pré-escola de 0-5 anos (First Look) é desenvolvido para conectar as crianças com Deus de forma simples mas profunda.
Por isso, 3 verdades básicas são sempre apresentadas durante todo o ano:
O Currículo desenvolvido para os pré-escolares “Abraçarem” a fé.
Como líder do ministério infantil, você deseja que suas crianças cresçam entendendo que:
Deus as criou. Deus as ama. E Jesus quer ser amigo delas para sempre.
O First Look combina desenvolvimento infantil e teologia para criar um currículo abrangente e uma estratégia para cada fase da vida da criança para influenciar sua fé desde o nascimento até a faculdade.