@blackcode_sa/metaestetics-api 1.8.17 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +233 -205
- package/dist/index.mjs +236 -210
- package/package.json +1 -1
- package/src/services/clinic/clinic.service.ts +91 -142
- package/src/services/clinic/utils/filter.utils.ts +180 -96
- package/src/services/practitioner/practitioner.service.ts +31 -0
- package/src/services/procedure/procedure.service.ts +326 -362
package/package.json
CHANGED
|
@@ -16,8 +16,8 @@ import {
|
|
|
16
16
|
writeBatch,
|
|
17
17
|
arrayUnion,
|
|
18
18
|
arrayRemove,
|
|
19
|
-
} from
|
|
20
|
-
import { BaseService } from
|
|
19
|
+
} from 'firebase/firestore';
|
|
20
|
+
import { BaseService } from '../base.service';
|
|
21
21
|
import {
|
|
22
22
|
Clinic,
|
|
23
23
|
CreateClinicData,
|
|
@@ -29,35 +29,31 @@ import {
|
|
|
29
29
|
ClinicBranchSetupData,
|
|
30
30
|
CLINIC_ADMINS_COLLECTION,
|
|
31
31
|
DoctorInfo,
|
|
32
|
-
} from
|
|
32
|
+
} from '../../types/clinic';
|
|
33
33
|
// Correct imports
|
|
34
|
-
import { ProcedureSummaryInfo } from
|
|
35
|
-
import { ClinicInfo } from
|
|
36
|
-
import { ClinicGroupService } from
|
|
37
|
-
import { ClinicAdminService } from
|
|
38
|
-
import {
|
|
39
|
-
geohashForLocation,
|
|
40
|
-
geohashQueryBounds,
|
|
41
|
-
distanceBetween,
|
|
42
|
-
} from "geofire-common";
|
|
34
|
+
import { ProcedureSummaryInfo } from '../../types/procedure';
|
|
35
|
+
import { ClinicInfo } from '../../types/profile';
|
|
36
|
+
import { ClinicGroupService } from './clinic-group.service';
|
|
37
|
+
import { ClinicAdminService } from './clinic-admin.service';
|
|
38
|
+
import { geohashForLocation, geohashQueryBounds, distanceBetween } from 'geofire-common';
|
|
43
39
|
import {
|
|
44
40
|
clinicSchema,
|
|
45
41
|
createClinicSchema,
|
|
46
42
|
updateClinicSchema,
|
|
47
43
|
clinicBranchSetupSchema,
|
|
48
|
-
} from
|
|
49
|
-
import { z } from
|
|
50
|
-
import { Auth } from
|
|
51
|
-
import { Firestore } from
|
|
52
|
-
import { FirebaseApp } from
|
|
53
|
-
import * as ClinicUtils from
|
|
54
|
-
import * as TagUtils from
|
|
55
|
-
import * as SearchUtils from
|
|
56
|
-
import * as AdminUtils from
|
|
57
|
-
import * as FilterUtils from
|
|
58
|
-
import { ClinicReviewInfo } from
|
|
59
|
-
import { PRACTITIONERS_COLLECTION } from
|
|
60
|
-
import { MediaService, MediaAccessLevel } from
|
|
44
|
+
} from '../../validations/clinic.schema';
|
|
45
|
+
import { z } from 'zod';
|
|
46
|
+
import { Auth } from 'firebase/auth';
|
|
47
|
+
import { Firestore } from 'firebase/firestore';
|
|
48
|
+
import { FirebaseApp } from 'firebase/app';
|
|
49
|
+
import * as ClinicUtils from './utils/clinic.utils';
|
|
50
|
+
import * as TagUtils from './utils/tag.utils';
|
|
51
|
+
import * as SearchUtils from './utils/search.utils';
|
|
52
|
+
import * as AdminUtils from './utils/admin.utils';
|
|
53
|
+
import * as FilterUtils from './utils/filter.utils';
|
|
54
|
+
import { ClinicReviewInfo } from '../../types/reviews';
|
|
55
|
+
import { PRACTITIONERS_COLLECTION } from '../../types/practitioner';
|
|
56
|
+
import { MediaService, MediaAccessLevel } from '../media/media.service';
|
|
61
57
|
|
|
62
58
|
export class ClinicService extends BaseService {
|
|
63
59
|
private clinicGroupService: ClinicGroupService;
|
|
@@ -70,7 +66,7 @@ export class ClinicService extends BaseService {
|
|
|
70
66
|
app: FirebaseApp,
|
|
71
67
|
clinicGroupService: ClinicGroupService,
|
|
72
68
|
clinicAdminService: ClinicAdminService,
|
|
73
|
-
mediaService: MediaService
|
|
69
|
+
mediaService: MediaService,
|
|
74
70
|
) {
|
|
75
71
|
super(db, auth, app);
|
|
76
72
|
this.clinicAdminService = clinicAdminService;
|
|
@@ -88,25 +84,23 @@ export class ClinicService extends BaseService {
|
|
|
88
84
|
private async processMedia(
|
|
89
85
|
media: string | File | Blob | null | undefined,
|
|
90
86
|
ownerId: string,
|
|
91
|
-
collectionName: string
|
|
87
|
+
collectionName: string,
|
|
92
88
|
): Promise<string | null> {
|
|
93
89
|
if (!media) return null;
|
|
94
90
|
|
|
95
91
|
// If already a string URL, return it directly
|
|
96
|
-
if (typeof media ===
|
|
92
|
+
if (typeof media === 'string') {
|
|
97
93
|
return media;
|
|
98
94
|
}
|
|
99
95
|
|
|
100
96
|
// If it's a File, upload it using MediaService
|
|
101
97
|
if (media instanceof File || media instanceof Blob) {
|
|
102
|
-
console.log(
|
|
103
|
-
`[ClinicService] Uploading ${collectionName} media for ${ownerId}`
|
|
104
|
-
);
|
|
98
|
+
console.log(`[ClinicService] Uploading ${collectionName} media for ${ownerId}`);
|
|
105
99
|
const metadata = await this.mediaService.uploadMedia(
|
|
106
100
|
media,
|
|
107
101
|
ownerId,
|
|
108
102
|
MediaAccessLevel.PUBLIC,
|
|
109
|
-
collectionName
|
|
103
|
+
collectionName,
|
|
110
104
|
);
|
|
111
105
|
return metadata.url;
|
|
112
106
|
}
|
|
@@ -124,18 +118,14 @@ export class ClinicService extends BaseService {
|
|
|
124
118
|
private async processMediaArray(
|
|
125
119
|
mediaArray: (string | File | Blob)[] | undefined,
|
|
126
120
|
ownerId: string,
|
|
127
|
-
collectionName: string
|
|
121
|
+
collectionName: string,
|
|
128
122
|
): Promise<string[]> {
|
|
129
123
|
if (!mediaArray || mediaArray.length === 0) return [];
|
|
130
124
|
|
|
131
125
|
const result: string[] = [];
|
|
132
126
|
|
|
133
127
|
for (const media of mediaArray) {
|
|
134
|
-
const processedUrl = await this.processMedia(
|
|
135
|
-
media,
|
|
136
|
-
ownerId,
|
|
137
|
-
collectionName
|
|
138
|
-
);
|
|
128
|
+
const processedUrl = await this.processMedia(media, ownerId, collectionName);
|
|
139
129
|
if (processedUrl) {
|
|
140
130
|
result.push(processedUrl);
|
|
141
131
|
}
|
|
@@ -154,18 +144,14 @@ export class ClinicService extends BaseService {
|
|
|
154
144
|
private async processPhotosWithTags(
|
|
155
145
|
photosWithTags: { url: string | File | Blob; tag: string }[] | undefined,
|
|
156
146
|
ownerId: string,
|
|
157
|
-
collectionName: string
|
|
147
|
+
collectionName: string,
|
|
158
148
|
): Promise<{ url: string; tag: string }[]> {
|
|
159
149
|
if (!photosWithTags || photosWithTags.length === 0) return [];
|
|
160
150
|
|
|
161
151
|
const result: { url: string; tag: string }[] = [];
|
|
162
152
|
|
|
163
153
|
for (const item of photosWithTags) {
|
|
164
|
-
const processedUrl = await this.processMedia(
|
|
165
|
-
item.url,
|
|
166
|
-
ownerId,
|
|
167
|
-
collectionName
|
|
168
|
-
);
|
|
154
|
+
const processedUrl = await this.processMedia(item.url, ownerId, collectionName);
|
|
169
155
|
if (processedUrl) {
|
|
170
156
|
result.push({
|
|
171
157
|
url: processedUrl,
|
|
@@ -181,10 +167,7 @@ export class ClinicService extends BaseService {
|
|
|
181
167
|
* Creates a new clinic.
|
|
182
168
|
* Handles both URL strings and File uploads for media fields.
|
|
183
169
|
*/
|
|
184
|
-
async createClinic(
|
|
185
|
-
data: CreateClinicData,
|
|
186
|
-
creatorAdminId: string
|
|
187
|
-
): Promise<Clinic> {
|
|
170
|
+
async createClinic(data: CreateClinicData, creatorAdminId: string): Promise<Clinic> {
|
|
188
171
|
try {
|
|
189
172
|
// Generate ID first so we can use it for media uploads
|
|
190
173
|
const clinicId = this.generateId();
|
|
@@ -192,35 +175,27 @@ export class ClinicService extends BaseService {
|
|
|
192
175
|
// Validate data - this now works because mediaResourceSchema has been updated to support Files/Blobs
|
|
193
176
|
const validatedData = createClinicSchema.parse(data);
|
|
194
177
|
|
|
195
|
-
const group = await this.clinicGroupService.getClinicGroup(
|
|
196
|
-
validatedData.clinicGroupId
|
|
197
|
-
);
|
|
178
|
+
const group = await this.clinicGroupService.getClinicGroup(validatedData.clinicGroupId);
|
|
198
179
|
if (!group) {
|
|
199
|
-
throw new Error(
|
|
200
|
-
`Clinic group ${validatedData.clinicGroupId} not found`
|
|
201
|
-
);
|
|
180
|
+
throw new Error(`Clinic group ${validatedData.clinicGroupId} not found`);
|
|
202
181
|
}
|
|
203
182
|
|
|
204
183
|
// Process media fields - convert File/Blob objects to URLs
|
|
205
|
-
const logoUrl = await this.processMedia(
|
|
206
|
-
validatedData.logo,
|
|
207
|
-
clinicId,
|
|
208
|
-
"clinic-logos"
|
|
209
|
-
);
|
|
184
|
+
const logoUrl = await this.processMedia(validatedData.logo, clinicId, 'clinic-logos');
|
|
210
185
|
const coverPhotoUrl = await this.processMedia(
|
|
211
186
|
validatedData.coverPhoto,
|
|
212
187
|
clinicId,
|
|
213
|
-
|
|
188
|
+
'clinic-cover-photos',
|
|
214
189
|
);
|
|
215
190
|
const featuredPhotos = await this.processMediaArray(
|
|
216
191
|
validatedData.featuredPhotos,
|
|
217
192
|
clinicId,
|
|
218
|
-
|
|
193
|
+
'clinic-featured-photos',
|
|
219
194
|
);
|
|
220
195
|
const photosWithTags = await this.processPhotosWithTags(
|
|
221
196
|
validatedData.photosWithTags,
|
|
222
197
|
clinicId,
|
|
223
|
-
|
|
198
|
+
'clinic-gallery',
|
|
224
199
|
);
|
|
225
200
|
|
|
226
201
|
const location = validatedData.location;
|
|
@@ -237,7 +212,7 @@ export class ClinicService extends BaseService {
|
|
|
237
212
|
recommendationPercentage: 0,
|
|
238
213
|
};
|
|
239
214
|
|
|
240
|
-
const clinicData: Omit<Clinic,
|
|
215
|
+
const clinicData: Omit<Clinic, 'createdAt' | 'updatedAt'> & {
|
|
241
216
|
createdAt: FieldValue;
|
|
242
217
|
updatedAt: FieldValue;
|
|
243
218
|
} = {
|
|
@@ -259,12 +234,8 @@ export class ClinicService extends BaseService {
|
|
|
259
234
|
proceduresInfo: validatedData.proceduresInfo || [],
|
|
260
235
|
reviewInfo: defaultReviewInfo,
|
|
261
236
|
admins: [creatorAdminId],
|
|
262
|
-
isActive:
|
|
263
|
-
|
|
264
|
-
isVerified:
|
|
265
|
-
validatedData.isVerified !== undefined
|
|
266
|
-
? validatedData.isVerified
|
|
267
|
-
: false,
|
|
237
|
+
isActive: validatedData.isActive !== undefined ? validatedData.isActive : true,
|
|
238
|
+
isVerified: validatedData.isVerified !== undefined ? validatedData.isVerified : false,
|
|
268
239
|
logo: logoUrl,
|
|
269
240
|
createdAt: serverTimestamp(),
|
|
270
241
|
updatedAt: serverTimestamp(),
|
|
@@ -295,13 +266,13 @@ export class ClinicService extends BaseService {
|
|
|
295
266
|
console.log(`[ClinicService] Clinic created successfully: ${clinicId}`);
|
|
296
267
|
|
|
297
268
|
const savedClinic = await this.getClinic(clinicId);
|
|
298
|
-
if (!savedClinic) throw new Error(
|
|
269
|
+
if (!savedClinic) throw new Error('Failed to retrieve created clinic');
|
|
299
270
|
return savedClinic;
|
|
300
271
|
} catch (error) {
|
|
301
272
|
if (error instanceof z.ZodError) {
|
|
302
|
-
throw new Error(
|
|
273
|
+
throw new Error('Invalid clinic data: ' + error.message);
|
|
303
274
|
}
|
|
304
|
-
console.error(
|
|
275
|
+
console.error('Error creating clinic:', error);
|
|
305
276
|
throw error;
|
|
306
277
|
}
|
|
307
278
|
}
|
|
@@ -313,7 +284,7 @@ export class ClinicService extends BaseService {
|
|
|
313
284
|
async updateClinic(
|
|
314
285
|
clinicId: string,
|
|
315
286
|
data: Partial<CreateClinicData>,
|
|
316
|
-
adminId: string
|
|
287
|
+
adminId: string,
|
|
317
288
|
): Promise<Clinic> {
|
|
318
289
|
try {
|
|
319
290
|
// First check if clinic exists
|
|
@@ -333,18 +304,14 @@ export class ClinicService extends BaseService {
|
|
|
333
304
|
|
|
334
305
|
// Process media fields if provided
|
|
335
306
|
if (validatedData.logo !== undefined) {
|
|
336
|
-
updatePayload.logo = await this.processMedia(
|
|
337
|
-
validatedData.logo,
|
|
338
|
-
clinicId,
|
|
339
|
-
"clinic-logos"
|
|
340
|
-
);
|
|
307
|
+
updatePayload.logo = await this.processMedia(validatedData.logo, clinicId, 'clinic-logos');
|
|
341
308
|
}
|
|
342
309
|
|
|
343
310
|
if (validatedData.coverPhoto !== undefined) {
|
|
344
311
|
updatePayload.coverPhoto = await this.processMedia(
|
|
345
312
|
validatedData.coverPhoto,
|
|
346
313
|
clinicId,
|
|
347
|
-
|
|
314
|
+
'clinic-cover-photos',
|
|
348
315
|
);
|
|
349
316
|
}
|
|
350
317
|
|
|
@@ -352,7 +319,7 @@ export class ClinicService extends BaseService {
|
|
|
352
319
|
updatePayload.featuredPhotos = await this.processMediaArray(
|
|
353
320
|
validatedData.featuredPhotos,
|
|
354
321
|
clinicId,
|
|
355
|
-
|
|
322
|
+
'clinic-featured-photos',
|
|
356
323
|
);
|
|
357
324
|
}
|
|
358
325
|
|
|
@@ -360,28 +327,27 @@ export class ClinicService extends BaseService {
|
|
|
360
327
|
updatePayload.photosWithTags = await this.processPhotosWithTags(
|
|
361
328
|
validatedData.photosWithTags,
|
|
362
329
|
clinicId,
|
|
363
|
-
|
|
330
|
+
'clinic-gallery',
|
|
364
331
|
);
|
|
365
332
|
}
|
|
366
333
|
|
|
367
334
|
// Process non-media fields
|
|
368
335
|
const fieldsToUpdate = [
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
336
|
+
'name',
|
|
337
|
+
'description',
|
|
338
|
+
'contactInfo',
|
|
339
|
+
'workingHours',
|
|
340
|
+
'tags',
|
|
341
|
+
'doctors',
|
|
342
|
+
'procedures',
|
|
343
|
+
'proceduresInfo',
|
|
344
|
+
'isActive',
|
|
345
|
+
'isVerified',
|
|
379
346
|
];
|
|
380
347
|
|
|
381
348
|
for (const field of fieldsToUpdate) {
|
|
382
349
|
if (validatedData[field as keyof typeof validatedData] !== undefined) {
|
|
383
|
-
updatePayload[field] =
|
|
384
|
-
validatedData[field as keyof typeof validatedData];
|
|
350
|
+
updatePayload[field] = validatedData[field as keyof typeof validatedData];
|
|
385
351
|
}
|
|
386
352
|
}
|
|
387
353
|
|
|
@@ -408,11 +374,11 @@ export class ClinicService extends BaseService {
|
|
|
408
374
|
|
|
409
375
|
// Return the updated clinic
|
|
410
376
|
const updatedClinic = await this.getClinic(clinicId);
|
|
411
|
-
if (!updatedClinic) throw new Error(
|
|
377
|
+
if (!updatedClinic) throw new Error('Failed to retrieve updated clinic');
|
|
412
378
|
return updatedClinic;
|
|
413
379
|
} catch (error) {
|
|
414
380
|
if (error instanceof z.ZodError) {
|
|
415
|
-
throw new Error(
|
|
381
|
+
throw new Error('Invalid clinic update data: ' + error.message);
|
|
416
382
|
}
|
|
417
383
|
console.error(`Error updating clinic ${clinicId}:`, error);
|
|
418
384
|
throw error;
|
|
@@ -467,14 +433,9 @@ export class ClinicService extends BaseService {
|
|
|
467
433
|
procedures?: string[];
|
|
468
434
|
tags?: ClinicTag[];
|
|
469
435
|
// Add other relevant filters based on Clinic/ProcedureSummaryInfo fields
|
|
470
|
-
}
|
|
436
|
+
},
|
|
471
437
|
): Promise<Clinic[]> {
|
|
472
|
-
return SearchUtils.findClinicsInRadius(
|
|
473
|
-
this.db,
|
|
474
|
-
center,
|
|
475
|
-
radiusInKm,
|
|
476
|
-
filters
|
|
477
|
-
);
|
|
438
|
+
return SearchUtils.findClinicsInRadius(this.db, center, radiusInKm, filters);
|
|
478
439
|
}
|
|
479
440
|
|
|
480
441
|
async addTags(
|
|
@@ -482,16 +443,9 @@ export class ClinicService extends BaseService {
|
|
|
482
443
|
adminId: string,
|
|
483
444
|
newTags: {
|
|
484
445
|
tags?: ClinicTag[];
|
|
485
|
-
}
|
|
446
|
+
},
|
|
486
447
|
): Promise<Clinic> {
|
|
487
|
-
return TagUtils.addTags(
|
|
488
|
-
this.db,
|
|
489
|
-
clinicId,
|
|
490
|
-
adminId,
|
|
491
|
-
newTags,
|
|
492
|
-
this.clinicAdminService,
|
|
493
|
-
this.app
|
|
494
|
-
);
|
|
448
|
+
return TagUtils.addTags(this.db, clinicId, adminId, newTags, this.clinicAdminService, this.app);
|
|
495
449
|
}
|
|
496
450
|
|
|
497
451
|
async removeTags(
|
|
@@ -499,7 +453,7 @@ export class ClinicService extends BaseService {
|
|
|
499
453
|
adminId: string,
|
|
500
454
|
tagsToRemove: {
|
|
501
455
|
tags?: ClinicTag[];
|
|
502
|
-
}
|
|
456
|
+
},
|
|
503
457
|
): Promise<Clinic> {
|
|
504
458
|
return TagUtils.removeTags(
|
|
505
459
|
this.db,
|
|
@@ -507,7 +461,7 @@ export class ClinicService extends BaseService {
|
|
|
507
461
|
adminId,
|
|
508
462
|
tagsToRemove,
|
|
509
463
|
this.clinicAdminService,
|
|
510
|
-
this.app
|
|
464
|
+
this.app,
|
|
511
465
|
);
|
|
512
466
|
}
|
|
513
467
|
|
|
@@ -516,14 +470,14 @@ export class ClinicService extends BaseService {
|
|
|
516
470
|
options?: {
|
|
517
471
|
isActive?: boolean;
|
|
518
472
|
includeGroupClinics?: boolean; // ako je true i admin je owner, uključuje sve klinike grupe
|
|
519
|
-
}
|
|
473
|
+
},
|
|
520
474
|
): Promise<Clinic[]> {
|
|
521
475
|
return ClinicUtils.getClinicsByAdmin(
|
|
522
476
|
this.db,
|
|
523
477
|
adminId,
|
|
524
478
|
options,
|
|
525
479
|
this.clinicAdminService,
|
|
526
|
-
this.clinicGroupService
|
|
480
|
+
this.clinicGroupService,
|
|
527
481
|
);
|
|
528
482
|
}
|
|
529
483
|
|
|
@@ -532,7 +486,7 @@ export class ClinicService extends BaseService {
|
|
|
532
486
|
this.db,
|
|
533
487
|
adminId,
|
|
534
488
|
this.clinicAdminService,
|
|
535
|
-
this.clinicGroupService
|
|
489
|
+
this.clinicGroupService,
|
|
536
490
|
);
|
|
537
491
|
}
|
|
538
492
|
|
|
@@ -543,24 +497,22 @@ export class ClinicService extends BaseService {
|
|
|
543
497
|
async createClinicBranch(
|
|
544
498
|
clinicGroupId: string,
|
|
545
499
|
setupData: ClinicBranchSetupData,
|
|
546
|
-
adminId: string
|
|
500
|
+
adminId: string,
|
|
547
501
|
): Promise<Clinic> {
|
|
548
|
-
console.log(
|
|
502
|
+
console.log('[CLINIC_SERVICE] Starting clinic branch creation', {
|
|
549
503
|
clinicGroupId,
|
|
550
504
|
adminId,
|
|
551
505
|
});
|
|
552
506
|
|
|
553
507
|
// Verify clinic group exists
|
|
554
|
-
const clinicGroup = await this.clinicGroupService.getClinicGroup(
|
|
555
|
-
clinicGroupId
|
|
556
|
-
);
|
|
508
|
+
const clinicGroup = await this.clinicGroupService.getClinicGroup(clinicGroupId);
|
|
557
509
|
if (!clinicGroup) {
|
|
558
|
-
console.error(
|
|
510
|
+
console.error('[CLINIC_SERVICE] Clinic group not found', {
|
|
559
511
|
clinicGroupId,
|
|
560
512
|
});
|
|
561
513
|
throw new Error(`Clinic group with ID ${clinicGroupId} not found`);
|
|
562
514
|
}
|
|
563
|
-
console.log(
|
|
515
|
+
console.log('[CLINIC_SERVICE] Clinic group verified');
|
|
564
516
|
|
|
565
517
|
// Validate branch setup data first
|
|
566
518
|
const validatedSetupData = clinicBranchSetupSchema.parse(setupData);
|
|
@@ -586,7 +538,7 @@ export class ClinicService extends BaseService {
|
|
|
586
538
|
isVerified: false,
|
|
587
539
|
};
|
|
588
540
|
|
|
589
|
-
console.log(
|
|
541
|
+
console.log('[CLINIC_SERVICE] Creating clinic branch', {
|
|
590
542
|
name: createClinicData.name,
|
|
591
543
|
hasLogo: !!createClinicData.logo,
|
|
592
544
|
hasCoverPhoto: !!createClinicData.coverPhoto,
|
|
@@ -595,7 +547,7 @@ export class ClinicService extends BaseService {
|
|
|
595
547
|
// Use createClinic which now handles validation and media uploads
|
|
596
548
|
const clinic = await this.createClinic(createClinicData, adminId);
|
|
597
549
|
|
|
598
|
-
console.log(
|
|
550
|
+
console.log('[CLINIC_SERVICE] Clinic branch created successfully', {
|
|
599
551
|
clinicId: clinic.id,
|
|
600
552
|
});
|
|
601
553
|
return clinic;
|
|
@@ -607,7 +559,7 @@ export class ClinicService extends BaseService {
|
|
|
607
559
|
|
|
608
560
|
async getAllClinics(
|
|
609
561
|
pagination?: number,
|
|
610
|
-
lastDoc?: any
|
|
562
|
+
lastDoc?: any,
|
|
611
563
|
): Promise<{ clinics: Clinic[]; lastDoc: any }> {
|
|
612
564
|
return ClinicUtils.getAllClinics(this.db, pagination, lastDoc);
|
|
613
565
|
}
|
|
@@ -616,15 +568,9 @@ export class ClinicService extends BaseService {
|
|
|
616
568
|
center: { latitude: number; longitude: number },
|
|
617
569
|
rangeInKm: number,
|
|
618
570
|
pagination?: number,
|
|
619
|
-
lastDoc?: any
|
|
571
|
+
lastDoc?: any,
|
|
620
572
|
): Promise<{ clinics: (Clinic & { distance: number })[]; lastDoc: any }> {
|
|
621
|
-
return ClinicUtils.getAllClinicsInRange(
|
|
622
|
-
this.db,
|
|
623
|
-
center,
|
|
624
|
-
rangeInKm,
|
|
625
|
-
pagination,
|
|
626
|
-
lastDoc
|
|
627
|
-
);
|
|
573
|
+
return ClinicUtils.getAllClinicsInRange(this.db, center, rangeInKm, pagination, lastDoc);
|
|
628
574
|
}
|
|
629
575
|
|
|
630
576
|
/**
|
|
@@ -643,6 +589,7 @@ export class ClinicService extends BaseService {
|
|
|
643
589
|
procedureTechnology?: string;
|
|
644
590
|
minRating?: number;
|
|
645
591
|
maxRating?: number;
|
|
592
|
+
nameSearch?: string;
|
|
646
593
|
pagination?: number;
|
|
647
594
|
lastDoc?: any;
|
|
648
595
|
isActive?: boolean;
|
|
@@ -658,16 +605,18 @@ export class ClinicService extends BaseService {
|
|
|
658
605
|
* This is optimized for mobile map usage to reduce payload size.
|
|
659
606
|
* @returns Array of minimal clinic info for map
|
|
660
607
|
*/
|
|
661
|
-
async getClinicsForMap(): Promise<
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
608
|
+
async getClinicsForMap(): Promise<
|
|
609
|
+
{
|
|
610
|
+
id: string;
|
|
611
|
+
name: string;
|
|
612
|
+
address: string;
|
|
613
|
+
latitude: number | undefined;
|
|
614
|
+
longitude: number | undefined;
|
|
615
|
+
}[]
|
|
616
|
+
> {
|
|
668
617
|
const clinicsRef = collection(this.db, CLINICS_COLLECTION);
|
|
669
618
|
const snapshot = await getDocs(clinicsRef);
|
|
670
|
-
const clinicsForMap = snapshot.docs.map(doc => {
|
|
619
|
+
const clinicsForMap = snapshot.docs.map((doc) => {
|
|
671
620
|
const data = doc.data();
|
|
672
621
|
return {
|
|
673
622
|
id: doc.id,
|