Skip to content

Commit bb4c53e

Browse files
committed
Increment Question Details Views
1 parent 35ed439 commit bb4c53e

File tree

5 files changed

+86
-1
lines changed

5 files changed

+86
-1
lines changed

app/(root)/questions/[id]/page.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import { getQuestion } from "@/lib/actions/question.action";
77
import { formatNumber, getTimeStamp } from "@/lib/utils";
88
import Link from "next/link";
99
import { redirect } from "next/navigation";
10-
import { title } from "process";
1110
import React from "react";
11+
import View from "../view";
1212

1313
const QuestionDetails = async ({ params }: RouteParams) => {
1414
const { id } = await params;
@@ -20,6 +20,8 @@ const QuestionDetails = async ({ params }: RouteParams) => {
2020

2121
return (
2222
<>
23+
<View questionId={id} />
24+
2325
<div className="flex-start w-full flex-col">
2426
<div className="flex w-full flex-col-reverse justify-between">
2527
<div className="flex items-center justify-start gap-1">

app/(root)/questions/view.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"use client";
2+
3+
import { toast } from "@/hooks/use-toast";
4+
import { incrementViews } from "@/lib/actions/question.action";
5+
import { useEffect } from "react";
6+
7+
const View = ({ questionId }: { questionId: string }) => {
8+
const handleIncrement = async () => {
9+
const result = await incrementViews({ questionId });
10+
11+
if (result.success) {
12+
toast({
13+
title: "Success",
14+
description: "Views incremented",
15+
});
16+
} else {
17+
toast({
18+
title: "Error",
19+
description: result.error?.message,
20+
variant: "destructive",
21+
});
22+
}
23+
};
24+
25+
useEffect(() => {
26+
handleIncrement();
27+
}, []);
28+
29+
return null;
30+
};
31+
32+
export default View;

lib/actions/question.action.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@ import {
1212
AskQuestionSchema,
1313
EditQuestionSchema,
1414
GetQuestionSchema,
15+
IncrementViewsSchema,
1516
PaginatedSearchParamsSchema,
1617
} from "../validations";
18+
import { revalidatePath } from "next/cache";
19+
import ROUTES from "@/constants/routes";
1720

1821
export async function createQuestion(
1922
params: CreateQuestionParams
@@ -200,6 +203,10 @@ export async function getQuestion(
200203
return handleError(validationResult) as ErrorResponse;
201204
}
202205

206+
if (validationResult instanceof Error) {
207+
return handleError(validationResult) as ErrorResponse;
208+
}
209+
203210
const { questionId } = validationResult.params!;
204211

205212
try {
@@ -285,3 +292,39 @@ export async function getQuestions(
285292
return handleError(error) as ErrorResponse;
286293
}
287294
}
295+
296+
export async function incrementViews(
297+
params: IncrementViewsParams
298+
): Promise<ActionResponse<{ views: number }>> {
299+
const validationResult = await action({
300+
params,
301+
schema: IncrementViewsSchema,
302+
});
303+
304+
if (validationResult instanceof Error) {
305+
return handleError(validationResult) as ErrorResponse;
306+
}
307+
308+
const { questionId } = validationResult.params!;
309+
310+
try {
311+
const question = await Question.findById(questionId);
312+
313+
if (!question) {
314+
throw new Error("Question not found");
315+
}
316+
317+
question.views += 1;
318+
319+
await question.save();
320+
321+
revalidatePath(ROUTES.QUESTION(questionId));
322+
323+
return {
324+
success: true,
325+
data: { views: question.views },
326+
};
327+
} catch (error) {
328+
return handleError(error) as ErrorResponse;
329+
}
330+
}

lib/validations.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,3 +145,7 @@ export const PaginatedSearchParamsSchema = z.object({
145145
export const GetTagQuestionsSchema = PaginatedSearchParamsSchema.extend({
146146
tagId: z.string().min(1, { message: "Tag ID is required." }),
147147
});
148+
149+
export const IncrementViewsSchema = z.object({
150+
questionId: z.string().min(1, { message: "Question ID is required." }),
151+
});

types/action.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,7 @@ interface GetQuestionParams {
3333
interface GetTagQuestionsParams extends Omit<PaginatedSearchParams, "filter"> {
3434
tagId: string;
3535
}
36+
37+
interface IncrementViewsParams {
38+
questionId: string;
39+
}

0 commit comments

Comments
 (0)