|
3 | 3 | <head>
|
4 | 4 | <meta charset="utf-8">
|
5 | 5 | <meta name="viewport" content="width=device-width, initial-scale=1">
|
6 |
| - <title>Recipe Generator</title> |
| 6 | + <title>RecipAI - Recipe Generator</title> |
7 | 7 | <link href=" https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel=" stylesheet" integrity=" sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin=" anonymous" >
|
8 | 8 | <script src=" https://cdn.jsdelivr.net/npm/[email protected]/dist/showdown.min.js" ></script>
|
9 | 9 | <link rel="stylesheet" href="styles.css">
|
|
26 | 26 | <body>
|
27 | 27 | <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
28 | 28 | <div class="container">
|
29 |
| - <a class="navbar-brand" href="#">Recipe Generator</a> |
| 29 | + <a class="navbar-brand" href="#">RecipAI - Recipe Generator</a> |
30 | 30 | <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
31 | 31 | <span class="navbar-toggler-icon"></span>
|
32 | 32 | </button>
|
|
44 | 44 | </nav>
|
45 | 45 |
|
46 | 46 | <div class="container my-5">
|
47 |
| - <h1>Recipe Generator</h1> |
48 |
| - <div class="col-lg-8 px-0"> |
49 |
| - <p class="fs-8">Don't know what to do with what's in your shopping cart? Well, click a picture and upload the image to Recipe Generator that will give you interesting ideas of what you can cook from those ingredients! This is built using <a href="https://github.com/gptscript-ai/gptscript" target="_blank">GPTScript</a>.</p> |
50 |
| - </div> |
| 47 | + <h1>RecipAI - Recipe Generator</h1> |
| 48 | + <p class="fs-8">Don't know what to do with what's in your shopping cart? Well, click a picture and upload the image to Recipe Generator that will give you interesting ideas of what you can cook from those ingredients! This is built using <a href="https://github.com/gptscript-ai/gptscript" target="_blank">GPTScript</a>.</p> |
51 | 49 | </div>
|
52 | 50 |
|
53 | 51 | <div class="container my-5">
|
54 | 52 | <div class="mb-3">
|
55 |
| - <form id="uploadForm"> |
| 53 | + <form id="uploadForm" enctype="multipart/form-data"> |
56 | 54 | <div class="input-group">
|
57 |
| - <input type="file" name="file" class="form-control" id="formFile" aria-describedby="inputGroupFileAddon04" aria-label="Upload"> |
58 |
| - <button class="btn btn-outline-secondary" type="button" id="inputGroupFileAddon04" onclick="uploadFile()">Upload File</button> |
59 |
| - </div> |
| 55 | + <input type="file" name="images" class="form-control" id="formFile" aria-describedby="inputGroupFileAddon04" aria-label="Upload" multiple> |
| 56 | + <button class="btn btn-outline-secondary" type="button" id="inputGroupFileAddon04" onclick="uploadFile()">Upload Files</button> |
| 57 | + </div> |
60 | 58 | </form>
|
61 | 59 | </div>
|
62 | 60 | <div id="loader" class="loader"></div>
|
| 61 | + <div id="randomMessage" class="mt-3"></div> <!-- Placeholder for random messages --> |
63 | 62 | <div id="recipeOutput"></div>
|
64 |
| - <script> |
65 |
| - document.addEventListener('DOMContentLoaded', function() { |
66 |
| - // Define uploadFile globally |
67 |
| - window.uploadFile = function() { |
68 |
| - var form = document.getElementById('uploadForm'); |
69 |
| - var formData = new FormData(form); |
70 |
| - var loader = document.getElementById('loader'); |
71 |
| - var recipeOutput = document.getElementById('recipeOutput'); |
72 |
| - loader.style.display = 'block'; // Show the loader |
73 |
| - |
74 |
| - fetch('/upload', { |
75 |
| - method: 'POST', |
76 |
| - body: formData, |
77 |
| - }) |
78 |
| - .then(response => response.json()) // Parse the JSON response |
79 |
| - .then(data => { |
80 |
| - loader.style.display = 'none'; // Hide the loader |
81 |
| - if(data.recipe) { |
82 |
| - var converter = new showdown.Converter() |
83 |
| - var parsedHtml = converter.makeHtml(data.recipe); |
84 |
| - recipeOutput.innerHTML = parsedHtml; // Display the recipe |
85 |
| - } else if (data.error) { |
86 |
| - recipeOutput.innerHTML = `<p>Error: ${data.error}</p>`; |
87 |
| - } |
88 |
| - }) |
89 |
| - .catch(error => { |
90 |
| - console.error('Error:', error); |
91 |
| - loader.style.display = 'none'; |
92 |
| - recipeOutput.innerHTML = `<p>Error: ${error}</p>`; |
93 |
| - }); |
94 |
| - }; |
95 |
| - }); |
96 |
| - </script> |
| 63 | + </div> |
| 64 | + |
| 65 | + <script> |
| 66 | + const randomMessages = [ |
| 67 | + "Hang tight! We're cooking up some suggestions.", |
| 68 | + "Did you know? The world's most expensive pizza costs $12,000!", |
| 69 | + "Cooking tip: Always taste as you go.", |
| 70 | + "A watched pot never boils, but we're fast!", |
| 71 | + "Finding recipes... Maybe it's a good day for pasta?", |
| 72 | + "Good food takes time, but we'll be quick!", |
| 73 | + "Analyzing ingredients... Let's surprise you with something delicious!", |
| 74 | + "Cooking is like love. It should be entered into with abandon or not at all." |
| 75 | + ]; |
| 76 | + |
| 77 | + document.addEventListener('DOMContentLoaded', function() { |
| 78 | + window.uploadFile = function() { |
| 79 | + var form = document.getElementById('uploadForm'); |
| 80 | + var formData = new FormData(form); |
| 81 | + var loader = document.getElementById('loader'); |
| 82 | + var recipeOutput = document.getElementById('recipeOutput'); |
| 83 | + loader.style.display = 'block'; // Show the loader |
| 84 | + |
| 85 | + // Display a random message |
| 86 | + var messageDiv = document.getElementById('randomMessage'); |
| 87 | + messageDiv.innerHTML = randomMessages[Math.floor(Math.random() * randomMessages.length)]; // Display initial random message |
| 88 | + var messageInterval = setInterval(function() { |
| 89 | + messageDiv.innerHTML = randomMessages[Math.floor(Math.random() * randomMessages.length)]; |
| 90 | + }, 5000); // Change message every 5 seconds |
| 91 | + |
| 92 | + |
| 93 | + fetch('/upload', { |
| 94 | + method: 'POST', |
| 95 | + body: formData, |
| 96 | + }) |
| 97 | + .then(response => response.json()) // Parse the JSON response |
| 98 | + .then(data => { |
| 99 | + clearInterval(messageInterval); // Stop changing messages |
| 100 | + loader.style.display = 'none'; // Hide the loader |
| 101 | + if(data.recipe) { |
| 102 | + var converter = new showdown.Converter(); |
| 103 | + var html = converter.makeHtml(data.recipe); |
| 104 | + recipeOutput.innerHTML = html; // Display the converted HTML |
| 105 | + messageDiv.innerHTML = ''; // Clear message |
| 106 | + } else if (data.error) { |
| 107 | + recipeOutput.innerHTML = `<p>Error: ${data.error}</p>`; |
| 108 | + messageDiv.innerHTML = ''; // Clear message |
| 109 | + } |
| 110 | + |
| 111 | + }) |
| 112 | + .catch(error => { |
| 113 | + console.error('Error:', error); |
| 114 | + loader.style.display = 'none'; |
| 115 | + recipeOutput.innerHTML = `<p>Error: ${error}</p>`; |
| 116 | + clearInterval(messageInterval); // Ensure interval is cleared on error |
| 117 | + messageDiv.innerHTML = ''; // Clear message |
| 118 | + }); |
| 119 | + }; |
| 120 | + }); |
| 121 | + </script> |
97 | 122 | </div>
|
98 | 123 |
|
99 | 124 | <script src=" https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity=" sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin=" anonymous" ></script>
|
|
0 commit comments