Skip to content

Commit bbaa42c

Browse files
authored
Merge pull request #32 from jeremyLabrado/feat/multi-image-recipe-generation
feat: Enhance product summary with health goals, religious requirements, and improved UI
2 parents fa8afa7 + 4751d50 commit bbaa42c

File tree

7 files changed

+508
-203
lines changed

7 files changed

+508
-203
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ The output format is a Markdown file to faciliate the display of the recipe on t
223223

224224
- **Challenge**: Present the application in multiple languages
225225

226-
- **Solution**: The same prompt is utilized, but the LLM is instructed to generate the output in a specific language, catering to the user's language preference (English/French).
226+
- **Solution**: The same prompt is utilized, but the LLM is instructed to generate the output in a specific language, catering to the user's language preference (English, French, Spanish, Italian, Arabic). The UI includes comprehensive translations for all features including allergen warnings, ingredient descriptions, and nutritional information.
227227

228228
**Direct Allergen Detection and Nutritional Analysis**
229229

lambda/barcode_product_summary/index.js

Lines changed: 97 additions & 50 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lambda/recipe_step_by_step/index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

resources/ui/src/assets/i18n/all.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ const customTranslations: Record<string, Record<string, string>> = {
3838
ingredients_desc_additive:
3939
"Click on each additive to view AI-generated detailed descriptions",
4040
ingredients_no_additive: "The product does not have additives",
41+
tab_ai_summary: "AI Summary",
42+
tab_ingredients: "Ingredients",
43+
tab_additives: "Additives",
44+
allergen_warning_title: "Allergen Warning",
45+
allergen_warning_message: "This product contains allergens you're sensitive to:",
4146
summary_title: "Summary of ingredients generated by AI",
4247
summary_benefits_title: "Benefits",
4348
summary_disadvantages_title: "Disadvantages",
@@ -128,6 +133,11 @@ const customTranslations: Record<string, Record<string, string>> = {
128133
ingredients_desc_additive:
129134
"Cliquez sur chaque additif pour voir les descriptions détaillées générées par l'IA",
130135
ingredients_no_additive: "Le produit ne contient pas d'additifs",
136+
tab_ai_summary: "Résumé IA",
137+
tab_ingredients: "Ingrédients",
138+
tab_additives: "Additifs",
139+
allergen_warning_title: "Avertissement Allergène",
140+
allergen_warning_message: "Ce produit contient des allergènes auxquels vous êtes sensible :",
131141
summary_title: "Résumé des ingrédients généré par IA",
132142
summary_benefits_title: "Avantages",
133143
summary_disadvantages_title: "Inconvénients",
@@ -218,8 +228,13 @@ const customTranslations: Record<string, Record<string, string>> = {
218228
ingredients_desc_ingredient:
219229
"Fai clic su ogni ingrediente per visualizzare le descrizioni dettagliate generate dall’AI",
220230
ingredients_no_additive: "Il prodotto non contiene additivi",
231+
tab_ai_summary: "Riepilogo IA",
232+
tab_ingredients: "Ingredienti",
233+
tab_additives: "Additivi",
221234
ingredients_desc_additive:
222235
"Fai clic su ogni additivo per visualizzare le descrizioni dettagliate generate dall’AI",
236+
allergen_warning_title: "Avviso Allergeni",
237+
allergen_warning_message: "Questo prodotto contiene allergeni a cui sei sensibile:",
223238
summary_title: "Riepilogo degli ingredienti generato dall’AI",
224239
summary_benefits_title: "Benefici",
225240
summary_disadvantages_title: "Svantaggi",
@@ -311,8 +326,13 @@ const customTranslations: Record<string, Record<string, string>> = {
311326
ingredients_desc_ingredient:
312327
"Haz clic en cada ingrediente para ver descripciones detalladas generadas por IA",
313328
ingredients_no_additive: "El producto no contiene aditivos",
329+
tab_ai_summary: "Resumen IA",
330+
tab_ingredients: "Ingredientes",
331+
tab_additives: "Aditivos",
314332
ingredients_desc_additive:
315333
"Haz clic en cada aditivo para ver descripciones detalladas generadas por IA",
334+
allergen_warning_title: "Advertencia de Alérgenos",
335+
allergen_warning_message: "Este producto contiene alérgenos a los que eres sensible:",
316336
summary_title: "Resumen de ingredientes generados por IA",
317337
summary_benefits_title: "Beneficios",
318338
summary_disadvantages_title: "Desventajas",
@@ -398,6 +418,11 @@ arabic:{
398418
"ingredients_desc_ingredient": "انقر على كل مكون لعرض الوصف التفصيلي الناتج عن الذكاء الاصطناعي",
399419
"ingredients_desc_additive": "انقر على كل إضافة لعرض الوصف التفصيلي الناتج عن الذكاء الاصطناعي",
400420
"ingredients_no_additive": "المنتج لا يحتوي على إضافات",
421+
"tab_ai_summary": "ملخص الذكاء الاصطناعي",
422+
"tab_ingredients": "المكونات",
423+
"tab_additives": "الإضافات",
424+
"allergen_warning_title": "تحذير من مسببات الحساسية",
425+
"allergen_warning_message": "يحتوي هذا المنتج على مسببات حساسية تؤثر عليك:",
401426
"summary_title": "ملخص المكونات الناتجة عن الذكاء الاصطناعي",
402427
"summary_benefits_title": "الفوائد",
403428
"summary_disadvantages_title": "العيوب",

resources/ui/src/pages/components/barcode.tsx

Lines changed: 111 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Button from "@cloudscape-design/components/button";
44
import Ingredients from "./barcode_ingredients";
55
import Badge from "@cloudscape-design/components/badge";
66
import Link from "@cloudscape-design/components/link";
7+
import Alert from "@cloudscape-design/components/alert";
78
import {
89
Box,
910
Container,
@@ -43,10 +44,17 @@ const Barcode: React.FC = () => {
4344
const [productCode, setProductCode] = useState("");
4445
const [showScanner, setShowScanner] = useState(false);
4546
const [tempProductCode, setTempProductCode] = useState("");
47+
const [hasPreferences, setHasPreferences] = useState(false);
4648
const currentTranslations = customTranslations[language]; // Get translations for the current language or fallback to English
4749

4850
let html5QrcodeScanner: any;
4951

52+
// Check if user has set preferences
53+
useEffect(() => {
54+
const stored = localStorage.getItem("userPreferences");
55+
setHasPreferences(!!stored);
56+
}, []);
57+
5058
function onScanFailure(error: unknown) {
5159
console.warn(`Code scan error = ${error}`);
5260
}
@@ -122,7 +130,11 @@ const Barcode: React.FC = () => {
122130
>
123131
<div style={{ textAlign: "center" }}>
124132
{!showScanner && (
125-
<Button variant="primary" onClick={handleButtonClick}>
133+
<Button
134+
variant="primary"
135+
onClick={handleButtonClick}
136+
iconName="search"
137+
>
126138
{currentTranslations["scan_button_label"]}
127139
</Button>
128140
)}
@@ -153,27 +165,106 @@ const Barcode: React.FC = () => {
153165
</div>
154166

155167
{!showScanner && (
156-
<Box>
157-
<div style={{ textAlign: "left" }}>
158-
<h4>{currentTranslations["scan_main_title"]}</h4>
159-
160-
<SpaceBetween direction="vertical" size="m">
161-
<div>
162-
<p>
163-
<Badge color="green">1</Badge>{" "}
164-
{currentTranslations["scan_label_1"]}{" "}
165-
<Link href="/preference">
166-
{currentTranslations["scan_label_2"]}
167-
</Link>
168-
</p>
169-
<p>
170-
<Badge color="green">2</Badge>{" "}
171-
{currentTranslations["scan_label_3"]}
172-
</p>
168+
<div style={{
169+
background: "white",
170+
borderRadius: "8px",
171+
padding: "20px",
172+
border: "1px solid #e5e7eb",
173+
boxShadow: "0 1px 3px rgba(0,0,0,0.1)"
174+
}}>
175+
{!hasPreferences && (
176+
<Alert
177+
type="warning"
178+
header="Set your preferences first"
179+
>
180+
To get personalized nutritional information, please{" "}
181+
<Link href="/preference">set your preferences</Link> before scanning.
182+
</Alert>
183+
)}
184+
185+
<div style={{
186+
textAlign: "center",
187+
margin: hasPreferences ? "0 0 24px 0" : "16px 0 24px 0"
188+
}}>
189+
<div style={{
190+
fontSize: "48px",
191+
marginBottom: "8px",
192+
opacity: 0.8
193+
}}>
194+
📱
195+
</div>
196+
<h3 style={{
197+
margin: "0 0 8px 0",
198+
fontSize: "18px",
199+
fontWeight: "600",
200+
color: "#1f2937"
201+
}}>
202+
{currentTranslations["scan_main_title"]}
203+
</h3>
204+
<p style={{
205+
margin: 0,
206+
fontSize: "14px",
207+
color: "#6b7280"
208+
}}>
209+
Point your camera at a product barcode
210+
</p>
211+
</div>
212+
213+
<div style={{ display: "flex", flexDirection: "column", gap: "12px" }}>
214+
<div style={{
215+
display: "flex",
216+
alignItems: "center",
217+
gap: "12px"
218+
}}>
219+
<div style={{
220+
background: "#3b82f6",
221+
color: "white",
222+
width: "24px",
223+
height: "24px",
224+
borderRadius: "50%",
225+
display: "flex",
226+
alignItems: "center",
227+
justifyContent: "center",
228+
fontWeight: "600",
229+
fontSize: "14px",
230+
flexShrink: 0
231+
}}>
232+
1
233+
</div>
234+
<span style={{ fontSize: "15px", lineHeight: "1.5", color: "#374151" }}>
235+
{currentTranslations["scan_label_1"]}{" "}
236+
<Link href="/preference">
237+
{currentTranslations["scan_label_2"]}
238+
</Link>
239+
</span>
240+
</div>
241+
242+
<div style={{
243+
display: "flex",
244+
alignItems: "center",
245+
gap: "12px"
246+
}}>
247+
<div style={{
248+
background: "#3b82f6",
249+
color: "white",
250+
width: "24px",
251+
height: "24px",
252+
borderRadius: "50%",
253+
display: "flex",
254+
alignItems: "center",
255+
justifyContent: "center",
256+
fontWeight: "600",
257+
fontSize: "14px",
258+
flexShrink: 0
259+
}}>
260+
2
173261
</div>
174-
</SpaceBetween>
262+
<span style={{ fontSize: "15px", lineHeight: "1.5", color: "#374151" }}>
263+
{currentTranslations["scan_label_3"]}
264+
</span>
265+
</div>
175266
</div>
176-
</Box>
267+
</div>
177268
)}
178269
<div id="reader"></div>
179270

0 commit comments

Comments
 (0)