-
-
Save jamesdohm/b8cb285004cbbd44493162823b7fbb7b to your computer and use it in GitHub Desktop.
Rivo x Skio example code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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