1
+ import { answerCollection , db , questionCollection , voteCollection } from "@/models/name" ;
2
+ import { databases , users } from "@/models/server/config" ;
3
+ import { UserPrefs } from "@/store/Auth" ;
4
+ import { NextRequest , NextResponse } from "next/server" ;
5
+ import { ID , Query } from "node-appwrite" ;
6
+
7
+ export async function POST ( request : NextRequest ) {
8
+ try {
9
+ const { votedById, voteStatus, type, typeId } = await request . json ( ) ;
10
+
11
+ const response = await databases . listDocuments ( db , voteCollection , [
12
+ Query . equal ( "type" , type ) ,
13
+ Query . equal ( "typeId" , typeId ) ,
14
+ Query . equal ( "votedById" , votedById ) ,
15
+ ] ) ;
16
+
17
+ if ( response . documents . length > 0 ) {
18
+ await databases . deleteDocument ( db , voteCollection , response . documents [ 0 ] . $id ) ;
19
+
20
+ // Decrease the reputation of the question/answer author
21
+ const questionOrAnswer = await databases . getDocument (
22
+ db ,
23
+ type === "question" ? questionCollection : answerCollection ,
24
+ typeId
25
+ ) ;
26
+
27
+ const authorPrefs = await users . getPrefs < UserPrefs > ( questionOrAnswer . authorId ) ;
28
+
29
+ await users . updatePrefs < UserPrefs > ( questionOrAnswer . authorId , {
30
+ reputation :
31
+ response . documents [ 0 ] . voteStatus === "upvoted"
32
+ ? Number ( authorPrefs . reputation ) - 1
33
+ : Number ( authorPrefs . reputation ) + 1 ,
34
+ } ) ;
35
+ }
36
+
37
+ // that means prev vote does not exists or voteStatus changed
38
+ if ( response . documents [ 0 ] ?. voteStatus !== voteStatus ) {
39
+ const doc = await databases . createDocument ( db , voteCollection , ID . unique ( ) , {
40
+ type,
41
+ typeId,
42
+ voteStatus,
43
+ votedById,
44
+ } ) ;
45
+
46
+ // Increate/Decrease the reputation of the question/answer author accordingly
47
+ const questionOrAnswer = await databases . getDocument (
48
+ db ,
49
+ type === "question" ? questionCollection : answerCollection ,
50
+ typeId
51
+ ) ;
52
+
53
+ const authorPrefs = await users . getPrefs < UserPrefs > ( questionOrAnswer . authorId ) ;
54
+
55
+ // if vote was present
56
+ if ( response . documents [ 0 ] ) {
57
+ await users . updatePrefs < UserPrefs > ( questionOrAnswer . authorId , {
58
+ reputation :
59
+ // that means prev vote was "upvoted" and new value is "downvoted" so we have to decrease the reputation
60
+ response . documents [ 0 ] . voteStatus === "upvoted"
61
+ ? Number ( authorPrefs . reputation ) - 1
62
+ : Number ( authorPrefs . reputation ) + 1 ,
63
+ } ) ;
64
+ } else {
65
+ await users . updatePrefs < UserPrefs > ( questionOrAnswer . authorId , {
66
+ reputation :
67
+ // that means prev vote was "upvoted" and new value is "downvoted" so we have to decrease the reputation
68
+ voteStatus === "upvoted"
69
+ ? Number ( authorPrefs . reputation ) + 1
70
+ : Number ( authorPrefs . reputation ) - 1 ,
71
+ } ) ;
72
+ }
73
+
74
+ const [ upvotes , downvotes ] = await Promise . all ( [
75
+ databases . listDocuments ( db , voteCollection , [
76
+ Query . equal ( "type" , type ) ,
77
+ Query . equal ( "typeId" , typeId ) ,
78
+ Query . equal ( "voteStatus" , "upvoted" ) ,
79
+ Query . equal ( "votedById" , votedById ) ,
80
+ Query . limit ( 1 ) , // for optimization as we only need total
81
+ ] ) ,
82
+ databases . listDocuments ( db , voteCollection , [
83
+ Query . equal ( "type" , type ) ,
84
+ Query . equal ( "typeId" , typeId ) ,
85
+ Query . equal ( "voteStatus" , "downvoted" ) ,
86
+ Query . equal ( "votedById" , votedById ) ,
87
+ Query . limit ( 1 ) , // for optimization as we only need total
88
+ ] ) ,
89
+ ] ) ;
90
+
91
+ return NextResponse . json (
92
+ {
93
+ data : { document : doc , voteResult : upvotes . total - downvotes . total } ,
94
+ message : response . documents [ 0 ] ? "Vote Status Updated" : "Voted" ,
95
+ } ,
96
+ {
97
+ status : 201 ,
98
+ }
99
+ ) ;
100
+ }
101
+
102
+ const [ upvotes , downvotes ] = await Promise . all ( [
103
+ databases . listDocuments ( db , voteCollection , [
104
+ Query . equal ( "type" , type ) ,
105
+ Query . equal ( "typeId" , typeId ) ,
106
+ Query . equal ( "voteStatus" , "upvoted" ) ,
107
+ Query . equal ( "votedById" , votedById ) ,
108
+ Query . limit ( 1 ) , // for optimization as we only need total
109
+ ] ) ,
110
+ databases . listDocuments ( db , voteCollection , [
111
+ Query . equal ( "type" , type ) ,
112
+ Query . equal ( "typeId" , typeId ) ,
113
+ Query . equal ( "voteStatus" , "downvoted" ) ,
114
+ Query . equal ( "votedById" , votedById ) ,
115
+ Query . limit ( 1 ) , // for optimization as we only need total
116
+ ] ) ,
117
+ ] ) ;
118
+
119
+ return NextResponse . json (
120
+ {
121
+ data : {
122
+ document : null , voteResult : upvotes . total - downvotes . total
123
+ } ,
124
+ message : "Vote Withdrawn" ,
125
+ } ,
126
+ {
127
+ status : 200 ,
128
+ }
129
+ ) ;
130
+ } catch ( error : any ) {
131
+ return NextResponse . json (
132
+ { message : error ?. message || "Error deleting answer" } ,
133
+ { status : error ?. status || error ?. code || 500 }
134
+ ) ;
135
+ }
136
+ }
0 commit comments