Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
320902d
Added in recurring donations
dburkhart07 Feb 3, 2026
ed330ef
prettier
dburkhart07 Feb 3, 2026
16daa0f
Final commit
dburkhart07 Feb 3, 2026
0484af8
Final commit
dburkhart07 Feb 4, 2026
d6f6acf
Final commit
dburkhart07 Feb 5, 2026
ffea078
Final commit fr this time
dburkhart07 Feb 5, 2026
90cbe4a
Fixed donation enum names
dburkhart07 Feb 5, 2026
ead7228
Merged main and made changes
dburkhart07 Feb 6, 2026
17a5fc5
prettier
dburkhart07 Feb 6, 2026
d634048
Review comments
dburkhart07 Feb 6, 2026
b60bc35
Final commit
dburkhart07 Feb 6, 2026
635b89b
Final commit fr this time
dburkhart07 Feb 6, 2026
fd9bb33
prettier
dburkhart07 Feb 6, 2026
1add714
Some more review comments
dburkhart07 Feb 7, 2026
e663e18
More comments
dburkhart07 Feb 7, 2026
077d928
More changes!!
dburkhart07 Feb 8, 2026
c94c88a
Added in main yarn configurations
dburkhart07 Feb 8, 2026
937192c
Final commit
dburkhart07 Feb 10, 2026
0e6b95b
prettier
dburkhart07 Feb 10, 2026
840973c
Fixed selected days text logic
dburkhart07 Feb 10, 2026
0e7c727
prettier
dburkhart07 Feb 11, 2026
baff8bb
merged main
dburkhart07 Feb 13, 2026
5681568
Merged main
dburkhart07 Feb 15, 2026
0dbbd4f
Implemented changes
dburkhart07 Feb 16, 2026
e426266
prettier
dburkhart07 Feb 16, 2026
33e509f
Fixed backend
dburkhart07 Feb 16, 2026
800c09b
prettier
dburkhart07 Feb 16, 2026
2495521
potential fix to mac issue
dburkhart07 Feb 16, 2026
6ec30bf
Fixed small issue in order service tests
dburkhart07 Feb 16, 2026
36608ed
so many review comments help
dburkhart07 Feb 17, 2026
f4b32a9
i forgot prettier
dburkhart07 Feb 17, 2026
3c9e869
Merged main
dburkhart07 Feb 18, 2026
e2a858d
Merged main
dburkhart07 Feb 18, 2026
acfe838
Merged main
dburkhart07 Feb 18, 2026
9c0fd79
Fixed width
dburkhart07 Feb 18, 2026
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
4 changes: 4 additions & 0 deletions apps/backend/src/config/migrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ import { UpdatePantryFields1763762628431 } from '../migrations/1763762628431-Upd
import { PopulateDummyData1768501812134 } from '../migrations/1768501812134-populateDummyData';
import { RemovePantryFromOrders1769316004958 } from '../migrations/1769316004958-RemovePantryFromOrders';
import { AddDonationRecurrenceFields1770080947285 } from '../migrations/1770080947285-AddDonationRecurrenceFields';
import { AddFoodRescueToDonationItems1770679339809 } from '../migrations/1770679339809-AddFoodRescueToDonationItems';
import { UpdateManufacturerEntity1768680807820 } from '../migrations/1768680807820-UpdateManufacturerEntity';
import { AddUserPoolId1769189327767 } from '../migrations/1769189327767-AddUserPoolId';
import { UpdateOrderEntity1769990652833 } from '../migrations/1769990652833-UpdateOrderEntity';
import { RenameDonationMatchingStatus1771260403657 } from '../migrations/1771260403657-RenameDonationMatchingStatus';

const schemaMigrations = [
User1725726359198,
Expand Down Expand Up @@ -59,9 +61,11 @@ const schemaMigrations = [
PopulateDummyData1768501812134,
RemovePantryFromOrders1769316004958,
AddDonationRecurrenceFields1770080947285,
AddFoodRescueToDonationItems1770679339809,
UpdateManufacturerEntity1768680807820,
AddUserPoolId1769189327767,
UpdateOrderEntity1769990652833,
RenameDonationMatchingStatus1771260403657,
];

export default schemaMigrations;
23 changes: 13 additions & 10 deletions apps/backend/src/donationItems/donationItems.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,29 @@ import { FoodType } from './types';
@Entity('donation_items')
export class DonationItem {
@PrimaryGeneratedColumn({ name: 'item_id' })
itemId: number;
itemId!: number;

@Column({ name: 'donation_id', type: 'int' })
donationId: number;
donationId!: number;

@ManyToOne(() => Donation, { nullable: false })
@JoinColumn({ name: 'donation_id', referencedColumnName: 'donationId' })
donation: Donation;
donation!: Donation;

@Column({ name: 'item_name', type: 'varchar', length: 255 })
itemName: string;
itemName!: string;

@Column({ name: 'quantity', type: 'int' })
quantity: number;
quantity!: number;

@Column({ name: 'reserved_quantity', type: 'int', default: 0 })
reservedQuantity: number;
reservedQuantity!: number;

@Column({ name: 'oz_per_item', type: 'int', nullable: true })
ozPerItem: number;
ozPerItem?: number;

@Column({ name: 'estimated_value', type: 'int', nullable: true })
estimatedValue: number;
estimatedValue?: number;

@Column({
name: 'food_type',
Expand All @@ -44,8 +44,11 @@ export class DonationItem {
enumName: 'food_type_enum',
nullable: true,
})
foodType: FoodType;
foodType?: FoodType;

@OneToMany(() => Allocation, (allocation) => allocation.item)
allocations: Allocation[];
allocations!: Allocation[];

@Column({ name: 'food_rescue', type: 'boolean', default: false })
foodRescue!: boolean;
}
21 changes: 9 additions & 12 deletions apps/backend/src/donations/donations.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ import {
Param,
NotFoundException,
ParseIntPipe,
BadRequestException,
} from '@nestjs/common';
import { ApiBody } from '@nestjs/swagger';
import { Donation } from './donations.entity';
import { DonationService } from './donations.service';
import { DonationStatus, RecurrenceEnum } from './types';
import { RecurrenceEnum } from './types';
import { CreateDonationDto } from './dtos/create-donation.dto';

@Controller('donations')
Expand All @@ -29,7 +28,14 @@ export class DonationsController {
return this.donationService.getNumberOfDonations();
}

@Get('/:donationId')
@Get('/by-fm-id/:foodManufacturerId')
async getDonationsByFoodManufacturer(
Copy link
Member

Choose a reason for hiding this comment

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

i think we can probably write controller tests

@Param('foodManufacturerId', ParseIntPipe) foodManufacturerId: number,
): Promise<Donation[]> {
return this.donationService.getByFoodManufacturer(foodManufacturerId);
}

@Get('/by-donation-id/:donationId')
async getDonation(
@Param('donationId', ParseIntPipe) donationId: number,
): Promise<Donation> {
Expand All @@ -43,15 +49,6 @@ export class DonationsController {
type: 'object',
properties: {
foodManufacturerId: { type: 'integer', example: 1 },
Copy link
Author

Choose a reason for hiding this comment

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

NOTE FOR PR Reviewer: We deleted this since it does not make sense to have either of these fields here in creating a donation. The status will always be the same, as will the date donated.

dateDonated: {
type: 'string',
format: 'date-time',
},
status: {
type: 'string',
enum: Object.values(DonationStatus),
example: DonationStatus.AVAILABLE,
},
totalItems: { type: 'integer', example: 100 },
totalOz: { type: 'number', example: 100.5 },
totalEstimatedValue: { type: 'number', example: 100.5 },
Expand Down
24 changes: 21 additions & 3 deletions apps/backend/src/donations/donations.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export class DonationService {
where: { donationId },
relations: ['foodManufacturer'],
});

if (!donation) {
throw new NotFoundException(`Donation ${donationId} not found`);
}
Expand All @@ -39,6 +38,25 @@ export class DonationService {
return this.repo.count();
}

async getByFoodManufacturer(foodManufacturerId: number): Promise<Donation[]> {
validateId(foodManufacturerId, 'Food Manufacturer');

const manufacturer = await this.manufacturerRepo.findOne({
where: { foodManufacturerId: foodManufacturerId },
Copy link
Member

Choose a reason for hiding this comment

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

do we need two foodManufacturerId's here since they're named the same thing

});

if (!manufacturer) {
throw new NotFoundException(
`Food Manufacturer ${foodManufacturerId} not found`,
);
}

return this.repo.find({
where: { foodManufacturer: { foodManufacturerId } },
relations: ['foodManufacturer'],
});
}

async create(donationData: CreateDonationDto): Promise<Donation> {
validateId(donationData.foodManufacturerId, 'Food Manufacturer');
const manufacturer = await this.manufacturerRepo.findOne({
Expand All @@ -52,8 +70,8 @@ export class DonationService {
}
const donation = this.repo.create({
foodManufacturer: manufacturer,
dateDonated: donationData.dateDonated,
status: donationData.status,
dateDonated: new Date(),
status: DonationStatus.AVAILABLE,
totalItems: donationData.totalItems,
totalOz: donationData.totalOz,
totalEstimatedValue: donationData.totalEstimatedValue,
Expand Down
11 changes: 1 addition & 10 deletions apps/backend/src/donations/dtos/create-donation.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,14 @@ import {
Min,
ValidateIf,
} from 'class-validator';
import { DonationStatus, RecurrenceEnum } from '../types';
import { RecurrenceEnum } from '../types';
import { Type } from 'class-transformer';

export class CreateDonationDto {
@IsNumber()
@Min(1)
foodManufacturerId!: number;

@Type(() => Date)
@IsDate()
@IsNotEmpty()
dateDonated!: Date;

@IsNotEmpty()
@IsEnum(DonationStatus)
status!: DonationStatus;

@IsNumber()
@Min(1)
@IsOptional()
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/donations/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export enum DonationStatus {
AVAILABLE = 'available',
FULFILLED = 'fulfilled',
MATCHING = 'matching',
MATCHED = 'matched',
}

export enum RecurrenceEnum {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class AddFoodRescueToDonationItems1770679339809
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE donation_items
ADD COLUMN food_rescue boolean NOT NULL DEFAULT false
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE donation_items
DROP COLUMN food_rescue
`);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class RenameDonationMatchingStatus1771260403657
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE donations
ALTER COLUMN status DROP DEFAULT;

CREATE TYPE donations_status_enum_new AS ENUM (
'available',
'matched',
'fulfilled'
);

ALTER TABLE donations
ALTER COLUMN status
TYPE donations_status_enum_new
USING (
CASE
WHEN status = 'matching'
THEN 'matched'
ELSE status::text
END
)::donations_status_enum_new;

DROP TYPE donations_status_enum;

ALTER TYPE donations_status_enum_new
RENAME TO donations_status_enum;

ALTER TABLE donations
ALTER COLUMN status
SET DEFAULT 'available';
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE donations
ALTER COLUMN status DROP DEFAULT;

CREATE TYPE donations_status_enum_old AS ENUM (
'available',
'matching',
'fulfilled'
);

ALTER TABLE donations
ALTER COLUMN status
TYPE donations_status_enum_old
USING (
CASE
WHEN status = 'matched'
THEN 'matching'
ELSE status::text
END
)::donations_status_enum_old;

DROP TYPE donations_status_enum;

ALTER TYPE donations_status_enum_old
RENAME TO donations_status_enum;

ALTER TABLE donations
ALTER COLUMN status
SET DEFAULT 'available';
`);
}
}
2 changes: 1 addition & 1 deletion apps/backend/src/orders/order.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('OrdersService', () => {
}

// Clean database at the start
await testDataSource.query(`DROP SCHEMA public CASCADE`);
await testDataSource.query(`DROP SCHEMA IF EXISTS public CASCADE`);
await testDataSource.query(`CREATE SCHEMA public`);

const module: TestingModule = await Test.createTestingModule({
Expand Down
16 changes: 13 additions & 3 deletions apps/frontend/src/api/apiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ export class ApiClient {
.then((response) => response.data);
}

public async getAllDonationsByFoodManufacturer(
foodManufacturerId: number,
): Promise<Donation[]> {
return this.axiosInstance
.get(`/api/donations/by-fm-id/${foodManufacturerId}`)
.then((response) => response.data);
}

public async fulfillDonation(
donationId: number,
body?: unknown,
Expand Down Expand Up @@ -180,12 +188,14 @@ export class ApiClient {
await this.axiosInstance.put(`/api/users/${userId}/role`, body);
}

public async getOrderFoodRequest(requestId: number): Promise<FoodRequest> {
public async getFoodRequest(requestId: number): Promise<FoodRequest> {
return this.get(`/api/requests/${requestId}`) as Promise<FoodRequest>;
}

public async getOrderDonation(donationId: number): Promise<Donation> {
return this.get(`/api/donations/${donationId}`) as Promise<Donation>;
public async getDonation(donationId: number): Promise<Donation> {
return this.get(
`/api/donations/by-donation-id/${donationId}`,
) as Promise<Donation>;
}

public async getDonationItemsByDonationId(
Expand Down
7 changes: 4 additions & 3 deletions apps/frontend/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import PantryPastOrders from '@containers/pantryPastOrders';
import Pantries from '@containers/pantries';
import Orders from '@containers/orders';
import PantryDashboard from '@containers/pantryDashboard';
import submitFoodRequestFormModal from '@components/forms/requestFormModal';
import { submitDeliveryConfirmationFormModal } from '@components/forms/deliveryConfirmationModal';
import FormRequests from '@containers/formRequests';
import PantryApplication from '@containers/pantryApplication';
Expand All @@ -22,6 +21,8 @@ import Homepage from '@containers/homepage';
import AdminOrderManagement from '@containers/adminOrderManagement';
import { Amplify } from 'aws-amplify';
import CognitoAuthConfig from './aws-exports';
import { Button } from '@chakra-ui/react';
Copy link
Member

Choose a reason for hiding this comment

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

seems to be some unnecessary imports

import FoodManufacturerDonationManagement from '@containers/foodManufacturerDonationManagement';
import LoginPage from '@containers/loginPage';
import SignupPage from '@containers/signupPage';
import ForgotPasswordPage from '@containers/forgotPasswordPage';
Expand Down Expand Up @@ -153,10 +154,10 @@ const router = createBrowserRouter([
),
},
{
path: '/donation-management',
path: '/fm-donation-management',
element: (
<ProtectedRoute>
<DonationManagement />
<FoodManufacturerDonationManagement />
</ProtectedRoute>
),
},
Expand Down
6 changes: 6 additions & 0 deletions apps/frontend/src/chakra-ui.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ declare module '@chakra-ui/react' {
export interface FieldRootProps extends ComponentPropsLenientChildren {}
export interface FieldHelperTextProps extends ComponentPropsLenientChildren {}

// Native Select components
export interface NativeSelectFieldProps
extends ComponentPropsLenientChildren {}

// Common components
export interface ButtonProps extends ComponentPropsStrictChildren {}
export interface IconButtonProps extends ComponentPropsStrictChildren {}
Expand All @@ -79,4 +83,6 @@ declare module '@chakra-ui/react' {
export interface CardProps extends ComponentPropsStrictChildren {}
export interface CardBodyProps extends ComponentPropsStrictChildren {}
export interface TextareaProps extends ComponentPropsStrictChildren {}
export interface NumberInputInputProps
extends ComponentPropsLenientChildren {}
}
Loading