@schematichq/schematic-react 0.2.0-rc.5 → 0.2.0-rc.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,13 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __getProtoOf = Object.getPrototypeOf;
6
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __commonJS = (cb, mod) => function __require() {
7
+ var __require = /* @__PURE__ */ ((x2) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x2, {
8
+ get: (a2, b2) => (typeof require !== "undefined" ? require : a2)[b2]
9
+ }) : x2)(function(x2) {
10
+ if (typeof require !== "undefined") return require.apply(this, arguments);
11
+ throw Error('Dynamic require of "' + x2 + '" is not supported');
12
+ });
13
+ var __commonJS = (cb, mod) => function __require2() {
8
14
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
9
15
  };
10
16
  var __copyProps = (to, from2, except, desc) => {
@@ -843,6 +849,357 @@ var require_classnames = __commonJS({
843
849
  }
844
850
  });
845
851
 
852
+ // node_modules/pluralize/pluralize.js
853
+ var require_pluralize = __commonJS({
854
+ "node_modules/pluralize/pluralize.js"(exports, module) {
855
+ (function(root, pluralize3) {
856
+ if (typeof __require === "function" && typeof exports === "object" && typeof module === "object") {
857
+ module.exports = pluralize3();
858
+ } else if (typeof define === "function" && define.amd) {
859
+ define(function() {
860
+ return pluralize3();
861
+ });
862
+ } else {
863
+ root.pluralize = pluralize3();
864
+ }
865
+ })(exports, function() {
866
+ var pluralRules = [];
867
+ var singularRules = [];
868
+ var uncountables = {};
869
+ var irregularPlurals = {};
870
+ var irregularSingles = {};
871
+ function sanitizeRule(rule) {
872
+ if (typeof rule === "string") {
873
+ return new RegExp("^" + rule + "$", "i");
874
+ }
875
+ return rule;
876
+ }
877
+ function restoreCase(word, token2) {
878
+ if (word === token2) return token2;
879
+ if (word === word.toLowerCase()) return token2.toLowerCase();
880
+ if (word === word.toUpperCase()) return token2.toUpperCase();
881
+ if (word[0] === word[0].toUpperCase()) {
882
+ return token2.charAt(0).toUpperCase() + token2.substr(1).toLowerCase();
883
+ }
884
+ return token2.toLowerCase();
885
+ }
886
+ function interpolate(str, args) {
887
+ return str.replace(/\$(\d{1,2})/g, function(match2, index) {
888
+ return args[index] || "";
889
+ });
890
+ }
891
+ function replace2(word, rule) {
892
+ return word.replace(rule[0], function(match2, index) {
893
+ var result = interpolate(rule[1], arguments);
894
+ if (match2 === "") {
895
+ return restoreCase(word[index - 1], result);
896
+ }
897
+ return restoreCase(match2, result);
898
+ });
899
+ }
900
+ function sanitizeWord(token2, word, rules) {
901
+ if (!token2.length || uncountables.hasOwnProperty(token2)) {
902
+ return word;
903
+ }
904
+ var len = rules.length;
905
+ while (len--) {
906
+ var rule = rules[len];
907
+ if (rule[0].test(word)) return replace2(word, rule);
908
+ }
909
+ return word;
910
+ }
911
+ function replaceWord(replaceMap, keepMap, rules) {
912
+ return function(word) {
913
+ var token2 = word.toLowerCase();
914
+ if (keepMap.hasOwnProperty(token2)) {
915
+ return restoreCase(word, token2);
916
+ }
917
+ if (replaceMap.hasOwnProperty(token2)) {
918
+ return restoreCase(word, replaceMap[token2]);
919
+ }
920
+ return sanitizeWord(token2, word, rules);
921
+ };
922
+ }
923
+ function checkWord(replaceMap, keepMap, rules, bool) {
924
+ return function(word) {
925
+ var token2 = word.toLowerCase();
926
+ if (keepMap.hasOwnProperty(token2)) return true;
927
+ if (replaceMap.hasOwnProperty(token2)) return false;
928
+ return sanitizeWord(token2, token2, rules) === token2;
929
+ };
930
+ }
931
+ function pluralize3(word, count, inclusive) {
932
+ var pluralized = count === 1 ? pluralize3.singular(word) : pluralize3.plural(word);
933
+ return (inclusive ? count + " " : "") + pluralized;
934
+ }
935
+ pluralize3.plural = replaceWord(
936
+ irregularSingles,
937
+ irregularPlurals,
938
+ pluralRules
939
+ );
940
+ pluralize3.isPlural = checkWord(
941
+ irregularSingles,
942
+ irregularPlurals,
943
+ pluralRules
944
+ );
945
+ pluralize3.singular = replaceWord(
946
+ irregularPlurals,
947
+ irregularSingles,
948
+ singularRules
949
+ );
950
+ pluralize3.isSingular = checkWord(
951
+ irregularPlurals,
952
+ irregularSingles,
953
+ singularRules
954
+ );
955
+ pluralize3.addPluralRule = function(rule, replacement) {
956
+ pluralRules.push([sanitizeRule(rule), replacement]);
957
+ };
958
+ pluralize3.addSingularRule = function(rule, replacement) {
959
+ singularRules.push([sanitizeRule(rule), replacement]);
960
+ };
961
+ pluralize3.addUncountableRule = function(word) {
962
+ if (typeof word === "string") {
963
+ uncountables[word.toLowerCase()] = true;
964
+ return;
965
+ }
966
+ pluralize3.addPluralRule(word, "$0");
967
+ pluralize3.addSingularRule(word, "$0");
968
+ };
969
+ pluralize3.addIrregularRule = function(single, plural) {
970
+ plural = plural.toLowerCase();
971
+ single = single.toLowerCase();
972
+ irregularSingles[single] = plural;
973
+ irregularPlurals[plural] = single;
974
+ };
975
+ [
976
+ // Pronouns.
977
+ ["I", "we"],
978
+ ["me", "us"],
979
+ ["he", "they"],
980
+ ["she", "they"],
981
+ ["them", "them"],
982
+ ["myself", "ourselves"],
983
+ ["yourself", "yourselves"],
984
+ ["itself", "themselves"],
985
+ ["herself", "themselves"],
986
+ ["himself", "themselves"],
987
+ ["themself", "themselves"],
988
+ ["is", "are"],
989
+ ["was", "were"],
990
+ ["has", "have"],
991
+ ["this", "these"],
992
+ ["that", "those"],
993
+ // Words ending in with a consonant and `o`.
994
+ ["echo", "echoes"],
995
+ ["dingo", "dingoes"],
996
+ ["volcano", "volcanoes"],
997
+ ["tornado", "tornadoes"],
998
+ ["torpedo", "torpedoes"],
999
+ // Ends with `us`.
1000
+ ["genus", "genera"],
1001
+ ["viscus", "viscera"],
1002
+ // Ends with `ma`.
1003
+ ["stigma", "stigmata"],
1004
+ ["stoma", "stomata"],
1005
+ ["dogma", "dogmata"],
1006
+ ["lemma", "lemmata"],
1007
+ ["schema", "schemata"],
1008
+ ["anathema", "anathemata"],
1009
+ // Other irregular rules.
1010
+ ["ox", "oxen"],
1011
+ ["axe", "axes"],
1012
+ ["die", "dice"],
1013
+ ["yes", "yeses"],
1014
+ ["foot", "feet"],
1015
+ ["eave", "eaves"],
1016
+ ["goose", "geese"],
1017
+ ["tooth", "teeth"],
1018
+ ["quiz", "quizzes"],
1019
+ ["human", "humans"],
1020
+ ["proof", "proofs"],
1021
+ ["carve", "carves"],
1022
+ ["valve", "valves"],
1023
+ ["looey", "looies"],
1024
+ ["thief", "thieves"],
1025
+ ["groove", "grooves"],
1026
+ ["pickaxe", "pickaxes"],
1027
+ ["passerby", "passersby"]
1028
+ ].forEach(function(rule) {
1029
+ return pluralize3.addIrregularRule(rule[0], rule[1]);
1030
+ });
1031
+ [
1032
+ [/s?$/i, "s"],
1033
+ [/[^\u0000-\u007F]$/i, "$0"],
1034
+ [/([^aeiou]ese)$/i, "$1"],
1035
+ [/(ax|test)is$/i, "$1es"],
1036
+ [/(alias|[^aou]us|t[lm]as|gas|ris)$/i, "$1es"],
1037
+ [/(e[mn]u)s?$/i, "$1s"],
1038
+ [/([^l]ias|[aeiou]las|[ejzr]as|[iu]am)$/i, "$1"],
1039
+ [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, "$1i"],
1040
+ [/(alumn|alg|vertebr)(?:a|ae)$/i, "$1ae"],
1041
+ [/(seraph|cherub)(?:im)?$/i, "$1im"],
1042
+ [/(her|at|gr)o$/i, "$1oes"],
1043
+ [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i, "$1a"],
1044
+ [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i, "$1a"],
1045
+ [/sis$/i, "ses"],
1046
+ [/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i, "$1$2ves"],
1047
+ [/([^aeiouy]|qu)y$/i, "$1ies"],
1048
+ [/([^ch][ieo][ln])ey$/i, "$1ies"],
1049
+ [/(x|ch|ss|sh|zz)$/i, "$1es"],
1050
+ [/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i, "$1ices"],
1051
+ [/\b((?:tit)?m|l)(?:ice|ouse)$/i, "$1ice"],
1052
+ [/(pe)(?:rson|ople)$/i, "$1ople"],
1053
+ [/(child)(?:ren)?$/i, "$1ren"],
1054
+ [/eaux$/i, "$0"],
1055
+ [/m[ae]n$/i, "men"],
1056
+ ["thou", "you"]
1057
+ ].forEach(function(rule) {
1058
+ return pluralize3.addPluralRule(rule[0], rule[1]);
1059
+ });
1060
+ [
1061
+ [/s$/i, ""],
1062
+ [/(ss)$/i, "$1"],
1063
+ [/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i, "$1fe"],
1064
+ [/(ar|(?:wo|[ae])l|[eo][ao])ves$/i, "$1f"],
1065
+ [/ies$/i, "y"],
1066
+ [/\b([pl]|zomb|(?:neck|cross)?t|coll|faer|food|gen|goon|group|lass|talk|goal|cut)ies$/i, "$1ie"],
1067
+ [/\b(mon|smil)ies$/i, "$1ey"],
1068
+ [/\b((?:tit)?m|l)ice$/i, "$1ouse"],
1069
+ [/(seraph|cherub)im$/i, "$1"],
1070
+ [/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$/i, "$1"],
1071
+ [/(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$/i, "$1sis"],
1072
+ [/(movie|twelve|abuse|e[mn]u)s$/i, "$1"],
1073
+ [/(test)(?:is|es)$/i, "$1is"],
1074
+ [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, "$1us"],
1075
+ [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i, "$1um"],
1076
+ [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i, "$1on"],
1077
+ [/(alumn|alg|vertebr)ae$/i, "$1a"],
1078
+ [/(cod|mur|sil|vert|ind)ices$/i, "$1ex"],
1079
+ [/(matr|append)ices$/i, "$1ix"],
1080
+ [/(pe)(rson|ople)$/i, "$1rson"],
1081
+ [/(child)ren$/i, "$1"],
1082
+ [/(eau)x?$/i, "$1"],
1083
+ [/men$/i, "man"]
1084
+ ].forEach(function(rule) {
1085
+ return pluralize3.addSingularRule(rule[0], rule[1]);
1086
+ });
1087
+ [
1088
+ // Singular words with no plurals.
1089
+ "adulthood",
1090
+ "advice",
1091
+ "agenda",
1092
+ "aid",
1093
+ "aircraft",
1094
+ "alcohol",
1095
+ "ammo",
1096
+ "analytics",
1097
+ "anime",
1098
+ "athletics",
1099
+ "audio",
1100
+ "bison",
1101
+ "blood",
1102
+ "bream",
1103
+ "buffalo",
1104
+ "butter",
1105
+ "carp",
1106
+ "cash",
1107
+ "chassis",
1108
+ "chess",
1109
+ "clothing",
1110
+ "cod",
1111
+ "commerce",
1112
+ "cooperation",
1113
+ "corps",
1114
+ "debris",
1115
+ "diabetes",
1116
+ "digestion",
1117
+ "elk",
1118
+ "energy",
1119
+ "equipment",
1120
+ "excretion",
1121
+ "expertise",
1122
+ "firmware",
1123
+ "flounder",
1124
+ "fun",
1125
+ "gallows",
1126
+ "garbage",
1127
+ "graffiti",
1128
+ "hardware",
1129
+ "headquarters",
1130
+ "health",
1131
+ "herpes",
1132
+ "highjinks",
1133
+ "homework",
1134
+ "housework",
1135
+ "information",
1136
+ "jeans",
1137
+ "justice",
1138
+ "kudos",
1139
+ "labour",
1140
+ "literature",
1141
+ "machinery",
1142
+ "mackerel",
1143
+ "mail",
1144
+ "media",
1145
+ "mews",
1146
+ "moose",
1147
+ "music",
1148
+ "mud",
1149
+ "manga",
1150
+ "news",
1151
+ "only",
1152
+ "personnel",
1153
+ "pike",
1154
+ "plankton",
1155
+ "pliers",
1156
+ "police",
1157
+ "pollution",
1158
+ "premises",
1159
+ "rain",
1160
+ "research",
1161
+ "rice",
1162
+ "salmon",
1163
+ "scissors",
1164
+ "series",
1165
+ "sewage",
1166
+ "shambles",
1167
+ "shrimp",
1168
+ "software",
1169
+ "species",
1170
+ "staff",
1171
+ "swine",
1172
+ "tennis",
1173
+ "traffic",
1174
+ "transportation",
1175
+ "trout",
1176
+ "tuna",
1177
+ "wealth",
1178
+ "welfare",
1179
+ "whiting",
1180
+ "wildebeest",
1181
+ "wildlife",
1182
+ "you",
1183
+ /pok[eé]mon$/i,
1184
+ // Regexes.
1185
+ /[^aeiou]ese$/i,
1186
+ // "chinese", "japanese"
1187
+ /deer$/i,
1188
+ // "deer", "reindeer"
1189
+ /fish$/i,
1190
+ // "fish", "blowfish", "angelfish"
1191
+ /measles$/i,
1192
+ /o[iu]s$/i,
1193
+ // "carnivorous"
1194
+ /pox$/i,
1195
+ // "chickpox", "smallpox"
1196
+ /sheep$/i
1197
+ ].forEach(pluralize3.addUncountableRule);
1198
+ return pluralize3;
1199
+ });
1200
+ }
1201
+ });
1202
+
846
1203
  // src/context/embed.tsx
847
1204
  import { createContext, useCallback, useEffect, useRef, useState } from "react";
848
1205
 
@@ -5020,7 +5377,7 @@ var { Deflate, deflate, deflateRaw, gzip } = deflate_1$1;
5020
5377
  var { Inflate, inflate, inflateRaw, ungzip } = inflate_1$1;
5021
5378
  var inflate_1 = inflate;
5022
5379
 
5023
- // node_modules/tslib/tslib.es6.mjs
5380
+ // node_modules/styled-components/node_modules/tslib/tslib.es6.mjs
5024
5381
  var __assign = function() {
5025
5382
  __assign = Object.assign || function __assign2(t) {
5026
5383
  for (var s2, i2 = 1, n = arguments.length; i2 < n; i2++) {
@@ -6418,7 +6775,7 @@ var registerWrapper = function registerWrapper2(stripe, startTime) {
6418
6775
  }
6419
6776
  stripe._registerWrapper({
6420
6777
  name: "stripe-js",
6421
- version: "4.3.0",
6778
+ version: "4.4.0",
6422
6779
  startTime
6423
6780
  });
6424
6781
  };
@@ -6857,6 +7214,7 @@ function BillingProductForSubscriptionResponseDataFromJSONTyped(json, ignoreDisc
6857
7214
  interval: json["interval"] == null ? void 0 : json["interval"],
6858
7215
  name: json["name"],
6859
7216
  price: json["price"],
7217
+ priceExternalId: json["price_external_id"] == null ? void 0 : json["price_external_id"],
6860
7218
  quantity: json["quantity"],
6861
7219
  subscriptionId: json["subscription_id"],
6862
7220
  updatedAt: new Date(json["updated_at"])
@@ -7288,6 +7646,7 @@ function CompanyPlanDetailResponseDataFromJSONTyped(json, ignoreDiscriminator) {
7288
7646
  ),
7289
7647
  icon: json["icon"],
7290
7648
  id: json["id"],
7649
+ isDefault: json["is_default"],
7291
7650
  monthlyPrice: json["monthly_price"] == null ? void 0 : BillingPriceResponseDataFromJSON(json["monthly_price"]),
7292
7651
  name: json["name"],
7293
7652
  planType: json["plan_type"],
@@ -7316,7 +7675,7 @@ function InvoiceResponseDataFromJSONTyped(json, ignoreDiscriminator) {
7316
7675
  customerExternalId: json["customer_external_id"],
7317
7676
  dueDate: json["due_date"] == null ? void 0 : new Date(json["due_date"]),
7318
7677
  environmentId: json["environment_id"],
7319
- externalId: json["external_id"],
7678
+ externalId: json["external_id"] == null ? void 0 : json["external_id"],
7320
7679
  id: json["id"],
7321
7680
  paymentMethodExternalId: json["payment_method_external_id"] == null ? void 0 : json["payment_method_external_id"],
7322
7681
  subscriptionExternalId: json["subscription_external_id"] == null ? void 0 : json["subscription_external_id"],
@@ -7344,7 +7703,6 @@ function PaymentMethodResponseDataFromJSONTyped(json, ignoreDiscriminator) {
7344
7703
  environmentId: json["environment_id"],
7345
7704
  externalId: json["external_id"],
7346
7705
  id: json["id"],
7347
- invoiceExternalId: json["invoice_external_id"] == null ? void 0 : json["invoice_external_id"],
7348
7706
  paymentMethodType: json["payment_method_type"],
7349
7707
  subscriptionExternalId: json["subscription_external_id"] == null ? void 0 : json["subscription_external_id"],
7350
7708
  updatedAt: new Date(json["updated_at"])
@@ -7883,7 +8241,7 @@ var defaultTheme = {
7883
8241
  sectionLayout: "merged",
7884
8242
  colorMode: "light",
7885
8243
  primary: "#000000",
7886
- secondary: "#000000",
8244
+ secondary: "#194BFB",
7887
8245
  card: {
7888
8246
  background: "#FFFFFF",
7889
8247
  borderRadius: 10,
@@ -7969,33 +8327,6 @@ function parseEditorState(data) {
7969
8327
  });
7970
8328
  return arr;
7971
8329
  }
7972
- async function fetchComponent(id, api) {
7973
- const nodes = [];
7974
- const settings = { ...defaultSettings };
7975
- const response = await api.hydrateComponent({ componentId: id });
7976
- const { data } = response;
7977
- if (data.component?.ast) {
7978
- const compressed = data.component.ast;
7979
- const json = inflate_1(Uint8Array.from(Object.values(compressed)), {
7980
- to: "string"
7981
- });
7982
- const ast = getEditorState(json);
7983
- if (ast) {
7984
- (0, import_lodash.default)(settings, ast.ROOT.props.settings);
7985
- nodes.push(...parseEditorState(ast));
7986
- }
7987
- }
7988
- let stripe = null;
7989
- if (data.stripeEmbed?.publishableKey) {
7990
- stripe = loadStripe(data.stripeEmbed.publishableKey);
7991
- }
7992
- return {
7993
- data,
7994
- nodes,
7995
- settings,
7996
- stripe
7997
- };
7998
- }
7999
8330
  var EmbedContext = createContext({
8000
8331
  api: null,
8001
8332
  data: {
@@ -8006,6 +8337,9 @@ var EmbedContext = createContext({
8006
8337
  stripe: null,
8007
8338
  layout: "portal",
8008
8339
  error: void 0,
8340
+ isPending: false,
8341
+ hydrate: () => {
8342
+ },
8009
8343
  setData: () => {
8010
8344
  },
8011
8345
  updateSettings: () => {
@@ -8032,7 +8366,10 @@ var EmbedProvider = ({
8032
8366
  settings: { ...defaultSettings },
8033
8367
  stripe: null,
8034
8368
  layout: "portal",
8369
+ isPending: false,
8035
8370
  error: void 0,
8371
+ hydrate: () => {
8372
+ },
8036
8373
  setData: () => {
8037
8374
  },
8038
8375
  updateSettings: () => {
@@ -8043,45 +8380,47 @@ var EmbedProvider = ({
8043
8380
  }
8044
8381
  };
8045
8382
  });
8046
- useEffect(() => {
8047
- const element = document.getElementById("schematic-fonts");
8048
- if (element) {
8049
- return void (styleRef.current = element);
8050
- }
8051
- const style = document.createElement("link");
8052
- style.id = "schematic-fonts";
8053
- style.rel = "stylesheet";
8054
- document.head.appendChild(style);
8055
- styleRef.current = style;
8056
- }, []);
8057
- useEffect(() => {
8058
- if (!accessToken) {
8059
- return;
8060
- }
8061
- const config = new Configuration({ ...apiConfig, apiKey: accessToken });
8062
- const api = new CheckoutApi(config);
8063
- setState((prev2) => ({ ...prev2, api }));
8064
- }, [accessToken, apiConfig]);
8065
- useEffect(() => {
8066
- if (!id || !state.api) {
8067
- return;
8068
- }
8069
- fetchComponent(id, state.api).then(async (resolvedData) => {
8070
- setState((prev2) => ({ ...prev2, ...resolvedData }));
8071
- }).catch((error) => setState((prev2) => ({ ...prev2, error })));
8072
- }, [id, state.api]);
8073
- useEffect(() => {
8074
- const fontSet = /* @__PURE__ */ new Set([]);
8075
- Object.values(state.settings.theme.typography).forEach(({ fontFamily }) => {
8076
- fontSet.add(fontFamily);
8077
- });
8078
- if (fontSet.size > 0) {
8079
- const src = `https://fonts.googleapis.com/css2?${[...fontSet].map((fontFamily) => `family=${fontFamily}&display=swap`).join("&")}`;
8080
- if (styleRef.current) {
8081
- styleRef.current.href = src;
8383
+ const hydrate = useCallback(async () => {
8384
+ setState((prev2) => ({ ...prev2, isPending: true, error: void 0 }));
8385
+ try {
8386
+ const nodes = [];
8387
+ const settings = { ...defaultSettings };
8388
+ if (!id || !state.api) {
8389
+ return new Error("Invalid component id or api instance.");
8390
+ }
8391
+ const response = await state.api.hydrateComponent({ componentId: id });
8392
+ const { data } = response;
8393
+ if (data.component?.ast) {
8394
+ const compressed = data.component.ast;
8395
+ const json = inflate_1(Uint8Array.from(Object.values(compressed)), {
8396
+ to: "string"
8397
+ });
8398
+ const ast = getEditorState(json);
8399
+ if (ast) {
8400
+ (0, import_lodash.default)(settings, ast.ROOT.props.settings);
8401
+ nodes.push(...parseEditorState(ast));
8402
+ }
8403
+ }
8404
+ let stripe = null;
8405
+ if (data.stripeEmbed?.publishableKey) {
8406
+ stripe = loadStripe(data.stripeEmbed.publishableKey);
8082
8407
  }
8408
+ setState((prev2) => ({
8409
+ ...prev2,
8410
+ data,
8411
+ nodes,
8412
+ settings,
8413
+ stripe,
8414
+ isPending: false
8415
+ }));
8416
+ } catch (error) {
8417
+ setState((prev2) => ({
8418
+ ...prev2,
8419
+ isPending: false,
8420
+ error: error instanceof Error ? error : new Error("An unknown error occurred.")
8421
+ }));
8083
8422
  }
8084
- }, [state.settings.theme.typography]);
8423
+ }, [id, state.api]);
8085
8424
  const setData = useCallback(
8086
8425
  (data) => {
8087
8426
  setState((prev2) => {
@@ -8124,6 +8463,40 @@ var EmbedProvider = ({
8124
8463
  },
8125
8464
  [setState]
8126
8465
  );
8466
+ useEffect(() => {
8467
+ const element = document.getElementById("schematic-fonts");
8468
+ if (element) {
8469
+ return void (styleRef.current = element);
8470
+ }
8471
+ const style = document.createElement("link");
8472
+ style.id = "schematic-fonts";
8473
+ style.rel = "stylesheet";
8474
+ document.head.appendChild(style);
8475
+ styleRef.current = style;
8476
+ }, []);
8477
+ useEffect(() => {
8478
+ if (!accessToken) {
8479
+ return;
8480
+ }
8481
+ const config = new Configuration({ ...apiConfig, apiKey: accessToken });
8482
+ const api = new CheckoutApi(config);
8483
+ setState((prev2) => ({ ...prev2, api }));
8484
+ }, [accessToken, apiConfig]);
8485
+ useEffect(() => {
8486
+ hydrate();
8487
+ }, [hydrate]);
8488
+ useEffect(() => {
8489
+ const fontSet = /* @__PURE__ */ new Set([]);
8490
+ Object.values(state.settings.theme.typography).forEach(({ fontFamily }) => {
8491
+ fontSet.add(fontFamily);
8492
+ });
8493
+ if (fontSet.size > 0) {
8494
+ const src = `https://fonts.googleapis.com/css2?${[...fontSet].map((fontFamily) => `family=${fontFamily}&display=swap`).join("&")}`;
8495
+ if (styleRef.current) {
8496
+ styleRef.current.href = src;
8497
+ }
8498
+ }
8499
+ }, [state.settings.theme.typography]);
8127
8500
  const renderChildren = () => {
8128
8501
  if (state.stripe) {
8129
8502
  return /* @__PURE__ */ jsx(
@@ -8135,23 +8508,23 @@ var EmbedProvider = ({
8135
8508
  theme: "stripe",
8136
8509
  variables: {
8137
8510
  // Base
8138
- spacingUnit: ".25rem",
8139
- colorPrimary: "#0570de",
8511
+ fontFamily: '"Public Sans", system-ui, sans-serif',
8512
+ spacingUnit: "0.25rem",
8513
+ borderRadius: "0.5rem",
8514
+ colorText: "#30313D",
8140
8515
  colorBackground: "#FFFFFF",
8141
- colorText: "#30313d",
8142
- colorDanger: "#df1b41",
8143
- fontFamily: "Public Sans, system-ui, sans-serif",
8144
- borderRadius: ".5rem",
8516
+ colorPrimary: "#0570DE",
8517
+ colorDanger: "#DF1B41",
8145
8518
  // Layout
8146
8519
  gridRowSpacing: "1.5rem",
8147
8520
  gridColumnSpacing: "1.5rem"
8148
8521
  },
8149
8522
  rules: {
8150
8523
  ".Label": {
8151
- color: "#020202",
8524
+ fontSize: "1rem",
8152
8525
  fontWeight: "400",
8153
- fontSize: "16px",
8154
- marginBottom: "12px"
8526
+ marginBottom: "0.75rem",
8527
+ color: state.settings.theme.typography.text.color
8155
8528
  }
8156
8529
  }
8157
8530
  },
@@ -8176,6 +8549,8 @@ var EmbedProvider = ({
8176
8549
  stripe: state.stripe,
8177
8550
  layout: state.layout,
8178
8551
  error: state.error,
8552
+ isPending: state.isPending,
8553
+ hydrate,
8179
8554
  setData,
8180
8555
  updateSettings,
8181
8556
  setStripe,
@@ -8196,7 +8571,7 @@ var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
8196
8571
  var __getOwnPropNames2 = Object.getOwnPropertyNames;
8197
8572
  var __getProtoOf2 = Object.getPrototypeOf;
8198
8573
  var __hasOwnProp2 = Object.prototype.hasOwnProperty;
8199
- var __commonJS2 = (cb, mod) => function __require() {
8574
+ var __commonJS2 = (cb, mod) => function __require2() {
8200
8575
  return mod || (0, cb[__getOwnPropNames2(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
8201
8576
  };
8202
8577
  var __copyProps2 = (to, from2, except, desc) => {
@@ -8756,19 +9131,36 @@ function v4(options, buf, offset) {
8756
9131
  }
8757
9132
  var v4_default = v4;
8758
9133
  var import_polyfill = __toESM2(require_browser_polyfill());
9134
+ function contextString(context) {
9135
+ const sortedContext = Object.keys(context).reduce((acc, key) => {
9136
+ const sortedKeys = Object.keys(
9137
+ context[key] || {}
9138
+ ).sort();
9139
+ const sortedObj = sortedKeys.reduce((obj, sortedKey) => {
9140
+ obj[sortedKey] = context[key][sortedKey];
9141
+ return obj;
9142
+ }, {});
9143
+ acc[key] = sortedObj;
9144
+ return acc;
9145
+ }, {});
9146
+ return JSON.stringify(sortedContext);
9147
+ }
8759
9148
  var anonymousIdKey = "schematicId";
8760
9149
  var Schematic = class {
8761
9150
  apiKey;
8762
9151
  apiUrl = "https://api.schematichq.com";
8763
- webSocketUrl = "wss://api.schematichq.com";
8764
- eventUrl = "https://c.schematichq.com";
8765
9152
  conn = null;
8766
9153
  context = {};
8767
9154
  eventQueue;
9155
+ eventUrl = "https://c.schematichq.com";
9156
+ flagListener;
9157
+ flagValueListeners = {};
9158
+ isPending = true;
9159
+ isPendingListeners = /* @__PURE__ */ new Set();
8768
9160
  storage;
8769
9161
  useWebSocket = false;
8770
9162
  values = {};
8771
- flagListener;
9163
+ webSocketUrl = "wss://api.schematichq.com";
8772
9164
  constructor(apiKey, options) {
8773
9165
  this.apiKey = apiKey;
8774
9166
  this.eventQueue = [];
@@ -8788,12 +9180,14 @@ var Schematic = class {
8788
9180
  if (options?.webSocketUrl !== void 0) {
8789
9181
  this.webSocketUrl = options.webSocketUrl;
8790
9182
  }
8791
- if (window?.addEventListener) {
9183
+ if (typeof window !== "undefined" && window?.addEventListener) {
8792
9184
  window.addEventListener("beforeunload", () => {
8793
9185
  this.flushEventQueue();
8794
9186
  });
8795
9187
  }
8796
9188
  }
9189
+ // Get value for a single flag
9190
+ // If in websocket mode, return the local value, otherwise make an API call
8797
9191
  async checkFlag(options) {
8798
9192
  const { fallback = false, key } = options;
8799
9193
  const context = options.context || this.context;
@@ -8821,7 +9215,7 @@ var Schematic = class {
8821
9215
  return fallback;
8822
9216
  });
8823
9217
  }
8824
- // Make a REST API call to fetch all flag values for a given context
9218
+ // Make an API call to fetch all flag values for a given context (use if not in websocket mode)
8825
9219
  checkFlags = async (context) => {
8826
9220
  context = context || this.context;
8827
9221
  const requestUrl = `${this.apiUrl}/flags/check`;
@@ -8851,18 +9245,6 @@ var Schematic = class {
8851
9245
  return false;
8852
9246
  });
8853
9247
  };
8854
- cleanup = async () => {
8855
- if (this.conn) {
8856
- try {
8857
- const socket = await this.conn;
8858
- socket.close();
8859
- } catch (error) {
8860
- console.error("Error during cleanup:", error);
8861
- } finally {
8862
- this.conn = null;
8863
- }
8864
- }
8865
- };
8866
9248
  // Send an identify event
8867
9249
  identify = (body) => {
8868
9250
  this.setContext({
@@ -8880,12 +9262,16 @@ var Schematic = class {
8880
9262
  this.context = context;
8881
9263
  return Promise.resolve();
8882
9264
  }
8883
- if (!this.conn) {
8884
- this.conn = this.wsConnect();
9265
+ try {
9266
+ this.setIsPending(true);
9267
+ if (!this.conn) {
9268
+ this.conn = this.wsConnect();
9269
+ }
9270
+ const socket = await this.conn;
9271
+ await this.wsSendMessage(socket, context);
9272
+ } catch (error) {
9273
+ console.error("Error setting Schematic context:", error);
8885
9274
  }
8886
- return this.conn.then((socket) => {
8887
- return this.wsSendMessage(socket, context);
8888
- });
8889
9275
  };
8890
9276
  // Send track event
8891
9277
  track = (body) => {
@@ -8897,6 +9283,9 @@ var Schematic = class {
8897
9283
  user: user ?? this.context.user
8898
9284
  });
8899
9285
  };
9286
+ /**
9287
+ * Event processing
9288
+ */
8900
9289
  flushEventQueue = () => {
8901
9290
  while (this.eventQueue.length > 0) {
8902
9291
  const event = this.eventQueue.shift();
@@ -8952,6 +9341,22 @@ var Schematic = class {
8952
9341
  this.eventQueue.push(event);
8953
9342
  return Promise.resolve();
8954
9343
  };
9344
+ /**
9345
+ * Websocket management
9346
+ */
9347
+ cleanup = async () => {
9348
+ if (this.conn) {
9349
+ try {
9350
+ const socket = await this.conn;
9351
+ socket.close();
9352
+ } catch (error) {
9353
+ console.error("Error during cleanup:", error);
9354
+ } finally {
9355
+ this.conn = null;
9356
+ }
9357
+ }
9358
+ };
9359
+ // Open a websocket connection
8955
9360
  wsConnect = () => {
8956
9361
  return new Promise((resolve, reject) => {
8957
9362
  const wsUrl = `${this.webSocketUrl}/flags/bootstrap`;
@@ -8967,6 +9372,8 @@ var Schematic = class {
8967
9372
  };
8968
9373
  });
8969
9374
  };
9375
+ // Send a message on the websocket indicating interest in a particular evaluation context
9376
+ // and wait for the initial set of flag values to be returned
8970
9377
  wsSendMessage = (socket, context) => {
8971
9378
  return new Promise((resolve, reject) => {
8972
9379
  if (contextString(context) == contextString(this.context)) {
@@ -8984,16 +9391,17 @@ var Schematic = class {
8984
9391
  (message.flags ?? []).forEach(
8985
9392
  (flag) => {
8986
9393
  this.values[contextString(context)][flag.flag] = flag.value;
9394
+ this.notifyFlagValueListeners(flag.flag);
8987
9395
  }
8988
9396
  );
8989
9397
  if (this.flagListener) {
8990
- this.flagListener(this.values[contextString(context)]);
9398
+ this.flagListener(this.getFlagValues());
8991
9399
  }
9400
+ this.setIsPending(false);
8992
9401
  if (!resolved) {
8993
9402
  resolved = true;
8994
9403
  resolve();
8995
9404
  }
8996
- socket.removeEventListener("message", messageHandler);
8997
9405
  };
8998
9406
  socket.addEventListener("message", messageHandler);
8999
9407
  socket.send(
@@ -9012,119 +9420,157 @@ var Schematic = class {
9012
9420
  }
9013
9421
  });
9014
9422
  };
9423
+ /**
9424
+ * State management
9425
+ */
9426
+ // isPending state
9427
+ getIsPending = () => {
9428
+ return this.isPending;
9429
+ };
9430
+ addIsPendingListener = (listener) => {
9431
+ this.isPendingListeners.add(listener);
9432
+ return () => {
9433
+ this.isPendingListeners.delete(listener);
9434
+ };
9435
+ };
9436
+ setIsPending = (isPending) => {
9437
+ this.isPending = isPending;
9438
+ this.isPendingListeners.forEach((listener) => listener());
9439
+ };
9440
+ // flagValues state
9441
+ getFlagValue = (flagKey) => {
9442
+ const values = this.getFlagValues();
9443
+ return values[flagKey];
9444
+ };
9445
+ getFlagValues = () => {
9446
+ const contextStr = contextString(this.context);
9447
+ return this.values[contextStr] ?? {};
9448
+ };
9449
+ addFlagValueListener = (flagKey, listener) => {
9450
+ if (!(flagKey in this.flagValueListeners)) {
9451
+ this.flagValueListeners[flagKey] = /* @__PURE__ */ new Set();
9452
+ }
9453
+ this.flagValueListeners[flagKey].add(listener);
9454
+ return () => {
9455
+ this.flagValueListeners[flagKey].delete(listener);
9456
+ };
9457
+ };
9458
+ notifyFlagValueListeners = (flagKey) => {
9459
+ const listeners = this.flagValueListeners?.[flagKey] ?? [];
9460
+ listeners.forEach((listener) => listener());
9461
+ };
9015
9462
  };
9016
- function contextString(context) {
9017
- const sortedContext = Object.keys(context).reduce((acc, key) => {
9018
- const sortedKeys = Object.keys(
9019
- context[key] || {}
9020
- ).sort();
9021
- const sortedObj = sortedKeys.reduce((obj, sortedKey) => {
9022
- obj[sortedKey] = context[key][sortedKey];
9023
- return obj;
9024
- }, {});
9025
- acc[key] = sortedObj;
9026
- return acc;
9027
- }, {});
9028
- return JSON.stringify(sortedContext);
9029
- }
9030
9463
 
9031
9464
  // src/context/schematic.tsx
9032
- import { createContext as createContext2, useEffect as useEffect2, useMemo, useState as useState2 } from "react";
9465
+ import React, { createContext as createContext2, useEffect as useEffect2, useMemo } from "react";
9033
9466
  import { jsx as jsx2 } from "react/jsx-runtime";
9034
- var SchematicContext = createContext2({
9035
- flagValues: {}
9036
- });
9467
+ var SchematicContext = createContext2(
9468
+ null
9469
+ );
9037
9470
  var SchematicProvider = ({
9038
9471
  children,
9039
9472
  client: providedClient,
9040
9473
  publishableKey,
9041
9474
  ...clientOpts
9042
9475
  }) => {
9043
- const [client, setClient] = useState2();
9044
- const [flagValues, setFlagValues] = useState2({});
9045
- const memoizedClientOpts = useMemo(
9046
- () => clientOpts,
9047
- /* eslint-disable-next-line react-hooks/exhaustive-deps */
9048
- [JSON.stringify(clientOpts)]
9049
- );
9050
- const { useWebSocket = true } = clientOpts;
9051
- useEffect2(() => {
9052
- let cleanupFunction;
9476
+ const client = useMemo(() => {
9477
+ const { useWebSocket = true } = clientOpts;
9053
9478
  if (providedClient) {
9054
- setClient(providedClient);
9055
- cleanupFunction = () => {
9056
- providedClient.cleanup().catch((error) => {
9057
- console.error("Error during cleanup:", error);
9058
- });
9059
- };
9060
- } else {
9061
- const newClient = new Schematic(publishableKey, {
9062
- ...memoizedClientOpts,
9063
- flagListener: setFlagValues,
9064
- useWebSocket
9065
- });
9066
- setClient(newClient);
9067
- cleanupFunction = () => {
9068
- newClient.cleanup().catch((error) => {
9479
+ return providedClient;
9480
+ }
9481
+ return new Schematic(publishableKey, {
9482
+ useWebSocket,
9483
+ ...clientOpts
9484
+ });
9485
+ }, [providedClient, publishableKey, clientOpts]);
9486
+ useEffect2(() => {
9487
+ return () => {
9488
+ if (!providedClient) {
9489
+ client.cleanup().catch((error) => {
9069
9490
  console.error("Error during cleanup:", error);
9070
9491
  });
9071
- };
9072
- }
9073
- return cleanupFunction;
9074
- }, [memoizedClientOpts, providedClient, publishableKey, useWebSocket]);
9075
- const contextValue = {
9076
- client,
9077
- flagValues
9078
- };
9492
+ }
9493
+ };
9494
+ }, [client, providedClient]);
9495
+ const contextValue = useMemo(
9496
+ () => ({
9497
+ client
9498
+ }),
9499
+ [client]
9500
+ );
9079
9501
  return /* @__PURE__ */ jsx2(SchematicContext.Provider, { value: contextValue, children });
9080
9502
  };
9503
+ var useSchematic = () => {
9504
+ const context = React.useContext(SchematicContext);
9505
+ if (context === null) {
9506
+ throw new Error("useSchematic must be used within a SchematicProvider");
9507
+ }
9508
+ return context;
9509
+ };
9081
9510
 
9082
9511
  // src/hooks/embed.ts
9083
9512
  import { useContext } from "react";
9084
9513
  var useEmbed = () => useContext(EmbedContext);
9085
9514
 
9086
9515
  // src/hooks/schematic.ts
9087
- import { useContext as useContext2, useEffect as useEffect3, useState as useState3 } from "react";
9088
- var useSchematic = () => useContext2(SchematicContext);
9516
+ import { useMemo as useMemo2, useSyncExternalStore, useCallback as useCallback2 } from "react";
9089
9517
  var useSchematicClient = (opts) => {
9090
9518
  const schematic = useSchematic();
9091
9519
  const { client } = opts ?? {};
9092
- if (client) {
9093
- return client;
9094
- }
9095
- return schematic.client;
9520
+ return useMemo2(() => {
9521
+ if (client) {
9522
+ return client;
9523
+ }
9524
+ return schematic.client;
9525
+ }, [client, schematic.client]);
9096
9526
  };
9097
9527
  var useSchematicContext = (opts) => {
9098
9528
  const client = useSchematicClient(opts);
9099
- const { setContext } = client ?? {};
9100
- return { setContext };
9529
+ return useMemo2(
9530
+ () => ({
9531
+ setContext: client.setContext.bind(client)
9532
+ }),
9533
+ [client]
9534
+ );
9101
9535
  };
9102
9536
  var useSchematicEvents = (opts) => {
9103
9537
  const client = useSchematicClient(opts);
9104
- const { track, identify } = client ?? {};
9105
- return { track, identify };
9538
+ const track = useCallback2(
9539
+ (...args) => client.track(...args),
9540
+ [client]
9541
+ );
9542
+ const identify = useCallback2(
9543
+ (...args) => client.identify(...args),
9544
+ [client]
9545
+ );
9546
+ return useMemo2(() => ({ track, identify }), [track, identify]);
9106
9547
  };
9107
9548
  var useSchematicFlag = (key, opts) => {
9108
- const { flagValues } = useSchematic();
9109
- const { client } = opts ?? {};
9110
- const { fallback = false } = opts ?? {};
9111
- const [value, setValue] = useState3(fallback);
9112
- const flagValue = flagValues[key];
9113
- useEffect3(() => {
9114
- if (typeof flagValue !== "undefined") {
9115
- setValue(flagValue);
9116
- } else if (client) {
9117
- client.checkFlag({ key, fallback }).then(setValue);
9118
- } else {
9119
- setValue(fallback);
9120
- }
9121
- }, [key, fallback, flagValue, client]);
9122
- return value;
9549
+ const client = useSchematicClient(opts);
9550
+ const fallback = opts?.fallback ?? false;
9551
+ const subscribe = useCallback2(
9552
+ (callback) => client.addFlagValueListener(key, callback),
9553
+ [client, key]
9554
+ );
9555
+ const getSnapshot = useCallback2(() => {
9556
+ const value = client.getFlagValue(key);
9557
+ return typeof value === "undefined" ? fallback : value;
9558
+ }, [client, key, fallback]);
9559
+ return useSyncExternalStore(subscribe, getSnapshot);
9560
+ };
9561
+ var useSchematicIsPending = (opts) => {
9562
+ const client = useSchematicClient(opts);
9563
+ const subscribe = useCallback2(
9564
+ (callback) => client.addIsPendingListener(callback),
9565
+ [client]
9566
+ );
9567
+ const getSnapshot = useCallback2(() => client.getIsPending(), [client]);
9568
+ return useSyncExternalStore(subscribe, getSnapshot);
9123
9569
  };
9124
9570
 
9125
9571
  // src/components/elements/plan-manager/PlanManager.tsx
9126
- import { forwardRef, useMemo as useMemo3 } from "react";
9127
- import { createPortal } from "react-dom";
9572
+ import { forwardRef as forwardRef2, useMemo as useMemo7 } from "react";
9573
+ import { createPortal as createPortal2 } from "react-dom";
9128
9574
 
9129
9575
  // src/utils/color.ts
9130
9576
  function hexToHSL(color) {
@@ -9205,7 +9651,7 @@ function hslToHex({ h, s: s2, l: l2 }) {
9205
9651
  }
9206
9652
  function adjustLightness(color, amount) {
9207
9653
  const { h, s: s2, l: l2 } = hexToHSL(color);
9208
- return hslToHex({ h, s: s2, l: Math.max(Math.min(l2 + amount, 100), 0) });
9654
+ return hslToHex({ h, s: s2, l: Math.max(Math.min(l2 + amount * 100, 100), 0) });
9209
9655
  }
9210
9656
  function lighten(color, amount) {
9211
9657
  return adjustLightness(color, amount);
@@ -9435,6 +9881,7 @@ var Container = dt.div`
9435
9881
  align-items: center;
9436
9882
  flex-shrink: 0;
9437
9883
  border-radius: 9999px;
9884
+
9438
9885
  ${({ $size }) => {
9439
9886
  const base = 24;
9440
9887
  let scale = 1;
@@ -9452,6 +9899,15 @@ var Container = dt.div`
9452
9899
  case "lg":
9453
9900
  scale *= 1.75;
9454
9901
  break;
9902
+ case "xl":
9903
+ scale *= 2;
9904
+ break;
9905
+ case "2xl":
9906
+ scale *= 2.5;
9907
+ break;
9908
+ case "3xl":
9909
+ scale *= 3;
9910
+ break;
9455
9911
  }
9456
9912
  return lt`
9457
9913
  font-size: ${base * scale / TEXT_BASE_SIZE}rem;
@@ -9460,12 +9916,19 @@ var Container = dt.div`
9460
9916
  height: ${(base + 8) * scale / TEXT_BASE_SIZE}rem;
9461
9917
  `;
9462
9918
  }}
9919
+
9463
9920
  ${({ $variant, $colors }) => $variant === "outline" ? lt`
9464
- color: ${$colors[0]};
9465
9921
  background-color: transparent;
9922
+
9923
+ ${Icon} {
9924
+ color: ${$colors[0]};
9925
+ }
9466
9926
  ` : lt`
9467
- color: ${$colors[0]};
9468
9927
  background-color: ${$colors[1]};
9928
+
9929
+ ${Icon} {
9930
+ color: ${$colors[0]};
9931
+ }
9469
9932
  `}
9470
9933
  `;
9471
9934
 
@@ -9487,18 +9950,40 @@ var IconRound = ({
9487
9950
  return /* @__PURE__ */ jsx5(Container, { $size: size, $variant: variant, $colors: colors, ...props, children: /* @__PURE__ */ jsx5(Icon2, { name }) });
9488
9951
  };
9489
9952
 
9490
- // src/components/ui/modal/Modal.tsx
9491
- import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef2 } from "react";
9492
- import { jsx as jsx6 } from "react/jsx-runtime";
9493
- var Modal = ({ children, onClose }) => {
9494
- const theme = nt();
9495
- const { setLayout } = useEmbed();
9496
- const ref = useRef2(null);
9497
- const handleClose = useCallback2(() => {
9498
- setLayout("portal");
9499
- onClose?.();
9953
+ // src/components/ui/loader/styles.ts
9954
+ var spin = mt`
9955
+ 0% {
9956
+ transform: rotate(0deg);
9957
+ }
9958
+ 100% {
9959
+ transform: rotate(360deg);
9960
+ }
9961
+ `;
9962
+ var Loader = dt.div`
9963
+ border: ${4 / TEXT_BASE_SIZE}rem solid hsla(0, 0%, 50%, 0.125);
9964
+ border-top: ${4 / TEXT_BASE_SIZE}rem solid ${({ theme }) => theme.secondary};
9965
+ border-radius: 50%;
9966
+ width: ${56 / TEXT_BASE_SIZE}rem;
9967
+ height: ${56 / TEXT_BASE_SIZE}rem;
9968
+ animation: ${spin} 1.5s linear infinite;
9969
+ display: inline-block;
9970
+ `;
9971
+
9972
+ // src/components/ui/modal/Modal.tsx
9973
+ import { useCallback as useCallback3, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef2 } from "react";
9974
+ import { jsx as jsx6 } from "react/jsx-runtime";
9975
+ var Modal = ({ children, size = "auto", onClose }) => {
9976
+ const theme = nt();
9977
+ const { setLayout } = useEmbed();
9978
+ const ref = useRef2(null);
9979
+ const isLightBackground = useMemo3(() => {
9980
+ return hexToHSL(theme.card.background).l > 50;
9981
+ }, [theme.card.background]);
9982
+ const handleClose = useCallback3(() => {
9983
+ setLayout("portal");
9984
+ onClose?.();
9500
9985
  }, [setLayout, onClose]);
9501
- useEffect4(() => {
9986
+ useEffect3(() => {
9502
9987
  ref.current?.focus();
9503
9988
  }, []);
9504
9989
  return /* @__PURE__ */ jsx6(
@@ -9523,7 +10008,7 @@ var Modal = ({ children, onClose }) => {
9523
10008
  $transform: "translate(-50%, -50%)",
9524
10009
  $width: "100%",
9525
10010
  $height: "100%",
9526
- $backgroundColor: hexToHSL(theme.card.background).l > 50 ? darken(theme.card.background, 15) : lighten(theme.card.background, 15),
10011
+ $backgroundColor: isLightBackground ? "hsla(0, 0%, 85%, 0.8)" : "hsla(0, 0%, 15%, 0.8)",
9527
10012
  $overflow: "hidden",
9528
10013
  children: /* @__PURE__ */ jsx6(
9529
10014
  Flex,
@@ -9534,9 +10019,13 @@ var Modal = ({ children, onClose }) => {
9534
10019
  $transform: "translate(-50%, -50%)",
9535
10020
  $flexDirection: "column",
9536
10021
  $overflow: "hidden",
9537
- $width: "calc(100% - 5rem)",
9538
- $height: "calc(100% - 5rem)",
9539
- $backgroundColor: hexToHSL(theme.card.background).l > 50 ? darken(theme.card.background, 2.5) : lighten(theme.card.background, 2.5),
10022
+ ...size === "auto" ? { $width: "min-content", $height: "min-content" } : {
10023
+ $width: "100%",
10024
+ $height: "100%",
10025
+ $maxWidth: "1366px",
10026
+ $maxHeight: "768px"
10027
+ },
10028
+ $backgroundColor: theme.card.background,
9540
10029
  $borderRadius: "0.5rem",
9541
10030
  $boxShadow: "0px 1px 20px 0px #1018280F, 0px 1px 3px 0px #1018281A;",
9542
10031
  id: "select-plan-dialog",
@@ -9551,27 +10040,36 @@ var Modal = ({ children, onClose }) => {
9551
10040
  };
9552
10041
 
9553
10042
  // src/components/ui/modal/ModalHeader.tsx
9554
- import { useCallback as useCallback3 } from "react";
10043
+ import { useCallback as useCallback4, useMemo as useMemo4 } from "react";
9555
10044
  import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
9556
- var ModalHeader = ({ children, onClose }) => {
10045
+ var ModalHeader = ({
10046
+ children,
10047
+ bordered = false,
10048
+ onClose
10049
+ }) => {
9557
10050
  const theme = nt();
9558
10051
  const { setLayout } = useEmbed();
9559
- const handleClose = useCallback3(() => {
10052
+ const isLightBackground = useMemo4(() => {
10053
+ return hexToHSL(theme.card.background).l > 50;
10054
+ }, [theme.card.background]);
10055
+ const handleClose = useCallback4(() => {
9560
10056
  setLayout("portal");
9561
10057
  onClose?.();
9562
10058
  }, [setLayout, onClose]);
9563
10059
  return /* @__PURE__ */ jsxs2(
9564
10060
  Flex,
9565
10061
  {
9566
- $justifyContent: "space-between",
10062
+ $justifyContent: children ? "space-between" : "end",
9567
10063
  $alignItems: "center",
10064
+ $flexShrink: "0",
9568
10065
  $gap: "1rem",
9569
- $height: "3.75rem",
9570
- $padding: "0 0.625rem 0 2.5rem",
9571
- $backgroundColor: theme.card.background,
9572
- $borderBottomWidth: "1px",
9573
- $borderBottomStyle: "solid",
9574
- $borderBottomColor: hexToHSL(theme.card.background).l > 50 ? darken(theme.card.background, 15) : lighten(theme.card.background, 15),
10066
+ $height: "5rem",
10067
+ $padding: "0 1.5rem 0 3rem",
10068
+ ...bordered && {
10069
+ $borderBottomWidth: "1px",
10070
+ $borderBottomStyle: "solid",
10071
+ $borderBottomColor: isLightBackground ? "hsla(0, 0%, 0%, 0.15)" : "hsla(0, 0%, 100%, 0.15)"
10072
+ },
9575
10073
  children: [
9576
10074
  children,
9577
10075
  /* @__PURE__ */ jsx7(Box, { $cursor: "pointer", onClick: handleClose, children: /* @__PURE__ */ jsx7(
@@ -9580,7 +10078,7 @@ var ModalHeader = ({ children, onClose }) => {
9580
10078
  name: "close",
9581
10079
  style: {
9582
10080
  fontSize: 36,
9583
- color: hexToHSL(theme.card.background).l > 50 ? darken(theme.card.background, 27.5) : lighten(theme.card.background, 27.5)
10081
+ color: isLightBackground ? "hsla(0, 0%, 0%, 0.275)" : "hsla(0, 0%, 100%, 0.275)"
9584
10082
  }
9585
10083
  }
9586
10084
  ) })
@@ -9632,14 +10130,14 @@ var ProgressBar = ({
9632
10130
  $overflow: "hidden",
9633
10131
  $width: "100%",
9634
10132
  $height: `${8 / TEXT_BASE_SIZE}rem`,
9635
- $background: "#F2F4F7",
10133
+ $backgroundColor: "#F2F4F7",
9636
10134
  $borderRadius: "9999px",
9637
10135
  children: /* @__PURE__ */ jsx8(
9638
10136
  Box,
9639
10137
  {
9640
10138
  $width: `${Math.min(progress, 100)}%`,
9641
10139
  $height: "100%",
9642
- $background: barColorMap[color],
10140
+ $backgroundColor: barColorMap[color],
9643
10141
  $borderRadius: "9999px"
9644
10142
  }
9645
10143
  )
@@ -9658,15 +10156,12 @@ var ProgressBar = ({
9658
10156
  };
9659
10157
 
9660
10158
  // src/components/elements/plan-manager/CheckoutDialog.tsx
9661
- import { useMemo as useMemo2, useState as useState5 } from "react";
10159
+ import { useMemo as useMemo6, useState as useState3 } from "react";
10160
+ var import_pluralize = __toESM(require_pluralize());
9662
10161
 
9663
- // src/components/elements/plan-manager/PaymentForm.tsx
9664
- import { useState as useState4 } from "react";
9665
- import {
9666
- LinkAuthenticationElement,
9667
- PaymentElement
9668
- } from "@stripe/react-stripe-js";
9669
- import { useStripe, useElements } from "@stripe/react-stripe-js";
10162
+ // src/components/elements/payment-method/PaymentMethod.tsx
10163
+ import { forwardRef, useMemo as useMemo5 } from "react";
10164
+ import { createPortal } from "react-dom";
9670
10165
 
9671
10166
  // src/components/elements/plan-manager/styles.ts
9672
10167
  var StyledButton = dt(Button2)`
@@ -9702,7 +10197,7 @@ var StyledButton = dt(Button2)`
9702
10197
  if (disabled) {
9703
10198
  const { l: l2 } = hexToHSL(theme.card.background);
9704
10199
  color = hslToHex({ h: 0, s: 0, l: l2 });
9705
- color = l2 > 50 ? darken(color, 7.5) : lighten(color, 7.5);
10200
+ color = l2 > 50 ? darken(color, 0.075) : lighten(color, 0.15);
9706
10201
  }
9707
10202
  return $variant === "filled" ? lt`
9708
10203
  background-color: ${color};
@@ -9725,8 +10220,8 @@ var StyledButton = dt(Button2)`
9725
10220
  &:not(:disabled):hover {
9726
10221
  ${({ $color = "primary", theme, $variant = "filled" }) => {
9727
10222
  const specified = theme[$color];
9728
- const lightened = lighten(specified, 15);
9729
- const color = specified === lightened ? darken(specified, 15) : lightened;
10223
+ const lightened = lighten(specified, 0.15);
10224
+ const color = specified === lightened ? darken(specified, 0.15) : lightened;
9730
10225
  const { l: l2 } = hexToHSL(theme[$color]);
9731
10226
  const textColor = l2 > 50 ? "#000000" : "#FFFFFF";
9732
10227
  return $variant === "filled" ? lt`
@@ -9748,1481 +10243,1696 @@ var StyledButton = dt(Button2)`
9748
10243
  switch ($size) {
9749
10244
  case "sm":
9750
10245
  return lt`
9751
- font-size: ${15 / 16}rem;
9752
- padding: ${12 / 16}rem 0;
9753
- border-radius: ${6 / 16}rem;
10246
+ font-size: ${15 / TEXT_BASE_SIZE}rem;
10247
+ padding: ${12 / TEXT_BASE_SIZE}rem 0;
10248
+ border-radius: ${6 / TEXT_BASE_SIZE}rem;
9754
10249
  `;
9755
10250
  case "md":
9756
10251
  return lt`
9757
- font-size: ${17 / 16}rem;
9758
- padding: ${16 / 16}rem 0;
9759
- border-radius: ${8 / 16}rem;
10252
+ font-size: ${17 / TEXT_BASE_SIZE}rem;
10253
+ padding: ${16 / TEXT_BASE_SIZE}rem 0;
10254
+ border-radius: ${8 / TEXT_BASE_SIZE}rem;
9760
10255
  `;
9761
10256
  case "lg":
9762
10257
  return lt`
9763
- font-size: ${19 / 16}rem;
9764
- padding: ${20 / 16}rem 0;
9765
- border-radius: ${10 / 16}rem;
10258
+ font-size: ${19 / TEXT_BASE_SIZE}rem;
10259
+ padding: ${20 / TEXT_BASE_SIZE}rem 0;
10260
+ border-radius: ${10 / TEXT_BASE_SIZE}rem;
9766
10261
  `;
9767
10262
  }
9768
10263
  }}
9769
10264
  `;
9770
10265
 
9771
- // src/components/elements/plan-manager/PaymentForm.tsx
10266
+ // src/components/elements/payment-method/PaymentMethod.tsx
9772
10267
  import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
9773
- var PaymentForm = ({ plan, period, onConfirm }) => {
9774
- const stripe = useStripe();
9775
- const elements = useElements();
9776
- const { api, data } = useEmbed();
9777
- const [message, setMessage] = useState4(null);
9778
- const [isLoading, setIsLoading] = useState4(false);
9779
- const [isConfirmed, setIsConfirmed] = useState4(false);
9780
- const handleSubmit = async (event) => {
9781
- event.preventDefault();
9782
- const priceId = period === "month" ? plan.monthlyPrice?.id : plan.yearlyPrice?.id;
9783
- if (!api || !stripe || !elements || !priceId) {
9784
- return;
9785
- }
9786
- setIsLoading(true);
9787
- setIsConfirmed(false);
9788
- try {
9789
- const { setupIntent, error } = await stripe.confirmSetup({
9790
- elements,
9791
- confirmParams: {
9792
- return_url: window.location.href
9793
- },
9794
- redirect: "if_required"
9795
- });
9796
- if (onConfirm && typeof setupIntent?.payment_method === "string") {
9797
- onConfirm(setupIntent.payment_method);
9798
- setIsConfirmed(true);
9799
- } else {
9800
- }
9801
- if (error?.type === "card_error" || error?.type === "validation_error") {
9802
- setMessage(error.message);
9803
- }
9804
- setIsLoading(false);
9805
- } catch (error) {
9806
- if (error instanceof Error) {
9807
- setMessage(error.message);
9808
- } else {
9809
- setMessage("An unexpected error occured.");
9810
- }
9811
- setIsLoading(false);
10268
+ var resolveDesignProps = (props) => {
10269
+ return {
10270
+ header: {
10271
+ isVisible: props.header?.isVisible ?? true,
10272
+ fontStyle: props.header?.fontStyle ?? "heading4"
10273
+ },
10274
+ functions: {
10275
+ allowEdit: props.functions?.allowEdit ?? true
9812
10276
  }
9813
10277
  };
9814
- return /* @__PURE__ */ jsxs4(
9815
- "form",
9816
- {
9817
- id: "payment-form",
9818
- onSubmit: handleSubmit,
9819
- style: {
9820
- display: "flex",
9821
- flexDirection: "column",
9822
- height: "100%",
9823
- overflowX: "hidden",
9824
- overflowY: "auto"
9825
- },
9826
- children: [
9827
- /* @__PURE__ */ jsx9(Box, { $width: "100%", $marginBottom: "1.5rem", children: /* @__PURE__ */ jsx9(Text, { $size: 18, children: "Add payment method" }) }),
9828
- /* @__PURE__ */ jsx9(
9829
- Flex,
9830
- {
9831
- $flexDirection: "column",
9832
- $gap: "1.5rem",
9833
- $marginBottom: "1.5rem",
9834
- $width: "100%",
9835
- children: /* @__PURE__ */ jsx9(
9836
- LinkAuthenticationElement,
9837
- {
9838
- id: "link-authentication-element"
9839
- }
9840
- )
9841
- }
9842
- ),
9843
- /* @__PURE__ */ jsxs4(Flex, { $flexDirection: "column", $width: "100%", $flex: "1", $height: "100%", children: [
9844
- /* @__PURE__ */ jsx9(PaymentElement, { id: "payment-element" }),
9845
- message && /* @__PURE__ */ jsx9(Text, { id: "payment-message", children: message })
9846
- ] }),
9847
- /* @__PURE__ */ jsx9("div", { children: /* @__PURE__ */ jsx9(
9848
- StyledButton,
9849
- {
9850
- id: "submit",
9851
- disabled: isLoading || !stripe || !elements || !data.stripeEmbed?.publishableKey || !data.stripeEmbed?.setupIntentClientSecret || isConfirmed,
9852
- $size: "md",
9853
- $color: "primary",
9854
- children: /* @__PURE__ */ jsx9(Text, { id: "button-text", children: !isLoading ? "Loading" : "Save payment method" })
9855
- }
9856
- ) })
9857
- ]
9858
- }
9859
- );
9860
10278
  };
9861
-
9862
- // src/components/elements/plan-manager/CheckoutDialog.tsx
9863
- import { Fragment, jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
9864
- var CheckoutDialog = () => {
9865
- const [checkoutStage, setCheckoutStage] = useState5(
9866
- "plan"
9867
- );
9868
- const [planPeriod, setPlanPeriod] = useState5("month");
9869
- const [selectedPlan, setSelectedPlan] = useState5();
9870
- const [paymentMethodId, setPaymentMethodId] = useState5();
9871
- const [isLoading, setIsLoading] = useState5(false);
9872
- const [isCheckoutComplete, setIsCheckoutComplete] = useState5(false);
10279
+ var PaymentMethod = forwardRef(({ children, className, portal, ...rest }, ref) => {
10280
+ const props = resolveDesignProps(rest);
9873
10281
  const theme = nt();
9874
- const { api, data, settings } = useEmbed();
9875
- const { currentPlan, availablePlans } = useMemo2(() => {
10282
+ const { data, layout } = useEmbed();
10283
+ const paymentMethod = useMemo5(() => {
10284
+ const { paymentMethodType, cardLast4, cardExpMonth, cardExpYear } = data.subscription?.paymentMethod || {};
10285
+ let monthsToExpiration;
10286
+ if (typeof cardExpYear === "number" && typeof cardExpMonth === "number") {
10287
+ const today = /* @__PURE__ */ new Date();
10288
+ const currentYear = today.getFullYear();
10289
+ const currentMonth = today.getMonth();
10290
+ const timeToExpiration = Math.round(
10291
+ +new Date(cardExpYear, cardExpMonth - 1) - +new Date(currentYear, currentMonth)
10292
+ );
10293
+ monthsToExpiration = Math.round(
10294
+ timeToExpiration / (1e3 * 60 * 60 * 24 * 30)
10295
+ );
10296
+ }
9876
10297
  return {
9877
- currentPlan: data.company?.plan,
9878
- availablePlans: data.activePlans
10298
+ paymentMethodType,
10299
+ cardLast4,
10300
+ monthsToExpiration
9879
10301
  };
9880
- }, [data.company, data.activePlans]);
9881
- const savingsPercentage = useMemo2(() => {
9882
- if (selectedPlan) {
9883
- const monthly = (selectedPlan?.monthlyPrice?.price || 0) * 12;
9884
- const yearly = selectedPlan?.yearlyPrice?.price || 0;
9885
- return Math.round((monthly - yearly) / monthly * 1e4) / 100;
9886
- }
9887
- return 0;
9888
- }, [selectedPlan]);
9889
- return /* @__PURE__ */ jsxs5(Modal, { children: [
9890
- /* @__PURE__ */ jsx10(ModalHeader, { children: /* @__PURE__ */ jsx10(Flex, { $gap: "1rem", children: !isCheckoutComplete && /* @__PURE__ */ jsxs5(Fragment, { children: [
9891
- /* @__PURE__ */ jsxs5(Flex, { $gap: "0.5rem", $alignItems: "center", children: [
9892
- checkoutStage === "plan" ? /* @__PURE__ */ jsx10(
9893
- Box,
9894
- {
9895
- $width: "0.9375rem",
9896
- $height: "0.9375rem",
9897
- $borderWidth: "2px",
9898
- $borderStyle: "solid",
9899
- $borderColor: hexToHSL(theme.card.background).l > 50 ? darken(theme.card.background, 12.5) : lighten(theme.card.background, 12.5),
9900
- $borderRadius: "9999px"
9901
- }
9902
- ) : /* @__PURE__ */ jsx10(
9903
- IconRound,
9904
- {
9905
- name: "check",
9906
- style: {
9907
- color: theme.card.background,
9908
- backgroundColor: hexToHSL(theme.card.background).l > 50 ? darken(theme.card.background, 12.5) : lighten(theme.card.background, 12.5),
9909
- fontSize: 16,
9910
- width: "1rem",
9911
- height: "1rem"
10302
+ }, [data.subscription?.paymentMethod]);
10303
+ const isLightBackground = useMemo5(() => {
10304
+ return hexToHSL(theme.card.background).l > 50;
10305
+ }, [theme.card.background]);
10306
+ if (!paymentMethod.paymentMethodType) {
10307
+ return null;
10308
+ }
10309
+ return /* @__PURE__ */ jsxs4("div", { ref, className, children: [
10310
+ props.header.isVisible && /* @__PURE__ */ jsxs4(
10311
+ Flex,
10312
+ {
10313
+ $justifyContent: "space-between",
10314
+ $alignItems: "center",
10315
+ $margin: "0 0 1rem",
10316
+ children: [
10317
+ /* @__PURE__ */ jsx9(
10318
+ Text,
10319
+ {
10320
+ $font: theme.typography[props.header.fontStyle].fontFamily,
10321
+ $size: theme.typography[props.header.fontStyle].fontSize,
10322
+ $weight: theme.typography[props.header.fontStyle].fontWeight,
10323
+ $color: theme.typography[props.header.fontStyle].color,
10324
+ children: "Payment Method"
9912
10325
  }
9913
- }
9914
- ),
9915
- /* @__PURE__ */ jsx10(
9916
- Box,
9917
- {
9918
- tabIndex: 0,
9919
- ...checkoutStage === "plan" ? {
9920
- style: {
9921
- fontWeight: "700"
9922
- }
9923
- } : {
9924
- style: {
9925
- cursor: "pointer"
9926
- },
9927
- onClick: () => setCheckoutStage("plan")
9928
- },
9929
- children: /* @__PURE__ */ jsx10(Text, { children: "1. Select plan" })
9930
- }
9931
- ),
9932
- /* @__PURE__ */ jsx10(
9933
- Icon2,
9934
- {
9935
- name: "chevron-right",
9936
- style: {
9937
- fontSize: 16,
9938
- color: hexToHSL(theme.card.background).l > 50 ? darken(theme.card.background, 17.5) : lighten(theme.card.background, 17.5)
10326
+ ),
10327
+ typeof paymentMethod.monthsToExpiration === "number" && paymentMethod.monthsToExpiration < 4 && /* @__PURE__ */ jsx9(
10328
+ Text,
10329
+ {
10330
+ $font: theme.typography.text.fontFamily,
10331
+ $size: 14,
10332
+ $color: "#DB6769",
10333
+ children: paymentMethod.monthsToExpiration > 0 ? `Expires in ${paymentMethod.monthsToExpiration} mo` : "Expired"
9939
10334
  }
9940
- }
9941
- )
9942
- ] }),
9943
- /* @__PURE__ */ jsxs5(Flex, { $gap: "0.5rem", $alignItems: "center", children: [
9944
- /* @__PURE__ */ jsx10(
9945
- Box,
9946
- {
9947
- $width: "0.9375rem",
9948
- $height: "0.9375rem",
9949
- $borderWidth: "2px",
9950
- $borderStyle: "solid",
9951
- $borderColor: hexToHSL(theme.card.background).l > 50 ? darken(theme.card.background, 12.5) : lighten(theme.card.background, 12.5),
9952
- $borderRadius: "9999px"
9953
- }
9954
- ),
9955
- /* @__PURE__ */ jsx10(
9956
- Box,
9957
- {
9958
- tabIndex: 0,
9959
- ...checkoutStage === "checkout" && {
9960
- style: {
9961
- fontWeight: "700"
9962
- }
9963
- },
9964
- children: /* @__PURE__ */ jsx10(Text, { children: "2. Checkout" })
9965
- }
9966
- )
9967
- ] })
9968
- ] }) }) }),
9969
- isCheckoutComplete && /* @__PURE__ */ jsx10(Flex, { $justifyContent: "center", $alignItems: "center", $flexGrow: "1", children: /* @__PURE__ */ jsx10(
9970
- Text,
10335
+ )
10336
+ ]
10337
+ }
10338
+ ),
10339
+ /* @__PURE__ */ jsx9(
10340
+ Flex,
9971
10341
  {
9972
- as: "h1",
9973
- $font: theme.typography.heading1.fontFamily,
9974
- $size: theme.typography.heading1.fontSize,
9975
- $weight: theme.typography.heading1.fontWeight,
9976
- $color: theme.typography.heading1.color,
9977
- children: "Subscription updated!"
10342
+ $justifyContent: "space-between",
10343
+ $alignItems: "center",
10344
+ $margin: "0 0 1rem",
10345
+ $backgroundColor: isLightBackground ? "hsla(0, 0%, 0%, 0.0625)" : "hsla(0, 0%, 100%, 0.125)",
10346
+ $padding: "0.375rem 1rem",
10347
+ $borderRadius: "9999px",
10348
+ children: /* @__PURE__ */ jsx9(Text, { $font: theme.typography.text.fontFamily, $size: 14, children: paymentMethod.cardLast4 ? `\u{1F4B3} Card ending in ${paymentMethod.cardLast4}` : "Other existing payment method" })
9978
10349
  }
9979
- ) }),
9980
- !isCheckoutComplete && /* @__PURE__ */ jsxs5(Flex, { $position: "relative", $flexGrow: "1", children: [
9981
- /* @__PURE__ */ jsxs5(
9982
- Flex,
9983
- {
9984
- $position: "absolute",
9985
- $top: "0",
9986
- $left: "0",
9987
- $flexDirection: "column",
9988
- $gap: "1rem",
9989
- $padding: "2rem 2.5rem 2rem 2.5rem",
9990
- $backgroundColor: darken(settings.theme.card.background, 2.5),
9991
- $flex: "1",
9992
- $width: "72.5%",
9993
- $height: "100%",
9994
- $overflow: "auto",
9995
- children: [
9996
- checkoutStage === "plan" && /* @__PURE__ */ jsxs5(Fragment, { children: [
9997
- /* @__PURE__ */ jsxs5(Flex, { $flexDirection: "column", $gap: "1rem", $marginBottom: "1rem", children: [
9998
- /* @__PURE__ */ jsx10(
9999
- Text,
10000
- {
10001
- as: "h1",
10002
- id: "select-plan-dialog-label",
10003
- $size: 18,
10004
- $marginBottom: "0.5rem",
10005
- children: "Select plan"
10006
- }
10007
- ),
10008
- /* @__PURE__ */ jsx10(
10009
- Text,
10010
- {
10011
- as: "p",
10012
- id: "select-plan-dialog-description",
10013
- $size: 14,
10014
- $weight: 400,
10015
- children: "Choose your base plan"
10016
- }
10017
- )
10018
- ] }),
10019
- /* @__PURE__ */ jsx10(Flex, { $gap: "1rem", $flexGrow: "1", children: availablePlans?.map((plan) => {
10020
- return /* @__PURE__ */ jsxs5(
10021
- Flex,
10022
- {
10023
- $height: "100%",
10024
- $flexDirection: "column",
10025
- $backgroundColor: settings.theme.card.background,
10026
- $flex: "1",
10027
- $outlineWidth: "2px",
10028
- $outlineStyle: "solid",
10029
- $outlineColor: plan.id === selectedPlan?.id ? theme.primary : "transparent",
10030
- $borderRadius: `${settings.theme.card.borderRadius / 16}rem`,
10031
- ...settings.theme.card.hasShadow && {
10032
- $boxShadow: "0px 1px 3px rgba(16, 24, 40, 0.1), 0px 1px 20px rgba(16, 24, 40, 0.06)"
10033
- },
10034
- children: [
10035
- /* @__PURE__ */ jsxs5(
10036
- Flex,
10037
- {
10038
- $flexDirection: "column",
10039
- $position: "relative",
10040
- $gap: "1rem",
10041
- $width: "100%",
10042
- $height: "auto",
10043
- $padding: `${settings.theme.card.padding / 16}rem`,
10044
- $borderBottomWidth: "1px",
10045
- $borderStyle: "solid",
10046
- $borderColor: hexToHSL(theme.card.background).l > 50 ? darken(theme.card.background, 17.5) : lighten(theme.card.background, 17.5),
10047
- children: [
10048
- /* @__PURE__ */ jsx10(Text, { $size: 20, $weight: 600, children: plan.name }),
10049
- /* @__PURE__ */ jsx10(Text, { $size: 14, children: plan.description }),
10050
- /* @__PURE__ */ jsxs5(Text, { children: [
10051
- /* @__PURE__ */ jsx10(Box, { $display: "inline-block", $fontSize: "1.5rem", children: formatCurrency(
10052
- (planPeriod === "month" ? plan.monthlyPrice : plan.yearlyPrice)?.price ?? 0
10350
+ ),
10351
+ layout === "payment" && createPortal(
10352
+ /* @__PURE__ */ jsxs4(Modal, { size: "md", children: [
10353
+ /* @__PURE__ */ jsx9(ModalHeader, { children: /* @__PURE__ */ jsx9(Box, { $fontWeight: "600", children: "Edit payment method" }) }),
10354
+ /* @__PURE__ */ jsxs4(
10355
+ Flex,
10356
+ {
10357
+ $flexDirection: "column",
10358
+ $padding: "2.5rem",
10359
+ $height: "100%",
10360
+ $gap: "1.5rem",
10361
+ children: [
10362
+ /* @__PURE__ */ jsx9(
10363
+ Flex,
10364
+ {
10365
+ $flexDirection: "column",
10366
+ $gap: "1rem",
10367
+ $backgroundColor: "#FBFBFB",
10368
+ $borderRadius: "0 0 0.5rem 0.5rem",
10369
+ $flex: "1",
10370
+ $height: "100%",
10371
+ children: /* @__PURE__ */ jsxs4(Flex, { $flexDirection: "column", $height: "100%", children: [
10372
+ /* @__PURE__ */ jsx9(
10373
+ Box,
10374
+ {
10375
+ $fontSize: "18px",
10376
+ $marginBottom: "1.5rem",
10377
+ $display: "inline-block",
10378
+ $width: "100%",
10379
+ children: "Default"
10380
+ }
10381
+ ),
10382
+ /* @__PURE__ */ jsxs4(Flex, { $gap: "1rem", children: [
10383
+ /* @__PURE__ */ jsx9(
10384
+ Flex,
10385
+ {
10386
+ $alignItems: "center",
10387
+ $padding: ".5rem 1rem",
10388
+ $border: "1px solid #E2E5E9",
10389
+ $borderRadius: ".5rem",
10390
+ $backgroundColor: "#ffffff",
10391
+ $gap: "1rem",
10392
+ $width: "100%",
10393
+ children: /* @__PURE__ */ jsxs4(Flex, { $justifyContent: "space-between", $flex: "1", children: [
10394
+ /* @__PURE__ */ jsxs4(Flex, { $alignItems: "center", $gap: "1rem", children: [
10395
+ /* @__PURE__ */ jsx9(Box, { $display: "inline-block", children: /* @__PURE__ */ jsx9(
10396
+ "svg",
10397
+ {
10398
+ viewBox: "0 0 24 16",
10399
+ fill: "none",
10400
+ xmlns: "http://www.w3.org/2000/svg",
10401
+ width: "26px",
10402
+ height: "auto",
10403
+ children: /* @__PURE__ */ jsxs4("g", { children: [
10404
+ /* @__PURE__ */ jsx9(
10405
+ "rect",
10406
+ {
10407
+ stroke: "#DDD",
10408
+ fill: "#FFF",
10409
+ x: ".25",
10410
+ y: ".25",
10411
+ width: "23",
10412
+ height: "15.5",
10413
+ rx: "2"
10414
+ }
10415
+ ),
10416
+ /* @__PURE__ */ jsx9(
10417
+ "path",
10418
+ {
10419
+ d: "M2.788 5.914A7.201 7.201 0 0 0 1 5.237l.028-.125h2.737c.371.013.672.125.77.519l.595 2.836.182.854 1.666-4.21h1.799l-2.674 6.167H4.304L2.788 5.914Zm7.312 5.37H8.399l1.064-6.172h1.7L10.1 11.284Zm6.167-6.021-.232 1.333-.153-.066a3.054 3.054 0 0 0-1.268-.236c-.671 0-.972.269-.98.531 0 .29.365.48.96.762.98.44 1.435.979 1.428 1.681-.014 1.28-1.176 2.108-2.96 2.108-.764-.007-1.5-.158-1.898-.328l.238-1.386.224.099c.553.23.917.328 1.596.328.49 0 1.015-.19 1.022-.604 0-.27-.224-.466-.882-.769-.644-.295-1.505-.788-1.491-1.674C11.878 5.84 13.06 5 14.74 5c.658 0 1.19.138 1.526.263Zm2.26 3.834h1.415c-.07-.308-.392-1.786-.392-1.786l-.12-.531c-.083.23-.23.604-.223.59l-.68 1.727Zm2.1-3.985L22 11.284h-1.575s-.154-.71-.203-.926h-2.184l-.357.926h-1.785l2.527-5.66c.175-.4.483-.512.889-.512h1.316Z",
10420
+ fill: "#1434CB"
10421
+ }
10422
+ )
10423
+ ] })
10424
+ }
10053
10425
  ) }),
10054
- /* @__PURE__ */ jsxs5(Box, { $display: "inline-block", $fontSize: "0.75rem", children: [
10055
- "/",
10056
- planPeriod
10057
- ] })
10426
+ /* @__PURE__ */ jsx9(Box, { $whiteSpace: "nowrap", children: "Visa **** 4242" })
10058
10427
  ] }),
10059
- (plan.current || plan.id === currentPlan?.id) && /* @__PURE__ */ jsx10(
10060
- Flex,
10061
- {
10062
- $position: "absolute",
10063
- $right: "1rem",
10064
- $top: "1rem",
10065
- $fontSize: "0.625rem",
10066
- $color: hexToHSL(theme.primary).l > 50 ? "#000000" : "#FFFFFF",
10067
- $backgroundColor: theme.primary,
10068
- $borderRadius: "9999px",
10069
- $padding: "0.125rem 0.85rem",
10070
- children: "Current plan"
10071
- }
10072
- )
10073
- ]
10428
+ /* @__PURE__ */ jsx9(Flex, { $alignItems: "center", children: /* @__PURE__ */ jsx9(Box, { $fontSize: "12px", $color: "#5D5D5D", children: "Expires: 3/30" }) })
10429
+ ] })
10074
10430
  }
10075
10431
  ),
10076
- /* @__PURE__ */ jsx10(
10077
- Flex,
10432
+ /* @__PURE__ */ jsx9(Flex, { children: /* @__PURE__ */ jsx9(
10433
+ StyledButton,
10078
10434
  {
10079
- $flexDirection: "column",
10080
- $position: "relative",
10081
- $gap: "0.5rem",
10082
- $flex: "1",
10083
- $width: "100%",
10084
- $height: "auto",
10085
- $padding: "1.5rem",
10086
- children: plan.features.map((feature) => {
10087
- return /* @__PURE__ */ jsxs5(
10088
- Flex,
10089
- {
10090
- $flexShrink: "0",
10091
- $gap: "1rem",
10092
- children: [
10093
- /* @__PURE__ */ jsx10(
10094
- IconRound,
10095
- {
10096
- name: feature.icon,
10097
- size: "tn",
10098
- colors: [
10099
- settings.theme.primary,
10100
- `${hexToHSL(settings.theme.card.background).l > 50 ? darken(settings.theme.card.background, 10) : lighten(settings.theme.card.background, 20)}`
10101
- ]
10102
- }
10103
- ),
10104
- /* @__PURE__ */ jsx10(Flex, { $alignItems: "center", children: /* @__PURE__ */ jsx10(Text, { $size: 12, children: feature.name }) })
10105
- ]
10106
- },
10107
- feature.id
10108
- );
10109
- })
10435
+ $size: "sm",
10436
+ $color: "primary",
10437
+ $variant: "outline",
10438
+ style: {
10439
+ whiteSpace: "nowrap",
10440
+ paddingLeft: "1rem",
10441
+ paddingRight: "1rem"
10442
+ },
10443
+ children: "Edit"
10110
10444
  }
10111
- ),
10112
- /* @__PURE__ */ jsxs5(
10445
+ ) })
10446
+ ] })
10447
+ ] })
10448
+ }
10449
+ ),
10450
+ /* @__PURE__ */ jsx9(
10451
+ Flex,
10452
+ {
10453
+ $flexDirection: "column",
10454
+ $gap: "1rem",
10455
+ $backgroundColor: "#FBFBFB",
10456
+ $borderRadius: "0 0 0.5rem 0.5rem",
10457
+ $flex: "1",
10458
+ $height: "100%",
10459
+ children: /* @__PURE__ */ jsxs4(Flex, { $flexDirection: "column", $height: "100%", children: [
10460
+ /* @__PURE__ */ jsx9(
10461
+ Box,
10462
+ {
10463
+ $fontSize: "18px",
10464
+ $marginBottom: "1.5rem",
10465
+ $display: "inline-block",
10466
+ $width: "100%",
10467
+ children: "Others"
10468
+ }
10469
+ ),
10470
+ /* @__PURE__ */ jsxs4(Flex, { $gap: "1rem", children: [
10471
+ /* @__PURE__ */ jsx9(
10113
10472
  Flex,
10114
10473
  {
10115
- $flexDirection: "column",
10116
- $position: "relative",
10474
+ $alignItems: "center",
10475
+ $padding: ".5rem 1rem",
10476
+ $border: "1px solid #E2E5E9",
10477
+ $borderRadius: ".5rem",
10478
+ $backgroundColor: "#ffffff",
10117
10479
  $gap: "1rem",
10118
10480
  $width: "100%",
10119
- $height: "auto",
10120
- $padding: "1.5rem",
10121
- children: [
10122
- plan.id === selectedPlan?.id && /* @__PURE__ */ jsxs5(
10123
- Flex,
10124
- {
10125
- $justifyContent: "center",
10126
- $alignItems: "center",
10127
- $gap: "0.25rem",
10128
- $fontSize: "0.9375rem",
10129
- $padding: "0.625rem 0",
10130
- children: [
10131
- /* @__PURE__ */ jsx10(
10132
- Icon2,
10133
- {
10134
- name: "check-rounded",
10135
- style: {
10136
- fontSize: 20,
10137
- lineHeight: "1",
10138
- color: theme.primary
10481
+ children: /* @__PURE__ */ jsxs4(Flex, { $justifyContent: "space-between", $flex: "1", children: [
10482
+ /* @__PURE__ */ jsxs4(Flex, { $alignItems: "center", $gap: "1rem", children: [
10483
+ /* @__PURE__ */ jsx9(Box, { $display: "inline-block", children: /* @__PURE__ */ jsx9(
10484
+ "svg",
10485
+ {
10486
+ viewBox: "0 0 24 16",
10487
+ fill: "none",
10488
+ xmlns: "http://www.w3.org/2000/svg",
10489
+ width: "26px",
10490
+ height: "auto",
10491
+ children: /* @__PURE__ */ jsxs4("g", { children: [
10492
+ /* @__PURE__ */ jsx9(
10493
+ "rect",
10494
+ {
10495
+ stroke: "#DDD",
10496
+ fill: "#FFF",
10497
+ x: ".25",
10498
+ y: ".25",
10499
+ width: "23",
10500
+ height: "15.5",
10501
+ rx: "2"
10139
10502
  }
10140
- }
10141
- ),
10142
- /* @__PURE__ */ jsx10(
10143
- Text,
10144
- {
10145
- style: {
10146
- color: hexToHSL(theme.card.background).l > 50 ? "#000000" : "#FFFFFF",
10147
- lineHeight: "1.4"
10148
- },
10149
- children: "Selected"
10150
- }
10151
- )
10152
- ]
10153
- }
10154
- ),
10155
- !(plan.current || plan.id === currentPlan?.id) && plan.id !== selectedPlan?.id && /* @__PURE__ */ jsx10(
10156
- StyledButton,
10157
- {
10158
- disabled: plan.valid === false,
10159
- $size: "sm",
10160
- $color: "primary",
10161
- $variant: "outline",
10162
- onClick: () => {
10163
- setSelectedPlan(plan);
10164
- },
10165
- children: "Select"
10166
- }
10167
- )
10168
- ]
10503
+ ),
10504
+ /* @__PURE__ */ jsx9(
10505
+ "path",
10506
+ {
10507
+ d: "M2.788 5.914A7.201 7.201 0 0 0 1 5.237l.028-.125h2.737c.371.013.672.125.77.519l.595 2.836.182.854 1.666-4.21h1.799l-2.674 6.167H4.304L2.788 5.914Zm7.312 5.37H8.399l1.064-6.172h1.7L10.1 11.284Zm6.167-6.021-.232 1.333-.153-.066a3.054 3.054 0 0 0-1.268-.236c-.671 0-.972.269-.98.531 0 .29.365.48.96.762.98.44 1.435.979 1.428 1.681-.014 1.28-1.176 2.108-2.96 2.108-.764-.007-1.5-.158-1.898-.328l.238-1.386.224.099c.553.23.917.328 1.596.328.49 0 1.015-.19 1.022-.604 0-.27-.224-.466-.882-.769-.644-.295-1.505-.788-1.491-1.674C11.878 5.84 13.06 5 14.74 5c.658 0 1.19.138 1.526.263Zm2.26 3.834h1.415c-.07-.308-.392-1.786-.392-1.786l-.12-.531c-.083.23-.23.604-.223.59l-.68 1.727Zm2.1-3.985L22 11.284h-1.575s-.154-.71-.203-.926h-2.184l-.357.926h-1.785l2.527-5.66c.175-.4.483-.512.889-.512h1.316Z",
10508
+ fill: "#1434CB"
10509
+ }
10510
+ )
10511
+ ] })
10512
+ }
10513
+ ) }),
10514
+ /* @__PURE__ */ jsx9(Box, { $whiteSpace: "nowrap", children: "Visa **** 2929" })
10515
+ ] }),
10516
+ /* @__PURE__ */ jsx9(Flex, { $alignItems: "center", children: /* @__PURE__ */ jsx9(Box, { $fontSize: "12px", $color: "#5D5D5D", children: "Expires: 3/30" }) })
10517
+ ] })
10169
10518
  }
10170
- )
10171
- ]
10172
- },
10173
- plan.id
10174
- );
10175
- }) })
10176
- ] }),
10177
- selectedPlan && checkoutStage === "checkout" && /* @__PURE__ */ jsx10(
10178
- PaymentForm,
10179
- {
10180
- plan: selectedPlan,
10181
- period: planPeriod,
10182
- onConfirm: (value) => {
10183
- setPaymentMethodId(value);
10184
- }
10185
- }
10186
- )
10187
- ]
10188
- }
10189
- ),
10190
- /* @__PURE__ */ jsxs5(
10191
- Flex,
10192
- {
10193
- $position: "absolute",
10194
- $top: "0",
10195
- $right: "0",
10196
- $flexDirection: "column",
10197
- $background: settings.theme.card.background,
10198
- $borderRadius: "0 0 0.5rem",
10199
- $width: "27.5%",
10200
- $height: "100%",
10201
- $boxShadow: "0px 1px 20px 0px #1018280F, 0px 1px 3px 0px #1018281A;",
10202
- children: [
10203
- /* @__PURE__ */ jsxs5(
10204
- Flex,
10205
- {
10206
- $flexDirection: "column",
10207
- $position: "relative",
10208
- $gap: "1rem",
10209
- $width: "100%",
10210
- $height: "auto",
10211
- $padding: "1.5rem",
10212
- $borderBottom: "1px solid #DEDEDE",
10213
- children: [
10214
- /* @__PURE__ */ jsx10(Flex, { $justifyContent: "space-between", children: /* @__PURE__ */ jsx10(Text, { $size: 20, $weight: 600, children: "Subscription" }) }),
10215
- /* @__PURE__ */ jsxs5(
10216
- Flex,
10217
- {
10218
- $border: "1px solid #D9D9D9",
10219
- $borderRadius: "2.5rem",
10220
- $cursor: "pointer",
10221
- children: [
10222
- /* @__PURE__ */ jsx10(
10223
- Flex,
10519
+ ),
10520
+ /* @__PURE__ */ jsxs4(Flex, { $gap: "1rem", children: [
10521
+ /* @__PURE__ */ jsx9(
10522
+ StyledButton,
10224
10523
  {
10225
- onClick: () => setPlanPeriod("month"),
10226
- $justifyContent: "center",
10227
- $alignItems: "center",
10228
- $padding: "0.25rem 0.5rem",
10229
- $flex: "1",
10230
- $backgroundColor: planPeriod === "month" ? darken(settings.theme.card.background, 8) : lighten(settings.theme.card.background, 2),
10231
- $borderRadius: "2.5rem",
10232
- children: /* @__PURE__ */ jsx10(Text, { $size: 12, $weight: planPeriod === "month" ? 600 : 400, children: "Billed monthly" })
10524
+ $size: "sm",
10525
+ $color: "primary",
10526
+ $variant: "outline",
10527
+ style: {
10528
+ whiteSpace: "nowrap",
10529
+ paddingLeft: "1rem",
10530
+ paddingRight: "1rem"
10531
+ },
10532
+ children: "Make Default"
10233
10533
  }
10234
10534
  ),
10235
- /* @__PURE__ */ jsx10(
10236
- Flex,
10535
+ /* @__PURE__ */ jsx9(
10536
+ StyledButton,
10237
10537
  {
10238
- onClick: () => setPlanPeriod("year"),
10239
- $justifyContent: "center",
10240
- $alignItems: "center",
10241
- $padding: "0.25rem 0.5rem",
10242
- $flex: "1",
10243
- $backgroundColor: planPeriod === "year" ? darken(settings.theme.card.background, 8) : lighten(settings.theme.card.background, 2),
10244
- $borderRadius: "2.5rem",
10245
- children: /* @__PURE__ */ jsx10(Text, { $size: 12, $weight: planPeriod === "year" ? 600 : 400, children: "Billed yearly" })
10538
+ $size: "sm",
10539
+ $color: "primary",
10540
+ $variant: "outline",
10541
+ style: {
10542
+ whiteSpace: "nowrap",
10543
+ paddingLeft: "1rem",
10544
+ paddingRight: "1rem"
10545
+ },
10546
+ children: "Edit"
10246
10547
  }
10247
10548
  )
10248
- ]
10249
- }
10250
- ),
10251
- savingsPercentage > 0 && /* @__PURE__ */ jsx10(Box, { children: /* @__PURE__ */ jsx10(Text, { $size: 11, $color: "#194BFB", children: planPeriod === "month" ? `Save up to ${savingsPercentage}% with yearly billing` : `You are saving ${savingsPercentage}% with yearly billing` }) })
10252
- ]
10253
- }
10254
- ),
10255
- /* @__PURE__ */ jsxs5(
10256
- Flex,
10257
- {
10258
- $flexDirection: "column",
10259
- $position: "relative",
10260
- $gap: "1rem",
10261
- $width: "100%",
10262
- $height: "auto",
10263
- $padding: "1.5rem",
10264
- $flex: "1",
10265
- $borderBottom: "1px solid #DEDEDE",
10266
- children: [
10267
- /* @__PURE__ */ jsx10(Box, { children: /* @__PURE__ */ jsx10(Text, { $size: 14, $color: "#5D5D5D", children: "Plan" }) }),
10268
- /* @__PURE__ */ jsxs5(
10269
- Flex,
10270
- {
10271
- $flexDirection: "column",
10272
- $fontSize: "0.875rem",
10273
- $color: "#5D5D5D",
10274
- $gap: "0.5rem",
10275
- children: [
10276
- currentPlan && /* @__PURE__ */ jsxs5(
10277
- Flex,
10278
- {
10279
- $alignItems: "center",
10280
- $justifyContent: "space-between",
10281
- $fontSize: "0.875rem",
10282
- $color: "#5D5D5D",
10283
- children: [
10284
- /* @__PURE__ */ jsx10(Flex, { $fontSize: "0.875rem", $color: "#5D5D5D", children: currentPlan.name }),
10285
- typeof currentPlan.planPrice === "number" && currentPlan.planPeriod && /* @__PURE__ */ jsxs5(Flex, { $fontSize: "0.75rem", $color: "#000000", children: [
10286
- formatCurrency(currentPlan.planPrice),
10287
- "/",
10288
- currentPlan.planPeriod
10289
- ] })
10290
- ]
10291
- }
10292
- ),
10293
- selectedPlan && /* @__PURE__ */ jsxs5(Fragment, { children: [
10294
- /* @__PURE__ */ jsx10(
10295
- Box,
10296
- {
10297
- $width: "100%",
10298
- $textAlign: "left",
10299
- $opacity: "50%",
10300
- $marginBottom: "-0.25rem",
10301
- $marginTop: "-0.25rem",
10302
- children: /* @__PURE__ */ jsx10(
10303
- Icon2,
10304
- {
10305
- name: "arrow-down",
10306
- style: {
10307
- display: "inline-block"
10308
- }
10309
- }
10310
- )
10311
- }
10312
- ),
10313
- /* @__PURE__ */ jsxs5(
10314
- Flex,
10315
- {
10316
- $alignItems: "center",
10317
- $justifyContent: "space-between",
10318
- $fontSize: "0.875rem",
10319
- $color: "#5D5D5D",
10320
- children: [
10321
- /* @__PURE__ */ jsx10(
10322
- Flex,
10323
- {
10324
- $fontSize: "0.875rem",
10325
- $color: "#000000",
10326
- $fontWeight: "600",
10327
- children: selectedPlan.name
10328
- }
10329
- ),
10330
- /* @__PURE__ */ jsxs5(Flex, { $fontSize: "0.75rem", $color: "#000000", children: [
10331
- formatCurrency(
10332
- (planPeriod === "month" ? selectedPlan.monthlyPrice : selectedPlan.yearlyPrice)?.price ?? 0
10333
- ),
10334
- "/",
10335
- planPeriod
10336
- ] })
10337
- ]
10338
- }
10339
- )
10340
- ] })
10341
- ]
10342
- }
10343
- )
10344
- ]
10345
- }
10346
- ),
10347
- /* @__PURE__ */ jsxs5(
10348
- Flex,
10349
- {
10350
- $flexDirection: "column",
10351
- $position: "relative",
10352
- $gap: "0.75rem",
10353
- $width: "100%",
10354
- $height: "auto",
10355
- $padding: "1.5rem",
10356
- children: [
10357
- selectedPlan && /* @__PURE__ */ jsxs5(
10358
- Flex,
10359
- {
10360
- $fontSize: "0.75rem",
10361
- $color: "#5D5D5D",
10362
- $justifyContent: "space-between",
10363
- children: [
10364
- /* @__PURE__ */ jsxs5(Box, { $fontSize: "0.75rem", $color: "#5D5D5D", children: [
10365
- planPeriod === "month" ? "Monthly" : "Yearly",
10366
- " total:",
10367
- " "
10368
- ] }),
10369
- /* @__PURE__ */ jsxs5(Box, { $fontSize: "0.75rem", $color: "#000000", children: [
10370
- formatCurrency(
10371
- (planPeriod === "month" ? selectedPlan.monthlyPrice : selectedPlan.yearlyPrice)?.price ?? 0
10372
- ),
10373
- "/",
10374
- planPeriod
10375
- ] })
10376
- ]
10377
- }
10378
- ),
10379
- checkoutStage === "plan" ? /* @__PURE__ */ jsx10(
10380
- StyledButton,
10381
- {
10382
- disabled: !selectedPlan,
10383
- onClick: () => {
10384
- setCheckoutStage("checkout");
10385
- },
10386
- $size: "sm",
10387
- children: /* @__PURE__ */ jsxs5(
10388
- Flex,
10389
- {
10390
- $gap: "0.5rem",
10391
- $alignItems: "center",
10392
- $justifyContent: "center",
10393
- $padding: "0 1rem",
10394
- children: [
10395
- /* @__PURE__ */ jsx10(Text, { $align: "left", children: "Next: Checkout" }),
10396
- /* @__PURE__ */ jsx10(Icon2, { name: "arrow-right" })
10397
- ]
10398
- }
10399
- )
10400
- }
10401
- ) : /* @__PURE__ */ jsx10(
10402
- StyledButton,
10403
- {
10404
- disabled: !api || !selectedPlan || selectedPlan?.id === currentPlan?.id || !paymentMethodId || isLoading,
10405
- onClick: async () => {
10406
- const priceId = (planPeriod === "month" ? selectedPlan?.monthlyPrice : selectedPlan?.yearlyPrice)?.id;
10407
- if (!api || !selectedPlan || !priceId || !paymentMethodId) {
10408
- return;
10409
- }
10410
- try {
10411
- setIsLoading(true);
10412
- setIsCheckoutComplete(false);
10413
- await api.checkout({
10414
- changeSubscriptionRequestBody: {
10415
- newPlanId: selectedPlan.id,
10416
- newPriceId: priceId,
10417
- paymentMethodId
10418
- }
10419
- });
10420
- setIsCheckoutComplete(true);
10421
- } catch (error) {
10422
- console.error(error);
10423
- } finally {
10424
- setIsCheckoutComplete(true);
10425
- setIsLoading(false);
10426
- }
10427
- },
10428
- $size: "md",
10429
- children: "Pay now"
10430
- }
10431
- ),
10432
- /* @__PURE__ */ jsx10(Box, { $fontSize: "0.75rem", $color: "#5D5D5D", children: "Discounts & credits applied at checkout" })
10433
- ]
10434
- }
10435
- )
10436
- ]
10437
- }
10438
- )
10439
- ] })
10440
- ] });
10441
- };
10442
-
10443
- // src/components/elements/plan-manager/PlanManager.tsx
10444
- import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
10445
- var resolveDesignProps = (props) => {
10446
- return {
10447
- header: {
10448
- isVisible: props.header?.isVisible ?? true,
10449
- title: {
10450
- fontStyle: props.header?.title?.fontStyle ?? "heading1"
10451
- },
10452
- description: {
10453
- isVisible: props.header?.description?.isVisible ?? true,
10454
- fontStyle: props.header?.description?.fontStyle ?? "text"
10455
- },
10456
- price: {
10457
- isVisible: props.header?.price?.isVisible ?? true,
10458
- fontStyle: props.header?.price?.fontStyle ?? "text"
10459
- }
10460
- },
10461
- addOns: {
10462
- isVisible: props.addOns?.isVisible ?? true,
10463
- fontStyle: props.addOns?.fontStyle ?? "heading4",
10464
- showLabel: props.addOns?.showLabel ?? true
10465
- },
10466
- callToAction: {
10467
- isVisible: props.callToAction?.isVisible ?? true,
10468
- buttonSize: props.callToAction?.buttonSize ?? "md",
10469
- buttonStyle: props.callToAction?.buttonStyle ?? "primary"
10470
- }
10471
- };
10472
- };
10473
- var PlanManager = forwardRef(({ children, className, portal, ...rest }, ref) => {
10474
- const props = resolveDesignProps(rest);
10475
- const { data, settings, layout, stripe, setLayout } = useEmbed();
10476
- const { currentPlan, canChangePlan } = useMemo3(() => {
10477
- return {
10478
- currentPlan: data.company?.plan,
10479
- canChangePlan: stripe !== null
10480
- };
10481
- }, [data.company, stripe]);
10482
- return /* @__PURE__ */ jsxs6("div", { ref, className, children: [
10483
- /* @__PURE__ */ jsx11(
10484
- Flex,
10485
- {
10486
- $flexDirection: "column",
10487
- $gap: "0.75rem",
10488
- ...canChangePlan && { $margin: "0 0 0.5rem" },
10489
- children: props.header.isVisible && currentPlan && /* @__PURE__ */ jsxs6(
10490
- Flex,
10491
- {
10492
- $justifyContent: "space-between",
10493
- $alignItems: "center",
10494
- $width: "100%",
10495
- ...canChangePlan && { $margin: "0 0 1.5rem" },
10496
- children: [
10497
- /* @__PURE__ */ jsxs6("div", { children: [
10498
- /* @__PURE__ */ jsx11(Box, { $margin: "0 0 0.75rem", children: /* @__PURE__ */ jsx11(
10499
- Text,
10500
- {
10501
- $font: settings.theme.typography[props.header.title.fontStyle].fontFamily,
10502
- $size: settings.theme.typography[props.header.title.fontStyle].fontSize,
10503
- $weight: settings.theme.typography[props.header.title.fontStyle].fontWeight,
10504
- $color: settings.theme.typography[props.header.title.fontStyle].color,
10505
- $lineHeight: 1,
10506
- children: currentPlan.name
10507
- }
10508
- ) }),
10509
- props.header.description.isVisible && currentPlan.description && /* @__PURE__ */ jsx11(
10510
- Text,
10511
- {
10512
- $font: settings.theme.typography[props.header.description.fontStyle].fontFamily,
10513
- $size: settings.theme.typography[props.header.description.fontStyle].fontSize,
10514
- $weight: settings.theme.typography[props.header.description.fontStyle].fontWeight,
10515
- $color: settings.theme.typography[props.header.description.fontStyle].color,
10516
- children: currentPlan.description
10517
- }
10518
- )
10519
- ] }),
10520
- props.header.price.isVisible && typeof currentPlan.planPrice === "number" && currentPlan.planPeriod && /* @__PURE__ */ jsxs6(
10521
- Text,
10522
- {
10523
- $font: settings.theme.typography[props.header.price.fontStyle].fontFamily,
10524
- $size: settings.theme.typography[props.header.price.fontStyle].fontSize,
10525
- $weight: settings.theme.typography[props.header.price.fontStyle].fontWeight,
10526
- $color: settings.theme.typography[props.header.price.fontStyle].color,
10527
- children: [
10528
- formatCurrency(currentPlan.planPrice),
10529
- "/",
10530
- currentPlan.planPeriod
10531
- ]
10549
+ ] })
10550
+ ] })
10551
+ ] })
10532
10552
  }
10533
10553
  )
10534
10554
  ]
10535
10555
  }
10536
10556
  )
10537
- }
10538
- ),
10539
- canChangePlan && props.callToAction.isVisible && /* @__PURE__ */ jsx11(
10540
- StyledButton,
10541
- {
10542
- onClick: () => {
10543
- setLayout("checkout");
10544
- },
10545
- $size: props.callToAction.buttonSize,
10546
- $color: props.callToAction.buttonStyle,
10547
- children: /* @__PURE__ */ jsx11(
10548
- Text,
10549
- {
10550
- $font: settings.theme.typography.text.fontFamily,
10551
- $size: settings.theme.typography.text.fontSize,
10552
- $weight: settings.theme.typography.text.fontWeight,
10553
- children: "Change Plan"
10554
- }
10555
- )
10556
- }
10557
- ),
10558
- canChangePlan && layout === "checkout" && createPortal(/* @__PURE__ */ jsx11(CheckoutDialog, {}), portal || document.body)
10557
+ ] }),
10558
+ portal || document.body
10559
+ )
10559
10560
  ] });
10560
10561
  });
10561
10562
 
10562
- // src/components/elements/included-features/IncludedFeatures.tsx
10563
- import { forwardRef as forwardRef2, useMemo as useMemo4 } from "react";
10564
- import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
10565
- function resolveDesignProps2(props) {
10566
- return {
10567
- header: {
10568
- isVisible: props.header?.isVisible ?? true,
10569
- fontStyle: props.header?.fontStyle ?? "heading4",
10570
- text: props.header?.text ?? "Included features"
10571
- },
10572
- icons: {
10573
- isVisible: props.icons?.isVisible ?? true,
10574
- fontStyle: props.icons?.fontStyle ?? "heading3",
10575
- style: props.icons?.style ?? "light"
10576
- },
10577
- entitlement: {
10578
- isVisible: props.entitlement?.isVisible ?? true,
10579
- fontStyle: props.entitlement?.fontStyle ?? "heading5"
10580
- },
10581
- usage: {
10582
- isVisible: props.usage?.isVisible ?? true,
10583
- fontStyle: props.usage?.fontStyle ?? "heading6"
10563
+ // src/components/elements/plan-manager/PaymentForm.tsx
10564
+ import { useState as useState2 } from "react";
10565
+ import {
10566
+ LinkAuthenticationElement,
10567
+ PaymentElement
10568
+ } from "@stripe/react-stripe-js";
10569
+ import { useStripe, useElements } from "@stripe/react-stripe-js";
10570
+ import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
10571
+ var PaymentForm = ({ plan, period, onConfirm }) => {
10572
+ const stripe = useStripe();
10573
+ const elements = useElements();
10574
+ const { api, data } = useEmbed();
10575
+ const [message, setMessage] = useState2(null);
10576
+ const [isLoading, setIsLoading] = useState2(false);
10577
+ const [isConfirmed, setIsConfirmed] = useState2(false);
10578
+ const handleSubmit = async (event) => {
10579
+ event.preventDefault();
10580
+ const priceId = period === "month" ? plan.monthlyPrice?.id : plan.yearlyPrice?.id;
10581
+ if (!api || !stripe || !elements || !priceId) {
10582
+ return;
10584
10583
  }
10585
- };
10586
- }
10587
- var IncludedFeatures = forwardRef2(({ className, ...rest }, ref) => {
10588
- const props = resolveDesignProps2(rest);
10589
- const { data, settings } = useEmbed();
10590
- const features = useMemo4(() => {
10591
- return (data.featureUsage?.features || []).map(
10592
- ({
10593
- access,
10594
- allocation,
10595
- allocationType,
10596
- feature,
10597
- period,
10598
- usage = 0,
10599
- ...props2
10600
- }) => {
10601
- return {
10602
- access,
10603
- allocation,
10604
- allocationType,
10605
- feature,
10606
- period,
10607
- /**
10608
- * @TODO: resolve feature price
10609
- */
10610
- price: void 0,
10611
- usage,
10612
- ...props2
10613
- };
10584
+ setIsLoading(true);
10585
+ setIsConfirmed(false);
10586
+ setMessage(null);
10587
+ try {
10588
+ const { setupIntent, error } = await stripe.confirmSetup({
10589
+ elements,
10590
+ confirmParams: {
10591
+ return_url: window.location.href
10592
+ },
10593
+ redirect: "if_required"
10594
+ });
10595
+ if (onConfirm && typeof setupIntent?.payment_method === "string") {
10596
+ onConfirm(setupIntent.payment_method);
10597
+ setIsConfirmed(true);
10598
+ } else {
10614
10599
  }
10615
- );
10616
- }, [data.featureUsage]);
10617
- return /* @__PURE__ */ jsxs7(Flex, { ref, className, $flexDirection: "column", $gap: "1.5rem", children: [
10618
- props.header.isVisible && /* @__PURE__ */ jsx12(Box, { children: /* @__PURE__ */ jsx12(
10619
- Text,
10620
- {
10621
- $font: settings.theme.typography[props.header.fontStyle].fontFamily,
10622
- $size: settings.theme.typography[props.header.fontStyle].fontSize,
10623
- $weight: settings.theme.typography[props.header.fontStyle].fontWeight,
10624
- $color: settings.theme.typography[props.header.fontStyle].color,
10625
- children: props.header.text
10600
+ if (error?.type === "card_error" || error?.type === "validation_error") {
10601
+ setMessage(error.message);
10626
10602
  }
10627
- ) }),
10628
- features.reduce(
10629
- (acc, { allocation, allocationType, feature, usage }, index) => {
10630
- if (!allocationType) {
10631
- return acc;
10632
- }
10633
- return [
10634
- ...acc,
10635
- /* @__PURE__ */ jsxs7(
10636
- Flex,
10637
- {
10638
- $flexWrap: "wrap",
10639
- $justifyContent: "space-between",
10640
- $alignItems: "center",
10641
- $gap: "1rem",
10642
- children: [
10643
- /* @__PURE__ */ jsxs7(Flex, { $gap: "1rem", children: [
10644
- props.icons.isVisible && feature?.icon && /* @__PURE__ */ jsx12(
10645
- IconRound,
10646
- {
10647
- name: feature.icon,
10648
- size: "sm",
10649
- colors: [
10650
- settings.theme.primary,
10651
- `${hexToHSL(settings.theme.card.background).l > 50 ? darken(settings.theme.card.background, 10) : lighten(settings.theme.card.background, 20)}`
10652
- ]
10653
- }
10654
- ),
10655
- feature?.name && /* @__PURE__ */ jsx12(Flex, { $alignItems: "center", children: /* @__PURE__ */ jsx12(
10656
- Text,
10657
- {
10658
- $font: settings.theme.typography[props.icons.fontStyle].fontFamily,
10659
- $size: settings.theme.typography[props.icons.fontStyle].fontSize,
10660
- $weight: settings.theme.typography[props.icons.fontStyle].fontWeight,
10661
- $color: settings.theme.typography[props.icons.fontStyle].color,
10662
- children: feature.name
10663
- }
10664
- ) })
10665
- ] }),
10666
- allocationType === "numeric" && feature?.name && /* @__PURE__ */ jsxs7(Box, { $textAlign: "right", children: [
10667
- props.entitlement.isVisible && /* @__PURE__ */ jsx12(
10668
- Text,
10669
- {
10670
- as: Box,
10671
- $font: settings.theme.typography[props.entitlement.fontStyle].fontFamily,
10672
- $size: settings.theme.typography[props.entitlement.fontStyle].fontSize,
10673
- $weight: settings.theme.typography[props.entitlement.fontStyle].fontWeight,
10674
- $color: settings.theme.typography[props.entitlement.fontStyle].color,
10675
- children: typeof allocation === "number" ? `${allocation} ${feature.name}` : `Unlimited ${feature.name}`
10676
- }
10677
- ),
10678
- props.usage.isVisible && /* @__PURE__ */ jsx12(
10679
- Text,
10680
- {
10681
- as: Box,
10682
- $font: settings.theme.typography[props.usage.fontStyle].fontFamily,
10683
- $size: settings.theme.typography[props.usage.fontStyle].fontSize,
10684
- $weight: settings.theme.typography[props.usage.fontStyle].fontWeight,
10685
- $color: settings.theme.typography[props.usage.fontStyle].color,
10686
- children: typeof allocation === "number" ? `${usage} of ${allocation} used` : `${usage} used`
10687
- }
10688
- )
10689
- ] })
10690
- ]
10691
- },
10692
- index
10693
- )
10694
- ];
10695
- },
10696
- []
10697
- )
10698
- ] });
10699
- });
10700
-
10701
- // src/components/elements/metered-features/MeteredFeatures.tsx
10702
- import { forwardRef as forwardRef3, useMemo as useMemo5 } from "react";
10703
- import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
10704
- function resolveDesignProps3(props) {
10705
- return {
10706
- isVisible: props.isVisible ?? true,
10707
- header: {
10708
- fontStyle: props.header?.fontStyle ?? "heading2"
10709
- },
10710
- description: {
10711
- isVisible: props.description?.isVisible ?? true,
10712
- fontStyle: props.description?.fontStyle ?? "text"
10713
- },
10714
- icon: {
10715
- isVisible: props.icon?.isVisible ?? true
10716
- },
10717
- allocation: {
10718
- isVisible: props.allocation?.isVisible ?? true,
10719
- fontStyle: props.allocation?.fontStyle ?? "heading4"
10720
- },
10721
- usage: {
10722
- isVisible: props.usage?.isVisible ?? true,
10723
- fontStyle: props.usage?.fontStyle ?? "heading5"
10724
- },
10725
- callToAction: {
10726
- isVisible: props.callToAction?.isVisible ?? true,
10727
- buttonSize: props.callToAction?.buttonSize ?? "md",
10728
- buttonStyle: props.callToAction?.buttonStyle ?? "primary"
10603
+ } catch (error) {
10604
+ setMessage("A problem occurred while saving your payment method.");
10605
+ } finally {
10606
+ setIsLoading(false);
10729
10607
  }
10730
10608
  };
10731
- }
10732
- var MeteredFeatures = forwardRef3(({ className, ...rest }, ref) => {
10733
- const props = resolveDesignProps3(rest);
10734
- const { data, settings } = useEmbed();
10735
- const features = useMemo5(() => {
10736
- return (data.featureUsage?.features || []).map(
10737
- ({
10738
- access,
10739
- allocation,
10740
- allocationType,
10741
- feature,
10742
- period,
10743
- usage,
10744
- ...props2
10745
- }) => {
10746
- return {
10747
- access,
10748
- allocation,
10749
- allocationType,
10750
- feature,
10751
- period,
10752
- /**
10753
- * @TODO: resolve feature price
10754
- */
10755
- price: void 0,
10756
- usage,
10757
- ...props2
10758
- };
10759
- }
10760
- );
10761
- }, [data.featureUsage]);
10762
- return /* @__PURE__ */ jsx13(Flex, { ref, className, $flexDirection: "column", $gap: "1.5rem", children: features.reduce(
10763
- (acc, { allocation, allocationType, feature, usage }, index) => {
10764
- if (!props.isVisible || allocationType !== "numeric" || typeof allocation !== "number") {
10765
- return acc;
10766
- }
10767
- return [
10768
- ...acc,
10769
- /* @__PURE__ */ jsxs8(Flex, { $gap: "1.5rem", children: [
10770
- props.icon.isVisible && feature?.icon && /* @__PURE__ */ jsx13(Box, { $flexShrink: "0", children: /* @__PURE__ */ jsx13(IconRound, { name: feature.icon, size: "sm" }) }),
10771
- /* @__PURE__ */ jsxs8(Box, { $flexGrow: "1", children: [
10772
- /* @__PURE__ */ jsxs8(Flex, { children: [
10773
- feature?.name && /* @__PURE__ */ jsxs8(Box, { $flexGrow: "1", children: [
10774
- /* @__PURE__ */ jsx13(
10775
- Text,
10776
- {
10777
- as: Box,
10778
- $font: settings.theme.typography[props.header.fontStyle].fontFamily,
10779
- $size: settings.theme.typography[props.header.fontStyle].fontSize,
10780
- $weight: settings.theme.typography[props.header.fontStyle].fontWeight,
10781
- $color: settings.theme.typography[props.header.fontStyle].color,
10782
- children: feature.name
10783
- }
10784
- ),
10785
- props.description.isVisible && /* @__PURE__ */ jsx13(
10786
- Text,
10787
- {
10788
- as: Box,
10789
- $font: settings.theme.typography[props.description.fontStyle].fontFamily,
10790
- $size: settings.theme.typography[props.description.fontStyle].fontSize,
10791
- $weight: settings.theme.typography[props.description.fontStyle].fontWeight,
10792
- $color: settings.theme.typography[props.description.fontStyle].color,
10793
- children: feature.description
10794
- }
10795
- )
10796
- ] }),
10797
- allocationType === "numeric" && feature?.name && /* @__PURE__ */ jsxs8(Box, { $textAlign: "right", children: [
10798
- props.allocation.isVisible && /* @__PURE__ */ jsx13(
10799
- Text,
10800
- {
10801
- as: Box,
10802
- $font: settings.theme.typography[props.allocation.fontStyle].fontFamily,
10803
- $size: settings.theme.typography[props.allocation.fontStyle].fontSize,
10804
- $weight: settings.theme.typography[props.allocation.fontStyle].fontWeight,
10805
- $color: settings.theme.typography[props.allocation.fontStyle].color,
10806
- children: typeof allocation === "number" ? `${allocation} ${feature.name}` : `Unlimited ${feature.name}`
10807
- }
10808
- ),
10809
- props.usage.isVisible && /* @__PURE__ */ jsx13(
10810
- Text,
10811
- {
10812
- as: Box,
10813
- $font: settings.theme.typography[props.usage.fontStyle].fontFamily,
10814
- $size: settings.theme.typography[props.usage.fontStyle].fontSize,
10815
- $weight: settings.theme.typography[props.usage.fontStyle].fontWeight,
10816
- $color: settings.theme.typography[props.usage.fontStyle].color,
10817
- children: typeof allocation === "number" ? `${usage} of ${allocation} used` : `${usage} used`
10818
- }
10819
- )
10820
- ] })
10821
- ] }),
10822
- typeof usage === "number" && typeof allocation === "number" && /* @__PURE__ */ jsx13(Box, { children: /* @__PURE__ */ jsx13(
10823
- ProgressBar,
10609
+ return /* @__PURE__ */ jsxs5(
10610
+ "form",
10611
+ {
10612
+ id: "payment-form",
10613
+ onSubmit: handleSubmit,
10614
+ style: {
10615
+ display: "flex",
10616
+ flexDirection: "column",
10617
+ overflowX: "hidden",
10618
+ overflowY: "auto"
10619
+ },
10620
+ children: [
10621
+ /* @__PURE__ */ jsx10(Box, { $width: "100%", $marginBottom: "1.5rem", children: /* @__PURE__ */ jsx10(Text, { $size: 18, children: "Add payment method" }) }),
10622
+ /* @__PURE__ */ jsx10(
10623
+ Flex,
10624
+ {
10625
+ $flexDirection: "column",
10626
+ $gap: "1.5rem",
10627
+ $width: "100%",
10628
+ $marginBottom: "1.5rem",
10629
+ children: /* @__PURE__ */ jsx10(
10630
+ LinkAuthenticationElement,
10824
10631
  {
10825
- progress: usage / allocation * 100,
10826
- value: usage,
10827
- total: allocation,
10828
- color: "blue"
10632
+ id: "link-authentication-element"
10829
10633
  }
10830
- ) })
10831
- ] })
10832
- ] }, index)
10833
- ];
10834
- },
10835
- []
10836
- ) });
10837
- });
10634
+ )
10635
+ }
10636
+ ),
10637
+ /* @__PURE__ */ jsx10(Box, { $marginBottom: "1.5rem", children: /* @__PURE__ */ jsx10(PaymentElement, { id: "payment-element" }) }),
10638
+ /* @__PURE__ */ jsx10(
10639
+ StyledButton,
10640
+ {
10641
+ id: "submit",
10642
+ disabled: isLoading || !stripe || !elements || !data.stripeEmbed?.publishableKey || !data.stripeEmbed?.setupIntentClientSecret || isConfirmed,
10643
+ $size: "md",
10644
+ $color: "primary",
10645
+ children: /* @__PURE__ */ jsx10(Text, { id: "button-text", children: isLoading ? "Loading" : "Save payment method" })
10646
+ }
10647
+ ),
10648
+ message && /* @__PURE__ */ jsx10(Box, { $margin: "1rem 0", children: /* @__PURE__ */ jsx10(Text, { id: "payment-message", $size: 15, $weight: 500, $color: "#DB6669", children: message }) })
10649
+ ]
10650
+ }
10651
+ );
10652
+ };
10838
10653
 
10839
- // src/components/elements/upcoming-bill/UpcomingBill.tsx
10840
- import { forwardRef as forwardRef4, useMemo as useMemo6 } from "react";
10841
- import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
10842
- function resolveDesignProps4(props) {
10843
- return {
10844
- header: {
10845
- isVisible: props.header?.isVisible ?? true,
10846
- fontStyle: props.header?.fontStyle ?? "heading4",
10847
- prefix: props.header?.prefix ?? "Next bill due"
10848
- },
10849
- price: {
10850
- isVisible: props.price?.isVisible ?? true,
10851
- fontStyle: props.price?.fontStyle ?? "heading1"
10852
- },
10853
- contractEndDate: {
10854
- isVisible: props.contractEndDate?.isVisible ?? true,
10855
- fontStyle: props.contractEndDate?.fontStyle ?? "heading6",
10856
- prefix: props.contractEndDate?.prefix ?? "Contract ends"
10654
+ // src/components/elements/plan-manager/CheckoutDialog.tsx
10655
+ import { Fragment, jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
10656
+ var FeatureName = ({
10657
+ entitlement
10658
+ }) => {
10659
+ const theme = nt();
10660
+ if (!entitlement.feature?.name) {
10661
+ return null;
10662
+ }
10663
+ if (entitlement.valueType === "numeric" || entitlement.valueType === "trait") {
10664
+ let period;
10665
+ if (entitlement.metricPeriod) {
10666
+ period = {
10667
+ current_day: "day",
10668
+ current_month: "mo",
10669
+ current_year: "yr"
10670
+ }[entitlement.metricPeriod];
10857
10671
  }
10858
- };
10859
- }
10860
- var UpcomingBill = forwardRef4(({ className, ...rest }, ref) => {
10861
- const props = resolveDesignProps4(rest);
10862
- const { data, settings, stripe } = useEmbed();
10863
- const { upcomingInvoice } = useMemo6(() => {
10864
- return {
10865
- upcomingInvoice: {
10866
- ...data.upcomingInvoice?.amountDue && {
10867
- amountDue: data.upcomingInvoice.amountDue
10868
- },
10869
- ...data.subscription?.interval && {
10870
- interval: data.subscription.interval
10871
- },
10872
- ...data.upcomingInvoice?.dueDate && {
10873
- dueDate: toPrettyDate(new Date(data.upcomingInvoice.dueDate))
10874
- }
10875
- }
10876
- };
10877
- }, [data.subscription, data.upcomingInvoice]);
10878
- if (!stripe || !data.upcomingInvoice) {
10879
- return null;
10880
- }
10881
- return /* @__PURE__ */ jsxs9("div", { ref, className, children: [
10882
- props.header.isVisible && upcomingInvoice.dueDate && /* @__PURE__ */ jsx14(
10883
- Flex,
10672
+ return /* @__PURE__ */ jsx11(Flex, { $alignItems: "center", children: /* @__PURE__ */ jsxs6(
10673
+ Text,
10884
10674
  {
10885
- $justifyContent: "space-between",
10886
- $alignItems: "center",
10887
- $margin: "0 0 0.75rem",
10888
- children: /* @__PURE__ */ jsxs9(
10889
- Text,
10890
- {
10891
- $font: settings.theme.typography[props.header.fontStyle].fontFamily,
10892
- $size: settings.theme.typography[props.header.fontStyle].fontSize,
10893
- $weight: settings.theme.typography[props.header.fontStyle].fontWeight,
10894
- $color: settings.theme.typography[props.header.fontStyle].color,
10895
- children: [
10896
- props.header.prefix,
10897
- " ",
10898
- upcomingInvoice.dueDate
10899
- ]
10900
- }
10901
- )
10675
+ $font: theme.typography.text.fontFamily,
10676
+ $size: theme.typography.text.fontSize,
10677
+ $weight: theme.typography.text.fontWeight,
10678
+ $color: theme.typography.text.color,
10679
+ children: [
10680
+ typeof entitlement.valueNumeric === "number" ? (0, import_pluralize.default)(
10681
+ entitlement.feature.name,
10682
+ entitlement.valueNumeric,
10683
+ true
10684
+ ) : `Unlimited ${(0, import_pluralize.default)(entitlement.feature.name)}`,
10685
+ period && `/${period}`
10686
+ ]
10902
10687
  }
10903
- ),
10904
- upcomingInvoice.amountDue && /* @__PURE__ */ jsxs9(Flex, { $justifyContent: "space-between", $alignItems: "start", $gap: "1rem", children: [
10905
- props.price.isVisible && /* @__PURE__ */ jsx14(Flex, { $alignItems: "end", $flexGrow: "1", children: /* @__PURE__ */ jsx14(
10906
- Text,
10907
- {
10908
- $font: settings.theme.typography[props.price.fontStyle].fontFamily,
10909
- $size: settings.theme.typography[props.price.fontStyle].fontSize,
10910
- $weight: settings.theme.typography[props.price.fontStyle].fontWeight,
10911
- $color: settings.theme.typography[props.price.fontStyle].color,
10912
- $lineHeight: 1,
10913
- children: formatCurrency(upcomingInvoice.amountDue)
10914
- }
10915
- ) }),
10916
- /* @__PURE__ */ jsx14(Box, { $maxWidth: "10rem", $lineHeight: "1", $textAlign: "right", children: /* @__PURE__ */ jsx14(
10917
- Text,
10918
- {
10919
- $font: settings.theme.typography[props.contractEndDate.fontStyle].fontFamily,
10920
- $size: settings.theme.typography[props.contractEndDate.fontStyle].fontSize,
10921
- $weight: settings.theme.typography[props.contractEndDate.fontStyle].fontWeight,
10922
- $color: settings.theme.typography[props.contractEndDate.fontStyle].color,
10923
- children: "Estimated monthly bill."
10924
- }
10925
- ) })
10926
- ] })
10927
- ] });
10928
- });
10929
-
10930
- // src/components/elements/payment-method/PaymentMethod.tsx
10931
- import { forwardRef as forwardRef5, useMemo as useMemo7 } from "react";
10932
- import { createPortal as createPortal2 } from "react-dom";
10933
- import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
10934
- var resolveDesignProps5 = (props) => {
10935
- return {
10936
- header: {
10937
- isVisible: props.header?.isVisible ?? true,
10938
- fontStyle: props.header?.fontStyle ?? "heading4"
10939
- },
10940
- functions: {
10941
- allowEdit: props.functions?.allowEdit ?? true
10688
+ ) });
10689
+ }
10690
+ return /* @__PURE__ */ jsx11(Flex, { $alignItems: "center", children: /* @__PURE__ */ jsx11(
10691
+ Text,
10692
+ {
10693
+ $font: theme.typography.text.fontFamily,
10694
+ $size: theme.typography.text.fontSize,
10695
+ $weight: theme.typography.text.fontWeight,
10696
+ $color: theme.typography.text.color,
10697
+ children: entitlement.feature.name
10942
10698
  }
10943
- };
10699
+ ) });
10944
10700
  };
10945
- var PaymentMethod = forwardRef5(({ children, className, portal, ...rest }, ref) => {
10946
- const props = resolveDesignProps5(rest);
10947
- const { data, settings, stripe, layout } = useEmbed();
10948
- const paymentMethod = useMemo7(() => {
10949
- const { cardLast4, cardExpMonth, cardExpYear } = data.subscription?.paymentMethod || {};
10950
- let monthsToExpiration;
10951
- if (typeof cardExpYear === "number" && typeof cardExpMonth === "number") {
10952
- const timeToExpiration = Math.round(
10953
- +new Date(cardExpYear, cardExpMonth - 1) - +/* @__PURE__ */ new Date()
10954
- );
10955
- monthsToExpiration = Math.round(
10956
- timeToExpiration / (1e3 * 60 * 60 * 24 * 30)
10957
- );
10701
+ var CheckoutDialog = () => {
10702
+ const theme = nt();
10703
+ const { api, data, setLayout } = useEmbed();
10704
+ const [checkoutStage, setCheckoutStage] = useState3(
10705
+ "plan"
10706
+ );
10707
+ const [planPeriod, setPlanPeriod] = useState3(
10708
+ () => data.company?.plan?.planPeriod || "month"
10709
+ );
10710
+ const [selectedPlan, setSelectedPlan] = useState3();
10711
+ const [paymentMethodId, setPaymentMethodId] = useState3();
10712
+ const [isLoading, setIsLoading] = useState3(false);
10713
+ const [error, setError] = useState3();
10714
+ const [showPaymentForm, setShowPaymentForm] = useState3(
10715
+ () => typeof data.subscription?.paymentMethod === "undefined"
10716
+ );
10717
+ const { paymentMethod, currentPlan, availablePlans, planPeriodOptions } = useMemo6(() => {
10718
+ const showMonthlyPriceOption = data.activePlans.some(
10719
+ (plan) => typeof plan.yearlyPrice !== "undefined"
10720
+ );
10721
+ const showYearlyPriceOption = data.activePlans.some(
10722
+ (plan) => typeof plan.yearlyPrice !== "undefined"
10723
+ );
10724
+ const planPeriodOptions2 = [];
10725
+ if (showMonthlyPriceOption) {
10726
+ planPeriodOptions2.push("month");
10727
+ }
10728
+ if (showYearlyPriceOption) {
10729
+ planPeriodOptions2.push("year");
10958
10730
  }
10959
10731
  return {
10960
- cardLast4,
10961
- monthsToExpiration
10732
+ paymentMethod: data.subscription?.paymentMethod,
10733
+ currentPlan: data.company?.plan,
10734
+ availablePlans: data.activePlans.filter(
10735
+ (plan) => plan.current || plan.yearlyPrice && planPeriod === "year" || plan.monthlyPrice && planPeriod === "month"
10736
+ ),
10737
+ planPeriodOptions: planPeriodOptions2
10962
10738
  };
10963
- }, [data.subscription?.paymentMethod]);
10964
- if (!stripe || !data.subscription?.paymentMethod) {
10965
- return null;
10966
- }
10967
- return /* @__PURE__ */ jsxs10("div", { ref, className, children: [
10968
- props.header.isVisible && /* @__PURE__ */ jsxs10(
10969
- Flex,
10970
- {
10971
- $justifyContent: "space-between",
10972
- $alignItems: "center",
10973
- $margin: "0 0 1rem",
10974
- children: [
10975
- /* @__PURE__ */ jsx15(
10976
- Text,
10977
- {
10978
- $font: settings.theme.typography[props.header.fontStyle].fontFamily,
10979
- $size: settings.theme.typography[props.header.fontStyle].fontSize,
10980
- $weight: settings.theme.typography[props.header.fontStyle].fontWeight,
10981
- $color: settings.theme.typography[props.header.fontStyle].color,
10982
- children: "Payment Method"
10983
- }
10984
- ),
10985
- typeof paymentMethod.monthsToExpiration === "number" && Math.abs(paymentMethod.monthsToExpiration) < 4 && /* @__PURE__ */ jsx15(
10986
- Text,
10987
- {
10988
- $font: settings.theme.typography.text.fontFamily,
10989
- $size: 14,
10990
- $color: "#DB6769",
10991
- children: paymentMethod.monthsToExpiration > 0 ? `Expires in ${paymentMethod.monthsToExpiration} mo` : "Expired"
10739
+ }, [
10740
+ data.subscription?.paymentMethod,
10741
+ data.company,
10742
+ data.activePlans,
10743
+ planPeriod
10744
+ ]);
10745
+ const savingsPercentage = useMemo6(() => {
10746
+ if (selectedPlan) {
10747
+ const monthly = (selectedPlan?.monthlyPrice?.price || 0) * 12;
10748
+ const yearly = selectedPlan?.yearlyPrice?.price || 0;
10749
+ return Math.round((monthly - yearly) / monthly * 1e4) / 100;
10750
+ }
10751
+ return 0;
10752
+ }, [selectedPlan]);
10753
+ const isLightBackground = useMemo6(() => {
10754
+ return hexToHSL(theme.card.background).l > 50;
10755
+ }, [theme.card.background]);
10756
+ const allowCheckout = api && selectedPlan && selectedPlan?.id !== currentPlan?.id && (paymentMethod && !showPaymentForm || paymentMethodId) && !isLoading;
10757
+ return /* @__PURE__ */ jsxs6(Modal, { size: "lg", children: [
10758
+ /* @__PURE__ */ jsx11(ModalHeader, { bordered: true, children: /* @__PURE__ */ jsxs6(Flex, { $gap: "1rem", children: [
10759
+ /* @__PURE__ */ jsxs6(Flex, { $gap: "0.5rem", $alignItems: "center", children: [
10760
+ checkoutStage === "plan" ? /* @__PURE__ */ jsx11(
10761
+ Box,
10762
+ {
10763
+ $width: `${20 / TEXT_BASE_SIZE}rem`,
10764
+ $height: `${20 / TEXT_BASE_SIZE}rem`,
10765
+ $borderWidth: "2px",
10766
+ $borderStyle: "solid",
10767
+ $borderColor: isLightBackground ? "hsla(0, 0%, 0%, 0.125)" : "hsla(0, 0%, 100%, 0.25)",
10768
+ $borderRadius: "9999px"
10769
+ }
10770
+ ) : /* @__PURE__ */ jsx11(
10771
+ IconRound,
10772
+ {
10773
+ name: "check",
10774
+ colors: [
10775
+ theme.card.background,
10776
+ isLightBackground ? "hsla(0, 0%, 0%, 0.125)" : "hsla(0, 0%, 100%, 0.25)"
10777
+ ],
10778
+ style: {
10779
+ fontSize: `${16 / TEXT_BASE_SIZE}rem`,
10780
+ width: `${20 / TEXT_BASE_SIZE}rem`,
10781
+ height: `${20 / TEXT_BASE_SIZE}rem`
10992
10782
  }
10993
- )
10994
- ]
10995
- }
10996
- ),
10997
- paymentMethod.cardLast4 && /* @__PURE__ */ jsx15(
10998
- Flex,
10999
- {
11000
- $justifyContent: "space-between",
11001
- $alignItems: "center",
11002
- $margin: "0 0 1rem",
11003
- $background: `${hexToHSL(settings.theme.card.background).l > 50 ? darken(settings.theme.card.background, 10) : lighten(settings.theme.card.background, 20)}`,
11004
- $padding: "0.375rem 1rem",
11005
- $borderRadius: "9999px",
11006
- children: /* @__PURE__ */ jsxs10(Text, { $font: settings.theme.typography.text.fontFamily, $size: 14, children: [
11007
- "\u{1F4B3} Card ending in ",
11008
- paymentMethod.cardLast4
11009
- ] })
11010
- }
11011
- ),
11012
- layout === "payment" && createPortal2(
11013
- /* @__PURE__ */ jsxs10(Modal, { size: "md", children: [
11014
- /* @__PURE__ */ jsx15(ModalHeader, { children: /* @__PURE__ */ jsx15(Box, { $fontWeight: "600", children: "Edit payment method" }) }),
11015
- /* @__PURE__ */ jsxs10(
11016
- Flex,
10783
+ }
10784
+ ),
10785
+ /* @__PURE__ */ jsx11(
10786
+ Box,
11017
10787
  {
11018
- $flexDirection: "column",
11019
- $padding: "2.5rem",
11020
- $height: "100%",
11021
- $gap: "1.5rem",
11022
- children: [
11023
- /* @__PURE__ */ jsx15(
11024
- Flex,
11025
- {
11026
- $flexDirection: "column",
11027
- $gap: "1rem",
11028
- $backgroundColor: "#FBFBFB",
11029
- $borderRadius: "0 0 0.5rem 0.5rem",
11030
- $flex: "1",
11031
- $height: "100%",
11032
- children: /* @__PURE__ */ jsxs10(Flex, { $flexDirection: "column", $height: "100%", children: [
11033
- /* @__PURE__ */ jsx15(
11034
- Box,
11035
- {
11036
- $fontSize: "18px",
11037
- $marginBottom: "1.5rem",
11038
- $display: "inline-block",
11039
- $width: "100%",
11040
- children: "Default"
11041
- }
11042
- ),
11043
- /* @__PURE__ */ jsxs10(Flex, { $gap: "1rem", children: [
11044
- /* @__PURE__ */ jsx15(
10788
+ tabIndex: 0,
10789
+ ...checkoutStage !== "plan" && {
10790
+ onClick: () => setCheckoutStage("plan"),
10791
+ $opacity: "0.6375",
10792
+ $cursor: "pointer"
10793
+ },
10794
+ children: /* @__PURE__ */ jsx11(
10795
+ Text,
10796
+ {
10797
+ $font: theme.typography.text.fontFamily,
10798
+ $size: 19,
10799
+ $weight: checkoutStage === "plan" ? 600 : 400,
10800
+ $color: theme.typography.text.color,
10801
+ children: "1. Select plan"
10802
+ }
10803
+ )
10804
+ }
10805
+ )
10806
+ ] }),
10807
+ /* @__PURE__ */ jsx11(
10808
+ Icon2,
10809
+ {
10810
+ name: "chevron-right",
10811
+ style: {
10812
+ fontSize: 16,
10813
+ color: isLightBackground ? "hsla(0, 0%, 0%, 0.175)" : "hsla(0, 0%, 100%, 0.35)"
10814
+ }
10815
+ }
10816
+ ),
10817
+ /* @__PURE__ */ jsxs6(Flex, { $gap: "0.5rem", $alignItems: "center", children: [
10818
+ /* @__PURE__ */ jsx11(
10819
+ Box,
10820
+ {
10821
+ $width: `${20 / TEXT_BASE_SIZE}rem`,
10822
+ $height: `${20 / TEXT_BASE_SIZE}rem`,
10823
+ $borderWidth: "2px",
10824
+ $borderStyle: "solid",
10825
+ $borderColor: isLightBackground ? "hsla(0, 0%, 0%, 0.125)" : "hsla(0, 0%, 100%, 0.25)",
10826
+ $borderRadius: "9999px"
10827
+ }
10828
+ ),
10829
+ /* @__PURE__ */ jsx11(
10830
+ Box,
10831
+ {
10832
+ tabIndex: 0,
10833
+ ...checkoutStage !== "checkout" && {
10834
+ $opacity: "0.6375"
10835
+ },
10836
+ children: /* @__PURE__ */ jsx11(
10837
+ Text,
10838
+ {
10839
+ $font: theme.typography.text.fontFamily,
10840
+ $size: 19,
10841
+ $weight: checkoutStage === "plan" ? 600 : 400,
10842
+ $color: theme.typography.text.color,
10843
+ children: "2. Checkout"
10844
+ }
10845
+ )
10846
+ }
10847
+ )
10848
+ ] })
10849
+ ] }) }),
10850
+ /* @__PURE__ */ jsxs6(Flex, { $position: "relative", $height: "calc(100% - 5rem)", children: [
10851
+ /* @__PURE__ */ jsxs6(
10852
+ Flex,
10853
+ {
10854
+ $flexDirection: "column",
10855
+ $flexGrow: "1",
10856
+ $gap: "1rem",
10857
+ $padding: "2rem 2.5rem 2rem 2.5rem",
10858
+ $backgroundColor: isLightBackground ? "hsla(0, 0%, 0%, 0.025)" : "hsla(0, 0%, 100%, 0.025)",
10859
+ $flex: "1",
10860
+ $overflow: "auto",
10861
+ children: [
10862
+ checkoutStage === "plan" && /* @__PURE__ */ jsxs6(Fragment, { children: [
10863
+ /* @__PURE__ */ jsxs6(Flex, { $flexDirection: "column", $gap: "1rem", $marginBottom: "1rem", children: [
10864
+ /* @__PURE__ */ jsx11(
10865
+ Text,
10866
+ {
10867
+ as: "h3",
10868
+ id: "select-plan-dialog-label",
10869
+ $font: theme.typography.heading3.fontFamily,
10870
+ $size: theme.typography.heading3.fontSize,
10871
+ $weight: theme.typography.heading3.fontWeight,
10872
+ $color: theme.typography.heading3.color,
10873
+ $marginBottom: "0.5rem",
10874
+ children: "Select plan"
10875
+ }
10876
+ ),
10877
+ /* @__PURE__ */ jsx11(
10878
+ Text,
10879
+ {
10880
+ as: "p",
10881
+ id: "select-plan-dialog-description",
10882
+ $font: theme.typography.text.fontFamily,
10883
+ $size: theme.typography.text.fontSize,
10884
+ $weight: theme.typography.text.fontWeight,
10885
+ $color: theme.typography.text.color,
10886
+ children: "Choose your base plan"
10887
+ }
10888
+ )
10889
+ ] }),
10890
+ /* @__PURE__ */ jsx11(Flex, { $flexWrap: "wrap", $gap: "1rem", $flexGrow: "1", children: availablePlans?.map((plan) => {
10891
+ return /* @__PURE__ */ jsxs6(
10892
+ Flex,
10893
+ {
10894
+ $flexDirection: "column",
10895
+ $width: "100%",
10896
+ $minWidth: "280px",
10897
+ $maxWidth: `calc(${100 / 3}% - 1rem)`,
10898
+ $backgroundColor: theme.card.background,
10899
+ $outlineWidth: "2px",
10900
+ $outlineStyle: "solid",
10901
+ $outlineColor: plan.id === selectedPlan?.id ? theme.primary : "transparent",
10902
+ $borderRadius: `${theme.card.borderRadius / TEXT_BASE_SIZE}rem`,
10903
+ ...theme.card.hasShadow && {
10904
+ $boxShadow: "0px 1px 3px rgba(16, 24, 40, 0.1), 0px 1px 20px rgba(16, 24, 40, 0.06)"
10905
+ },
10906
+ children: [
10907
+ /* @__PURE__ */ jsxs6(
11045
10908
  Flex,
11046
10909
  {
11047
- $alignItems: "center",
11048
- $padding: ".5rem 1rem",
11049
- $border: "1px solid #E2E5E9",
11050
- $borderRadius: ".5rem",
11051
- $backgroundColor: "#ffffff",
10910
+ $flexDirection: "column",
10911
+ $position: "relative",
11052
10912
  $gap: "1rem",
11053
10913
  $width: "100%",
11054
- children: /* @__PURE__ */ jsxs10(Flex, { $justifyContent: "space-between", $flex: "1", children: [
11055
- /* @__PURE__ */ jsxs10(Flex, { $alignItems: "center", $gap: "1rem", children: [
11056
- /* @__PURE__ */ jsx15(Box, { $display: "inline-block", children: /* @__PURE__ */ jsx15(
11057
- "svg",
11058
- {
11059
- viewBox: "0 0 24 16",
11060
- fill: "none",
11061
- xmlns: "http://www.w3.org/2000/svg",
11062
- width: "26px",
11063
- height: "auto",
11064
- children: /* @__PURE__ */ jsxs10("g", { children: [
11065
- /* @__PURE__ */ jsx15(
11066
- "rect",
11067
- {
11068
- stroke: "#DDD",
11069
- fill: "#FFF",
11070
- x: ".25",
11071
- y: ".25",
11072
- width: "23",
11073
- height: "15.5",
11074
- rx: "2"
11075
- }
11076
- ),
11077
- /* @__PURE__ */ jsx15(
11078
- "path",
11079
- {
11080
- d: "M2.788 5.914A7.201 7.201 0 0 0 1 5.237l.028-.125h2.737c.371.013.672.125.77.519l.595 2.836.182.854 1.666-4.21h1.799l-2.674 6.167H4.304L2.788 5.914Zm7.312 5.37H8.399l1.064-6.172h1.7L10.1 11.284Zm6.167-6.021-.232 1.333-.153-.066a3.054 3.054 0 0 0-1.268-.236c-.671 0-.972.269-.98.531 0 .29.365.48.96.762.98.44 1.435.979 1.428 1.681-.014 1.28-1.176 2.108-2.96 2.108-.764-.007-1.5-.158-1.898-.328l.238-1.386.224.099c.553.23.917.328 1.596.328.49 0 1.015-.19 1.022-.604 0-.27-.224-.466-.882-.769-.644-.295-1.505-.788-1.491-1.674C11.878 5.84 13.06 5 14.74 5c.658 0 1.19.138 1.526.263Zm2.26 3.834h1.415c-.07-.308-.392-1.786-.392-1.786l-.12-.531c-.083.23-.23.604-.223.59l-.68 1.727Zm2.1-3.985L22 11.284h-1.575s-.154-.71-.203-.926h-2.184l-.357.926h-1.785l2.527-5.66c.175-.4.483-.512.889-.512h1.316Z",
11081
- fill: "#1434CB"
11082
- }
11083
- )
11084
- ] })
11085
- }
11086
- ) }),
11087
- /* @__PURE__ */ jsx15(Box, { $whiteSpace: "nowrap", children: "Visa **** 4242" })
11088
- ] }),
11089
- /* @__PURE__ */ jsx15(Flex, { $alignItems: "center", children: /* @__PURE__ */ jsx15(Box, { $fontSize: "12px", $color: "#5D5D5D", children: "Expires: 3/30" }) })
11090
- ] })
11091
- }
10914
+ $height: "auto",
10915
+ $padding: `${theme.card.padding / TEXT_BASE_SIZE}rem`,
10916
+ $borderBottomWidth: "1px",
10917
+ $borderStyle: "solid",
10918
+ $borderColor: isLightBackground ? "hsla(0, 0%, 0%, 0.175)" : "hsla(0, 0%, 100%, 0.175)",
10919
+ children: [
10920
+ /* @__PURE__ */ jsx11(Text, { $size: 20, $weight: 600, children: plan.name }),
10921
+ /* @__PURE__ */ jsx11(Text, { $size: 14, children: plan.description }),
10922
+ /* @__PURE__ */ jsxs6(Text, { children: [
10923
+ /* @__PURE__ */ jsx11(Box, { $display: "inline-block", $fontSize: "1.5rem", children: formatCurrency(
10924
+ (planPeriod === "month" ? plan.monthlyPrice : plan.yearlyPrice)?.price ?? 0
10925
+ ) }),
10926
+ /* @__PURE__ */ jsxs6(Box, { $display: "inline-block", $fontSize: "0.75rem", children: [
10927
+ "/",
10928
+ planPeriod
10929
+ ] })
10930
+ ] }),
10931
+ (plan.current || plan.id === currentPlan?.id) && /* @__PURE__ */ jsx11(
10932
+ Flex,
10933
+ {
10934
+ $position: "absolute",
10935
+ $right: "1rem",
10936
+ $top: "1rem",
10937
+ $fontSize: "0.625rem",
10938
+ $color: hexToHSL(theme.primary).l > 50 ? "#000000" : "#FFFFFF",
10939
+ $backgroundColor: theme.primary,
10940
+ $borderRadius: "9999px",
10941
+ $padding: "0.125rem 0.85rem",
10942
+ children: "Current plan"
10943
+ }
10944
+ )
10945
+ ]
10946
+ }
11092
10947
  ),
11093
- /* @__PURE__ */ jsx15(Flex, { children: /* @__PURE__ */ jsx15(
11094
- StyledButton,
10948
+ /* @__PURE__ */ jsx11(
10949
+ Flex,
11095
10950
  {
11096
- $size: "sm",
11097
- $color: "primary",
11098
- $variant: "outline",
11099
- style: {
11100
- whiteSpace: "nowrap",
11101
- paddingLeft: "1rem",
11102
- paddingRight: "1rem"
11103
- },
11104
- children: "Edit"
10951
+ $flexDirection: "column",
10952
+ $position: "relative",
10953
+ $gap: "0.5rem",
10954
+ $flex: "1",
10955
+ $width: "100%",
10956
+ $height: "auto",
10957
+ $padding: "1.5rem",
10958
+ children: plan.entitlements.map((entitlement) => {
10959
+ return /* @__PURE__ */ jsx11(
10960
+ Flex,
10961
+ {
10962
+ $flexWrap: "wrap",
10963
+ $justifyContent: "space-between",
10964
+ $alignItems: "center",
10965
+ $gap: "1rem",
10966
+ children: /* @__PURE__ */ jsxs6(Flex, { $gap: "1rem", children: [
10967
+ entitlement.feature?.icon && /* @__PURE__ */ jsx11(
10968
+ IconRound,
10969
+ {
10970
+ name: entitlement.feature.icon,
10971
+ size: "sm",
10972
+ colors: [
10973
+ theme.primary,
10974
+ isLightBackground ? "hsla(0, 0%, 0%, 0.0625)" : "hsla(0, 0%, 100%, 0.25)"
10975
+ ]
10976
+ }
10977
+ ),
10978
+ /* @__PURE__ */ jsx11(FeatureName, { entitlement })
10979
+ ] })
10980
+ },
10981
+ entitlement.id
10982
+ );
10983
+ })
11105
10984
  }
11106
- ) })
11107
- ] })
11108
- ] })
11109
- }
11110
- ),
11111
- /* @__PURE__ */ jsx15(
11112
- Flex,
11113
- {
11114
- $flexDirection: "column",
11115
- $gap: "1rem",
11116
- $backgroundColor: "#FBFBFB",
11117
- $borderRadius: "0 0 0.5rem 0.5rem",
11118
- $flex: "1",
11119
- $height: "100%",
11120
- children: /* @__PURE__ */ jsxs10(Flex, { $flexDirection: "column", $height: "100%", children: [
11121
- /* @__PURE__ */ jsx15(
11122
- Box,
11123
- {
11124
- $fontSize: "18px",
11125
- $marginBottom: "1.5rem",
11126
- $display: "inline-block",
11127
- $width: "100%",
11128
- children: "Others"
11129
- }
11130
- ),
11131
- /* @__PURE__ */ jsxs10(Flex, { $gap: "1rem", children: [
11132
- /* @__PURE__ */ jsx15(
10985
+ ),
10986
+ /* @__PURE__ */ jsxs6(
11133
10987
  Flex,
11134
10988
  {
11135
- $alignItems: "center",
11136
- $padding: ".5rem 1rem",
11137
- $border: "1px solid #E2E5E9",
11138
- $borderRadius: ".5rem",
11139
- $backgroundColor: "#ffffff",
10989
+ $flexDirection: "column",
10990
+ $position: "relative",
11140
10991
  $gap: "1rem",
11141
10992
  $width: "100%",
11142
- children: /* @__PURE__ */ jsxs10(Flex, { $justifyContent: "space-between", $flex: "1", children: [
11143
- /* @__PURE__ */ jsxs10(Flex, { $alignItems: "center", $gap: "1rem", children: [
11144
- /* @__PURE__ */ jsx15(Box, { $display: "inline-block", children: /* @__PURE__ */ jsx15(
11145
- "svg",
11146
- {
11147
- viewBox: "0 0 24 16",
11148
- fill: "none",
11149
- xmlns: "http://www.w3.org/2000/svg",
11150
- width: "26px",
11151
- height: "auto",
11152
- children: /* @__PURE__ */ jsxs10("g", { children: [
11153
- /* @__PURE__ */ jsx15(
11154
- "rect",
11155
- {
11156
- stroke: "#DDD",
11157
- fill: "#FFF",
11158
- x: ".25",
11159
- y: ".25",
11160
- width: "23",
11161
- height: "15.5",
11162
- rx: "2"
11163
- }
11164
- ),
11165
- /* @__PURE__ */ jsx15(
11166
- "path",
11167
- {
11168
- d: "M2.788 5.914A7.201 7.201 0 0 0 1 5.237l.028-.125h2.737c.371.013.672.125.77.519l.595 2.836.182.854 1.666-4.21h1.799l-2.674 6.167H4.304L2.788 5.914Zm7.312 5.37H8.399l1.064-6.172h1.7L10.1 11.284Zm6.167-6.021-.232 1.333-.153-.066a3.054 3.054 0 0 0-1.268-.236c-.671 0-.972.269-.98.531 0 .29.365.48.96.762.98.44 1.435.979 1.428 1.681-.014 1.28-1.176 2.108-2.96 2.108-.764-.007-1.5-.158-1.898-.328l.238-1.386.224.099c.553.23.917.328 1.596.328.49 0 1.015-.19 1.022-.604 0-.27-.224-.466-.882-.769-.644-.295-1.505-.788-1.491-1.674C11.878 5.84 13.06 5 14.74 5c.658 0 1.19.138 1.526.263Zm2.26 3.834h1.415c-.07-.308-.392-1.786-.392-1.786l-.12-.531c-.083.23-.23.604-.223.59l-.68 1.727Zm2.1-3.985L22 11.284h-1.575s-.154-.71-.203-.926h-2.184l-.357.926h-1.785l2.527-5.66c.175-.4.483-.512.889-.512h1.316Z",
11169
- fill: "#1434CB"
10993
+ $height: "auto",
10994
+ $padding: "1.5rem",
10995
+ children: [
10996
+ plan.id === selectedPlan?.id && /* @__PURE__ */ jsxs6(
10997
+ Flex,
10998
+ {
10999
+ $justifyContent: "center",
11000
+ $alignItems: "center",
11001
+ $gap: "0.25rem",
11002
+ $fontSize: "0.9375rem",
11003
+ $padding: "0.625rem 0",
11004
+ children: [
11005
+ /* @__PURE__ */ jsx11(
11006
+ Icon2,
11007
+ {
11008
+ name: "check-rounded",
11009
+ style: {
11010
+ fontSize: 20,
11011
+ lineHeight: "1",
11012
+ color: theme.primary
11170
11013
  }
11171
- )
11172
- ] })
11173
- }
11174
- ) }),
11175
- /* @__PURE__ */ jsx15(Box, { $whiteSpace: "nowrap", children: "Visa **** 2929" })
11176
- ] }),
11177
- /* @__PURE__ */ jsx15(Flex, { $alignItems: "center", children: /* @__PURE__ */ jsx15(Box, { $fontSize: "12px", $color: "#5D5D5D", children: "Expires: 3/30" }) })
11178
- ] })
11014
+ }
11015
+ ),
11016
+ /* @__PURE__ */ jsx11(
11017
+ Text,
11018
+ {
11019
+ $lineHeight: "1.4",
11020
+ $color: theme.typography.text.color,
11021
+ children: "Selected"
11022
+ }
11023
+ )
11024
+ ]
11025
+ }
11026
+ ),
11027
+ !(plan.current || plan.id === currentPlan?.id) && plan.id !== selectedPlan?.id && /* @__PURE__ */ jsx11(
11028
+ StyledButton,
11029
+ {
11030
+ disabled: plan.valid === false,
11031
+ ...plan.valid === true && {
11032
+ onClick: () => setSelectedPlan(plan)
11033
+ },
11034
+ $size: "sm",
11035
+ $color: "primary",
11036
+ $variant: "outline",
11037
+ children: "Select"
11038
+ }
11039
+ )
11040
+ ]
11179
11041
  }
11180
- ),
11181
- /* @__PURE__ */ jsxs10(Flex, { $gap: "1rem", children: [
11182
- /* @__PURE__ */ jsx15(
11183
- StyledButton,
11042
+ )
11043
+ ]
11044
+ },
11045
+ plan.id
11046
+ );
11047
+ }) })
11048
+ ] }),
11049
+ selectedPlan && checkoutStage === "checkout" && /* @__PURE__ */ jsx11(Fragment, { children: showPaymentForm ? /* @__PURE__ */ jsxs6(Fragment, { children: [
11050
+ /* @__PURE__ */ jsx11(
11051
+ PaymentForm,
11052
+ {
11053
+ plan: selectedPlan,
11054
+ period: planPeriod,
11055
+ onConfirm: (value) => {
11056
+ setPaymentMethodId(value);
11057
+ }
11058
+ }
11059
+ ),
11060
+ typeof data.subscription?.paymentMethod !== "undefined" && /* @__PURE__ */ jsx11(
11061
+ Box,
11062
+ {
11063
+ tabIndex: 0,
11064
+ onClick: () => setShowPaymentForm(false),
11065
+ $cursor: "pointer",
11066
+ children: /* @__PURE__ */ jsx11(
11067
+ Text,
11068
+ {
11069
+ $font: theme.typography.link.fontFamily,
11070
+ $size: theme.typography.link.fontSize,
11071
+ $weight: theme.typography.link.fontWeight,
11072
+ $color: theme.typography.link.color,
11073
+ children: "Use existing payment method"
11074
+ }
11075
+ )
11076
+ }
11077
+ )
11078
+ ] }) : /* @__PURE__ */ jsxs6(Fragment, { children: [
11079
+ /* @__PURE__ */ jsx11(PaymentMethod, {}),
11080
+ /* @__PURE__ */ jsx11(
11081
+ Box,
11082
+ {
11083
+ tabIndex: 0,
11084
+ onClick: () => setShowPaymentForm(true),
11085
+ $cursor: "pointer",
11086
+ children: /* @__PURE__ */ jsx11(
11087
+ Text,
11088
+ {
11089
+ $font: theme.typography.link.fontFamily,
11090
+ $size: theme.typography.link.fontSize,
11091
+ $weight: theme.typography.link.fontWeight,
11092
+ $color: theme.typography.link.color,
11093
+ children: "Change payment method"
11094
+ }
11095
+ )
11096
+ }
11097
+ )
11098
+ ] }) })
11099
+ ]
11100
+ }
11101
+ ),
11102
+ /* @__PURE__ */ jsxs6(
11103
+ Flex,
11104
+ {
11105
+ $flexDirection: "column",
11106
+ $backgroundColor: theme.card.background,
11107
+ $borderRadius: "0 0 0.5rem",
11108
+ $width: "21.5rem",
11109
+ $boxShadow: "0px 1px 20px 0px #1018280F, 0px 1px 3px 0px #1018281A;",
11110
+ children: [
11111
+ /* @__PURE__ */ jsxs6(
11112
+ Flex,
11113
+ {
11114
+ $flexDirection: "column",
11115
+ $position: "relative",
11116
+ $gap: "1rem",
11117
+ $width: "100%",
11118
+ $height: "auto",
11119
+ $padding: "1.5rem",
11120
+ $borderBottomWidth: "1px",
11121
+ $borderStyle: "solid",
11122
+ $borderColor: isLightBackground ? "hsla(0, 0%, 0%, 0.1)" : "hsla(0, 0%, 100%, 0.2)",
11123
+ children: [
11124
+ /* @__PURE__ */ jsx11(Flex, { $justifyContent: "space-between", children: /* @__PURE__ */ jsx11(
11125
+ Text,
11126
+ {
11127
+ as: "h3",
11128
+ $font: theme.typography.heading3.fontFamily,
11129
+ $size: theme.typography.heading3.fontSize,
11130
+ $weight: theme.typography.heading3.fontWeight,
11131
+ $color: theme.typography.heading3.color,
11132
+ children: "Subscription"
11133
+ }
11134
+ ) }),
11135
+ planPeriodOptions.length > 1 && /* @__PURE__ */ jsxs6(
11136
+ Flex,
11137
+ {
11138
+ $borderWidth: "1px",
11139
+ $borderStyle: "solid",
11140
+ $borderColor: isLightBackground ? "hsla(0, 0%, 0%, 0.1)" : "hsla(0, 0%, 100%, 0.2)",
11141
+ $borderRadius: "2.5rem",
11142
+ $cursor: "pointer",
11143
+ children: [
11144
+ /* @__PURE__ */ jsx11(
11145
+ Flex,
11184
11146
  {
11185
- $size: "sm",
11186
- $color: "primary",
11187
- $variant: "outline",
11188
- style: {
11189
- whiteSpace: "nowrap",
11190
- paddingLeft: "1rem",
11191
- paddingRight: "1rem"
11147
+ onClick: () => setPlanPeriod("month"),
11148
+ $justifyContent: "center",
11149
+ $alignItems: "center",
11150
+ $padding: "0.25rem 0.5rem",
11151
+ $flex: "1",
11152
+ ...planPeriod === "month" && {
11153
+ $backgroundColor: isLightBackground ? "hsla(0, 0%, 0%, 0.075)" : "hsla(0, 0%, 100%, 0.15)"
11192
11154
  },
11193
- children: "Make Default"
11155
+ $borderRadius: "2.5rem",
11156
+ children: /* @__PURE__ */ jsx11(
11157
+ Text,
11158
+ {
11159
+ $font: theme.typography.text.fontFamily,
11160
+ $size: 14,
11161
+ $weight: planPeriod === "month" ? 600 : 400,
11162
+ $color: theme.typography.text.color,
11163
+ children: "Billed monthly"
11164
+ }
11165
+ )
11194
11166
  }
11195
11167
  ),
11196
- /* @__PURE__ */ jsx15(
11197
- StyledButton,
11168
+ /* @__PURE__ */ jsx11(
11169
+ Flex,
11198
11170
  {
11199
- $size: "sm",
11200
- $color: "primary",
11201
- $variant: "outline",
11202
- style: {
11203
- whiteSpace: "nowrap",
11204
- paddingLeft: "1rem",
11205
- paddingRight: "1rem"
11171
+ onClick: () => setPlanPeriod("year"),
11172
+ $justifyContent: "center",
11173
+ $alignItems: "center",
11174
+ $padding: "0.25rem 0.5rem",
11175
+ $flex: "1",
11176
+ ...planPeriod === "year" && {
11177
+ $backgroundColor: isLightBackground ? "hsla(0, 0%, 0%, 0.075)" : "hsla(0, 0%, 100%, 0.15)"
11206
11178
  },
11207
- children: "Edit"
11179
+ $borderRadius: "2.5rem",
11180
+ children: /* @__PURE__ */ jsx11(
11181
+ Text,
11182
+ {
11183
+ $font: theme.typography.text.fontFamily,
11184
+ $size: 14,
11185
+ $weight: planPeriod === "year" ? 600 : 400,
11186
+ $color: theme.typography.text.color,
11187
+ children: "Billed yearly"
11188
+ }
11189
+ )
11208
11190
  }
11209
11191
  )
11210
- ] })
11211
- ] })
11212
- ] })
11213
- }
11214
- )
11192
+ ]
11193
+ }
11194
+ ),
11195
+ savingsPercentage > 0 && /* @__PURE__ */ jsx11(Box, { children: /* @__PURE__ */ jsx11(
11196
+ Text,
11197
+ {
11198
+ $font: theme.typography.text.fontFamily,
11199
+ $size: 11,
11200
+ $weight: theme.typography.text.fontWeight,
11201
+ $color: theme.primary,
11202
+ children: planPeriod === "month" ? `Save up to ${savingsPercentage}% with yearly billing` : `You are saving ${savingsPercentage}% with yearly billing`
11203
+ }
11204
+ ) })
11205
+ ]
11206
+ }
11207
+ ),
11208
+ /* @__PURE__ */ jsxs6(
11209
+ Flex,
11210
+ {
11211
+ $flexDirection: "column",
11212
+ $position: "relative",
11213
+ $gap: "1rem",
11214
+ $width: "100%",
11215
+ $height: "auto",
11216
+ $padding: "1.5rem",
11217
+ $flex: "1",
11218
+ $borderBottomWidth: "1px",
11219
+ $borderStyle: "solid",
11220
+ $borderColor: isLightBackground ? "hsla(0, 0%, 0%, 0.1)" : "hsla(0, 0%, 100%, 0.2)",
11221
+ children: [
11222
+ /* @__PURE__ */ jsx11(Box, { $opacity: "0.625", children: /* @__PURE__ */ jsx11(
11223
+ Text,
11224
+ {
11225
+ $font: theme.typography.text.fontFamily,
11226
+ $size: 14,
11227
+ $weight: theme.typography.text.fontWeight,
11228
+ $color: theme.typography.text.color,
11229
+ children: "Plan"
11230
+ }
11231
+ ) }),
11232
+ /* @__PURE__ */ jsxs6(Flex, { $flexDirection: "column", $gap: "0.5rem", children: [
11233
+ currentPlan && /* @__PURE__ */ jsxs6(Flex, { $justifyContent: "space-between", $alignItems: "center", children: [
11234
+ /* @__PURE__ */ jsx11(
11235
+ Flex,
11236
+ {
11237
+ ...selectedPlan && {
11238
+ $opacity: "0.625",
11239
+ $textDecoration: "line-through"
11240
+ },
11241
+ children: /* @__PURE__ */ jsx11(
11242
+ Text,
11243
+ {
11244
+ $font: theme.typography.heading4.fontFamily,
11245
+ $size: theme.typography.heading4.fontSize,
11246
+ $weight: theme.typography.heading4.fontWeight,
11247
+ $color: theme.typography.heading4.color,
11248
+ children: currentPlan.name
11249
+ }
11250
+ )
11251
+ }
11252
+ ),
11253
+ typeof currentPlan.planPrice === "number" && currentPlan.planPeriod && /* @__PURE__ */ jsx11(Flex, { children: /* @__PURE__ */ jsxs6(
11254
+ Text,
11255
+ {
11256
+ $font: theme.typography.text.fontFamily,
11257
+ $size: theme.typography.text.fontSize,
11258
+ $weight: theme.typography.text.fontWeight,
11259
+ $color: theme.typography.text.color,
11260
+ children: [
11261
+ formatCurrency(currentPlan.planPrice),
11262
+ "/",
11263
+ currentPlan.planPeriod
11264
+ ]
11265
+ }
11266
+ ) })
11267
+ ] }),
11268
+ selectedPlan && /* @__PURE__ */ jsxs6(Fragment, { children: [
11269
+ /* @__PURE__ */ jsx11(
11270
+ Box,
11271
+ {
11272
+ $width: "100%",
11273
+ $textAlign: "left",
11274
+ $opacity: "50%",
11275
+ $marginBottom: "-0.25rem",
11276
+ $marginTop: "-0.25rem",
11277
+ children: /* @__PURE__ */ jsx11(
11278
+ Icon2,
11279
+ {
11280
+ name: "arrow-down",
11281
+ style: {
11282
+ display: "inline-block"
11283
+ }
11284
+ }
11285
+ )
11286
+ }
11287
+ ),
11288
+ /* @__PURE__ */ jsxs6(Flex, { $justifyContent: "space-between", $alignItems: "center", children: [
11289
+ /* @__PURE__ */ jsx11(Flex, { children: /* @__PURE__ */ jsx11(
11290
+ Text,
11291
+ {
11292
+ $font: theme.typography.heading4.fontFamily,
11293
+ $size: theme.typography.heading4.fontSize,
11294
+ $weight: theme.typography.heading4.fontWeight,
11295
+ $color: theme.typography.heading4.color,
11296
+ children: selectedPlan.name
11297
+ }
11298
+ ) }),
11299
+ /* @__PURE__ */ jsx11(Flex, { children: /* @__PURE__ */ jsxs6(
11300
+ Text,
11301
+ {
11302
+ $font: theme.typography.text.fontFamily,
11303
+ $size: theme.typography.text.fontSize,
11304
+ $weight: theme.typography.text.fontWeight,
11305
+ $color: theme.typography.text.color,
11306
+ children: [
11307
+ formatCurrency(
11308
+ (planPeriod === "month" ? selectedPlan.monthlyPrice : selectedPlan.yearlyPrice)?.price ?? 0
11309
+ ),
11310
+ "/",
11311
+ planPeriod
11312
+ ]
11313
+ }
11314
+ ) })
11315
+ ] })
11316
+ ] })
11317
+ ] })
11318
+ ]
11319
+ }
11320
+ ),
11321
+ /* @__PURE__ */ jsxs6(
11322
+ Flex,
11323
+ {
11324
+ $flexDirection: "column",
11325
+ $position: "relative",
11326
+ $gap: "1rem",
11327
+ $width: "100%",
11328
+ $height: "auto",
11329
+ $padding: "1.5rem",
11330
+ children: [
11331
+ selectedPlan && /* @__PURE__ */ jsxs6(Flex, { $justifyContent: "space-between", children: [
11332
+ /* @__PURE__ */ jsx11(Box, { $opacity: "0.625", children: /* @__PURE__ */ jsxs6(
11333
+ Text,
11334
+ {
11335
+ $font: theme.typography.text.fontFamily,
11336
+ $size: theme.typography.text.fontSize,
11337
+ $weight: theme.typography.text.fontWeight,
11338
+ $color: theme.typography.text.color,
11339
+ children: [
11340
+ planPeriod === "month" ? "Monthly" : "Yearly",
11341
+ " total:",
11342
+ " "
11343
+ ]
11344
+ }
11345
+ ) }),
11346
+ /* @__PURE__ */ jsx11(Box, { children: /* @__PURE__ */ jsxs6(
11347
+ Text,
11348
+ {
11349
+ $font: theme.typography.text.fontFamily,
11350
+ $size: theme.typography.text.fontSize,
11351
+ $weight: theme.typography.text.fontWeight,
11352
+ $color: theme.typography.text.color,
11353
+ children: [
11354
+ formatCurrency(
11355
+ (planPeriod === "month" ? selectedPlan.monthlyPrice : selectedPlan.yearlyPrice)?.price ?? 0
11356
+ ),
11357
+ "/",
11358
+ planPeriod
11359
+ ]
11360
+ }
11361
+ ) })
11362
+ ] }),
11363
+ checkoutStage === "plan" ? /* @__PURE__ */ jsx11(
11364
+ StyledButton,
11365
+ {
11366
+ disabled: !selectedPlan,
11367
+ ...selectedPlan && {
11368
+ onClick: () => setCheckoutStage("checkout")
11369
+ },
11370
+ children: /* @__PURE__ */ jsxs6(
11371
+ Flex,
11372
+ {
11373
+ $gap: "0.5rem",
11374
+ $justifyContent: "center",
11375
+ $alignItems: "center",
11376
+ $padding: "0 1rem",
11377
+ children: [
11378
+ /* @__PURE__ */ jsx11(Text, { $align: "left", $lineHeight: 1, children: "Next: Checkout" }),
11379
+ /* @__PURE__ */ jsx11(Icon2, { name: "arrow-right" })
11380
+ ]
11381
+ }
11382
+ )
11383
+ }
11384
+ ) : /* @__PURE__ */ jsx11(
11385
+ StyledButton,
11386
+ {
11387
+ ...allowCheckout ? {
11388
+ onClick: async () => {
11389
+ const priceId = (planPeriod === "month" ? selectedPlan?.monthlyPrice : selectedPlan?.yearlyPrice)?.id;
11390
+ if (!priceId) {
11391
+ return;
11392
+ }
11393
+ try {
11394
+ setIsLoading(true);
11395
+ await api.checkout({
11396
+ changeSubscriptionRequestBody: {
11397
+ newPlanId: selectedPlan.id,
11398
+ newPriceId: priceId,
11399
+ ...paymentMethodId && { paymentMethodId }
11400
+ }
11401
+ });
11402
+ setLayout("success");
11403
+ } catch {
11404
+ setError(
11405
+ "Error processing payment. Please try a different payment method."
11406
+ );
11407
+ } finally {
11408
+ setIsLoading(false);
11409
+ }
11410
+ }
11411
+ } : { disabled: true },
11412
+ children: "Pay now"
11413
+ }
11414
+ ),
11415
+ /* @__PURE__ */ jsx11(Box, { $opacity: "0.625", children: /* @__PURE__ */ jsx11(
11416
+ Text,
11417
+ {
11418
+ $font: theme.typography.text.fontFamily,
11419
+ $size: theme.typography.text.fontSize,
11420
+ $weight: theme.typography.text.fontWeight,
11421
+ $color: theme.typography.text.color,
11422
+ children: "Discounts & credits applied at checkout"
11423
+ }
11424
+ ) }),
11425
+ error && /* @__PURE__ */ jsx11(Box, { children: /* @__PURE__ */ jsx11(
11426
+ Text,
11427
+ {
11428
+ $font: theme.typography.text.fontFamily,
11429
+ $size: theme.typography.text.fontSize,
11430
+ $weight: 500,
11431
+ $color: "#DB6669",
11432
+ children: error
11433
+ }
11434
+ ) })
11435
+ ]
11436
+ }
11437
+ )
11438
+ ]
11439
+ }
11440
+ )
11441
+ ] })
11442
+ ] });
11443
+ };
11444
+
11445
+ // src/components/elements/plan-manager/PlanManager.tsx
11446
+ import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
11447
+ var resolveDesignProps2 = (props) => {
11448
+ return {
11449
+ header: {
11450
+ isVisible: props.header?.isVisible ?? true,
11451
+ title: {
11452
+ fontStyle: props.header?.title?.fontStyle ?? "heading1"
11453
+ },
11454
+ description: {
11455
+ isVisible: props.header?.description?.isVisible ?? true,
11456
+ fontStyle: props.header?.description?.fontStyle ?? "text"
11457
+ },
11458
+ price: {
11459
+ isVisible: props.header?.price?.isVisible ?? true,
11460
+ fontStyle: props.header?.price?.fontStyle ?? "text"
11461
+ }
11462
+ },
11463
+ addOns: {
11464
+ isVisible: props.addOns?.isVisible ?? true,
11465
+ fontStyle: props.addOns?.fontStyle ?? "heading4",
11466
+ showLabel: props.addOns?.showLabel ?? true
11467
+ },
11468
+ callToAction: {
11469
+ isVisible: props.callToAction?.isVisible ?? true,
11470
+ buttonSize: props.callToAction?.buttonSize ?? "lg",
11471
+ buttonStyle: props.callToAction?.buttonStyle ?? "primary"
11472
+ }
11473
+ };
11474
+ };
11475
+ var PlanManager = forwardRef2(({ children, className, portal, ...rest }, ref) => {
11476
+ const props = resolveDesignProps2(rest);
11477
+ const theme = nt();
11478
+ const { data, layout, stripe, setLayout } = useEmbed();
11479
+ const { currentPlan, canChangePlan } = useMemo7(() => {
11480
+ return {
11481
+ currentPlan: data.company?.plan,
11482
+ canChangePlan: stripe !== null
11483
+ };
11484
+ }, [data.company, stripe]);
11485
+ return /* @__PURE__ */ jsxs7("div", { ref, className, children: [
11486
+ /* @__PURE__ */ jsx12(
11487
+ Flex,
11488
+ {
11489
+ $flexDirection: "column",
11490
+ $gap: "0.75rem",
11491
+ ...canChangePlan && { $margin: "0 0 0.5rem" },
11492
+ children: props.header.isVisible && currentPlan && /* @__PURE__ */ jsxs7(
11493
+ Flex,
11494
+ {
11495
+ $justifyContent: "space-between",
11496
+ $alignItems: "center",
11497
+ $width: "100%",
11498
+ ...canChangePlan && { $margin: "0 0 1.5rem" },
11499
+ children: [
11500
+ /* @__PURE__ */ jsxs7("div", { children: [
11501
+ /* @__PURE__ */ jsx12(Box, { $margin: "0 0 0.75rem", children: /* @__PURE__ */ jsx12(
11502
+ Text,
11503
+ {
11504
+ $font: theme.typography[props.header.title.fontStyle].fontFamily,
11505
+ $size: theme.typography[props.header.title.fontStyle].fontSize,
11506
+ $weight: theme.typography[props.header.title.fontStyle].fontWeight,
11507
+ $color: theme.typography[props.header.title.fontStyle].color,
11508
+ $lineHeight: 1,
11509
+ children: currentPlan.name
11510
+ }
11511
+ ) }),
11512
+ props.header.description.isVisible && currentPlan.description && /* @__PURE__ */ jsx12(
11513
+ Text,
11514
+ {
11515
+ $font: theme.typography[props.header.description.fontStyle].fontFamily,
11516
+ $size: theme.typography[props.header.description.fontStyle].fontSize,
11517
+ $weight: theme.typography[props.header.description.fontStyle].fontWeight,
11518
+ $color: theme.typography[props.header.description.fontStyle].color,
11519
+ children: currentPlan.description
11520
+ }
11521
+ )
11522
+ ] }),
11523
+ props.header.price.isVisible && typeof currentPlan.planPrice === "number" && currentPlan.planPeriod && /* @__PURE__ */ jsxs7(
11524
+ Text,
11525
+ {
11526
+ $font: theme.typography[props.header.price.fontStyle].fontFamily,
11527
+ $size: theme.typography[props.header.price.fontStyle].fontSize,
11528
+ $weight: theme.typography[props.header.price.fontStyle].fontWeight,
11529
+ $color: theme.typography[props.header.price.fontStyle].color,
11530
+ children: [
11531
+ formatCurrency(currentPlan.planPrice),
11532
+ "/",
11533
+ currentPlan.planPeriod
11534
+ ]
11535
+ }
11536
+ )
11537
+ ]
11538
+ }
11539
+ )
11540
+ }
11541
+ ),
11542
+ canChangePlan && props.callToAction.isVisible && /* @__PURE__ */ jsx12(
11543
+ StyledButton,
11544
+ {
11545
+ onClick: () => {
11546
+ setLayout("checkout");
11547
+ },
11548
+ $size: props.callToAction.buttonSize,
11549
+ $color: props.callToAction.buttonStyle,
11550
+ children: "Change Plan"
11551
+ }
11552
+ ),
11553
+ canChangePlan && layout === "checkout" && createPortal2(/* @__PURE__ */ jsx12(CheckoutDialog, {}), portal || document.body)
11554
+ ] });
11555
+ });
11556
+
11557
+ // src/components/elements/included-features/IncludedFeatures.tsx
11558
+ import { forwardRef as forwardRef3, useMemo as useMemo8 } from "react";
11559
+ var import_pluralize2 = __toESM(require_pluralize());
11560
+ import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
11561
+ function resolveDesignProps3(props) {
11562
+ return {
11563
+ header: {
11564
+ isVisible: props.header?.isVisible ?? true,
11565
+ fontStyle: props.header?.fontStyle ?? "heading4",
11566
+ text: props.header?.text ?? "Included features"
11567
+ },
11568
+ icons: {
11569
+ isVisible: props.icons?.isVisible ?? true,
11570
+ fontStyle: props.icons?.fontStyle ?? "heading5",
11571
+ style: props.icons?.style ?? "light"
11572
+ },
11573
+ entitlement: {
11574
+ isVisible: props.entitlement?.isVisible ?? true,
11575
+ fontStyle: props.entitlement?.fontStyle ?? "text"
11576
+ },
11577
+ usage: {
11578
+ isVisible: props.usage?.isVisible ?? true,
11579
+ fontStyle: props.usage?.fontStyle ?? "heading6"
11580
+ }
11581
+ };
11582
+ }
11583
+ var IncludedFeatures = forwardRef3(({ className, ...rest }, ref) => {
11584
+ const props = resolveDesignProps3(rest);
11585
+ const theme = nt();
11586
+ const { data } = useEmbed();
11587
+ const features = useMemo8(() => {
11588
+ return (data.featureUsage?.features || []).map(
11589
+ ({
11590
+ access,
11591
+ allocation,
11592
+ allocationType,
11593
+ feature,
11594
+ period,
11595
+ usage = 0,
11596
+ ...props2
11597
+ }) => {
11598
+ return {
11599
+ access,
11600
+ allocation,
11601
+ allocationType,
11602
+ feature,
11603
+ period,
11604
+ /**
11605
+ * @TODO: resolve feature price
11606
+ */
11607
+ price: void 0,
11608
+ usage,
11609
+ ...props2
11610
+ };
11611
+ }
11612
+ );
11613
+ }, [data.featureUsage]);
11614
+ const isLightBackground = useMemo8(() => {
11615
+ return hexToHSL(theme.card.background).l > 50;
11616
+ }, [theme.card.background]);
11617
+ return /* @__PURE__ */ jsxs8(Flex, { ref, className, $flexDirection: "column", $gap: "1.5rem", children: [
11618
+ props.header.isVisible && /* @__PURE__ */ jsx13(Box, { children: /* @__PURE__ */ jsx13(
11619
+ Text,
11620
+ {
11621
+ $font: theme.typography[props.header.fontStyle].fontFamily,
11622
+ $size: theme.typography[props.header.fontStyle].fontSize,
11623
+ $weight: theme.typography[props.header.fontStyle].fontWeight,
11624
+ $color: theme.typography[props.header.fontStyle].color,
11625
+ children: props.header.text
11626
+ }
11627
+ ) }),
11628
+ features.reduce(
11629
+ (acc, { allocation, allocationType, feature, usage }, index) => {
11630
+ if (!allocationType) {
11631
+ return acc;
11632
+ }
11633
+ return [
11634
+ ...acc,
11635
+ /* @__PURE__ */ jsxs8(
11636
+ Flex,
11637
+ {
11638
+ $flexWrap: "wrap",
11639
+ $justifyContent: "space-between",
11640
+ $alignItems: "center",
11641
+ $gap: "1rem",
11642
+ children: [
11643
+ /* @__PURE__ */ jsxs8(Flex, { $gap: "1rem", children: [
11644
+ props.icons.isVisible && feature?.icon && /* @__PURE__ */ jsx13(
11645
+ IconRound,
11646
+ {
11647
+ name: feature.icon,
11648
+ size: "sm",
11649
+ colors: [
11650
+ theme.primary,
11651
+ isLightBackground ? "hsla(0, 0%, 0%, 0.0625)" : "hsla(0, 0%, 100%, 0.25)"
11652
+ ]
11653
+ }
11654
+ ),
11655
+ feature?.name && /* @__PURE__ */ jsx13(Flex, { $alignItems: "center", children: /* @__PURE__ */ jsx13(
11656
+ Text,
11657
+ {
11658
+ $font: theme.typography[props.icons.fontStyle].fontFamily,
11659
+ $size: theme.typography[props.icons.fontStyle].fontSize,
11660
+ $weight: theme.typography[props.icons.fontStyle].fontWeight,
11661
+ $color: theme.typography[props.icons.fontStyle].color,
11662
+ children: feature.name
11663
+ }
11664
+ ) })
11665
+ ] }),
11666
+ allocationType === "numeric" && feature?.name && /* @__PURE__ */ jsxs8(Box, { $textAlign: "right", children: [
11667
+ props.entitlement.isVisible && /* @__PURE__ */ jsx13(
11668
+ Text,
11669
+ {
11670
+ as: Box,
11671
+ $font: theme.typography[props.entitlement.fontStyle].fontFamily,
11672
+ $size: theme.typography[props.entitlement.fontStyle].fontSize,
11673
+ $weight: theme.typography[props.entitlement.fontStyle].fontWeight,
11674
+ $lineHeight: 1.5,
11675
+ $color: theme.typography[props.entitlement.fontStyle].color,
11676
+ children: typeof allocation === "number" ? (0, import_pluralize2.default)(feature.name, allocation, true) : `Unlimited ${(0, import_pluralize2.default)(feature.name)}`
11677
+ }
11678
+ ),
11679
+ props.usage.isVisible && /* @__PURE__ */ jsx13(
11680
+ Text,
11681
+ {
11682
+ as: Box,
11683
+ $font: theme.typography[props.usage.fontStyle].fontFamily,
11684
+ $size: theme.typography[props.usage.fontStyle].fontSize,
11685
+ $weight: theme.typography[props.usage.fontStyle].fontWeight,
11686
+ $lineHeight: 1.5,
11687
+ $color: theme.typography[props.usage.fontStyle].color,
11688
+ children: typeof allocation === "number" ? `${usage} of ${allocation} used` : `${usage} used`
11689
+ }
11690
+ )
11691
+ ] })
11692
+ ]
11693
+ },
11694
+ index
11695
+ )
11696
+ ];
11697
+ },
11698
+ []
11699
+ )
11700
+ ] });
11701
+ });
11702
+
11703
+ // src/components/elements/metered-features/MeteredFeatures.tsx
11704
+ import { forwardRef as forwardRef4, useMemo as useMemo9 } from "react";
11705
+ import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
11706
+ function resolveDesignProps4(props) {
11707
+ return {
11708
+ isVisible: props.isVisible ?? true,
11709
+ header: {
11710
+ fontStyle: props.header?.fontStyle ?? "heading2"
11711
+ },
11712
+ description: {
11713
+ isVisible: props.description?.isVisible ?? true,
11714
+ fontStyle: props.description?.fontStyle ?? "text"
11715
+ },
11716
+ icon: {
11717
+ isVisible: props.icon?.isVisible ?? true
11718
+ },
11719
+ allocation: {
11720
+ isVisible: props.allocation?.isVisible ?? true,
11721
+ fontStyle: props.allocation?.fontStyle ?? "heading4"
11722
+ },
11723
+ usage: {
11724
+ isVisible: props.usage?.isVisible ?? true,
11725
+ fontStyle: props.usage?.fontStyle ?? "heading5"
11726
+ },
11727
+ callToAction: {
11728
+ isVisible: props.callToAction?.isVisible ?? true,
11729
+ buttonSize: props.callToAction?.buttonSize ?? "md",
11730
+ buttonStyle: props.callToAction?.buttonStyle ?? "primary"
11731
+ }
11732
+ };
11733
+ }
11734
+ var MeteredFeatures = forwardRef4(({ className, ...rest }, ref) => {
11735
+ const props = resolveDesignProps4(rest);
11736
+ const theme = nt();
11737
+ const { data } = useEmbed();
11738
+ const features = useMemo9(() => {
11739
+ return (data.featureUsage?.features || []).map(
11740
+ ({
11741
+ access,
11742
+ allocation,
11743
+ allocationType,
11744
+ feature,
11745
+ period,
11746
+ usage,
11747
+ ...props2
11748
+ }) => {
11749
+ return {
11750
+ access,
11751
+ allocation,
11752
+ allocationType,
11753
+ feature,
11754
+ period,
11755
+ /**
11756
+ * @TODO: resolve feature price
11757
+ */
11758
+ price: void 0,
11759
+ usage,
11760
+ ...props2
11761
+ };
11762
+ }
11763
+ );
11764
+ }, [data.featureUsage]);
11765
+ return /* @__PURE__ */ jsx14(Flex, { ref, className, $flexDirection: "column", $gap: "1.5rem", children: features.reduce(
11766
+ (acc, { allocation, allocationType, feature, usage }, index) => {
11767
+ if (!props.isVisible || allocationType !== "numeric" || typeof allocation !== "number") {
11768
+ return acc;
11769
+ }
11770
+ return [
11771
+ ...acc,
11772
+ /* @__PURE__ */ jsxs9(Flex, { $gap: "1.5rem", children: [
11773
+ props.icon.isVisible && feature?.icon && /* @__PURE__ */ jsx14(Box, { $flexShrink: "0", children: /* @__PURE__ */ jsx14(IconRound, { name: feature.icon, size: "sm" }) }),
11774
+ /* @__PURE__ */ jsxs9(Box, { $flexGrow: "1", children: [
11775
+ /* @__PURE__ */ jsxs9(Flex, { children: [
11776
+ feature?.name && /* @__PURE__ */ jsxs9(Box, { $flexGrow: "1", children: [
11777
+ /* @__PURE__ */ jsx14(
11778
+ Text,
11779
+ {
11780
+ as: Box,
11781
+ $font: theme.typography[props.header.fontStyle].fontFamily,
11782
+ $size: theme.typography[props.header.fontStyle].fontSize,
11783
+ $weight: theme.typography[props.header.fontStyle].fontWeight,
11784
+ $color: theme.typography[props.header.fontStyle].color,
11785
+ children: feature.name
11786
+ }
11787
+ ),
11788
+ props.description.isVisible && /* @__PURE__ */ jsx14(
11789
+ Text,
11790
+ {
11791
+ as: Box,
11792
+ $font: theme.typography[props.description.fontStyle].fontFamily,
11793
+ $size: theme.typography[props.description.fontStyle].fontSize,
11794
+ $weight: theme.typography[props.description.fontStyle].fontWeight,
11795
+ $color: theme.typography[props.description.fontStyle].color,
11796
+ children: feature.description
11797
+ }
11798
+ )
11799
+ ] }),
11800
+ allocationType === "numeric" && feature?.name && /* @__PURE__ */ jsxs9(Box, { $textAlign: "right", children: [
11801
+ props.allocation.isVisible && /* @__PURE__ */ jsx14(
11802
+ Text,
11803
+ {
11804
+ as: Box,
11805
+ $font: theme.typography[props.allocation.fontStyle].fontFamily,
11806
+ $size: theme.typography[props.allocation.fontStyle].fontSize,
11807
+ $weight: theme.typography[props.allocation.fontStyle].fontWeight,
11808
+ $color: theme.typography[props.allocation.fontStyle].color,
11809
+ children: typeof allocation === "number" ? `${allocation} ${feature.name}` : `Unlimited ${feature.name}`
11810
+ }
11811
+ ),
11812
+ props.usage.isVisible && /* @__PURE__ */ jsx14(
11813
+ Text,
11814
+ {
11815
+ as: Box,
11816
+ $font: theme.typography[props.usage.fontStyle].fontFamily,
11817
+ $size: theme.typography[props.usage.fontStyle].fontSize,
11818
+ $weight: theme.typography[props.usage.fontStyle].fontWeight,
11819
+ $color: theme.typography[props.usage.fontStyle].color,
11820
+ children: typeof allocation === "number" ? `${usage} of ${allocation} used` : `${usage} used`
11821
+ }
11822
+ )
11823
+ ] })
11824
+ ] }),
11825
+ typeof usage === "number" && typeof allocation === "number" && /* @__PURE__ */ jsx14(Box, { children: /* @__PURE__ */ jsx14(
11826
+ ProgressBar,
11827
+ {
11828
+ progress: usage / allocation * 100,
11829
+ value: usage,
11830
+ total: allocation,
11831
+ color: "blue"
11832
+ }
11833
+ ) })
11834
+ ] })
11835
+ ] }, index)
11836
+ ];
11837
+ },
11838
+ []
11839
+ ) });
11840
+ });
11841
+
11842
+ // src/components/elements/upcoming-bill/UpcomingBill.tsx
11843
+ import { forwardRef as forwardRef5, useMemo as useMemo10 } from "react";
11844
+ import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
11845
+ function resolveDesignProps5(props) {
11846
+ return {
11847
+ header: {
11848
+ isVisible: props.header?.isVisible ?? true,
11849
+ fontStyle: props.header?.fontStyle ?? "heading4",
11850
+ prefix: props.header?.prefix ?? "Next bill due"
11851
+ },
11852
+ price: {
11853
+ isVisible: props.price?.isVisible ?? true,
11854
+ fontStyle: props.price?.fontStyle ?? "heading1"
11855
+ },
11856
+ contractEndDate: {
11857
+ isVisible: props.contractEndDate?.isVisible ?? true,
11858
+ fontStyle: props.contractEndDate?.fontStyle ?? "heading6",
11859
+ prefix: props.contractEndDate?.prefix ?? "Contract ends"
11860
+ }
11861
+ };
11862
+ }
11863
+ var UpcomingBill = forwardRef5(({ className, ...rest }, ref) => {
11864
+ const props = resolveDesignProps5(rest);
11865
+ const theme = nt();
11866
+ const { data, stripe } = useEmbed();
11867
+ const { upcomingInvoice } = useMemo10(() => {
11868
+ return {
11869
+ upcomingInvoice: {
11870
+ ...data.upcomingInvoice?.amountDue && {
11871
+ amountDue: data.upcomingInvoice.amountDue
11872
+ },
11873
+ ...data.subscription?.interval && {
11874
+ interval: data.subscription.interval
11875
+ },
11876
+ ...data.upcomingInvoice?.dueDate && {
11877
+ dueDate: toPrettyDate(new Date(data.upcomingInvoice.dueDate))
11878
+ }
11879
+ }
11880
+ };
11881
+ }, [data.subscription, data.upcomingInvoice]);
11882
+ if (!stripe || !upcomingInvoice.amountDue || !upcomingInvoice.dueDate) {
11883
+ return null;
11884
+ }
11885
+ return /* @__PURE__ */ jsxs10("div", { ref, className, children: [
11886
+ props.header.isVisible && upcomingInvoice.dueDate && /* @__PURE__ */ jsx15(
11887
+ Flex,
11888
+ {
11889
+ $justifyContent: "space-between",
11890
+ $alignItems: "center",
11891
+ $margin: "0 0 0.75rem",
11892
+ children: /* @__PURE__ */ jsxs10(
11893
+ Text,
11894
+ {
11895
+ $font: theme.typography[props.header.fontStyle].fontFamily,
11896
+ $size: theme.typography[props.header.fontStyle].fontSize,
11897
+ $weight: theme.typography[props.header.fontStyle].fontWeight,
11898
+ $color: theme.typography[props.header.fontStyle].color,
11899
+ children: [
11900
+ props.header.prefix,
11901
+ " ",
11902
+ upcomingInvoice.dueDate
11215
11903
  ]
11216
11904
  }
11217
11905
  )
11218
- ] }),
11219
- portal || document.body
11220
- )
11906
+ }
11907
+ ),
11908
+ upcomingInvoice.amountDue && /* @__PURE__ */ jsxs10(Flex, { $justifyContent: "space-between", $alignItems: "start", $gap: "1rem", children: [
11909
+ props.price.isVisible && /* @__PURE__ */ jsx15(Flex, { $alignItems: "end", $flexGrow: "1", children: /* @__PURE__ */ jsx15(
11910
+ Text,
11911
+ {
11912
+ $font: theme.typography[props.price.fontStyle].fontFamily,
11913
+ $size: theme.typography[props.price.fontStyle].fontSize,
11914
+ $weight: theme.typography[props.price.fontStyle].fontWeight,
11915
+ $color: theme.typography[props.price.fontStyle].color,
11916
+ $lineHeight: 1,
11917
+ children: formatCurrency(upcomingInvoice.amountDue)
11918
+ }
11919
+ ) }),
11920
+ /* @__PURE__ */ jsx15(Box, { $maxWidth: "10rem", $lineHeight: "1", $textAlign: "right", children: /* @__PURE__ */ jsx15(
11921
+ Text,
11922
+ {
11923
+ $font: theme.typography[props.contractEndDate.fontStyle].fontFamily,
11924
+ $size: theme.typography[props.contractEndDate.fontStyle].fontSize,
11925
+ $weight: theme.typography[props.contractEndDate.fontStyle].fontWeight,
11926
+ $color: theme.typography[props.contractEndDate.fontStyle].color,
11927
+ children: "Estimated monthly bill."
11928
+ }
11929
+ ) })
11930
+ ] })
11221
11931
  ] });
11222
11932
  });
11223
11933
 
11224
11934
  // src/components/elements/invoices/Invoices.tsx
11225
- import { forwardRef as forwardRef6, useMemo as useMemo8 } from "react";
11935
+ import { forwardRef as forwardRef6, useMemo as useMemo11 } from "react";
11226
11936
  import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
11227
11937
  function resolveDesignProps6(props) {
11228
11938
  return {
@@ -11250,8 +11960,8 @@ function resolveDesignProps6(props) {
11250
11960
  }
11251
11961
  var Invoices = forwardRef6(({ className, ...rest }, ref) => {
11252
11962
  const props = resolveDesignProps6(rest);
11253
- const { settings } = useEmbed();
11254
- const { invoices } = useMemo8(() => {
11963
+ const theme = nt();
11964
+ const { invoices } = useMemo11(() => {
11255
11965
  return {
11256
11966
  invoices: [
11257
11967
  {
@@ -11269,10 +11979,10 @@ var Invoices = forwardRef6(({ className, ...rest }, ref) => {
11269
11979
  props.header.isVisible && /* @__PURE__ */ jsx16(Flex, { $justifyContent: "space-between", $alignItems: "center", children: /* @__PURE__ */ jsx16(
11270
11980
  Text,
11271
11981
  {
11272
- $font: settings.theme.typography[props.header.fontStyle].fontFamily,
11273
- $size: settings.theme.typography[props.header.fontStyle].fontSize,
11274
- $weight: settings.theme.typography[props.header.fontStyle].fontWeight,
11275
- $color: settings.theme.typography[props.header.fontStyle].color,
11982
+ $font: theme.typography[props.header.fontStyle].fontFamily,
11983
+ $size: theme.typography[props.header.fontStyle].fontSize,
11984
+ $weight: theme.typography[props.header.fontStyle].fontWeight,
11985
+ $color: theme.typography[props.header.fontStyle].color,
11276
11986
  children: "Invoices"
11277
11987
  }
11278
11988
  ) }),
@@ -11284,20 +11994,20 @@ var Invoices = forwardRef6(({ className, ...rest }, ref) => {
11284
11994
  props.date.isVisible && /* @__PURE__ */ jsx16(
11285
11995
  Text,
11286
11996
  {
11287
- $font: settings.theme.typography[props.date.fontStyle].fontFamily,
11288
- $size: settings.theme.typography[props.date.fontStyle].fontSize,
11289
- $weight: settings.theme.typography[props.date.fontStyle].fontWeight,
11290
- $color: settings.theme.typography[props.date.fontStyle].color,
11997
+ $font: theme.typography[props.date.fontStyle].fontFamily,
11998
+ $size: theme.typography[props.date.fontStyle].fontSize,
11999
+ $weight: theme.typography[props.date.fontStyle].fontWeight,
12000
+ $color: theme.typography[props.date.fontStyle].color,
11291
12001
  children: toPrettyDate(date)
11292
12002
  }
11293
12003
  ),
11294
12004
  props.amount.isVisible && /* @__PURE__ */ jsxs11(
11295
12005
  Text,
11296
12006
  {
11297
- $font: settings.theme.typography[props.amount.fontStyle].fontFamily,
11298
- $size: settings.theme.typography[props.amount.fontStyle].fontSize,
11299
- $weight: settings.theme.typography[props.amount.fontStyle].fontWeight,
11300
- $color: settings.theme.typography[props.amount.fontStyle].color,
12007
+ $font: theme.typography[props.amount.fontStyle].fontFamily,
12008
+ $size: theme.typography[props.amount.fontStyle].fontSize,
12009
+ $weight: theme.typography[props.amount.fontStyle].fontWeight,
12010
+ $color: theme.typography[props.amount.fontStyle].color,
11301
12011
  children: [
11302
12012
  "$",
11303
12013
  amount
@@ -11311,10 +12021,10 @@ var Invoices = forwardRef6(({ className, ...rest }, ref) => {
11311
12021
  /* @__PURE__ */ jsx16(
11312
12022
  Text,
11313
12023
  {
11314
- $font: settings.theme.typography[props.collapse.fontStyle].fontFamily,
11315
- $size: settings.theme.typography[props.collapse.fontStyle].fontSize,
11316
- $weight: settings.theme.typography[props.collapse.fontStyle].fontWeight,
11317
- $color: settings.theme.typography[props.collapse.fontStyle].color,
12024
+ $font: theme.typography[props.collapse.fontStyle].fontFamily,
12025
+ $size: theme.typography[props.collapse.fontStyle].fontSize,
12026
+ $weight: theme.typography[props.collapse.fontStyle].fontWeight,
12027
+ $color: theme.typography[props.collapse.fontStyle].color,
11318
12028
  children: "See all"
11319
12029
  }
11320
12030
  )
@@ -11323,7 +12033,7 @@ var Invoices = forwardRef6(({ className, ...rest }, ref) => {
11323
12033
  });
11324
12034
 
11325
12035
  // src/components/embed/ComponentTree.tsx
11326
- import { useEffect as useEffect5, useState as useState6 } from "react";
12036
+ import { useEffect as useEffect5, useState as useState5, Children } from "react";
11327
12037
 
11328
12038
  // src/components/embed/renderer.ts
11329
12039
  import { createElement } from "react";
@@ -11348,54 +12058,139 @@ var StyledViewport = dt.div`
11348
12058
  margin-right: auto;
11349
12059
  `;
11350
12060
 
11351
- // src/components/layout/viewport/Viewport.tsx
12061
+ // src/components/layout/RenderLayout.tsx
12062
+ import { useState as useState4 } from "react";
12063
+ import { useEffect as useEffect4 } from "react";
11352
12064
  import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
12065
+ var DisabledState = () => {
12066
+ const theme = nt();
12067
+ return /* @__PURE__ */ jsx18(Box, { $width: "100%", children: /* @__PURE__ */ jsxs12(
12068
+ Flex,
12069
+ {
12070
+ $flexDirection: "column",
12071
+ $padding: `${theme.card.padding / TEXT_BASE_SIZE}rem`,
12072
+ $width: "100%",
12073
+ $height: "auto",
12074
+ $borderRadius: `${theme.card.borderRadius / TEXT_BASE_SIZE}rem`,
12075
+ $backgroundColor: theme.card.background,
12076
+ $alignItems: "center",
12077
+ $justifyContent: "center",
12078
+ children: [
12079
+ /* @__PURE__ */ jsx18(
12080
+ Box,
12081
+ {
12082
+ $marginBottom: "8px",
12083
+ $fontSize: `${theme.typography.heading1.fontSize / TEXT_BASE_SIZE}rem`,
12084
+ $fontFamily: theme.typography.heading1.fontFamily,
12085
+ $fontWeight: theme.typography.heading1.fontWeight,
12086
+ $color: theme.typography.heading1.color,
12087
+ children: "Coming soon"
12088
+ }
12089
+ ),
12090
+ /* @__PURE__ */ jsx18(
12091
+ Box,
12092
+ {
12093
+ $marginBottom: "8px",
12094
+ $fontSize: `${theme.typography.text.fontSize / TEXT_BASE_SIZE}rem`,
12095
+ $fontFamily: theme.typography.text.fontFamily,
12096
+ $fontWeight: theme.typography.text.fontWeight,
12097
+ $color: theme.typography.text.color,
12098
+ children: "The plan manager will be back very soon."
12099
+ }
12100
+ )
12101
+ ]
12102
+ }
12103
+ ) });
12104
+ };
12105
+ var SuccessState = () => {
12106
+ const [isOpen, setIsOpen] = useState4(true);
12107
+ const theme = nt();
12108
+ const { hydrate, data, api, setLayout, isPending } = useEmbed();
12109
+ useEffect4(() => {
12110
+ if (api && data.component?.id) {
12111
+ hydrate();
12112
+ setTimeout(() => setIsOpen(false), 2e3);
12113
+ }
12114
+ }, [api, data.component?.id, hydrate]);
12115
+ useEffect4(() => {
12116
+ if (!isPending && !isOpen) {
12117
+ setLayout("portal");
12118
+ }
12119
+ }, [isPending, isOpen, setLayout]);
12120
+ return /* @__PURE__ */ jsxs12(
12121
+ Flex,
12122
+ {
12123
+ $flexDirection: "column",
12124
+ $justifyContent: "center",
12125
+ $alignItems: "center",
12126
+ $gap: `${32 / TEXT_BASE_SIZE}rem`,
12127
+ $width: "min-content",
12128
+ $height: "min-content",
12129
+ $margin: "auto",
12130
+ $padding: `${theme.card.padding / TEXT_BASE_SIZE}rem ${theme.card.padding * 1.5 / TEXT_BASE_SIZE}rem`,
12131
+ $whiteSpace: "nowrap",
12132
+ $backgroundColor: theme.card.background,
12133
+ $borderRadius: "0.5rem",
12134
+ $boxShadow: "0px 1px 20px 0px #1018280F, 0px 1px 3px 0px #1018281A;",
12135
+ children: [
12136
+ /* @__PURE__ */ jsx18(
12137
+ IconRound,
12138
+ {
12139
+ name: "check",
12140
+ size: "3xl",
12141
+ colors: [theme.card.background, theme.primary]
12142
+ }
12143
+ ),
12144
+ /* @__PURE__ */ jsx18(
12145
+ Text,
12146
+ {
12147
+ as: "h1",
12148
+ $font: theme.typography.heading1.fontFamily,
12149
+ $size: theme.typography.heading1.fontSize,
12150
+ $weight: theme.typography.heading1.fontWeight,
12151
+ $color: theme.typography.heading1.color,
12152
+ children: "Subscription updated!"
12153
+ }
12154
+ ),
12155
+ /* @__PURE__ */ jsx18(
12156
+ Text,
12157
+ {
12158
+ as: "p",
12159
+ $font: theme.typography.text.fontFamily,
12160
+ $size: theme.typography.text.fontSize,
12161
+ $weight: theme.typography.text.fontWeight,
12162
+ $color: theme.typography.text.color,
12163
+ children: "Loading..."
12164
+ }
12165
+ )
12166
+ ]
12167
+ }
12168
+ );
12169
+ };
12170
+ var RenderLayout = ({ children }) => {
12171
+ const { layout } = useEmbed();
12172
+ switch (layout) {
12173
+ case "disabled":
12174
+ return /* @__PURE__ */ jsx18(DisabledState, {});
12175
+ case "success":
12176
+ return /* @__PURE__ */ jsx18(SuccessState, {});
12177
+ default:
12178
+ return children;
12179
+ }
12180
+ };
12181
+
12182
+ // src/components/layout/viewport/Viewport.tsx
12183
+ import { jsx as jsx19 } from "react/jsx-runtime";
11353
12184
  var Viewport = forwardRef8(
11354
12185
  ({ children, ...props }, ref) => {
11355
- const { settings, layout } = useEmbed();
11356
- return /* @__PURE__ */ jsx18(
12186
+ const theme = nt();
12187
+ return /* @__PURE__ */ jsx19(
11357
12188
  StyledViewport,
11358
12189
  {
11359
12190
  ref,
11360
- $numberOfColumns: settings.theme.numberOfColumns,
12191
+ $numberOfColumns: theme.numberOfColumns,
11361
12192
  ...props,
11362
- children: layout === "disabled" ? /* @__PURE__ */ jsx18(Box, { $width: "100%", children: /* @__PURE__ */ jsxs12(
11363
- Flex,
11364
- {
11365
- $flexDirection: "column",
11366
- $padding: `${settings.theme.card.padding / 16}rem`,
11367
- $width: "100%",
11368
- $height: "auto",
11369
- $borderRadius: `${settings.theme.card.borderRadius / 16}rem`,
11370
- $backgroundColor: settings.theme.card.background,
11371
- $alignItems: "center",
11372
- $justifyContent: "center",
11373
- children: [
11374
- /* @__PURE__ */ jsx18(
11375
- Box,
11376
- {
11377
- $marginBottom: "8px",
11378
- $fontSize: `${settings.theme.typography.heading1.fontSize / 16}rem`,
11379
- $fontFamily: settings.theme.typography.heading1.fontFamily,
11380
- $fontWeight: settings.theme.typography.heading1.fontWeight,
11381
- $color: settings.theme.typography.heading1.color,
11382
- children: "Coming soon"
11383
- }
11384
- ),
11385
- /* @__PURE__ */ jsx18(
11386
- Box,
11387
- {
11388
- $marginBottom: "8px",
11389
- $fontSize: `${settings.theme.typography.text.fontSize / 16}rem`,
11390
- $fontFamily: settings.theme.typography.text.fontFamily,
11391
- $fontWeight: settings.theme.typography.text.fontWeight,
11392
- $color: settings.theme.typography.text.color,
11393
- children: "The plan manager will be back very soon."
11394
- }
11395
- )
11396
- ]
11397
- }
11398
- ) }) : children
12193
+ children: /* @__PURE__ */ jsx19(RenderLayout, { children })
11399
12194
  }
11400
12195
  );
11401
12196
  }
@@ -11434,7 +12229,7 @@ var StyledCard = dt.div(
11434
12229
 
11435
12230
  ${() => {
11436
12231
  const { l: l2 } = hexToHSL(theme.card.background);
11437
- const borderColor = l2 > 50 ? darken(theme.card.background, 10) : lighten(theme.card.background, 20);
12232
+ const borderColor = l2 > 50 ? "hsla(0, 0%, 0%, 0.1)" : "hsla(0, 0%, 100%, 0.2)";
11438
12233
  const borderRadius = `${$borderRadius / TEXT_BASE_SIZE}rem`;
11439
12234
  const boxShadow = "0px 1px 20px 0px #1018280F, 0px 1px 3px 0px #1018281A";
11440
12235
  if ($sectionLayout === "merged") {
@@ -11466,19 +12261,19 @@ var StyledCard = dt.div(
11466
12261
  );
11467
12262
 
11468
12263
  // src/components/layout/card/Card.tsx
11469
- import { jsx as jsx19 } from "react/jsx-runtime";
12264
+ import { jsx as jsx20 } from "react/jsx-runtime";
11470
12265
  var Card = forwardRef9(
11471
12266
  ({ children, className }, ref) => {
11472
- const { settings } = useEmbed();
11473
- return /* @__PURE__ */ jsx19(
12267
+ const theme = nt();
12268
+ return /* @__PURE__ */ jsx20(
11474
12269
  StyledCard,
11475
12270
  {
11476
12271
  ref,
11477
12272
  className,
11478
- $sectionLayout: settings.theme?.sectionLayout,
11479
- $borderRadius: settings.theme?.card?.borderRadius,
11480
- $padding: settings.theme?.card?.padding,
11481
- $shadow: settings.theme?.card?.hasShadow,
12273
+ $sectionLayout: theme?.sectionLayout,
12274
+ $borderRadius: theme?.card?.borderRadius,
12275
+ $padding: theme?.card?.padding,
12276
+ $shadow: theme?.card?.hasShadow,
11482
12277
  children
11483
12278
  }
11484
12279
  );
@@ -11492,10 +12287,10 @@ var StyledColumn = dt.div`
11492
12287
  `;
11493
12288
 
11494
12289
  // src/components/layout/column/Column.tsx
11495
- import { jsx as jsx20 } from "react/jsx-runtime";
12290
+ import { jsx as jsx21 } from "react/jsx-runtime";
11496
12291
  var Column = forwardRef10(
11497
12292
  ({ children, ...props }, ref) => {
11498
- return /* @__PURE__ */ jsx20(StyledColumn, { ref, ...props, children: /* @__PURE__ */ jsx20(Card, { children }) });
12293
+ return /* @__PURE__ */ jsx21(StyledColumn, { ref, ...props, children: /* @__PURE__ */ jsx21(Card, { children }) });
11499
12294
  }
11500
12295
  );
11501
12296
 
@@ -11541,101 +12336,88 @@ function createRenderer(options) {
11541
12336
  };
11542
12337
  }
11543
12338
 
11544
- // src/components/ui/loader/styles.ts
11545
- var spin = mt`
11546
- 0% {
11547
- transform: rotate(0deg);
11548
- }
11549
- 100% {
11550
- transform: rotate(360deg);
11551
- }
11552
- `;
11553
- var Loader = dt.div(() => {
11554
- const { settings } = useEmbed();
11555
- return lt`
11556
- border: 4px solid rgba(0, 0, 0, 0.1);
11557
- border-top: 4px solid ${settings.theme.primary};
11558
- border-radius: 50%;
11559
- width: 40px;
11560
- height: 40px;
11561
- animation: ${spin} 1.5s linear infinite;
11562
- display: inline-block;
11563
- `;
11564
- });
11565
-
11566
12339
  // src/components/embed/ComponentTree.tsx
11567
- import { Fragment as Fragment2, jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
11568
- var ComponentTree = () => {
11569
- const { error, nodes, settings } = useEmbed();
11570
- const [children, setChildren] = useState6(
11571
- /* @__PURE__ */ jsx21(
11572
- Flex,
11573
- {
11574
- $width: "100%",
11575
- $height: "100%",
11576
- $alignItems: "center",
11577
- $justifyContent: "center",
11578
- $padding: `${settings.theme.card.padding / 16}rem`,
11579
- children: /* @__PURE__ */ jsx21(Loader, {})
11580
- }
11581
- )
12340
+ import { Fragment as Fragment2, jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
12341
+ var Loading = () => {
12342
+ const theme = nt();
12343
+ return /* @__PURE__ */ jsx22(
12344
+ Flex,
12345
+ {
12346
+ $width: "100%",
12347
+ $height: "100%",
12348
+ $alignItems: "center",
12349
+ $justifyContent: "center",
12350
+ $padding: `${theme.card.padding / TEXT_BASE_SIZE}rem`,
12351
+ children: /* @__PURE__ */ jsx22(Loader, {})
12352
+ }
12353
+ );
12354
+ };
12355
+ var Error2 = ({ message }) => {
12356
+ const theme = nt();
12357
+ return /* @__PURE__ */ jsxs13(
12358
+ Flex,
12359
+ {
12360
+ $flexDirection: "column",
12361
+ $padding: `${theme.card.padding / TEXT_BASE_SIZE}rem`,
12362
+ $width: "100%",
12363
+ $height: "auto",
12364
+ $borderRadius: `${theme.card.borderRadius / TEXT_BASE_SIZE}rem`,
12365
+ $backgroundColor: theme.card.background,
12366
+ $alignItems: "center",
12367
+ $justifyContent: "center",
12368
+ children: [
12369
+ /* @__PURE__ */ jsx22(
12370
+ Box,
12371
+ {
12372
+ $marginBottom: `${8 / TEXT_BASE_SIZE}rem`,
12373
+ $fontSize: `${theme.typography.heading1.fontSize / TEXT_BASE_SIZE}rem`,
12374
+ $fontFamily: theme.typography.heading1.fontFamily,
12375
+ $fontWeight: theme.typography.heading1.fontWeight,
12376
+ $color: theme.typography.heading1.color,
12377
+ children: "404 Error"
12378
+ }
12379
+ ),
12380
+ /* @__PURE__ */ jsx22(
12381
+ Box,
12382
+ {
12383
+ $marginBottom: `${8 / TEXT_BASE_SIZE}rem`,
12384
+ $fontSize: `${theme.typography.text.fontSize / TEXT_BASE_SIZE}rem`,
12385
+ $fontFamily: theme.typography.text.fontFamily,
12386
+ $fontWeight: theme.typography.text.fontWeight,
12387
+ $color: theme.typography.text.color,
12388
+ children: message
12389
+ }
12390
+ )
12391
+ ]
12392
+ }
11582
12393
  );
12394
+ };
12395
+ var ComponentTree = () => {
12396
+ const { error, nodes } = useEmbed();
12397
+ const [children, setChildren] = useState5(/* @__PURE__ */ jsx22(Loading, {}));
11583
12398
  useEffect5(() => {
11584
12399
  const renderer = createRenderer();
11585
12400
  setChildren(nodes.map(renderer));
11586
12401
  }, [nodes]);
11587
12402
  if (error) {
11588
- return /* @__PURE__ */ jsxs13(
11589
- Flex,
11590
- {
11591
- $flexDirection: "column",
11592
- $padding: `${settings.theme.card.padding / 16}rem`,
11593
- $width: "100%",
11594
- $height: "auto",
11595
- $borderRadius: `${settings.theme.card.borderRadius / 16}rem`,
11596
- $backgroundColor: settings.theme.card.background,
11597
- $alignItems: "center",
11598
- $justifyContent: "center",
11599
- children: [
11600
- /* @__PURE__ */ jsx21(
11601
- Box,
11602
- {
11603
- $marginBottom: "8px",
11604
- $fontSize: `${settings.theme.typography.heading1.fontSize / 16}rem`,
11605
- $fontFamily: settings.theme.typography.heading1.fontFamily,
11606
- $fontWeight: settings.theme.typography.heading1.fontWeight,
11607
- $color: settings.theme.typography.heading1.color,
11608
- children: "404 Error"
11609
- }
11610
- ),
11611
- /* @__PURE__ */ jsx21(
11612
- Box,
11613
- {
11614
- $marginBottom: "8px",
11615
- $fontSize: `${settings.theme.typography.text.fontSize / 16}rem`,
11616
- $fontFamily: settings.theme.typography.text.fontFamily,
11617
- $fontWeight: settings.theme.typography.text.fontWeight,
11618
- $color: settings.theme.typography.text.color,
11619
- children: error.message
11620
- }
11621
- )
11622
- ]
11623
- }
11624
- );
12403
+ return /* @__PURE__ */ jsx22(Error2, { message: error.message });
12404
+ }
12405
+ if (Children.count(children) === 0) {
12406
+ return /* @__PURE__ */ jsx22(Loading, {});
11625
12407
  }
11626
- return /* @__PURE__ */ jsx21(Fragment2, { children });
12408
+ return /* @__PURE__ */ jsx22(Fragment2, { children });
11627
12409
  };
11628
12410
 
11629
12411
  // src/components/embed/Embed.tsx
11630
- import { jsx as jsx22 } from "react/jsx-runtime";
12412
+ import { jsx as jsx23 } from "react/jsx-runtime";
11631
12413
  var SchematicEmbed = ({ id, accessToken, apiConfig }) => {
11632
12414
  if (accessToken?.length === 0) {
11633
- return /* @__PURE__ */ jsx22("div", { children: "Please provide an access token." });
12415
+ return /* @__PURE__ */ jsx23("div", { children: "Please provide an access token." });
11634
12416
  }
11635
12417
  if (!accessToken?.startsWith("token_")) {
11636
- return /* @__PURE__ */ jsx22("div", { children: 'Invalid access token; your temporary access token will start with "token_".' });
12418
+ return /* @__PURE__ */ jsx23("div", { children: 'Invalid access token; your temporary access token will start with "token_".' });
11637
12419
  }
11638
- return /* @__PURE__ */ jsx22(EmbedProvider, { id, accessToken, apiConfig, children: /* @__PURE__ */ jsx22(ComponentTree, {}) });
12420
+ return /* @__PURE__ */ jsx23(EmbedProvider, { id, accessToken, apiConfig, children: /* @__PURE__ */ jsx23(ComponentTree, {}) });
11639
12421
  };
11640
12422
  export {
11641
12423
  Box,
@@ -11649,6 +12431,7 @@ export {
11649
12431
  IconRound,
11650
12432
  IncludedFeatures,
11651
12433
  Invoices,
12434
+ Loader,
11652
12435
  MeteredFeatures,
11653
12436
  Modal,
11654
12437
  ModalHeader,
@@ -11668,7 +12451,8 @@ export {
11668
12451
  useSchematic,
11669
12452
  useSchematicContext,
11670
12453
  useSchematicEvents,
11671
- useSchematicFlag
12454
+ useSchematicFlag,
12455
+ useSchematicIsPending
11672
12456
  };
11673
12457
  /*! Bundled license information:
11674
12458