Skip to content

Commit

Permalink
feat: add styling when expired providers exists, to the points box in… (
Browse files Browse the repository at this point in the history
#2674)

* feat: add styling when expired providers exists, to the points box in the sidebar

* fix: remove unused code

* fix: y padding in points display in stamp selector
  • Loading branch information
nutrina committed Jul 5, 2024
1 parent 667b7f4 commit 223ea9e
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 53 deletions.
1 change: 0 additions & 1 deletion app/components/GenericBanner.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { PlatformBanner, Hyperlink } from "@gitcoin/passport-platforms";

export function GenericBanner({ banner }: { banner: PlatformBanner }) {
console.log("geri banner", banner);
const heading = banner.heading ? <>{banner.heading} </> : null;
return (
<div className="mt-8 text-sm">
Expand Down
99 changes: 73 additions & 26 deletions app/components/PlatformDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import { customStampProviders, getStampProviderIds } from "../config/providers";
import { PLATFORM_ID } from "@gitcoin/passport-types";
import { useCustomization } from "../hooks/useCustomization";

// --- Helpers
import { intersect } from "../utils/helpers";

const PlatformJsonButton = ({
platformPassportData,
platform,
Expand Down Expand Up @@ -91,12 +94,25 @@ const ExpirationIndicator = ({ expirationDate }: { expirationDate: Date | string

const statusClass =
daysUntilExpiration > 45 ? "text-color-8" : daysUntilExpiration > 10 ? "text-color-9" : "text-color-10";
return (
<div className="pl-4 flex items-center text-color-6 bg-gradient-to-b from-background via-background to-[#082F2A] border border-t-0 rounded-t-none rounded-b-lg border-foreground-5 py-2">
<span className={`text-3xl pr-2 ${statusClass}`}>{daysUntilExpiration}</span>{" "}
{daysUntilExpiration === 1 ? "day" : "days"} until stamps expire
</div>
);
if (daysUntilExpiration < 0) {
// bg-gradient-to-b from-background to-background-5/30
// hover:bg-opacity-100 hover:from-transparent hover:shadow-even-md hover:border-background-5 hover:to-background-5/60 hover:shadow-background-5"
return (
<div
className="pl-4 flex items-center text-color-7 border-t-0 rounded-t-none rounded-b-lg py-2
border border-background-5 bg-gradient-to-b from-background to-background-5/30"
>
Stamp expired
</div>
);
} else {
return (
<div className="pl-4 flex items-center text-color-6 bg-gradient-to-b from-background via-background to-[#082F2A] border border-t-0 rounded-t-none rounded-b-lg border-foreground-5 py-2">
<span className={`text-3xl pr-2 ${statusClass}`}>{daysUntilExpiration}</span>{" "}
{daysUntilExpiration === 1 ? "day" : "days"} until stamps expire
</div>
);
}
};

export const customSideBarGradient = "bg-gradient-to-b from-background via-background to-[#082F2A]";
Expand All @@ -113,13 +129,13 @@ export const PlatformDetails = ({
onClose: () => void;
}) => {
const { scoredPlatforms } = useContext(ScorerContext);
const { passport, platformExpirationDates } = useContext(CeramicContext);
const { passport, platformExpirationDates, expiredProviders } = useContext(CeramicContext);

const currentPlatformScoreSpec = scoredPlatforms.find((platform) => platform.name === currentPlatform.name);

const platformPassportData = useMemo(
() =>
verifiedProviders && passport && passport.stamps.filter((stamp) => verifiedProviders.includes(stamp.provider)),
verifiedProviders && passport && passport.stamps.filter((stamp) => verifiedProviders?.includes(stamp.provider)),
[verifiedProviders, passport]
);

Expand All @@ -131,6 +147,54 @@ export const PlatformDetails = ({
const pointsGained = +earnedPoints.toFixed(2);
const pointsAvailable = +Math.max(possiblePoints - earnedPoints, 0).toFixed(2);

verifiedProviders = verifiedProviders || [];
const hasExpiredProviders = useMemo(() => {
return intersect(new Set(expiredProviders), new Set(verifiedProviders)).size > 0;
}, [verifiedProviders, expiredProviders]);

const pointsBox = useMemo(() => {
if (!hasStamps) {
return null;
}

return hasExpiredProviders ? (
<>
<div className="mt-4 border-background-5 border rounded-t-lg px-4 py-2">
<div className="flex justify-between">
<p className="text-color-10">points gained</p>
<p className="text-color-7">points left</p>
</div>
<div className="flex justify-between text-5xl">
<p className="text-color-10">{pointsGained}</p>
<p className="text-color-7">{pointsAvailable}</p>
</div>
<ProgressBar
pointsGained={pointsGained}
pointsAvailable={pointsAvailable}
gainedBarColor="rgb(var(--color-text-7))"
availableBarColor="rgb(var(--color-text-10))"
/>
</div>
<ExpirationIndicator expirationDate={platformExpirationDates[currentPlatform.platform as PLATFORM_ID] || ""} />
</>
) : (
<>
<div className="mt-4 border-foreground-5 border rounded-t-lg px-4 py-2 bg-gradient-to-b from-background via-background to-[#082F2A]">
<div className="flex justify-between">
<p className="text-color-6">points gained</p>
<p className="text-color-2">points left</p>
</div>
<div className="flex justify-between text-5xl">
<p className="text-color-6">{pointsGained}</p>
<p className="text-color-2">{pointsAvailable}</p>
</div>
<ProgressBar pointsGained={pointsGained} pointsAvailable={pointsAvailable} />
</div>
<ExpirationIndicator expirationDate={platformExpirationDates[currentPlatform.platform as PLATFORM_ID] || ""} />
</>
);
}, [hasStamps, hasExpiredProviders]);

return (
<div className="w-full text-color-1">
<div className="flex w-full items-center justify-between">
Expand Down Expand Up @@ -159,24 +223,7 @@ export const PlatformDetails = ({
<p className="mt-8 text-base md:w-8/12">{currentPlatform?.description}</p>
)}
{bannerConfig && <GenericBanner banner={bannerConfig} />}
{hasStamps && (
<>
<div className={`mt-4 border-foreground-5 border rounded-t-lg px-4 py-2 ${customSideBarGradient}`}>
<div className="flex justify-between">
<p className="text-color-6">points gained</p>
<p className="text-color-2">points left</p>
</div>
<div className="flex justify-between text-5xl">
<p className="text-color-6">{pointsGained}</p>
<p className="text-color-2">{pointsAvailable}</p>
</div>
<ProgressBar pointsGained={pointsGained} pointsAvailable={pointsAvailable} />
</div>
<ExpirationIndicator
expirationDate={platformExpirationDates[currentPlatform.platform as PLATFORM_ID] || ""}
/>
</>
)}
{pointsBox}
</div>
);
};
14 changes: 11 additions & 3 deletions app/components/ProgressBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@ interface ProgressBarProps {
pointsGained: number;
pointsAvailable: number;
isSlim?: boolean;
gainedBarColor?: string;
availableBarColor?: string;
}

export const ProgressBar: React.FC<ProgressBarProps> = ({ pointsGained, pointsAvailable, isSlim = false }) => {
export const ProgressBar: React.FC<ProgressBarProps> = ({
pointsGained,
pointsAvailable,
isSlim = false,
gainedBarColor = "rgb(var(--color-foreground-4))",
availableBarColor = "#C1F6FF",
}) => {
const percentGained = (pointsGained / (pointsGained + pointsAvailable)) * 100 || 0;

const gainedBarWidth = isSlim ? 3 : 6;
Expand All @@ -24,7 +32,7 @@ export const ProgressBar: React.FC<ProgressBarProps> = ({ pointsGained, pointsAv
y1="5"
x2={100 + capDistance}
y2="5"
stroke="rgb(var(--color-foreground-4))"
stroke={gainedBarColor}
strokeWidth={remainingBarWidth}
strokeLinecap="round"
/>
Expand All @@ -44,7 +52,7 @@ export const ProgressBar: React.FC<ProgressBarProps> = ({ pointsGained, pointsAv
y1="5"
x2={percentGained + capDistance}
y2="5"
stroke="#C1F6FF"
stroke={availableBarColor}
strokeWidth={gainedBarWidth}
strokeLinecap="round"
/>
Expand Down
96 changes: 73 additions & 23 deletions app/components/StampSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,37 +62,87 @@ export function StampSelector({ currentPlatform, currentProviders, verifiedProvi
}
const isVerified = verifiedProviders?.indexOf(provider.name) !== -1;
const isExpired = expiredProviders?.indexOf(provider.name) !== -1;
const isValid = isVerified && !isExpired;

let textColor = isValid ? "text-color-1" : "text-color-2";

const rawWeight = stampWeights?.[provider.name];
const weight = rawWeight ? +parseFloat(rawWeight).toFixed(2) : 0;

return (
<React.Fragment key={provider.name}>
<div
data-testid={`indicator-${provider.name}`}
className={`relative rounded ${isValid ? "border-foreground-2" : "border-color-3"} text-base ${textColor} flex justify-between items-stretch border text-color-3 mt-4 `}
>
<div className={`p-4 border-r w-3/4 ${isValid && customSideBarGradient}`}>
<p className={`${isValid && "font-bold text-color-6"}`}>
{isValid && checkMark()} {provider.title}
</p>
{provider.description && <p className="my-2 text-sm leading-tight">{provider.description}</p>}
if (isExpired) {
// Return verified stamp
return (
<React.Fragment key={provider.name}>
<div
data-testid={`indicator-${provider.name}`}
className="relative rounded text-base flex justify-between items-stretch text-color-3 mt-4 border border-background-5 bg-gradient-to-b from-background to-background-5/30"
>
<div className="p-4 border-r border-background-5 w-3/4">
<p className="">
{provider.title}
<p
className="text-xs bg-background-5 px-1 ml-2 rounded text-right font-alt text-black inline-block relative -top-0.5"
data-testid="expired-label"
>
Expired
</p>
</p>
{provider.description && <p className="my-2 text-sm leading-tight">{provider.description}</p>}
</div>

<div className="w-1/4 flex items-center text-color-7 py-3">
<p className="text-2xl text-center w-full text-s leading-none">
<span>{weight}</span> <br />
<span className="text-base">points</span>
</p>
</div>
</div>

</React.Fragment>
);
} else if (isVerified) {
// Return expired stamp
return (
<React.Fragment key={provider.name}>
<div
className={`${isValid && "bg-gradient-to-r from-foreground-2 to-foreground-4"} w-1/4 flex items-center ${isValid && "text-background-4"}`}
data-testid={`indicator-${provider.name}`}
className={`relative rounded border-foreground-2 text-base flex justify-between items-stretch border text-color-1 mt-4 `}
>
<p className="text-2xl text-center w-full text-s leading-none">
<span className={`${isValid && "font-bold"}`}>{weight}</span> <br />
<span className="text-base">points</span>
</p>
<div className={`p-4 border-r w-3/4 ${customSideBarGradient}`}>
<p className="font-bold text-color-6">
{checkMark()} {provider.title}
</p>
{provider.description && <p className="my-2 text-sm leading-tight">{provider.description}</p>}
</div>

<div className="bg-gradient-to-r from-foreground-2 to-foreground-4 w-1/4 flex items-center text-background-4 py-3">
<p className="text-2xl text-center w-full text-s leading-none">
<span className="font-bold">{weight}</span> <br />
<span className="text-base">points</span>
</p>
</div>
</div>
</div>
</React.Fragment>
);
</React.Fragment>
);
} else {
// Return unverified stamp
return (
<React.Fragment key={provider.name}>
<div
data-testid={`indicator-${provider.name}`}
className={`relative rounded border-color-3 text-base text-color-3 flex justify-between items-stretch border mt-4 `}
>
<div className="p-4 border-r w-3/4">
<p>{provider.title}</p>
{provider.description && <p className="my-2 text-sm leading-tight">{provider.description}</p>}
</div>

<div className="w-1/4 flex items-center py-3">
<p className="text-2xl text-center w-full text-s leading-none">
<span>{weight}</span> <br />
<span className="text-base">points</span>
</p>
</div>
</div>
</React.Fragment>
);
}
})}
</div>
);
Expand Down

0 comments on commit 223ea9e

Please sign in to comment.