pricing4react
Version:
A library of components that ease the integration of feature toggling driven by pricing plans into your React application's UI.
130 lines (129 loc) • 8.94 kB
JavaScript
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
exports.__esModule = true;
exports.Plan = void 0;
var jsx_runtime_1 = require("react/jsx-runtime");
var react_1 = require("react");
var react_router_dom_1 = require("react-router-dom");
var Button_1 = require("../../components/Button");
var EditorContextProvider_1 = require("../../context/EditorContextProvider");
var Icons_1 = require("../../components/Icons");
var utils_1 = require("../../utils");
function Plan() {
var state = (0, react_router_dom_1.useLocation)().state;
var index = state.index;
var isPlanIncluded = index !== null;
var navigate = (0, react_router_dom_1.useNavigate)();
var goBack = function () { return navigate(".."); };
var _a = (0, react_1.useContext)(EditorContextProvider_1.EditorContext), attributes = _a.attributes, plans = _a.plans, setPlans = _a.setPlans;
var initialFeatures = isPlanIncluded
? plans[index].features
: attributes.map(function (attribute) { return ({
name: attribute.id,
type: (0, utils_1.computeType)(attribute.defaultValue),
value: attribute.defaultValue
}); });
var initialPlan = isPlanIncluded
? {
name: plans[state.index].name,
description: plans[state.index].description,
price: plans[state.index].price.toString(),
currency: plans[state.index].currency
}
: {
name: "",
description: "",
price: "",
currency: ""
};
var _b = (0, react_1.useState)(initialPlan), plan = _b[0], setPlan = _b[1];
var _c = (0, react_1.useState)(initialFeatures), features = _c[0], setFeatures = _c[1];
var isPlanNameEmpty = plan.name === "";
var isPlanNameCompound = plan.name.trim().split(" ").length > 1;
var priceRegex = /^\d+.?\d{0,2}?$/;
var isValidPrice = priceRegex.test(plan.price);
var addPlan = function () {
return setPlans(__spreadArray(__spreadArray([], plans, true), [__assign(__assign({}, plan), { price: Number(plan.price), features: features })], false));
};
var editPlan = function (planPosition) {
var newPlans = plans.map(function (oldPlan, index) {
return index === planPosition
? __assign(__assign({}, plan), { price: Number(plan.price), features: features }) : oldPlan;
});
setPlans(newPlans);
};
var deletePlan = function () {
setPlans(plans.filter(function (_, index) { return index !== state.index; }));
goBack();
};
var handleSubmit = function (e) {
e.preventDefault();
if (isPlanIncluded) {
editPlan(index);
}
else {
addPlan();
}
goBack();
};
var handleChange = function (e) {
var _a;
return setPlan(__assign(__assign({}, plan), (_a = {}, _a[e.target.name] = e.target.value, _a)));
};
return ((0, jsx_runtime_1.jsxs)("article", __assign({ className: "pp-content__main" }, { children: [(0, jsx_runtime_1.jsxs)("header", __assign({ className: "pp-content-header" }, { children: [(0, jsx_runtime_1.jsx)(Button_1.Button, __assign({ onClick: goBack }, { children: (0, jsx_runtime_1.jsx)(Icons_1.ArrowLeft, {}) })), (0, jsx_runtime_1.jsx)("h1", { children: isPlanIncluded ? plans[index].name : "New Plan" })] })), (0, jsx_runtime_1.jsxs)("form", __assign({ className: "pp-form", onSubmit: handleSubmit }, { children: [(0, jsx_runtime_1.jsxs)("div", __assign({ className: "pp-form__group" }, { children: [isPlanNameEmpty && (0, jsx_runtime_1.jsx)("small", { children: "Plan name is required" }), isPlanNameCompound && ((0, jsx_runtime_1.jsx)("small", { children: "Compound plan names are not allowed. Use only one word" })), (0, jsx_runtime_1.jsx)("label", __assign({ htmlFor: "name", className: "pp-form__label" }, { children: "Plan name" })), (0, jsx_runtime_1.jsx)("input", { id: "name", name: "name", className: "pp-form__field", value: plan.name, onChange: handleChange })] })), (0, jsx_runtime_1.jsxs)("div", __assign({ className: "pp-form__group" }, { children: [(0, jsx_runtime_1.jsx)("label", __assign({ htmlFor: "description", className: "pp-form__label" }, { children: "Description" })), (0, jsx_runtime_1.jsx)("input", { id: "description", name: "description", className: "pp-form__field", value: plan.description, onChange: handleChange })] })), (0, jsx_runtime_1.jsxs)("div", __assign({ className: "pp-form__group" }, { children: [!isValidPrice && ((0, jsx_runtime_1.jsx)("small", { children: "Invalid price. Plan has to be zero or positive and contain a dot" })), (0, jsx_runtime_1.jsx)("label", __assign({ htmlFor: "price", className: "pp-form__label" }, { children: "Price" })), (0, jsx_runtime_1.jsx)("input", { id: "price", name: "price", type: "number", className: "pp-form__field", value: plan.price, onChange: handleChange })] })), (0, jsx_runtime_1.jsxs)("div", __assign({ className: "pp-form__group" }, { children: [(0, jsx_runtime_1.jsx)("label", __assign({ htmlFor: "currency", className: "pp-form__label" }, { children: "Currency" })), (0, jsx_runtime_1.jsx)("input", { id: "currency", name: "currency", className: "pp-form__field", value: plan.currency, onChange: handleChange })] })), (0, jsx_runtime_1.jsx)(FeatureList, { features: features, setFeatures: setFeatures }), (0, jsx_runtime_1.jsxs)("footer", __assign({ className: "pp-plan-actions" }, { children: [isPlanIncluded && ((0, jsx_runtime_1.jsx)(Button_1.Button, __assign({ className: "pp-btn", style: { backgroundColor: "red" }, type: "button", onClick: deletePlan }, { children: "Delete plan" }))), (0, jsx_runtime_1.jsx)(Button_1.Button, __assign({ className: "pp-btn" }, { children: isPlanIncluded ? "Save changes" : "Add plan" }))] }))] }))] })));
}
exports.Plan = Plan;
function FeatureList(_a) {
var features = _a.features, setFeatures = _a.setFeatures;
var handleTextChange = function (e) {
return setFeatures(features.map(function (feature) {
return feature.name === e.target.name
? __assign(__assign({}, feature), { value: e.target.value }) : feature;
}));
};
var handleNumberChange = function (e) {
return setFeatures(features.map(function (feature) {
return feature.name === e.target.name
? __assign(__assign({}, feature), { value: e.currentTarget.valueAsNumber }) : feature;
}));
};
var handleCheckboxChange = function (e) {
console.log(e.target.checked);
setFeatures(features.map(function (feature) {
return feature.name === e.target.name
? __assign(__assign({}, feature), { value: e.target.checked }) : feature;
}));
};
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: features.map(function (feature) {
switch (feature.type) {
case "TEXT": {
return ((0, jsx_runtime_1.jsxs)("div", __assign({ className: "pp-form__group" }, { children: [(0, jsx_runtime_1.jsx)("label", __assign({ className: "pp-form__label" }, { children: feature.name })), (0, jsx_runtime_1.jsx)("input", { className: "pp-form__field", type: "text", id: feature.name, name: feature.name, value: feature.value.toString(), onChange: handleTextChange })] }), feature.name));
}
case "NUMERIC": {
return ((0, jsx_runtime_1.jsxs)("div", __assign({ className: "pp-form__group" }, { children: [(0, jsx_runtime_1.jsx)("label", __assign({ className: "pp-form__label" }, { children: feature.name })), (0, jsx_runtime_1.jsx)("input", { className: "pp-form__field", type: "number", id: feature.name, name: feature.name, value: feature.value.toString(), onChange: handleNumberChange })] }), feature.name));
}
case "CONDITION": {
return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { children: feature.name }), (0, jsx_runtime_1.jsx)("input", { type: "checkbox", id: feature.name, name: feature.name, checked: feature.value, onChange: handleCheckboxChange })] }, feature.name));
}
}
}) }));
}