[questions][feat] update question filter (#384)

* [questions][chore] refactor question queries

* [questions][chore] destructure values from input

* [questions][feat] add sorting

* [question][fix] fix frontend

* [questions][feat] add sorting

* [questions][feat] add sorting index

* [questions][chore] push migration file

* [questions][fix] fix ci issues

* [questions][fix] fix import errors

Co-authored-by: Jeff Sieu <jeffsy00@gmail.com>
pull/413/head
hpkoh 2 years ago committed by GitHub
parent 5e6482aa2e
commit b37ce69c25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,12 @@
/*
Warnings:
- Added the required column `upvotes` to the `QuestionsQuestion` table without a default value. This is not possible if the table is not empty.
*/
-- AlterTable
ALTER TABLE "QuestionsQuestion" ADD COLUMN "lastSeenAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "upvotes" INTEGER NOT NULL;
-- AlterTable
ALTER TABLE "QuestionsQuestionEncounter" ADD COLUMN "netVotes" INTEGER NOT NULL DEFAULT 0;

@ -0,0 +1,12 @@
/*
Warnings:
- You are about to drop the column `netVotes` on the `QuestionsQuestionEncounter` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE "QuestionsQuestion" ALTER COLUMN "lastSeenAt" DROP DEFAULT,
ALTER COLUMN "upvotes" SET DEFAULT 0;
-- AlterTable
ALTER TABLE "QuestionsQuestionEncounter" DROP COLUMN "netVotes";

@ -0,0 +1,5 @@
-- CreateIndex
CREATE INDEX "QuestionsQuestion_lastSeenAt_id_idx" ON "QuestionsQuestion"("lastSeenAt", "id");
-- CreateIndex
CREATE INDEX "QuestionsQuestion_upvotes_id_idx" ON "QuestionsQuestion"("upvotes", "id");

@ -404,6 +404,8 @@ model QuestionsQuestion {
userId String?
content String @db.Text
questionType QuestionsQuestionType
lastSeenAt DateTime
upvotes Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@ -412,6 +414,9 @@ model QuestionsQuestion {
votes QuestionsQuestionVote[]
comments QuestionsQuestionComment[]
answers QuestionsAnswer[]
@@index([lastSeenAt, id])
@@index([upvotes, id])
}
model QuestionsQuestionEncounter {

@ -26,6 +26,8 @@ import {
} from '~/utils/questions/useSearchFilter';
import { trpc } from '~/utils/trpc';
import { SortOrder, SortType } from '~/types/questions.d';
export default function QuestionsHomePage() {
const router = useRouter();
@ -70,6 +72,9 @@ export default function QuestionsHomePage() {
locations: selectedLocations,
questionTypes: selectedQuestionTypes,
roles: [],
// TODO: Implement sort order and sort type choices
sortOrder: SortOrder.DESC,
sortType: SortType.NEW,
startDate,
},
],

@ -5,18 +5,33 @@ import { TRPCError } from '@trpc/server';
import { createProtectedRouter } from './context';
import type { Question } from '~/types/questions';
import { SortOrder, SortType } from '~/types/questions.d';
const TWO_WEEK_IN_MS = 12096e5;
export const questionsQuestionRouter = createProtectedRouter()
.query('getQuestionsByFilter', {
input: z.object({
companyNames: z.string().array(),
endDate: z.date(),
endDate: z.date().default(new Date()),
locations: z.string().array(),
pageSize: z.number().default(50),
questionTypes: z.nativeEnum(QuestionsQuestionType).array(),
roles: z.string().array(),
startDate: z.date().optional(),
sortOrder: z.nativeEnum(SortOrder),
sortType: z.nativeEnum(SortType),
startDate: z.date().default(new Date(Date.now() - TWO_WEEK_IN_MS)),
}),
async resolve({ ctx, input }) {
const sortCondition =
input.sortType === SortType.TOP
? {
upvotes: input.sortOrder,
}
: {
lastSeenAt: input.sortOrder,
};
const questionsData = await ctx.prisma.questionsQuestion.findMany({
include: {
_count: {
@ -41,7 +56,7 @@ export const questionsQuestionRouter = createProtectedRouter()
votes: true,
},
orderBy: {
createdAt: 'desc',
...sortCondition,
},
where: {
...(input.questionTypes.length > 0
@ -53,6 +68,10 @@ export const questionsQuestionRouter = createProtectedRouter()
: {}),
encounters: {
some: {
seenAt: {
gte: input.startDate,
lte: input.endDate,
},
...(input.companyNames.length > 0
? {
company: {
@ -204,8 +223,7 @@ export const questionsQuestionRouter = createProtectedRouter()
data: {
content: input.content,
encounters: {
create: [
{
create: {
company: {
connect: {
id: input.companyId,
@ -220,8 +238,8 @@ export const questionsQuestionRouter = createProtectedRouter()
},
},
},
],
},
lastSeenAt: input.seenAt,
questionType: input.questionType,
userId,
},
@ -316,13 +334,28 @@ export const questionsQuestionRouter = createProtectedRouter()
const userId = ctx.session?.user?.id;
const { questionId, vote } = input;
return await ctx.prisma.questionsQuestionVote.create({
const incrementValue = vote === Vote.UPVOTE ? 1 : -1;
const [questionVote] = await ctx.prisma.$transaction([
ctx.prisma.questionsQuestionVote.create({
data: {
questionId,
userId,
vote,
},
});
}),
ctx.prisma.questionsQuestion.update({
data: {
upvotes: {
increment: incrementValue,
},
},
where: {
id: questionId,
},
}),
]);
return questionVote;
},
})
.mutation('updateVote', {
@ -347,14 +380,30 @@ export const questionsQuestionRouter = createProtectedRouter()
});
}
return await ctx.prisma.questionsQuestionVote.update({
const incrementValue = vote === Vote.UPVOTE ? 2 : -2;
const [questionVote] = await ctx.prisma.$transaction([
ctx.prisma.questionsQuestionVote.update({
data: {
vote,
},
where: {
id,
},
});
}),
ctx.prisma.questionsQuestion.update({
data: {
upvotes: {
increment: incrementValue,
},
},
where: {
id: voteToUpdate.questionId,
},
}),
]);
return questionVote;
},
})
.mutation('deleteVote', {
@ -377,10 +426,25 @@ export const questionsQuestionRouter = createProtectedRouter()
});
}
return await ctx.prisma.questionsQuestionVote.delete({
const incrementValue = voteToDelete.vote === Vote.UPVOTE ? -1 : 1;
const [questionVote] = await ctx.prisma.$transaction([
ctx.prisma.questionsQuestionVote.delete({
where: {
id: input.id,
},
});
}),
ctx.prisma.questionsQuestion.update({
data: {
upvotes: {
increment: incrementValue,
},
},
where: {
id: voteToDelete.questionId,
},
}),
]);
return questionVote;
},
});

@ -20,7 +20,7 @@ export type AggregatedQuestionEncounter = {
companyCounts: Record<string, number>;
locationCounts: Record<string, number>;
roleCounts: Record<string, number>;
}
};
export type AnswerComment = {
content: string;
@ -50,3 +50,13 @@ export type QuestionComment = {
user: string;
userImage: string;
};
export enum SortOrder {
ASC = 'asc',
DESC = 'desc',
}
export enum SortType {
TOP,
NEW,
}

Loading…
Cancel
Save