Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/frontend/src/components/dashboardCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const CARD_TYPE_ICON: Record<DashboardCardType, React.ReactNode> = {
const CARD_TYPE_DATE_LABEL: Record<DashboardCardType, string> = {
[DashboardCardType.ACTION]: 'Applied',
[DashboardCardType.ORDER]: 'Requested',
[DashboardCardType.UPCOMING_DONATION]: 'Scheduled',
[DashboardCardType.UPCOMING_DONATION]: 'Scheduled to send',
[DashboardCardType.RECENT_DONATION]: 'Donated',
[DashboardCardType.FOOD_REQUEST]: 'Requested',
};
Expand Down
15 changes: 14 additions & 1 deletion apps/frontend/src/components/foodRequestManagement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { capitalize, formatDate } from '@utils/utils';
import { FloatingAlert } from '@components/floatingAlert';
import { FoodRequestStatus, FoodRequestSummaryDto } from '../types/types';
import PageEmptyState from '@components/pageEmptyState';
import SectionEmptyState from '@components/sectionEmptyState';
import { PaginationControl } from '@components/pagination';
import RequestDetailsModal from '@components/forms/requestDetailsModal';
import PantryDeleteRequestActionModal from '@components/forms/pantryDeleteRequestModal';
Expand Down Expand Up @@ -56,15 +57,18 @@ const RequestManagement: React.FC<RequestManagementProps> = ({
useState<FoodRequestSummaryDto | null>(null);

const [alertState, setAlertMessage] = useAlert();
const [fetchFailed, setFetchFailed] = useState(false);

const navigate = useNavigate();
const location = useLocation();

const loadRequests = useCallback(async () => {
setFetchFailed(false);
try {
const data = await fetchData();
setRequests(data);
} catch {
setFetchFailed(true);
setAlertMessage('Error fetching requests', AlertStatus.ERROR);
}
}, [fetchData, setAlertMessage]);
Expand Down Expand Up @@ -172,7 +176,16 @@ const RequestManagement: React.FC<RequestManagementProps> = ({
timeout={6000}
/>
)}
{requests.length === 0 ? (
{fetchFailed ? (
<>
<SectionEmptyState subtitle="We couldn't load your food requests. Please try again." />
<Box display="flex" justifyContent="center">
<Button onClick={loadRequests} variant="outline">
Retry
</Button>
</Box>
</>
) : requests.length === 0 ? (
<PageEmptyState entity="food requests" />
) : (
<>
Expand Down
2 changes: 2 additions & 0 deletions apps/frontend/src/components/forms/addNewVolunteerModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ const NewVolunteerModal: React.FC<NewVolunteerModalProps> = ({

return (
<Dialog.Root
lazyMount
unmountOnExit
open={isOpen}
onOpenChange={(e: { open: boolean }) =>
e.open ? setIsOpen(true) : closeAndReset()
Expand Down
2 changes: 2 additions & 0 deletions apps/frontend/src/components/forms/assignVolunteersModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ const AssignVolunteersModal: React.FC<AssignVolunteersModalProps> = ({

return (
<Dialog.Root
lazyMount
unmountOnExit
size="md"
open={isOpen}
onOpenChange={(e: { open: boolean }) => {
Expand Down
11 changes: 10 additions & 1 deletion apps/frontend/src/components/forms/changePasswordModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const ChangePasswordModal: React.FC<ChangePasswordModalProps> = ({
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
const [showOldPassword, setShowOldPassword] = useState(false);
const [alertState, setAlertMessage] = useAlert();
const [isSaving, setIsSaving] = useState(false);

const handleChangePassword = async () => {
if (password.length < 8) {
Expand All @@ -52,6 +53,7 @@ const ChangePasswordModal: React.FC<ChangePasswordModalProps> = ({
return;
}

setIsSaving(true);
try {
await updatePassword({
oldPassword,
Expand All @@ -77,6 +79,8 @@ const ChangePasswordModal: React.FC<ChangePasswordModalProps> = ({
AlertStatus.ERROR,
);
}
} finally {
setIsSaving(false);
}
};

Expand All @@ -103,6 +107,8 @@ const ChangePasswordModal: React.FC<ChangePasswordModalProps> = ({

return (
<Dialog.Root
lazyMount
unmountOnExit
open={open}
onOpenChange={(e: { open: boolean }) => {
if (!e.open) {
Expand Down Expand Up @@ -221,7 +227,10 @@ const ChangePasswordModal: React.FC<ChangePasswordModalProps> = ({
textStyle="p2"
fontWeight={600}
mt={8}
disabled={!confirmPassword || !password || !oldPassword}
loading={isSaving}
disabled={
!confirmPassword || !password || !oldPassword || isSaving
}
>
Change Password
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ const CompleteRequiredActionsModal: React.FC<

return (
<Dialog.Root
lazyMount
unmountOnExit
open={isOpen}
size="md"
onOpenChange={(e: { open: boolean }) => {
Expand Down
2 changes: 2 additions & 0 deletions apps/frontend/src/components/forms/confirmActionModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ const ConfirmActionModal: React.FC<ConfirmActionModalProps> = ({

return (
<Dialog.Root
lazyMount
unmountOnExit
open={isOpen}
onOpenChange={(e: { open: boolean }) => !e.open && onClose()}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ const ConfirmFoodManufacturerDecisionModal: React.FC<
useModalBodyCleanup();
return (
<Dialog.Root
lazyMount
unmountOnExit
open={isOpen}
onOpenChange={(e: { open: boolean }) => !e.open && onClose()}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ const ConfirmPantryDecisionModal: React.FC<ConfirmPantryDecisionModalProps> = ({
useModalBodyCleanup();
return (
<Dialog.Root
lazyMount
unmountOnExit
open={isOpen}
onOpenChange={(e: { open: boolean }) => !e.open && onClose()}
>
Expand Down
2 changes: 2 additions & 0 deletions apps/frontend/src/components/forms/createNewOrderModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ const CreateNewOrderModal: React.FC<CreateNewOrderModalModalProps> = ({

return (
<Dialog.Root
lazyMount
unmountOnExit
open={isOpen}
size="md"
onOpenChange={(e: { open: boolean }) => {
Expand Down
2 changes: 2 additions & 0 deletions apps/frontend/src/components/forms/donationDetailsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ const DonationDetailsModal: React.FC<DonationDetailsModalProps> = ({

return (
<Dialog.Root
lazyMount
unmountOnExit
open={isOpen}
onOpenChange={(e: { open: boolean }) => {
if (!e.open) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ const EditableFMApplication: React.FC<EditableFMApplicationProps> = ({
AlertStatus.ERROR,
);
}
}, [foodManufacturerId]);
}, [foodManufacturerId, setAlertMessage]);

useEffect(() => {
// Fetch the application when we don't have one loaded already
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ const EditablePantryApplication: React.FC<EditablePantryApplicationProps> = ({
} finally {
setIsLoading(false);
}
}, []);
}, [setAlertMessage]);

useEffect(() => {
if (!initialApplication) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ interface FmCompleteRequiredActionsModalProps {
donation: DonationDetails;
isOpen: boolean;
onClose: () => void;
onSuccess: () => void;
onSuccess: (allOrdersComplete: boolean) => void;
}

interface OrderFormData {
Expand Down Expand Up @@ -160,16 +160,16 @@ const FmCompleteRequiredActionsModal: React.FC<
const [isSubmitting, setIsSubmitting] = useState(false);
const [alertState, setAlertMessage] = useAlert();

// True once every relevant item has both ozPerItem and estimatedValue filled in
// True once every relevant item has both ozPerItem and estimatedValue set to at least 0.01
const isSubmitEnabled = useMemo(
() =>
donation.relevantDonationItems.length > 0 &&
donation.relevantDonationItems.every(
(item) =>
itemFormData[item.itemId].ozPerItem !== '' &&
itemFormData[item.itemId].estimatedValue !== '',
parseFloat(itemFormData[item.itemId].ozPerItem) >= 0.01 &&
parseFloat(itemFormData[item.itemId].estimatedValue) >= 0.01,
),
[itemFormData],
[itemFormData, donation.relevantDonationItems],
);

// The order currently shown in the shipping stage based on the current page
Expand Down Expand Up @@ -284,7 +284,13 @@ const FmCompleteRequiredActionsModal: React.FC<
});
}

onSuccess();
// Whether every pending order now has both a shipping cost and a tracking
// link set, i.e. will flip to SHIPPED once this save lands on the backend
const allOrdersComplete = orders.every((order) => {
const { trackingLink, shippingCost } = orderFormData[order.orderId];
return trackingLink.trim() !== '' && shippingCost !== '';
});
onSuccess(allOrdersComplete);
} catch (error) {
const rawMsg = axios.isAxiosError(error) && error.response?.data?.message;
const msg = Array.isArray(rawMsg) ? rawMsg[0] : rawMsg;
Expand Down Expand Up @@ -312,6 +318,8 @@ const FmCompleteRequiredActionsModal: React.FC<

return (
<Dialog.Root
lazyMount
unmountOnExit
open={isOpen}
size="lg"
onOpenChange={(e: { open: boolean }) => {
Expand Down
13 changes: 11 additions & 2 deletions apps/frontend/src/components/forms/fmDeleteDonationModal.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useRef } from 'react';
import React, { useRef, useState } from 'react';
import {
Box,
Button,
Expand Down Expand Up @@ -29,24 +29,30 @@ const FMDeleteDonationActionModal: React.FC<
> = ({ donation, isOpen, onClose, onSuccess }) => {
useModalBodyCleanup();
const [alertState, setAlertMessage] = useAlert();
const [isDeleting, setIsDeleting] = useState(false);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

think we need this for all of our other deletion modals: pantryDeleteRequestModal, volunteerCloseOrderModal, .

While we are at it, we should do isSaving and setIsSaving useState for changePasswordModal, requestDetailsModal, and orderDetailsModal.


const donationRef = useRef<Donation | null>(donation);
if (donation) donationRef.current = donation;
const displayDonation = donation ?? donationRef.current;

const onDeleteDonation = async () => {
if (!donation) return;
if (!donation || isDeleting) return;
setIsDeleting(true);
try {
await apiClient.deleteDonation(donation.donationId);
onClose();
onSuccess();
} catch {
setAlertMessage('Donation could not be deleted.', AlertStatus.ERROR);
} finally {
setIsDeleting(false);
}
};

return (
<Dialog.Root
lazyMount
unmountOnExit
open={isOpen}
size="md"
onOpenChange={(e: { open: boolean }) => {
Expand Down Expand Up @@ -107,6 +113,7 @@ const FMDeleteDonationActionModal: React.FC<
textAlign="center"
lineHeight="28px"
onClick={onClose}
disabled={isDeleting}
>
Cancel
</Button>
Expand All @@ -121,6 +128,8 @@ const FMDeleteDonationActionModal: React.FC<
flexShrink={0}
textAlign="center"
onClick={onDeleteDonation}
loading={isDeleting}
disabled={isDeleting}
>
Delete
</Button>
Expand Down
2 changes: 2 additions & 0 deletions apps/frontend/src/components/forms/newDonationFormModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ const NewDonationFormModal: React.FC<NewDonationFormModalProps> = ({

return (
<Dialog.Root
lazyMount
unmountOnExit
open={isOpen}
size="md"
onOpenChange={(e: { open: boolean }) => {
Expand Down
9 changes: 9 additions & 0 deletions apps/frontend/src/components/forms/orderDetailsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ const OrderDetailsModal: React.FC<OrderDetailsModalProps> = ({
>({});
// The item whose allocation box is currently being edited (focused).
const [editingItemId, setEditingItemId] = useState<number | null>(null);
const [isSaving, setIsSaving] = useState(false);

const groupedManufacturerItems = useGroupedItemsByFoodType(manufacturerItems);

Expand Down Expand Up @@ -161,6 +162,7 @@ const OrderDetailsModal: React.FC<OrderDetailsModalProps> = ({

const handleSave = async () => {
if (orderId === null) return;
setIsSaving(true);
try {
await ApiClient.editAllocations(orderId, {
allocations: allocationsBody,
Expand All @@ -172,6 +174,8 @@ const OrderDetailsModal: React.FC<OrderDetailsModalProps> = ({
setAlertMessage('Successfully updated order.', AlertStatus.INFO);
} catch {
setAlertMessage('Order could not be updated.', AlertStatus.ERROR);
} finally {
setIsSaving(false);
}
};

Expand All @@ -191,6 +195,8 @@ const OrderDetailsModal: React.FC<OrderDetailsModalProps> = ({

return (
<Dialog.Root
lazyMount
unmountOnExit
open={isOpen}
size="xl"
onOpenChange={(e: { open: boolean }) => {
Expand Down Expand Up @@ -457,13 +463,16 @@ const OrderDetailsModal: React.FC<OrderDetailsModalProps> = ({
background="bg"
color="neutral.800"
borderColor="neutral.200"
disabled={isSaving}
>
Cancel
</Button>
<Button
onClick={handleSave}
bg="blue.hover"
color="white"
loading={isSaving}
disabled={isSaving}
>
Update Order
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ const OrderReceivedActionModal: React.FC<OrderReceivedActionModalProps> = ({

return (
<Dialog.Root
lazyMount
unmountOnExit
open={isOpen}
size="xl"
onOpenChange={(e: { open: boolean }) => {
Expand Down
2 changes: 2 additions & 0 deletions apps/frontend/src/components/forms/pantryApplicationModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const PantryApplicationModal: React.FC<PantryApplicationModalProps> = ({
const pantryUser = pantry.pantryUser;
return (
<Dialog.Root
lazyMount
unmountOnExit
open={isOpen}
onOpenChange={(e: { open: boolean }) => {
if (!e.open) onClose();
Expand Down
Loading
Loading