-
+ {
+ createQuestion({
+ company: data.company,
+ content: data.questionContent,
+ location: data.location,
+ questionType: data.questionType,
+ seenAt: data.date,
+ });
+ }}
+ />
- {Array.from({ length: 10 }).map((_, index) => (
+ {(questions ?? []).map((question) => (
))}
diff --git a/apps/portal/src/server/router/questions-question-router.ts b/apps/portal/src/server/router/questions-question-router.ts
index 8918f036..b54d27b0 100644
--- a/apps/portal/src/server/router/questions-question-router.ts
+++ b/apps/portal/src/server/router/questions-question-router.ts
@@ -1,5 +1,5 @@
import { z } from 'zod';
-import {QuestionsQuestionType, Vote } from '@prisma/client';
+import { QuestionsQuestionType, Vote } from '@prisma/client';
import { TRPCError } from '@trpc/server';
import { createProtectedRouter } from './context';
@@ -17,28 +17,28 @@ export const questionsQuestionRouter = createProtectedRouter()
async resolve({ ctx, input }) {
const questionsData = await ctx.prisma.questionsQuestion.findMany({
include: {
- _count: {
- select: {
- answers: true,
- comments: true,
+ _count: {
+ select: {
+ answers: true,
+ comments: true,
+ },
},
- },
- encounters: {
- select: {
- company: true,
- location: true,
- role: true,
+ encounters: {
+ select: {
+ company: true,
+ location: true,
+ role: true,
+ },
},
- },
- user: {
- select: {
- name: true,
+ user: {
+ select: {
+ name: true,
+ },
},
- },
- votes: true,
+ votes: true,
},
orderBy: {
- createdAt: 'desc',
+ createdAt: 'desc',
},
where: {
questionType: input.questionType,
@@ -47,68 +47,91 @@ export const questionsQuestionRouter = createProtectedRouter()
return questionsData
.filter((data) => {
for (let i = 0; i < data.encounters.length; i++) {
- const encounter = data.encounters[i]
- const matchCompany = (!input.company || (encounter.company === input.company));
- const matchLocation = (!input.location || (encounter.location === input.location));
- const matchRole = (!input.company || (encounter.role === input.role));
- if (matchCompany && matchLocation && matchRole) {return true};
+ const encounter = data.encounters[i];
+ const matchCompany =
+ !input.company || encounter.company === input.company;
+ const matchLocation =
+ !input.location || encounter.location === input.location;
+ const matchRole = !input.company || encounter.role === input.role;
+ if (matchCompany && matchLocation && matchRole) {
+ return true;
+ }
}
return false;
})
.map((data) => {
- const votes:number = data.votes.reduce(
- (previousValue:number, currentValue) => {
- let result:number = previousValue;
+ const votes: number = data.votes.reduce(
+ (previousValue: number, currentValue) => {
+ let result: number = previousValue;
- switch(currentValue.vote) {
- case Vote.UPVOTE:
- result += 1
- break;
- case Vote.DOWNVOTE:
- result -= 1
- break;
+ switch (currentValue.vote) {
+ case Vote.UPVOTE:
+ result += 1;
+ break;
+ case Vote.DOWNVOTE:
+ result -= 1;
+ break;
}
return result;
},
- 0
- );
+ 0,
+ );
- let userName = "";
+ let userName = '';
if (data.user) {
userName = data.user.name!;
}
const question: Question = {
- company: "",
+ company: data.encounters[0].company,
content: data.content,
id: data.id,
- location: "",
+ location: data.encounters[0].location ?? 'Unknown location',
numAnswers: data._count.answers,
numComments: data._count.comments,
numVotes: votes,
- role: "",
+ role: data.encounters[0].role ?? 'Unknown role',
updatedAt: data.updatedAt,
user: userName,
};
return question;
- });
- }
+ });
+ },
})
.mutation('create', {
input: z.object({
+ company: z.string(),
content: z.string(),
+ location: z.string(),
questionType: z.nativeEnum(QuestionsQuestionType),
+ role: z.string().optional(),
+ seenAt: z.date(),
}),
async resolve({ ctx, input }) {
const userId = ctx.session?.user?.id;
- return await ctx.prisma.questionsQuestion.create({
+ const question = await ctx.prisma.questionsQuestion.create({
data: {
- ...input,
+ content: input.content,
+ questionType: input.questionType,
+ userId,
+ },
+ });
+
+ // Create question encounter
+ await ctx.prisma.questionsQuestionEncounter.create({
+ data: {
+ company: input.company,
+ location: input.location,
+ questionId: question.id,
+ role: input.role,
+ seenAt: input.seenAt,
userId,
},
});
+
+ return question;
},
})
.mutation('update', {
@@ -116,7 +139,6 @@ export const questionsQuestionRouter = createProtectedRouter()
content: z.string().optional(),
id: z.string(),
questionType: z.nativeEnum(QuestionsQuestionType).optional(),
-
}),
async resolve({ ctx, input }) {
const userId = ctx.session?.user?.id;
@@ -179,11 +201,11 @@ export const questionsQuestionRouter = createProtectedRouter()
}),
async resolve({ ctx, input }) {
const userId = ctx.session?.user?.id;
- const {questionId} = input
+ const { questionId } = input;
return await ctx.prisma.questionsQuestionVote.findUnique({
where: {
- questionId_userId : {questionId,userId }
+ questionId_userId: { questionId, userId },
},
});
},
@@ -211,7 +233,7 @@ export const questionsQuestionRouter = createProtectedRouter()
}),
async resolve({ ctx, input }) {
const userId = ctx.session?.user?.id;
- const {id, vote} = input
+ const { id, vote } = input;
const voteToUpdate = await ctx.prisma.questionsQuestionVote.findUnique({
where: {
@@ -246,7 +268,8 @@ export const questionsQuestionRouter = createProtectedRouter()
const voteToDelete = await ctx.prisma.questionsQuestionVote.findUnique({
where: {
id: input.id,
- },});
+ },
+ });
if (voteToDelete?.id !== userId) {
throw new TRPCError({
@@ -261,4 +284,4 @@ export const questionsQuestionRouter = createProtectedRouter()
},
});
},
- });
\ No newline at end of file
+ });
diff --git a/apps/portal/src/utils/questions/constants.ts b/apps/portal/src/utils/questions/constants.ts
index 966e1a1f..155359d5 100644
--- a/apps/portal/src/utils/questions/constants.ts
+++ b/apps/portal/src/utils/questions/constants.ts
@@ -1,3 +1,5 @@
+import type { QuestionsQuestionType } from '@prisma/client';
+
import type { FilterChoices } from '~/components/questions/filter/FilterSection';
export const COMPANIES: FilterChoices = [
@@ -12,18 +14,18 @@ export const COMPANIES: FilterChoices = [
];
// Code, design, behavioral
-export const QUESTION_TYPES: FilterChoices = [
+export const QUESTION_TYPES: FilterChoices
= [
{
label: 'Coding',
- value: 'coding',
+ value: 'CODING',
},
{
label: 'Design',
- value: 'design',
+ value: 'SYSTEM_DESIGN',
},
{
label: 'Behavioral',
- value: 'behavioral',
+ value: 'BEHAVIORAL',
},
];
diff --git a/apps/portal/src/utils/questions/createSlug.ts b/apps/portal/src/utils/questions/createSlug.ts
new file mode 100644
index 00000000..9c8a81ae
--- /dev/null
+++ b/apps/portal/src/utils/questions/createSlug.ts
@@ -0,0 +1,7 @@
+export default function createSlug(content: string) {
+ return content
+ .toLowerCase()
+ .replace(/[^a-z0-9]+/g, '-')
+ .replace(/(^-|-$)+/g, '')
+ .substring(0, 100);
+}
diff --git a/apps/portal/src/utils/questions/useSearchFilter.ts b/apps/portal/src/utils/questions/useSearchFilter.ts
index 711f5ead..392a69c8 100644
--- a/apps/portal/src/utils/questions/useSearchFilter.ts
+++ b/apps/portal/src/utils/questions/useSearchFilter.ts
@@ -1,14 +1,14 @@
import { useRouter } from 'next/router';
import { useCallback, useEffect, useState } from 'react';
-export const useSearchFilter = (
+export const useSearchFilter = (
name: string,
- defaultValues?: Array,
+ defaultValues?: Array,
) => {
const [isInitialized, setIsInitialized] = useState(false);
const router = useRouter();
- const [filters, setFilters] = useState>(defaultValues || []);
+ const [filters, setFilters] = useState>(defaultValues || []);
useEffect(() => {
if (router.isReady && !isInitialized) {
@@ -16,7 +16,7 @@ export const useSearchFilter = (
const query = router.query[name];
if (query) {
const queryValues = Array.isArray(query) ? query : [query];
- setFilters(queryValues);
+ setFilters(queryValues as Array);
} else {
// Try to load from local storage
const localStorageValue = localStorage.getItem(name);
@@ -37,7 +37,7 @@ export const useSearchFilter = (
}, [isInitialized, name, router]);
const setFiltersCallback = useCallback(
- (newFilters: Array) => {
+ (newFilters: Array) => {
setFilters(newFilters);
localStorage.setItem(name, JSON.stringify(newFilters));
router.replace({
@@ -54,14 +54,17 @@ export const useSearchFilter = (
return [filters, setFiltersCallback, isInitialized] as const;
};
-export const useSearchFilterSingle = (name: string, defaultValue: string) => {
+export const useSearchFilterSingle = (
+ name: string,
+ defaultValue: Value,
+) => {
const [filters, setFilters, isInitialized] = useSearchFilter(name, [
defaultValue,
]);
return [
filters[0],
- (value: string) => {
+ (value: Value) => {
setFilters([value]);
},
isInitialized,