-
Celeste Robert authoredCeleste Robert authored
PricingComparator.js 8.63 KiB
/* eslint-disable react/no-unescaped-entities */
import React from "react";
import { FaMinus, FaPlus, FaSortDown } from "react-icons/fa";
import styles from "./PricingComparator.module.css";
import { Dropdown } from "../Dropdown";
import formatNumber from "@site/src/utils/formatNumber";
import plans from "@site/src/constants/plans";
import competitors from "@site/src/constants/competitors";
function getPrices(users, paidAnnually, labCompetitor, chatCompetitor) {
const plan = [
{
users: 1,
paidMonthly: plans.grenouille.paidMonthly,
paidAnnually: plans.grenouille.paidAnnually,
},
{
users: 2,
paidMonthly: plans.grenouille.paidMonthly,
paidAnnually: plans.etang2.paidAnnually,
},
{
users: 5,
paidMonthly: plans.grenouille.paidMonthly,
paidAnnually: plans.etang5.paidAnnually,
},
{
users: 10,
paidMonthly: plans.grenouille.paidMonthly,
paidAnnually: plans.etang10.paidAnnually,
},
{
users: 50,
paidMonthly: plans.grenouille.paidMonthly,
paidAnnually: plans.etang50.paidAnnually,
},
{
users: 100,
paidMonthly: plans.grenouille.paidMonthly,
paidAnnually: plans.etang100.paidAnnually,
},
]
.slice()
.reverse()
.find(plan => plan.users <= users);
let labCompetitorParsed = labCompetitor.plans.find(plan => plan.users <= users);
if (paidAnnually) {
return {
froggit: (plan.paidAnnually * Math.max(plan.users, users)) / users,
lab: labCompetitorParsed.paidAnnually,
chat: chatCompetitor.paidAnnually,
};
}
return {
froggit: (plan.paidMonthly * Math.max(plan.users, users)) / users,
lab: labCompetitorParsed.paidMonthly,
chat: chatCompetitor.paidMonthly,
};
}
export default function PricingComparator() {
const [users, setUsers] = React.useState(1);
const [paidAnnually, setPaidAnnually] = React.useState(true);
const [labCompetitor, setLabCompetitor] = React.useState(competitors.lab[0]);
const [chatCompetitor, setChatCompetitor] = React.useState(
competitors.chat[0]
);
const prices = getPrices(users, paidAnnually, labCompetitor, chatCompetitor);
const decreaseUsers = shiftKey => {
const step = shiftKey ? 10 : 1;
setUsers(currentUsers => Math.max(1, currentUsers - step));
};
const increaseUsers = shiftKey => {
const step = shiftKey ? 10 : 1;
setUsers(currentUsers => currentUsers + step);
};
const value = Math.round(prices.froggit - (prices.lab + prices.chat)) * users * 12;
let message = <>
Économise{users > 1 ? "z" : ""}{" "}
<span className={styles.summaryBadge}>
{formatNumber(
Math.abs(value)
)}
€
</span>{" "}
par an pour {users} utilisateur
{users > 1 ? "s" : ""} avec Froggit !
</>;
if (value > 0) {
message = <>
Froggit ne {users > 1 ? "vous" : "te"} ferait rien économiser, mais c'est le prix de la souveraineté numérique et de la conformité RGPD !
</>;
}
return (
<div className={styles.container}>
<div className={styles.controls}>
<div className={styles.controlsUsers}>
<div className={styles.controlsUsersLabel}>Utilisateurs</div>
<div className={styles.controlsUsersActions}>
<button
type="button"
className="button button--secondary button--sm"
onClick={event => decreaseUsers(event.shiftKey)}
disabled={users <= 1}
>
<FaMinus size={10} />
</button>
<input
type="text"
onKeyDown={event => {
switch (event.key) {
case "ArrowDown":
return decreaseUsers(event.shiftKey);
case "ArrowUp":
return increaseUsers(event.shiftKey);
}
}}
onChange={event => {
const value = Math.round(Number(event.target.value));
if (isNaN(value)) {
return;
}
setUsers(Math.max(1, value));
}}
pattern="[0-9]*"
value={users}
className={styles.controlsUsersInput}
/>
<button
type="button"
className="button button--secondary button--sm"
onClick={event => increaseUsers(event.shiftKey)}
>
<FaPlus size={10} />
</button>
</div>
</div>
<ul className={`${styles.controlsPeriodicity} pills`}>
<li
role="button"
tabIndex={0}
className={`pills__item ${
!paidAnnually ? "pills__item--active" : ""
}`}
onClick={() => setPaidAnnually(false)}
>
Mensuel
</li>
<li
role="button"
tabIndex={0}
className={`pills__item ${
paidAnnually ? "pills__item--active" : ""
}`}
onClick={() => setPaidAnnually(true)}
>
Annuel <span className="badge badge--success">-20%</span>
</li>
</ul>
</div>
<div className={styles.table}>
<div className={styles.tableHead}>
<div className={styles.tableHeadCell} />
<div className={styles.tableHeadCell}>
<div>
<strong>Froggit</strong>
</div>
<small>GitLab + Mattermost</small>
</div>
<div className={styles.tableHeadCell}>
<div>
<Dropdown>
<div className="dropdown">
<div
tabIndex={0}
role="button"
className={styles.dropdownTrigger}
>
<strong>{labCompetitor.name}</strong> <FaSortDown />
</div>
<ul className="dropdown__menu">
{competitors.lab.map(competitor => (
<li key={competitor.name}>
<div
className="dropdown__link"
onClick={() => setLabCompetitor(competitor)}
>
{competitor.name}
</div>
</li>
))}
</ul>
</div>
</Dropdown>
</div>
<small> </small>
</div>
<div className={styles.tableHeadCell}>
<FaPlus
style={{
position: "absolute",
top: "24px",
left: "0",
transform: "translateX(-50%)",
}}
/>
<div>
<Dropdown>
<div className="dropdown">
<div
tabIndex={0}
role="button"
className={styles.dropdownTrigger}
>
<strong>{chatCompetitor.name}</strong> <FaSortDown />
</div>
<ul className="dropdown__menu">
{competitors.chat.map(competitor => (
<li key={competitor.name}>
<div
className="dropdown__link"
onClick={() => setChatCompetitor(competitor)}
>
{competitor.name}
</div>
</li>
))}
</ul>
</div>
</Dropdown>
</div>
<small> </small>
</div>
</div>
<div className={styles.tableRow}>
<div className={styles.tableRowCell}>
<small>Tarif mensuel HT par utilisateur</small>
</div>
<div className={styles.tableRowCell}>
<small>{formatNumber(prices.froggit)}€</small>
</div>
<div className={styles.tableRowCell}>
<small>{formatNumber(prices.lab)}€</small>
</div>
<div className={styles.tableRowCell}>
<small>{formatNumber(prices.chat)}€</small>
</div>
</div>
<div className={styles.tableRow}>
<div className={styles.tableRowCell} />
<div className={styles.tableRowCell}>
<strong>{formatNumber(prices.froggit)}€</strong>
</div>
<div className={styles.tableRowCell}>
<strong>{formatNumber(prices.lab + prices.chat)}€</strong>
</div>
</div>
</div>
<p className={styles.summary}>
{message}
</p>
</div>
);
}