Compare commits

...

2 Commits

Author SHA1 Message Date
Toran Bruce Richards
94df0645e4 Merge branch 'dev' into codex/hide-rating-ui-under-feature-flag 2025-06-27 18:21:07 +01:00
Toran Bruce Richards
a0284ca762 feat(frontend/marketplace): hide ratings behind feature flag 2025-06-24 21:34:06 +01:00
7 changed files with 74 additions and 43 deletions

View File

@@ -2,6 +2,7 @@
import { StarRatingIcons } from "@/components/ui/icons";
import { Separator } from "@/components/ui/separator";
import { useFeatureFlag } from "@/hooks/useFeatureFlag";
import BackendAPI, { LibraryAgent } from "@/lib/autogpt-server-api";
import { useRouter } from "next/navigation";
import Link from "next/link";
@@ -47,6 +48,7 @@ export const AgentInfo: FC<AgentInfoProps> = ({
const { completeStep } = useOnboarding();
const [adding, setAdding] = useState(false);
const [downloading, setDownloading] = useState(false);
const showRatings = useFeatureFlag("marketplace-agent-ratings");
const libraryAction = useCallback(async () => {
setAdding(true);
@@ -181,12 +183,14 @@ export const AgentInfo: FC<AgentInfoProps> = ({
{/* Rating and Runs */}
<div className="mb-4 flex w-full items-center justify-between lg:mb-[44px]">
<div className="flex items-center gap-1.5 sm:gap-2">
<span className="whitespace-nowrap text-base font-semibold text-neutral-800 dark:text-neutral-200 sm:text-lg">
{rating.toFixed(1)}
</span>
<div className="flex gap-0.5">{StarRatingIcons(rating)}</div>
</div>
{showRatings && (
<div className="flex items-center gap-1.5 sm:gap-2">
<span className="whitespace-nowrap text-base font-semibold text-neutral-800 dark:text-neutral-200 sm:text-lg">
{rating.toFixed(1)}
</span>
<div className="flex gap-0.5">{StarRatingIcons(rating)}</div>
</div>
)}
<div className="whitespace-nowrap text-base font-semibold text-neutral-800 dark:text-neutral-200 sm:text-lg">
{runs.toLocaleString()} runs
</div>

View File

@@ -3,6 +3,7 @@
import * as React from "react";
import Image from "next/image";
import { IconStarFilled, IconMore } from "@/components/ui/icons";
import { useFeatureFlag } from "@/hooks/useFeatureFlag";
import { Status, StatusType } from "./Status";
import { StoreSubmissionRequest } from "@/lib/autogpt-server-api";
@@ -47,6 +48,7 @@ export const AgentTableCard: React.FC<AgentTableCardProps> = ({
categories: [],
});
};
const showRatings = useFeatureFlag("marketplace-agent-ratings");
return (
<div className="border-b border-neutral-300 p-4 dark:border-neutral-700">
@@ -83,12 +85,14 @@ export const AgentTableCard: React.FC<AgentTableCardProps> = ({
<div className="text-sm text-neutral-600 dark:text-neutral-400">
{runs.toLocaleString()} runs
</div>
<div className="flex items-center gap-1">
<span className="text-sm font-medium text-neutral-800 dark:text-neutral-200">
{rating.toFixed(1)}
</span>
<IconStarFilled className="h-4 w-4 text-neutral-800 dark:text-neutral-200" />
</div>
{showRatings && (
<div className="flex items-center gap-1">
<span className="text-sm font-medium text-neutral-800 dark:text-neutral-200">
{rating.toFixed(1)}
</span>
<IconStarFilled className="h-4 w-4 text-neutral-800 dark:text-neutral-200" />
</div>
)}
</div>
</div>
);

View File

@@ -3,6 +3,7 @@
import * as React from "react";
import Image from "next/image";
import { IconStarFilled, IconMore, IconEdit } from "@/components/ui/icons";
import { useFeatureFlag } from "@/hooks/useFeatureFlag";
import { Status, StatusType } from "./Status";
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
import { TrashIcon } from "@radix-ui/react-icons";
@@ -46,6 +47,7 @@ export const AgentTableRow: React.FC<AgentTableRowProps> = ({
}) => {
// Create a unique ID for the checkbox
const checkboxId = `agent-${id}-checkbox`;
const showRatings = useFeatureFlag("marketplace-agent-ratings");
const handleEdit = React.useCallback(() => {
onEditSubmission({
@@ -138,7 +140,7 @@ export const AgentTableRow: React.FC<AgentTableRowProps> = ({
{/* Reviews column */}
<div className="text-right">
{rating ? (
{showRatings && rating ? (
<div className="flex items-center justify-end gap-1">
<span className="text-sm font-medium text-neutral-800 dark:text-neutral-200">
{rating.toFixed(1)}
@@ -147,7 +149,7 @@ export const AgentTableRow: React.FC<AgentTableRowProps> = ({
</div>
) : (
<span className="text-sm text-neutral-600 dark:text-neutral-400">
No reviews
{showRatings ? "No reviews" : ""}
</span>
)}
</div>

View File

@@ -1,6 +1,7 @@
import * as React from "react";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { StarRatingIcons } from "@/components/ui/icons";
import { useFeatureFlag } from "@/hooks/useFeatureFlag";
interface CreatorInfoCardProps {
username: string;
@@ -19,6 +20,7 @@ export const CreatorInfoCard: React.FC<CreatorInfoCardProps> = ({
averageRating,
totalRuns,
}) => {
const showRatings = useFeatureFlag("marketplace-agent-ratings");
return (
<div
className="inline-flex h-auto min-h-[500px] w-full max-w-[440px] flex-col items-start justify-between rounded-[26px] bg-violet-100 p-4 dark:bg-violet-900 sm:h-[632px] sm:w-[440px] sm:p-6"
@@ -80,23 +82,25 @@ export const CreatorInfoCard: React.FC<CreatorInfoCardProps> = ({
<div className="flex w-full flex-col items-start justify-start gap-3">
<div className="h-px w-full bg-neutral-700 dark:bg-neutral-300" />
<div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row sm:gap-0">
<div className="flex w-full flex-col items-start justify-start gap-2.5 sm:w-[164px]">
<div className="w-full text-base font-medium leading-normal text-neutral-800 dark:text-neutral-200">
Average rating
</div>
<div className="inline-flex items-center gap-2">
<div className="text-[18px] font-semibold leading-[28px] text-neutral-800 dark:text-neutral-200">
{averageRating.toFixed(1)}
{showRatings && (
<div className="flex w-full flex-col items-start justify-start gap-2.5 sm:w-[164px]">
<div className="w-full text-base font-medium leading-normal text-neutral-800 dark:text-neutral-200">
Average rating
</div>
<div
className="flex items-center gap-px"
role="img"
aria-label={`Rating: ${averageRating} out of 5 stars`}
>
{StarRatingIcons(averageRating)}
<div className="inline-flex items-center gap-2">
<div className="text-[18px] font-semibold leading-[28px] text-neutral-800 dark:text-neutral-200">
{averageRating.toFixed(1)}
</div>
<div
className="flex items-center gap-px"
role="img"
aria-label={`Rating: ${averageRating} out of 5 stars`}
>
{StarRatingIcons(averageRating)}
</div>
</div>
</div>
</div>
)}
<div className="flex w-full flex-col items-start justify-start gap-2.5 sm:w-[164px]">
<div className="w-full text-base font-medium leading-normal text-neutral-800 dark:text-neutral-200">
Number of runs

View File

@@ -1,5 +1,6 @@
import Image from "next/image";
import { StarRatingIcons } from "@/components/ui/icons";
import { useFeatureFlag } from "@/hooks/useFeatureFlag";
import {
Card,
CardContent,
@@ -21,6 +22,7 @@ export const FeaturedAgentCard: React.FC<FeaturedStoreCardProps> = ({
backgroundColor,
}) => {
const [isHovered, setIsHovered] = useState(false);
const showRatings = useFeatureFlag("marketplace-agent-ratings");
return (
<Card
@@ -63,10 +65,12 @@ export const FeaturedAgentCard: React.FC<FeaturedStoreCardProps> = ({
<div className="font-semibold">
{agent.runs?.toLocaleString() ?? "0"} runs
</div>
<div className="flex items-center gap-1.5">
<p>{agent.rating.toFixed(1) ?? "0.0"}</p>
{StarRatingIcons(agent.rating)}
</div>
{showRatings && (
<div className="flex items-center gap-1.5">
<p>{agent.rating.toFixed(1) ?? "0.0"}</p>
{StarRatingIcons(agent.rating)}
</div>
)}
</CardFooter>
</Card>
);

View File

@@ -2,6 +2,7 @@ import * as React from "react";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import Image from "next/image";
import { StarRatingIcons } from "@/components/ui/icons";
import { useFeatureFlag } from "@/hooks/useFeatureFlag";
interface StoreCardProps {
agentName: string;
@@ -26,6 +27,7 @@ export const StoreCard: React.FC<StoreCardProps> = ({
hideAvatar = false,
creatorName,
}) => {
const showRatings = useFeatureFlag("marketplace-agent-ratings");
const handleClick = () => {
onClick();
};
@@ -101,18 +103,20 @@ export const StoreCard: React.FC<StoreCardProps> = ({
<div className="text-lg font-semibold text-neutral-800 dark:text-neutral-200">
{runs.toLocaleString()} runs
</div>
<div className="flex items-center gap-2">
<span className="text-lg font-semibold text-neutral-800 dark:text-neutral-200">
{rating.toFixed(1)}
</span>
<div
className="inline-flex items-center"
role="img"
aria-label={`Rating: ${rating.toFixed(1)} out of 5 stars`}
>
{StarRatingIcons(rating)}
{showRatings && (
<div className="flex items-center gap-2">
<span className="text-lg font-semibold text-neutral-800 dark:text-neutral-200">
{rating.toFixed(1)}
</span>
<div
className="inline-flex items-center"
role="img"
aria-label={`Rating: ${rating.toFixed(1)} out of 5 stars`}
>
{StarRatingIcons(rating)}
</div>
</div>
</div>
)}
</div>
</div>
</div>

View File

@@ -0,0 +1,9 @@
import { useFlags } from "launchdarkly-react-client-sdk";
export function useFeatureFlag(flagKey: string): boolean {
const flags = useFlags();
if (flags && flagKey in flags) {
return Boolean((flags as Record<string, boolean>)[flagKey]);
}
return false;
}