mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-05-18 13:47:08 -04:00
Add books feature
This commit is contained in:
@@ -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}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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() {
|
||||
</p>
|
||||
</>
|
||||
},
|
||||
{
|
||||
id: 'books', title: 'Works to discuss', allowAdd: true,
|
||||
content: <>
|
||||
<p className="mt-2">
|
||||
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: <i>Peter Singer - Animal
|
||||
Liberation</i>. 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!
|
||||
</p>
|
||||
</>
|
||||
},
|
||||
// {
|
||||
// id: 'causeAreas', title: 'Cause Areas', allowAdd: true,
|
||||
// content: <>
|
||||
|
||||
@@ -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"},
|
||||
]
|
||||
|
||||
|
||||
@@ -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() {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-4 space-y-2 flex-grow">
|
||||
{user.profile.books?.length > 0 && (
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{user.profile.books.slice(0, 6).map(({value}) => (
|
||||
<span key={value?.id}
|
||||
className="inline-block text-xs px-2 py-1 bg-blue-50 text-blue-700 dark:text-white dark:bg-gray-700 rounded-full">
|
||||
{value?.name}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user