Skip to content

Commit

Permalink
fix: review meal
Browse files Browse the repository at this point in the history
  • Loading branch information
Th0rgal committed Dec 13, 2024
1 parent cbb4119 commit 648bbf5
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 129 deletions.
34 changes: 27 additions & 7 deletions components/addmeal/FixBugDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const LongTextInputDialog = ({ visible, onClose, onSubmit }) => {
const [text, setText] = useState("");
const [theme, setTheme] = useState(Appearance.getColorScheme());
const [contentHeight, setContentHeight] = useState(0);
const lineHeight = 20; // Approximate height of one line
const lineHeight = 20;

useEffect(() => {
const subscription = Appearance.addChangeListener(({ colorScheme }) => {
Expand All @@ -15,10 +15,25 @@ const LongTextInputDialog = ({ visible, onClose, onSubmit }) => {
return () => subscription.remove();
}, []);

const isDarkTheme = theme === "dark";
const handleSubmit = () => {
if (!text || !text.trim()) {
console.warn("Feedback text is empty");
return;
}

const handleTextChange = (newText) => {
setText(newText);
const cleanText = text.trim();
console.log("Submitting feedback:", cleanText);

try {
onSubmit(cleanText);
} catch (error) {
console.error("Error submitting feedback:", error);
}
};

const handleTextChange = (newText: string) => {
const sanitizedText = newText.replace(/[\x00-\x1F\x7F-\x9F]/g, "");
setText(sanitizedText);
};

const handleContentSizeChange = (event) => {
Expand All @@ -39,18 +54,23 @@ const LongTextInputDialog = ({ visible, onClose, onSubmit }) => {
<TextInput
style={[
styles.input,
isDarkTheme ? styles.inputDark : styles.inputLight,
theme === "dark" ? styles.inputDark : styles.inputLight,
]}
onChangeText={handleTextChange}
onContentSizeChange={handleContentSizeChange}
value={text}
multiline
numberOfLines={5}
placeholderTextColor={isDarkTheme ? "#ccc" : "#666"}
placeholderTextColor={theme === "dark" ? "#ccc" : "#666"}
placeholder="Please describe the issue..."
/>
</View>
<Dialog.Button label="Cancel" onPress={onClose} />
<Dialog.Button label="Submit" onPress={() => onSubmit(text)} />
<Dialog.Button
label="Submit"
onPress={handleSubmit}
disabled={!text.trim()}
/>
</Dialog.Container>
);
};
Expand Down
253 changes: 132 additions & 121 deletions components/addmeal/ReviewMeal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import React, { useRef, useState } from "react";
import { View, Text, TouchableOpacity, useColorScheme } from "react-native";
import {
View,
Text,
TouchableOpacity,
useColorScheme,
ImageBackground,
} from "react-native";
import BottomSheet, { BottomSheetFlatList } from "@gorhom/bottom-sheet";
import { styles } from "./styles";
import { CustomBackground } from "./BottomSheet/CustomBackground";
Expand All @@ -14,17 +20,13 @@ import { useMealsDatabase } from "../../shared/MealsStorageContext";

const SNAP_POINTS = ["90%"];

const ReviewMeal = ({
imageURI,
mealData,
onUpdate,
onClose,
}: {
imageURI: string;
interface ReviewMealProps {
mealData: StoredMeal;
onUpdate: (data: any) => void;
onUpdate: (updates: Partial<StoredMeal>) => void;
onClose: () => void;
}) => {
}

const ReviewMeal = ({ mealData, onUpdate, onClose }: ReviewMealProps) => {
const bottomSheetRef = useRef<BottomSheet>(null);
const colorScheme = useColorScheme();
const [dialogVisible, setDialogVisible] = useState(false);
Expand All @@ -41,45 +43,46 @@ const ReviewMeal = ({
const handleFeedback = async (feedback: string) => {
try {
const meal_id = mealData.meal_id;
const requestBody = {
meal_id,
feedback,
};
console.log("Sending feedback request:", {
url: "https://api.calorily.com/meals/feedback",
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${jwt.slice(0, 10)}...`, // Log partial JWT for security
},
body: requestBody,
});
console.log("Sending feedback for meal:", meal_id);
console.log("Feedback content:", feedback);

// Optimistically update and close
onUpdate({
status: "analyzing",
last_analysis: null,
});
setDialogVisible(false);
onClose();

// Send request in background
const response = await fetch("https://api.calorily.com/meals/feedback", {
const response = await fetch("https://api.calorily.com/feedback", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${jwt}`,
},
body: JSON.stringify(requestBody),
body: JSON.stringify({
meal_id,
feedback: feedback,
}),
});

if (!response.ok) {
const responseData = await response.json();
throw new Error(responseData.error || "Failed to submit feedback");
const errorData = await response.json();
console.error("Feedback API error:", {
status: response.status,
statusText: response.statusText,
error: errorData,
});
throw new Error(`API error: ${errorData.message || "Unknown error"}`);
}

const data = await response.json();
console.log("Feedback submitted successfully:", data);

setDialogVisible(false);
onUpdate({
status: "analyzing",
error_message: null,
});
} catch (error) {
console.error("Feedback error:", error);
alert(error.message);
console.error("Error submitting feedback:", {
error: error.message,
stack: error.stack,
meal_id: mealData.meal_id,
});
// Optionally show an error message to the user
}
};

Expand All @@ -101,93 +104,101 @@ const ReviewMeal = ({
onClose={onClose}
>
<View style={styles(colorScheme).contentContainer}>
<View style={styles(colorScheme).titleContainer}>
<Text style={styles(colorScheme).resultTitle}>
{mealData.last_analysis?.meal_name || "Unnamed Meal"}
</Text>
<Text style={styles(colorScheme).calories}>
{Math.round(
ingredients.reduce(
(sum, item) => sum + calculateCalories(item),
0
)
)}{" "}
kCal
</Text>
</View>

<View style={styles(colorScheme).macroContainer}>
<View style={styles(colorScheme).macroGroup}>
<View style={styles(colorScheme).macroItem}>
<Ionicons
name="egg"
size={20}
style={styles(colorScheme).macroIcon}
/>
<Text style={styles(colorScheme).macroText}>
{Math.round(
ingredients.reduce((sum, item) => sum + item.proteins, 0)
)}
g
</Text>
</View>

<View style={styles(colorScheme).macroItem}>
<Ionicons
name="pizza"
size={20}
style={styles(colorScheme).macroIcon}
/>
<Text style={styles(colorScheme).macroText}>
{Math.round(
ingredients.reduce((sum, item) => sum + item.fats, 0)
)}
g
</Text>
</View>
<ImageBackground
source={{ uri: mealData.image_uri }}
style={styles(colorScheme).imageBackground}
imageStyle={styles(colorScheme).backgroundImage}
>
<View style={styles(colorScheme).titleContainer}>
<Text style={styles(colorScheme).resultTitle}>
{mealData.last_analysis?.meal_name || "Unnamed Meal"}
</Text>
<Text style={styles(colorScheme).calories}>
{Math.round(
ingredients.reduce(
(sum, item) => sum + calculateCalories(item),
0
)
)}{" "}
kCal
</Text>
</View>

<View style={styles(colorScheme).macroItem}>
<Ionicons
name="ice-cream"
size={20}
style={styles(colorScheme).macroIcon}
/>
<Text style={styles(colorScheme).macroText}>
{Math.round(
ingredients.reduce((sum, item) => sum + item.carbs, 0)
)}
g
</Text>
<View style={styles(colorScheme).macroContainer}>
<View style={styles(colorScheme).macroGroup}>
<View style={styles(colorScheme).macroItem}>
<Ionicons
name="egg"
size={20}
style={styles(colorScheme).macroIcon}
/>
<Text style={styles(colorScheme).macroText}>
{Math.round(
ingredients.reduce((sum, item) => sum + item.proteins, 0)
)}
g
</Text>
</View>

<View style={styles(colorScheme).macroItem}>
<Ionicons
name="pizza"
size={20}
style={styles(colorScheme).macroIcon}
/>
<Text style={styles(colorScheme).macroText}>
{Math.round(
ingredients.reduce((sum, item) => sum + item.fats, 0)
)}
g
</Text>
</View>

<View style={styles(colorScheme).macroItem}>
<Ionicons
name="ice-cream"
size={20}
style={styles(colorScheme).macroIcon}
/>
<Text style={styles(colorScheme).macroText}>
{Math.round(
ingredients.reduce((sum, item) => sum + item.carbs, 0)
)}
g
</Text>
</View>
</View>
</View>
</View>

<BottomSheetFlatList
data={ingredients}
renderItem={({ item, index }) => (
<IngredientItem
item={item}
index={index}
colorScheme={colorScheme}
toggleSelection={() => {}}
/>
)}
keyExtractor={(_item, index) => index.toString()}
/>

<TouchableOpacity
style={styles(colorScheme).secondaryButton}
onPress={() => setDialogVisible(true)}
>
<Text style={styles(colorScheme).secondaryButtonText}>Fix a bug</Text>
</TouchableOpacity>

<TouchableOpacity
style={styles(colorScheme).mainButton}
onPress={() => bottomSheetRef.current?.close()}
>
<Text style={styles(colorScheme).mainButtonText}>Close</Text>
</TouchableOpacity>
<BottomSheetFlatList
data={ingredients}
renderItem={({ item, index }) => (
<IngredientItem
item={item}
index={index}
colorScheme={colorScheme}
toggleSelection={() => {}}
/>
)}
keyExtractor={(_item, index) => index.toString()}
/>

<TouchableOpacity
style={styles(colorScheme).secondaryButton}
onPress={() => setDialogVisible(true)}
>
<Text style={styles(colorScheme).secondaryButtonText}>
Fix a bug
</Text>
</TouchableOpacity>

<TouchableOpacity
style={styles(colorScheme).mainButton}
onPress={() => bottomSheetRef.current?.close()}
>
<Text style={styles(colorScheme).mainButtonText}>Close</Text>
</TouchableOpacity>
</ImageBackground>
</View>

<LongTextInputDialog
Expand Down
8 changes: 8 additions & 0 deletions components/addmeal/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,12 @@ export const styles = (colorScheme: StylesProps["colorScheme"]) =>
opacity: 0.8,
color: colorScheme === "dark" ? "#FFF" : "#000",
},
imageBackground: {
width: "100%",
height: "100%",
justifyContent: "space-between",
},
backgroundImage: {
borderRadius: 10,
},
});
1 change: 0 additions & 1 deletion components/screens/Summary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ const Summary = ({ navigation }) => {

{reviewingMeal && (
<ReviewMeal
imageURI={reviewingMeal.image_uri}
mealData={reviewingMeal}
onUpdate={(updatedData) => {
onMealUpdate(reviewingMeal, updatedData);
Expand Down

0 comments on commit 648bbf5

Please sign in to comment.