Skip to content
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ node_modules
.turbo
.next
.docusaurus
packages/shared-db/migrations
packages/shared-db/migrations
apps/app/src/routeTree.gen.ts
16 changes: 15 additions & 1 deletion apps/api/src/routes/api/feeds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import {
FeedWrappedResponseSchema,
UpdateFeedRequestSchema,
} from "@curatedotfun/types";
import { ForbiddenError, NotFoundError } from "@curatedotfun/utils";
import {
ConflictError,
ForbiddenError,
NotFoundError,
} from "@curatedotfun/utils";
import { zValidator } from "@hono/zod-validator";
import { Hono } from "hono";
import { z } from "zod";
Expand Down Expand Up @@ -84,6 +88,16 @@ feedsRoutes.post(
);
} catch (error) {
c.var.sp.getLogger().error({ error, accountId }, "Error creating feed");
if (error instanceof ConflictError) {
return c.json(
ApiErrorResponseSchema.parse({
statusCode: 409,
success: false,
error: { message: error.message },
}),
409,
);
}
return c.json(
ApiErrorResponseSchema.parse({
statusCode: 500,
Expand Down
39 changes: 39 additions & 0 deletions apps/api/src/routes/api/users.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { FeedService } from "@curatedotfun/core-services";
import {
ApiErrorResponseSchema,
CreateUserRequestSchema,
FeedsWrappedResponseSchema,
UpdateUserRequestSchema,
UserDeletedWrappedResponseSchema,
UserNearAccountIdParamSchema,
Expand Down Expand Up @@ -333,4 +335,41 @@ usersRoutes.get(
},
);

usersRoutes.get(
"/:nearAccountId/feeds",
zValidator("param", UserNearAccountIdParamSchema),
async (c) => {
const { nearAccountId } = c.req.valid("param");
const sp = c.var.sp;

try {
const feedService: FeedService = sp.getFeedService();
const feeds = await feedService.getFeedsByCreator(nearAccountId);

return c.json(
FeedsWrappedResponseSchema.parse({
statusCode: 200,
success: true,
data: feeds.map((feed) => ({
...feed,
config: feed.config,
})),
}),
);
} catch (error) {
c.var.sp
.getLogger()
.error({ error }, `Error fetching feeds for ${nearAccountId}`);
return c.json(
ApiErrorResponseSchema.parse({
statusCode: 500,
success: false,
error: { message: "Failed to fetch feeds" },
}),
500,
);
}
},
);

export { usersRoutes };
165 changes: 0 additions & 165 deletions apps/app/src/components/BasicInformationForm.tsx

This file was deleted.

22 changes: 22 additions & 0 deletions apps/app/src/components/Leaderboard.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from "react";
import { ChevronDown, ChevronUp } from "lucide-react";
import { LeaderboardEntry } from "../lib/api";
import { Container } from "./Container";
import { Hero } from "./Hero";
Expand Down Expand Up @@ -33,6 +34,8 @@ export default React.memo(function Leaderboard({
handleTimeDropdownToggle,
handleFeedDropdownClose,
handleTimeDropdownClose,
expandAllRows,
collapseAllRows,
feedDropdownRef,
timeDropdownRef,
table,
Expand Down Expand Up @@ -63,6 +66,25 @@ export default React.memo(function Leaderboard({
timeDropdownRef={timeDropdownRef}
/>

{hasData && (
<div className="flex justify-end gap-2 mb-4">
<button
onClick={expandAllRows}
className="flex items-center gap-1.5 px-3 py-2 text-sm border border-neutral-300 rounded-md bg-white hover:bg-neutral-50 transition-colors text-[#111111]"
>
<ChevronDown className="h-4 w-4" />
Expand All
</button>
<button
onClick={collapseAllRows}
className="flex items-center gap-1.5 px-3 py-2 text-sm border border-neutral-300 rounded-md bg-white hover:bg-neutral-50 transition-colors text-[#111111]"
>
<ChevronUp className="h-4 w-4" />
Collapse All
</button>
</div>
)}

<LeaderboardTable
table={table}
isLoading={isLoading}
Expand Down
2 changes: 1 addition & 1 deletion apps/app/src/components/UserMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export default function UserMenu({ className }: UserMenuProps) {
) : (
<ProfileImage size="small" />
)}
<p className="text-sm font-medium leading-6 hidden sm:block">
<p className="text-sm font-medium leading-6">
{getUserDisplayName()}
</p>
<ChevronDown
Expand Down
53 changes: 53 additions & 0 deletions apps/app/src/components/coming-soon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Clock, Sparkles } from "lucide-react";
import { Card } from "./ui/card";
import { Badge } from "./ui/badge";

interface ComingSoonProps {
title: string;
description?: string;
features?: string[];
}

export function ComingSoon({ title, description, features }: ComingSoonProps) {
return (
<Card className="p-6 space-y-6">
<div className="text-center space-y-4">
<div className="flex items-center justify-center space-x-2">
<Sparkles className="h-8 w-8" />
<h2 className="text-2xl font-semibold">{title}</h2>
</div>

<Badge
variant="secondary"
className="flex items-center space-x-1 w-fit mx-auto"
>
<Clock className="h-3 w-3" />
<span>Coming Soon</span>
</Badge>

{description && (
<p className="text-gray-600 dark:text-gray-400 max-w-md mx-auto">
{description}
</p>
)}
</div>

{features && features.length > 0 && (
<div className="space-y-3">
<h3 className="text-lg font-medium text-center">What to expect:</h3>
<ul className="space-y-2 max-w-md mx-auto">
{features.map((feature, index) => (
<li
key={index}
className="flex items-center space-x-2 text-sm text-gray-600 dark:text-gray-400"
>
<div className="w-1.5 h-1.5 bg-blue-500 rounded-full flex-shrink-0" />
<span>{feature}</span>
</li>
))}
</ul>
</div>
)}
</Card>
);
}
Loading