Skip to content

Instantly share code, notes, and snippets.

@mjcarnaje
Created May 22, 2024 14:54
Show Gist options
  • Save mjcarnaje/7c5e3fd581fef5688296c9dcafdda4f9 to your computer and use it in GitHub Desktop.
Save mjcarnaje/7c5e3fd581fef5688296c9dcafdda4f9 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Relofair Chat</title>
</head>
<body>
<div id="chat-container"></div>
<script src="https://fengyuanchen.github.io/datepicker/js/datepicker.js" defer></script>
<script src="https://gist.github.com/steffenr/3741573.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
var today = new Date(); // Get today's date
$('[data-toggle="datepicker"]').datepicker({
format: 'dd.mm.yyyy',
autoHide: true, // Added this line to enable auto-hide
startDate: today, // Disable past date
filter: function(date) {
return date.getDay() !== 0; // Disables Sundays
}
});
if (window.innerWidth < 768) {
$('[data-toggle="datepicker"]').attr('readonly', 'readonly');
}
});
document.getElementById('b2c-form').addEventListener("submit", function(e){
e.preventDefault();
var AuszugsortValue = encodeURIComponent(document.getElementById("Auszugsort").value);
var EinzugsortValue = encodeURIComponent(document.getElementById("Einzugsort").value);
var UmzugsdatumValue = encodeURIComponent(document.getElementById("Umzugsdatum").value);
let baseUrl = "https://www.relofair.com/b2c-de/"; // Adjust if necessary
let newUrl = baseUrl + "anfrage-schritt1" + "?Auszugsort=" + AuszugsortValue + "&Einzugsort=" + EinzugsortValue + "&Umzugsdatum=" + UmzugsdatumValue;
window.location.href = newUrl;
});
const speechBubbles = document.querySelectorAll('.speech-bubble');
let currentBubbleIndex = 0;
function typeText(element, text, index) {
if (index < text.length) {
element.textContent += text.charAt(index);
setTimeout(() => {
typeText(element, text, index + 1);
}, 50);
} else {
setTimeout(() => {
element.style.opacity = 0;
setTimeout(() => {
currentBubbleIndex = (currentBubbleIndex + 1) % speechBubbles.length;
showNextBubble();
}, 2000);
}, 2000);
}
}
function showNextBubble() {
if (currentBubbleIndex < speechBubbles.length) {
const bubbleText = speechBubbles[currentBubbleIndex].textContent;
speechBubbles[currentBubbleIndex].textContent = '';
speechBubbles[currentBubbleIndex].style.opacity = 1;
typeText(speechBubbles[currentBubbleIndex], bubbleText, 0);
}
}
showNextBubble();
</script>
<script type="text/javascript">
// Define FormExtension
const FormExtension = {
name: "Forms",
type: "response",
match: ({ trace }) =>
trace.type === "ext_form" || (trace.payload && trace.payload.name === "ext_form"),
render: ({ trace, element }) => {
const formContainer = document.createElement("form");
formContainer.innerHTML = `
<style>
form {
box-sizing: border-box;
width: 310px;
}
label {
font-size: 1em;
color: #333;
margin-bottom: 2px;
display: block;
}
input[type="text"], input[type="email"], input[type="tel"] {
width: 100%;
border: 1px solid #ccc;
border-radius: 5px;
background: #f9f9f9;
margin: 2px 0;
padding: 12px;
outline: none;
transition: border-color 0.3s;
box-sizing: border-box;
}
input[type="text"]:focus, input[type="email"]:focus, input[type="tel"]:focus {
border-color: #2e7ff1;
}
.phone {
width: 100%;
}
.invalid {
border-color: red;
}
.submit {
background: linear-gradient(to right, #2e6ee1, #2e7ff1);
border: none;
color: white;
padding: 10px;
border-radius: 5px;
width: 100%;
cursor: pointer;
font-size: 1em;
transition: background 0.3s;
}
.submit:hover {
background: linear-gradient(to right, #2e7ff1, #2e6ee1);
}
</style>
<label for="name">Name</label>
<input type="text" class="name" name="name" required><br><br>
<label for="email">Email</label>
<input type="email" class="email" name="email" required pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}$" title="Invalid email address"><br><br>
<label for="phone">Phone Number</label>
<input type="tel" class="phone" name="phone" required pattern="\\d+" title="Invalid phone number, please enter only numbers"><br><br>
<input type="submit" class="submit" value="Submit">
`;
formContainer.addEventListener("submit", function (event) {
event.preventDefault();
const name = formContainer.querySelector(".name");
const email = formContainer.querySelector(".email");
const phone = formContainer.querySelector(".phone");
if (
!name.checkValidity() ||
!email.checkValidity() ||
!phone.checkValidity()
) {
name.classList.add("invalid");
email.classList.add("invalid");
phone.classList.add("invalid");
return;
}
formContainer.querySelector(".submit").remove();
window.voiceflow.chat.interact({
type: "complete",
payload: {
name: name.value,
email: email.value,
phone: phone.value,
},
});
});
element.appendChild(formContainer);
},
};
// Define FileUploadExtension
const FileUploadExtension = {
name: "FileUpload",
type: "response",
match: ({ trace }) =>
trace.type === "ext_fileUpload" ||
(trace.payload && trace.payload.name === "ext_fileUpload"),
render: ({ trace, element }) => {
const fileUploadContainer = document.createElement("div");
fileUploadContainer.innerHTML = `
<style>
.my-file-upload {
border: 2px dashed rgba(46, 110, 225, 0.3);
padding: 20px;
text-align: center;
cursor: pointer;
}
</style>
<div class='my-file-upload'>Drag and drop a file here or click to upload</div>
<input type='file' style='display: none;'>
`;
const fileInput =
fileUploadContainer.querySelector("input[type=file]");
const fileUploadBox =
fileUploadContainer.querySelector(".my-file-upload");
fileUploadBox.addEventListener("click", function () {
fileInput.click();
});
fileInput.addEventListener("change", function () {
const file = fileInput.files[0];
console.log("File selected:", file);
fileUploadContainer.innerHTML = `<img src="https://s3.amazonaws.com/com.voiceflow.studio/share/upload/upload.gif" alt="Upload" width="50" height="50">`;
var data = new FormData();
data.append("file", file);
fetch("https://tmpfiles.org/api/v1/upload", {
method: "POST",
body: data,
})
.then((response) => {
if (response.ok) {
return response.json();
} else {
throw new Error("Upload failed: " + response.statusText);
}
})
.then((result) => {
console.log("File uploaded:", result.data.url);
window.voiceflow.chat.interact({
type: "complete",
payload: {
file: result.data.url.replace(
"https://tmpfiles.org/",
"https://tmpfiles.org/dl/",
),
},
});
})
.catch((error) => {
console.error(error);
fileUploadContainer.innerHTML =
"<div>Error during upload</div>";
});
});
element.appendChild(fileUploadContainer);
},
};
(function(d, t) {
var v = d.createElement(t), s = d.getElementsByTagName(t)[0];
v.onload = function() {
window.voiceflow.chat.load({
verify: { projectID: '662679cb65bcc6956845eed1' },
url: 'https://general-runtime.voiceflow.com',
versionID: 'production',
render: {
mode: 'embedded',
target: document.getElementById('chat-container')
},
autostart: false,
allowDangerousHTML: true,
assistant: {
extensions: [
FormExtension,
FileUploadExtension,
],
},
}).then((controller) => {
console.log('Chat widget loaded and opened.');
}).catch((error) => {
console.error('Error loading chat widget:', error);
});
};
v.src = "https://cdn.voiceflow.com/widget/bundle.mjs";
v.type = "text/javascript";
s.parentNode.insertBefore(v, s);
})(document, 'script');
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment