@jjlmoya/utils-babies 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +69 -0
- package/src/category/i18n/en.ts +48 -0
- package/src/category/i18n/es.ts +48 -0
- package/src/category/i18n/fr.ts +48 -0
- package/src/category/index.ts +24 -0
- package/src/category/seo.astro +15 -0
- package/src/components/PreviewNavSidebar.astro +116 -0
- package/src/components/PreviewToolbar.astro +143 -0
- package/src/data.ts +30 -0
- package/src/env.d.ts +5 -0
- package/src/index.ts +19 -0
- package/src/layouts/PreviewLayout.astro +117 -0
- package/src/pages/[locale]/[slug].astro +146 -0
- package/src/pages/[locale].astro +251 -0
- package/src/pages/index.astro +4 -0
- package/src/tests/faq_count.test.ts +19 -0
- package/src/tests/locale_completeness.test.ts +42 -0
- package/src/tests/mocks/astro_mock.js +2 -0
- package/src/tests/no_h1_in_components.test.ts +48 -0
- package/src/tests/seo_length.test.ts +23 -0
- package/src/tests/tool_validation.test.ts +17 -0
- package/src/tool/baby-feeding-calculator/bibliography.astro +7 -0
- package/src/tool/baby-feeding-calculator/component.astro +210 -0
- package/src/tool/baby-feeding-calculator/i18n/en.ts +162 -0
- package/src/tool/baby-feeding-calculator/i18n/es.ts +162 -0
- package/src/tool/baby-feeding-calculator/i18n/fr.ts +162 -0
- package/src/tool/baby-feeding-calculator/index.ts +47 -0
- package/src/tool/baby-feeding-calculator/logic.ts +85 -0
- package/src/tool/baby-feeding-calculator/seo.astro +58 -0
- package/src/tool/baby-feeding-calculator/style.css +329 -0
- package/src/tool/baby-percentile-calculator/bibliography.astro +7 -0
- package/src/tool/baby-percentile-calculator/component.astro +388 -0
- package/src/tool/baby-percentile-calculator/i18n/en.ts +244 -0
- package/src/tool/baby-percentile-calculator/i18n/es.ts +244 -0
- package/src/tool/baby-percentile-calculator/i18n/fr.ts +244 -0
- package/src/tool/baby-percentile-calculator/index.ts +54 -0
- package/src/tool/baby-percentile-calculator/lmsData.ts +80 -0
- package/src/tool/baby-percentile-calculator/logic.ts +85 -0
- package/src/tool/baby-percentile-calculator/seo.astro +36 -0
- package/src/tool/baby-percentile-calculator/style.css +393 -0
- package/src/tool/baby-size-converter/bibliography.astro +7 -0
- package/src/tool/baby-size-converter/component.astro +289 -0
- package/src/tool/baby-size-converter/data.json +11 -0
- package/src/tool/baby-size-converter/i18n/en.ts +203 -0
- package/src/tool/baby-size-converter/i18n/es.ts +203 -0
- package/src/tool/baby-size-converter/i18n/fr.ts +203 -0
- package/src/tool/baby-size-converter/index.ts +53 -0
- package/src/tool/baby-size-converter/logic.ts +44 -0
- package/src/tool/baby-size-converter/seo.astro +36 -0
- package/src/tool/baby-size-converter/style.css +394 -0
- package/src/tool/fertile-days-estimator/bibliography.astro +7 -0
- package/src/tool/fertile-days-estimator/component.astro +265 -0
- package/src/tool/fertile-days-estimator/i18n/en.ts +258 -0
- package/src/tool/fertile-days-estimator/i18n/es.ts +262 -0
- package/src/tool/fertile-days-estimator/i18n/fr.ts +258 -0
- package/src/tool/fertile-days-estimator/index.ts +47 -0
- package/src/tool/fertile-days-estimator/logic.ts +58 -0
- package/src/tool/fertile-days-estimator/seo.astro +36 -0
- package/src/tool/fertile-days-estimator/style.css +419 -0
- package/src/tool/pregnancy-calculator/bibliography.astro +7 -0
- package/src/tool/pregnancy-calculator/calculator.ts +41 -0
- package/src/tool/pregnancy-calculator/component.astro +432 -0
- package/src/tool/pregnancy-calculator/i18n/en.ts +315 -0
- package/src/tool/pregnancy-calculator/i18n/es.ts +319 -0
- package/src/tool/pregnancy-calculator/i18n/fr.ts +315 -0
- package/src/tool/pregnancy-calculator/index.ts +55 -0
- package/src/tool/pregnancy-calculator/milestones.ts +153 -0
- package/src/tool/pregnancy-calculator/seo.astro +36 -0
- package/src/tool/pregnancy-calculator/store.ts +60 -0
- package/src/tool/pregnancy-calculator/style.css +807 -0
- package/src/tool/vaccination-calendar/bibliography.astro +7 -0
- package/src/tool/vaccination-calendar/component.astro +286 -0
- package/src/tool/vaccination-calendar/i18n/en.ts +170 -0
- package/src/tool/vaccination-calendar/i18n/es.ts +174 -0
- package/src/tool/vaccination-calendar/i18n/fr.ts +170 -0
- package/src/tool/vaccination-calendar/index.ts +47 -0
- package/src/tool/vaccination-calendar/logic.ts +59 -0
- package/src/tool/vaccination-calendar/seo.astro +36 -0
- package/src/tool/vaccination-calendar/style.css +316 -0
- package/src/tool/vaccination-calendar/vaccinationData.ts +21 -0
- package/src/tools.ts +17 -0
- package/src/types.ts +72 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import type { BabyFeedingCalculatorLocaleContent } from '../index';
|
|
2
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
3
|
+
|
|
4
|
+
const slug = 'calculateur-biberons-bebe';
|
|
5
|
+
const title = 'Calculateur de biberons pour bébé';
|
|
6
|
+
const description = "Calculez la quantité de lait dont votre bébé a besoin selon son poids et son âge. Tétées recommandées, millilitres par tétée et signaux de faim et de satiété.";
|
|
7
|
+
|
|
8
|
+
const faq = [
|
|
9
|
+
{
|
|
10
|
+
question: "De quelle quantité de lait un nouveau-né a-t-il besoin ?",
|
|
11
|
+
answer: "Le premier jour de vie, l'estomac du nouveau-né a la taille d'une cerise et ne nécessite que 5 à 7 ml par tétée. À partir du cinquième jour, la capacité passe à 45–60 ml et les besoins augmentent progressivement.",
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
question: 'À quelle fréquence un bébé doit-il manger ?',
|
|
15
|
+
answer: 'Les nouveau-nés ont besoin de 8 à 12 tétées par jour. À 3 mois, cela se réduit généralement à 7–8 tétées, et à 6 mois à environ 5 tétées par jour.',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
question: 'Comment savoir si mon bébé mange suffisamment ?',
|
|
19
|
+
answer: "Les indicateurs les plus fiables sont : une prise de poids adéquate, au moins 5 à 6 couches mouillées par jour et des signaux de satiété après les tétées.",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
question: "Les quantités sont-elles identiques pour l'allaitement et le lait maternisé ?",
|
|
23
|
+
answer: "Avec l'allaitement, il est recommandé de nourrir à la demande sans mesurer les volumes. Avec le lait maternisé, la référence habituelle est de 150 ml par kg de poids corporel par jour.",
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
const howTo = [
|
|
28
|
+
{
|
|
29
|
+
name: "Sélectionnez l'âge du bébé",
|
|
30
|
+
text: "Choisissez l'unité (jours, semaines ou mois) et ajustez la valeur avec le curseur ou les boutons.",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'Entrez le poids du bébé',
|
|
34
|
+
text: 'Utilisez le curseur de poids ou les boutons pour ajuster le poids actuel du bébé en kilogrammes.',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: "Sélectionnez le type d'alimentation",
|
|
38
|
+
text: 'Choisissez entre sein, mixte ou lait maternisé pour obtenir le guide le plus adapté.',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'Consultez le plan recommandé',
|
|
42
|
+
text: 'La calculatrice affiche le nombre de tétées, les millilitres par tétée et le total journalier estimé.',
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
47
|
+
'@context': 'https://schema.org',
|
|
48
|
+
'@type': 'FAQPage',
|
|
49
|
+
mainEntity: faq.map((item) => ({
|
|
50
|
+
'@type': 'Question',
|
|
51
|
+
name: item.question,
|
|
52
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
53
|
+
})),
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const howToSchema: WithContext<HowTo> = {
|
|
57
|
+
'@context': 'https://schema.org',
|
|
58
|
+
'@type': 'HowTo',
|
|
59
|
+
name: title,
|
|
60
|
+
description,
|
|
61
|
+
step: howTo.map((step) => ({
|
|
62
|
+
'@type': 'HowToStep',
|
|
63
|
+
name: step.name,
|
|
64
|
+
text: step.text,
|
|
65
|
+
})),
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
69
|
+
'@context': 'https://schema.org',
|
|
70
|
+
'@type': 'SoftwareApplication',
|
|
71
|
+
name: title,
|
|
72
|
+
description,
|
|
73
|
+
applicationCategory: 'UtilitiesApplication',
|
|
74
|
+
operatingSystem: 'Web',
|
|
75
|
+
offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
|
|
76
|
+
inLanguage: 'fr',
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export const content: BabyFeedingCalculatorLocaleContent = {
|
|
80
|
+
slug,
|
|
81
|
+
title,
|
|
82
|
+
description,
|
|
83
|
+
ui: {
|
|
84
|
+
labelConfig: 'Paramètres actuels',
|
|
85
|
+
labelPlan: 'Plan recommandé',
|
|
86
|
+
unitDays: 'jours',
|
|
87
|
+
unitWeeks: 'semaines',
|
|
88
|
+
unitMonths: 'mois',
|
|
89
|
+
labelWeight: 'Poids du bébé',
|
|
90
|
+
labelFeedType: "Type d'alimentation",
|
|
91
|
+
feedBreast: 'Sein',
|
|
92
|
+
feedMixed: 'Mixte',
|
|
93
|
+
feedFormula: 'Lait maternisé',
|
|
94
|
+
labelFreeDemand: 'À la demande',
|
|
95
|
+
labelMlPerFeed: 'ml par tétée',
|
|
96
|
+
labelFeedsCount: 'Tétées / 24h',
|
|
97
|
+
labelDailyTotal: 'Total journalier (est.)',
|
|
98
|
+
labelHunger: 'Signaux de faim',
|
|
99
|
+
labelFullness: 'Signaux de satiété',
|
|
100
|
+
faqTitle: 'Questions fréquentes',
|
|
101
|
+
bibliographyTitle: 'Références',
|
|
102
|
+
},
|
|
103
|
+
seo: [
|
|
104
|
+
{ type: 'summary', title: "Résumé : Alimentation du bébé", items: [
|
|
105
|
+
"La capacité gastrique du nouveau-né est de seulement 5 à 7 ml le premier jour.",
|
|
106
|
+
"La référence générale pour le lait maternisé est de 150 ml par kg de poids par jour.",
|
|
107
|
+
"L'allaitement maternel est proposé à la demande sans volumes fixes.",
|
|
108
|
+
"La fréquence des tétées diminue avec l'âge : de 8–12 à 4–5 à 6 mois.",
|
|
109
|
+
]},
|
|
110
|
+
{ type: 'title', text: "De combien de lait mon bébé a-t-il besoin selon son poids et son âge ?", level: 2 },
|
|
111
|
+
{ type: 'paragraph', html: "Les besoins en lait évoluent rapidement au cours des premiers mois. La calculatrice estime la quantité selon le poids actuel et l'âge du bébé, en suivant les recommandations pédiatriques de l'OMS et de l'AAP." },
|
|
112
|
+
{ type: 'stats', columns: 3, items: [
|
|
113
|
+
{ value: '5–7 ml', label: 'Jour 1 (taille cerise)' },
|
|
114
|
+
{ value: '150 ml/kg', label: 'Référence journalière lait maternisé' },
|
|
115
|
+
{ value: '8–12', label: 'Tétées/jour nouveau-né' },
|
|
116
|
+
]},
|
|
117
|
+
{ type: 'title', text: "Taille de l'estomac par âge", level: 3 },
|
|
118
|
+
{ type: 'table', headers: ['Âge', 'Taille réf.', 'Capacité', 'Tétées/jour'], rows: [
|
|
119
|
+
['Jour 1', 'Cerise', '5–7 ml', '8–12'],
|
|
120
|
+
['Jours 2–4', 'Noix', '22–27 ml', '8–12'],
|
|
121
|
+
['Jours 5–30', 'Oeuf', '45–60 ml', '8–10'],
|
|
122
|
+
['1–3 mois', 'Maximale', '90–120 ml', '7–8'],
|
|
123
|
+
['3–6 mois', 'Maximale', '120–150 ml', '5–6'],
|
|
124
|
+
['6+ mois', 'Maximale', '150–180 ml', '4–5'],
|
|
125
|
+
]},
|
|
126
|
+
{ type: 'tip', html: "Un indicateur fiable d'une alimentation adéquate est le nombre de couches mouillées : 5 à 6 par jour à partir du cinquième jour indiquent une bonne hydratation." },
|
|
127
|
+
{ type: 'title', text: "Allaitement maternel vs lait maternisé", level: 3 },
|
|
128
|
+
{ type: 'comparative', columns: 2, items: [
|
|
129
|
+
{ title: "Allaitement maternel", description: "Alimentation naturelle à la demande.", points: ["Pas d'horaire fixe", "Anticorps actifs", "Composition variable", "Difficile à quantifier"] },
|
|
130
|
+
{ title: "Lait maternisé", description: "Tétées programmées avec volume mesurable.", points: ["Toutes les 3–4 heures", "Composition stable", "Facile à contrôler", "Préparation stérile requise"] },
|
|
131
|
+
]},
|
|
132
|
+
{ type: 'list', items: [
|
|
133
|
+
"Prise de poids adéquate : 150–200 g/semaine le premier mois",
|
|
134
|
+
"Au moins 5–6 couches mouillées par jour",
|
|
135
|
+
"Le bébé est calme après les tétées",
|
|
136
|
+
"Urine claire ou jaune très pâle",
|
|
137
|
+
]},
|
|
138
|
+
],
|
|
139
|
+
faqTitle: "Questions fréquentes",
|
|
140
|
+
faq,
|
|
141
|
+
bibliographyTitle: "Références",
|
|
142
|
+
bibliography: [
|
|
143
|
+
{
|
|
144
|
+
name: "OMS - Alimentation du nourrisson et du jeune enfant",
|
|
145
|
+
url: 'https://www.who.int/fr/health-topics/infant-feeding',
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
name: 'La Leche League International',
|
|
149
|
+
url: 'https://www.llli.org',
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: "UNICEF - Allaitement maternel",
|
|
153
|
+
url: 'https://www.unicef.fr/article/lallaitement-maternel',
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: "Société Française de Pédiatrie",
|
|
157
|
+
url: 'https://www.sfpediatrie.com',
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
howTo,
|
|
161
|
+
schemas: [faqSchema as any, howToSchema as any, appSchema],
|
|
162
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { BabiesToolEntry, ToolDefinition, ToolLocaleContent } from '../../types';
|
|
2
|
+
import BabyFeedingCalculatorComponent from './component.astro';
|
|
3
|
+
import BabyFeedingCalculatorSEO from './seo.astro';
|
|
4
|
+
import BabyFeedingCalculatorBibliography from './bibliography.astro';
|
|
5
|
+
|
|
6
|
+
export interface BabyFeedingCalculatorUI {
|
|
7
|
+
[key: string]: string;
|
|
8
|
+
labelConfig: string;
|
|
9
|
+
labelPlan: string;
|
|
10
|
+
unitDays: string;
|
|
11
|
+
unitWeeks: string;
|
|
12
|
+
unitMonths: string;
|
|
13
|
+
labelWeight: string;
|
|
14
|
+
labelFeedType: string;
|
|
15
|
+
feedBreast: string;
|
|
16
|
+
feedMixed: string;
|
|
17
|
+
feedFormula: string;
|
|
18
|
+
labelFreeDemand: string;
|
|
19
|
+
labelMlPerFeed: string;
|
|
20
|
+
labelFeedsCount: string;
|
|
21
|
+
labelDailyTotal: string;
|
|
22
|
+
labelHunger: string;
|
|
23
|
+
labelFullness: string;
|
|
24
|
+
faqTitle: string;
|
|
25
|
+
bibliographyTitle: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type BabyFeedingCalculatorLocaleContent = ToolLocaleContent<BabyFeedingCalculatorUI>;
|
|
29
|
+
|
|
30
|
+
export const babyFeedingCalculator: BabiesToolEntry<BabyFeedingCalculatorUI> = {
|
|
31
|
+
id: 'baby-feeding-calculator',
|
|
32
|
+
icons: { bg: 'mdi:baby-bottle', fg: 'mdi:baby-bottle-outline' },
|
|
33
|
+
i18n: {
|
|
34
|
+
es: () => import('./i18n/es').then((m) => m.content),
|
|
35
|
+
en: () => import('./i18n/en').then((m) => m.content),
|
|
36
|
+
fr: () => import('./i18n/fr').then((m) => m.content),
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export { BabyFeedingCalculatorComponent, BabyFeedingCalculatorSEO, BabyFeedingCalculatorBibliography };
|
|
41
|
+
|
|
42
|
+
export const BABY_FEEDING_CALCULATOR_TOOL: ToolDefinition = {
|
|
43
|
+
entry: babyFeedingCalculator,
|
|
44
|
+
Component: BabyFeedingCalculatorComponent,
|
|
45
|
+
SEOComponent: BabyFeedingCalculatorSEO,
|
|
46
|
+
BibliographyComponent: BabyFeedingCalculatorBibliography,
|
|
47
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export type FeedType = 'breast' | 'mixed' | 'formula';
|
|
2
|
+
export type AgeUnit = 'days' | 'weeks' | 'months';
|
|
3
|
+
|
|
4
|
+
export function toAgeInDays(age: number, unit: AgeUnit): number {
|
|
5
|
+
if (unit === 'weeks') return age * 7;
|
|
6
|
+
if (unit === 'months') return age * 30.44;
|
|
7
|
+
return age;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface FeedingResult {
|
|
11
|
+
numFeeds: number;
|
|
12
|
+
perFeedMin: number;
|
|
13
|
+
perFeedMax: number;
|
|
14
|
+
totalMin: number;
|
|
15
|
+
totalMax: number;
|
|
16
|
+
showAcWarning: boolean;
|
|
17
|
+
scale: number;
|
|
18
|
+
hint: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function getStomachInfo(ageInDays: number): { scale: number; hint: string } {
|
|
22
|
+
if (ageInDays <= 1) return { scale: 0.25, hint: 'Cereza' };
|
|
23
|
+
if (ageInDays <= 4) return { scale: 0.5, hint: 'Nuez' };
|
|
24
|
+
if (ageInDays <= 30) return { scale: 0.8, hint: 'Huevo' };
|
|
25
|
+
return { scale: 1.0, hint: 'Máxima capacidad' };
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function getNumFeeds(ageInDays: number): number {
|
|
29
|
+
if (ageInDays < 30) return 8;
|
|
30
|
+
if (ageInDays < 90) return 7;
|
|
31
|
+
if (ageInDays < 180) return 5;
|
|
32
|
+
return 4;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function getBaseRatio(ageInDays: number): number {
|
|
36
|
+
if (ageInDays > 300) return 80;
|
|
37
|
+
if (ageInDays > 180) return 100;
|
|
38
|
+
return 150;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function applyEarlyAgeFactors(
|
|
42
|
+
totalMin: number,
|
|
43
|
+
totalMax: number,
|
|
44
|
+
ageInDays: number,
|
|
45
|
+
weight: number,
|
|
46
|
+
): [number, number] {
|
|
47
|
+
if (ageInDays >= 10) return [totalMin, totalMax];
|
|
48
|
+
const factor = Math.max(0.15, ageInDays / 10);
|
|
49
|
+
let min = totalMin * factor;
|
|
50
|
+
let max = totalMax * factor;
|
|
51
|
+
if (ageInDays < 2) {
|
|
52
|
+
min = weight * 15;
|
|
53
|
+
max = weight * 25;
|
|
54
|
+
}
|
|
55
|
+
return [min, max];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function applyAcCap(min: number, max: number): [number, number] {
|
|
59
|
+
return [Math.min(min, 800), Math.min(max, 950)];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function calcPerFeed(
|
|
63
|
+
totalMin: number,
|
|
64
|
+
totalMax: number,
|
|
65
|
+
numFeeds: number,
|
|
66
|
+
ageInDays: number,
|
|
67
|
+
): [number, number, number, number] {
|
|
68
|
+
if (ageInDays <= 1) return [5, 10, 5 * numFeeds, 10 * numFeeds];
|
|
69
|
+
const pMin = Math.min(Math.round((totalMin / numFeeds) / 5) * 5, 240);
|
|
70
|
+
const pMax = Math.min(Math.round((totalMax / numFeeds) / 5) * 5, 270);
|
|
71
|
+
return [pMin, pMax, Math.round(totalMin), Math.round(totalMax)];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function calculateFeeding(ageInDays: number, weight: number): FeedingResult {
|
|
75
|
+
const { scale, hint } = getStomachInfo(ageInDays);
|
|
76
|
+
const numFeeds = getNumFeeds(ageInDays);
|
|
77
|
+
const baseRatio = getBaseRatio(ageInDays);
|
|
78
|
+
const showAcWarning = ageInDays >= 180;
|
|
79
|
+
let tMin = weight * baseRatio;
|
|
80
|
+
let tMax = weight * (baseRatio + 20);
|
|
81
|
+
if (showAcWarning) [tMin, tMax] = applyAcCap(tMin, tMax);
|
|
82
|
+
[tMin, tMax] = applyEarlyAgeFactors(tMin, tMax, ageInDays, weight);
|
|
83
|
+
const [perFeedMin, perFeedMax, totalMin, totalMax] = calcPerFeed(tMin, tMax, numFeeds, ageInDays);
|
|
84
|
+
return { numFeeds, perFeedMin, perFeedMax, totalMin, totalMax, showAcWarning, scale, hint };
|
|
85
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
import {
|
|
3
|
+
SEOTitle,
|
|
4
|
+
SEOStats,
|
|
5
|
+
SEOTip,
|
|
6
|
+
SEOTable,
|
|
7
|
+
SEOList,
|
|
8
|
+
SEOSummary,
|
|
9
|
+
SEOComparative,
|
|
10
|
+
SEOGlossary,
|
|
11
|
+
SEOArticle,
|
|
12
|
+
} from '@jjlmoya/utils-shared';
|
|
13
|
+
import { babyFeedingCalculator } from './index';
|
|
14
|
+
import type { KnownLocale } from '../../types';
|
|
15
|
+
|
|
16
|
+
interface Props {
|
|
17
|
+
locale?: KnownLocale;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const { locale = 'es' } = Astro.props;
|
|
21
|
+
const content = await babyFeedingCalculator.i18n[locale]?.();
|
|
22
|
+
if (!content) return null;
|
|
23
|
+
|
|
24
|
+
const { seo } = content;
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
<SEOArticle>
|
|
28
|
+
{seo.map((section: any) => {
|
|
29
|
+
switch (section.type) {
|
|
30
|
+
case 'summary':
|
|
31
|
+
return <SEOSummary title={section.title} items={section.items} />;
|
|
32
|
+
case 'title':
|
|
33
|
+
return <SEOTitle title={section.text} level={section.level || 2} />;
|
|
34
|
+
case 'paragraph':
|
|
35
|
+
return <p set:html={section.html} />;
|
|
36
|
+
case 'stats':
|
|
37
|
+
return <SEOStats stats={section.items} columns={section.columns} />;
|
|
38
|
+
case 'tip':
|
|
39
|
+
return <SEOTip><Fragment set:html={section.html} /></SEOTip>;
|
|
40
|
+
case 'table':
|
|
41
|
+
return (
|
|
42
|
+
<SEOTable headers={section.headers}>
|
|
43
|
+
{section.rows.map((row: string[]) => (
|
|
44
|
+
<tr>{row.map((cell: string) => <td set:html={cell} />)}</tr>
|
|
45
|
+
))}
|
|
46
|
+
</SEOTable>
|
|
47
|
+
);
|
|
48
|
+
case 'list':
|
|
49
|
+
return <SEOList items={section.items} />;
|
|
50
|
+
case 'comparative':
|
|
51
|
+
return <SEOComparative items={section.items} columns={section.columns} />;
|
|
52
|
+
case 'glossary':
|
|
53
|
+
return <SEOGlossary items={section.items} />;
|
|
54
|
+
default:
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
})}
|
|
58
|
+
</SEOArticle>
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
.baby-feeding-calculator {
|
|
2
|
+
--bfc-bg: #fff;
|
|
3
|
+
--bfc-bg-muted: #f8fafc;
|
|
4
|
+
--bfc-bg-alt: #f1f5f9;
|
|
5
|
+
--bfc-text: #0f172a;
|
|
6
|
+
--bfc-text-muted: #334155;
|
|
7
|
+
--bfc-text-dim: #64748b;
|
|
8
|
+
--bfc-border: #e2e8f0;
|
|
9
|
+
--bfc-border-inner: #cbd5e1;
|
|
10
|
+
--bfc-shadow: rgba(0, 0, 0, 0.08);
|
|
11
|
+
--bfc-primary: #0d9488;
|
|
12
|
+
--bfc-primary-on: #fff;
|
|
13
|
+
--bfc-primary-soft: #f0fdfa;
|
|
14
|
+
--bfc-primary-glow: rgba(13, 148, 136, 0.3);
|
|
15
|
+
--bfc-hunger-bg: #fff7ed;
|
|
16
|
+
--bfc-hunger-text: #c2410c;
|
|
17
|
+
--bfc-satiety-bg: #f0fdf4;
|
|
18
|
+
--bfc-satiety-text: #15803d;
|
|
19
|
+
|
|
20
|
+
width: 100%;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.theme-dark .baby-feeding-calculator {
|
|
24
|
+
--bfc-bg: #111827;
|
|
25
|
+
--bfc-bg-muted: #1f2937;
|
|
26
|
+
--bfc-bg-alt: #374151;
|
|
27
|
+
--bfc-text: #f9fafb;
|
|
28
|
+
--bfc-text-muted: #e2e8f0;
|
|
29
|
+
--bfc-text-dim: #94a3b8;
|
|
30
|
+
--bfc-border: #374151;
|
|
31
|
+
--bfc-border-inner: #4b5563;
|
|
32
|
+
--bfc-shadow: rgba(0, 0, 0, 0.3);
|
|
33
|
+
--bfc-primary: #2dd4bf;
|
|
34
|
+
--bfc-primary-on: #fff;
|
|
35
|
+
--bfc-primary-soft: rgba(13, 148, 136, 0.05);
|
|
36
|
+
--bfc-primary-glow: rgba(45, 212, 191, 0.3);
|
|
37
|
+
--bfc-hunger-bg: rgba(194, 65, 12, 0.1);
|
|
38
|
+
--bfc-hunger-text: #fdba74;
|
|
39
|
+
--bfc-satiety-bg: rgba(21, 128, 61, 0.1);
|
|
40
|
+
--bfc-satiety-text: #4ade80;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.baby-feeding-calculator-card {
|
|
44
|
+
background: var(--bfc-bg);
|
|
45
|
+
border: 1px solid var(--bfc-border);
|
|
46
|
+
border-radius: 1rem;
|
|
47
|
+
box-shadow: 0 2px 12px var(--bfc-shadow);
|
|
48
|
+
overflow: hidden;
|
|
49
|
+
width: 100%;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.baby-feeding-calculator-card-main {
|
|
53
|
+
display: grid;
|
|
54
|
+
grid-template-columns: 1fr 1fr;
|
|
55
|
+
gap: 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@media (max-width: 720px) {
|
|
59
|
+
.baby-feeding-calculator-card-main {
|
|
60
|
+
grid-template-columns: 1fr;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.baby-feeding-calculator-card-left {
|
|
65
|
+
padding: 1.5rem;
|
|
66
|
+
border-right: 1px solid var(--bfc-border);
|
|
67
|
+
display: flex;
|
|
68
|
+
flex-direction: column;
|
|
69
|
+
gap: 1.25rem;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@media (max-width: 720px) {
|
|
73
|
+
.baby-feeding-calculator-card-left {
|
|
74
|
+
border-right: none;
|
|
75
|
+
border-bottom: 1px solid var(--bfc-border);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.baby-feeding-calculator-card-right {
|
|
80
|
+
padding: 1.5rem;
|
|
81
|
+
display: flex;
|
|
82
|
+
flex-direction: column;
|
|
83
|
+
gap: 1.25rem;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.baby-feeding-calculator-section-marker {
|
|
87
|
+
font-size: 0.7rem;
|
|
88
|
+
font-weight: 700;
|
|
89
|
+
letter-spacing: 0.1em;
|
|
90
|
+
text-transform: uppercase;
|
|
91
|
+
color: var(--bfc-text-dim);
|
|
92
|
+
padding-bottom: 0.5rem;
|
|
93
|
+
border-bottom: 1px solid var(--bfc-border);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.baby-feeding-calculator-input-group {
|
|
97
|
+
display: flex;
|
|
98
|
+
flex-direction: column;
|
|
99
|
+
gap: 0.5rem;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.baby-feeding-calculator-input-label {
|
|
103
|
+
font-size: 0.8rem;
|
|
104
|
+
font-weight: 600;
|
|
105
|
+
color: var(--bfc-text-muted);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.baby-feeding-calculator-unit-nav {
|
|
109
|
+
display: flex;
|
|
110
|
+
gap: 0.25rem;
|
|
111
|
+
background: var(--bfc-bg-alt);
|
|
112
|
+
border-radius: 0.5rem;
|
|
113
|
+
padding: 0.2rem;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.baby-feeding-calculator-unit-tab {
|
|
117
|
+
flex: 1;
|
|
118
|
+
padding: 0.3rem 0.5rem;
|
|
119
|
+
border: none;
|
|
120
|
+
border-radius: 0.35rem;
|
|
121
|
+
background: transparent;
|
|
122
|
+
color: var(--bfc-text-dim);
|
|
123
|
+
font-size: 0.75rem;
|
|
124
|
+
font-weight: 600;
|
|
125
|
+
cursor: pointer;
|
|
126
|
+
transition: background 0.15s, color 0.15s;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.baby-feeding-calculator-unit-tab.active {
|
|
130
|
+
background: var(--bfc-primary);
|
|
131
|
+
color: var(--bfc-primary-on);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.baby-feeding-calculator-stepper-box {
|
|
135
|
+
display: flex;
|
|
136
|
+
align-items: center;
|
|
137
|
+
gap: 0.5rem;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.baby-feeding-calculator-btn-step {
|
|
141
|
+
width: 2rem;
|
|
142
|
+
height: 2rem;
|
|
143
|
+
border: 1px solid var(--bfc-border-inner);
|
|
144
|
+
border-radius: 0.4rem;
|
|
145
|
+
background: var(--bfc-bg-muted);
|
|
146
|
+
color: var(--bfc-text);
|
|
147
|
+
font-size: 1.1rem;
|
|
148
|
+
cursor: pointer;
|
|
149
|
+
display: flex;
|
|
150
|
+
align-items: center;
|
|
151
|
+
justify-content: center;
|
|
152
|
+
transition: background 0.15s, border-color 0.15s;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.baby-feeding-calculator-btn-step:hover {
|
|
156
|
+
background: var(--bfc-primary-soft);
|
|
157
|
+
border-color: var(--bfc-primary);
|
|
158
|
+
color: var(--bfc-primary);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.baby-feeding-calculator-val-view {
|
|
162
|
+
flex: 1;
|
|
163
|
+
display: flex;
|
|
164
|
+
align-items: baseline;
|
|
165
|
+
justify-content: center;
|
|
166
|
+
gap: 0.3rem;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.baby-feeding-calculator-val-big {
|
|
170
|
+
font-size: 1.5rem;
|
|
171
|
+
font-weight: 700;
|
|
172
|
+
color: var(--bfc-text);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.baby-feeding-calculator-val-sub {
|
|
176
|
+
font-size: 0.75rem;
|
|
177
|
+
color: var(--bfc-text-dim);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.baby-feeding-calculator-slider-line {
|
|
181
|
+
width: 100%;
|
|
182
|
+
accent-color: var(--bfc-primary);
|
|
183
|
+
cursor: pointer;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.baby-feeding-calculator-type-rack {
|
|
187
|
+
display: flex;
|
|
188
|
+
gap: 0.4rem;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.baby-feeding-calculator-type-tile {
|
|
192
|
+
flex: 1;
|
|
193
|
+
padding: 0.45rem 0.5rem;
|
|
194
|
+
border: 1px solid var(--bfc-border-inner);
|
|
195
|
+
border-radius: 0.5rem;
|
|
196
|
+
background: var(--bfc-bg-muted);
|
|
197
|
+
color: var(--bfc-text-muted);
|
|
198
|
+
font-size: 0.78rem;
|
|
199
|
+
font-weight: 600;
|
|
200
|
+
cursor: pointer;
|
|
201
|
+
text-align: center;
|
|
202
|
+
transition: background 0.15s, border-color 0.15s, color 0.15s;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.baby-feeding-calculator-type-tile.active {
|
|
206
|
+
background: var(--bfc-primary-soft);
|
|
207
|
+
border-color: var(--bfc-primary);
|
|
208
|
+
color: var(--bfc-primary);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.baby-feeding-calculator-gauge-area {
|
|
212
|
+
display: flex;
|
|
213
|
+
flex-direction: column;
|
|
214
|
+
align-items: center;
|
|
215
|
+
gap: 0.5rem;
|
|
216
|
+
padding: 1rem 0;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.baby-feeding-calculator-gauge-viz {
|
|
220
|
+
width: 100px;
|
|
221
|
+
height: 100px;
|
|
222
|
+
display: flex;
|
|
223
|
+
align-items: center;
|
|
224
|
+
justify-content: center;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.baby-feeding-calculator-stomach-bubble {
|
|
228
|
+
width: 80px;
|
|
229
|
+
height: 80px;
|
|
230
|
+
border-radius: 50%;
|
|
231
|
+
background: var(--bfc-primary-soft);
|
|
232
|
+
border: 2px solid var(--bfc-primary);
|
|
233
|
+
box-shadow: 0 0 16px var(--bfc-primary-glow);
|
|
234
|
+
display: flex;
|
|
235
|
+
align-items: center;
|
|
236
|
+
justify-content: center;
|
|
237
|
+
transform-origin: center;
|
|
238
|
+
transition: transform 0.4s ease;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.baby-feeding-calculator-visual-hint {
|
|
242
|
+
font-size: 0.65rem;
|
|
243
|
+
font-weight: 700;
|
|
244
|
+
color: var(--bfc-primary);
|
|
245
|
+
text-align: center;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.baby-feeding-calculator-res-card-box {
|
|
249
|
+
background: var(--bfc-bg-muted);
|
|
250
|
+
border: 1px solid var(--bfc-border);
|
|
251
|
+
border-radius: 0.75rem;
|
|
252
|
+
padding: 1rem;
|
|
253
|
+
text-align: center;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.baby-feeding-calculator-res-main-val {
|
|
257
|
+
font-size: 1.25rem;
|
|
258
|
+
font-weight: 700;
|
|
259
|
+
color: var(--bfc-primary);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.baby-feeding-calculator-res-label {
|
|
263
|
+
font-size: 0.72rem;
|
|
264
|
+
font-weight: 600;
|
|
265
|
+
color: var(--bfc-text-dim);
|
|
266
|
+
text-transform: uppercase;
|
|
267
|
+
letter-spacing: 0.05em;
|
|
268
|
+
margin-bottom: 0.25rem;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.baby-feeding-calculator-stats-grid {
|
|
272
|
+
display: grid;
|
|
273
|
+
grid-template-columns: repeat(3, 1fr);
|
|
274
|
+
gap: 0.5rem;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.baby-feeding-calculator-stat-item {
|
|
278
|
+
background: var(--bfc-bg-muted);
|
|
279
|
+
border: 1px solid var(--bfc-border);
|
|
280
|
+
border-radius: 0.6rem;
|
|
281
|
+
padding: 0.75rem 0.5rem;
|
|
282
|
+
text-align: center;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.baby-feeding-calculator-stat-value {
|
|
286
|
+
font-size: 1rem;
|
|
287
|
+
font-weight: 700;
|
|
288
|
+
color: var(--bfc-text);
|
|
289
|
+
margin-bottom: 0.2rem;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.baby-feeding-calculator-stat-label {
|
|
293
|
+
font-size: 0.65rem;
|
|
294
|
+
color: var(--bfc-text-dim);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.baby-feeding-calculator-behavior-sec {
|
|
298
|
+
display: flex;
|
|
299
|
+
flex-direction: column;
|
|
300
|
+
gap: 0.4rem;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.baby-feeding-calculator-pills-container {
|
|
304
|
+
display: flex;
|
|
305
|
+
flex-wrap: wrap;
|
|
306
|
+
gap: 0.35rem;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.baby-feeding-calculator-pill {
|
|
310
|
+
display: inline-block;
|
|
311
|
+
padding: 0.25rem 0.6rem;
|
|
312
|
+
border-radius: 999px;
|
|
313
|
+
font-size: 0.7rem;
|
|
314
|
+
font-weight: 600;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.baby-feeding-calculator-pill-hambre {
|
|
318
|
+
background: var(--bfc-hunger-bg);
|
|
319
|
+
color: var(--bfc-hunger-text);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.baby-feeding-calculator-pill-saciedad {
|
|
323
|
+
background: var(--bfc-satiety-bg);
|
|
324
|
+
color: var(--bfc-satiety-text);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.baby-feeding-calculator-hidden {
|
|
328
|
+
display: none;
|
|
329
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Bibliography as BibliographyUI } from '@jjlmoya/utils-shared';
|
|
3
|
+
import type { BibliographyEntry } from '../../types';
|
|
4
|
+
interface Props { links?: BibliographyEntry[]; title: string; }
|
|
5
|
+
const { links = [], title } = Astro.props;
|
|
6
|
+
---
|
|
7
|
+
<BibliographyUI links={links} title={title} />
|