Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/components/Cashout/Cashout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as _consts from './Cashout.consts'
import { interfaces as peanutInterfaces } from '@squirrel-labs/peanut-sdk'
import * as consts from '@/constants'
import { OfframpType } from '../Offramp/Offramp.consts'

export const Cashout = ({}) => {
const [step, setStep] = useState<_consts.ICashoutScreenState>(_consts.INIT_VIEW_STATE)
const [tokenValue, setTokenValue] = useState<undefined | string>(undefined)
Expand Down
18 changes: 18 additions & 0 deletions src/components/Global/Banner/GenericBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { MarqueeWrapper } from '../MarqueeWrapper'

interface GenericBannerProps {
message: string
backgroundColor?: string
icon?: string
}
Comment on lines +3 to +7
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding aria labels for accessibility

The icon prop should include accessibility attributes for screen readers.

 interface GenericBannerProps {
     message: string
     backgroundColor?: string
-    icon?: string
+    icon?: {
+        symbol: string
+        ariaLabel: string
+    }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
interface GenericBannerProps {
message: string
backgroundColor?: string
icon?: string
}
interface GenericBannerProps {
message: string
backgroundColor?: string
icon?: {
symbol: string
ariaLabel: string
}
}


export function GenericBanner({ message, backgroundColor = 'bg-purple-1', icon }: GenericBannerProps) {
return (
<MarqueeWrapper backgroundColor={backgroundColor} direction="left">
<span className="z-10 mx-4 text-sm font-semibold">
{icon && <span className="mr-2">{icon}</span>}
{message}
</span>
</MarqueeWrapper>
)
}
Comment on lines +9 to +18
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance component configurability and accessibility

The component needs several improvements:

  1. Default background color should be externalized to a theme configuration
  2. Icon needs proper accessibility attributes
  3. Missing test coverage for different prop combinations
-export function GenericBanner({ message, backgroundColor = 'bg-purple-1', icon }: GenericBannerProps) {
+export function GenericBanner({ message, backgroundColor = theme.banner.default, icon }: GenericBannerProps) {
     return (
         <MarqueeWrapper backgroundColor={backgroundColor} direction="left">
             <span className="z-10 mx-4 text-sm font-semibold">
-                {icon && <span className="mr-2">{icon}</span>}
+                {icon && (
+                    <span 
+                        className="mr-2" 
+                        role="img" 
+                        aria-label={icon.ariaLabel}
+                    >
+                        {icon.symbol}
+                    </span>
+                )}
                 {message}
             </span>
         </MarqueeWrapper>
     )
 }

Would you like me to help create test cases for this component?

Committable suggestion skipped: line range outside the PR's diff.

16 changes: 16 additions & 0 deletions src/components/Global/Banner/MaintenanceBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { GenericBanner } from './GenericBanner'
import config from '@/config/routesUnderMaintenance'

interface MaintenanceBannerProps {
pathname: string
}

export function MaintenanceBanner({ pathname }: MaintenanceBannerProps) {
const isUnderMaintenance = config.routes.some((route) => pathname.startsWith(route))

if (!isUnderMaintenance) {
return null
}

return <GenericBanner message="Under maintenance" icon="⚠️" />
Copy link
Contributor

Choose a reason for hiding this comment

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

thought: we should use our icons, but I believe that is changing from current version to pw

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good point!

}
Comment on lines +1 to +16
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error boundary for route configuration issues

The component should gracefully handle potential configuration errors.

+import { ErrorBoundary } from '@/components/ErrorBoundary'
+
 export function MaintenanceBanner({ pathname }: MaintenanceBannerProps) {
     const isUnderMaintenance = config.routes.some((route) => pathname.startsWith(route))
 
     if (!isUnderMaintenance) {
         return null
     }
 
-    return <GenericBanner message="Under maintenance" icon="⚠️" />
+    return (
+        <ErrorBoundary fallback={null}>
+            <GenericBanner message="Under maintenance" icon="⚠️" />
+        </ErrorBoundary>
+    )
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { GenericBanner } from './GenericBanner'
import config from '@/config/routesUnderMaintenance'
interface MaintenanceBannerProps {
pathname: string
}
export function MaintenanceBanner({ pathname }: MaintenanceBannerProps) {
const isUnderMaintenance = config.routes.some((route) => pathname.startsWith(route))
if (!isUnderMaintenance) {
return null
}
return <GenericBanner message="Under maintenance" icon="⚠️" />
}
import { GenericBanner } from './GenericBanner'
import config from '@/config/routesUnderMaintenance'
import { ErrorBoundary } from '@/components/ErrorBoundary'
interface MaintenanceBannerProps {
pathname: string
}
export function MaintenanceBanner({ pathname }: MaintenanceBannerProps) {
const isUnderMaintenance = config.routes.some((route) => pathname.startsWith(route))
if (!isUnderMaintenance) {
return null
}
return (
<ErrorBoundary fallback={null}>
<GenericBanner message="Under maintenance" icon="⚠️" />
</ErrorBoundary>
)
}

32 changes: 14 additions & 18 deletions src/components/Global/Banner/index.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
import { usePathname } from 'next/navigation'
import { MarqueeWrapper } from '../MarqueeWrapper'
import { GenericBanner } from './GenericBanner'
import { MaintenanceBanner } from './MaintenanceBanner'
import { MAINTAINABLE_ROUTES } from '@/config/routesUnderMaintenance'

export function Banner() {
const pathname = usePathname()
const isCashout = pathname.startsWith('/cashout')
const isRequest = pathname.startsWith('/request')
if (!pathname) return null

// Return null if not on cashout or request pages
if (!isCashout && !isRequest) return null
// First check for maintenance
const maintenanceBanner = <MaintenanceBanner pathname={pathname} />
if (maintenanceBanner) return maintenanceBanner

// Show maintenance message for cashout
if (isCashout) {
return (
<MarqueeWrapper backgroundColor="bg-purple-1" direction="left">
<span className="z-10 mx-4 text-sm font-semibold">⚠️ Under maintenance</span>
</MarqueeWrapper>
)
// Show beta message for all request paths (create and pay) unless under maintenance
if (pathname.startsWith(MAINTAINABLE_ROUTES.REQUEST)) {
return <GenericBanner message="Beta feature - share your thoughts!" backgroundColor="bg-purple-1" />
}

// Show beta message for request
return (
<MarqueeWrapper backgroundColor="bg-purple-1" direction="left">
<span className="z-10 mx-4 text-sm font-semibold">Beta feature - share your thoughts!</span>
</MarqueeWrapper>
)
return null
}

export { GenericBanner } from './GenericBanner'
export { MaintenanceBanner } from './MaintenanceBanner'
19 changes: 19 additions & 0 deletions src/config/routesUnderMaintenance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
interface MaintenanceConfig {
routes: string[]
}

export const MAINTAINABLE_ROUTES = {
CASHOUT: '/cashout',
REQUEST: '/request',
SEND: '/send',
CLAIM: '/claim',
} as const

// Static configuration - edit this file to change maintenance state
const config: MaintenanceConfig = {
routes: [
MAINTAINABLE_ROUTES.CASHOUT, // Routes under maintenance
],
}

export default config
Loading