Skip to content

Instantly share code, notes, and snippets.

@jamesdohm
Created December 21, 2023 15:45
Show Gist options
  • Save jamesdohm/b8cb285004cbbd44493162823b7fbb7b to your computer and use it in GitHub Desktop.
Save jamesdohm/b8cb285004cbbd44493162823b7fbb7b to your computer and use it in GitHub Desktop.
Rivo x Skio example code
<html>
<style>
/* Styling for the main container */
.rivo-container {
border: 1px solid #eaeaea;
font-family: var(--font-heading-family);
padding: 40px;
box-shadow: 0 4px 16px rgb(0 0 0 / .1);
margin: 5px;
margin-bottom: 30px;
border-radius: 25px;
}
/* Styling for the button */
button.rivo-redeem-points {
background: #000;
color: #fff;
padding: 10px 15px 10px 15px;
border: 0;
cursor: pointer;
font-weight: 600;
border-radius: 50px;
}
/* Styling for the skeleton placeholder */
.skeleton-placeholder {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 200px;
background-color: #f0f0f0;
border-radius: 8px;
margin: 5px;
}
/* Styling for points container within the main container */
.rivo-points-container {
margin: 10px 20px 20px 0px;
}
/* Styling for links within the points container */
.rivo-points-container a {
font-size: small;
text-decoration: underline !important;
text-decoration-color: black;
}
/* Styling for the rewards list */
#rewards-list {
list-style-type: none;
padding: 0;
max-width: fit-content;
}
/* Styling for each reward item in the list */
.reward-item {
margin-bottom: 10px;
padding: 10px 20px 10px 20px;
background: #eaeaea;
border-radius: 0px;
display: flex;
justify-content: space-between;
align-items: center;
max-width: 550px;
}
/* Styling for text within each reward item */
.reward-item span {
margin-right: 10px;
font-family: avenir next;
font-weight: 500;
letter-spacing: 0px;
width: 180px;
color: #6d7278;
}
/* Styling for the code container in each reward item */
.code-container {
padding: 5px;
display: inline-block;
margin-right: 10px;
width: 180px;
font-weight: bold;
color: black;
font-size: 16px;
font-family: monospace;
text-align: center;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
/* Styling for the copy reward button */
.copy-reward-button {
background-color: #fff;
color: black;
font-size: 12px;
font-family: avenir next;
font-weight: 500 !important;
padding: 10px 15px;
border: 1px solid #eaeaea;
border-radius: 30px;
cursor: pointer;
min-width: 80px;
}
/* Styling for the copy reward button on hover */
.copy-reward-button:hover {
opacity: 80%;
}
/* Styling for the paragraphs */
.points-balance {
font-size: 24px;
font-weight:500 !important;
letter-spacing:0px;
font-family: avenir next;
}
.rivo-points-balance {
font-weight:bold;
}
.rivo-h3 {
font-size: 18px;
font-weight:500 !important;
letter-spacing:0px;
font-family: avenir next;
}
</style>
<!-- Skeleton Placeholder for loading state -->
<div class="skeleton-placeholder" id="skeleton-placeholder">
</div>
<!-- Main container for loyalty program information -->
<div class="rivo-container" id="rivo-container" style="display: none;">
<!-- Points container displaying user's points balance -->
<div class="rivo-points-container">
<h2 class="points-balance">
<span id="prefix">You have </span>
<span class="rivo-points-balance"></span>
<span id="suffix"> points</span>
</h2>
</div>
<!-- Container for available rewards -->
<div class="rivo-rewards-container">
<h3 class="rivo-h3">Available Rewards</h3>
<p id="no-rewards-msg" style="display: none;">You have no rewards available.</p>
<ul id="rewards-list" style="display: none;"></ul>
<a href="/pages/loyalty-program" target="_blank">
<button class="rivo-redeem-points">View my Loyalty profile</button>
</a>
</div>
</div>
<script type="text/javascript">
// JavaScript to handle the loyalty program functionality
// Check if RivoJS is already loaded
if (window.RivoJS) {
initializeLoyaltyProgram();
} else {
// Listen for the RivoJS loaded event
document.addEventListener("rivo-js-loaded", function() {
initializeLoyaltyProgram();
});
}
// Function to initialize the loyalty program
function initializeLoyaltyProgram() {
console.log("RivoJS loaded and ready to use");
// Hide the skeleton and show the main container after a delay
setTimeout(function() {
document.getElementById('skeleton-placeholder').style.display = 'none';
document.getElementById('rivo-container').style.display = 'block';
}, 1000);
// Function to format numbers with commas
function formatNumberWithCommas(number) {
if (!isNaN(number) && number !== null && number !== '') {
return Number(number).toLocaleString();
}
return number;
}
// Function to observe changes in points and update display
function observePointsChanges() {
let pointsSpan = document.querySelector('.rivo-points-balance');
if (pointsSpan) {
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
if (mutation.type === 'childList') {
let currentPoints = pointsSpan.textContent;
pointsSpan.textContent = formatNumberWithCommas(currentPoints);
}
});
});
observer.observe(pointsSpan, { childList: true });
}
}
observePointsChanges();
// Function to update the points display
function updatePointsDisplay(points) {
let pointsSpan = document.querySelector('.rivo-points-balance');
pointsSpan.textContent = formatNumberWithCommas(points);
}
// Fetch customer details and update points display
RivoJS.getCustomerDetails().then(function(resp) {
if (resp && typeof resp.points_tally !== 'undefined') {
updatePointsDisplay(resp.points_tally);
}
}).catch(function(error) {
console.error('Error fetching customer details:', error);
});
// Fetch customer points purchases and display rewards
RivoJS.getCustomerPointsPurchases().then(function(resp) {
const rewards = resp.points_purchases;
const rewardsList = document.getElementById('rewards-list');
const noRewardsMsg = document.getElementById('no-rewards-msg');
if (rewards.length === 0) {
noRewardsMsg.style.display = 'block';
} else {
rewards.forEach(reward => {
const listItem = document.createElement('li');
listItem.classList.add('reward-item');
const nameSpan = document.createElement('span');
nameSpan.textContent = reward.name;
listItem.appendChild(nameSpan);
const codeContainer = document.createElement('div');
codeContainer.classList.add('code-container');
codeContainer.textContent = reward.code;
listItem.appendChild(codeContainer);
const copyButton = document.createElement('button');
copyButton.textContent = 'Copy';
copyButton.classList.add('copy-reward-button');
copyButton.onclick = function() {
navigator.clipboard.writeText(reward.code).then(() => {
// Change the button text to "Copied!" and revert after 2 seconds
copyButton.textContent = 'Copied!';
setTimeout(() => {
copyButton.textContent = 'Copy';
}, 3000);
}, err => {
console.error('Error copying text:', err);
});
};
listItem.appendChild(copyButton);
rewardsList.appendChild(listItem);
});
rewardsList.style.display = 'block';
}
});
}
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment