Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified Backend/__pycache__/sign_in_handler.cpython-312.pyc
Binary file not shown.
Binary file modified Backend/__pycache__/sign_up_handler.cpython-312.pyc
Binary file not shown.
54 changes: 52 additions & 2 deletions Backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,11 @@ async def analyze_image_or_question(

logging.debug(f"Final stripped answer: {answer}")

plant_name = extract_plant_name(answer)

return {
"answer": answer,
"plant_name": "Dummy Example"
"plant_name": plant_name
}

except Exception as e:
Expand Down Expand Up @@ -241,4 +243,52 @@ def extract_plant_name(answer: str) -> str:
# Run the app (for development / debugging only)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
uvicorn.run(app, host="0.0.0.0", port=8000)

@app.post("/check_plant_name")
async def check_plant_name(request: PlantNameRequest):
"""
Check if the recognized plant name exists in the known plants list.
"""
known_plants = [
"Aloe vera",
"Basil",
"Boston fern",
"Calathea",
"Cactus",
"Chili Plant",
"Citrus Plant",
"Dumb Cane (Dieffenbachia)",
"Dragon Tree (Dracaena)",
"Elephant Ear",
"Fern",
"Flamingo Flower",
"Maple",
"Mint",
"Monstera",
"Oak",
"Orchid",
"Parsley",
"Peace Lily",
"Philodendron",
"Pothos",
"Rosemary",
"Rose",
"Snake Plant (Sansevieria)",
"Spider Plant",
"Succulent",
"Sunflower",
"Tomato Plant",
"Tulip",
"Weeping Fig (Ficus Benjamina)",
"ZZ Plant (Zamioculcas Zamiifolia)"
]

# Check if the plant name is in the known plants list (case-insensitive)
plant_name = request.plant_name.strip().lower()

for known_plant in known_plants:
if plant_name == known_plant.lower():
return {"plant_name": known_plant}

return {"plant_name": "Unknown Plant"}
5 changes: 5 additions & 0 deletions Backend/users.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,10 @@
"username": "Klemens",
"email": "klemens@mustermann.de",
"password": "$argon2id$v=19$m=65536,t=3,p=4$MjpB+q+Dux8q4geeYnmBLw$XFAdo4Re3hISCIpyl/EbeKiZWzxZBafT2AnP7I1rH14"
},
{
"username": "Ben",
"email": "ben@mustermann.de",
"password": "$argon2id$v=19$m=65536,t=3,p=4$wtfYMnaSCMhsBqWvnynMzQ$FchOvoK3AGCqlyVoq/naE4DPVNEXg9T2FVY7hQYwHPg"
}
]
56 changes: 56 additions & 0 deletions Frontend/theme/app-calender.html
Original file line number Diff line number Diff line change
Expand Up @@ -259,5 +259,61 @@ <h4 class="modal-title"><strong>Add a category</strong></h4>
<script src="./js/plugins-init/fullcalendar-init.js"></script>

</body>
<script>
$(document).ready(function() {
// Handle checkbox change in to-do list
$('.water-plant-checkbox').on('change', function() {
const eventId = $(this).data('event-id'); // Get associated event ID
const isChecked = $(this).prop('checked'); // Get the checkbox state (checked or not)

// Save the task state in localStorage
localStorage.setItem(eventId, isChecked ? 'checked' : 'unchecked');

// If the task is checked (i.e., completed)
if (isChecked) {
// Remove the corresponding event from the calendar
removeEventFromCalendar(eventId);
}
});

// Function to remove event from calendar
function removeEventFromCalendar(eventId) {
const calendar = $('#calendar').fullCalendar('getCalendar'); // Get FullCalendar instance
const event = calendar.getEventById(eventId); // Get event by its ID

if (event) {
event.remove(); // Remove the event from the calendar
}
}

// Load task states from localStorage and update checkboxes
$('.water-plant-checkbox').each(function() {
const eventId = $(this).data('event-id');
const taskState = localStorage.getItem(eventId);

if (taskState === 'checked') {
$(this).prop('checked', true);
removeEventFromCalendar(eventId);
} else {
$(this).prop('checked', false);
}
});

// Initialize calendar
$('#calendar').fullCalendar({
events: [
{
id: 'event1', // Event ID should match the one in to-do list
title: 'Water - Monstera #1',
start: '2025-01-29T09:00:00', // Example event date
color: '#28a745', // Color of the event
},
],
editable: true,
});
});

</script>


</html>
431 changes: 242 additions & 189 deletions Frontend/theme/dashboard.html

Large diffs are not rendered by default.

130 changes: 89 additions & 41 deletions Frontend/theme/plantid.html
Original file line number Diff line number Diff line change
Expand Up @@ -215,69 +215,117 @@ <h5 class="modal-title">Plant Recognized</h5>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
async function analyzePhoto(input) {
const file = input.files[0]; // Get the uploaded file
<script>
async function analyzePhoto(input) {
const file = input.files[0]; // Get the uploaded file

if (!file) {
alert("Please upload a valid image.");
return;
}
if (!file) {
alert("Please upload a valid image.");
return;
}

// Validate file type
if (!file.type.startsWith('image/')) {
alert("Please upload a valid image file.");
return;
}
// Validate file type
if (!file.type.startsWith('image/')) {
alert("Please upload a valid image file.");
return;
}

// Show loading state (optional)
const modal = new bootstrap.Modal(document.getElementById('inventoryModal'));
document.getElementById("plantMessage").innerText = "Analyzing the image...";
modal.show();

// Prepare the form data
const formData = new FormData();
formData.append("file", file);
formData.append("question", "Identify the plant in the image. Return only the plant name.");

try {
// Call the backend API
const response = await fetch("http://127.0.0.1:8000/analyze", {
method: "POST",
body: formData,
});

// Show loading state (optional)
const modal = new bootstrap.Modal(document.getElementById('inventoryModal'));
document.getElementById("plantMessage").innerText = "Analyzing the image...";
modal.show();
if (!response.ok) {
const errorData = await response.json();
throw new Error(`Error: ${response.statusText} - ${errorData.detail || errorData.message}`);
}

// Prepare the form data
const formData = new FormData();
formData.append("file", file);
formData.append("question", "Identify the plant in the image. Return only the plant name.");
const data = await response.json(); // Parse the response
const plantName = data.plant_name; // Use "plant_name" from the backend

try {
// Call the backend API
const response = await fetch("http://127.0.0.1:8000/analyze", {
if (plantName) {
// Check if the plant name is recognized by calling the backend
const nameCheckResponse = await fetch("http://127.0.0.1:8000/check_plant_name", {
method: "POST",
body: formData,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ plant_name: plantName })
});

if (!response.ok) {
const errorData = await response.json();
throw new Error(`Error: ${response.statusText} - ${errorData.detail || errorData.message}`);
}

const data = await response.json(); // Parse the response
const plantName = data.plant_name; // Use "plant_name" from the backend
if (nameCheckResponse.ok) {
const nameCheckData = await nameCheckResponse.json();
const recognizedPlantName = nameCheckData.plant_name;

if (plantName) {
// Show modal with the plant name
document.getElementById("plantMessage").innerText = `A ${plantName} was recognized. Do you want to add it to your inventory?`;
document.getElementById("plantMessage").innerText = `A ${recognizedPlantName} was recognized. Do you want to add it to your inventory?`;

// Show the modal
modal.show();

// Optionally, handle "Add to Inventory" button click
// Handle "Add to Inventory" button click
document.getElementById("addToInventoryBtn").onclick = function() {
// You can add the code here to save the plant to the user's inventory
console.log(`Added ${plantName} to inventory`);
alert(`${plantName} has been added to your inventory!`);
// Add the recognized plant to the dashboard table
addPlantToTable(recognizedPlantName);
alert(`${recognizedPlantName} has been added to your inventory!`);
modal.hide();
};
} else {
alert("Unable to recognize the plant. Please try again.");
modal.hide();
}
} catch (error) {
console.error("Error during API call:", error);
alert("Something went wrong. Please try again.");
} else {
alert("Unable to recognize the plant. Please try again.");
modal.hide();
}
} catch (error) {
console.error("Error during API call:", error);
alert("Something went wrong. Please try again.");
modal.hide();
}
</script>
}

// Function to add the recognized plant to the table
function addPlantToTable(plantName) {
// Example plant data (You can modify it to add more fields like room, health status, etc.)
const newPlant = {
name: plantName,
plantType: plantName, // This could be customized to show more info (like the genus or category)
room: 'Living Room', // Example room
healthStatus: 'Healthy', // Default health status
lastWatered: '1 day ago' // Example last watered info
};

// Add the plant to the dashboard table
const tableBody = document.querySelector('#plantTable tbody');

// Create a new row
const newRow = document.createElement('tr');

// Fill the row with the plant's data
newRow.innerHTML = `
<td><span class="editable" data-column="name">${newPlant.name}</span></td>
<td><span class="editable" data-column="plant">${newPlant.plantType}</span></td>
<td><span class="editable" data-column="room">${newPlant.room}</span></td>
<td><span class="editable" data-column="health">${newPlant.healthStatus}</span></td>
<td><span class="editable" data-column="lastWatered">${newPlant.lastWatered}</span></td>
<td><button class="edit-btn btn btn-success"><i class="fa fa-edit"></i> Edit</button></td>
`;

// Append the new row to the table
tableBody.appendChild(newRow);
}
</script>

</body>
</html>
29 changes: 22 additions & 7 deletions Frontend/theme/sign-in.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ <h3>Sign in to To Your Account</h3>
<!-- Submit Button -->
<button type="submit" class="btn btn-main-md">Sign In</button>
</form>
<div id="formMessage"></div>
<div class="new-acount">
<a href="contact.html">Forgot your password?</a>
<p>Don't Have an account? <a href="sign-up.html"> SIGN UP</a></p>
Expand Down Expand Up @@ -85,14 +86,21 @@ <h3>Sign in to To Your Account</h3>
document.getElementById('signinForm').addEventListener('submit', function(event) {
event.preventDefault();

const email = document.getElementById('signinEmail').value;
const password = document.getElementById('signinPassword').value;
const email = document.getElementById('signinEmail');
const password = document.getElementById('signinPassword');

const userData = {
email: email,
password: password
email: email.value,
password: password.value
};


// Clear any previous error messages
email.style.borderColor = '';
password.style.borderColor = '';
const errorMessage = document.getElementById('formMessage');
errorMessage.textContent = '';
errorMessage.style.color = ''; // Reset color

// Send the user data to the sign-in handler
fetch('http://localhost:8080/signin', {
method: 'POST',
Expand All @@ -107,13 +115,20 @@ <h3>Sign in to To Your Account</h3>
alert('Login successful!');
window.location.href = 'dashboard.html'; // Redirect to dashboard
} else {
alert('Error: ' + data.message);
// Display error in the input boxes
errorMessage.textContent = data.message;
errorMessage.style.color = 'red';

// Highlight the email and password fields with a red border
email.style.borderColor = 'red';
password.style.borderColor = 'red';
}
})
.catch(error => {
alert('Error: ' + error.message);
});
});
</script>
</script>


</html>