@ciromaciel/auth-react 1.4.1 → 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/README.md CHANGED
@@ -151,7 +151,7 @@ organization and on which plan, then one list of actions with "Sair" last.
151
151
  onAccountClick={openAccount}
152
152
  onBillingClick={openBilling}
153
153
  items={[{ id: 'docs', label: 'Documentação', icon: IconFileText, onClick: openDocs }]}
154
- plan={{ name: 'Pro', used: 3, limit: 9, unit: 'projetos', onClick: openPlans }}
154
+ plan={{ name: 'Pro', used: 8, limit: 9, unit: 'projetos', canUpgrade: true, onClick: openPlans }}
155
155
  organization={{ name: 'Acme', role: 'owner' }}
156
156
  />
157
157
  ```
@@ -162,6 +162,10 @@ organization and on which plan, then one list of actions with "Sair" last.
162
162
  own group after billing. The component takes no JSX, so every app's card keeps the same shape.
163
163
  - `plan` and `organization` draw the context strip; leave them out and it is not drawn.
164
164
  `limit: null` hides the usage bar.
165
+ - The strip informs; "Assinatura" is the way to billing. The strip adds a "Fazer upgrade"
166
+ invite only when `canUpgrade` is `true` (there is a plan above this one) and usage is at 80%
167
+ of the limit or more. At the limit, the bar and the count turn red and "Limite atingido" appears on the badge's line.
168
+ `plan.onClick` is what the invite opens; `actionLabel` renames it.
165
169
  - The footer reads "Protegido por Auth" with a "Termos" link to the same terms the sign-in
166
170
  cites. `termsUrl` points it elsewhere, `termsUrl={null}` drops the link, and `branded={false}`
167
171
  removes the footer.
package/dist/index.esm.js CHANGED
@@ -3984,6 +3984,13 @@ const ROLE_LABELS = {
3984
3984
  member: 'Membro'
3985
3985
  };
3986
3986
 
3987
+ /*
3988
+ * From this share of the limit on, the strip invites to upgrade. Below it the
3989
+ * strip only informs: "Assinatura" is the door that is always there, and a
3990
+ * second link to the same modal right above it was two doors to one room.
3991
+ */
3992
+ const UPGRADE_THRESHOLD = 0.8;
3993
+
3987
3994
  /**
3988
3995
  * @typedef {Object} UserInformationItem
3989
3996
  * @property {string} [id] - Stable key
@@ -3996,8 +4003,12 @@ const ROLE_LABELS = {
3996
4003
  * @property {number} [used] - How many of the plan's resources are in use
3997
4004
  * @property {number|null} [limit] - The plan's ceiling; `null` hides the meter
3998
4005
  * @property {string} [unit] - What is counted, in the plural: "projetos"
3999
- * @property {string} [actionLabel='Ver planos']
4000
- * @property {Function} [onClick] - Opens the plans
4006
+ * @property {boolean} [canUpgrade=false] - There is a plan above this one. Without
4007
+ * it the invite never shows, however full the plan is: on the last rung there
4008
+ * is nowhere to go
4009
+ * @property {string} [actionLabel='Fazer upgrade']
4010
+ * @property {Function} [onClick] - Opens the plans. The invite shows only with
4011
+ * `canUpgrade` and usage at 80% of the limit or more
4001
4012
  *
4002
4013
  * @typedef {Object} UserInformationOrganization
4003
4014
  * @property {string} name
@@ -4185,6 +4196,15 @@ function ContextStrip({
4185
4196
  const role = organization?.role ? ROLE_LABELS[organization.role] || organization.role : null;
4186
4197
  const hasMeter = plan && Number.isFinite(plan.used) && Number.isFinite(plan.limit) && plan.limit > 0;
4187
4198
  const ratio = hasMeter ? Math.min(1, Math.max(0, plan.used / plan.limit)) : 0;
4199
+ const isFull = hasMeter && plan.used >= plan.limit;
4200
+ const showsInvite = hasMeter && plan.canUpgrade === true && typeof plan.onClick === 'function' && ratio >= UPGRADE_THRESHOLD;
4201
+ /*
4202
+ * "Limite atingido" sits on the badge's line, whose left side is empty
4203
+ * when there is no organization. Next to the count it would wrap to two
4204
+ * lines beside the invite. With an organization there, it falls back to
4205
+ * the count.
4206
+ */
4207
+ const limitNoticeOnTop = isFull && !organization?.name;
4188
4208
  return /*#__PURE__*/jsxs(Stack, {
4189
4209
  gap: 8,
4190
4210
  px: padded ? 16 : 0,
@@ -4197,7 +4217,12 @@ function ContextStrip({
4197
4217
  children: [(organization?.name || plan?.name) && /*#__PURE__*/jsxs(Group, {
4198
4218
  gap: 8,
4199
4219
  wrap: "nowrap",
4200
- children: [organization?.name && /*#__PURE__*/jsxs(Fragment, {
4220
+ children: [limitNoticeOnTop && /*#__PURE__*/jsx(Text, {
4221
+ fz: 12,
4222
+ fw: 700,
4223
+ c: "red.8",
4224
+ children: "Limite atingido"
4225
+ }), organization?.name && /*#__PURE__*/jsxs(Fragment, {
4201
4226
  children: [/*#__PURE__*/jsx(IconBuilding, {
4202
4227
  size: 14,
4203
4228
  stroke: 1.5,
@@ -4251,7 +4276,7 @@ function ContextStrip({
4251
4276
  children: /*#__PURE__*/jsx(Box, {
4252
4277
  h: "100%",
4253
4278
  w: `${ratio * 100}%`,
4254
- bg: "gray.9"
4279
+ bg: isFull ? 'red.8' : 'gray.9'
4255
4280
  })
4256
4281
  }), /*#__PURE__*/jsxs(Group, {
4257
4282
  justify: "space-between",
@@ -4259,18 +4284,24 @@ function ContextStrip({
4259
4284
  wrap: "nowrap",
4260
4285
  children: [/*#__PURE__*/jsx(Text, {
4261
4286
  fz: 12,
4262
- fw: 500,
4263
- c: "gray.6",
4264
- children: `${plan.used} de ${plan.limit}${plan.unit ? ` ${plan.unit}` : ''}`
4265
- }), plan.onClick && /*#__PURE__*/jsx(Anchor, {
4266
- component: "button",
4267
- type: "button",
4268
- fz: 12,
4269
- fw: 700,
4270
- c: "gray.9",
4271
- underline: "always",
4287
+ fw: isFull ? 700 : 500,
4288
+ c: isFull ? 'red.8' : 'gray.6',
4289
+ children: `${plan.used} de ${plan.limit}${plan.unit ? ` ${plan.unit}` : ''}${isFull && !limitNoticeOnTop ? ' · limite atingido' : ''}`
4290
+ }), showsInvite && /*#__PURE__*/jsx(UnstyledButton, {
4272
4291
  onClick: plan.onClick,
4273
- children: plan.actionLabel || 'Ver planos'
4292
+ fz: 11,
4293
+ fw: 800,
4294
+ lts: "0.5px",
4295
+ c: "white",
4296
+ bg: "gray.9",
4297
+ px: 8,
4298
+ py: 3,
4299
+ lh: 1.4,
4300
+ style: {
4301
+ flex: 'none',
4302
+ whiteSpace: 'nowrap'
4303
+ },
4304
+ children: plan.actionLabel || 'Fazer upgrade'
4274
4305
  })]
4275
4306
  })]
4276
4307
  })]