diff --git a/components/brave_rewards/resources/rewards_page/components/explore/card_item_view.tsx b/components/brave_rewards/resources/rewards_page/components/explore/card_item_view.tsx
new file mode 100644
index 000000000000..41785dcae45b
--- /dev/null
+++ b/components/brave_rewards/resources/rewards_page/components/explore/card_item_view.tsx
@@ -0,0 +1,46 @@
+/* Copyright (c) 2024 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+import * as React from 'react'
+
+import { UICardItem } from '../../lib/app_state'
+import { NewTabLink } from '../../../shared/components/new_tab_link'
+
+function sanitizeURL(url: string) {
+ try {
+ return new URL(url).protocol === 'https:' ? url : ''
+ } catch {
+ return ''
+ }
+}
+
+function thumbnailURL(url: string) {
+ url = sanitizeURL(url)
+ try {
+ if (/(^|\.)brave\.com$/i.test(new URL(url).hostname)) {
+ return `chrome://rewards-image/${url}`
+ }
+ return ''
+ } catch {
+ return ''
+ }
+}
+
+interface Props {
+ item: UICardItem
+}
+
+export function CardItemView(props: Props) {
+ const { item } = props
+ return (
+
+
+
+ {item.title}
+ {item.description}
+
+
+ )
+}
diff --git a/components/brave_rewards/resources/rewards_page/components/explore/community_card.tsx b/components/brave_rewards/resources/rewards_page/components/explore/community_card.tsx
index bd342e8fe64f..1a5944536ec0 100644
--- a/components/brave_rewards/resources/rewards_page/components/explore/community_card.tsx
+++ b/components/brave_rewards/resources/rewards_page/components/explore/community_card.tsx
@@ -6,7 +6,7 @@
import * as React from 'react'
import { useLocaleContext } from '../../lib/locale_strings'
import { useAppState } from '../../lib/app_model_context'
-import { UICardItem } from '../../lib/app_state'
+import { CardItemView } from './card_item_view'
import { NewTabLink } from '../../../shared/components/new_tab_link'
import * as urls from '../../../shared/lib/rewards_urls'
@@ -24,28 +24,16 @@ export function CommunityCard() {
return null
}
- function renderItem(item: UICardItem) {
- return (
-
-
-
- {item.title}
- {item.description}
-
-
- )
- }
-
return (
{getString('communityTitle')}
- {getString('viewAllLink')}
+ {getString('viewAllLink')}
- {card.items.map(renderItem)}
+ {card.items.map((item, i) => )}
)
diff --git a/components/brave_rewards/resources/rewards_page/components/explore/explore_view.style.ts b/components/brave_rewards/resources/rewards_page/components/explore/explore_view.style.ts
index 595725c2a338..34a3be1eafab 100644
--- a/components/brave_rewards/resources/rewards_page/components/explore/explore_view.style.ts
+++ b/components/brave_rewards/resources/rewards_page/components/explore/explore_view.style.ts
@@ -13,6 +13,22 @@ export const style = scoped.css`
gap: 8px;
}
+ .loading {
+ --leo-progressring-size: 32px;
+
+ padding-top: 33%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ opacity: 1;
+
+ transition: opacity 500ms 1.5s ease-in-out;
+
+ @starting-style {
+ opacity: 0;
+ }
+ }
+
.columns {
display: flex;
gap: 24px;
diff --git a/components/brave_rewards/resources/rewards_page/components/explore/explore_view.tsx b/components/brave_rewards/resources/rewards_page/components/explore/explore_view.tsx
index 47e70b0e6765..7c6ca6f187bb 100644
--- a/components/brave_rewards/resources/rewards_page/components/explore/explore_view.tsx
+++ b/components/brave_rewards/resources/rewards_page/components/explore/explore_view.tsx
@@ -4,7 +4,9 @@
* You can obtain one at https://mozilla.org/MPL/2.0/. */
import * as React from 'react'
+import ProgressRing from '@brave/leo/react/progressRing'
+import { useAppState } from '../../lib/app_model_context'
import { useBreakpoint } from '../../lib/breakpoint'
import { CommunityCard } from './community_card'
import { MerchStoreCard } from './merch_store_card'
@@ -13,6 +15,17 @@ import { style } from './explore_view.style'
export function ExploreView() {
const viewType = useBreakpoint()
+ const [cards] = useAppState((state) => [state.cards])
+
+ if (!cards) {
+ return (
+
+ )
+ }
if (viewType === 'double') {
return (
diff --git a/components/brave_rewards/resources/rewards_page/components/explore/merch_store_card.tsx b/components/brave_rewards/resources/rewards_page/components/explore/merch_store_card.tsx
index a9b1ade1f72f..6872a6aefc4d 100644
--- a/components/brave_rewards/resources/rewards_page/components/explore/merch_store_card.tsx
+++ b/components/brave_rewards/resources/rewards_page/components/explore/merch_store_card.tsx
@@ -8,8 +8,8 @@ import Icon from '@brave/leo/react/icon'
import { useLocaleContext } from '../../lib/locale_strings'
import { useAppState } from '../../lib/app_model_context'
-import { UICardItem } from '../../lib/app_state'
import { NewTabLink } from '../../../shared/components/new_tab_link'
+import { CardItemView } from './card_item_view'
import * as urls from '../../../shared/lib/rewards_urls'
@@ -26,18 +26,6 @@ export function MerchStoreCard() {
return null
}
- function renderItem(item: UICardItem) {
- return (
-
-
-
- {item.title}
- {item.description}
-
-
- )
- }
-
return (
@@ -48,7 +36,7 @@ export function MerchStoreCard() {
- {card.items.map(renderItem)}
+ {card.items.map((item, i) => )}
)