Skip to content
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

Decentralized Verification Feedback: Badges Tooltips + Filters #4765

Merged
merged 3 commits into from
Sep 24, 2024
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
2 changes: 2 additions & 0 deletions lang/ca.json
Original file line number Diff line number Diff line change
Expand Up @@ -1714,6 +1714,8 @@
"tooltip.donation.matching": "Aquesta estimació es basa en les donacions fetes fins ara aquesta ronda de finançament quadràtic i no considera l'anàlisi de frau. La quantitat real d'emparellament pot variar.",
"tooltip.flowrate": "Les donacions recurrents es prenen del teu Saldo de Transmissió. Diposita tokens i mantén el teu saldo per habilitar les donacions recurrents.",
"tooltip.withdraw_stream_balance": "Si teniu donacions recurrents actives, el vostre saldo disponible per retirar serà lleugerament inferior al vostre saldo actual.",
"tooltip.vouched": "Aquest projecte ha estat avalat com a legítim pels verificadors de Giveth",
"tooltip.givback_eligible": "Aquest projecte ha estat verificat com un Bé Públic per Giveth",
"ubi": "Renta bàsica",
"water-and-sanitation": "Aigua i Sanejament"
}
2 changes: 2 additions & 0 deletions lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1714,6 +1714,8 @@
"tooltip.donation.matching": "This estimation is based on the donations made so far this quadratic funding round and is not considering fraud analysis. Actual matching amount vary.",
"tooltip.flowrate": "Recurring donations are taken out of your Stream Balance. Deposit tokens & maintain your balance to enable recurring donations.",
"tooltip.withdraw_stream_balance": "If you have active recurring donations your available stream balance to withdraw will be slightly less than your actual balance.",
"tooltip.vouched": "This project has been Vouched for as legitimate by Giveth Verifiers",
"tooltip.givback_eligible": "This project has been verified as a Public Good by Giveth",
"ubi": "UBI",
"water-and-sanitation": "Water & Sanitation"
}
2 changes: 2 additions & 0 deletions lang/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -1714,6 +1714,8 @@
"tooltip.donation.matching": "Esta estimación se basa en las donaciones realizadas hasta ahora en esta ronda de financiamiento cuadrático y no tiene en cuenta el análisis de fraude. El monto real de fondos complementarios puede variar.",
"tooltip.flowrate": "Las donaciones recurrentes se toman de tu Saldo de Transmisión. Deposita tokens y mantén tu saldo para habilitar las donaciones recurrentes.",
"tooltip.withdraw_stream_balance": "Si tiene donaciones recurrentes activas, su saldo disponible para retirar será ligeramente menor que su saldo actual.",
"tooltip.vouched": "Este proyecto ha sido avalado como legítimo por los verificadores de Giveth",
"tooltip.givback_eligible": "Este proyecto ha sido verificado como un Bien Público por Giveth",
"ubi": "RBI",
"water-and-sanitation": "Agua & Saneamiento"
}
2 changes: 2 additions & 0 deletions src/apollo/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export interface IProject {
export enum EProjectsFilter {
ACCEPT_GIV = 'AcceptGiv',
VERIFIED = 'Verified',
IS_GIVBACK_ELIGIBLE = 'IsGivbackEligible',
BOOSTED_WITH_GIVPOWER = 'BoostedWithGivPower',
GIVING_BLOCK = 'GivingBlock',
Endaoment = 'Endaoment',
Expand All @@ -115,6 +116,7 @@ export enum ECampaignType {

export enum ECampaignFilterField {
Verified = 'verified',
IsGivbackEligible = 'isGivbackEligible',
AcceptGiv = 'givingBlocksId',
GivingBlock = 'fromGivingBlock',
Endaoment = 'fromEndaoment',
Expand Down
29 changes: 26 additions & 3 deletions src/components/IconWithToolTip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,55 @@ import type { FC, ReactNode } from 'react';
interface IIconWithTooltipProps extends ITooltipDirection {
icon: ReactNode;
children: ReactNode;
delay?: boolean;
}

export const IconWithTooltip: FC<IIconWithTooltipProps> = ({
icon,
direction,
align = 'center',
children,
delay = false,
}) => {
const [show, setShow] = useState(false);
const elRef = useRef<HTMLDivElement>(null);
const timeoutRef = useRef<NodeJS.Timeout | null>(null);

const showTooltip = () => {
if (delay) {
timeoutRef.current = setTimeout(() => {
setShow(true);
}, 500); // 0.5 second delay
} else {
setShow(true);
}
};

const hideTooltip = () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
setShow(false);
};

useEffect(() => {
function handleRemoveTooltip() {
setShow(false);
hideTooltip();
}
window.addEventListener('scroll', handleRemoveTooltip);

return () => {
window.removeEventListener('scroll', handleRemoveTooltip);
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
};
}, []);

return (
<IconWithTooltipContainer
onMouseEnter={() => setShow(true)}
onMouseLeave={() => setShow(false)}
onMouseEnter={showTooltip}
onMouseLeave={hideTooltip}
onClick={e => {
e.stopPropagation(); // make tooltip content clickable without affecting parent
}}
Expand Down
13 changes: 7 additions & 6 deletions src/components/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ interface ITooltipProps extends ITooltipDirection {
}

const ARROW_SIZE = 0;
const MARGIN = 4;

export const Tooltip: FC<ITooltipProps> = ({
parentRef,
Expand Down Expand Up @@ -124,13 +125,13 @@ const tooltipStyleCalc = (
let translateY;
if (isMobile && direction !== 'bottom') {
style = {
top: parentRect.top - ARROW_SIZE - 50,
top: parentRect.top - ARROW_SIZE - 50 - MARGIN,
left: 10,
width: '95vw',
};
} else if (isMobile && direction === 'bottom') {
style = {
top: parentRect.bottom + ARROW_SIZE,
top: parentRect.bottom + ARROW_SIZE + MARGIN,
left: 10,
width: '95vw',
};
Expand All @@ -139,15 +140,15 @@ const tooltipStyleCalc = (
case 'top':
translateX = translateXForTopBottom(align, parentRect);
style = {
top: parentRect.top - ARROW_SIZE,
top: parentRect.top - ARROW_SIZE - MARGIN,
left: parentRect.left,
transform: `translate(${translateX}, -100%)`,
};
break;
case 'bottom':
translateX = translateXForTopBottom(align, parentRect);
style = {
top: parentRect.bottom + ARROW_SIZE,
top: parentRect.bottom + ARROW_SIZE + MARGIN,
left: parentRect.left,
transform: `translate(${translateX}, 0)`,
};
Expand All @@ -157,15 +158,15 @@ const tooltipStyleCalc = (
translateY = translateYForRightLeft(align, parentRect);
style = {
top: parentRect.bottom,
left: parentRect.right + ARROW_SIZE,
left: parentRect.right + ARROW_SIZE + MARGIN,
transform: `translate(0, ${translateY})`,
};
break;
case 'left':
translateY = translateYForRightLeft(align, parentRect);
style = {
top: parentRect.bottom,
left: parentRect.left - ARROW_SIZE,
left: parentRect.left - ARROW_SIZE - MARGIN,
transform: `translate(-100%, ${translateY})`,
};
break;
Expand Down
4 changes: 2 additions & 2 deletions src/components/menu/FilterMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ interface IFilterMenuProps {

const projectsFeatures = [
{
label: { id: 'label.vouched' },
value: EProjectsFilter.VERIFIED,
label: { id: 'label.isGivbackEligible' },
value: EProjectsFilter.IS_GIVBACK_ELIGIBLE,
Comment on lines +26 to +27
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Issues Found:

  • EProjectsFilter.VERIFIED is still used in src/helpers/url.tsx.

Please update or remove this usage to ensure consistency with the new filter value.

Analysis chain

LGTM! Verify translations and update related components.

The change from "vouched" to "isGivbackEligible" aligns well with the PR objectives. This update shifts the focus from project verification to GIVback eligibility, which seems to be the intended behavior.

To ensure consistency across the codebase:

  1. Verify that the new label 'label.isGivbackEligible' is properly translated in all language files.
  2. Check other components that might be using the old EProjectsFilter.VERIFIED value and update them accordingly.

Run the following script to help with these verifications:

This script will help identify any inconsistencies or areas that might need updating due to this change.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash

# Check for the new label in translation files
echo "Checking for 'label.isGivbackEligible' in translation files:"
rg --type json "label\.isGivbackEligible"

echo "\nChecking for usages of EProjectsFilter.VERIFIED:"
rg --type typescript "EProjectsFilter\.VERIFIED"

echo "\nChecking for usages of EProjectsFilter.IS_GIVBACK_ELIGIBLE:"
rg --type typescript "EProjectsFilter\.IS_GIVBACK_ELIGIBLE"

Length of output: 800


Script:

#!/bin/bash

# Check for the new label in translation files
echo "Checking for 'label.isGivbackEligible' in translation files:"
rg --type json "label\.isGivbackEligible"

echo "\nChecking for usages of EProjectsFilter.VERIFIED in TypeScript files:"
rg --type ts "EProjectsFilter\.VERIFIED"

echo "\nChecking for usages of EProjectsFilter.IS_GIVBACK_ELIGIBLE in TypeScript files:"
rg --type ts "EProjectsFilter\.IS_GIVBACK_ELIGIBLE"

Length of output: 1014

},
];

Expand Down
2 changes: 1 addition & 1 deletion src/components/project-card/ProjectCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const ProjectCard = (props: IProjectCard) => {
estimatedMatching || {};

const { activeStartedRound, activeQFRound } = getActiveRound(qfRounds);
const hasFooter = activeStartedRound || verified;
const hasFooter = activeStartedRound || verified || isGivbackEligible;

const {
allocatedFundUSDPreferred,
Expand Down
61 changes: 46 additions & 15 deletions src/components/views/project/ProjectBadges.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useIntl } from 'react-intl';
import { useProjectContext } from '@/context/project.context';
import ProjectBadge from './ProjectBadge';
import { hasActiveRound } from '@/helpers/qf';
import { IconWithTooltip } from '@/components/IconWithToolTip';

const ProjectBadges = () => {
const { projectData } = useProjectContext();
Expand All @@ -28,23 +29,45 @@ const ProjectBadges = () => {
return (
<CustomFlex gap='16px'>
{verified && (
<ProjectBadge
badgeText={formatMessage({
id: 'label.vouched',
})}
wrapperColor={semanticColors.jade[700]}
BadgeIcon={<IconVerifiedBadge16 />}
/>
<IconWithTooltip
delay
icon={
<ProjectBadge
badgeText={formatMessage({
id: 'label.vouched',
})}
wrapperColor={semanticColors.jade[700]}
BadgeIcon={<IconVerifiedBadge16 />}
/>
}
direction='top'
>
<TooltipContent>
{formatMessage({ id: 'tooltip.vouched' })}
</TooltipContent>
</IconWithTooltip>
)}
{isGivbackEligible && (
<ProjectBadge
badgeText={formatMessage({
id: 'label.isGivbackEligible',
})}
textColor={brandColors.giv[500]}
wrapperColor={'white'}
BadgeIcon={<IconGIVBack16 color={brandColors.giv[500]} />}
/>
<IconWithTooltip
delay
icon={
<ProjectBadge
badgeText={formatMessage({
id: 'label.isGivbackEligible',
})}
textColor={brandColors.giv[500]}
wrapperColor={'white'}
BadgeIcon={
<IconGIVBack16 color={brandColors.giv[500]} />
}
/>
}
direction='top'
>
<TooltipContent>
{formatMessage({ id: 'tooltip.givback_eligible' })}
</TooltipContent>
</IconWithTooltip>
)}

{isQF && (
Expand Down Expand Up @@ -76,4 +99,12 @@ const CustomFlex = styled(Flex)`
padding-top: 8px;
`;

export const TooltipContent = styled.div`
color: ${neutralColors.gray[100]};
cursor: default;
text-align: center;
width: 150px;
font-size: 0.8em;
`;

export default ProjectBadges;
3 changes: 1 addition & 2 deletions src/components/views/project/ProjectGIVbackToast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -409,8 +409,7 @@ const Wrapper = styled(Flex)`

const InnerLink = styled.a`
cursor: pointer;
text-decoration: underline;
color: ${neutralColors.gray[900]};
color: ${brandColors.pinky[500]};
`;

export default ProjectGIVbackToast;
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export const ProjectStats = () => {
</IconWithTooltip>
</Flex>
<VerificationBadge
isVerified={projectData?.verified}
isVerified={projectData?.isGivbackEligible}
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Inconsistent usage of verification properties detected across the codebase

The change from projectData?.verified to projectData?.isGivbackEligible in ProjectStats.tsx impacts multiple components:

  • projectData?.verified is used in:

    • src/components/views/project/ProjectGIVbackToast.tsx
    • src/components/views/project/ProjectTabs.tsx
    • src/components/views/donate/DonatePageProjectDescription.tsx
  • projectData?.isGivbackEligible is used in:

    • src/components/views/project/ProjectGIVbackToast.tsx
    • src/components/views/project/projectActionCard/ProjectStats.tsx
    • src/components/views/donate/DonatePageProjectDescription.tsx
  • VerificationBadge component is used in:

    • src/components/views/project/projectActionCard/ProjectStats.tsx
    • src/components/views/userProfile/projectsTab/ProjectItem.tsx

This scattered usage suggests potential inconsistencies in how project verification status is handled and displayed across the application. It's recommended to:

  1. Review and unify the verification criteria to ensure consistency.
  2. Update all affected components to use the new isGivbackEligible property if it aligns with the intended functionality.
  3. Consider renaming the VerificationBadge component if its purpose is now specifically tied to GIVbacks eligibility.
  4. Conduct thorough testing to ensure that the changes do not introduce bugs or inconsistencies in the user interface.
Analysis chain

Verify the implications of changing verification criteria

The change from projectData?.verified to projectData?.isGivbackEligible alters the criteria for determining a project's verification status. While this might align with new requirements, it raises several concerns:

  1. The new criteria (isGivbackEligible) might not be a direct equivalent to the previous verified status. A project could potentially be verified but not eligible for GIVbacks, or vice versa.
  2. The component name VerificationBadge might now be misleading if it's specifically showing GIVbacks eligibility rather than a general verification status.
  3. Other parts of the application might still be using projectData?.verified, which could lead to inconsistencies in how project verification is represented across the platform.

To ensure consistency and correct implementation, please run the following script:

This script will help identify other occurrences of these properties and the VerificationBadge component, allowing you to ensure consistent usage across the codebase.

Additionally, consider the following actions:

  1. Update the VerificationBadge component name or its internal logic to accurately reflect its new purpose if it's now specifically for GIVbacks eligibility.
  2. Ensure that this change is documented in the project's documentation or changelog.
  3. Verify that this change aligns with the intended user experience and doesn't introduce confusion for users familiar with the previous verification system.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for other occurrences of 'verified' and 'isGivbackEligible' in the codebase

echo "Searching for 'verified' property usage:"
rg 'projectData\?\.verified' --type typescript

echo "\nSearching for 'isGivbackEligible' property usage:"
rg 'projectData\?\.isGivbackEligible' --type typescript

echo "\nSearching for 'VerificationBadge' component usage:"
rg '<VerificationBadge' --type typescript

Length of output: 592


Script:

#!/bin/bash
# Description: Check for other occurrences of 'verified' and 'isGivbackEligible' in the codebase

echo "Searching for 'verified' property usage:"
rg 'projectData\?\.verified' --type typescriptreact

echo "\nSearching for 'isGivbackEligible' property usage:"
rg 'projectData\?\.isGivbackEligible' --type typescriptreact

echo "\nSearching for 'VerificationBadge' component usage:"
rg '<VerificationBadge' --type typescriptreact

Length of output: 622


Script:

#!/bin/bash
# Description: Check for other occurrences of 'verified' and 'isGivbackEligible' in the codebase within .ts and .tsx files

echo "Searching for 'verified' property usage in .ts and .tsx files:"
rg 'projectData\?\.verified' --glob '*.ts' --glob '*.tsx'

echo "\nSearching for 'isGivbackEligible' property usage in .ts and .tsx files:"
rg 'projectData\?\.isGivbackEligible' --glob '*.ts' --glob '*.tsx'

echo "\nSearching for 'VerificationBadge' component usage in .ts and .tsx files:"
rg '<VerificationBadge' --glob '*.ts' --glob '*.tsx'

Length of output: 1415

verificationStatus={projectData?.verificationFormStatus}
/>
</StatRow>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ const ProjectItem: FC<IProjectItem> = props => {
</P>
<div>
<VerificationBadge
isVerified={project?.verified}
isVerified={project?.isGivbackEligible}
verificationStatus={
project.projectVerificationForm?.status
}
Expand Down
6 changes: 6 additions & 0 deletions src/helpers/url.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ export function campaignLinkGenerator(campaign: ICampaign) {
case ECampaignFilterField.Verified:
params.append('filter', EProjectsFilter.VERIFIED);
break;
case ECampaignFilterField.IsGivbackEligible:
params.append(
'filter',
EProjectsFilter.IS_GIVBACK_ELIGIBLE,
);
break;
case ECampaignFilterField.Endaoment:
params.append('filter', EProjectsFilter.Endaoment);
break;
Expand Down
Loading