Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
30 changes: 26 additions & 4 deletions src/api/graphql/resolvers/nonprofits.resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
getNonprofitsWithFilters,
updateNonprofit,
updateNonprofitSchema,
getChapterIdsByNames,
} from '../../../core';
import { GraphQLError } from 'graphql';
import { z } from 'zod';
Expand All @@ -14,24 +15,42 @@ import type {
NonprofitSortOption,
} from '../../../core/services/nonprofits.service';

// Infer TypeScript types directly from your Zod schemas
type CreateNonprofitInput = z.infer<typeof createNonprofitSchema>;
type UpdateNonprofitInput = z.infer<typeof updateNonprofitSchema>;

interface NonprofitsQueryArgs {
chapterIds?: string[];
chapterNames?: string[];
statuses?: StatusType[];
sort?: NonprofitSortOption[];
}

export const nonprofitResolvers = {
Query: {
nonprofits: (
nonprofits: async (
_parent: unknown,
{ chapterIds, statuses, sort }: NonprofitsQueryArgs
{ chapterIds, chapterNames, statuses, sort }: NonprofitsQueryArgs
) => {
return getNonprofitsWithFilters({ chapterIds, statuses, sort });
let resolvedChapterIds = chapterIds;

// If frontend passes chapterNames, convert them to ids
if (
(!resolvedChapterIds || resolvedChapterIds.length === 0) &&
chapterNames?.length
) {
resolvedChapterIds = await getChapterIdsByNames(chapterNames);

// If user selected chapters but none matched, return empty list
if (!resolvedChapterIds || resolvedChapterIds.length === 0) return [];
}

return getNonprofitsWithFilters({
chapterIds: resolvedChapterIds,
statuses,
sort,
});
},

nonprofit: async (_parent: unknown, { id }: { id: string }) => {
const nonprofit = await getNonprofitById(id);
if (!nonprofit) {
Expand All @@ -48,6 +67,7 @@ export const nonprofitResolvers = {
return nonprofit;
},
},

Mutation: {
createNonprofit: (
_parent: unknown,
Expand All @@ -56,6 +76,7 @@ export const nonprofitResolvers = {
const validatedInput = createNonprofitSchema.parse(input);
return createNonprofit(validatedInput);
},

updateNonprofit: (
_parent: unknown,
{
Expand All @@ -66,6 +87,7 @@ export const nonprofitResolvers = {
const validatedInput = updateNonprofitSchema.parse(input);
return updateNonprofit(nonprofit_id, validatedInput);
},

deleteNonprofit: (_parent: unknown, { id }: { id: string }) => {
return deleteNonprofit(id);
},
Expand Down
1 change: 1 addition & 0 deletions src/api/graphql/schemas/nonprofits.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const nonprofitSchemaString = `
type Query {
nonprofits(
chapterIds: [ID!]
chapterNames: [String!]
statuses: [StatusType!]
sort: [NonprofitSortOption!]
): [Nonprofit!]!
Expand Down
12 changes: 12 additions & 0 deletions src/core/services/nonprofits.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,3 +519,15 @@ export async function deleteNonprofit(id: string): Promise<EnrichedNonprofit> {
throw new DatabaseError('Failed to delete nonprofit');
}
}

export async function getChapterIdsByNames(names: string[]): Promise<string[]> {
const cleaned = [...new Set(names.map((n) => n.trim()).filter(Boolean))];
if (cleaned.length === 0) return [];

const chapters = await prisma.chapters.findMany({
where: { name: { in: cleaned } },
select: { chapter_id: true },
});

return chapters.map((c) => c.chapter_id);
}