React
by Tyler Brown
HTML
<div id="app"></div>
CSS
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
li {
margin: 8px 0;
}
h2 {
font-weight: bold;
margin-bottom: 15px;
}
.done {
color: rgba(0, 0, 0, 0.3);
text-decoration: line-through;
}
input {
margin-right: 5px;
}
React
const pricing = (() => {
const absMin = 0;
const pricePoints = [
{cap: 100, price: 3015},
{cap: 150, price: 4266},
{cap: 200, price: 5474},
{cap: 250, price: 6558},
{cap: 300, price: 7467},
{cap: 350, price: 8260},
{cap: 400, price: 8968},
{cap: 450, price: 9599},
{cap: 500, price: 10145},
{cap: 600, price: 11472},
{cap: 700, price: 12376},
{cap: 800, price: 13264},
{cap: 900, price: 13905},
{cap: 1000, price: 14680},
{cap: 1250, price: 16125},
{cap: 1500, price: 17175},
{cap: 1750, price: 18638},
{cap: 2000, price: 20100},
{cap: 2500, price: 23200},
{cap: 3000, price: 26340},
{cap: 3500, price: 29120},
{cap: 4000, price: 31200},
{cap: 4500, price: 34515},
{cap: 5000, price: 37650},
{cap: 5500, price: 40590},
{cap: 6000, price: 43440},
{cap: 6500, price: 46020},
{cap: 7000, price: 48580},
{cap: 8000, price: 54400},
{cap: 9000, price: 60030},
{cap: 10000, price: 65300},
{cap: 15000, price: 85500},
{cap: 20000, price: 93000},
];
const percents = {
intl: 0.10,
vol: (empCount) => (empCount > 300) ? 0.3 : 0.3,
volNoMatch: 0.80,
groups: 0.25,
analytics: 0.20,
sso: (empCount) => (empCount > 300) ? 0.10 : 0.05,
payroll: 0.20,
};
const getPrice = (empCount=0, {match=false, intl=false, vol=false, groups=false, analytics=false, sso=false, payroll=false, madness=false} = {}) => {
if (empCount > 20000) return null;
const pricePoint = pricePoints.find(mp => mp.cap >= empCount);
if (!pricePoint) return null;
const basePrice = pricePoint.price;
const priceFromPercent = (percentage) => Math.round(basePrice * percentage);
const hasMatch = !!(match || intl);
const volPercentage = hasMatch ? percents.vol(empCount) :...