diff --git a/icons/share.svg b/icons/share.svg
new file mode 100644
index 0000000000..f1124e47d0
--- /dev/null
+++ b/icons/share.svg
@@ -0,0 +1,3 @@
+
diff --git a/mocks/apps/ratings.ts b/mocks/apps/ratings.ts
index 3eeca5b693..3a0322850d 100644
--- a/mocks/apps/ratings.ts
+++ b/mocks/apps/ratings.ts
@@ -6,6 +6,7 @@ export const ratings = {
fields: {
appId: apps[0].id,
rating: 4.3,
+ count: 15,
},
},
],
diff --git a/public/icons/name.d.ts b/public/icons/name.d.ts
index eb787ac206..62b9e9732f 100644
--- a/public/icons/name.d.ts
+++ b/public/icons/name.d.ts
@@ -116,6 +116,7 @@
| "score/score-not-ok"
| "score/score-ok"
| "search"
+ | "share"
| "social/canny"
| "social/coingecko"
| "social/coinmarketcap"
diff --git a/types/client/marketplace.ts b/types/client/marketplace.ts
index 800e7ecb6d..a6785311c7 100644
--- a/types/client/marketplace.ts
+++ b/types/client/marketplace.ts
@@ -29,6 +29,7 @@ export type MarketplaceAppOverview = MarketplaceAppPreview & MarketplaceAppSocia
export type AppRating = {
recordId: string;
value: number | undefined;
+ count?: number;
}
export type MarketplaceAppWithSecurityReport = MarketplaceAppOverview & {
diff --git a/ui/marketplace/FavoriteIcon.tsx b/ui/marketplace/FavoriteIcon.tsx
index e2b589b98d..a424f1a6e1 100644
--- a/ui/marketplace/FavoriteIcon.tsx
+++ b/ui/marketplace/FavoriteIcon.tsx
@@ -9,13 +9,13 @@ type Props = {
}
const FavoriteIcon = ({ isFavorite, color }: Props) => {
- const heartFilledColor = useColorModeValue('blue.700', 'gray.400');
- const defaultColor = isFavorite ? heartFilledColor : 'gray.400';
+ const heartFilledColor = useColorModeValue('blue.600', 'blue.300');
+ const defaultColor = isFavorite ? heartFilledColor : (color || 'gray.400');
return (
);
diff --git a/ui/marketplace/MarketplaceAppCard.tsx b/ui/marketplace/MarketplaceAppCard.tsx
index 834255eff6..050e17c5e3 100644
--- a/ui/marketplace/MarketplaceAppCard.tsx
+++ b/ui/marketplace/MarketplaceAppCard.tsx
@@ -5,6 +5,8 @@ import React, { useCallback } from 'react';
import type { MarketplaceAppWithSecurityReport, ContractListTypes, AppRating } from 'types/client/marketplace';
import useIsMobile from 'lib/hooks/useIsMobile';
+import isBrowser from 'lib/isBrowser';
+import CopyToClipboard from 'ui/shared/CopyToClipboard';
import AppSecurityReport from './AppSecurityReport';
import FavoriteIcon from './FavoriteIcon';
@@ -168,7 +170,7 @@ const MarketplaceAppCard = ({
>
More info
-
+
}
+ ml={ 2 }
+ />
+
diff --git a/ui/marketplace/MarketplaceAppModal.tsx b/ui/marketplace/MarketplaceAppModal.tsx
index 0eb9906480..430766b1ac 100644
--- a/ui/marketplace/MarketplaceAppModal.tsx
+++ b/ui/marketplace/MarketplaceAppModal.tsx
@@ -10,7 +10,9 @@ import { ContractListTypes } from 'types/client/marketplace';
import config from 'configs/app';
import useIsMobile from 'lib/hooks/useIsMobile';
import { nbsp } from 'lib/html-entities';
+import isBrowser from 'lib/isBrowser';
import * as mixpanel from 'lib/mixpanel/index';
+import CopyToClipboard from 'ui/shared/CopyToClipboard';
import type { IconName } from 'ui/shared/IconSvg';
import IconSvg from 'ui/shared/IconSvg';
@@ -113,6 +115,8 @@ const MarketplaceAppModal = ({
} catch (err) {}
}
+ const iconColor = useColorModeValue('blue.600', 'gray.400');
+
return (
}
+ icon={ }
+ />
+
+
diff --git a/ui/marketplace/MarketplaceAppTopBar.tsx b/ui/marketplace/MarketplaceAppTopBar.tsx
index 5cfc939208..8f9c233620 100644
--- a/ui/marketplace/MarketplaceAppTopBar.tsx
+++ b/ui/marketplace/MarketplaceAppTopBar.tsx
@@ -53,7 +53,7 @@ const MarketplaceAppTopBar = ({ appId, data, isLoading, securityReport }: Props)
return (
<>
-
+
{ !isMobile && }
diff --git a/ui/marketplace/MarketplaceList.tsx b/ui/marketplace/MarketplaceList.tsx
index 19cf53722b..0d4706c5c3 100644
--- a/ui/marketplace/MarketplaceList.tsx
+++ b/ui/marketplace/MarketplaceList.tsx
@@ -45,10 +45,7 @@ const MarketplaceList = ({
return apps.length > 0 ? (
<>
{ rating?.value }
+ { rating?.count && ({ rating?.count }) }
>
) }
@@ -58,6 +59,7 @@ const Rating = ({
void;
@@ -24,7 +25,7 @@ const getTooltipText = (canRate: boolean | undefined) => {
};
const TriggerButton = (
- { rating, fullView, isActive, onClick, canRate }: Props,
+ { rating, count, fullView, isActive, onClick, canRate }: Props,
ref: React.ForwardedRef,
) => {
const textColor = useColorModeValue('blackAlpha.800', 'whiteAlpha.800');
@@ -75,8 +76,9 @@ const TriggerButton = (
/>
) }
{ (rating && !fullView) ? (
-
+
{ rating }
+ ({ count })
) : (
'Rate it!'
diff --git a/ui/marketplace/Rating/useRatings.tsx b/ui/marketplace/Rating/useRatings.tsx
index 7c4ff1aa9f..663b1b3667 100644
--- a/ui/marketplace/Rating/useRatings.tsx
+++ b/ui/marketplace/Rating/useRatings.tsx
@@ -28,11 +28,12 @@ export type RateFunction = (
function formatRatings(data: Airtable.Records) {
return data.reduce((acc: Record, record) => {
- const fields = record.fields as { appId: string | Array; rating: number | undefined };
+ const fields = record.fields as { appId: string | Array; rating: number | undefined; count?: number };
const appId = Array.isArray(fields.appId) ? fields.appId[0] : fields.appId;
acc[appId] = {
recordId: record.id,
value: fields.rating,
+ count: fields.count,
};
return acc;
}, {});
@@ -63,7 +64,7 @@ export default function useRatings() {
return;
}
try {
- const data = await airtable('apps_ratings').select({ fields: [ 'appId', 'rating' ] }).all();
+ const data = await airtable('apps_ratings').select({ fields: [ 'appId', 'rating', 'count' ] }).all();
const ratings = formatRatings(data);
setRatings(ratings);
} catch (error) {
diff --git a/ui/marketplace/__screenshots__/MarketplaceAppModal.pw.tsx_dark-color-mode_base-view-dark-mode-1.png b/ui/marketplace/__screenshots__/MarketplaceAppModal.pw.tsx_dark-color-mode_base-view-dark-mode-1.png
index e917e49cca..493887e925 100644
Binary files a/ui/marketplace/__screenshots__/MarketplaceAppModal.pw.tsx_dark-color-mode_base-view-dark-mode-1.png and b/ui/marketplace/__screenshots__/MarketplaceAppModal.pw.tsx_dark-color-mode_base-view-dark-mode-1.png differ
diff --git a/ui/marketplace/__screenshots__/MarketplaceAppModal.pw.tsx_default_base-view-dark-mode-1.png b/ui/marketplace/__screenshots__/MarketplaceAppModal.pw.tsx_default_base-view-dark-mode-1.png
index b714324fa3..0e0c241482 100644
Binary files a/ui/marketplace/__screenshots__/MarketplaceAppModal.pw.tsx_default_base-view-dark-mode-1.png and b/ui/marketplace/__screenshots__/MarketplaceAppModal.pw.tsx_default_base-view-dark-mode-1.png differ
diff --git a/ui/marketplace/__screenshots__/MarketplaceAppModal.pw.tsx_default_mobile-base-view-1.png b/ui/marketplace/__screenshots__/MarketplaceAppModal.pw.tsx_default_mobile-base-view-1.png
index 11b310da3c..61f498f479 100644
Binary files a/ui/marketplace/__screenshots__/MarketplaceAppModal.pw.tsx_default_mobile-base-view-1.png and b/ui/marketplace/__screenshots__/MarketplaceAppModal.pw.tsx_default_mobile-base-view-1.png differ
diff --git a/ui/pages/Marketplace.pw.tsx b/ui/pages/Marketplace.pw.tsx
index 1b790db9b3..49f046ace9 100644
--- a/ui/pages/Marketplace.pw.tsx
+++ b/ui/pages/Marketplace.pw.tsx
@@ -22,7 +22,7 @@ test.beforeEach(async({ mockConfigResponse, mockEnvs, mockAssetResponse, page })
await mockConfigResponse('NEXT_PUBLIC_MARKETPLACE_CONFIG_URL', MARKETPLACE_CONFIG_URL, JSON.stringify(appsMock));
await mockConfigResponse('NEXT_PUBLIC_MARKETPLACE_SECURITY_REPORTS_URL', MARKETPLACE_SECURITY_REPORTS_URL, JSON.stringify(securityReportsMock));
await Promise.all(appsMock.map(app => mockAssetResponse(app.logo, './playwright/mocks/image_s.jpg')));
- await page.route('https://api.airtable.com/v0/test/apps_ratings?fields%5B%5D=appId&fields%5B%5D=rating', (route) => route.fulfill({
+ await page.route('https://api.airtable.com/v0/test/apps_ratings?fields%5B%5D=appId&fields%5B%5D=rating&fields%5B%5D=count', (route) => route.fulfill({
status: 200,
body: JSON.stringify(ratingsMock),
}));
diff --git a/ui/pages/MarketplaceApp.pw.tsx b/ui/pages/MarketplaceApp.pw.tsx
index bebab02457..e17d554f3d 100644
--- a/ui/pages/MarketplaceApp.pw.tsx
+++ b/ui/pages/MarketplaceApp.pw.tsx
@@ -35,7 +35,7 @@ const testFn: Parameters[1] = async({ render, mockConfigResponse, m
Method: 'eth_chainId',
ReturnType: numberToHex(Number(config.chain.id)),
});
- await page.route('https://api.airtable.com/v0/test/apps_ratings?fields%5B%5D=appId&fields%5B%5D=rating', (route) => route.fulfill({
+ await page.route('https://api.airtable.com/v0/test/apps_ratings?fields%5B%5D=appId&fields%5B%5D=rating&fields%5B%5D=count', (route) => route.fulfill({
status: 200,
body: JSON.stringify(ratingsMock),
}));
diff --git a/ui/pages/__screenshots__/Marketplace.pw.tsx_dark-color-mode_base-view-dark-mode-1.png b/ui/pages/__screenshots__/Marketplace.pw.tsx_dark-color-mode_base-view-dark-mode-1.png
index cd2c0136f8..829eba61cc 100644
Binary files a/ui/pages/__screenshots__/Marketplace.pw.tsx_dark-color-mode_base-view-dark-mode-1.png and b/ui/pages/__screenshots__/Marketplace.pw.tsx_dark-color-mode_base-view-dark-mode-1.png differ
diff --git a/ui/pages/__screenshots__/Marketplace.pw.tsx_dark-color-mode_with-banner-dark-mode-1.png b/ui/pages/__screenshots__/Marketplace.pw.tsx_dark-color-mode_with-banner-dark-mode-1.png
index 477686b33a..1f3138fb98 100644
Binary files a/ui/pages/__screenshots__/Marketplace.pw.tsx_dark-color-mode_with-banner-dark-mode-1.png and b/ui/pages/__screenshots__/Marketplace.pw.tsx_dark-color-mode_with-banner-dark-mode-1.png differ
diff --git a/ui/pages/__screenshots__/Marketplace.pw.tsx_dark-color-mode_with-featured-app-dark-mode-1.png b/ui/pages/__screenshots__/Marketplace.pw.tsx_dark-color-mode_with-featured-app-dark-mode-1.png
index 36c19db3e2..e10739c05a 100644
Binary files a/ui/pages/__screenshots__/Marketplace.pw.tsx_dark-color-mode_with-featured-app-dark-mode-1.png and b/ui/pages/__screenshots__/Marketplace.pw.tsx_dark-color-mode_with-featured-app-dark-mode-1.png differ
diff --git a/ui/pages/__screenshots__/Marketplace.pw.tsx_default_base-view-dark-mode-1.png b/ui/pages/__screenshots__/Marketplace.pw.tsx_default_base-view-dark-mode-1.png
index ef79ab8616..e97deccb80 100644
Binary files a/ui/pages/__screenshots__/Marketplace.pw.tsx_default_base-view-dark-mode-1.png and b/ui/pages/__screenshots__/Marketplace.pw.tsx_default_base-view-dark-mode-1.png differ
diff --git a/ui/pages/__screenshots__/Marketplace.pw.tsx_default_mobile-base-view-1.png b/ui/pages/__screenshots__/Marketplace.pw.tsx_default_mobile-base-view-1.png
index f8a419b6c1..a24009cbcf 100644
Binary files a/ui/pages/__screenshots__/Marketplace.pw.tsx_default_mobile-base-view-1.png and b/ui/pages/__screenshots__/Marketplace.pw.tsx_default_mobile-base-view-1.png differ
diff --git a/ui/pages/__screenshots__/Marketplace.pw.tsx_default_mobile-with-banner-1.png b/ui/pages/__screenshots__/Marketplace.pw.tsx_default_mobile-with-banner-1.png
index a1aea97f7e..8facaeda8c 100644
Binary files a/ui/pages/__screenshots__/Marketplace.pw.tsx_default_mobile-with-banner-1.png and b/ui/pages/__screenshots__/Marketplace.pw.tsx_default_mobile-with-banner-1.png differ
diff --git a/ui/pages/__screenshots__/Marketplace.pw.tsx_default_mobile-with-featured-app-1.png b/ui/pages/__screenshots__/Marketplace.pw.tsx_default_mobile-with-featured-app-1.png
index 17d2c4035b..105ec24bf5 100644
Binary files a/ui/pages/__screenshots__/Marketplace.pw.tsx_default_mobile-with-featured-app-1.png and b/ui/pages/__screenshots__/Marketplace.pw.tsx_default_mobile-with-featured-app-1.png differ
diff --git a/ui/pages/__screenshots__/Marketplace.pw.tsx_default_with-banner-dark-mode-1.png b/ui/pages/__screenshots__/Marketplace.pw.tsx_default_with-banner-dark-mode-1.png
index 4b9e369833..9eb7a71870 100644
Binary files a/ui/pages/__screenshots__/Marketplace.pw.tsx_default_with-banner-dark-mode-1.png and b/ui/pages/__screenshots__/Marketplace.pw.tsx_default_with-banner-dark-mode-1.png differ
diff --git a/ui/pages/__screenshots__/Marketplace.pw.tsx_default_with-featured-app-dark-mode-1.png b/ui/pages/__screenshots__/Marketplace.pw.tsx_default_with-featured-app-dark-mode-1.png
index ad3a840796..d54f84e16e 100644
Binary files a/ui/pages/__screenshots__/Marketplace.pw.tsx_default_with-featured-app-dark-mode-1.png and b/ui/pages/__screenshots__/Marketplace.pw.tsx_default_with-featured-app-dark-mode-1.png differ
diff --git a/ui/pages/__screenshots__/MarketplaceApp.pw.tsx_dark-color-mode_base-view-dark-mode-1.png b/ui/pages/__screenshots__/MarketplaceApp.pw.tsx_dark-color-mode_base-view-dark-mode-1.png
index 253979b7c2..afa7b3e39e 100644
Binary files a/ui/pages/__screenshots__/MarketplaceApp.pw.tsx_dark-color-mode_base-view-dark-mode-1.png and b/ui/pages/__screenshots__/MarketplaceApp.pw.tsx_dark-color-mode_base-view-dark-mode-1.png differ
diff --git a/ui/pages/__screenshots__/MarketplaceApp.pw.tsx_default_base-view-dark-mode-1.png b/ui/pages/__screenshots__/MarketplaceApp.pw.tsx_default_base-view-dark-mode-1.png
index 5867526a56..71cd5a6fe3 100644
Binary files a/ui/pages/__screenshots__/MarketplaceApp.pw.tsx_default_base-view-dark-mode-1.png and b/ui/pages/__screenshots__/MarketplaceApp.pw.tsx_default_base-view-dark-mode-1.png differ
diff --git a/ui/pages/__screenshots__/MarketplaceApp.pw.tsx_default_mobile-base-view-1.png b/ui/pages/__screenshots__/MarketplaceApp.pw.tsx_default_mobile-base-view-1.png
index 56da5e5830..3a6167f61b 100644
Binary files a/ui/pages/__screenshots__/MarketplaceApp.pw.tsx_default_mobile-base-view-1.png and b/ui/pages/__screenshots__/MarketplaceApp.pw.tsx_default_mobile-base-view-1.png differ
diff --git a/ui/shared/CopyToClipboard.tsx b/ui/shared/CopyToClipboard.tsx
index f241913760..c17a16092e 100644
--- a/ui/shared/CopyToClipboard.tsx
+++ b/ui/shared/CopyToClipboard.tsx
@@ -1,6 +1,7 @@
import { IconButton, Tooltip, useClipboard, chakra, useDisclosure, Skeleton, useColorModeValue } from '@chakra-ui/react';
import React, { useEffect, useState } from 'react';
+import type { IconName } from 'ui/shared/IconSvg';
import IconSvg from 'ui/shared/IconSvg';
export interface Props {
@@ -10,14 +11,18 @@ export interface Props {
onClick?: (event: React.MouseEvent) => void;
size?: number;
type?: 'link';
+ icon?: IconName;
+ variant?: string;
+ colorScheme?: string;
}
-const CopyToClipboard = ({ text, className, isLoading, onClick, size = 5, type }: Props) => {
+const CopyToClipboard = ({ text, className, isLoading, onClick, size = 5, type, icon, variant = 'simple', colorScheme }: Props) => {
const { hasCopied, onCopy } = useClipboard(text, 1000);
const [ copied, setCopied ] = useState(false);
// have to implement controlled tooltip because of the issue - https://github.com/chakra-ui/chakra-ui/issues/7107
const { isOpen, onOpen, onClose } = useDisclosure();
const iconColor = useColorModeValue('gray.400', 'gray.500');
+ const iconName = icon || (type === 'link' ? 'link' : 'copy');
useEffect(() => {
if (hasCopied) {
@@ -40,10 +45,11 @@ const CopyToClipboard = ({ text, className, isLoading, onClick, size = 5, type }
}
+ icon={ }
boxSize={ size }
color={ iconColor }
- variant="simple"
+ variant={ variant }
+ colorScheme={ colorScheme }
display="inline-block"
flexShrink={ 0 }
onClick={ handleClick }