mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
refactor(platform): simplify waitlist code and remove type duplication
- Backend: Extract _waitlist_to_store_entry helper to reduce duplication - Backend: Use dict comprehension in update_waitlist_admin for cleaner code - Frontend: Import types directly from shared types file instead of re-exporting - Frontend: Remove redundant isMember check in WaitlistCard handleJoinClick Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1982,6 +1982,23 @@ async def get_agent_as_admin(
|
||||
return graph
|
||||
|
||||
|
||||
def _waitlist_to_store_entry(
|
||||
waitlist: prisma.models.WaitlistEntry,
|
||||
) -> store_model.StoreWaitlistEntry:
|
||||
"""Convert a WaitlistEntry to StoreWaitlistEntry for public display."""
|
||||
return store_model.StoreWaitlistEntry(
|
||||
waitlist_id=waitlist.id,
|
||||
slug=waitlist.slug,
|
||||
name=waitlist.name,
|
||||
subHeading=waitlist.subHeading,
|
||||
videoUrl=waitlist.videoUrl,
|
||||
agentOutputDemoUrl=waitlist.agentOutputDemoUrl,
|
||||
imageUrls=waitlist.imageUrls or [],
|
||||
description=waitlist.description,
|
||||
categories=waitlist.categories,
|
||||
)
|
||||
|
||||
|
||||
async def get_waitlist() -> list[store_model.StoreWaitlistEntry]:
|
||||
"""Get all active waitlists for public display."""
|
||||
try:
|
||||
@@ -1997,20 +2014,7 @@ async def get_waitlist() -> list[store_model.StoreWaitlistEntry]:
|
||||
active_waitlists = [w for w in waitlists if w.status not in excluded_statuses]
|
||||
sorted_list = sorted(active_waitlists, key=lambda x: x.votes, reverse=True)
|
||||
|
||||
return [
|
||||
store_model.StoreWaitlistEntry(
|
||||
waitlist_id=waitlist.id,
|
||||
slug=waitlist.slug,
|
||||
name=waitlist.name,
|
||||
subHeading=waitlist.subHeading,
|
||||
videoUrl=waitlist.videoUrl,
|
||||
agentOutputDemoUrl=waitlist.agentOutputDemoUrl,
|
||||
imageUrls=waitlist.imageUrls or [],
|
||||
description=waitlist.description,
|
||||
categories=waitlist.categories,
|
||||
)
|
||||
for waitlist in sorted_list
|
||||
]
|
||||
return [_waitlist_to_store_entry(w) for w in sorted_list]
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching waitlists: {e}")
|
||||
raise DatabaseError("Failed to fetch waitlists") from e
|
||||
@@ -2100,17 +2104,7 @@ async def add_user_to_waitlist(
|
||||
else:
|
||||
logger.debug(f"Email {email} already on waitlist {waitlist_id}")
|
||||
|
||||
return store_model.StoreWaitlistEntry(
|
||||
waitlist_id=waitlist.id,
|
||||
slug=waitlist.slug,
|
||||
name=waitlist.name,
|
||||
subHeading=waitlist.subHeading,
|
||||
videoUrl=waitlist.videoUrl,
|
||||
agentOutputDemoUrl=waitlist.agentOutputDemoUrl,
|
||||
imageUrls=waitlist.imageUrls or [],
|
||||
description=waitlist.description,
|
||||
categories=waitlist.categories,
|
||||
)
|
||||
return _waitlist_to_store_entry(waitlist)
|
||||
|
||||
except ValueError:
|
||||
raise
|
||||
@@ -2232,28 +2226,24 @@ async def update_waitlist_admin(
|
||||
|
||||
try:
|
||||
# Build update data from non-None fields
|
||||
update_data: dict[str, typing.Any] = {}
|
||||
field_mappings = {
|
||||
"name": data.name,
|
||||
"slug": data.slug,
|
||||
"subHeading": data.subHeading,
|
||||
"description": data.description,
|
||||
"categories": data.categories,
|
||||
"imageUrls": data.imageUrls,
|
||||
"videoUrl": data.videoUrl,
|
||||
"agentOutputDemoUrl": data.agentOutputDemoUrl,
|
||||
"storeListingId": data.storeListingId,
|
||||
}
|
||||
update_data: dict[str, typing.Any] = {
|
||||
k: v for k, v in field_mappings.items() if v is not None
|
||||
}
|
||||
|
||||
if data.name is not None:
|
||||
update_data["name"] = data.name
|
||||
if data.slug is not None:
|
||||
update_data["slug"] = data.slug
|
||||
if data.subHeading is not None:
|
||||
update_data["subHeading"] = data.subHeading
|
||||
if data.description is not None:
|
||||
update_data["description"] = data.description
|
||||
if data.categories is not None:
|
||||
update_data["categories"] = data.categories
|
||||
if data.imageUrls is not None:
|
||||
update_data["imageUrls"] = data.imageUrls
|
||||
if data.videoUrl is not None:
|
||||
update_data["videoUrl"] = data.videoUrl
|
||||
if data.agentOutputDemoUrl is not None:
|
||||
update_data["agentOutputDemoUrl"] = data.agentOutputDemoUrl
|
||||
# Handle status separately due to enum conversion
|
||||
if data.status is not None:
|
||||
update_data["status"] = prisma.enums.WaitlistExternalStatus(data.status)
|
||||
if data.storeListingId is not None:
|
||||
update_data["storeListingId"] = data.storeListingId
|
||||
|
||||
if not update_data:
|
||||
# No updates, just return current data
|
||||
|
||||
@@ -2,67 +2,13 @@
|
||||
|
||||
import { revalidatePath } from "next/cache";
|
||||
import BackendAPI from "@/lib/autogpt-server-api";
|
||||
|
||||
export type WaitlistAdminResponse = {
|
||||
id: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
slug: string;
|
||||
name: string;
|
||||
subHeading: string;
|
||||
description: string;
|
||||
categories: string[];
|
||||
imageUrls: string[];
|
||||
videoUrl: string | null;
|
||||
agentOutputDemoUrl: string | null;
|
||||
status: string;
|
||||
votes: number;
|
||||
signupCount: number;
|
||||
storeListingId: string | null;
|
||||
owningUserId: string;
|
||||
};
|
||||
|
||||
export type WaitlistAdminListResponse = {
|
||||
waitlists: WaitlistAdminResponse[];
|
||||
totalCount: number;
|
||||
};
|
||||
|
||||
export type WaitlistSignup = {
|
||||
type: "user" | "email";
|
||||
userId: string | null;
|
||||
email: string | null;
|
||||
username: string | null;
|
||||
};
|
||||
|
||||
export type WaitlistSignupListResponse = {
|
||||
waitlistId: string;
|
||||
signups: WaitlistSignup[];
|
||||
totalCount: number;
|
||||
};
|
||||
|
||||
export type WaitlistCreateRequest = {
|
||||
name: string;
|
||||
slug: string;
|
||||
subHeading: string;
|
||||
description: string;
|
||||
categories?: string[];
|
||||
imageUrls?: string[];
|
||||
videoUrl?: string | null;
|
||||
agentOutputDemoUrl?: string | null;
|
||||
};
|
||||
|
||||
export type WaitlistUpdateRequest = {
|
||||
name?: string;
|
||||
slug?: string;
|
||||
subHeading?: string;
|
||||
description?: string;
|
||||
categories?: string[];
|
||||
imageUrls?: string[];
|
||||
videoUrl?: string | null;
|
||||
agentOutputDemoUrl?: string | null;
|
||||
status?: string;
|
||||
storeListingId?: string | null;
|
||||
};
|
||||
import type {
|
||||
WaitlistAdminResponse,
|
||||
WaitlistAdminListResponse,
|
||||
WaitlistSignupListResponse,
|
||||
WaitlistCreateRequest,
|
||||
WaitlistUpdateRequest,
|
||||
} from "@/lib/autogpt-server-api/types";
|
||||
|
||||
export async function getWaitlistsAdmin(): Promise<WaitlistAdminListResponse> {
|
||||
const api = new BackendAPI();
|
||||
|
||||
@@ -20,11 +20,11 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/__legacy__/ui/select";
|
||||
import {
|
||||
updateWaitlist,
|
||||
type WaitlistAdminResponse,
|
||||
type WaitlistUpdateRequest,
|
||||
} from "../actions";
|
||||
import { updateWaitlist } from "../actions";
|
||||
import type {
|
||||
WaitlistAdminResponse,
|
||||
WaitlistUpdateRequest,
|
||||
} from "@/lib/autogpt-server-api/types";
|
||||
import { useToast } from "@/components/molecules/Toast/use-toast";
|
||||
|
||||
type EditWaitlistDialogProps = {
|
||||
|
||||
@@ -17,10 +17,8 @@ import {
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/__legacy__/ui/table";
|
||||
import {
|
||||
getWaitlistSignups,
|
||||
type WaitlistSignupListResponse,
|
||||
} from "../actions";
|
||||
import { getWaitlistSignups } from "../actions";
|
||||
import type { WaitlistSignupListResponse } from "@/lib/autogpt-server-api/types";
|
||||
import { useToast } from "@/components/molecules/Toast/use-toast";
|
||||
import { User, Mail, Download } from "lucide-react";
|
||||
|
||||
|
||||
@@ -10,11 +10,8 @@ import {
|
||||
TableRow,
|
||||
} from "@/components/__legacy__/ui/table";
|
||||
import { Button } from "@/components/atoms/Button/Button";
|
||||
import {
|
||||
getWaitlistsAdmin,
|
||||
deleteWaitlist,
|
||||
type WaitlistAdminResponse,
|
||||
} from "../actions";
|
||||
import { getWaitlistsAdmin, deleteWaitlist } from "../actions";
|
||||
import type { WaitlistAdminResponse } from "@/lib/autogpt-server-api/types";
|
||||
import { EditWaitlistDialog } from "./EditWaitlistDialog";
|
||||
import { WaitlistSignupsDialog } from "./WaitlistSignupsDialog";
|
||||
import { Trash2, Edit, Users, Link } from "lucide-react";
|
||||
|
||||
@@ -25,9 +25,7 @@ export function WaitlistCard({
|
||||
}: WaitlistCardProps) {
|
||||
function handleJoinClick(e: React.MouseEvent) {
|
||||
e.stopPropagation();
|
||||
if (!isMember) {
|
||||
onJoinClick(e);
|
||||
}
|
||||
onJoinClick(e);
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user