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 added .DS_Store
Binary file not shown.
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
# Project Name
# Project chatbot

Replace this readme with your own information about your project.

Start by briefly describing the assignment in a sentence or two. Keep it short and to the point.
My task was to develop an interactive chatbot in JavaScript where the user can communicate with the bot by entering their name and responding to various questions. I was to build upon the existing code by handling user inputs, controlling the flow of the conversation, and adding new features and effects such as conditional statements, different input types, and potentially sound.

## The problem

Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next?
To approach the problem, I started by carefully reading through the existing code (and watched Jennie's video) to understand how the chatbot was structured and which functions were already in place. I identified the key areas where I needed to add new functionality, such as handling user input, managing the conversation flow, and dynamically updating the content on the page.

I used JavaScript, HTML, and CSS as the main technologies for this project. I utilized JavaScript to handle user interactions, create functions for different conversation stages, and control the timing of messages using setTimeout. In addition, I employed CSS to style the chat interface and make it visually appealing, and HTML to structure the content on the page.

For planning, I outlined the conversation flow and identified key questions and answers to include. I then broke down the development into smaller tasks, such as creating event listeners for user inputs, implementing functions to handle specific stages of the conversation, and testing each step to ensure it worked correctly.

If I had more time, I would further enhance the chatbot by adding more diverse response types, such as drop-down menus or clickable options, implementing additional sound effects, and optimizing the code to make it more scalable and efficient.

## View it live

Have you deployed your project somewhere? Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about.
https://cookiebot-lifeisbetterwithcookies.netlify.app/
Binary file added code/.DS_Store
Binary file not shown.
Binary file added code/assets/.DS_Store
Binary file not shown.
Binary file added code/assets/Userpic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added code/assets/botpic1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added code/assets/botpic2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added code/assets/chatsound.wav
Binary file not shown.
Binary file added code/assets/cookiemonster2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added code/assets/cookiemonster3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added code/assets/userlogomonster.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 45 additions & 16 deletions code/index.html
Original file line number Diff line number Diff line change
@@ -1,32 +1,61 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./style.css" />
<link
href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"
rel="stylesheet" />
<title>Chatbot</title>
</head>

<body>
<h1>Welcome to my chatbot!</h1>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./style.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<link
href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"
rel="stylesheet" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Gloria+Hallelujah&display=swap" rel="stylesheet">
<title>Cookiebot</title>
</head>

<!-- Chat sound -->
<audio id="chatSound" src="assets/chatsound.wav" preload="auto"></audio>

<body>
<div class="welcome-container">

<!-- Brand and picture -->
<div class="cookie-message">
<h1>Life is better with cookies!</h1>
<div class="image-container">
<img src="assets/cookiemonster3.png" alt="Cookie monster" class="monster-picture">
<img src="assets/cookiemonster2.png" alt="Cookie monster" class="monster-picture2">
</div>
</div>

<!-- Chat -->
<main>
<section class="chat" id="chat"></section>
<div class="input-wrapper" id="input-wrapper">
<form id="name-form">
<label for="name-input">Name</label>
<input id="name-input" type="text" />
<button class="send-btn" type="submit">
Send
</button>
</form>
</div>
</main>
</div>

<!-- personal info -->
<footer>
<div class="personal-info-items">
<h4><i class="fa-brands fa-github"></i> EmelieNyberg</h4>
<h4><i class="fa-brands fa-linkedin"></i> Emelie Nyberg Kedert</h4>
<h4>© 2024 Copyright - Developed by Emelie Nyberg Kedert</h4>
</div>
</footer>

<!-- JavaScript -->
<script src="./script.js"></script>

<script src="./script.js"></script>
</body>
</body>

</html>
</html>
194 changes: 161 additions & 33 deletions code/script.js
Original file line number Diff line number Diff line change
@@ -1,53 +1,181 @@
// DOM selectors (variables that point to selected DOM elements) goes here 👇
const chat = document.getElementById('chat')
// DOM selectors

// Functions goes here 👇
const chat = document.getElementById('chat');
const nameInput = document.getElementById('name-input');
const form = document.getElementById('name-form');
const chatSound = document.getElementById('chatSound');

// A function that will add a chat bubble in the correct place based on who the sender is
// Functions

// Welcome the user back again
const goodbyeMessage = (choice) => {
if (choice === 'Yes') { // If yes, message that order is prepaired
showMessage(`Your order will be prepaired. Thank you for using the Cookiebot! 🍪`, 'bot');
} else { // If no, massage that the order is canceled
showMessage(`No order has been placed. Hope we meet again soon!`, 'bot')
}
};

// User bubble show confirmation choice
const handleConfirmationChoice = (choice) => {
showMessage(`${choice}`, 'user');
document.getElementById('buttonContainer').style.display = 'none'; // Hide buttons
setTimeout(() => goodbyeMessage(choice), 1000);
};

// Confirmation buttons
const createConfirmationButtons = () => {
form.style.display = 'none'; // Hide form
form.innerHTML = `
<div class="button-container" id="buttonContainer">
<button type="button" id="yesButton" class="button-class">Yes</button>
<button type="button" id="noButton" class="button-class">No</button>
</div>
`;
form.style.display = 'block'; // Show buttons

// DOM, Event listeners and invoking yes or no buttons
document.getElementById('yesButton').addEventListener('click', () => handleConfirmationChoice('Yes'));
document.getElementById('noButton').addEventListener('click', () => handleConfirmationChoice('No'));
};

// Ask for order confirmation
// Also printing out correct price depending on drink or not
const askForOrderConfirmation = (choice) => {
let totalPrice = '';
if (choice === 'Milk' || choice === 'Coffee') {
totalPrice = '$10';
} else {
totalPrice = '$5';
}
showMessage(`Wonderful! The total price will be ${totalPrice}, are you sure you'd like to place the order?`, 'bot')
createConfirmationButtons();
};

// User bubble show drink choice and passes the choice to next function
const handleDrinkChoice = (choice) => {
showMessage(`${choice} please`, 'user');
document.getElementById('buttonContainer').style.display = 'none'; // Hide buttons
setTimeout(() => askForOrderConfirmation(choice), 1000);
};

// Drink buttons
const createDrinkButtons = () => {
form.style.display = 'none'; // Hide form
form.innerHTML = `
<div class="button-container" id="buttonContainer">
<button type="button" id="milk" class="button-class">🥛 Milk</button>
<button type="button" id="coffee" class="button-class">☕️ Coffee</button>
<button type="button" id="noDrink" class="button-class">No drink</button>
</div>
`;
form.style.display = 'block'; // Show buttons

// DOM, Event listeners and Invoking each drink button
document.getElementById('milk').addEventListener('click', () => handleDrinkChoice('Milk'));
document.getElementById('coffee').addEventListener('click', () => handleDrinkChoice('Coffee'));
document.getElementById('noDrink').addEventListener('click', () => handleDrinkChoice('No drink'));
};

// Asking for drink
const askForDrinkChoice = (choice) => {
showMessage(`Mmm ${choice}, great choice, would you like a drink?`, 'bot')
createDrinkButtons();
};

// User bubble show cookie choice and passes the choice to next function
const handleCookieChoice = (choice) => {
showMessage(`I choose ${choice}!`, 'user');
document.getElementById('buttonContainer').style.display = 'none'; // Hide buttons
setTimeout(() => askForDrinkChoice(choice), 1000);
};

// Cookie buttons
const createCookieButtons = () => {
form.style.display = 'none'; // hide form
form.innerHTML = `
<div class="button-container" id="buttonContainer">
<button type="button" id="darkChocolate" class="button-class">🍪 Dark chocolate</button>
<button type="button" id="milkChocolate" class="button-class">🍪 Milk chocolate</button>
<button type="button" id="nutsChocolate" class="button-class">🍪 Nuts and white chocolate</button>
</div>
`;
form.style.display = 'block'; // show buttons

// Here I:
// 1.Select DOMs,
// 2.Add Event listeners
// 3.Invoking handleCookieChoice function + passes the cookie choice
document.getElementById('darkChocolate').addEventListener('click', () => handleCookieChoice('Dark chocolate'));
document.getElementById('milkChocolate').addEventListener('click', () => handleCookieChoice('Milk chocolate'));
document.getElementById('nutsChocolate').addEventListener('click', () => handleCookieChoice('Nuts and white chocolate'));
};

// Asking for what kind of cookie
const askForCookieChoice = (name) => {
showMessage(`Welcome ${name}! What kind of cookie would you like to order?`, 'bot');
createCookieButtons();
};

// Handeling the name input, if the user types nothing in the field
//the bot will ask again for name
// If the user print in a name, the program continues
const handleNameInput = (event) => {
event.preventDefault();
const name = nameInput.value.trim(); // Trim is getting rid of spaces
if (name === '') {
showMessage(name, 'user');
setTimeout(() => { // Using setTimeout to delay the bot message
showMessage(`Please type in your name...`, 'bot');
form.addEventListener('submit', handleNameInput); // Invoking the function again
}, 1000);
} else {
showMessage(name, 'user');
nameInput.value = ''; // Empty textfield
setTimeout(() => askForCookieChoice(name), 1000); // Continue with the next question
}
};

// Event listener for the form
form.addEventListener('submit', handleNameInput);

// Funcion that shows diffrent chat bubbles depending on 'user' or 'bot'
const showMessage = (message, sender) => {
// The if statement checks if the sender is the user and if that's the case it inserts
// an HTML section inside the chat with the posted message from the user
if (sender === 'user') {
chat.innerHTML += `
<section class="user-msg">
<div class="bubble user-bubble">
<p>${message}</p>
</div>
<img src="assets/user.png" alt="User" />
<img src="assets/userlogomonster.png" alt="User" />
</section>
`
// The else if statement checks if the sender is the bot and if that's the case it inserts
// an HTML section inside the chat with the posted message from the bot
`;
} else if (sender === 'bot') {
chat.innerHTML += `
<section class="bot-msg">
<img src="assets/bot.png" alt="Bot" />
<img src="assets/botpic2.png" alt="Bot" />
<div class="bubble bot-bubble">
<p>${message}</p>
</div>
</section>
`
`;
}
// Chat sound every time showMessage is used
if (chatSound) {
chatSound.currentTime = 0; // to be able to also have chat sound on bot
chatSound.play().catch(error => {
console.error("Your browser do not support the video tag", error);
});
}
setTimeout(() => {
chat.scrollTop = chat.scrollHeight;
}, 10);
};

// This little thing makes the chat scroll to the last message when there are too many to
// be shown in the chat box
chat.scrollTop = chat.scrollHeight
}

// A function to start the conversation
// Greeting message
const greetUser = () => {
// Here we call the function showMessage, that we declared earlier with the argument:
// "Hello there, what's your name?" for message, and the argument "bot" for sender
showMessage("Hello there, what's your name?", 'bot')
// Just to check it out, change 'bot' to 'user' here 👆 and see what happens
}

// Eventlisteners goes here 👇

// Here we invoke the first function to get the chatbot to ask the first question when
// the website is loaded. Normally we invoke functions like this: greeting()
// To add a little delay to it, we can wrap it in a setTimeout (a built in JavaScript function):
// and pass along two arguments:
// 1.) the function we want to delay, and 2.) the delay in milliseconds
// This means the greeting function will be called one second after the website is loaded.
setTimeout(greetUser, 1000)
showMessage(`Hello! I'm the Cookiebot, what's your name?`, 'bot');
};

// Start by greeting the user Welcome!
setTimeout(greetUser, 1000);
Loading