Repository navigation
Pk/mspca 46 animal availability frontend endpoint - #30
pujitakalinadhabhotla wants to merge 9 commits into
Conversation
dburkhart07
left a comment
There was a problem hiding this comment.
some initial comments. can you please merge main in so this diff gets cleaned up a bit?
| brown: '#5e3638', | ||
| }, | ||
| purple: { | ||
| avatar: '#b57bf8', |
There was a problem hiding this comment.
can you check the figma again? i think this is supposed to be a different hexcode: https://www.figma.com/design/NNzZhw8n4UWmG3UeJTLEwD/MSPCA?node-id=633-8125&m=dev
| @@ -0,0 +1,16 @@ | |||
| // TEMPORARY: the animals API doesn't return restriction tags yet, so these are | |||
There was a problem hiding this comment.
we should have restrictions returned, so we shouldnt need any mock data anymore. lets just add the data into the db ourselves and taht should have all the schema we need
There was a problem hiding this comment.
Fairly certain we are going to be using lucide-react icons. can we use those corresponding ones from the figma instead of this and the list filter?
| const defaultBaseUrl = | ||
| import.meta.env.VITE_API_BASE_URL ?? 'http://localhost:3000'; | ||
|
|
||
| export interface Animal { |
There was a problem hiding this comment.
lets create a separate types.ts file within frontend/src and put all the interfaces in there.
|
|
||
| export interface Animal { | ||
| animalId: number; | ||
| chameleonAnimalId: number; |
| location: string; | ||
| picture: string | null; | ||
| fosterBioMemo: string | null; | ||
| // Restriction tag labels (e.g. 'Dog-Free Home'). Not returned by the API yet; |
There was a problem hiding this comment.
this will also need updating since we do return it
| const defaultBaseUrl = | ||
| import.meta.env.VITE_API_BASE_URL ?? 'http://localhost:3000'; | ||
|
|
||
| export interface Animal { |
There was a problem hiding this comment.
lets also just make sure all of these schemas are exactly right with what the backend entities are
| @@ -1,108 +1,24 @@ | |||
| import { MigrationInterface, QueryRunner } from 'typeorm'; | |||
|
|
|||
| export class CreateAnimals1792897315518 implements MigrationInterface { | |||
There was a problem hiding this comment.
we should already have this migration. can you make sure this goes away when we update it? the entity is different now too
| @IsPositive() | ||
| chameleonAnimalId!: number; | ||
|
|
||
| @IsOptional() |
There was a problem hiding this comment.
this should have the new docstring of @IsNonEmptyString, as well as specific ValidateIf. we should be able to still accept null values for this though
dburkhart07
left a comment
There was a problem hiding this comment.
for right now, can we comment out the stuff in main.tsx so that we only use the nonauthenticated frontend? we will adjust this later when we implement sign-in.
sorry theres so many comments 😭 lmk if you have any questions on any of them. tysm pujita, really good work on this so far, ik it was lowk a huge pr!
| // Remaining months of age, e.g. 5 for "4Y5M" | ||
| ageMonth: number; | ||
| sex: string; | ||
| // 'Dog' | 'Cat' | 'Small Animals' | 'Baby Bottle Animals' | 'Farm Animals' |
There was a problem hiding this comment.
nit: we can delete these comments tbh
| matchId: number; | ||
| volunteerId: number; | ||
| chameleonAnimalId: string; | ||
| // 'Pending' | 'Active' | 'Complete' | 'Denied' | 'Withdrawn' | 'Canceled' |
|
|
||
| it('does not update preferences when an added animal does not exist', async () => { | ||
| const error = new NotFoundException( | ||
| 'Animals with Chameleon IDs not found: 998, 999', |
There was a problem hiding this comment.
nit: this error should be A998 and A999
| 'At least one of added or removed must be provided', | ||
| ); | ||
| } | ||
| await this.animalsService.checkAllExistOrFail(dto.added ?? []); |
There was a problem hiding this comment.
this is already being checked in the service, can we just keep it there?
| description: 'No volunteer or animal exists with the given ID.', | ||
| }) | ||
| async createMatch(@Body() body: CreateMatchDto): Promise<Match> { | ||
| await this.animalsService.findByChameleonIdOrFail(body.chameleonAnimalId); |
There was a problem hiding this comment.
we should move this check into the service as well, and therefore we shouldnt have a diff for this file or the controller tests
| locations: string[]; | ||
| } | ||
|
|
||
| const ChevronIcon: React.FC<{ open: boolean }> = ({ open }) => ( |
There was a problem hiding this comment.
why do we need this? can we just use a lucide icon instead?
| align="stretch" | ||
| gap="4" | ||
| > | ||
| {options.length === 0 ? ( |
There was a problem hiding this comment.
options will always have something available.
| { label: 'Requires Medication', color: 'trello.requiresMedication' }, | ||
| ]; | ||
|
|
||
| export const getRestriction = (label: string): Restriction | undefined => |
There was a problem hiding this comment.
this is a Restriction enum
| label, | ||
| color: | ||
| key === 'restrictions' | ||
| ? getRestriction(label)?.color ?? 'neutrals.black' |
There was a problem hiding this comment.
when would this ever fail?
| Clear Filters | ||
| </Button> | ||
| </Flex> | ||
| {chips.map((chip) => ( |
There was a problem hiding this comment.
these are supposed to have a buttons to view them horizontally, rather than overflowing into the next line. id check the figma design again on this
ℹ️ Issue
Closes https://mspca.atlassian.net/jira/software/projects/MSPCA/boards/1?filter=&groupBy=none&selectedIssue=MSPCA-46
📝 Description
Adds the Animal Availability page, where volunteers browse animals that need fostering, filter them, view details, and request to foster. Also adds the backend endpoint that supplies the animals.
Changes:
GET /api/animals(animals.controller.ts,animals.service.ts,animals.module.ts): returns all animals, or[]when there are none. Covered by new controller and service tests.1793300000000-AddMatchAdditionalComments.ts,matches.entity.ts,create-match.dto.ts,matches.service.ts): new optionaladditional_commentscolumn onmatches, accepted byPOST /api/matches.routes.ts,app.tsx):ROUTES.ANIMAL_AVAILABILITY = '/animal-availability', rendering the new page.pages/AnimalAvailability.tsx): fetches all animals once and shows a card grid with loading, error (with retry), and empty states. The map area is left blank.components/AnimalCard.tsx: reusable card showing the photo (placeholder), name, breed, restriction tags, age, and location, with a "See More" button.components/AnimalModal.tsx: opens from "See More" and shows full details plus a comments box. Apply sends the foster request throughcreateMatch.components/AnimalFilters.tsx,utils/animals.ts: filter panel for Animal Type, Restrictions, and Location with Apply/Cancel, chips, and Clear Filters. Filtering runs in the browser on the already-fetched list, so changing a filter makes no new API request.components/RestrictionTag.tsx: colored tag pill used on the card and in the modal.api/apiClient.ts: addedgetAnimalsandcreateMatch.theme.ts: added acardshadow token and the avatar purple from the Figma.utils/mockRestrictions.ts: temporary mock tags (see notes). The logo, placeholder photo, and two icons are inassets/.✔️ Verification
yarn typeorm:migratepsql(no seed migration), for example:npx nx serve backendandnpx nx serve frontendanimalstable shows the empty state.matches.npx jest apps/backend/src/animals apps/backend/src/matches