Skip to content

Commit 8904a64

Browse files
committed
Implemented Interaction model and server-action
1 parent 288ad07 commit 8904a64

File tree

3 files changed

+73
-2
lines changed

3 files changed

+73
-2
lines changed

components/shared/Votes.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
"use client";
22

3+
import { useEffect } from "react";
34
import Image from "next/image";
4-
import { usePathname } from "next/navigation";
5+
import { usePathname, useRouter } from "next/navigation";
56

67
import { upvoteAnswer, downvoteAnswer } from "@/lib/actions/answer.action";
7-
8+
import { viewQuestion } from "@/lib/actions/interaction.action";
89
import {
910
downvoteQuestion,
1011
upvoteQuestion,
@@ -32,8 +33,16 @@ const Votes = ({
3233
hasdownVoted,
3334
hasSaved,
3435
}: Props) => {
36+
const router = useRouter();
3537
const pathname = usePathname();
3638

39+
useEffect(() => {
40+
viewQuestion({
41+
questionId: JSON.parse(itemId),
42+
userId: userId ? JSON.parse(userId) : undefined,
43+
});
44+
}, [itemId, userId, pathname, router]);
45+
3746
const handleSave = async () => {
3847
await toggleSaveQuestion({
3948
userId: JSON.parse(userId),

database/interaction.model.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Schema, models, model, Document } from "mongoose";
2+
3+
export interface IInteraction extends Document {
4+
user: Schema.Types.ObjectId;
5+
action: string;
6+
question: Schema.Types.ObjectId;
7+
answer: Schema.Types.ObjectId;
8+
tags: Schema.Types.ObjectId[];
9+
createdAt: Date;
10+
}
11+
12+
const InteractionSchema = new Schema({
13+
user: { type: Schema.Types.ObjectId, ref: "User", required: true },
14+
action: { type: String, required: true },
15+
question: { type: Schema.Types.ObjectId, ref: "Question" },
16+
answer: { type: Schema.Types.ObjectId, ref: "Answer" },
17+
tags: [{ type: Schema.Types.ObjectId, ref: "Tag" }],
18+
createdAt: { type: Date, default: Date.now },
19+
});
20+
21+
const Interaction =
22+
models.Interaction || model("Interaction", InteractionSchema);
23+
24+
export default Interaction;

lib/actions/interaction.action.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"use server";
2+
3+
import Question from "@/database/question.model";
4+
import Interaction from "@/database/interaction.model";
5+
6+
import { connectToDatabase } from "@/lib/mongoose";
7+
8+
import type { ViewQuestionParams } from "./shared.types";
9+
10+
export async function viewQuestion(params: ViewQuestionParams) {
11+
try {
12+
connectToDatabase();
13+
14+
const { questionId, userId } = params;
15+
16+
// update view count for the question
17+
await Question.findByIdAndUpdate(questionId, { $inc: { views: 1 } });
18+
19+
if (userId) {
20+
const existingInteraction = await Interaction.findOne({
21+
user: userId,
22+
action: "view",
23+
question: questionId,
24+
});
25+
26+
if (existingInteraction) return console.log("User has already viewed.");
27+
28+
await Interaction.create({
29+
user: userId,
30+
action: "view",
31+
question: questionId,
32+
});
33+
}
34+
} catch (error) {
35+
console.log(error);
36+
throw error;
37+
}
38+
}

0 commit comments

Comments
 (0)