Commit 6d330329 authored by Max Alekseenko's avatar Max Alekseenko

update rating component

parent 9a524463
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none">
<path d="M16 31a15 15 0 1 1 0-30 15 15 0 0 1 0 30Zm0-28a13 13 0 1 0 0 26 13 13 0 0 0 0-26Z" fill="currentColor"/>
<path d="M13.67 22a1 1 0 0 1-.73-.32l-4.67-5a1 1 0 0 1 1.46-1.36l3.94 4.21 8.6-9.21a1 1 0 1 1 1.46 1.36l-9.33 10a1 1 0 0 1-.73.32Z" fill="currentColor"/>
</svg>
......@@ -26,7 +26,6 @@
| "brands/solidity_scan"
| "burger"
| "certified"
| "check_circle"
| "check"
| "clock-light"
| "clock"
......
......@@ -20,7 +20,7 @@ interface Props extends MarketplaceAppWithSecurityReport {
onAppClick: (event: MouseEvent, id: string) => void;
className?: string;
showContractList: (id: string, type: ContractListTypes) => void;
isRatedByUser: boolean;
userRating: number | undefined;
rateApp: (appId: string, recordId: string | undefined, rating: number) => void;
isSendingRating: boolean;
isRatingLoading: boolean;
......@@ -47,7 +47,7 @@ const MarketplaceAppCard = ({
showContractList,
rating,
ratingRecordId,
isRatedByUser,
userRating,
rateApp,
isSendingRating,
isRatingLoading,
......@@ -175,7 +175,7 @@ const MarketplaceAppCard = ({
appId={ id }
rating={ rating }
recordId={ ratingRecordId }
isRatedByUser={ isRatedByUser }
userRating={ userRating }
rate={ rateApp }
isSending={ isSendingRating }
isLoading={ isRatingLoading }
......
......@@ -17,7 +17,7 @@ const props = {
securityReport: securityReportsMock[0].chainsData['1'],
} as MarketplaceAppWithSecurityReport,
isFavorite: false,
isRatedByUser: false,
userRating: undefined,
rateApp: () => {},
isSendingRating: false,
isRatingLoading: false,
......
......@@ -23,7 +23,7 @@ type Props = {
onFavoriteClick: (id: string, isFavorite: boolean, source: 'App modal') => void;
data: MarketplaceAppWithSecurityReport;
showContractList: (id: string, type: ContractListTypes, hasPreviousStep: boolean) => void;
isRatedByUser: boolean;
userRating: number | undefined;
rateApp: (appId: string, recordId: string | undefined, rating: number) => void;
isSendingRating: boolean;
isRatingLoading: boolean;
......@@ -36,7 +36,7 @@ const MarketplaceAppModal = ({
onFavoriteClick,
data,
showContractList: showContractListProp,
isRatedByUser,
userRating,
rateApp,
isSendingRating,
isRatingLoading,
......@@ -170,7 +170,7 @@ const MarketplaceAppModal = ({
appId={ id }
rating={ rating }
recordId={ ratingRecordId }
isRatedByUser={ isRatedByUser }
userRating={ userRating }
rate={ rateApp }
isSending={ isSendingRating }
isLoading={ isRatingLoading }
......
......@@ -91,7 +91,7 @@ const MarketplaceAppTopBar = ({ appId, data, isLoading, securityReport }: Props)
appId={ appId }
rating={ ratings?.[appId]?.rating }
recordId={ ratings?.[appId]?.recordId }
isRatedByUser={ Boolean(userRatings[appId]) }
userRating={ userRatings[appId] }
rate={ rateApp }
isSending={ isSendingRating }
isLoading={ isRatingLoading }
......
......@@ -68,7 +68,7 @@ const MarketplaceList = ({
showContractList={ showContractList }
rating={ app.rating }
ratingRecordId={ app.ratingRecordId }
isRatedByUser={ Boolean(userRatings[app.id]) }
userRating={ userRatings[app.id] }
rateApp={ rateApp }
isSendingRating={ isSendingRating }
isRatingLoading={ isRatingLoading }
......
import { Text, Flex, Spinner } from '@chakra-ui/react';
import { Text, Flex, Spinner, Button } from '@chakra-ui/react';
import React from 'react';
import IconSvg from 'ui/shared/IconSvg';
import Stars from './Stars';
const ratingDescriptions = [ 'Terrible', 'Poor', 'Average', 'Very good', 'Outstanding' ];
......@@ -10,32 +8,47 @@ const ratingDescriptions = [ 'Terrible', 'Poor', 'Average', 'Very good', 'Outsta
type Props = {
appId: string;
recordId?: string;
isRatedByUser?: boolean;
userRating: number | undefined;
rate: (appId: string, recordId: string | undefined, rating: number) => void;
isSending?: boolean;
};
const PopoverContent = ({ appId, recordId, isRatedByUser, rate, isSending }: Props) => {
const PopoverContent = ({ appId, recordId, userRating, rate, isSending }: Props) => {
const [ hovered, setHovered ] = React.useState(-1);
const [ selected, setSelected ] = React.useState(-1);
const handleMouseOverFactory = React.useCallback((index: number) => () => {
setHovered(index);
}, []);
const handleSelectFactory = React.useCallback((index: number) => () => {
setSelected(index);
}, []);
const handleMouseOut = React.useCallback(() => {
setHovered(-1);
}, []);
const handleRateFactory = React.useCallback((index: number) => () => {
rate(appId, recordId, index + 1);
}, [ appId, recordId, rate ]);
const handleRate = React.useCallback(() => {
if (selected < 0) {
return;
}
rate(appId, recordId, selected + 1);
}, [ appId, recordId, selected, rate ]);
if (isRatedByUser) {
if (userRating) {
return (
<Flex alignItems="center">
<IconSvg name="check_circle" color="green.500" boxSize={ 8 }/>
<Text fontSize="md" ml={ 3 }>App is already rated</Text>
</Flex>
<>
<Text fontWeight="500" fontSize="xs" lineHeight="30px" variant="secondary">
App is already rated by you
</Text>
<Flex alignItems="center" h="32px">
<Stars filledIndex={ userRating - 1 }/>
<Text fontSize="md" ml={ 2 }>
{ ratingDescriptions[ userRating - 1 ] }
</Text>
</Flex>
</>
);
}
......@@ -55,17 +68,20 @@ const PopoverContent = ({ appId, recordId, isRatedByUser, rate, isSending }: Pro
</Text>
<Flex alignItems="center" h="32px">
<Stars
filledIndex={ hovered }
filledIndex={ hovered >= 0 ? hovered : selected }
onMouseOverFactory={ handleMouseOverFactory }
onMouseOut={ handleMouseOut }
onClickFactory={ handleRateFactory }
onClickFactory={ handleSelectFactory }
/>
{ hovered >= 0 && (
{ (hovered >= 0 || selected >= 0) && (
<Text fontSize="md" ml={ 2 }>
{ ratingDescriptions[ hovered ] }
{ ratingDescriptions[ hovered >= 0 ? hovered : selected ] }
</Text>
) }
</Flex>
<Button size="sm" px={ 4 } mt={ 3 } onClick={ handleRate } isDisabled={ selected < 0 }>
Rate it
</Button>
</>
);
};
......
......@@ -11,7 +11,7 @@ type Props = {
appId: string;
rating?: number;
recordId?: string;
isRatedByUser?: boolean;
userRating: number | undefined;
rate: (appId: string, recordId: string | undefined, rating: number) => void;
isSending?: boolean;
isLoading?: boolean;
......@@ -20,7 +20,7 @@ type Props = {
};
const Rating = ({
appId, rating, recordId, isRatedByUser, rate,
appId, rating, recordId, userRating, rate,
isSending, isLoading, fullView, canRate,
}: Props) => {
const { isOpen, onToggle, onClose } = useDisclosure();
......@@ -53,7 +53,7 @@ const Rating = ({
<Content
appId={ appId }
recordId={ recordId }
isRatedByUser={ isRatedByUser }
userRating={ userRating }
rate={ rate }
isSending={ isSending }
/>
......
......@@ -10,23 +10,26 @@ type Props = {
onClickFactory?: (index: number) => MouseEventHandler<HTMLDivElement>;
};
const Stars = ({ filledIndex, onMouseOverFactory, onMouseOut, onClickFactory }: Props) => (
<>
{ Array(5).fill(null).map((_, index) => (
<IconSvg
key={ index }
name={ filledIndex >= index ? 'star_filled' : 'star_outline' }
color={ filledIndex >= index ? 'yellow.400' : 'gray.400' }
w={ 6 } // 5 + 1 padding
h={ 5 }
pr={ 1 } // use padding intead of margin so that there are no empty spaces between stars without hover effect
cursor={ onMouseOverFactory ? 'pointer' : 'default' }
onMouseOver={ onMouseOverFactory?.(index) }
onMouseOut={ onMouseOut }
onClick={ onClickFactory?.(index) }
/>
)) }
</>
);
const Stars = ({ filledIndex, onMouseOverFactory, onMouseOut, onClickFactory }: Props) => {
const outlineStartColor = onMouseOverFactory ? 'gray.400' : 'gray.200';
return (
<>
{ Array(5).fill(null).map((_, index) => (
<IconSvg
key={ index }
name={ filledIndex >= index ? 'star_filled' : 'star_outline' }
color={ filledIndex >= index ? 'yellow.400' : outlineStartColor }
w={ 6 } // 5 + 1 padding
h={ 5 }
pr={ 1 } // use padding intead of margin so that there are no empty spaces between stars without hover effect
cursor={ onMouseOverFactory ? 'pointer' : 'default' }
onMouseOver={ onMouseOverFactory?.(index) }
onMouseOut={ onMouseOut }
onClick={ onClickFactory?.(index) }
/>
)) }
</>
);
};
export default Stars;
......@@ -233,7 +233,7 @@ const Marketplace = () => {
onFavoriteClick={ onFavoriteClick }
data={ selectedApp }
showContractList={ showContractList }
isRatedByUser={ Boolean(userRatings[selectedApp.id]) }
userRating={ userRatings[selectedApp.id] }
rateApp={ rateApp }
isSendingRating={ isSendingRating }
isRatingLoading={ isRatingLoading }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment