-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(ui): add info card #16931
feat(ui): add info card #16931
Conversation
WalkthroughThis pull request introduces significant changes to the grants and components system, primarily focusing on replacing the Changes
Sequence DiagramsequenceDiagram
participant User
participant SearchResults
participant InfoCardGrid
participant GrantService
User->>SearchResults: Perform grant search
SearchResults->>GrantService: Fetch grants
GrantService-->>SearchResults: Return grant data
SearchResults->>InfoCardGrid: Render grants
InfoCardGrid-->>SearchResults: Display grid/list view
Possibly Related PRs
Suggested Reviewers
Tip CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
Datadog ReportAll test runs ✅ 38 Total Test Services: 0 Failed, 35 Passed Test ServicesThis report shows up to 10 services
🔻 Code Coverage Decreases vs Default Branch (8)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (7)
apps/web/screens/Grants/utils.ts (2)
41-43
: Refactor repeated date handling patternThe date formatting logic is repeated across multiple case blocks with slight variations. Additionally, the potential undefined return from
formatDate
isn't explicitly handled.Consider extracting the common pattern:
const formatGrantDate = ( date: string | null | undefined, locale: Locale, format?: string ): string | undefined => { if (!date) return undefined; return formatDate(new Date(date), locale, format); }Then use it in the case blocks:
case GrantStatus.Closed: { - const date = grant.dateTo - ? formatDate(new Date(grant.dateTo), locale) - : undefined + const date = formatGrantDate(grant.dateTo, locale) // ... rest of the code }Also applies to: 60-62, 74-76, 102-104
Line range hint
134-148
: Enhance type safety in generateStatusTagWhile the function is well-implemented, the type safety could be improved.
Consider these type improvements:
+type StatusVariant = 'mint' | 'rose'; +interface StatusTag { + label: string; + variant: StatusVariant; +} export const generateStatusTag = ( status: Status['applicationStatus'], formatMessage: IntlShape['formatMessage'], -) => +): StatusTag | undefined => status !== 'unknown' ? { label: status === 'open' ? formatMessage(m.search.applicationOpen) : formatMessage(m.search.applicationClosed), - variant: status === 'open' ? ('mint' as const) : ('rose' as const), + variant: status === 'open' ? 'mint' : 'rose', } : undefinedapps/web/components/InfoCardGrid/DetailedInfoCard.tsx (2)
24-28
: Enforce maximum detail lines at type levelInstead of relying on a comment to indicate the maximum number of detail lines, consider enforcing this constraint at the type level using TypeScript's tuple types.
- //max 5 lines - detailLines?: Array<{ + detailLines?: [ + { icon: IconMapIcon; text: string }, + { icon: IconMapIcon; text: string }?, + { icon: IconMapIcon; text: string }?, + { icon: IconMapIcon; text: string }?, + { icon: IconMapIcon; text: string }? + ] | { icon: IconMapIcon text: string - }> + }[]
Line range hint
43-170
: Consider memoizing render functions for performance optimizationThe component contains several render functions that could benefit from memoization to prevent unnecessary re-renders, especially for the logo and details sections which depend on props that may not change frequently.
+ const MemoizedLogo = React.memo(({ logo, logoAlt }: { logo?: string; logoAlt?: string }) => { + if (!logo) return null; + return ( + <Box style={{ flex: '0 0 40px' }}> + <img height={40} src={logo} alt={logoAlt} /> + </Box> + ); + }); + const MemoizedDetailLine = React.memo(({ icon, text }: { icon: IconMapIcon; text: string }) => ( + <Box display="flex" flexDirection="row" alignItems="center"> + <Icon icon={icon} size="medium" type="outline" color="blue400" useStroke /> + <Box marginLeft={2}> + <Text variant="medium">{text}</Text> + </Box> + </Box> + ));apps/web/components/InfoCardGrid/InfoCard.tsx (2)
31-40
: Optimize window size effectThe effect can be simplified and made more performant.
- useEffect(() => { - if (width < theme.breakpoints.md) { - return setIsMobile(true) - } - setIsMobile(false) - }, [width]) + useEffect(() => { + setIsMobile(width < theme.breakpoints.md) + }, [width])
44-71
: Consider extracting style logicThe className determination logic could be extracted to improve readability.
+ const getCardStyle = (size: 'large' | 'medium' | 'small') => { + switch(size) { + case 'large': return styles.infoCardWide + case 'small': return styles.infoCardSmall + default: return styles.infoCard + } + } return ( <FocusableBox - className={ - size === 'large' - ? styles.infoCardWide - : size === 'small' - ? styles.infoCardSmall - : styles.infoCard - } + className={getCardStyle(size)}apps/web/screens/Grants/SearchResults/SearchResultsContent.tsx (1)
112-113
: Address TODO commentThere's an unresolved TODO comment regarding text readiness.
Would you like me to help implement the deadline status text logic or create a GitHub issue to track this task?
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
.github/CODEOWNERS
(1 hunks)apps/web/components/InfoCardGrid/DetailedInfoCard.tsx
(4 hunks)apps/web/components/InfoCardGrid/InfoCard.tsx
(1 hunks)apps/web/components/InfoCardGrid/InfoCardGrid.tsx
(1 hunks)apps/web/components/InfoCardGrid/SimpleInfoCard.tsx
(1 hunks)apps/web/screens/Grants/Grant/Grant.tsx
(0 hunks)apps/web/screens/Grants/SearchResults/SearchResultsContent.tsx
(2 hunks)apps/web/screens/Grants/utils.ts
(4 hunks)
💤 Files with no reviewable changes (1)
- apps/web/screens/Grants/Grant/Grant.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- .github/CODEOWNERS
- apps/web/components/InfoCardGrid/InfoCardGrid.tsx
🧰 Additional context used
📓 Path-based instructions (5)
apps/web/components/InfoCardGrid/SimpleInfoCard.tsx (1)
Pattern apps/**/*
: "Confirm that the code adheres to the following:
- NextJS best practices, including file structure, API routes, and static generation methods.
- Efficient state management and server-side rendering techniques.
- Optimal use of TypeScript for component and utility type safety."
apps/web/screens/Grants/SearchResults/SearchResultsContent.tsx (1)
Pattern apps/**/*
: "Confirm that the code adheres to the following:
- NextJS best practices, including file structure, API routes, and static generation methods.
- Efficient state management and server-side rendering techniques.
- Optimal use of TypeScript for component and utility type safety."
apps/web/components/InfoCardGrid/InfoCard.tsx (1)
Pattern apps/**/*
: "Confirm that the code adheres to the following:
- NextJS best practices, including file structure, API routes, and static generation methods.
- Efficient state management and server-side rendering techniques.
- Optimal use of TypeScript for component and utility type safety."
apps/web/components/InfoCardGrid/DetailedInfoCard.tsx (1)
Pattern apps/**/*
: "Confirm that the code adheres to the following:
- NextJS best practices, including file structure, API routes, and static generation methods.
- Efficient state management and server-side rendering techniques.
- Optimal use of TypeScript for component and utility type safety."
apps/web/screens/Grants/utils.ts (1)
Pattern apps/**/*
: "Confirm that the code adheres to the following:
- NextJS best practices, including file structure, API routes, and static generation methods.
- Efficient state management and server-side rendering techniques.
- Optimal use of TypeScript for component and utility type safety."
🔇 Additional comments (8)
apps/web/screens/Grants/utils.ts (1)
Line range hint 11-16
: Well-designed type definitions
The Status interface is well-structured with proper type constraints and optional properties. The use of literal types for applicationStatus provides excellent type safety.
apps/web/components/InfoCardGrid/DetailedInfoCard.tsx (3)
32-42
: LGTM! Clean component declaration with proper typing
The component declaration follows React best practices with proper prop typing and default values.
172-180
: LGTM! Clean and structured render method
The main render method follows React best practices with proper component composition and layout structure.
Line range hint 1-180
: Verify component organization follows NextJS conventions
Let's verify that the component follows NextJS conventions for component organization and is properly exported.
✅ Verification successful
Let me gather more information about the component organization to ensure a thorough verification.
Component follows NextJS conventions but lacks barrel exports
The component follows NextJS conventions by being:
- Located in the appropriate components directory structure
- Properly organized with related components in a feature-specific folder (InfoCardGrid)
- Using TypeScript and following React functional component patterns
However, there's a minor improvement opportunity:
- Missing index.ts barrel file in the InfoCardGrid directory for cleaner exports
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify component organization and exports
# Check if the component is properly exported in the barrel file
rg -l "export.*DetailedInfoCard" apps/web/components/
# Check component organization
fd -t d "components" apps/web/ -x echo "Found components directory: {}"
Length of output: 726
Script:
#!/bin/bash
# Check the component's directory structure and related files
fd . apps/web/components/InfoCardGrid/ -x echo "File in InfoCardGrid: {}"
# Check if this component is being used across the application
rg "DetailedInfoCard" apps/web/ -l
# Check if there are any index files that might be exporting this component
rg "DetailedInfoCard" apps/web/components/InfoCardGrid/index.ts
Length of output: 717
apps/web/components/InfoCardGrid/SimpleInfoCard.tsx (2)
19-36
: Improve header accessibility
The header section's accessibility can be enhanced by adding an appropriate aria-level attribute.
38-69
: 🛠️ Refactor suggestion
Optimize content rendering logic
The content rendering logic can be simplified by extracting common elements and reducing duplication.
- const renderContent = () => {
- if (size === 'large') {
- return (
- <GridContainer>
- <GridRow direction="row">
- <GridColumn span="12/12">
- <Text variant="h3" color="blue400">
- {title}
- </Text>
- {description && (
- <Box flexGrow={1} marginTop={1}>
- <Text>{description}</Text>
- </Box>
- )}
- </GridColumn>
- </GridRow>
- </GridContainer>
- )
- }
+ const Content = () => (
+ <>
+ <Text variant="h3" color="blue400">
+ {title}
+ </Text>
+ {description && (
+ <Box marginTop={1} flexGrow={size === 'large' ? 1 : undefined}>
+ <Text>{description}</Text>
+ </Box>
+ )}
+ </>
+ )
+
+ const renderContent = () => (
+ size === 'large' ? (
+ <GridContainer>
+ <GridRow>
+ <GridColumn span="12/12">
+ <Content />
+ </GridColumn>
+ </GridRow>
+ </GridContainer>
+ ) : <Content />
+ )
Likely invalid or redundant comment.
apps/web/components/InfoCardGrid/InfoCard.tsx (1)
1-2
: Optimize SSR compatibility
The useWindowSize
hook might cause hydration mismatches during SSR.
apps/web/screens/Grants/SearchResults/SearchResultsContent.tsx (1)
62-128
: 🛠️ Refactor suggestion
Optimize grant data transformation
The grant mapping logic is complex and could benefit from optimization.
- Extract the mapping logic to a separate utility function
- Memoize the transformed data
- Add proper type safety
+ const transformGrant = useCallback((grant: Grant) => {
+ if (!grant?.applicationId) return null;
+
+ const status = parseStatus(grant, formatMessage, locale);
+
+ return {
+ id: grant.id,
+ eyebrow: grant.fund?.title ?? grant.name ?? '',
+ // ... rest of the transformation
+ };
+ }, [formatMessage, locale]);
+
+ const transformedGrants = useMemo(() =>
+ grants?.map(transformGrant).filter(isDefined) ?? [],
+ [grants, transformGrant]
+ );
return (
<InfoCardGrid
columns={!isGridLayout ? 1 : 2}
variant="detailed"
- cards={grants?.map((grant) => {
- // ... current transformation logic
- }).filter(isDefined) ?? []}
+ cards={transformedGrants}
/>
);
Likely invalid or redundant comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🥳
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🔭 Outside diff range comments (1)
apps/web/screens/Grants/SearchResults/SearchResults.tsx (1)
Line range hint
161-169
: Enhance error handling strategyConsider implementing a more robust error handling approach:
- Add error state management
- Display user-friendly error messages
- Consider implementing error boundaries
+ const [error, setError] = useState<Error | null>(null); if (res.error) { setGrants([]) - console.error('Error fetching grants', res.error) + setError(res.error) + // Consider using a toast or error message component }
🧹 Nitpick comments (9)
apps/web/screens/Grants/SearchResults/SearchResults.tsx (1)
Line range hint
100-106
: Consider adding page number validationWhile setting a default page to 1 is good, consider adding validation to ensure the parsed page number is positive and within valid bounds.
- page: page ? Number.parseInt(page) : 1, + page: page ? Math.max(1, Number.parseInt(page)) || 1 : 1,libs/island-ui/core/src/lib/InfoCardGrid/DetailedInfoCard.tsx (2)
21-22
: EnsurelogoAlt
prop is provided whenlogo
is used for accessibilityTo improve accessibility, the
logoAlt
prop should be required whenever alogo
is provided. This ensures that screen readers have appropriate alternative text for images.Consider updating the
DetailedProps
type to reflect this requirement:export type DetailedProps = BaseProps & { logo?: string - logoAlt?: string + logoAlt?: string // Consider making this required when `logo` is provided subEyebrow?: string // max 5 lines detailLines?: Array<{ icon: IconMapIcon text: string }> tags?: Array<ActionCardProps['tag']> }You might enforce this at runtime or explore conditional types in TypeScript to make
logoAlt
required whenlogo
is present.
87-106
: SimplifyrenderTags
by removing redundant null checksIn the
renderTags
function, the null check within themap
function is redundant since you're already filtering out undefined values using.filter(isDefined)
. Simplifying the code enhances readability.Apply this diff to streamline the tag rendering:
const renderTags = () => { if (!tags?.length) { return null } return ( <Inline space={1}> - {tags - .map((tag, index) => { - if (!tag) { - return null - } - return ( - <Tag key={`${tag.label}-${index}`} disabled variant={tag.variant}> - {tag.label} - </Tag> - ) - }) - .filter(isDefined)} + {tags + .filter(isDefined) + .map((tag, index) => ( + <Tag key={`${tag.label}-${index}`} disabled variant={tag.variant}> + {tag.label} + </Tag> + ))} </Inline> ) }libs/island-ui/core/src/lib/InfoCardGrid/InfoCardGrid.tsx (1)
18-26
: OptimizeisMobile
state managementThe
isMobile
state is being updated on every window resize, which could lead to performance issues. Consider using a memoized value or updating the state only when the breakpoint is crossed.You can modify the
useEffect
hook:useEffect(() => { - if (width < theme.breakpoints.md) { - return setIsMobile(true) - } - setIsMobile(false) + const mobile = width < theme.breakpoints.md + if (mobile !== isMobile) { + setIsMobile(mobile) + } }, [width])libs/island-ui/core/src/lib/InfoCardGrid/SimpleInfoCard.tsx (1)
14-16
: Returnnull
instead ofundefined
when rendering nothingIn the
renderHeader
function, returningnull
explicitly is preferred overundefined
for clarity and to align with React best practices.Apply this diff:
const renderHeader = () => { if (!eyebrow) { - return + return null } // ... }libs/island-ui/core/src/lib/InfoCardGrid/InfoCard.tsx (2)
23-29
: Consider making variant property required for better type safetyThe variant property is optional for the simple type but required for detailed type. This asymmetry could lead to ambiguous type checking.
export type InfoCardProps = | (BaseProps & { - variant?: 'simple' + variant: 'simple' }) | (DetailedProps & { variant: 'detailed' })
44-72
: Add type safety for background color propThe background color prop uses string literals which could be made type-safe.
+ type BackgroundColor = 'yellow100' | 'white'; <FocusableBox ... - background={size === 'small' ? 'yellow100' : 'white'} + background={size === 'small' ? 'yellow100' as BackgroundColor : 'white' as BackgroundColor} ... >apps/web/screens/Grants/SearchResults/SearchResultsContent.tsx (2)
30-53
: Consider persisting layout preferenceThe layout toggle state resets on page refresh. Consider using localStorage or similar mechanism to persist user's layout preference.
- const [isGridLayout, setIsGridLayout] = useState(true) + const [isGridLayout, setIsGridLayout] = useState(() => { + if (typeof window === 'undefined') return true; + return localStorage.getItem('grantsLayoutPreference') !== 'list'; + }); + + const toggleLayout = useCallback(() => { + const newValue = !isGridLayout; + setIsGridLayout(newValue); + localStorage.setItem('grantsLayoutPreference', newValue ? 'grid' : 'list'); + }, [isGridLayout]);
Line range hint
128-160
: Add error boundary for robust error handlingConsider wrapping the component with an error boundary to gracefully handle runtime errors.
class GrantsErrorBoundary extends React.Component { static getDerivedStateFromError(error) { return { hasError: true }; } render() { if (this.state.hasError) { return <Box> <Text variant="h3">{formatMessage(m.error.somethingWentWrong)}</Text> </Box>; } return this.props.children; } }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (17)
.github/CODEOWNERS
(0 hunks)apps/web/components/real.ts
(0 hunks)apps/web/screens/Grants/Grant/GrantSidebar.tsx
(0 hunks)apps/web/screens/Grants/SearchResults/SearchResults.tsx
(13 hunks)apps/web/screens/Grants/SearchResults/SearchResultsContent.tsx
(2 hunks)apps/web/screens/Grants/messages.ts
(1 hunks)apps/web/screens/queries/Grants.ts
(1 hunks)libs/cms/src/lib/cms.elasticsearch.service.ts
(0 hunks)libs/cms/src/lib/models/grant.model.ts
(0 hunks)libs/cms/src/lib/search/importers/grants.service.ts
(1 hunks)libs/island-ui/core/src/index.ts
(1 hunks)libs/island-ui/core/src/lib/InfoCardGrid/DetailedInfoCard.tsx
(4 hunks)libs/island-ui/core/src/lib/InfoCardGrid/InfoCard.css.ts
(1 hunks)libs/island-ui/core/src/lib/InfoCardGrid/InfoCard.tsx
(1 hunks)libs/island-ui/core/src/lib/InfoCardGrid/InfoCardGrid.tsx
(1 hunks)libs/island-ui/core/src/lib/InfoCardGrid/SimpleInfoCard.tsx
(1 hunks)libs/island-ui/core/src/lib/InfoCardGrid/index.ts
(1 hunks)
💤 Files with no reviewable changes (5)
- apps/web/components/real.ts
- .github/CODEOWNERS
- apps/web/screens/Grants/Grant/GrantSidebar.tsx
- libs/cms/src/lib/cms.elasticsearch.service.ts
- libs/cms/src/lib/models/grant.model.ts
✅ Files skipped from review due to trivial changes (1)
- libs/island-ui/core/src/lib/InfoCardGrid/index.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- apps/web/screens/queries/Grants.ts
- apps/web/screens/Grants/messages.ts
- libs/cms/src/lib/search/importers/grants.service.ts
🧰 Additional context used
📓 Path-based instructions (8)
libs/island-ui/core/src/index.ts (1)
Pattern libs/**/*
: "Confirm that the code adheres to the following:
- Reusability of components and hooks across different NextJS apps.
- TypeScript usage for defining props and exporting types.
- Effective tree-shaking and bundling practices."
libs/island-ui/core/src/lib/InfoCardGrid/SimpleInfoCard.tsx (1)
Pattern libs/**/*
: "Confirm that the code adheres to the following:
- Reusability of components and hooks across different NextJS apps.
- TypeScript usage for defining props and exporting types.
- Effective tree-shaking and bundling practices."
apps/web/screens/Grants/SearchResults/SearchResultsContent.tsx (1)
Pattern apps/**/*
: "Confirm that the code adheres to the following:
- NextJS best practices, including file structure, API routes, and static generation methods.
- Efficient state management and server-side rendering techniques.
- Optimal use of TypeScript for component and utility type safety."
libs/island-ui/core/src/lib/InfoCardGrid/InfoCard.css.ts (1)
Pattern libs/**/*
: "Confirm that the code adheres to the following:
- Reusability of components and hooks across different NextJS apps.
- TypeScript usage for defining props and exporting types.
- Effective tree-shaking and bundling practices."
libs/island-ui/core/src/lib/InfoCardGrid/InfoCard.tsx (1)
Pattern libs/**/*
: "Confirm that the code adheres to the following:
- Reusability of components and hooks across different NextJS apps.
- TypeScript usage for defining props and exporting types.
- Effective tree-shaking and bundling practices."
libs/island-ui/core/src/lib/InfoCardGrid/DetailedInfoCard.tsx (1)
Pattern libs/**/*
: "Confirm that the code adheres to the following:
- Reusability of components and hooks across different NextJS apps.
- TypeScript usage for defining props and exporting types.
- Effective tree-shaking and bundling practices."
libs/island-ui/core/src/lib/InfoCardGrid/InfoCardGrid.tsx (1)
Pattern libs/**/*
: "Confirm that the code adheres to the following:
- Reusability of components and hooks across different NextJS apps.
- TypeScript usage for defining props and exporting types.
- Effective tree-shaking and bundling practices."
apps/web/screens/Grants/SearchResults/SearchResults.tsx (1)
Pattern apps/**/*
: "Confirm that the code adheres to the following:
- NextJS best practices, including file structure, API routes, and static generation methods.
- Efficient state management and server-side rendering techniques.
- Optimal use of TypeScript for component and utility type safety."
🔇 Additional comments (12)
apps/web/screens/Grants/SearchResults/SearchResults.tsx (5)
59-60
: LGTM: Good use of constant for pagination size
The PAGE_SIZE constant improves maintainability and consistency across the component.
73-78
: LGTM: Improved state management with TypeScript
Good separation of concerns between grants and total hits state. The use of optional chaining with fallback values provides good type safety.
109-114
: LGTM: Well-implemented pagination logic
Good use of useMemo for performance optimization and proper handling of edge cases in totalPages calculation.
309-330
: LGTM: Well-implemented pagination UI
Good implementation of the Pagination component with:
- Proper conditional rendering
- Type-safe event handling
- Consistent styling with variant="purple"
376-378
: LGTM: Well-typed props interface
Good use of TypeScript for props definition with proper optional types.
libs/island-ui/core/src/lib/InfoCardGrid/DetailedInfoCard.tsx (1)
72-76
: Verify that the updated icon size aligns with design guidelines
The icon size in renderDetails
has been changed from "small"
to "medium"
. Please ensure that this change conforms to the design specifications and maintains the intended UI consistency.
libs/island-ui/core/src/lib/InfoCardGrid/InfoCard.css.ts (1)
3-20
: Styles are well-defined and follow best practices
The CSS styles for the info cards are appropriately defined using vanilla-extract
. The use of maxWidth
and minHeight
provides consistent sizing across different components.
libs/island-ui/core/src/lib/InfoCardGrid/InfoCardGrid.tsx (1)
1-50
: Component adheres to coding guidelines
The InfoCardGrid
component is well-structured, using TypeScript effectively to define props and types. It promotes reusability across NextJS applications and considers responsive design principles.
libs/island-ui/core/src/lib/InfoCardGrid/SimpleInfoCard.tsx (1)
1-71
: Component is well-designed and meets the guidelines
The SimpleInfoCard
component is implemented properly, with clear separation of concerns and effective use of TypeScript for prop definitions. It enhances reusability and maintainability.
libs/island-ui/core/src/lib/InfoCardGrid/InfoCard.tsx (1)
11-21
: Well-structured type definitions with proper TypeScript usage
The BaseProps
interface is well-defined with clear, required fields and proper TypeScript types.
libs/island-ui/core/src/index.ts (1)
63-63
: LGTM: Export properly placed in Cards section
The InfoCardGrid export is correctly placed in the module exports.
apps/web/screens/Grants/SearchResults/SearchResultsContent.tsx (1)
57-126
: Optimize grant data transformation
The grant mapping logic could benefit from the previously suggested optimizations regarding memoization and utility extraction.
What
New
<InfoCard />
component for UIScreenshots / Gifs
Attach Screenshots / Gifs to help reviewers understand the scope of the pull request
Checklist:
Summary by CodeRabbit
Release Notes
New Features
InfoCardGrid
component for displaying information cards.SearchResultsContent
component.SearchResults
component with a newPagination
feature.Bug Fixes
Documentation
Grants
section.Refactor
mapGrant
function for better clarity and maintainability.PlazaCard
component withInfoCardGrid
in relevant areas.Style
InfoCard
components to ensure consistent layout and responsiveness.