Skip to content
2 changes: 1 addition & 1 deletion apps/backend/src/orders/order.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import { ManufacturerModule } from '../foodManufacturers/manufacturers.module';
import { DonationItemsModule } from '../donationItems/donationItems.module';
import { Allocation } from '../allocations/allocations.entity';
import { Donation } from '../donations/donations.entity';
import { PantriesModule } from '../pantries/pantries.module';
import { EmailsModule } from '../emails/email.module';
import { User } from '../users/users.entity';
import { UsersModule } from '../users/users.module';
import { PantriesModule } from '../pantries/pantries.module';

@Module({
imports: [
Expand Down
176 changes: 95 additions & 81 deletions apps/frontend/src/containers/adminDashboard.tsx
Comment thread
Yurika-Kan marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
import React, { useEffect, useState } from 'react';
import ApiClient from '@api/apiClient';
import { Box, Heading, Text } from '@chakra-ui/react';
import DashboardCard, {
ORDER_STATUS_BADGE,
DashboardCardType,
DONATION_STATUS_BADGE,
ORDER_STATUS_BADGE,
} from '@components/dashboardCard';
import { FloatingAlert } from '@components/floatingAlert';
import PageEmptyState from '@components/pageEmptyState';
import SectionEmptyState from '@components/sectionEmptyState';
import { DashboardStats } from '@components/dashboardStats';
import React, { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAlert } from '../hooks/alert';
import { ROUTES } from '../routes';
import {
PendingApplication,
OrderSummary,
AlertStatus,
Donation,
OrderSummary,
PendingApplication,
User,
AlertStatus,
} from '../types/types';
import { DashboardCardType } from '@components/dashboardCard';
import ApiClient from '@api/apiClient';
import { useAlert } from '../hooks/alert';
import { FloatingAlert } from '@components/floatingAlert';
import { useNavigate } from 'react-router-dom';
import { ROUTES } from '../routes';
import SectionEmptyState from '@components/sectionEmptyState';
import PageEmptyState from '@components/pageEmptyState';
import { DashboardStats } from '@components/dashboardStats';

const AdminDashboard: React.FC = () => {
const navigate = useNavigate();

const [alertState, setAlertMessage] = useAlert();
const [loading, setLoading] = useState(true);
const [pendingApplications, setPendingApplications] = useState<
PendingApplication[]
>([]);
Expand All @@ -33,72 +34,85 @@ const AdminDashboard: React.FC = () => {
const [currentUser, setCurrentUser] = useState<User | null>(null);
const [stats, setStats] = useState<Record<string, string> | null>(null);

const fetchPendingApplications = async () => {
try {
const pendingApplications =
await ApiClient.getRecentPendingApplications();
setPendingApplications(pendingApplications);
} catch {
setAlertMessage('Error fetching pending applications', AlertStatus.ERROR);
}
};

const fetchRecentOrders = async () => {
try {
const allOrders = await ApiClient.getAllOrders();
const sortedOrders = allOrders.sort(
(a: OrderSummary, b: OrderSummary) =>
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
);
const recentOrders = sortedOrders.slice(0, 2);
setRecentOrders(recentOrders);
} catch {
setAlertMessage('Error fetching orders', AlertStatus.ERROR);
}
};

const fetchRecentDonations = async () => {
try {
const allDonations = await ApiClient.getAllDonations();
const sortedDonations = allDonations.sort(
(a: Donation, b: Donation) =>
new Date(b.dateDonated).getTime() - new Date(a.dateDonated).getTime(),
);
const recentDonations = sortedDonations.slice(0, 2);
setRecentDonations(recentDonations);
} catch {
setAlertMessage('Error fetching donations', AlertStatus.ERROR);
}
};

const fetchMe = async () => {
let user: User;
try {
user = await ApiClient.getMe();
setCurrentUser(user);
} catch {
setAlertMessage(
'Authentication error. Please log in and try again.',
AlertStatus.ERROR,
);
return;
}

try {
const userStats = await ApiClient.getUserStats(user.id);
setStats(userStats);
} catch {
setAlertMessage('Error fetching dashboard statistics', AlertStatus.ERROR);
}
};

useEffect(() => {
fetchMe();
fetchRecentDonations();
fetchRecentOrders();
fetchPendingApplications();
const fetchMe = async () => {
let user: User;
try {
user = await ApiClient.getMe();
setCurrentUser(user);
} catch {
setAlertMessage('Error fetching user data', AlertStatus.ERROR);
return;
}

try {
const userStats = await ApiClient.getUserStats(user.id);
setStats(userStats);
} catch {
setAlertMessage(
'Error fetching dashboard statistics',
AlertStatus.ERROR,
);
}
};

const fetchPendingApplications = async () => {
try {
const applications = await ApiClient.getRecentPendingApplications();
setPendingApplications(applications);
} catch {
setAlertMessage(
'Error fetching pending applications',
AlertStatus.ERROR,
);
}
};

const fetchRecentOrders = async () => {
try {
const allOrders = await ApiClient.getAllOrders();
const sortedOrders = allOrders.sort(
(a: OrderSummary, b: OrderSummary) =>
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),
);
setRecentOrders(sortedOrders.slice(0, 2));
} catch {
setAlertMessage('Error fetching recent orders', AlertStatus.ERROR);
}
};

const fetchRecentDonations = async () => {
try {
const allDonations = await ApiClient.getAllDonations();
const sortedDonations = allDonations.sort(
(a: Donation, b: Donation) =>
new Date(b.dateDonated).getTime() -
new Date(a.dateDonated).getTime(),
);
setRecentDonations(sortedDonations.slice(0, 2));
} catch {
setAlertMessage('Error fetching recent donations', AlertStatus.ERROR);
}
};

const load = async () => {
try {
await Promise.all([
fetchMe(),
fetchPendingApplications(),
fetchRecentOrders(),
fetchRecentDonations(),
]);
} finally {
setLoading(false);
}
};

load();
}, [setAlertMessage]);

if (loading) return null;

const isPageEmpty =
Comment thread
jxuistrying marked this conversation as resolved.
pendingApplications.length === 0 &&
recentOrders.length === 0 &&
Expand All @@ -122,7 +136,7 @@ const AdminDashboard: React.FC = () => {

{isPageEmpty ? (
<PageEmptyState
subtitle="You have no orders or applications to review at this time."
entity="orders or applications to review"
primaryButtonText="View Pantries"
primaryButtonLink={ROUTES.PANTRY_MANAGEMENT}
secondaryButtonText="View Donations"
Expand All @@ -135,7 +149,7 @@ const AdminDashboard: React.FC = () => {
</Text>
{pendingApplications.length === 0 ? (
<Box mb={16}>
<SectionEmptyState subtitle="You have no pending applications at this time" />
<SectionEmptyState entity="pending applications" />
</Box>
) : (
<Box
Expand Down Expand Up @@ -182,7 +196,7 @@ const AdminDashboard: React.FC = () => {
</Text>
{recentOrders.length === 0 ? (
<Box mb={16}>
<SectionEmptyState subtitle="You have no recent orders at this time" />
<SectionEmptyState entity="recent orders" />
</Box>
) : (
<Box
Expand Down Expand Up @@ -218,7 +232,7 @@ const AdminDashboard: React.FC = () => {
</Text>
{recentDonations.length === 0 ? (
<Box mb={16}>
<SectionEmptyState subtitle="You have no recent donations at this time" />
<SectionEmptyState entity="recent donations" />
</Box>
) : (
<Box
Expand Down
52 changes: 24 additions & 28 deletions apps/frontend/src/containers/foodManufacturerDashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import React, { useEffect, useState } from 'react';
import ApiClient from '@api/apiClient';
import { Box, Heading, Text } from '@chakra-ui/react';
import DashboardCard, { DashboardCardType } from '@components/dashboardCard';
import { FloatingAlert } from '@components/floatingAlert';
import PageEmptyState from '@components/pageEmptyState';
import SectionEmptyState from '@components/sectionEmptyState';
import { DashboardStats } from '@components/dashboardStats';
import React, { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAlert } from '../hooks/alert';
import { ROUTES } from '../routes';
import {
AlertStatus,
Donation,
Expand All @@ -9,22 +17,14 @@ import {
FoodManufacturer,
User,
} from '../types/types';
import ApiClient from '@api/apiClient';
import { useAlert } from '../hooks/alert';
import { FloatingAlert } from '@components/floatingAlert';
import { useNavigate } from 'react-router-dom';
import { ROUTES } from '../routes';
import SectionEmptyState from '@components/sectionEmptyState';
import PageEmptyState from '@components/pageEmptyState';
import { DashboardStats } from '@components/dashboardStats';

const FoodManufacturerDashboard: React.FC = () => {
const navigate = useNavigate();

const [alertState, setAlertMessage] = useAlert();
const [errorAlertState, setErrorMessage] = useAlert();
const [loading, setLoading] = useState(true);
const [foodManufacturer, setFoodManufacturer] =
useState<FoodManufacturer | null>(null);
const [user, setUser] = useState<User | null>(null);
const [upcomingReminders, setUpcomingReminders] = useState<
DonationReminderDto[]
>([]);
Expand All @@ -33,28 +33,24 @@ const FoodManufacturerDashboard: React.FC = () => {

useEffect(() => {
const fetchFmData = async () => {
let fmId: number;
let currentUser: User;
try {
currentUser = await ApiClient.getMe();
setUser(currentUser);

fmId = await ApiClient.getCurrentUserFoodManufacturerId();
const fmId = await ApiClient.getCurrentUserFoodManufacturerId();
const fm = await ApiClient.getFoodManufacturer(fmId);
setFoodManufacturer(fm);
} catch {
setAlertMessage(
'Error fetching your manufacturer profile.',
AlertStatus.ERROR,
);
setErrorMessage('Error fetching dashboard data', AlertStatus.ERROR);
return;
} finally {
setLoading(false);
}

try {
const userStats = await ApiClient.getUserStats(currentUser.id);
setStats(userStats);
} catch {
setAlertMessage(
setErrorMessage(
'Error fetching dashboard statistics',
AlertStatus.ERROR,
);
Expand All @@ -68,7 +64,7 @@ const FoodManufacturerDashboard: React.FC = () => {
if (reminders.status === 'fulfilled') {
setUpcomingReminders(reminders.value);
} else {
setAlertMessage(
setErrorMessage(
'Error fetching upcoming donations.',
AlertStatus.ERROR,
);
Expand All @@ -85,24 +81,24 @@ const FoodManufacturerDashboard: React.FC = () => {
.slice(0, 2);
setRecentDonations(sorted);
} else {
setAlertMessage('Error fetching recent donations.', AlertStatus.ERROR);
setErrorMessage('Error fetching recent donations.', AlertStatus.ERROR);
}
};
fetchFmData();
}, [setAlertMessage]);
}, [setErrorMessage]);

if (!foodManufacturer) return null;
if (loading) return null;

const isPageEmpty =
upcomingReminders.length === 0 && recentDonations.length === 0;

return (
<Box p={12}>
{alertState?.status === AlertStatus.ERROR && (
{errorAlertState && (
<FloatingAlert
key={alertState.id}
message={alertState.message}
status={alertState.status}
key={errorAlertState.id}
message={errorAlertState.message}
status={errorAlertState.status}
timeout={6000}
/>
)}
Expand Down
Loading
Loading