Conversation
- Add comprehensive dark theme with CSS custom properties - Implement glassmorphism effects and modern card styles - Update all UI components with new design system - Add smooth animations and transitions - Reduce code complexity while maintaining functionality - Improve visual hierarchy with better typography and spacing
✅ Deploy Preview for tel-on-chain ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
WalkthroughThis PR introduces a comprehensive design system overhaul for the tel-ui-web frontend, migrating from basic light theme styling to a cohesive dark theme with semantic color tokens, modernized UI components, and refined visual layouts across pages and components while simplifying state management in several areas. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~35 minutes Areas requiring extra attention:
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (8)
tel-ui-web/src/components/ui/Button.tsx (1)
21-25: Inconsistent hover color for danger variant.The danger variant uses a hardcoded
hover:bg-red-600while all other variants use CSS variables for hover states. For design system consistency, consider using a CSS variable like--danger-hover.- 'bg-[var(--danger)] text-white hover:bg-red-600': variant === 'danger', + 'bg-[var(--danger)] text-white hover:bg-[var(--danger-hover)]': variant === 'danger',This would require adding
--danger-hoverto your CSS variables inglobals.css.tel-ui-web/src/components/TokenSelector.tsx (1)
39-43: Silent failure when addresses are invalid.The guard
if (!isValidAddress(...)) return;silently exits without user feedback. However, the form already has validation viareact-hook-form(lines 97-98, 106-107). This guard is redundant sincehandleSubmitwon't callonSubmitif validation fails, unless the form is submitted programmatically.Consider removing this redundant check or, if kept for defensive purposes, adding user feedback.
const onSubmit = (data: FormData) => { - if (!isValidAddress(data.token0) || !isValidAddress(data.token1)) return; onTokensChange(data.token0, data.token1); onFiltersChange({ chainId: data.chainId, dex: data.dex || undefined }); };tel-ui-web/src/components/ui/Pagination.tsx (1)
76-85: Inconsistent use of raw<button>instead ofButtoncomponent.The navigation arrows use the
Buttoncomponent, but page number buttons use raw<button>elements with inline styles. This creates inconsistency in focus states, accessibility features, and styling patterns.Consider using the
Buttoncomponent with appropriate variant for page numbers to maintain consistency.- <button - onClick={() => onPageChange(page as number)} - className={`min-w-[32px] h-8 text-sm rounded-md transition-all ${ - currentPage === page - ? 'bg-[var(--accent)] text-white' - : 'text-[var(--foreground-muted)] hover:text-[var(--foreground)] hover:bg-[var(--surface)]' - }`} - > - {page} - </button> + <Button + variant={currentPage === page ? 'primary' : 'ghost'} + size="sm" + onClick={() => onPageChange(page as number)} + className="min-w-[32px]" + > + {page} + </Button>tel-ui-web/src/components/PoolList.tsx (1)
27-32: Consider making chainId configurable.The
chainIdis hardcoded to1(Ethereum mainnet). If multi-chain support is planned, consider accepting this as a prop or from a context provider.tel-ui-web/src/app/globals.css (1)
99-118: Gradient utilities use hardcoded secondary colors.The gradient definitions mix CSS variables with hardcoded hex values (e.g.,
#8b5cf6,#34d399,#f87171,#a78bfa). For consistency and easier theme adjustments, consider defining these as CSS variables.:root { + /* Gradient secondary colors */ + --accent-gradient-end: #8b5cf6; + --success-gradient-end: #34d399; + --danger-gradient-end: #f87171; ... } .gradient-accent { - background: linear-gradient(135deg, var(--accent) 0%, #8b5cf6 100%); + background: linear-gradient(135deg, var(--accent) 0%, var(--accent-gradient-end) 100%); }tel-ui-web/src/components/StatsSummary.tsx (1)
157-191: Non-null assertions rely on surrounding conditionals.The code uses
!assertions (e.g.,displayData.strongestBuyLevel!.token1_liquidity) after conditional checks. While safe in this context, extracting the values in the condition would be more explicit:{displayData.isAggregate && displayData.strongestBuyLevel && ( <div className="..."> {/* Use strongestBuyLevel directly without ! */} {formatNumber(displayData.strongestBuyLevel.token1_liquidity, { compact: true })} </div> )}tel-ui-web/src/app/token-aggregate/page.tsx (1)
197-206: StatsSummary receives zeroes for liquidity but relies on aggregate mode.Passing
totalBuyLiquidity={0}andtotalSellLiquidity={0}works becausemode="aggregate"causesStatsSummaryto fetch its own data. However, this creates duplicate API calls sinceuseTokenAggregateDatais called both here and insideStatsSummary.Consider either passing the already-fetched
datato avoid duplicate requests, or calculating the totals here and passing them directly.+const totalBuyLiquidity = data?.price_levels + ?.filter(level => level.side === 'Buy') + .reduce((sum, level) => sum + level.token1_liquidity, 0) ?? 0; + +const totalSellLiquidity = data?.price_levels + ?.filter(level => level.side === 'Sell') + .reduce((sum, level) => sum + level.token1_liquidity, 0) ?? 0; <StatsSummary - totalBuyLiquidity={0} - totalSellLiquidity={0} + totalBuyLiquidity={totalBuyLiquidity} + totalSellLiquidity={totalSellLiquidity} currentPrice={data.current_price} token0Symbol={data.token0.symbol} token1Symbol={data.token1.symbol} - mode="aggregate" - tokenAddress={submittedToken} + mode="pair" chainId={1} />tel-ui-web/src/components/LiquidityChart.tsx (1)
132-151: Consider extracting the toggle button to reduce duplication.The price type toggle buttons share identical structure with only the value and label differing. Consider extracting this pattern into a reusable component or using a mapping approach.
Apply this diff to reduce duplication:
- <div className="flex items-center gap-2 p-1 rounded-lg bg-[var(--surface)]"> - <button - onClick={() => onPriceTypeChange('wall')} - className={`px-3 py-1.5 text-xs font-medium rounded-md transition-all ${ - priceType === 'wall' - ? 'bg-[var(--accent)] text-white' - : 'text-[var(--foreground-muted)] hover:text-[var(--foreground)]' - }`} - > - Wall Price - </button> - <button - onClick={() => onPriceTypeChange('current')} - className={`px-3 py-1.5 text-xs font-medium rounded-md transition-all ${ - priceType === 'current' - ? 'bg-[var(--accent)] text-white' - : 'text-[var(--foreground-muted)] hover:text-[var(--foreground)]' - }`} - > - Current - </button> - </div> + <div className="flex items-center gap-2 p-1 rounded-lg bg-[var(--surface)]"> + {(['wall', 'current'] as const).map((type) => ( + <button + key={type} + onClick={() => onPriceTypeChange(type)} + className={`px-3 py-1.5 text-xs font-medium rounded-md transition-all ${ + priceType === type + ? 'bg-[var(--accent)] text-white' + : 'text-[var(--foreground-muted)] hover:text-[var(--foreground)]' + }`} + > + {type === 'wall' ? 'Wall Price' : 'Current'} + </button> + ))} + </div>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
tel-ui-web/src/app/globals.css(1 hunks)tel-ui-web/src/app/layout.tsx(2 hunks)tel-ui-web/src/app/page.tsx(4 hunks)tel-ui-web/src/app/token-aggregate/page.tsx(2 hunks)tel-ui-web/src/components/LiquidityChart.tsx(4 hunks)tel-ui-web/src/components/PoolList.tsx(2 hunks)tel-ui-web/src/components/StatsSummary.tsx(2 hunks)tel-ui-web/src/components/TokenSelector.tsx(5 hunks)tel-ui-web/src/components/ui/Button.tsx(3 hunks)tel-ui-web/src/components/ui/Input.tsx(2 hunks)tel-ui-web/src/components/ui/Pagination.tsx(2 hunks)tel-ui-web/src/components/ui/Select.tsx(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (7)
tel-ui-web/src/components/ui/Pagination.tsx (1)
tel-ui-web/src/components/ui/Button.tsx (1)
Button(51-51)
tel-ui-web/src/components/LiquidityChart.tsx (1)
tel-ui-web/src/lib/utils.ts (2)
formatNumber(7-35)formatPrice(37-79)
tel-ui-web/src/components/ui/Input.tsx (1)
tel-ui-web/src/lib/utils.ts (1)
cn(3-5)
tel-ui-web/src/components/ui/Select.tsx (1)
tel-ui-web/src/lib/utils.ts (1)
cn(3-5)
tel-ui-web/src/components/PoolList.tsx (3)
tel-ui-web/src/hooks/usePoolData.ts (1)
usePoolData(23-77)tel-ui-web/src/types/api.ts (1)
Pool(53-63)tel-ui-web/src/components/ui/Pagination.tsx (1)
Pagination(14-101)
tel-ui-web/src/components/TokenSelector.tsx (5)
tel-ui-web/src/lib/utils.ts (1)
isValidAddress(86-88)tel-ui-web/src/lib/constants.ts (1)
SUPPORTED_CHAINS(3-24)tel-ui-web/src/components/ui/Button.tsx (1)
Button(51-51)tel-ui-web/src/components/ui/Input.tsx (1)
Input(42-42)tel-ui-web/src/components/ui/Select.tsx (1)
Select(53-53)
tel-ui-web/src/app/token-aggregate/page.tsx (3)
tel-ui-web/src/hooks/useTokenAggregateData.ts (1)
useTokenAggregateData(18-65)tel-ui-web/src/components/LiquidityChart.tsx (1)
LiquidityChart(89-205)tel-ui-web/src/components/StatsSummary.tsx (1)
StatsSummary(22-196)
🔇 Additional comments (22)
tel-ui-web/src/components/ui/Select.tsx (1)
20-44: LGTM! Consistent styling with the new design system.The Select component styling aligns well with the Input component, using the same CSS variables and transition patterns. The error state handling and hover effects are appropriately implemented.
tel-ui-web/src/components/ui/Button.tsx (1)
38-41: Clean loading spinner implementation.The spinner uses
currentColorappropriately, ensuring it inherits the correct color from each button variant. The opacity layering creates a nice visual effect.tel-ui-web/src/app/layout.tsx (2)
22-22: Hardcoded dark mode ignores user system preferences.The
className="dark"is hardcoded, which means users who prefer light mode (via OS settings) won't have their preference respected. If this is intentional (dark-only design), this is fine. Otherwise, consider respectingprefers-color-schemeor providing a toggle.Is the intent to have a dark-only theme, or should there be light mode support in the future?
4-14: Metadata updates look good.The updated title, keywords, and OpenGraph data better reflect the analytics focus of the application.
tel-ui-web/src/components/TokenSelector.tsx (1)
61-71: Styling updates align with the design system.The use of CSS variables and consistent class naming (e.g.,
card,text-[var(--foreground)],text-[var(--accent)]) integrates well with the broader theming changes.tel-ui-web/src/components/ui/Input.tsx (1)
14-33: LGTM! Consistent theming with Select component.The Input component styling mirrors the Select component exactly, ensuring a cohesive form control appearance. The placeholder opacity modifier (
/50) and error state handling are well-implemented.tel-ui-web/src/components/ui/Pagination.tsx (1)
22-46: Page number generation logic is correct.The algorithm properly handles edge cases with dots for ellipsis, deduplicates entries, and guards against small page counts. The early return on line 51 prevents unnecessary rendering.
tel-ui-web/src/app/page.tsx (3)
43-80: Header implementation looks good.The sticky header with glassmorphism effect (
glassclass) is well-implemented. The conditional rendering of the back button based oncurrentViewand the refresh functionality with loading state are properly handled.
113-151: Welcome state UI is clean and informative.The empty state provides clear guidance with visual hierarchy. The feature list effectively communicates the application's capabilities.
177-203: Error handling provides good UX with recovery option.The error state includes clear messaging, visual indicators, and a retry button. Consider wrapping the error display with an error boundary at a higher level for uncaught exceptions.
tel-ui-web/src/components/PoolList.tsx (2)
34-41: Client-side filtering on paginated data may yield incomplete results.The search filter operates only on the currently fetched page of pools. Users searching for a specific pool may not find it if it's on a different page. Consider either fetching all pools for client-side search or implementing server-side search.
117-147: Pool list UI and selection state look good.The pool row implementation with hover states, selection highlighting, and truncated address display provides a clean UX. The DEX badge using
DEX_NAMESmapping with fallback to raw value is a nice touch.tel-ui-web/src/app/globals.css (2)
3-33: Well-structured design token system.The CSS custom properties are organized logically with clear naming conventions. The semantic color tokens (success, danger, warning) and the subtle variants with rgba transparency provide a flexible theming foundation.
126-152: Animations are appropriately subtle.The animation durations (0.3s-0.4s) and easing functions are well-chosen for a professional feel. The
pulse-glowinfinite animation is used sparingly which is good for performance.tel-ui-web/src/components/StatsSummary.tsx (2)
40-79: Data transformation logic is well-structured.The
useMemocorrectly handles both aggregate and pair modes with appropriate dependency array. The conditional data fetching pattern (passingundefinedto skip) integrates cleanly with the hook design.
137-149: Ratio bar provides clear visual feedback.The buy/sell ratio visualization with the progress bar and numeric display effectively communicates the liquidity balance. The transition animation adds polish.
tel-ui-web/src/app/token-aggregate/page.tsx (2)
37-46: Chart data transformation is correct.The filtering for valid price bounds and mapping to the expected chart format handles the data appropriately. The fallback to empty array prevents runtime errors.
99-111: Example tokens provide good discoverability.The quick-access buttons for common tokens improve UX by letting users explore without knowing addresses. The click handler correctly sets both input and submitted state.
tel-ui-web/src/components/LiquidityChart.tsx (4)
36-70: LGTM! Clean tooltip modernization.The inline type annotation is appropriate for the Recharts tooltip, and the updated styling with CSS variables aligns well with the new design system. The simplified "Buy"/"Sell" labels improve clarity.
72-87: Axis tick styling updated correctly.The color tokens and typography updates align with the new design system. The positioning and rotation values are appropriate for the chart layout.
90-104: Data processing logic is sound.The state management and memoized data processing correctly filter and sort based on the scale range. The useMemo dependencies are complete and appropriate.
171-202: CSS custom properties are properly defined.All CSS variables used in the chart (
--foreground-muted,--border,--success,--danger,--accent,--foreground) are correctly defined intel-ui-web/src/app/globals.cssand will render as expected.
| /* Text gradient */ | ||
| .text-gradient { | ||
| background: linear-gradient(135deg, var(--accent) 0%, #a78bfa 100%); | ||
| -webkit-background-clip: text; | ||
| -webkit-text-fill-color: transparent; | ||
| background-clip: text; | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
CSS background-clip text browser support compatibility 2024 2025
💡 Result:
Short answer
- background-clip: text is widely usable in modern browsers in 2024–2025, but you should still include the WebKit-prefixed form for best cross‑browser coverage (Safari, older Chrome/Edge builds). Use color: transparent. [1][2][3]
Compatibility summary (Dec 2025)
- Safari (macOS & iOS): supports (has long required -webkit- prefix in many releases). [1][2]
- Chrome / Edge / Chrome for Android / Samsung Internet: supported in modern releases (unprefixed in recent Chromium; older versions relied on -webkit-). [2][3]
- Firefox: historically differed — behavior and support has changed across versions; test target Firefox versions and use fallbacks/feature queries. [1][2][3]
Recommended pattern
-
Use both forms and a feature query/fallback:
.text-clip {
background: linear-gradient(90deg,#f06,#4a90e2);
color: transparent;
-webkit-background-clip: text;
background-clip: text;
} -
Optional feature query to provide alternate styling when not supported:
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
.text-clip { color: #f06; /* fallback */ }
}
Sources
[1] MDN — background-clip (docs + compatibility).
[2] Web Platform Features Explorer — background-clip: text (status & notes).
[3] Can I use — background-clip (support table).
🌐 Web query:
-webkit-text-fill-color transparent text selection accessibility issues
💡 Result:
Short answer
- Using -webkit-text-fill-color: transparent with -webkit-background-clip: text (or background-clip: text) can make text selection invisible or low‑contrast for some users because the fill remains transparent when selected unless you explicitly override selection styles. It’s also a non‑standard WebKit property with browser-support and rendering quirks to watch. [1][2][3][4]
Why this causes accessibility issues
- Transparent fill + clipped background = the visible color is the background image/gradient; when a user selects text the browser’s selection styling may not change that clipped background, leaving selected text unreadable (insufficient contrast) or completely invisible. That breaks WCAG contrast requirements for selected text. [1][2]
- -webkit-text-fill-color is WebKit-specific and historically had inconsistent behavior across engines and versions (rendering artifacts, differing precedence vs color). If a browser doesn’t support background-clip:text, using color: transparent will simply hide text. [2][3][5]
How to fix / mitigate (brief)
- Provide a safe fallback: use feature queries and fallbacks so non‑supporting browsers get a normal readable color. Example: @supports (background-clip: text) { ... } else use a plain color. [2]
- Override ::selection to set readable selected text and selection background (ensure contrast ratio >= WCAG). Many browsers accept -webkit-text-fill-color inside ::selection, so explicitly set selection text color (not transparent). Example approach: ::selection { background: #xxx; color: #yyy; -webkit-text-fill-color: #yyy; }. That restores visibility when selected. [1][4]
- Test across browsers (Safari/Chrome/Edge/Firefox) and assistive tech; avoid relying solely on non‑standard properties for critical content. [2][3]
References
- MDN ::selection — notes on allowed properties and accessibility/contrast guidance. [1]
- WebKit blog: background-clip:text history and recommended feature-query/fallback patterns. [2]
- Stack Overflow discussion on -webkit-text-fill-color vs color, browser behavior and why people use the prefixed property. [3]
- Practical example showing overriding selection to restore readable selected text. [4]
Sources
[1] MDN ::selection (CSS) — selection styling and accessibility.
[2] WebKit blog — background-clip:text and guidance (feature queries / fallbacks).
[3] StackOverflow threads on -webkit-text-fill-color and compatibility/behavior.
[4] Practical tutorial / article demonstrating ::selection override to fix selection visibility.
🌐 Web query:
CSS background-clip text fallback accessibility WCAG guidelines
💡 Result:
Short answer: using background-clip: text (text filled with an image/gradient) is treated like "text over an image" or "image of text" for WCAG — it must remain readable and meet the WCAG contrast and non‑text rules, and you must provide an accessible fallback if the decorative effect is unavailable. Key requirements and practical fallbacks:
What WCAG requires (high level)
- Text over images/gradients must meet the WCAG contrast rules (1.4.3 and, for higher level, 1.4.6). Test the actual text appearance against the worst-case background area. [1][2][3]
- If text is effectively an "image of text" (purely decorative headings, logos, or text conveyed only visually), follow the Images of Text guidance: don’t use images of text for essential content; provide text alternatives or use real text styled for accessibility. [4][5]
Accessibility risks with background-clip: text
- The visible fill is an image/gradient that can vary under the glyphs, making contrast unpredictable and harder to test. Automated tools may flag failures if any glyph area falls below required contrast. [1][6]
- Some user agents or high‑contrast modes may ignore background images/CSS effects, which can hide the fill and change appearance; ensure content still remains readable. [3]
Practical fallbacks and fixes
- Provide a solid-color or high-contrast text fallback for UAs that don't support the effect:
- e.g. set color to an accessible color and then override with background/clip when supported. Use feature detection (e.g. @supports(-webkit-background-clip: text) ) or progressive enhancement. [MDN guidance; see example below]. [2]
- Ensure the fallback (or combination of background + text outline/overlay) meets WCAG contrast (4.5:1 for normal text, 3:1 for large). If the clipped background has variable color, add a semi-opaque overlay behind the text area or a text-stroke/shadow to guarantee contrast against the worst-case background. [1][3][6]
- Avoid using the effect for essential information or interactive controls. If it’s decorative, mark it as decorative (so it isn’t relied on by AT) or ensure the content is available as plain accessible text. [4]
- Test visually on real content and across the worst-case parts of the background (not just an average color). Use contrast tools and manual checks (including high-contrast modes and UA text-only rendering). The W3C ACT rules and testing guidance explain how to test text-over-image cases. [7][5]
Minimal code pattern (concept)
- Provide accessible fallback color, then enable clipped fill when supported:
- base: color: #111; /* accessible fallback */
- @supports (background-clip: text) { background: linear-gradient(...); -webkit-background-clip: text; color: transparent; }
- If needed add: text-shadow or -webkit-text-stroke and/or a semi-opaque overlay to ensure contrast for all parts of the glyphs.
References
- WCAG understanding for Contrast (1.4.3 / 1.4.6) and contrast testing guidance. [W3C / Understanding Contrast]. [1]
- MDN accessibility guide on color contrast and readability (text over images/gradients). [2]
- WCAG Techniques: using CSS for decorative images and notes about background images being ignored by user agents. [3]
- W3C Images of Text guidance / ACT rule (Images of Text & when images-of-text are allowed). [4][7]
- W3C ACT rule: "Text has minimum contrast" and "Images of text" that cover testing rules for text over backgrounds. [7]
- Practical guidance on testing and fixing text-over-image contrast (developer/accessibility guides). [6]
If you want, I can:
- give a short tested CSS snippet with feature detection and a11y-safe fallback; or
- check a specific gradient/image + font size you plan to use for contrast and propose exact color/overlay values.
Add accessible fallback and ::selection styling for text gradient.
The current gradient text technique has two accessibility issues:
-
Selected text is invisible — When users select the text,
-webkit-text-fill-color: transparentcauses selected text to become unreadable or invisible because the selection styling doesn't properly override the transparent fill. Add::selectionoverride to restore contrast:.text-gradient::selection { background: [selection-bg-color]; -webkit-text-fill-color: [readable-text-color]; }
-
Missing fallback for unsupported browsers — Browsers without
background-clip: textsupport (and some Firefox versions) will render invisible text. Add a feature query with a fallback color:.text-gradient { color: [accessible-fallback-color]; /* fallback */ } @supports (background-clip: text) { .text-gradient { background: linear-gradient(135deg, var(--accent) 0%, #a78bfa 100%); -webkit-background-clip: text; background-clip: text; color: transparent; } }
Ensure the fallback color meets WCAG contrast ratio (4.5:1 for normal text).
🤖 Prompt for AI Agents
In tel-ui-web/src/app/globals.css around lines 112 to 118, the .text-gradient
rule makes selected text invisible and provides no fallback for browsers lacking
background-clip:text; fix by adding a .text-gradient::selection rule that
restores a readable text color and a readable selection background, and add a
fallback color on .text-gradient plus an @supports (background-clip: text) block
that applies the gradient, background-clip and transparent color only when
supported; ensure the fallback color meets WCAG 4.5:1 contrast for normal text.
| const EXAMPLE_TOKENS = [ | ||
| { name: 'WETH', address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' }, | ||
| { name: 'LINK', address: '0x514910771AF9Ca656af840dff83E8264EcF986CA' }, | ||
| { name: 'UNI', address: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984' }, | ||
| { name: 'PEPE', address: '0x6982508145454ce325ddbe47a25d4ec3d2311933' }, | ||
| { name: 'WBTC', address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599' }, | ||
| ]; |
There was a problem hiding this comment.
Inconsistent address checksumming in EXAMPLE_TOKENS.
The PEPE token address is lowercase while others are checksummed. For consistency and to avoid potential issues with case-sensitive address comparisons, use consistent checksummed addresses.
const EXAMPLE_TOKENS = [
{ name: 'WETH', address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2' },
{ name: 'LINK', address: '0x514910771AF9Ca656af840dff83E8264EcF986CA' },
{ name: 'UNI', address: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984' },
- { name: 'PEPE', address: '0x6982508145454ce325ddbe47a25d4ec3d2311933' },
+ { name: 'PEPE', address: '0x6982508145454Ce325dDbE47a25d4ec3d2311933' },
{ name: 'WBTC', address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599' },
];🤖 Prompt for AI Agents
tel-ui-web/src/app/token-aggregate/page.tsx around lines 12-18: the PEPE token
address is lowercase while the others are EIP-55 checksummed; replace the PEPE
address with its checksummed form and ensure all entries use checksummed
addresses (you can normalize/validate each address programmatically using
ethers.utils.getAddress or a similar library before committing).
| <Button variant="outline" size="sm" onClick={() => setSubmittedToken(submittedToken)} className="mt-3"> | ||
| Try Again | ||
| </Button> |
There was a problem hiding this comment.
Retry button won't trigger a refetch.
Setting setSubmittedToken(submittedToken) with the same value won't cause React to re-render or the useTokenAggregateData hook to refetch, since the state value doesn't change. Use the hook's refetch function instead.
-const { data, loading, error } = useTokenAggregateData({
+const { data, loading, error, refetch } = useTokenAggregateData({
tokenAddress: submittedToken || undefined,
dex: 'all',
chainId: 1,
});
...
-<Button variant="outline" size="sm" onClick={() => setSubmittedToken(submittedToken)} className="mt-3">
+<Button variant="outline" size="sm" onClick={() => refetch()} className="mt-3">
Try Again
</Button>Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In tel-ui-web/src/app/token-aggregate/page.tsx around lines 161-163, the "Try
Again" button calls setSubmittedToken(submittedToken) which does nothing because
the state value doesn't change; instead, import or destructure the refetch
function from useTokenAggregateData and call refetch in the button onClick (or,
if using react-query, call the queryClient refetch method) so the hook actually
re-fetches; update the button to call refetch and ensure refetch is defined
where the hook is used.
| <input | ||
| type="range" | ||
| min="5" | ||
| max="50" | ||
| step="5" | ||
| value={scaleRange} | ||
| onChange={(e) => setScaleRange(Number(e.target.value))} | ||
| className="w-20" | ||
| /> |
There was a problem hiding this comment.
Add accessibility label to range input.
The range slider lacks proper labeling for screen readers. Without an accessible label, users relying on assistive technologies cannot understand the purpose of this control.
Apply this diff to add an accessible label:
<div className="flex items-center gap-2">
<span className="text-xs text-[var(--foreground-muted)]">±{scaleRange}%</span>
<input
type="range"
min="5"
max="50"
step="5"
value={scaleRange}
onChange={(e) => setScaleRange(Number(e.target.value))}
className="w-20"
+ aria-label="Scale range percentage"
/>
</div>Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In tel-ui-web/src/components/LiquidityChart.tsx around lines 157 to 165 the
range input lacks an accessible label for screen readers; add an explicit label
by either assigning an id to the input and rendering a corresponding <label
htmlFor="..."> (can be visually hidden via CSS) or by adding an
aria-label/aria-labelledby attribute (e.g., aria-label="Chart scale" or
aria-labelledby pointing to a hidden label) so assistive technologies convey the
control's purpose; keep the existing props
(min/max/step/value/onChange/className) unchanged.
| {pools.length === itemsPerPage && ( | ||
| <Pagination | ||
| currentPage={currentPage} | ||
| totalPages={currentPage + 1} | ||
| onPageChange={setCurrentPage} | ||
| totalItems={pools.length} | ||
| itemsPerPage={itemsPerPage} | ||
| /> | ||
| )} |
There was a problem hiding this comment.
Pagination logic is inaccurate and may cause confusion.
Setting totalPages to currentPage + 1 is a workaround that doesn't reflect actual pagination state. This means users always see a "next page" button when the current page is full, even if no more data exists. The totalItems is also set to pools.length (current page items) rather than the actual total.
Consider fetching total count from the API or implementing cursor-based pagination. If server-side total isn't available, at least disable "next" when fetched items are fewer than itemsPerPage.
- {pools.length === itemsPerPage && (
+ {filteredPools.length > 0 && (
<Pagination
currentPage={currentPage}
- totalPages={currentPage + 1}
+ totalPages={pools.length === itemsPerPage ? currentPage + 1 : currentPage}
onPageChange={setCurrentPage}
- totalItems={pools.length}
+ totalItems={currentPage * itemsPerPage}
itemsPerPage={itemsPerPage}
+ showItemsInfo={false}
/>
)}Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In tel-ui-web/src/components/PoolList.tsx around lines 149–157, the Pagination
props are incorrect: totalPages is hardcoded to currentPage + 1 and totalItems
is set to pools.length (only current page items). Replace these with a real
total count if the API provides one (set totalItems = totalCount and totalPages
= Math.ceil(totalCount / itemsPerPage)); if the API does not return a total, do
not fake totalPages — instead pass a hasNext/disableNext flag computed as
(pools.length === itemsPerPage) ? true : false (or set totalPages = currentPage
+ (pools.length === itemsPerPage ? 1 : 0)), and update the Pagination component
to accept/handle totalItems optional or a hasNext prop so the Next button is
disabled when fetched items < itemsPerPage; preferably request and use
totalCount from the backend.
Summary by CodeRabbit
Release Notes
New Features
UI/UX Improvements
Chores
✏️ Tip: You can customize this high-level summary in your review settings.