@ciromaciel/auth-react 1.4.0 → 1.5.0

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.
package/dist/index.js CHANGED
@@ -2535,17 +2535,13 @@ function Wordmark({
2535
2535
  });
2536
2536
  }
2537
2537
 
2538
+ // Where the terms live. Hardcoded on purpose, like `API_BASE` in authSdk.js:
2539
+ // this ships inside the published bundle, and every screen of the seven panels
2540
+ // that links to the terms — the sign-in notice and the account card's footer —
2541
+ // must point at the same document. `termsUrl` overrides it for whoever hosts
2542
+ // their own.
2538
2543
  const TERMS_URL = 'https://myinfrastructure.click/legal/terms';
2539
2544
 
2540
- /**
2541
- * The terms notice under the first step.
2542
- *
2543
- * It sits on step ONE and nowhere else: the account is born on the first
2544
- * `verify` and there is no separate sign-up screen to put it on — this form IS
2545
- * the sign-up for whoever has never entered. On step two the person already
2546
- * agreed by asking for the code; repeating it there would only push the code
2547
- * field down.
2548
- */
2549
2545
  function TermsNotice({
2550
2546
  url,
2551
2547
  text,
@@ -3990,6 +3986,13 @@ const ROLE_LABELS = {
3990
3986
  member: 'Membro'
3991
3987
  };
3992
3988
 
3989
+ /*
3990
+ * From this share of the limit on, the strip invites to upgrade. Below it the
3991
+ * strip only informs: "Assinatura" is the door that is always there, and a
3992
+ * second link to the same modal right above it was two doors to one room.
3993
+ */
3994
+ const UPGRADE_THRESHOLD = 0.8;
3995
+
3993
3996
  /**
3994
3997
  * @typedef {Object} UserInformationItem
3995
3998
  * @property {string} [id] - Stable key
@@ -4002,8 +4005,12 @@ const ROLE_LABELS = {
4002
4005
  * @property {number} [used] - How many of the plan's resources are in use
4003
4006
  * @property {number|null} [limit] - The plan's ceiling; `null` hides the meter
4004
4007
  * @property {string} [unit] - What is counted, in the plural: "projetos"
4005
- * @property {string} [actionLabel='Ver planos']
4006
- * @property {Function} [onClick] - Opens the plans
4008
+ * @property {boolean} [canUpgrade=false] - There is a plan above this one. Without
4009
+ * it the invite never shows, however full the plan is: on the last rung there
4010
+ * is nowhere to go
4011
+ * @property {string} [actionLabel='Fazer upgrade']
4012
+ * @property {Function} [onClick] - Opens the plans. The invite shows only with
4013
+ * `canUpgrade` and usage at 80% of the limit or more
4007
4014
  *
4008
4015
  * @typedef {Object} UserInformationOrganization
4009
4016
  * @property {string} name
@@ -4019,7 +4026,9 @@ const ROLE_LABELS = {
4019
4026
  * @param {UserInformationItem[]} [props.items] - The panel's own rows, shown in their own group
4020
4027
  * @param {UserInformationPlan} [props.plan] - The plan strip; omitted, the strip is not drawn
4021
4028
  * @param {UserInformationOrganization} [props.organization] - Where the person is acting
4022
- * @param {boolean} [props.branded=true] - The "Protegido por Auth" line
4029
+ * @param {boolean} [props.branded=true] - The footer: "Protegido por Auth" and the terms link
4030
+ * @param {string|null} [props.termsUrl] - Where "Termos" points; `null` removes the link
4031
+ * @param {string} [props.termsLabel='Termos']
4023
4032
  * @param {string} [props.accountLabel='Conta']
4024
4033
  * @param {string} [props.billingLabel='Assinatura']
4025
4034
  * @param {string} [props.signOutLabel='Sair']
@@ -4033,6 +4042,8 @@ function UserInformation({
4033
4042
  plan,
4034
4043
  organization,
4035
4044
  branded = true,
4045
+ termsUrl = TERMS_URL,
4046
+ termsLabel = 'Termos',
4036
4047
  accountLabel = 'Conta',
4037
4048
  billingLabel = 'Assinatura',
4038
4049
  signOutLabel = 'Sair',
@@ -4140,23 +4151,39 @@ function UserInformation({
4140
4151
  hasDivider: true
4141
4152
  })]
4142
4153
  }), branded && /*#__PURE__*/jsxRuntime.jsxs(core.Group, {
4143
- justify: "center",
4144
- gap: 4,
4145
- py: 8,
4154
+ justify: termsUrl ? 'space-between' : 'center',
4155
+ gap: 8,
4156
+ px: 16,
4157
+ py: 10,
4146
4158
  bg: "gray.1",
4147
4159
  style: {
4148
4160
  borderTop: '1px solid var(--mantine-color-gray-2)'
4149
4161
  },
4150
- children: [/*#__PURE__*/jsxRuntime.jsx(core.Text, {
4162
+ children: [/*#__PURE__*/jsxRuntime.jsxs(core.Text, {
4151
4163
  fz: 11,
4152
4164
  fw: 500,
4153
4165
  c: "gray.5",
4154
- children: "Protegido por"
4155
- }), /*#__PURE__*/jsxRuntime.jsx(core.Text, {
4166
+ children: ["Protegido por", ' ', /*#__PURE__*/jsxRuntime.jsx(core.Text, {
4167
+ span: true,
4168
+ inherit: true,
4169
+ fw: 800,
4170
+ c: "gray.7",
4171
+ children: "Auth"
4172
+ })]
4173
+ }), termsUrl && /*#__PURE__*/jsxRuntime.jsx(core.Anchor, {
4174
+ href: termsUrl
4175
+ /*
4176
+ * A new tab, like the sign-in's notice: the card sits
4177
+ * over a working panel, and reading the terms must
4178
+ * not navigate away from it.
4179
+ */,
4180
+ target: "_blank",
4181
+ rel: "noopener noreferrer",
4156
4182
  fz: 11,
4157
- fw: 800,
4158
- c: "gray.7",
4159
- children: "Auth"
4183
+ fw: 500,
4184
+ c: "gray.5",
4185
+ underline: "always",
4186
+ children: termsLabel
4160
4187
  })]
4161
4188
  })]
4162
4189
  });
@@ -4171,6 +4198,15 @@ function ContextStrip({
4171
4198
  const role = organization?.role ? ROLE_LABELS[organization.role] || organization.role : null;
4172
4199
  const hasMeter = plan && Number.isFinite(plan.used) && Number.isFinite(plan.limit) && plan.limit > 0;
4173
4200
  const ratio = hasMeter ? Math.min(1, Math.max(0, plan.used / plan.limit)) : 0;
4201
+ const isFull = hasMeter && plan.used >= plan.limit;
4202
+ const showsInvite = hasMeter && plan.canUpgrade === true && typeof plan.onClick === 'function' && ratio >= UPGRADE_THRESHOLD;
4203
+ /*
4204
+ * "Limite atingido" sits on the badge's line, whose left side is empty
4205
+ * when there is no organization. Next to the count it would wrap to two
4206
+ * lines beside the invite. With an organization there, it falls back to
4207
+ * the count.
4208
+ */
4209
+ const limitNoticeOnTop = isFull && !organization?.name;
4174
4210
  return /*#__PURE__*/jsxRuntime.jsxs(core.Stack, {
4175
4211
  gap: 8,
4176
4212
  px: padded ? 16 : 0,
@@ -4183,7 +4219,12 @@ function ContextStrip({
4183
4219
  children: [(organization?.name || plan?.name) && /*#__PURE__*/jsxRuntime.jsxs(core.Group, {
4184
4220
  gap: 8,
4185
4221
  wrap: "nowrap",
4186
- children: [organization?.name && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
4222
+ children: [limitNoticeOnTop && /*#__PURE__*/jsxRuntime.jsx(core.Text, {
4223
+ fz: 12,
4224
+ fw: 700,
4225
+ c: "red.8",
4226
+ children: "Limite atingido"
4227
+ }), organization?.name && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
4187
4228
  children: [/*#__PURE__*/jsxRuntime.jsx(iconsReact.IconBuilding, {
4188
4229
  size: 14,
4189
4230
  stroke: 1.5,
@@ -4237,7 +4278,7 @@ function ContextStrip({
4237
4278
  children: /*#__PURE__*/jsxRuntime.jsx(core.Box, {
4238
4279
  h: "100%",
4239
4280
  w: `${ratio * 100}%`,
4240
- bg: "gray.9"
4281
+ bg: isFull ? 'red.8' : 'gray.9'
4241
4282
  })
4242
4283
  }), /*#__PURE__*/jsxRuntime.jsxs(core.Group, {
4243
4284
  justify: "space-between",
@@ -4245,18 +4286,24 @@ function ContextStrip({
4245
4286
  wrap: "nowrap",
4246
4287
  children: [/*#__PURE__*/jsxRuntime.jsx(core.Text, {
4247
4288
  fz: 12,
4248
- fw: 500,
4249
- c: "gray.6",
4250
- children: `${plan.used} de ${plan.limit}${plan.unit ? ` ${plan.unit}` : ''}`
4251
- }), plan.onClick && /*#__PURE__*/jsxRuntime.jsx(core.Anchor, {
4252
- component: "button",
4253
- type: "button",
4254
- fz: 12,
4255
- fw: 700,
4256
- c: "gray.9",
4257
- underline: "always",
4289
+ fw: isFull ? 700 : 500,
4290
+ c: isFull ? 'red.8' : 'gray.6',
4291
+ children: `${plan.used} de ${plan.limit}${plan.unit ? ` ${plan.unit}` : ''}${isFull && !limitNoticeOnTop ? ' · limite atingido' : ''}`
4292
+ }), showsInvite && /*#__PURE__*/jsxRuntime.jsx(core.UnstyledButton, {
4258
4293
  onClick: plan.onClick,
4259
- children: plan.actionLabel || 'Ver planos'
4294
+ fz: 11,
4295
+ fw: 800,
4296
+ lts: "0.5px",
4297
+ c: "white",
4298
+ bg: "gray.9",
4299
+ px: 8,
4300
+ py: 3,
4301
+ lh: 1.4,
4302
+ style: {
4303
+ flex: 'none',
4304
+ whiteSpace: 'nowrap'
4305
+ },
4306
+ children: plan.actionLabel || 'Fazer upgrade'
4260
4307
  })]
4261
4308
  })]
4262
4309
  })]