// USECASE on AI RECIPE GENERATOR
// ===================================================================================================================
// ==== Assignment 2 | Part 2 ========================================================================================
/*
STUDENT NAME: POOJA NAMDEV SALGAR
STUDENT NUMBER: 23267148
STUDENT EMAIL: pooja.salgar2@dcu.mail.ie
MODULE NAME: Foundations of AI (online)
MODULE CODE: CA686I
*/
// ===================================================================================================================
//===============================================================================================================================================================
// MH edit
// moved to top
// Replace these with your actual OpenAI and Image Generation API URLs and keys
// const openaiURL = "https://api.openai.com/v1/engines/text-davinci-003/completions"; // removed - 404 error
const openaiURL = "https://api.openai.com/v1/chat/completions"; // replacement, can use model 'davinci-002' for compatibility
const imageGenerationApiURL = "https://api.openai.com/v1/images/generations";
const apiKey = "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";
// ======================body=======================================================================================================
$('body').css({
"display": "flex",
"margin": "0",
"padding": "0",
"text-align": "center",
// Enable vertical scrolling if content overflows
"overflow-y": "auto",
"background-image": "url('https://ancientbrain.com/uploads/pooja20/DALLE2023-12-0201.37.37-Createadark-themedimageforarecipewebsitebackgroundemphasizingmorefoodattheedgeoftheleftside.Theimageshouldfeatureanabundance.png')", // Set your background image // https://labs.openai.com/
"background-size": "cover", // Cover the entire viewport
"background-repeat": "no-repeat", // Prevent the image from repeating
"background-attachment": "fixed", // Keep the background fixed during scroll
"background-position": "center", // Center the background image
"align-items": "center",
"justify-content": "center",
});
//=================================================================================================================================================================
//Dynamically write HTML content into the document
document.write(`
<nav id="navbar">
<ul>
<li><a href="#contact">Contact</a></li>
<li><a href="#feedback">Feedback</a></li> <!-- Adding Feedback link -->
<li><a href="#home">Home</a></li>
</ul>
</nav>
<div id="contactModal" class="modal" style="display: none;">
<div class="modal-content">
<span class="close" onclick="document.getElementById('contactModal').style.display='none'">×</span>
<h3>Contact Us</h3>
<p>Email: contact@example.com</p>
<p>Phone: 123-456-7890</p>
<!-- More contact details here -->
</div>
</div>
<div id="enterkey" >
<div class="container">
<h2>AI Recipe Generator</h2>
<textarea id="ingredients" placeholder="Enter ingredients, separated by commas (e.g., eggs, flour, sugar) or Dish name"></textarea>
<button onclick="generateRecipe()">Generate Recipe</button>
</div>
<div class="container" id="response-container">
<h2 style="text-align:center">Amazing Recipe!!</h2>
<div id="response"></div>
</div>
<div class="container" id="image-container">
<h2>Generated Image</h2>
<img id="recipe-image" src="" alt="Recipe image will appear here" style="max-width:300px; height:300px;" />
</div>
<div class="container" id="feedback-container">
<h2>Feedback Form</h2>
<form id="feedback-form">
<label for="feedback">Your Feedback:</label>
<textarea id="feedback" placeholder="Please write feedback here"></textarea>
<button type="submit">Submit Feedback</button>
</form>
<div id="feedback-message" style="display:none; color: green; margin-top: 10px;"></div> <!-- Feedback confirmation message -->
</div>
<audio id="background-music" loop>
<source src="https://ancientbrain.com/uploads/pooja20/JustinBieber-YummyLyricseMP3.to.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
<div class="music-controls">
<div class="button-container">
<button id="play-music">►</button> <!-- Play symbol -->
<span>Play Music</span>
</div>
<div class="button-container">
<button id="pause-music">❚❚</button> <!-- Pause symbol -->
<span>Pause Music</span>
</div>
<div class="button-container">
<button id="stop-music">◼</button> <!-- Stop symbol -->
<span>Stop Music</span>
</div>
</div>
`);
//======================================================================================================================================================
// Add CSS styles for containers and input elements===============================================================================
const containerStyle = {
"padding": "20px",
"margin-bottom": "20px",
"border": "1px solid #ee5f5b",
"border-radius": "10px", // Rounded corners
"background-color": "rgba(255, 255, 255, 0.8)", // White with opacity for readability
"width": "80%", // Adjust the width as needed
"max-width": "800px", // Set a maximum width
"box-shadow": "0 4px 8px rgba(0, 0, 0, 0.2)", // Soft shadow for depth
"color": "#333", // Dark text color for contrast
"margin": "20px auto", // Center the container
"text-align": "left" // Align text to the left
};
$(".container").css(containerStyle);
$("h2:contains('AI Recipe Generator')").css({
"color": "#A52A2A",
"animation": "pulse 1s infinite ease-in-out"
});
//==========================================================================================================================================
// Adding keyframes for the pulse animation
$("<style>").prop("type", "text/css").html(`
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.1); }
100% { transform: scale(1); }
}
`).appendTo("head");
//====================================================================================================================================
// jQuery to change color of text to dark blue when user enters text in textarea
$("#ingredients").on('input', function() {
if ($(this).val() !== "") {
$(this).css({"color": "darkblue", "font-weight": "bold"}); // Change text color to dark blue and make it bold
} else {
$(this).css({"color": "black", "font-weight": "normal"}); // Revert back to black and normal weight when textarea is empty
}
});
//=====CSS styles for navbar=======================================================================================================
$("#navbar ul").css({
"list-style-type": "none",
"margin": "0",
"padding": "0",
"overflow": "hidden",
"background-color": "#27496D",
"position": "fixed",
"top": "0",
"width": "100%",
"z-index": "1000"
});
$("#navbar ul").css({
"list-style-type": "none",
"margin": "0",
"padding": "0"
});
$("#navbar ul li").css({
"float": "right" // Right align the navbar items
});
$("#navbar ul li a, .dropbtn").css({
"display": "block",
"color": "white",
"text-align": "right",
"padding": "0px 4px",
"font-size": "14px",
"text-decoration": "none"
});
$(".dropdown").css({
"display": "inline-block"
});
$(".dropdown-content").css({
"display": "none",
"position": "absolute",
"background-color": "#f9f9f9",
"min-width": "160px",
"box-shadow": "0px 8px 16px 0px rgba(0,0,0,0.2)",
"z-index": "1"
});
$(".dropdown-content a").css({
"color": "black",
"padding": "0px 4px",
"text-decoration": "none",
"display": "block",
"text-align": "left"
});
$(".dropdown-content a:hover").css({
"background-color": "#f1f1f1"
});
$(".dropdown:hover .dropdown-content").css({
"display": "block"
});
$(".dropdown:hover .dropbtn").css({
"background-color": "#3e8e41"
});
$("#navbar ul li a:hover:not(.active), .dropdown:hover .dropbtn").css({
"background-color": "#555"
});
$("#navbar ul li a.active").css({
"background-color": "#4CAF50"
});
//=====================================================================================================================================
// CSS styles for modal
$(".modal").css({
"position": "fixed",
"z-index": "1",
"left": "0",
"top": "0",
"width": "100%",
"height": "100%",
"overflow": "auto",
"background-color": "rgba(0,0,0,0.4)" // Black with opacity
});
$(".modal-content").css({
"background-color": "#ADD8E6", // Light blue background color
"margin": "15% auto",
"padding": "20px",
"border": "1px solid #888",
"width": "80%" // Adjust as needed
});
$(".close").css({
"color": "#aaa",
"float": "right",
"font-size": "28px",
"cursor": "pointer"
});
//==========================================================================================================================================================
// CSS styles for input elements=====================
const inputStyle = {
"text-align": "center",
"width":"100%",
"margin": "20px 20px",
"padding": "10px",
"border-radius": "20px",
"border": "none",
"box-shadow": "0 4px 8px rgba(0, 0, 0, 0.2), 0 6px 20px rgba(0, 0, 0, 0.19)"
};
$(".container").css(containerStyle);
$("textarea").css(inputStyle);
$("button").css(inputStyle);
$("#enterkey").css({
"display": "flex",
"flex-direction": "column", // Stack children vertically
"align-items": "center", // Center-align children horizontally
"justify-content": "space-between", // Distribute space between children
"width": "100%",
"max-width": "1000px",
"margin": "0 auto"
});
$("#response-container").css({
"max-height":"80vh",
"overflow-y":"scroll",
})
//=============================================================================================================================
// Style the "Generate Recipe" button
$("button").css({
"width": "50%",
"padding": "10px",
"margin-top": "10px",
"background-color": "#007bff",
"color": "#fff",
"border": "none",
"border-radius": "5px",
"cursor": "pointer"
});
//================================================================================================================================================================
//=====style for Music buttons===================================================================================================================================
$(".music-controls").css({
"position": "fixed",
"top": "0", // Positioned at the top of the page
"left": "-30", // Positioned at the left side of the page
"padding": "10px", // Padding around the controls
"text-align": "center",
"z-index": "10" // Adjusted z-index to prevent overlap
});
$(".music-controls .button-container").css({
"display": "flex", // Use flexbox layout
"align-items": "center", // Vertically center the items
"margin-bottom": "5px" // Margin between each button-container
});
$(".music-controls button").css({
"border-radius": "50%", // Circular shape for buttons
"width": "40px", // Width of the button
"height": "40px", // Height of the button
"padding": "10px", // Padding inside the button
"margin-right": "5px", // Space between the button and text
"display": "inline-block" // Make the button an inline-block element
});
$(".music-controls span").css({
"font-size": "16px", // Font size for the text
"display": "inline-block", // Make the text an inline-block element
"position": "relative", // Position relative to its normal position
"top": "-5",
"font-weight": "bold",
"color": "#FFFFFF"// Move the text 5 pixels up
});
//====================================================================================================================================================
// Add hover effect for the button
$("button").hover(function() {
$(this).css("background-color", "#0056b3");
}, function() {
$(this).css("background-color", "#007bff");
});
//================================================================================================================================================================
// Center align text within containers
$(".container").css("text-align", "center");
$(".container:first").css("margin-top", "30px");
//===============================================================================================================================================================
// Function to generate a recipe===========================================================================================================
function generateRecipe() {
const ingredients = $("#ingredients").val().trim();
if (!ingredients) {
displayError("Please enter some ingredients to continue.");
return;
}
const recipePrompt = `Given these ingredients: ${ingredients}, can you provide a recipe?`;
sendRequestToOpenAI(recipePrompt);
}
//================================================================================================================================================================
// Function to play background music==============================================================================================================================
function playBackgroundMusic() {
var music = document.getElementById("background-music");
music.play();
}
playBackgroundMusic();
// Add event listeners for music control buttons
$(document).ready(function() {
$('#play-music').click(function() {
$('#background-music')[0].play();
});
$('#pause-music').click(function() {
$('#background-music')[0].pause();
});
$('#stop-music').click(function() {
var music = $('#background-music')[0];
music.pause();
music.currentTime = 0;
});
});
//=============================================================================================================================================
//Function to send a request to OpenAI's GPT-3 API
function sendRequestToOpenAI(prompt) {
$("#response").text("Generating recipe... Please wait.");
const data = {
// model: 'davinci-002', // MH edit
prompt: prompt,
max_tokens: 1024,
temperature: 0.7
};
createImageEdit();
$.ajax({
type: "POST",
url: openaiURL,
data: JSON.stringify(data),
headers: {
"Authorization": `Bearer ${apiKey}`,
"Content-Type": "application/json"
},
success: function(response) {
const recipeText = response.choices[0].text.trim();
displayRecipeInSteps(recipeText); // Display the recipe in a step-by-step format
// Trigger image generation with the recipe text
},
error: function(xhr) {
displayError("Failed to generate recipe. Please try again.");
}
});
}
//================================================================================================================================================
//display recipe==============================================================================================================================================
function displayRecipeInSteps(recipeText) {
// Split the recipe text into steps assuming each step is separated by two new lines.
var steps = recipeText.split("\n\n");
// Create a list of steps, each in a new line, ensuring empty steps are not added
var formattedSteps = steps.map(step => `<p>${step.trim()}</p>`).join('');
// Update the response container with the formatted steps
$("#response").html(formattedSteps);
}
//===========================================================================================================================================================
//========function of generate image=========================================================================================================================
async function createImageEdit() {
const imagen=document.getElementById('ingredients').value;
const display_image=document.getElementById('recipe-image');
try {
const imageres = await fetch(imageGenerationApiURL,
// Replace with the actual API endpoint
{
method:'post',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`
},
body:JSON.stringify({
model:'dall-e-2',
prompt:imagen,
n:1,
size: '1024x1024',
})
}
);
const getdata=await imageres.json();
const getimage = getdata.data[0].url;
display_image.src=getimage;
console.log('Edited Image URL:', imageUrl);
} catch (error) {
console.error('Error:', error.message);
}
}
//=============================================================================================================================================================
$(document).ready(function() {
// Prevents default form submission and shows feedback message
$('#feedback-form').on('submit', function(event) {
event.preventDefault();
var feedback = $('#feedback').val();
$('#feedback-message').text('Thank you for your feedback!').show();
$('#feedback').val('');
});
// Change style of text input in the #ingredients textarea
$("#ingredients").on('input', function() {
if ($(this).val() !== "") {
$(this).css({
"color": "darkblue",
"font-weight": "bold",
"font-size": "16px"
});
} else {
$(this).css({
"color": "black",
"font-weight": "normal",
"font-size": "14px"
});
}
});
// Dropdown animation
$(".dropdown").hover(function() {
$(this).find(".dropdown-content").slideDown(200);
}, function() {
$(this).find(".dropdown-content").slideUp(200);
});
// Contact modal display
$("#navbar ul li a[href='#contact']").click(function(event) {
event.preventDefault();
$("#contactModal").css("display", "block");
});
// Change the color of "Amazing Recipe!!" text
$("#response-container h2:contains('Amazing Recipe!!')").css("color", "darkblue");
// Change the color and font-weight of the "Generating recipe..." text
$("#response").css({"color": "black", "font-weight": "bold"});
// Function to display recipe steps in bold black text
function displayRecipeInSteps(recipeText) {
var steps = recipeText.split("\n\n");
var formattedSteps = steps.map(step => `<p style='color: black; font-weight: bold;'>${step.trim()}</p>`).join('');
$("#response").html(formattedSteps);
}
$("#feedback-container h2:contains('Feedback Form')").css({
"color": "green",
"animation": "animateText 1.5s infinite"
});
$("#image-container h2:contains('Generated Image')").css("color", "darkblue");
$("#image-container").css({
"border-radius": "30px"
});
$("#enterkey .container").css({
"display": "flex", // Use flexbox
"flex-direction": "column", // Stack children vertically
"align-items": "center", // Center-align children horizontally
"justify-content": "center", // Center-align children vertically
});
// Style for the textarea
$("#ingredients").css({
"width": "80%", // Adjust the width as needed
"margin": "10px 0", // Add some margin for spacing
});
// Keyframes for the text animation
$("<style>").prop("type", "text/css").html(`
@keyframes animateText {
0% { transform: scale(1); }
50% { transform: scale(1.1); }
100% { transform: scale(1); }
}
`).appendTo("head");
$("#feedback-form label:contains('Your Feedback')").css({
"color": "darkblue"
});
});
//=====================================================================================================================================================s
// Function to display error messages
function displayError(message) {
$("#response-container").html(`<span class="error">${message}</span>`);
}