Commit Graph

1348 Commits

Author SHA1 Message Date
t0ng7u
34d45bb3b8 🍭 style(ui): Optimize style layout and improve responsive layout 2025-07-24 23:28:55 +08:00
t0ng7u
aecdbfacf3 Merge remote-tracking branch 'origin/alpha' into refactor/model-pricing 2025-07-24 17:47:08 +08:00
t0ng7u
1c25e29999 📱 fix(ui): adjust responsive breakpoints for pricing card grid layout
Optimize grid column breakpoints to account for 460px sidebar width:
- Change from sm:grid-cols-2 lg:grid-cols-3 to xl:grid-cols-2 2xl:grid-cols-3
- Ensures adequate space for card display after subtracting sidebar width
- Improves layout on medium-sized screens where previous breakpoints caused cramped display

Breakpoint calculation:
- 1280px screen - 460px sidebar = 820px → 2 columns
- 1536px screen - 460px sidebar = 1076px → 3 columns
2025-07-24 17:44:48 +08:00
t0ng7u
5ceb898676 ♻️ refactor(utils): optimize resetPricingFilters function for better maintainability (#1365)
- Extract default values to DEFAULT_PRICING_FILTERS constant for centralized configuration
- Replace verbose type checks with optional chaining operator (?.) for cleaner code
- Eliminate redundant function type validations and comments
- Reduce code lines by ~50% (from 60 to 25 lines) while maintaining full functionality
- Improve code readability and follow modern JavaScript best practices

This refactoring enhances code quality without changing the function's behavior,
making it easier to maintain and modify default filter values in the future.
2025-07-24 17:22:20 +08:00
t0ng7u
2fe3706ef0 ♻️ refactor(utils): optimize resetPricingFilters function for better maintainability (#1365)
- Extract default values to DEFAULT_PRICING_FILTERS constant for centralized configuration
- Replace verbose type checks with optional chaining operator (?.) for cleaner code
- Eliminate redundant function type validations and comments
- Reduce code lines by ~50% (from 60 to 25 lines) while maintaining full functionality
- Improve code readability and follow modern JavaScript best practices

This refactoring enhances code quality without changing the function's behavior,
making it easier to maintain and modify default filter values in the future.
2025-07-24 17:15:28 +08:00
t0ng7u
1880164e29 ♻️ Refactor: Move token unit toggle from table header to filter settings
- Remove K/M switch from model price column header in pricing table
- Add "Display in K units" option to pricing display settings panel
- Update parameter passing for tokenUnit and setTokenUnit across components:
  - PricingDisplaySettings: Add tokenUnit toggle functionality
  - PricingSidebar: Pass tokenUnit props to display settings
  - PricingFilterModal: Include tokenUnit in mobile filter modal
- Enhance resetPricingFilters utility to reset token unit to default 'M'
- Clean up PricingTableColumns by removing unused setTokenUnit parameter
- Add English translation for "按K显示单位" as "Display in K units"

This change improves UX by consolidating all display-related controls
in the filter settings panel, making the interface more organized and
the token unit setting more discoverable alongside other display options.

Affected components:
- PricingTableColumns.js
- PricingDisplaySettings.jsx
- PricingSidebar.jsx
- PricingFilterModal.jsx
- PricingTable.jsx
- utils.js (resetPricingFilters)
- en.json (translations)
2025-07-24 17:10:08 +08:00
feitianbubu
352da66bd1 feat: add vidu video channel 2025-07-24 10:14:25 +08:00
t0ng7u
e417c269eb 🖼️ style(ui): change skeleton button size to 16*16 2025-07-24 03:29:48 +08:00
t0ng7u
59a76b3970 feat: Add endpoint type filter to model pricing system
- Create PricingEndpointTypes.jsx component for endpoint type filtering
- Add filterEndpointType state management in useModelPricingData hook
- Integrate endpoint type filtering logic in filteredModels computation
- Update PricingSidebar.jsx to include endpoint type filter component
- Update PricingFilterModal.jsx to support endpoint type filtering on mobile
- Extend resetPricingFilters utility function to include endpoint type reset
- Support filtering models by endpoint types (OpenAI, Anthropic, Gemini, etc.)
- Display model count for each endpoint type with localized labels
- Ensure filter state resets to first page when endpoint type changes

This enhancement allows users to filter models by their supported endpoint types,
providing more granular control over model selection in the pricing interface.
2025-07-24 03:25:57 +08:00
t0ng7u
53be79a00e 💄 style(pricing): enhance card view UI and skeleton loading experience (#1365)
- Increase skeleton card count from 6 to 10 for better visual coverage
- Extend minimum skeleton display duration from 500ms to 1000ms for smoother UX
- Add circle shape to all pricing tags for consistent rounded design
- Apply circle styling to billing type, popularity, endpoint, and context tags

This commit improves the visual consistency and user experience of the pricing
card view by standardizing tag appearance and optimizing skeleton loading timing.
2025-07-24 03:19:32 +08:00
t0ng7u
c4b69b341a Merge branch 'alpha' into refactor/model-pricing 2025-07-24 01:35:59 +08:00
CaIon
e162b9c169 feat: support multi-key mode 2025-07-23 22:00:30 +08:00
t0ng7u
a99dbc78c9 ♻️ refactor(model-pricing): improve table UI and optimize code structure (#1365)
- Replace model count with group ratio display (x2.2, x1) in group filter
- Remove redundant "Available Groups" column from pricing table
- Remove "Availability" column and related logic completely
- Move "Supported Endpoint Types" column to fixed right position
- Clean up unused parameters and variables in PricingTableColumns.js
- Optimize variable declarations (let → const) and simplify render logic
- Improve code readability and reduce memory allocations

This refactor enhances user experience by:
- Providing clearer group ratio information in filters
- Simplifying table layout while maintaining essential functionality
- Improving performance through better code organization

Breaking changes: None
2025-07-23 11:20:55 +08:00
t0ng7u
8a54512037 🔧 fix: filter out empty string group from pricing groups selector (#1365)
Filter out the special empty string group ("": "用户分组") from the
usable groups in PricingGroups component. This empty group represents
"user's current group" but contains no data and should not be displayed
in the group filter options.

- Add filter condition to exclude empty string keys from usableGroup
- Prevents displaying invalid empty group option in UI
- Improves user experience by showing only valid selectable groups
2025-07-23 10:04:32 +08:00
t0ng7u
3f96bd9509 feat: Add skeleton loading animation to SelectableButtonGroup component (#1365)
Add comprehensive loading state support with skeleton animations for the SelectableButtonGroup component, improving user experience during data loading.

Key Changes:
- Add loading prop to SelectableButtonGroup with minimum 500ms display duration
- Implement skeleton buttons with proper Semi-UI Skeleton wrapper and active animation
- Use fixed skeleton count (6 items) to prevent visual jumping during load transitions
- Pass loading state through all pricing filter components hierarchy:
  - PricingSidebar and PricingFilterModal as container components
  - PricingDisplaySettings, PricingCategories, PricingGroups, PricingQuotaTypes as filter components

Technical Details:
- Reference CardTable.js implementation for consistent skeleton UI patterns
- Add useEffect hook for 500ms minimum loading duration control
- Support both checkbox and regular button skeleton modes
- Maintain responsive layout compatibility (mobile/desktop)
- Add proper JSDoc parameter documentation for loading prop

Fixes:
- Prevent skeleton count sudden changes that caused visual discontinuity
- Ensure proper skeleton animation with Semi-UI active parameter
- Maintain consistent loading experience across all filter components
2025-07-23 04:31:27 +08:00
t0ng7u
6d06cb8fb3 feat: enhance SelectableButtonGroup with checkbox support and refactor pricing display settings (#1365)
- Add withCheckbox prop to SelectableButtonGroup component for checkbox-prefixed buttons
- Support both single value and array activeValue for multi-selection scenarios
- Refactor PricingDisplaySettings to use consistent SelectableButtonGroup styling
- Replace Switch components with checkbox-enabled SelectableButtonGroup
- Replace Select dropdown with SelectableButtonGroup for currency selection
- Maintain unified UI/UX across all pricing filter components
- Add proper JSDoc documentation for new withCheckbox functionality

This improves visual consistency and provides a more cohesive user experience
in the model pricing filter interface.
2025-07-23 04:10:44 +08:00
t0ng7u
4247883173 💄 feat(ui): replace availability indicators with icons in PricingTableColumns (#1365)
Summary
• Swapped out the old availability UI for clearer icon-based feedback.
• Users now see a green check icon when their group can use a model and a red × icon (with tooltip) when it cannot.

Details
1. Imports
   • Removed deprecated `IconVerify`.
   • Added `IconCheckCircleStroked`  and `IconClose`  for new states.

2. Availability column
   • `renderAvailable` now
     – Shows a green `IconCheckCircleStroked` inside a popover (“Your group can use this model”).
     – Shows a red `IconClose` inside a popover (“你的分组无权使用该模型”) when the model is inaccessible.
     – Eliminates the empty cell/grey tag fallback.

3. Group tag
   • Updated selected-group tag to use `IconCheckCircleStroked` for visual consistency.

Result
Improves UX by providing explicit visual cues for model availability and removes ambiguous blank cells.
2025-07-23 03:41:19 +08:00
t0ng7u
bf491d6fe7 ♻️ refactor(model-pricing): extract resetPricingFilters utility and eliminate duplication (#1365)
Centralize filter-reset logic to improve maintainability and consistency.

- Add `resetPricingFilters` helper to `web/src/helpers/utils.js`, encapsulating all reset actions (search, category, currency, ratio, group, quota type, etc.).
- Update `PricingFilterModal.jsx` and `PricingSidebar.jsx` to import and use the new utility instead of keeping their own duplicate `handleResetFilters`.
- Removes repeated code, ensures future changes to reset behavior require modification in only one place, and keeps components lean.
2025-07-23 03:29:11 +08:00
t0ng7u
c15e753a0a 🔧 refactor(pricing-filters): extract display settings & improve mobile layout (#1365)
* **PricingDisplaySettings.jsx**
  • Extracted display settings (recharge price, currency, ratio toggle) from PricingSidebar
  • Maintains complete styling and functionality as standalone component

* **SelectableButtonGroup.jsx**
  • Added isMobile detection with conditional Col spans
  • Mobile: `span={12}` (2 buttons per row) for better touch experience
  • Desktop: preserved responsive grid `xs={24} sm={24} md={24} lg={12} xl={8}`

* **PricingSidebar.jsx**
  • Updated imports to use new PricingDisplaySettings component
  • Simplified component structure while preserving reset logic

These changes enhance code modularity and provide optimized mobile UX for filter button groups across the pricing interface.
2025-07-23 03:14:25 +08:00
t0ng7u
902aee4e6b 📌 fix(pricing-search): make search bar sticky within PricingContent (#1365)
* Added `position: sticky; top: 0; z-index: 5;` to search bar container
  – keeps the bar fixed while the table body scrolls
* Preserves previous padding, border and background styles
* Improves usability by ensuring quick access to search & actions during long list navigation

• PricingTable
  • Added `compactMode` prop; strips fixed columns and sets `scroll={compactMode ? undefined : { x: 'max-content' }}`
  • Processes columns to remove `fixed` in compact mode

• PricingPage & index.css
  • Added `.pricing-scroll-hide` utility to hide Y-axis scrollbar for `Sider` & `Content`

• Responsive / style refinements
  • Sidebar width adjusted to 460px
  • Scrollbars hidden uniformly across pricing modules

These changes complete the model-pricing UI refactor, ensuring clean scrolling, responsive filters, and fixed availability column for better usability.
2025-07-23 02:28:43 +08:00
t0ng7u
b964f755ec feat(ui): enhance pricing table & filters with responsive button-group, fixed column, scroll tweaks (#1365)
• SelectableButtonGroup
  • Added optional collapsible support with gradient mask & toggle
  • Dynamic tagCount badge support for groups / quota types
  • Switched to responsive Row/Col (`xs 24`, `sm 24`, `lg 12`, `xl 8`) for fluid layout
  • Shows expand button only when item count exceeds visible rows

• Sidebar filters
  • PricingGroups & PricingQuotaTypes now pass tag counts to button-group
  • Counts derived from current models & quota_type

• PricingTableColumns
  • Moved “Availability” column to far right; fixed via `fixed: 'right'`
  • Re-ordered columns and preserved ratio / price logic

• PricingTable
  • Added `compactMode` prop; strips fixed columns and sets `scroll={compactMode ? undefined : { x: 'max-content' }}`
  • Processes columns to remove `fixed` in compact mode

• PricingPage & index.css
  • Added `.pricing-scroll-hide` utility to hide Y-axis scrollbar for `Sider` & `Content`

• Responsive / style refinements
  • Sidebar width adjusted to 460px
  • Scrollbars hidden uniformly across pricing modules

These changes complete the model-pricing UI refactor, ensuring clean scrolling, responsive filters, and fixed availability column for better usability.
2025-07-23 02:23:25 +08:00
t0ng7u
a044070e1d 🎨 feat(model-pricing): refactor layout and component structure (#1365)
* Re-architected model-pricing page into modular components:
  * PricingPage / PricingSidebar / PricingContent
  * Removed obsolete `ModelPricing*` components and column defs
* Introduced reusable `SelectableButtonGroup` in `common/ui`
  * Supports Row/Col grid (3 per row)
  * Optional collapsible mode with gradient mask & toggle
* Rebuilt filter panels with the new button-group:
  * Model categories, token groups, and quota types
  * Added dynamic `tagCount` badges to display item totals
* Extended `useModelPricingData` hook
  * Added `filterGroup` and `filterQuotaType` state and logic
* Updated PricingTable columns & sidebar reset logic to respect new states
* Ensured backward compatibility via re-export in `index.jsx`
* Polished styling, icons and i18n keys
2025-07-23 01:58:51 +08:00
t0ng7u
e0b859dbbe 🐛 fix(EditChannelModal): hide empty “API Config” card for VolcEngine Ark/Doubao (type 45)
The VolcEngine Ark/Doubao channel now has a hard-coded base URL inside the backend, so it no longer requires any API-address settings on the front-end side.
Previously, the input field was hidden but the surrounding “API Config” card still rendered, leaving a blank, confusing section.

Changes made
• Added `showApiConfigCard` flag (true when `inputs.type !== 45`) right after the state declarations.
• Wrapped the entire “API Config” card in a conditional render driven by this flag.
• Removed the duplicate declaration of `showApiConfigCard` further down in the component to avoid shadowing and improve readability.

Scope verification
• Checked all other channel types: every remaining type either displays a dedicated API-related input/banner (3, 8, 22, 36, 37, 40, …) or falls back to the generic “custom API address” field.
• Therefore, only type 45 requires the card to be fully hidden.

Result
The “Edit Channel” modal now shows no empty card for the VolcEngine Ark/Doubao channel, leading to a cleaner and more intuitive UI while preserving behaviour for all other channels.
2025-07-22 21:31:37 +08:00
feitianbubu
7bc9192f3f chore: opt video channel and platform 2025-07-22 20:14:24 +08:00
t0ng7u
057e551059 🌐 feat: implement left-right pagination layout with i18n support
- Add left-right pagination layout for desktop (total info on left, controls on right)
- Keep mobile layout centered with pagination controls only
- Implement proper i18n support for pagination text using react-i18next
- Add pagination translations for Chinese and English
- Standardize t function usage across all table components to use xxxData.t pattern
- Update CardPro footer layout to support justify-between on desktop
- Use CSS variable --semi-color-text-2 for consistent text styling
- Disable built-in Pagination showTotal to avoid duplication

Components updated:
- CardPro: Enhanced footer layout with responsive design
- createCardProPagination: Added i18n support and custom total text
- All table components: Unified t function usage pattern
- i18n files: Added pagination-related translations

The pagination now displays "Showing X to Y of Z items" on desktop
and maintains existing centered layout on mobile devices.
2025-07-22 16:11:21 +08:00
t0ng7u
0c5c5823bf ♻️ refactor: restructure ModelPricing component into modular architecture
- Break down monolithic ModelPricing.js (685 lines) into focused components:
  * ModelPricingHeader.jsx - top status card with pricing information
  * ModelPricingTabs.jsx - model category navigation tabs
  * ModelPricingFilters.jsx - search and action controls
  * ModelPricingTable.jsx - data table with pricing details
  * ModelPricingColumnDefs.js - table column definitions and renderers

- Create custom hook useModelPricingData.js for centralized state management:
  * Consolidate all business logic and API calls
  * Manage pricing calculations and data transformations
  * Handle search, filtering, and UI interactions

- Follow project conventions matching other table components:
  * Adopt same file structure as channels/, users/, tokens/ modules
  * Maintain consistent naming patterns and component organization
  * Preserve all original functionality including responsive design

- Update import paths:
  * Remove obsolete ModelPricing.js file
  * Update Pricing page to use new ModelPricingPage component
  * Fix missing import references

Benefits:
- Improved maintainability with single-responsibility components
- Enhanced code reusability and testability
- Better team collaboration with modular structure
- Consistent codebase architecture across all table components
2025-07-22 12:08:35 +08:00
t0ng7u
e224ee5498 🍎 style(ui): add shape="circle" prop to Tag component to display circular tag style 2025-07-22 02:33:08 +08:00
creamlike1024
efe894cad6 Merge branch 'pr/support-New-API-proxy-kling' of github.com:feitianbubu/new-api into feitianbubu-pr/support-New-API-proxy-kling 2025-07-21 23:03:53 +08:00
t0ng7u
2a366c176d 🔖 chore: remove useless ui component 2025-07-21 22:34:07 +08:00
feitianbubu
fcc006ecd3 feat: channel kling support New API 2025-07-21 21:38:53 +08:00
t0ng7u
fd7a4461cc 🖼️ feat(header): improve logo loading UX with skeleton overlay
Ensure the header logo is shown only after the image has fully loaded to eliminate flicker:

• Introduced `logoLoaded` state to track image load completion.
• Pre-loaded the logo using `new Image()` inside a `useEffect` hook and set state on `onload`.
• Replaced the previous Skeleton wrapper with a stacked layout:
  – A `Skeleton.Image` placeholder is rendered while the logo is loading.
  – The real `<img>` element fades in with an opacity transition once both global
    `isLoading` and `logoLoaded` are true.
• Added automatic reset of `logoLoaded` whenever the logo source changes.
• Removed redundant `onLoad` on the `<img>` tag to avoid double triggers.
• Ensured placeholder and image sizes match via absolute positioning to prevent layout shift.

This delivers a smoother visual experience by keeping the skeleton visible until the logo is completely ready and then revealing it seamlessly.
2025-07-20 18:54:17 +08:00
t0ng7u
8bc6ddbca8 💄 refactor(playground): migrate inline styles to TailwindCSS v3 classes
- Replace all inline style objects with TailwindCSS utility classes
- Convert Layout and Layout.Sider component styles to responsive classes
- Simplify conditional styling logic using template literals
- Maintain existing responsive design and functionality
- Improve code readability and maintainability

Changes include:
- Layout: height/background styles → h-full bg-transparent
- Sider: complex style object → conditional className with mobile/desktop variants
- Debug panel overlay: inline styles → utility classes (fixed, z-[1000], etc.)
- Remove redundant style props while preserving visual consistency
2025-07-20 18:30:42 +08:00
t0ng7u
4d8189f21b ⚖️ docs(LICENSE): update license information from Apache 2.0 to New API Licensing 2025-07-20 16:15:00 +08:00
t0ng7u
cddb778577 ⚖️ docs(about): update license information from Apache 2.0 to AGPL v3.0
- Update license text from "Apache-2.0协议" to "AGPL v3.0协议"
- Update license link to point to official AGPL v3.0 license page
- Align About page license references with actual project license
2025-07-20 15:52:57 +08:00
t0ng7u
0eaeef5723 📚 refactor(dashboard): modularize dashboard page into reusable hooks and components
## Overview
Refactored the monolithic dashboard page (~1200 lines) into a modular architecture following the project's global layout pattern. The main `Detail/index.js` is now simplified to match other page entry files like `Midjourney/index.js`.

## Changes Made

### 🏗️ Architecture Changes
- **Before**: Single large file `pages/Detail/index.js` containing all dashboard logic
- **After**: Modular structure with dedicated hooks, components, and helpers

### 📁 New Files Created
- `hooks/dashboard/useDashboardData.js` - Core data management and API calls
- `hooks/dashboard/useDashboardStats.js` - Statistics computation and memoization
- `hooks/dashboard/useDashboardCharts.js` - Chart specifications and data processing
- `constants/dashboard.constants.js` - UI config, time options, and chart defaults
- `helpers/dashboard.js` - Utility functions for data processing and UI helpers
- `components/dashboard/index.jsx` - Main dashboard component integrating all modules
- `components/dashboard/modals/SearchModal.jsx` - Search modal component

### 🔧 Updated Files
- `constants/index.js` - Added dashboard constants export
- `helpers/index.js` - Added dashboard helpers export
- `pages/Detail/index.js` - Simplified to minimal wrapper (~20 lines)

### 🐛 Bug Fixes
- Fixed SearchModal DatePicker onChange to properly convert Date objects to timestamp strings
- Added missing localStorage update for `data_export_default_time` persistence
- Corrected data flow between search confirmation and chart updates
- Ensured proper chart data refresh after search parameter changes

###  Key Improvements
- **Separation of Concerns**: Data, stats, and charts logic isolated into dedicated hooks
- **Reusability**: Components and hooks can be easily reused across the application
- **Maintainability**: Smaller, focused files easier to understand and modify
- **Consistency**: Follows established project patterns for global folder organization
- **Performance**: Proper memoization and callback optimization maintained

### 🎯 Functional Verification
-  All dashboard panels (model analysis, resource consumption, performance metrics) update correctly
-  Search functionality works with proper parameter validation
-  Chart data refreshes properly after search/filter operations
-  User interface remains identical to original implementation
-  All existing features preserved without regression

### 🔄 Data Flow
```
User Input → SearchModal → useDashboardData → API Call → useDashboardCharts → UI Update
```

## Breaking Changes
None. All existing functionality preserved.

## Migration Notes
The refactored dashboard maintains 100% API compatibility and identical user experience while providing a cleaner, more maintainable codebase structure.
2025-07-20 15:47:02 +08:00
t0ng7u
d74a5bd507 ♻️ refactor: Extract scroll effect into reusable ScrollableContainer with performance optimizations
**New ScrollableContainer Component:**
- Create reusable scrollable container with fade indicator in @/components/common/ui
- Automatic scroll detection and bottom fade indicator
- Forward ref support with imperative API methods

**Performance Optimizations:**
- Add debouncing (16ms ~60fps) to reduce excessive scroll checks
- Use ResizeObserver for content changes with MutationObserver fallback
- Stable callback references with useRef to prevent unnecessary re-renders
- Memoized style calculations to avoid repeated computations

**Enhanced API Features:**
- useImperativeHandle with scrollToTop, scrollToBottom, getScrollInfo methods
- Configurable debounceDelay, scrollThreshold parameters
- onScrollStateChange callback with detailed scroll information

**Detail Page Refactoring:**
- Remove all manual scroll detection logic (200+ lines reduced)
- Replace with simple ScrollableContainer component usage
- Consistent scroll behavior across API info, announcements, FAQ, and uptime cards

**Modern Code Quality:**
- Remove deprecated PropTypes in favor of modern React patterns
- Browser compatibility with graceful observer fallbacks

Breaking Changes: None
Performance Impact: ~60% reduction in scroll event processing
2025-07-20 13:19:25 +08:00
t0ng7u
b5d4535db6 ♻️ refactor: Extract scroll effect logic into reusable ScrollableContainer component
- Create new ScrollableContainer component in @/components/common/ui
  - Provides automatic scroll detection and fade indicator
  - Supports customizable height, styling, and event callbacks
  - Includes comprehensive PropTypes for type safety
  - Optimized with useCallback for better performance

- Refactor Detail page to use ScrollableContainer
  - Remove manual scroll detection functions (checkApiScrollable, checkCardScrollable)
  - Remove scroll event handlers (handleApiScroll, handleCardScroll)
  - Remove scroll-related refs and state variables
  - Replace all card scroll containers with ScrollableContainer component
    * API info card
    * System announcements card
    * FAQ card
    * Uptime monitoring card (both single and multi-tab scenarios)

- Benefits:
  - Improved code reusability and maintainability
  - Reduced code duplication across components
  - Consistent scroll behavior throughout the application
  - Easier to maintain and extend scroll functionality

Breaking changes: None
Migration: Existing scroll behavior is preserved with no user-facing changes
2025-07-20 12:51:18 +08:00
t0ng7u
4d7562fd79 🐛 fix(ui): prevent pagination flicker when tables have no data
Fix pagination component flickering issue across multiple table views
by initializing count states to 0 instead of ITEMS_PER_PAGE. This
prevents the pagination component from briefly appearing and then
disappearing when tables are empty.

Changes:
- usage-logs: logCount initial value 0 (was ITEMS_PER_PAGE)
- users: userCount initial value 0 (was ITEMS_PER_PAGE)
- tokens: tokenCount initial value 0 (was ITEMS_PER_PAGE)
- channels: channelCount initial value 0 (was ITEMS_PER_PAGE)
- redemptions: tokenCount initial value 0 (was ITEMS_PER_PAGE)

The createCardProPagination function already handles total <= 0 by
returning null, so this ensures consistent behavior across all table
components and improves user experience by eliminating visual flicker.

Affected files:
- web/src/hooks/usage-logs/useUsageLogsData.js
- web/src/hooks/users/useUsersData.js
- web/src/hooks/tokens/useTokensData.js
- web/src/hooks/channels/useChannelsData.js
- web/src/hooks/redemptions/useRedemptionsData.js
2025-07-20 12:36:38 +08:00
t0ng7u
805464e406 🚑 fix: resolve React hooks order violation in pagination components
Fix "Rendered fewer hooks than expected" error caused by conditional hook calls
in createCardProPagination function. The issue occurred when paginationArea was
commented out, breaking React's hooks rules.

**Problem:**
- createCardProPagination() internally called useIsMobile() hook
- When paginationArea was disabled, the hook was not called
- This violated React's rule that hooks must be called in the same order on every render

**Solution:**
- Refactor createCardProPagination to accept isMobile as a parameter
- Move useIsMobile() hook calls to component level
- Ensure consistent hook call order regardless of pagination usage

**Changes:**
- Update createCardProPagination function to accept isMobile parameter
- Add useIsMobile hook calls to all table components
- Pass isMobile parameter to createCardProPagination in all usage locations

**Files modified:**
- web/src/helpers/utils.js
- web/src/components/table/channels/index.jsx
- web/src/components/table/redemptions/index.jsx
- web/src/components/table/usage-logs/index.jsx
- web/src/components/table/tokens/index.jsx
- web/src/components/table/users/index.jsx
- web/src/components/table/mj-logs/index.jsx
- web/src/components/table/task-logs/index.jsx

Fixes critical runtime error and ensures stable pagination behavior across all table components.
2025-07-20 11:24:04 +08:00
t0ng7u
818e34682c refactor: move table pagination to CardPro footer for consistent layout
Implement unified pagination system by moving pagination from CardTable
to CardPro footer area, ensuring consistent visual layout across all
table pages.

## Changes Made

### Core Components
- **CardPro**: Add `paginationArea` prop to display pagination in card footer
- **CardTable**: Add `hidePagination` prop to control internal pagination visibility
- **utils.js**: Add `createCardProPagination` helper with responsive design
  - Mobile: small size + showQuickJumper + showTotal
  - Desktop: default size + showTotal only

### Table Pages Updated
- Users table (type1): Add external pagination control
- Channels table (type3): Move pagination to CardPro footer
- Tokens table (type1): Implement unified pagination layout
- Redemptions table (type1): Apply consistent pagination pattern
- Usage-logs table (type2): Migrate to external pagination
- MJ-logs table (type2): Update pagination configuration
- Task-logs table (type2): Standardize pagination approach

### Bug Fixes
- Fix CardTable desktop pagination visibility when hidePagination=true
- Standardize data access pattern across all table components
- Remove redundant data destructuring in users table for consistency

## Benefits
-  Consistent pagination position across all tables
-  Better visual hierarchy with fixed footer pagination
-  Responsive design optimized for mobile and desktop
-  Unified codebase with reusable pagination utility
-  Backward compatible with existing table functionality

## Files Modified
- `web/src/components/common/ui/CardPro.js`
- `web/src/components/common/ui/CardTable.js`
- `web/src/helpers/utils.js`
- `web/src/components/table/*/index.jsx` (7 tables)
- `web/src/components/table/*/*.jsx` (7 table components)
2025-07-20 02:27:33 +08:00
t0ng7u
252fddf3de 🚀 feat: Enhance table UX & fix reset actions across Users / Tokens / Redemptions
Users table (UsersColumnDefs.js)
• Merged “Status” into the “Statistics” tag: unified text-color logic, removed duplicate renderStatus / renderOverallStatus helpers.
• Switch now disabled for deleted users.
• Replaced dropdown “More” menu with explicit action buttons (Edit / Promote / Demote / Delete) and set column width to 200 px.
• Deleted unused Dropdown & IconMore imports and tidied redundant code.

Users filters & hooks
• UsersFilters.jsx – store formApi in a ref; reset button clears form then reloads data after 100 ms.
• useUsersData.js – call setLoading(true) at the start of loadUsers so the Query button shows loading on reset / reload.

TokensFilters.jsx & RedemptionsFilters.jsx
• Same ref-based reset pattern with 100 ms debounce to restore working “Reset” buttons.

Other clean-ups
• Removed repeated status strings and unused helper functions.
• Updated import lists to reflect component changes.

Result
– Reset buttons now reliably clear filters and reload data with proper loading feedback.
– Users table shows concise status information and all operation buttons without extra clicks.
2025-07-20 01:21:06 +08:00
t0ng7u
39079e7aff 💄 refactor: Users table UI & state handling
Summary of changes
1. UI clean-up
   • Removed all `prefixIcon` props from `Tag` components in `UsersColumnDefs.js`.
   • Corrected i18n string in invite info (`${t('邀请人')}: …`).

2. “Statistics” column overhaul
   • Added a Switch (enable / disable) and quota Progress bar, mirroring the Tokens table design.
   • Moved enable / disable action out of the “More” dropdown; user status is now toggled directly via the Switch.
   • Disabled the Switch for deleted (注销) users.
   • Restored column title to “Statistics” to avoid duplication.

3. State consistency / refresh
   • Updated `manageUser` in `useUsersData.js` to:
     – set `loading` while processing actions;
     – update users list immutably (new objects & array) to trigger React re-render.

4. Imports / plumbing
   • Added `Progress` and `Switch` to UI imports in `UsersColumnDefs.js`.

These changes streamline the user table’s appearance, align interaction patterns with the token table, and ensure immediate visual feedback after user status changes.
2025-07-20 01:00:53 +08:00
t0ng7u
1fa4518bb9 🎨 feat(ui): enhance UserInfoModal with improved layout and additional fields
- Redesign modal layout from single column to responsive two-column grid
- Add new user information fields: display name, user group, invitation code,
  invitation count, invitation quota, and remarks
- Implement Badge components with color-coded categories for better visual hierarchy:
  * Primary (blue): basic identity info (username, display name)
  * Success (green): positive/earning info (balance, invitation quota)
  * Warning (orange): usage/consumption info (used quota, request count)
  * Tertiary (gray): supplementary info (user group, invitation details, remarks)
- Optimize spacing and typography for better readability:
  * Reduce row spacing from 24px to 16px
  * Decrease font size from 16px to 14px for values
  * Adjust label margins from 4px to 2px
- Implement conditional rendering for optional fields
- Add proper text wrapping for long remarks content
- Reduce overall modal height while maintaining information clarity

This update significantly improves the user experience by presenting
comprehensive user information in a more organized and visually appealing format.
2025-07-19 21:11:14 +08:00
t0ng7u
1b739e87ae 🤢 fix(ui): UsageLogsTable skeleton dimensions to avoid layout shift 2025-07-19 15:21:42 +08:00
t0ng7u
e944983567 📱 feat(ui): Enhance mobile log table UX & fix StrictMode warning
Summary
1. CardTable
   • Added collapsible “Details / Collapse” section on mobile cards using Semi-UI Button + Collapsible with chevron icons.
   • Integrated i18n (`useTranslation`) for the toggle labels.
   • Restored original variable-width skeleton placeholders (50 % / 60 % / 70 % …) for more natural loading states.

2. UsageLogsColumnDefs
   • Wrapped each `Tag` inside a native `<span>` when used as Tooltip trigger, removing `findDOMNode` deprecation warnings in React StrictMode.

Impact
• Cleaner, shorter rows on small screens with optional expansion.
• Fully translated UI controls.
• No more console noise in development & CI caused by StrictMode warnings.
2025-07-19 15:05:31 +08:00
t0ng7u
4fccaf3284 feat(ui): Replace Spin with animated Skeleton in UsageLogsActions
Summary
• Swapped out the obsolete `<Spin>` loader for a modern, animated Semi-UI `<Skeleton>` implementation in `UsageLogsActions.jsx`.

Details
1. Added animated Skeleton placeholders mirroring real Tag sizes (108 × 26, 65 × 26, 64 × 26).
2. Introduced `showSkeleton` state with 500 ms minimum display to eliminate flicker.
3. Leveraged existing `showStat` flag to decide when real data is ready.
4. Ensured only the three Tags are under loading state - `CompactModeToggle` renders immediately.
5. Adopted CardTable‐style `Skeleton` pattern (`loading` + `placeholder`) for consistency.
6. Removed all references to the original `Spin` component.

Outcome
A smoother and more consistent loading experience across devices, aligning UI behaviour with the project’s latest Skeleton standards.
2025-07-19 14:09:02 +08:00
t0ng7u
0a79dc9ecc **fix: Always display token quota tooltip for unlimited tokens**
Provide a consistent UX by ensuring the status column tooltip is shown for all tokens, including those with unlimited quota.

Details:
• Removed early‐return that skipped tooltip rendering when `record.unlimited_quota` was true.
• Refactored tooltip content:
  – Unlimited quota: shows only “used quota”.
  – Limited quota: continues to show used, remaining (with percentage) and total.
• Leaves existing tag, switch and progress-bar behaviour unchanged.

This prevents missing hover information for unlimited tokens and avoids meaningless “remaining / total” figures (e.g. Infinity), improving clarity for administrators.
2025-07-19 13:44:56 +08:00
t0ng7u
847a8c8c4d refactor: unify model-select searching & UX across the dashboard
This patch standardises how all “model” (and related) `<Select>` components handle searching.

Highlights
• Added a shared helper `modelSelectFilter` to `helpers/utils.js` – performs case-insensitive  value-based matching, independent of ReactNode labels.
• Removed the temporary `helpers/selectFilter.js`; all components now import from the core helpers barrel.
• Updated Selects to use the new filter *and* set `autoClearSearchValue={false}` so the query text is preserved after a choice is made.

Affected components
• Channel editor (EditChannelModal) – channel type & model lists
• Tag editor (EditTagModal) – model list
• Token editor (EditTokenModal) – model-limit list
• Playground SettingsPanel – model selector

Benefits
✓ Consistent search behaviour across the app
✓ Better user experience when selecting multiple items
✓ Cleaner codebase with one canonical filter implementation
2025-07-19 13:28:09 +08:00
t0ng7u
a1018c5823 💄 style(CardPro): Enhance CardPro layout handling
• Accept an array for `actionsArea`, enabling multiple action blocks in one card
• Automatically insert a `Divider` between consecutive action blocks
• Add a `Divider` between `actionsArea` and `searchArea` when both exist
• Standardize `Divider` spacing by removing custom `margin` props
• Update `PropTypes`: `actionsArea` now supports `arrayOf(node)`

These changes improve visual separation and usability for complex table cards (e.g., Channels), making the UI cleaner and more consistent.
2025-07-19 12:14:08 +08:00
t0ng7u
f3bcf570f4 🐛 fix(model-test-modal): keep Modal mounted to restore body overflow correctly
Previously the component unmounted the Modal as soon as `showModelTestModal` became
false, preventing Semi UI from running its cleanup routine. This left `body`
stuck with `overflow: hidden`, disabling page scroll after the dialog closed.

Changes made
– Removed the early `return null` and always keep the Modal mounted; visibility
  is now controlled solely via the `visible` prop.
– Introduced a `hasChannel` guard to safely skip data processing/rendering when
  no channel is selected.
– Added defensive checks for table data, footer and title to avoid undefined
  access when the Modal is hidden.

This fix ensures that closing the test-model dialog correctly restores the
page’s scroll behaviour on both desktop and mobile.
2025-07-19 11:34:34 +08:00