diff --git a/app/fund/dashboard/FunderDashboardContent.tsx b/app/fund/dashboard/FunderDashboardContent.tsx
new file mode 100644
index 000000000..60d4e159b
--- /dev/null
+++ b/app/fund/dashboard/FunderDashboardContent.tsx
@@ -0,0 +1,33 @@
+'use client';
+
+import { useEffect } from 'react';
+import { useRouter } from 'next/navigation';
+import { FundsGiven } from '@/components/Funding/dashboard/FundsGiven';
+import { useUser } from '@/contexts/UserContext';
+
+export function FunderDashboardContent() {
+ const router = useRouter();
+ const { user, isLoading: isLoadingUser } = useUser();
+
+ useEffect(() => {
+ if (!isLoadingUser && !user) {
+ router.replace('/');
+ }
+ }, [isLoadingUser, router, user]);
+
+ if (isLoadingUser || !user) return null;
+
+ const firstName = user.firstName?.trim();
+
+ return (
+ <>
+
+
+ {firstName ? `Welcome back, ${firstName}.` : 'Welcome back.'}
+
+
Here's where your funding stands today.
+
+
+ >
+ );
+}
diff --git a/app/fund/dashboard/page.tsx b/app/fund/dashboard/page.tsx
index 1793f01c0..a2c325435 100644
--- a/app/fund/dashboard/page.tsx
+++ b/app/fund/dashboard/page.tsx
@@ -1,7 +1,7 @@
import { Metadata } from 'next';
import { PageLayout } from '@/app/layouts/PageLayout';
-import { FunderDashboardPage } from '@/components/Funding/dashboard/FunderDashboardPage';
import { buildOpenGraphMetadata } from '@/lib/metadata';
+import { FunderDashboardContent } from './FunderDashboardContent';
export const metadata: Metadata = buildOpenGraphMetadata({
title: 'Funder Dashboard',
@@ -11,8 +11,8 @@ export const metadata: Metadata = buildOpenGraphMetadata({
export default function FunderDashboardRoute() {
return (
-
-
+
+
);
}
diff --git a/app/my-funding/components/FundsReceivedTab.tsx b/app/my-funding/components/FundsReceived.tsx
similarity index 97%
rename from app/my-funding/components/FundsReceivedTab.tsx
rename to app/my-funding/components/FundsReceived.tsx
index 3f87597a8..0e8dee0fe 100644
--- a/app/my-funding/components/FundsReceivedTab.tsx
+++ b/app/my-funding/components/FundsReceived.tsx
@@ -14,7 +14,7 @@ import { transformContributionToFeedEntry } from '@/types/contribution';
import type { FeedEntry } from '@/types/feed';
import { cn } from '@/utils/styles';
-interface FundsReceivedTabProps {
+interface FundsReceivedProps {
userId: number;
authorId?: number;
}
@@ -164,7 +164,7 @@ function PeerReviews({ authorId }: Readonly<{ authorId?: number }>) {
);
}
-export function FundsReceivedTab({ userId, authorId }: Readonly) {
+export function FundsReceived({ userId, authorId }: Readonly) {
const router = useRouter();
const browsePeerReviewBounties = () => {
diff --git a/app/my-funding/components/MyFundingPage.tsx b/app/my-funding/components/MyFundingPage.tsx
index 5d2d722bd..c04adf83c 100644
--- a/app/my-funding/components/MyFundingPage.tsx
+++ b/app/my-funding/components/MyFundingPage.tsx
@@ -4,11 +4,11 @@ import { useEffect, type ReactNode } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { ArrowDownLeft, ArrowUpRight } from 'lucide-react';
import { PageLayout } from '@/app/layouts/PageLayout';
-import { FunderDashboardPage } from '@/components/Funding/dashboard/FunderDashboardPage';
+import { FundsGiven } from '@/components/Funding/dashboard/FundsGiven';
import { Icon } from '@/components/ui/icons/Icon';
import { Tabs } from '@/components/ui/Tabs';
import { useUser } from '@/contexts/UserContext';
-import { FundsReceivedTab } from './FundsReceivedTab';
+import { FundsReceived } from './FundsReceived';
type MyFundingTab = 'given' | 'received';
@@ -121,8 +121,9 @@ export function MyFundingPage() {
const searchParams = useSearchParams();
const { user, isLoading: isLoadingUser } = useUser();
const activeTab = resolveMyFundingTab(searchParams.get('tab'));
+ const isModerator = !!user?.isModerator;
const hasModeratorOverrideOnReceivedTab =
- activeTab === 'received' && user?.isModerator === true && searchParams.has('funder_id');
+ activeTab === 'received' && isModerator && searchParams.has('funder_id');
useEffect(() => {
if (isLoadingUser) return;
@@ -153,9 +154,9 @@ export function MyFundingPage() {
return (
}>
{activeTab === 'given' ? (
-
+
) : (
-
+
)}
);
diff --git a/components/Funding/dashboard/FunderDashboardPage.tsx b/components/Funding/dashboard/FundsGiven.tsx
similarity index 65%
rename from components/Funding/dashboard/FunderDashboardPage.tsx
rename to components/Funding/dashboard/FundsGiven.tsx
index f2d598e38..b5f89d615 100644
--- a/components/Funding/dashboard/FunderDashboardPage.tsx
+++ b/components/Funding/dashboard/FundsGiven.tsx
@@ -1,6 +1,6 @@
'use client';
-import { FC, useCallback, useEffect, useMemo, useState } from 'react';
+import { useCallback, useEffect, useMemo, useState, type ReactNode } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { Plus } from 'lucide-react';
import { Button } from '@/components/ui/Button';
@@ -10,39 +10,30 @@ import { FundedProposalsSection } from '@/components/Funding/dashboard/FundedPro
import { FeedContent } from '@/components/Feed/FeedContent';
import { FunderService } from '@/services/funder.service';
import { useFeed } from '@/hooks/useFeed';
-import { useUser } from '@/contexts/UserContext';
import { FunderOverview } from '@/types/funder';
import {
SearchableUserSingleSelect,
UserOption,
} from '@/components/ui/form/SearchableUserSingleSelect';
-function parseFunderIdParam(raw: string | null): number | undefined {
- if (!raw) return undefined;
- const n = Number(raw);
- return Number.isFinite(n) && n > 0 ? n : undefined;
+function parseFunderIdParam(funderIdParam: string | null): number | undefined {
+ if (!funderIdParam) return undefined;
+ const funderId = Number(funderIdParam);
+ return Number.isFinite(funderId) && funderId > 0 ? funderId : undefined;
}
-interface FunderDashboardPageProps {
- embedded?: boolean;
+interface FundsGivenProps {
+ userId: number;
+ isModerator: boolean;
}
-export const FunderDashboardPage: FC = ({ embedded = false }) => {
+export function FundsGiven({ userId, isModerator }: Readonly) {
const router = useRouter();
const searchParams = useSearchParams();
- const { user, isLoading: isLoadingUser } = useUser();
- const userId = user?.id;
- useEffect(() => {
- if (!isLoadingUser && !user) {
- router.replace('/');
- }
- }, [isLoadingUser, user, router]);
-
- const funderIdOverride = user?.isModerator
- ? parseFunderIdParam(searchParams.get('funder_id'))
- : undefined;
- const funderId = funderIdOverride ?? userId;
+ const funderId = isModerator
+ ? (parseFunderIdParam(searchParams.get('funder_id')) ?? userId)
+ : userId;
const [selectedUser, setSelectedUser] = useState(null);
@@ -67,13 +58,7 @@ export const FunderDashboardPage: FC = ({ embedded = f
() => ({
endpoint: 'grant_feed' as const,
contentType: 'GRANT',
- // The override `funderId` is resolved at the call site and passed in
- // as `created_by` so we don't have to duplicate the override logic in
- // the lower-level services.
createdBy: funderId,
- // Defer the initial fetch until funderId is known so we don't fire a
- // first request without `created_by` and a second with it.
- enabled: funderId != null,
}),
[funderId]
);
@@ -86,7 +71,6 @@ export const FunderDashboardPage: FC = ({ embedded = f
} = useFeed('all', grantFeedOptions);
useEffect(() => {
- if (isLoadingUser || !user) return;
let cancelled = false;
setIsLoadingOverview(true);
FunderService.getFundingOverview(funderId)
@@ -102,19 +86,22 @@ export const FunderDashboardPage: FC = ({ embedded = f
return () => {
cancelled = true;
};
- }, [funderId, isLoadingUser, user]);
+ }, [funderId]);
- if (isLoadingUser || !user) return null;
-
- const firstName = user.firstName?.trim();
+ let overviewContent: ReactNode = null;
+ if (isLoadingOverview) {
+ overviewContent = (
+
+ );
+ } else if (overview) {
+ overviewContent = ;
+ }
return (
-
- {user.isModerator && (
+ <>
+ {isModerator && (
-
+
View as user (moderator only)
= ({ embedded = f
)}
- {!embedded && (
-
-
- {firstName ? `Welcome back, ${firstName}.` : 'Welcome back.'}
-
-
Here's where your funding stands today.
-
- )}
-
- {isLoadingOverview ? (
-
- ) : overview ? (
-
- ) : null}
+ {overviewContent}
- {funderId &&
}
+
@@ -194,6 +168,6 @@ export const FunderDashboardPage: FC = ({ embedded = f
{overview && (
)}
-
+ >
);
-};
+}