diff --git a/app/api/interests/route.ts b/app/api/interests/route.ts index f914c85a..5f860905 100644 --- a/app/api/interests/route.ts +++ b/app/api/interests/route.ts @@ -1,5 +1,5 @@ -import { prisma } from "@/lib/server/prisma"; -import { NextResponse } from "next/server"; +import {prisma} from "@/lib/server/prisma"; +import {NextResponse} from "next/server"; export async function GET() { try { @@ -28,6 +28,17 @@ export async function GET() { cacheStrategy: cacheStrategy, }); + const books = await prisma.book.findMany({ + select: { + id: true, + name: true, + }, + orderBy: { + name: 'asc' + }, + cacheStrategy: cacheStrategy, + }); + const causeAreas = await prisma.causeArea.findMany({ select: { id: true, @@ -50,12 +61,12 @@ export async function GET() { cacheStrategy: cacheStrategy, }); - return NextResponse.json({ interests, coreValues, causeAreas, connections }); + return NextResponse.json({interests, coreValues, books, causeAreas, connections}); } catch (error) { console.error('Error fetching interests:', error); return NextResponse.json( - { error: "Failed to fetch interests" }, - { status: 500 } + {error: "Failed to fetch interests"}, + {status: 500} ); } } diff --git a/app/api/profiles/route.ts b/app/api/profiles/route.ts index 35ec155f..b822cb2d 100644 --- a/app/api/profiles/route.ts +++ b/app/api/profiles/route.ts @@ -12,6 +12,7 @@ export async function GET(request: Request) { const maxIntroversion = url.searchParams.get("maxIntroversion"); const interests = url.searchParams.get("interests")?.split(",").filter(Boolean) || []; const coreValues = url.searchParams.get("coreValues")?.split(",").filter(Boolean) || []; + const books = url.searchParams.get("books")?.split(",").filter(Boolean) || []; const causeAreas = url.searchParams.get("causeAreas")?.split(",").filter(Boolean) || []; const connections = url.searchParams.get("connections")?.split(",").filter(Boolean) || []; const searchQueries = url.searchParams.get("searchQuery")?.split(",").map(q => q.trim()).filter(Boolean) || []; @@ -116,6 +117,22 @@ export async function GET(request: Request) { ]; } + // AND + if (books.length > 0) { + where.profile.AND = [ + ...where.profile.AND, + ...books.map((name) => ({ + books: { + some: { + value: { + name: name, + }, + }, + }, + })), + ]; + } + if (causeAreas.length > 0) { where.profile.AND = [ ...where.profile.AND, @@ -194,6 +211,17 @@ export async function GET(request: Request) { }, }, }, + { + profile: { + books: { + some: { + value: { + name: {contains: query, mode: "insensitive"}, + }, + }, + }, + }, + }, { profile: { causeAreas: { @@ -259,6 +287,7 @@ export async function GET(request: Request) { include: { intellectualInterests: {include: {interest: true}}, coreValues: {include: {value: true}}, + books: {include: {value: true}}, causeAreas: {include: {causeArea: true}}, desiredConnections: {include: {connection: true}}, promptAnswers: true, diff --git a/app/api/user/update-profile/route.ts b/app/api/user/update-profile/route.ts index 9a26d8e1..42bd8a10 100644 --- a/app/api/user/update-profile/route.ts +++ b/app/api/user/update-profile/route.ts @@ -14,8 +14,9 @@ export async function POST(req: Request) { } const data = await req.json(); - const {profile, image, name, interests = [], connections = [], coreValues = [], causeAreas = []} = data; + const {profile, image, name, interests = [], connections = [], coreValues = [], books = [], causeAreas = []} = data; + console.log('books: ', books) Object.keys(profile).forEach(key => { if (profile[key] === '' || !profile[key]) { delete profile[key]; @@ -71,6 +72,8 @@ export async function POST(req: Request) { profileConnection: prisma.profileConnection, value: prisma.value, profileValue: prisma.profileValue, + book: prisma.book, + profileBook: prisma.profileBook, causeArea: prisma.causeArea, profileCauseArea: prisma.profileCauseArea, } as const; @@ -79,7 +82,7 @@ export async function POST(req: Request) { async function handleFeatures(features: any, attribute: ModelKey, profileAttribute: string, idName: string) { // Add new features - if (features.length > 0 && updatedUser.profile) { + if (features !== null && updatedUser.profile) { // First, find or create all features console.log('profile', profileAttribute, profileAttribute); const operations = features.map((feat: { id?: string; name: string }) => @@ -95,25 +98,31 @@ export async function POST(req: Request) { // Get the IDs of all created/updated features const ids = createdFeatures.map(v => v.id); - // First, remove all existing interests for this profile - await modelMap[profileAttribute].deleteMany({ - where: {profileId: updatedUser.profile.id}, - }); + const profileId = updatedUser.profile.id; + console.log('profile ID:', profileId); - // Then, create new connections + // First, remove all existing features for this profile + const res = await modelMap[profileAttribute].deleteMany({ + where: {profileId: profileId}, + }); + console.log('deleted profile:', profileAttribute, res); + + // Then, create new features if (ids.length > 0) { - await modelMap[profileAttribute].createMany({ + const create_res =await modelMap[profileAttribute].createMany({ data: ids.map(id => ({ - profileId: updatedUser.profile!.id, + profileId: profileId, [idName]: id, })), skipDuplicates: true, }); + console.log('created many:', profileAttribute, create_res); } } } await handleFeatures(interests, 'interest', 'profileInterest', 'interestId') + await handleFeatures(books, 'book', 'profileBook', 'valueId') await handleFeatures(connections, 'connection', 'profileConnection', 'connectionId') await handleFeatures(coreValues, 'value', 'profileValue', 'valueId') await handleFeatures(causeAreas, 'causeArea', 'profileCauseArea', 'causeAreaId') diff --git a/app/complete-profile/page.tsx b/app/complete-profile/page.tsx index a889397e..bc720cc5 100644 --- a/app/complete-profile/page.tsx +++ b/app/complete-profile/page.tsx @@ -56,7 +56,7 @@ function RegisterComponent() { const router = useRouter(); const {data: session, update} = useSession(); - const featureNames = ['interests', 'coreValues', 'description', 'connections', 'causeAreas']; + const featureNames = ['interests', 'coreValues', 'description', 'connections', 'causeAreas', 'books']; const [showMoreInfo, _setShowMoreInfo] = useState(() => Object.fromEntries(featureNames.map((id) => [id, false])) @@ -141,6 +141,7 @@ function RegisterComponent() { setSelFeat('coreValues', 'coreValues', 'value') setSelFeat('connections', 'desiredConnections', 'connection') setSelFeat('causeAreas', 'causeAreas', 'causeArea') + setSelFeat('books', 'books', 'value') setImages([]) setKeys(profile?.images) @@ -309,10 +310,11 @@ function RegisterComponent() { ...(key && {image: key}), ...(name && {name}), }; - for (const name of ['interests', 'connections', 'coreValues', 'causeAreas']) { + for (const name of ['books', 'interests', 'connections', 'coreValues', 'causeAreas']) { + // if (!selectedFeatures[name].size) continue; data[name] = Array.from(selectedFeatures[name]).map(id => ({ id: id.startsWith('new-') ? undefined : id, - name: allFeatures[name].find(i => i.id === id)?.name || id.replace('new-', '') + name: allFeatures[name].find(i => i.id === id)?.name })); } console.log('data', data) @@ -416,6 +418,20 @@ function RegisterComponent() {
> }, + { + id: 'books', title: 'Works to discuss', allowAdd: true, + content: <> ++ List the works (books, articles, essays, reports, etc.) you would like to bring up. + For each work, include the exact title (as it appears on the cover), the + author’s full name, and, if necessary, the edition or publication year. For example: Peter Singer - Animal + Liberation. If you want to focus on specific + chapters, themes, or questions, note them in your description—it helps keep the discussion targeted. Don’t just write + “something by Orwell” or “that new mystery”; vague entries waste time and make it harder for others to find + the right work. Be explicit so everyone is literally on the same page! +
+ > + }, // { // id: 'causeAreas', title: 'Cause Areas', allowAdd: true, // content: <> diff --git a/app/profiles/ProfileFilters.tsx b/app/profiles/ProfileFilters.tsx index 33094a17..fa36d831 100644 --- a/app/profiles/ProfileFilters.tsx +++ b/app/profiles/ProfileFilters.tsx @@ -31,6 +31,7 @@ export const dropdownConfig: { id: DropdownKey, name: string }[] = [ {id: "connections", name: "Connection Type"}, {id: "coreValues", name: "Values"}, {id: "interests", name: "Interests"}, + {id: "books", name: "Works"}, // {id: "causeAreas", name: "Cause Areas"}, ] diff --git a/app/profiles/page.tsx b/app/profiles/page.tsx index ec5b1dc2..ab5d1709 100644 --- a/app/profiles/page.tsx +++ b/app/profiles/page.tsx @@ -20,6 +20,7 @@ const initialState = { maxIntroversion: null as number | null, interests: [] as string[], coreValues: [] as string[], + books: [] as string[], causeAreas: [] as string[], connections: [] as string[], searchQuery: '', @@ -33,6 +34,7 @@ type ProfileFilters = { minIntroversion: number | null; maxIntroversion: number | null; interests: string[]; + books: string[]; coreValues: string[]; causeAreas: string[]; connections: string[]; @@ -327,6 +329,18 @@ export default function ProfilePage() { )} +