Skip to content

Commit 64482b4

Browse files
committed
Refactor API calls to use new query functions and update components accordingly
- Replaced direct server client calls with new query functions in ImagesPage, OverviewPage, PlaygroundPage, ProjectImagesPage, ProjectSettingsPage, ProjectsPage, ProfilePage, SecurityPage, TemplatesPage, and AuditPage. - Updated props in various components to use `data` instead of `initialData` for consistency. - Created new query functions for admin, images, projects, templates, billing, audits, and usage. - Adjusted types in API response handling to improve type safety and clarity. - Enhanced pagination and search capabilities in the new query functions.
1 parent 7dabdd3 commit 64482b4

53 files changed

Lines changed: 341 additions & 259 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/web/eslint.config.mjs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { defineConfig, globalIgnores } from "eslint/config";
21
import nextVitals from "eslint-config-next/core-web-vitals";
32
import nextTs from "eslint-config-next/typescript";
3+
import { defineConfig, globalIgnores } from "eslint/config";
44

55
const eslintConfig = defineConfig([
66
...nextVitals,
@@ -13,6 +13,14 @@ const eslintConfig = defineConfig([
1313
"build/**",
1414
"next-env.d.ts",
1515
]),
16+
{
17+
settings: {
18+
// Fix for ESLint 10+: eslint-plugin-react uses context.getFilename() (legacy API)
19+
// which was removed in ESLint 10 flat config. Declaring the version explicitly
20+
// prevents the plugin from trying to auto-detect it and failing.
21+
react: { version: "19" },
22+
},
23+
},
1624
]);
1725

1826
export default eslintConfig;
Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,13 @@
11
import type { ReactElement } from "react";
22
import { AdminImageList } from "@/components/features/admin";
3-
import { getServerClient } from "@/lib/api/server";
3+
import { getAdminImages } from "@/lib/api/queries";
44

55
interface PageProps {
66
searchParams: Promise<{ userId?: string; projectId?: string }>;
77
}
88

99
export default async function AdminImagesPage(props: PageProps): Promise<ReactElement> {
1010
const { userId, projectId } = await props.searchParams;
11-
const client = await getServerClient();
12-
const { data } = await client.api.admin.images.get({
13-
query: {
14-
page: 1,
15-
limit: 20,
16-
...(userId && { userId }),
17-
...(projectId && { projectId }),
18-
},
19-
});
20-
return <AdminImageList initialData={data} initialUserId={userId} initialProjectId={projectId} />;
11+
const data = await getAdminImages({ page: 1, limit: 20, userId, projectId });
12+
return <AdminImageList data={data} userId={userId} projectId={projectId} />;
2113
}

apps/web/src/app/(admin)/admin/layout.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,14 @@ import { Suspense, type PropsWithChildren, type ReactElement } from "react";
22
import { isAdminRole } from "@ogstack/shared";
33
import { redirect } from "next/navigation";
44
import { AppShell } from "@/components/layout/app-shell";
5-
import { getServerClient } from "@/lib/api/server";
5+
import { getCurrentUser } from "@/lib/api/queries";
66
import { ROUTES } from "@/lib/constants";
77
import { AuthProvider } from "@/providers/auth-provider";
88
import { ConfirmProvider } from "@/providers/confirm-provider";
99

10-
async function getUser() {
11-
const client = await getServerClient();
12-
const { data, error } = await client.api.users.me.get();
13-
if (error) return null;
14-
return data;
15-
}
16-
1710
async function AdminAuthenticatedShell(props: PropsWithChildren): Promise<ReactElement> {
1811
const { children } = props;
19-
const user = await getUser();
12+
const user = await getCurrentUser();
2013

2114
if (!user) {
2215
redirect(ROUTES.login);
@@ -27,7 +20,7 @@ async function AdminAuthenticatedShell(props: PropsWithChildren): Promise<ReactE
2720
}
2821

2922
return (
30-
<AuthProvider initialUser={user}>
23+
<AuthProvider user={user}>
3124
<AppShell variant="admin">{children}</AppShell>
3225
</AuthProvider>
3326
);
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import type { ReactElement } from "react";
22
import { notFound } from "next/navigation";
33
import { AdminOverview } from "@/components/features/admin";
4-
import { getServerClient } from "@/lib/api/server";
4+
import { getAdminStats } from "@/lib/api/queries";
55

66
export default async function AdminOverviewPage(): Promise<ReactElement> {
7-
const client = await getServerClient();
8-
const { data } = await client.api.admin.stats.get();
7+
const data = await getAdminStats();
98
if (!data) notFound();
109
return <AdminOverview stats={data} />;
1110
}

apps/web/src/app/(admin)/admin/users/[id]/page.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,15 @@ import {
99
AdminUserUsage,
1010
} from "@/components/features/admin";
1111
import { PageHeader } from "@/components/ui/layout/page-header";
12-
import { getServerClient } from "@/lib/api/server";
12+
import { getAdminUser } from "@/lib/api/queries";
1313

1414
interface PageProps {
1515
params: Promise<{ id: string }>;
1616
}
1717

1818
export default async function AdminUserDetailPage(props: PageProps): Promise<ReactElement> {
1919
const { id } = await props.params;
20-
const client = await getServerClient();
21-
const { data: user } = await client.api.admin.users({ id }).get();
20+
const user = await getAdminUser(id);
2221

2322
if (!user) notFound();
2423

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import type { ReactElement } from "react";
22
import { AdminUserList } from "@/components/features/admin";
3-
import { getServerClient } from "@/lib/api/server";
3+
import { getAdminUsers } from "@/lib/api/queries";
44

55
export default async function AdminUsersPage(): Promise<ReactElement> {
6-
const client = await getServerClient();
7-
const { data } = await client.api.admin.users.get({ query: { page: 1, limit: 20 } });
8-
return <AdminUserList initialData={data} />;
6+
const data = await getAdminUsers({ page: 1, limit: 20 });
7+
return <AdminUserList data={data} />;
98
}

apps/web/src/app/(auth)/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export default function AuthLayout(props: PropsWithChildren): ReactElement {
1010

1111
return (
1212
<QueryProvider>
13-
<AuthProvider initialUser={null}>
13+
<AuthProvider user={null}>
1414
{siteKey && (
1515
<Script
1616
src={`https://www.google.com/recaptcha/enterprise.js?render=${siteKey}`}

apps/web/src/app/(dashboard)/analytics/page.tsx

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { PeriodSummary } from "@/components/features/analytics/period-summary";
99
import { TemplateBreakdown } from "@/components/features/analytics/template-breakdown";
1010
import { TopProjects, type TopProject } from "@/components/features/analytics/top-projects";
1111
import { PageHeader } from "@/components/ui/layout/page-header";
12-
import { getServerClient } from "@/lib/api/server";
12+
import { getImages, getUsageDaily, getUsageHistory, getUsageStats } from "@/lib/api/queries";
1313
import type { ImageItem } from "@/types/api";
1414
import { formatPeriod } from "@/utils/formatters";
1515

@@ -80,23 +80,18 @@ export default async function AnalyticsPage(props: AnalyticsPageProps): Promise<
8080
const range = parseRange(params.range);
8181
const useDaily = range === "30d";
8282

83-
const client = await getServerClient();
84-
8583
const dateRange = rangeToDateRange(range);
8684

87-
const [usageRes, imagesRes, dailyRes, historyRes] = await Promise.all([
88-
client.api.usage.stats.get({ query: {} }),
89-
client.api.images.get({ query: { page: 1, limit: 100 } }),
90-
useDaily ? client.api.usage.daily.get({ query: dateRange }) : Promise.resolve({ data: null }),
91-
!useDaily
92-
? client.api.usage.history.get({ query: dateRange })
93-
: Promise.resolve({ data: null }),
85+
const [usage, imagesData, dailyData, historyData] = await Promise.all([
86+
getUsageStats(),
87+
getImages({ page: 1, limit: 100 }),
88+
useDaily ? getUsageDaily(dateRange) : Promise.resolve(null),
89+
!useDaily ? getUsageHistory(dateRange) : Promise.resolve(null),
9490
]);
9591

96-
const usage = usageRes.data;
97-
const images = imagesRes.data?.items ?? [];
98-
const daily = dailyRes.data ?? [];
99-
const history = historyRes.data ?? [];
92+
const images = imagesData?.items ?? [];
93+
const daily = dailyData ?? [];
94+
const history = historyData ?? [];
10095

10196
const points = useDaily
10297
? daily.map((d) => {
Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
import type { ReactElement } from "react";
22
import { ApiKeyList } from "@/components/features/api-keys/api-key-list";
3-
import { getServerClient } from "@/lib/api/server";
3+
import { getApiKeys, getProjects } from "@/lib/api/queries";
44

55
export default async function ApiKeysPage(): Promise<ReactElement> {
6-
const client = await getServerClient();
7-
8-
const [projectsRes, keysRes] = await Promise.all([
9-
client.api.projects.get({ query: { page: 1, limit: 100 } }),
10-
client.api.keys.get({ query: {} }),
6+
const [projectsData, keys] = await Promise.all([
7+
getProjects({ page: 1, limit: 100 }),
8+
getApiKeys(),
119
]);
1210

13-
return <ApiKeyList projects={projectsRes.data?.items ?? []} initialData={keysRes.data ?? null} />;
11+
return <ApiKeyList projects={projectsData?.items ?? []} data={keys ?? null} />;
1412
}

apps/web/src/app/(dashboard)/audits/[id]/page.tsx

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,22 @@ import { notFound } from "next/navigation";
44
import { AuditReport } from "@/components/features/audit";
55
import type { AuditViewer } from "@/components/features/audit/ai-recommendations";
66
import { PageHeader } from "@/components/ui/layout/page-header";
7-
import { getServerClient } from "@/lib/api/server";
7+
import { getAudit, getCurrentUser } from "@/lib/api/queries";
88

99
interface PageProps {
1010
params: Promise<{ id: string }>;
1111
}
1212

1313
export default async function DashboardAuditReportPage(props: PageProps): Promise<ReactElement> {
1414
const { id } = await props.params;
15-
const client = await getServerClient();
1615

17-
const [reportRes, userRes] = await Promise.all([
18-
client.api.audits({ id }).get(),
19-
client.api.users.me.get(),
20-
]);
16+
const [report, user] = await Promise.all([getAudit(id), getCurrentUser()]);
2117

22-
if (reportRes.error || !reportRes.data) {
18+
if (!report) {
2319
notFound();
2420
}
2521

26-
const report = reportRes.data;
27-
const viewer: AuditViewer = userRes.data ? "authenticated" : "anonymous";
22+
const viewer: AuditViewer = user ? "authenticated" : "anonymous";
2823

2924
return (
3025
<>

0 commit comments

Comments
 (0)