source: petify-frontend/src/api/reviews.ts

Last change on this file was 92e7c7a, checked in by veronika-ils <ilioskaveronika@…>, 7 hours ago

Petify fullstack project

  • Property mode set to 100644
File size: 5.0 KB
RevLine 
[92e7c7a]1function getBaseUrl(): string {
2 const base = (import.meta.env.VITE_API_BASE_URL as string | undefined) ?? ''
3 return base.replace(/\/$/, '')
4}
5
6function joinUrl(base: string, path: string): string {
7 if (!base) return path
8 return `${base}${path.startsWith('/') ? '' : '/'}${path}`
9}
10
11export interface Review {
12 reviewId: number
13 reviewerId: number
14 reviewerName: string
15 reviewerUsername: string
16 rating: number
17 comment: string
18 createdAt: string
19 updatedAt?: string
20}
21
22export async function createReview(
23 targetUserId: number,
24 userId: number,
25 rating: number,
26 comment: string
27): Promise<Review> {
28 const url = joinUrl(getBaseUrl(), `/api/reviews/${targetUserId}`)
29 const response = await fetch(url, {
30 method: 'POST',
31 headers: {
32 'Content-Type': 'application/json',
33 'X-User-Id': String(userId),
34 },
35 body: JSON.stringify({
36 rating,
37 comment,
38 }),
39 })
40
41 if (!response.ok) {
42 const error = await response.json()
43 throw new Error(error.error || 'Failed to create review')
44 }
45
46 return await response.json()
47}
48
49export async function getReviewsByOwner(targetUserId: number): Promise<Review[]> {
50 const url = joinUrl(getBaseUrl(), `/api/reviews/${targetUserId}`)
51 const response = await fetch(url, {
52 method: 'GET',
53 headers: {
54 'Content-Type': 'application/json',
55 },
56 })
57
58 if (!response.ok) {
59 const text = await response.text()
60 throw new Error(`Failed to fetch reviews: ${response.status} ${response.statusText}. ${text.slice(0, 160)}`)
61 }
62
63 return await readJsonResponse<Review[]>(response, 'reviews')
64}
65
66export async function getReviewsLeftByUser(reviewerId: number): Promise<Review[]> {
67 const url = joinUrl(getBaseUrl(), `/api/reviews/by/${reviewerId}`)
68 const response = await fetch(url, {
69 method: 'GET',
70 headers: {
71 'Content-Type': 'application/json',
72 },
73 })
74
75 if (!response.ok) {
76 const text = await response.text()
77 throw new Error(`Failed to fetch reviews left by user: ${response.status} ${response.statusText}. ${text.slice(0, 160)}`)
78 }
79
80 return await readJsonResponse<Review[]>(response, 'reviews left by user')
81}
82
83export async function getReviewsByClinic(clinicId: number): Promise<Review[]> {
84 const url = joinUrl(getBaseUrl(), `/api/reviews/clinics/${clinicId}`)
85 const response = await fetch(url, {
86 method: 'GET',
87 headers: {
88 'Content-Type': 'application/json',
89 },
90 })
91
92 if (!response.ok) {
93 throw new Error('Failed to fetch clinic reviews')
94 }
95
96 return await response.json()
97}
98
99export async function createClinicReview(
100 clinicId: number,
101 userId: number,
102 rating: number,
103 comment: string
104): Promise<Review> {
105 const url = joinUrl(getBaseUrl(), `/api/reviews/clinics/${clinicId}`)
106 const response = await fetch(url, {
107 method: 'POST',
108 headers: {
109 'Content-Type': 'application/json',
110 'X-User-Id': String(userId),
111 },
112 body: JSON.stringify({
113 rating,
114 comment,
115 }),
116 })
117
118 if (!response.ok) {
119 const error = await response.json()
120 throw new Error(error.error || 'Failed to create clinic review')
121 }
122
123 return await response.json()
124}
125
126export async function getMyClinicReview(clinicId: number, userId: number): Promise<Review | null> {
127 const url = joinUrl(getBaseUrl(), `/api/reviews/clinics/${clinicId}/mine`)
128 const response = await fetch(url, {
129 method: 'GET',
130 headers: {
131 'Content-Type': 'application/json',
132 'X-User-Id': String(userId),
133 },
134 })
135
136 if (response.status === 204) {
137 return null
138 }
139
140 if (!response.ok) {
141 const error = await response.json()
142 throw new Error(error.error || 'Failed to fetch clinic review')
143 }
144
145 return await response.json()
146}
147
148export async function updateReview(
149 reviewId: number,
150 userId: number,
151 rating: number,
152 comment: string
153): Promise<Review> {
154 const url = joinUrl(getBaseUrl(), `/api/reviews/${reviewId}`)
155 const response = await fetch(url, {
156 method: 'PUT',
157 headers: {
158 'Content-Type': 'application/json',
159 'X-User-Id': String(userId),
160 },
161 body: JSON.stringify({
162 rating,
163 comment,
164 }),
165 })
166
167 if (!response.ok) {
168 const error = await response.json()
169 throw new Error(error.error || 'Failed to update review')
170 }
171
172 return await response.json()
173}
174
175export async function deleteReview(reviewId: number, userId: number): Promise<void> {
176 const url = joinUrl(getBaseUrl(), `/api/reviews/${reviewId}`)
177 const response = await fetch(url, {
178 method: 'DELETE',
179 headers: {
180 'Content-Type': 'application/json',
181 'X-User-Id': String(userId),
182 },
183 })
184
185 if (!response.ok) {
186 const error = await response.json()
187 throw new Error(error.error || 'Failed to delete review')
188 }
189}
190
191async function readJsonResponse<T>(response: Response, label: string): Promise<T> {
192 const contentType = response.headers.get('content-type') || ''
193 const text = await response.text()
194
195 if (!contentType.includes('application/json')) {
196 throw new Error(`Expected JSON for ${label}, but backend returned non-JSON. ${text.slice(0, 160)}`)
197 }
198
199 return JSON.parse(text) as T
200}
Note: See TracBrowser for help on using the repository browser.