-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Darragh Curran
committed
May 10, 2024
1 parent
7ad914c
commit 829c2c7
Showing
5 changed files
with
225 additions
and
1 deletion.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
|
||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<link rel="stylesheet" href="roi.css"> | ||
<title>Understanding the transformative impact of AI-first customer service on your business</title> | ||
</head> | ||
<body> | ||
<p>Fin Agent will instantly answer 30 ⇛ 80% of your customer questions so that your team don't have to.</p> | ||
<div style="padding-top: 1em; text-align: justify"> | ||
Assuming your team handles | ||
<span class="compositeSlider"> | ||
<input type="range" id="conversationVolumeSlider" min="100" max="100000" value="10000" class="slider"/> | ||
<span class="compositeSliderValue">10000</span> <label for="conversationVolumeSlider">conversations a month</label> | ||
</span> | ||
with a | ||
|
||
<span class="compositeSlider"> | ||
<input type="range" id="supportTeamSizeSlider" min="1" max="1000" value="20" class="slider"/> | ||
<label for="supportTeamSizeSlider">support team size</label> of <span class="compositeSliderValue">20</span> | ||
</span> | ||
with an average | ||
<span class="compositeSlider"> | ||
<input type="range" id="averageMonthlyCostPerEmployeeSlider" min="1000" max="7000" value="4000" class="slider"/> | ||
<label for="averageMonthlyCostPerEmployeeSlider">monthly cost</label> of $<span class="compositeSliderValue">4000</span> | ||
</span> | ||
per team member... | ||
|
||
<p><strong>Then.... </strong> with a <span class="compositeSlider"> | ||
<input type="range" id="resolutionRateSlider" min="20" max="100" value="40" class="slider"/> | ||
<label for="resolutionRateSlider">resolution rate of </label><span class="compositeSliderValue">40</span>% | ||
</span></p> | ||
<p id="roi-output"></p> | ||
<p id="roi-explanation" style="font-size: 50%; color: grey;"></p> | ||
</div> | ||
<script src="roi.js"></script> | ||
</body> | ||
</html> |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
body { | ||
font-family: Arial, sans-serif; | ||
font-size: 2em; | ||
line-height: 2em; | ||
margin: 0; | ||
padding: 20px; | ||
background: #f0f0f0; | ||
} | ||
|
||
.calculator { | ||
margin: 20px; | ||
background: white; | ||
box-shadow: 0 4px 8px rgba(0,0,0,0.1); | ||
} | ||
|
||
.top-row { | ||
display: flex; | ||
} | ||
|
||
.left-panel, .right-panel { | ||
padding: 20px; | ||
border: 1px solid #ccc; | ||
} | ||
|
||
.left-panel { | ||
width: 30%; | ||
border-right: none; /* seamless between panels */ | ||
} | ||
|
||
.right-panel { | ||
width: 70%; | ||
text-align: center; | ||
} | ||
|
||
.assumptions-row { | ||
padding: 20px; | ||
border: 1px solid #ccc; | ||
border-top: none; /* seamless between sections */ | ||
display: flex; /* Align child elements horizontally */ | ||
justify-content: space-around; /* Distribute space around items */ | ||
} | ||
|
||
.compositeSlider { | ||
position:relative; | ||
font-weight: bold; | ||
white-space: nowrap; | ||
} | ||
|
||
.compositeSlider input { | ||
position: absolute; | ||
top: -1.5em; | ||
left: 50%; | ||
transform: translateX(-50%); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
|
||
document.querySelectorAll('input, select').forEach(input => { | ||
input.addEventListener('change', calculate); | ||
}); | ||
|
||
function calculate() { | ||
const conversations = parseInt(document.getElementById('conversationVolumeSlider').value, 10); | ||
const teamSize = parseInt(document.getElementById('supportTeamSizeSlider').value, 10); | ||
const resolutionRate = parseFloat(document.getElementById('resolutionRateSlider').value); | ||
// const involvementRate = parseFloat(document.getElementById('involvementSlider').value); | ||
const involvementRate = 100; | ||
const costPerEmployeeMonth = parseFloat(document.getElementById('averageMonthlyCostPerEmployeeSlider').value); | ||
const ratioOfFinConversationTimeVsHuman = 0.25; //todo - derive that from team size vs volume... | ||
const costPerResolution = 0.99; | ||
|
||
const resolvedConversations = conversations * (resolutionRate/100.0) * (involvementRate/100.0); | ||
let monthlyPerAgent = conversations / teamSize | ||
let hoursPerConversation = (40 * 4) / monthlyPerAgent ; | ||
const timeSavings = resolvedConversations * (hoursPerConversation * ratioOfFinConversationTimeVsHuman); // assuming 0.5 hours saved per resolution | ||
let personMonthsSaved = timeSavings / (40 * 4); | ||
const costSavings = costPerEmployeeMonth * personMonthsSaved; | ||
let finCosts = resolvedConversations * costPerResolution; | ||
// let roiDollars = costSavings-finCosts; | ||
|
||
// document.getElementById('impactMessage').textContent = ` | ||
// You currently spend approximately $${teamSize * costPerEmployeeMonth} on support salaries. | ||
// Each team member handles approximately ${(conversations / teamSize).toFixed(0)} conversations per month. | ||
// | ||
// Fin will resolve approximately ${resolvedConversations.toFixed(0)} conversations per month. | ||
// | ||
// We estimate that will save you ${timeSavings.toFixed(1)} hours | ||
// which avoids spending $${costSavings.toFixed(2)} on staffing costs, | ||
// assuming it takes on average ${ratioOfFinConversationTimeVsHuman.toFixed(2)} hours to handle each. | ||
// | ||
// TOTAL ROI $${roiDollars.toFixed(0)} | ||
// `; | ||
document.getElementById('roi-output').textContent = ` | ||
You could save $${costSavings.toFixed(2)} on staffing costs per month, by spending $${finCosts.toFixed(2)}. | ||
`; | ||
document.getElementById('roi-explanation').textContent = ` | ||
We see in practice that the conversations humans handle that Fin cannot typically take ${1.0 / ratioOfFinConversationTimeVsHuman} times longer than those it can resolve. | ||
Savings are based on human labor avoided on the conversations Fin takes care of. | ||
Based on the values above, Fin will resolve ${resolvedConversations} conversations, | ||
saving you ${timeSavings} hours of human labor per month. At your average salary of $${costPerEmployeeMonth} and subtracting the cost | ||
for Fin ($${finCosts}) this works out at $${costSavings.toFixed(2)} savings. | ||
`; | ||
} | ||
|
||
function setSliderValue(target, value) { | ||
var compositeSlider = target.closest('.compositeSlider'); | ||
var rangeSlider = compositeSlider.getElementsByClassName('slider')[0]; | ||
var sliderValue = compositeSlider.getElementsByClassName('compositeSliderValue')[0]; | ||
rangeSlider.value = value; | ||
sliderValue.innerText = value; | ||
calculate(); | ||
} | ||
|
||
document.querySelectorAll('input.slider').forEach(input => { | ||
input.addEventListener('input', function() { | ||
var compositeSlider = this.closest('.compositeSlider'); | ||
var sliderValue = compositeSlider.getElementsByClassName('compositeSliderValue')[0]; | ||
sliderValue.innerText = this.value; | ||
console.log("calculate range change") | ||
calculate(); | ||
}); | ||
}); | ||
|
||
calculate(); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
two variations | ||
|
||
one worrydream style, paragraph with sliders in it... | ||
one with more typical calc layout... | ||
|
||
consider adding copilot too as further layer... |