add user profile, profile vibe and trip vibe and social signal
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import type { Vibe } from "@/app/generated/prisma/enums";
|
||||
|
||||
interface UpsertProfileInput {
|
||||
bio?: string;
|
||||
city?: string;
|
||||
instagram?: string;
|
||||
interests: string[];
|
||||
vibe?: Vibe;
|
||||
}
|
||||
|
||||
export const profileRepo = {
|
||||
@@ -21,12 +23,14 @@ export const profileRepo = {
|
||||
city: data.city,
|
||||
instagram: data.instagram,
|
||||
interests: data.interests,
|
||||
vibe: data.vibe,
|
||||
},
|
||||
update: {
|
||||
bio: data.bio,
|
||||
city: data.city,
|
||||
instagram: data.instagram,
|
||||
interests: data.interests,
|
||||
vibe: data.vibe,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { Prisma } from "@/app/generated/prisma/client";
|
||||
import type { ActivityCategory } from "@/app/generated/prisma/enums";
|
||||
import type { ActivityCategory, Vibe } from "@/app/generated/prisma/enums";
|
||||
import {
|
||||
utcStartOfDay,
|
||||
utcDayStartFromYmd,
|
||||
@@ -8,11 +8,15 @@ import {
|
||||
maxUtcDate,
|
||||
} from "@/lib/trip-dates";
|
||||
|
||||
export type GroupSize = "SMALL" | "MEDIUM" | "LARGE";
|
||||
|
||||
export interface TripFilters {
|
||||
q?: string;
|
||||
from?: string;
|
||||
to?: string;
|
||||
category?: ActivityCategory;
|
||||
vibe?: Vibe;
|
||||
groupSize?: GroupSize;
|
||||
}
|
||||
|
||||
export const tripRepo = {
|
||||
@@ -47,6 +51,18 @@ export const tripRepo = {
|
||||
andParts.push({ category: filters.category });
|
||||
}
|
||||
|
||||
if (filters?.vibe) {
|
||||
andParts.push({ vibe: filters.vibe });
|
||||
}
|
||||
|
||||
if (filters?.groupSize === "SMALL") {
|
||||
andParts.push({ maxParticipants: { lte: 10 } });
|
||||
} else if (filters?.groupSize === "MEDIUM") {
|
||||
andParts.push({ maxParticipants: { gte: 11, lte: 20 } });
|
||||
} else if (filters?.groupSize === "LARGE") {
|
||||
andParts.push({ maxParticipants: { gte: 21 } });
|
||||
}
|
||||
|
||||
if (!filters?.from && !filters?.to) {
|
||||
andParts.push({ date: { gte: todayStart } });
|
||||
} else {
|
||||
@@ -104,6 +120,22 @@ export const tripRepo = {
|
||||
},
|
||||
},
|
||||
images: { orderBy: { order: "asc" }, take: 1 },
|
||||
participants: {
|
||||
where: { status: "CONFIRMED" },
|
||||
take: 10,
|
||||
orderBy: { createdAt: "asc" },
|
||||
select: {
|
||||
id: true,
|
||||
user: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
image: true,
|
||||
profile: { select: { interests: true } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
_count: {
|
||||
select: {
|
||||
participants: { where: { status: { not: "CANCELLED" } } },
|
||||
@@ -129,7 +161,16 @@ export const tripRepo = {
|
||||
},
|
||||
images: { orderBy: { order: "asc" } },
|
||||
participants: {
|
||||
include: { user: { select: { id: true, name: true, image: true } } },
|
||||
include: {
|
||||
user: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
image: true,
|
||||
profile: { select: { city: true, interests: true } },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
reviews: {
|
||||
orderBy: { createdAt: "desc" },
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { Prisma } from "@/app/generated/prisma/client";
|
||||
import type { Vibe } from "@/app/generated/prisma/enums";
|
||||
|
||||
export interface PeopleFilters {
|
||||
city?: string;
|
||||
interest?: string;
|
||||
vibe?: Vibe;
|
||||
}
|
||||
|
||||
export const userRepo = {
|
||||
async findByEmail(email: string) {
|
||||
@@ -42,6 +49,7 @@ export const userRepo = {
|
||||
city: true,
|
||||
interests: true,
|
||||
instagram: true,
|
||||
vibe: true,
|
||||
},
|
||||
},
|
||||
organizerVerification: { select: { status: true } },
|
||||
@@ -49,6 +57,56 @@ export const userRepo = {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Discovery /people: ambil user yang punya profil sosial terisi (minimal salah
|
||||
* satu dari bio/city/interests/vibe). Filter optional by city/interest/vibe.
|
||||
* Tidak ekspos email/KYC.
|
||||
*/
|
||||
async findPeople(filters?: PeopleFilters, limit = 60) {
|
||||
const profileWhere: Prisma.UserProfileWhereInput = {
|
||||
OR: [
|
||||
{ bio: { not: null } },
|
||||
{ city: { not: null } },
|
||||
{ vibe: { not: null } },
|
||||
{ interests: { isEmpty: false } },
|
||||
],
|
||||
};
|
||||
|
||||
if (filters?.city) {
|
||||
profileWhere.city = {
|
||||
contains: filters.city,
|
||||
mode: "insensitive",
|
||||
};
|
||||
}
|
||||
if (filters?.interest) {
|
||||
profileWhere.interests = { has: filters.interest.toLowerCase() };
|
||||
}
|
||||
if (filters?.vibe) {
|
||||
profileWhere.vibe = filters.vibe;
|
||||
}
|
||||
|
||||
return prisma.user.findMany({
|
||||
where: { profile: { is: profileWhere } },
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
image: true,
|
||||
createdAt: true,
|
||||
profile: {
|
||||
select: {
|
||||
bio: true,
|
||||
city: true,
|
||||
interests: true,
|
||||
vibe: true,
|
||||
},
|
||||
},
|
||||
organizerVerification: { select: { status: true } },
|
||||
},
|
||||
orderBy: { createdAt: "desc" },
|
||||
take: limit,
|
||||
});
|
||||
},
|
||||
|
||||
async create(data: Prisma.UserCreateInput) {
|
||||
return prisma.user.create({ data });
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user