Skip to content

Instantly share code, notes, and snippets.

@LaurenceLeech
Last active March 1, 2024 12:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LaurenceLeech/2669a3966ce00c3747fe1858199a48a0 to your computer and use it in GitHub Desktop.
Save LaurenceLeech/2669a3966ce00c3747fe1858199a48a0 to your computer and use it in GitHub Desktop.
Rivo x Skio example code
<html>
<style>
:root {
/* Text color for buttons, links, and code containers; contrasts well with light backgrounds */
--primary-dark: #000000;
/* Background color for copy button and text color for dark backgrounds; ensures legibility */
--primary-light: #ffffff;
/* Border color for the main container and buttons; provides a subtle, defining edge */
--border-color: #eaeaea;
/* Background color for skeleton placeholders and reward items; highlights distinct sections */
--background-accent: #f0f0f0;
/* Text color for reward items; softer contrast than primary text color */
--secondary-text: #6d7278;
}
/* Styling for the main container */
.rivo-container {
border: 1px solid var(--border-color);
padding: 40px;
margin: 5px;
margin-bottom: 30px;
border-radius: 25px;
}
/* Styling for the button */
button.rivo-redeem-points {
background: var(--primary-dark);
color: var(--primary-light);
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: var(--background-accent);
border-radius: 8px;
margin: 5px;
}
/* Styling for points container within the main container */
.rivo-points-container {
margin: 10px 20px 20px 0px;
}
/* Styling for the subscription instruction copy */
#subscription-instruction-msg {
font-size: small;
color: var(--primary-dark);
}
/* Styling for links within the points container */
.rivo-points-container a {
font-size: small;
text-decoration: underline !important;
text-decoration-color: var(--primary-dark);
}
/* Styling for the rewards list */
#rewards-list {
list-style-type: none;
padding: 0;
}
/* Styling for each reward item in the list */
.reward-item {
margin-bottom: 10px;
padding: 10px 20px 10px 20px;
background: var(--background-accent);
border-radius: 0px;
display: flex;
justify-content: space-between;
align-items: center;
}
/* 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: var(--secondary-text);
}
/* 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: var(--primary-dark);
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: var(--primary-light);
color: var(--primary-dark);
font-size: 12px;
font-family: avenir next;
font-weight: 500;
padding: 10px 15px;
border: 1px solid var(--border-color);
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;
letter-spacing: 0px;
}
.rivo-points-balance {
font-weight: bold;
}
.rivo-h3 {
font-size: 18px;
font-weight: 500;
letter-spacing: 0px;
}
</style>
<!-- Skeleton Placeholder for loading state -->
<div class="skeleton-loader" 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>
<hr class="SubscriptionDivider-sc-14q967r-0 iJvDbM" style="margin: 15px 0px;">
<!-- 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>
<p id="subscription-instruction-msg" style="display: none;">
Copy your code and apply it to your next subscription.
</p>
<ul id="rewards-list" style="display: none;"></ul>
<hr class="SubscriptionDivider-sc-14q967r-0 iJvDbM" style="margin: 15px 0px;">
<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';
}, 2500);
// Function to format numbers with commas
function formatNumberWithCommas(number) {
if (!isNaN(number) && number !== null && number !== '') {
return Number(number).toLocaleString();
}
return number;
}
// Fetch customer details and update points display or show login message
RivoJS.getCustomerDetails().then(function (resp) {
if (resp && typeof resp.points_tally !== 'undefined') {
let pointsSpan = document.querySelector('.rivo-points-balance');
pointsSpan.textContent = formatNumberWithCommas(resp.points_tally);
} else {
const pointsBalance = document.querySelector('.points-balance');
pointsBalance.style.display = 'none';
pointsBalance.classList.add('hidden');
const loginMessageDiv = document.createElement('div');
loginMessageDiv.innerHTML = 'Log in to your <a href="/account" target="_blank">store account</a> to view your reward details';
loginMessageDiv.classList.add('rivo-login-message'); // Add a class to the new div (replace 'login-message' with your actual class name)
document.querySelector('.rivo-points-container').appendChild(loginMessageDiv);
}
}).catch(function (error) {
console.error('Error fetching customer details:', error);
const pointsBalance = document.querySelector('.points-balance');
pointsBalance.style.display = 'none';
pointsBalance.classList.add('hidden');
const loginMessageDiv = document.createElement('div');
loginMessageDiv.innerHTML = 'Log in to your <a href="/account" target="_blank">store account</a> to view your reward details';
loginMessageDiv.classList.add('rivo-login-message');
document.querySelector('.rivo-points-container').appendChild(loginMessageDiv);
});
// Fetch customer points purchases and display rewards
RivoJS.getCustomerPointsPurchases().then(function (resp) {
console.log(resp);
const rewards = resp.points_purchases;
rewards.sort((a, b) => new Date(b.applied_at) - new Date(a.applied_at));
const recentRewards = rewards.slice(0, 2);
const rewardsList = document.getElementById('rewards-list');
const noRewardsMsg = document.getElementById('no-rewards-msg');
const subscriptionInstructionMsg = document.getElementById('subscription-instruction-msg');
if (recentRewards.length === 0) {
noRewardsMsg.style.display = 'block';
subscriptionInstructionMsg.style.display = 'none';
} else {
recentRewards.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 3 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';
subscriptionInstructionMsg.style.display = 'block';
}
});
}
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment