Skip to content

feat(admin): require expiration for credit grants unless 'Never expires' is checked#15

Open
kiloconnect[bot] wants to merge 1 commit intomainfrom
session/agent_fb167b27-bee3-4de5-aadd-28c00ea62a2f
Open

feat(admin): require expiration for credit grants unless 'Never expires' is checked#15
kiloconnect[bot] wants to merge 1 commit intomainfrom
session/agent_fb167b27-bee3-4de5-aadd-28c00ea62a2f

Conversation

@kiloconnect
Copy link
Contributor

@kiloconnect kiloconnect bot commented Feb 4, 2026

Summary

This PR updates the admin user detail page to require an expiration date or hours when granting credits, unless the user explicitly checks a "Never expires" checkbox.

Changes

  • Add "Never expires" checkbox option to the credit grant form
  • Make expiration date OR expiration hours required by default
  • When "Never expires" is checked, expiration fields become disabled and cleared
  • Add form validation to enforce the requirement
  • Reset "Never expires" state when changing credit category or after successful submission

Motivation

This prevents accidentally creating credits without expiration dates, which creates unnecessary financial liabilities. Users who genuinely need non-expiring credits can explicitly check the "Never expires" box.

Testing

  • TypeScript type checking passes
  • Lint-staged checks pass

Built for Brendan by Kilo for Slack

…es' is checked

- Add 'Never expires' checkbox option to the credit grant form
- Make expiration date OR expiration hours required by default
- When 'Never expires' is checked, expiration fields become disabled
- Add form validation to enforce the requirement
- Clear expiration fields when 'Never expires' is checked

This prevents accidentally creating credits without expiration dates,
which creates unnecessary financial liabilities. Users who genuinely
need non-expiring credits can explicitly check the 'Never expires' box.
<div>
<Label className="text-sm font-medium" htmlFor="expiry-hours">
Expiry Hours
Expiry Hours{!neverExpires && !expirationDate ? ' (required)' : ''}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Required indicator condition is incorrect for "Expiry Hours"

This shows "(required)" whenever expirationDate is empty, even if the user already entered expiryHours. Consider only showing required when neither expiration field is set.

Suggested change
Expiry Hours{!neverExpires && !expirationDate ? ' (required)' : ''}
Expiry Hours{!neverExpires && !expiryHours && !expirationDate ? ' (required)' : ''}

step="0.01"
id="expiry-hours"
disabled={!selectedCredit}
disabled={!selectedCredit || neverExpires}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Required indicator condition is incorrect for "Expiration Date"

This shows "(required)" whenever expiryHours is empty, even if the user already selected an expirationDate. Consider only showing required when neither expiration field is set.

Suggested change
disabled={!selectedCredit || neverExpires}
Expiration Date{!neverExpires && !expiryHours && !expirationDate ? ' (required)' : ''}

<div>
<Label className="text-sm font-medium" htmlFor="date">
Expiration Date
Expiration Date{!neverExpires && !expiryHours ? ' (required)' : ''}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUGGESTION: Date input value fallback likely never triggers + format mismatch

expirationDate is a string state initialized to '', so expirationDate ?? ... will always pick expirationDate (empty string is not nullish) and never fall back to the category default. Also, <input type="date"> expects YYYY-MM-DD, while toISOString() produces a full timestamp (YYYY-MM-DDTHH:mm:ss.sssZ).

Consider using something like expirationDate || (selectedCreditCategory?.credit_expiry_date ? selectedCreditCategory.credit_expiry_date.toISOString().slice(0, 10) : '').

@kiloconnect
Copy link
Contributor Author

kiloconnect bot commented Feb 4, 2026

Code Review Summary

Status: 3 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 1

Fix these issues in Kilo Cloud

Issue Details (click to expand)

WARNING

File Line Issue
src/app/admin/components/UserAdmin/UserAdminCreditGrant.tsx 235 "Expiry Hours (required)" indicator shows even when hours are provided
src/app/admin/components/UserAdmin/UserAdminCreditGrant.tsx 245 "Expiration Date (required)" indicator shows even when a date is selected

SUGGESTION

File Line Issue
src/app/admin/components/UserAdmin/UserAdminCreditGrant.tsx 250 type="date" value fallback uses ?? (never triggers for empty string) + toISOString() format mismatch
Other Observations (not in diff)

Issues found in unchanged code that cannot receive inline comments:

File Line Issue
Files Reviewed (1 files)
  • src/app/admin/components/UserAdmin/UserAdminCreditGrant.tsx - 3 issues

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants