@hed-hog/contact-us 0.0.1

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.
Files changed (39) hide show
  1. package/dist/contact-us.controller.d.ts +32 -0
  2. package/dist/contact-us.controller.d.ts.map +1 -0
  3. package/dist/contact-us.controller.js +120 -0
  4. package/dist/contact-us.controller.js.map +1 -0
  5. package/dist/contact-us.module.d.ts +3 -0
  6. package/dist/contact-us.module.d.ts.map +1 -0
  7. package/dist/contact-us.module.js +33 -0
  8. package/dist/contact-us.module.js.map +1 -0
  9. package/dist/contact-us.service.d.ts +33 -0
  10. package/dist/contact-us.service.d.ts.map +1 -0
  11. package/dist/contact-us.service.js +272 -0
  12. package/dist/contact-us.service.js.map +1 -0
  13. package/dist/dto/contact-us-response.dto.d.ts +4 -0
  14. package/dist/dto/contact-us-response.dto.d.ts.map +1 -0
  15. package/dist/dto/contact-us-response.dto.js +21 -0
  16. package/dist/dto/contact-us-response.dto.js.map +1 -0
  17. package/dist/dto/contact-us-send.dto.d.ts +6 -0
  18. package/dist/dto/contact-us-send.dto.d.ts.map +1 -0
  19. package/dist/dto/contact-us-send.dto.js +29 -0
  20. package/dist/dto/contact-us-send.dto.js.map +1 -0
  21. package/dist/dto/contact-us-status.dto.d.ts +6 -0
  22. package/dist/dto/contact-us-status.dto.d.ts.map +1 -0
  23. package/dist/dto/contact-us-status.dto.js +28 -0
  24. package/dist/dto/contact-us-status.dto.js.map +1 -0
  25. package/dist/index.d.ts +2 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +18 -0
  28. package/dist/index.js.map +1 -0
  29. package/hedhog/data/menu.yaml +10 -0
  30. package/hedhog/data/route.yaml +36 -0
  31. package/hedhog/table/contact_us.yaml +31 -0
  32. package/package.json +37 -0
  33. package/src/contact-us.controller.ts +68 -0
  34. package/src/contact-us.module.ts +19 -0
  35. package/src/contact-us.service.ts +288 -0
  36. package/src/dto/contact-us-response.dto.ts +6 -0
  37. package/src/dto/contact-us-send.dto.ts +12 -0
  38. package/src/dto/contact-us-status.dto.ts +14 -0
  39. package/src/index.ts +2 -0
@@ -0,0 +1,32 @@
1
+ import { ContactUsService } from "./contact-us.service";
2
+ import { ContactUsResponseDTO } from "./dto/contact-us-response.dto";
3
+ import { ContactUsSendDTO } from "./dto/contact-us-send.dto";
4
+ import { ContactUsStatusDTO } from "./dto/contact-us-status.dto";
5
+ export declare class ContactUsController {
6
+ private readonly contactUsService;
7
+ constructor(contactUsService: ContactUsService);
8
+ getContactUsSettings(): Promise<Record<string, any>>;
9
+ getUserStats(): Promise<{
10
+ total: any;
11
+ totalNew: any;
12
+ totalResponded: any;
13
+ totalProgress: any;
14
+ }>;
15
+ getContactUsMessage(id: number): Promise<any>;
16
+ getContactUsMessages(paginationParams: any, { status }: {
17
+ status: any;
18
+ }): Promise<{
19
+ data: any[];
20
+ total: any;
21
+ page: number;
22
+ pageSize: any;
23
+ prev: number;
24
+ next: number;
25
+ lastPage: number;
26
+ }>;
27
+ deleteContactUsMessage(id: number): Promise<any>;
28
+ updateContactUsMessageStatus(id: number, { status }: ContactUsStatusDTO): Promise<any>;
29
+ respondToContactUsMessage(locale: string, id: number, { response }: ContactUsResponseDTO, user: any): Promise<string>;
30
+ createContactUsMessage(locale: string, { name, email, message }: ContactUsSendDTO): Promise<any>;
31
+ }
32
+ //# sourceMappingURL=contact-us.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-us.controller.d.ts","sourceRoot":"","sources":["../src/contact-us.controller.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,qBACa,mBAAmB;IAE5B,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBAAhB,gBAAgB,EAAE,gBAAgB;IAK/C,oBAAoB;IAKpB,YAAY;;;;;;IAKZ,mBAAmB,CAA4B,EAAE,EAAE,MAAM;IAKzD,oBAAoB,CAAe,gBAAgB,KAAA,EAAW,EAAE,MAAM,EAAE;;KAAA;;;;;;;;;IAKxE,sBAAsB,CAA4B,EAAE,EAAE,MAAM;IAK5D,4BAA4B,CACL,EAAE,EAAE,MAAM,EAC7B,EAAE,MAAM,EAAE,EAAE,kBAAkB;IAMlC,yBAAyB,CACnB,MAAM,EAAE,MAAM,EACG,EAAE,EAAE,MAAM,EAC7B,EAAE,QAAQ,EAAE,EAAE,oBAAoB,EAClC,IAAI,KAAA;IAOR,sBAAsB,CAChB,MAAM,EAAE,MAAM,EAChB,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,gBAAgB;CAIrD"}
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.ContactUsController = void 0;
16
+ const api_1 = require("@hed-hog/api");
17
+ const api_locale_1 = require("@hed-hog/api-locale");
18
+ const api_pagination_1 = require("@hed-hog/api-pagination");
19
+ const common_1 = require("@nestjs/common");
20
+ const contact_us_service_1 = require("./contact-us.service");
21
+ const contact_us_response_dto_1 = require("./dto/contact-us-response.dto");
22
+ const contact_us_send_dto_1 = require("./dto/contact-us-send.dto");
23
+ const contact_us_status_dto_1 = require("./dto/contact-us-status.dto");
24
+ let ContactUsController = class ContactUsController {
25
+ constructor(contactUsService) {
26
+ this.contactUsService = contactUsService;
27
+ }
28
+ async getContactUsSettings() {
29
+ return this.contactUsService.getContactUsSettings();
30
+ }
31
+ async getUserStats() {
32
+ return this.contactUsService.getUserStats();
33
+ }
34
+ async getContactUsMessage(id) {
35
+ return this.contactUsService.getContactUsMessage(id);
36
+ }
37
+ async getContactUsMessages(paginationParams, { status }) {
38
+ return this.contactUsService.getContactUsMessages(paginationParams, status);
39
+ }
40
+ async deleteContactUsMessage(id) {
41
+ return this.contactUsService.deleteContactUsMessage(id);
42
+ }
43
+ async updateContactUsMessageStatus(id, { status }) {
44
+ return this.contactUsService.updateContactUsMessageStatus(id, { status });
45
+ }
46
+ async respondToContactUsMessage(locale, id, { response }, user) {
47
+ return this.contactUsService.respondToContactUsMessage(locale, id, { response }, user);
48
+ }
49
+ async createContactUsMessage(locale, { name, email, message }) {
50
+ return this.contactUsService.createContactUsMessage(locale, { name, email, message });
51
+ }
52
+ };
53
+ exports.ContactUsController = ContactUsController;
54
+ __decorate([
55
+ (0, api_1.Public)(),
56
+ (0, common_1.Get)('settings'),
57
+ __metadata("design:type", Function),
58
+ __metadata("design:paramtypes", []),
59
+ __metadata("design:returntype", Promise)
60
+ ], ContactUsController.prototype, "getContactUsSettings", null);
61
+ __decorate([
62
+ (0, common_1.Get)('stats'),
63
+ __metadata("design:type", Function),
64
+ __metadata("design:paramtypes", []),
65
+ __metadata("design:returntype", Promise)
66
+ ], ContactUsController.prototype, "getUserStats", null);
67
+ __decorate([
68
+ (0, common_1.Get)(':id'),
69
+ __param(0, (0, common_1.Param)('id', common_1.ParseIntPipe)),
70
+ __metadata("design:type", Function),
71
+ __metadata("design:paramtypes", [Number]),
72
+ __metadata("design:returntype", Promise)
73
+ ], ContactUsController.prototype, "getContactUsMessage", null);
74
+ __decorate([
75
+ (0, common_1.Get)(),
76
+ __param(0, (0, api_pagination_1.Pagination)()),
77
+ __param(1, (0, common_1.Query)()),
78
+ __metadata("design:type", Function),
79
+ __metadata("design:paramtypes", [Object, Object]),
80
+ __metadata("design:returntype", Promise)
81
+ ], ContactUsController.prototype, "getContactUsMessages", null);
82
+ __decorate([
83
+ (0, common_1.Delete)(':id'),
84
+ __param(0, (0, common_1.Param)('id', common_1.ParseIntPipe)),
85
+ __metadata("design:type", Function),
86
+ __metadata("design:paramtypes", [Number]),
87
+ __metadata("design:returntype", Promise)
88
+ ], ContactUsController.prototype, "deleteContactUsMessage", null);
89
+ __decorate([
90
+ (0, common_1.Patch)('status/:id'),
91
+ __param(0, (0, common_1.Param)('id', common_1.ParseIntPipe)),
92
+ __param(1, (0, common_1.Body)()),
93
+ __metadata("design:type", Function),
94
+ __metadata("design:paramtypes", [Number, contact_us_status_dto_1.ContactUsStatusDTO]),
95
+ __metadata("design:returntype", Promise)
96
+ ], ContactUsController.prototype, "updateContactUsMessageStatus", null);
97
+ __decorate([
98
+ (0, common_1.Post)('response/:id'),
99
+ __param(0, (0, api_locale_1.Locale)()),
100
+ __param(1, (0, common_1.Param)('id', common_1.ParseIntPipe)),
101
+ __param(2, (0, common_1.Body)()),
102
+ __param(3, (0, api_1.User)()),
103
+ __metadata("design:type", Function),
104
+ __metadata("design:paramtypes", [String, Number, contact_us_response_dto_1.ContactUsResponseDTO, Object]),
105
+ __metadata("design:returntype", Promise)
106
+ ], ContactUsController.prototype, "respondToContactUsMessage", null);
107
+ __decorate([
108
+ (0, api_1.Public)(),
109
+ (0, common_1.Post)(),
110
+ __param(0, (0, api_locale_1.Locale)()),
111
+ __param(1, (0, common_1.Body)()),
112
+ __metadata("design:type", Function),
113
+ __metadata("design:paramtypes", [String, contact_us_send_dto_1.ContactUsSendDTO]),
114
+ __metadata("design:returntype", Promise)
115
+ ], ContactUsController.prototype, "createContactUsMessage", null);
116
+ exports.ContactUsController = ContactUsController = __decorate([
117
+ (0, common_1.Controller)('contact-us'),
118
+ __metadata("design:paramtypes", [contact_us_service_1.ContactUsService])
119
+ ], ContactUsController);
120
+ //# sourceMappingURL=contact-us.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-us.controller.js","sourceRoot":"","sources":["../src/contact-us.controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare class ContactUsModule {
2
+ }
3
+ //# sourceMappingURL=contact-us.module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-us.module.d.ts","sourceRoot":"","sources":["../src/contact-us.module.ts"],"names":[],"mappings":"AAOA,qBAWa,eAAe;CAAG"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.ContactUsModule = void 0;
10
+ const admin_1 = require("@hed-hog/admin");
11
+ const api_locale_1 = require("@hed-hog/api-locale");
12
+ const api_pagination_1 = require("@hed-hog/api-pagination");
13
+ const api_prisma_1 = require("@hed-hog/api-prisma");
14
+ const common_1 = require("@nestjs/common");
15
+ const contact_us_controller_1 = require("./contact-us.controller");
16
+ const contact_us_service_1 = require("./contact-us.service");
17
+ let ContactUsModule = class ContactUsModule {
18
+ };
19
+ exports.ContactUsModule = ContactUsModule;
20
+ exports.ContactUsModule = ContactUsModule = __decorate([
21
+ (0, common_1.Module)({
22
+ imports: [
23
+ (0, common_1.forwardRef)(() => api_locale_1.LocaleModule),
24
+ (0, common_1.forwardRef)(() => api_prisma_1.PrismaModule),
25
+ (0, common_1.forwardRef)(() => api_pagination_1.PaginationModule),
26
+ (0, common_1.forwardRef)(() => admin_1.AdminModule)
27
+ ],
28
+ controllers: [contact_us_controller_1.ContactUsController],
29
+ providers: [contact_us_service_1.ContactUsService],
30
+ exports: [(0, common_1.forwardRef)(() => contact_us_service_1.ContactUsService)],
31
+ })
32
+ ], ContactUsModule);
33
+ //# sourceMappingURL=contact-us.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-us.module.js","sourceRoot":"","sources":["../src/contact-us.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,0CAA6C;AAC7C,oDAAmD;AACnD,4DAA2D;AAC3D,oDAAmD;AACnD,2CAAoD;AACpD,mEAA8D;AAC9D,6DAAwD;AAYjD,IAAM,eAAe,GAArB,MAAM,eAAe;CAAG,CAAA;AAAlB,0CAAe;0BAAf,eAAe;IAX3B,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,yBAAY,CAAC;YAC9B,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,yBAAY,CAAC;YAC9B,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,iCAAgB,CAAC;YAClC,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,mBAAW,CAAC;SAC9B;QACD,WAAW,EAAE,CAAC,2CAAmB,CAAC;QAClC,SAAS,EAAE,CAAC,qCAAgB,CAAC;QAC7B,OAAO,EAAE,CAAC,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,qCAAgB,CAAC,CAAC;KAC9C,CAAC;GACW,eAAe,CAAG"}
@@ -0,0 +1,33 @@
1
+ import { MailService as MailManagerService, SettingService } from '@hed-hog/admin';
2
+ import { PrismaService } from '@hed-hog/api-prisma';
3
+ import { ContactUsResponseDTO } from './dto/contact-us-response.dto';
4
+ import { ContactUsSendDTO } from './dto/contact-us-send.dto';
5
+ import { ContactUsStatusDTO } from './dto/contact-us-status.dto';
6
+ export declare class ContactUsService {
7
+ private readonly prisma;
8
+ private readonly mail;
9
+ private readonly setting;
10
+ constructor(prisma: PrismaService, mail: MailManagerService, setting: SettingService);
11
+ getContactUsSettings(): Promise<Record<string, any>>;
12
+ getUserStats(): Promise<{
13
+ total: any;
14
+ totalNew: any;
15
+ totalResponded: any;
16
+ totalProgress: any;
17
+ }>;
18
+ getContactUsMessage(id: number): Promise<any>;
19
+ getContactUsMessages(paginationParams: any, status: any): Promise<{
20
+ data: any[];
21
+ total: any;
22
+ page: number;
23
+ pageSize: any;
24
+ prev: number;
25
+ next: number;
26
+ lastPage: number;
27
+ }>;
28
+ deleteContactUsMessage(id: number): Promise<any>;
29
+ updateContactUsMessageStatus(id: number, { status }: ContactUsStatusDTO): Promise<any>;
30
+ respondToContactUsMessage(locale: string, id: number, { response }: ContactUsResponseDTO, user: any): Promise<string>;
31
+ createContactUsMessage(locale: string, { name, email, message }: ContactUsSendDTO): Promise<any>;
32
+ }
33
+ //# sourceMappingURL=contact-us.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-us.service.d.ts","sourceRoot":"","sources":["../src/contact-us.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,IAAI,kBAAkB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,qBACa,gBAAgB;IAEzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAFP,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,cAAc;IAGpC,oBAAoB;IAOpB,YAAY;;;;;;IAkBZ,mBAAmB,CAAC,EAAE,EAAE,MAAM;IAU9B,oBAAoB,CAAC,gBAAgB,KAAA,EAAE,MAAM,KAAA;cAsHjC,GAAG,EAAE;;;;;;;;IAUjB,sBAAsB,CAAC,EAAE,EAAE,MAAM;IAcjC,4BAA4B,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,kBAAkB;IAmBvE,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,EAAE,oBAAoB,EAAE,IAAI,KAAA;IAgC9F,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,gBAAgB;CA2CxF"}
@@ -0,0 +1,272 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ContactUsService = void 0;
13
+ const admin_1 = require("@hed-hog/admin");
14
+ const api_prisma_1 = require("@hed-hog/api-prisma");
15
+ const common_1 = require("@nestjs/common");
16
+ const date_fns_1 = require("date-fns");
17
+ let ContactUsService = class ContactUsService {
18
+ constructor(prisma, mail, setting) {
19
+ this.prisma = prisma;
20
+ this.mail = mail;
21
+ this.setting = setting;
22
+ }
23
+ async getContactUsSettings() {
24
+ return this.setting.getSettingValues([
25
+ 'contact-us-phone',
26
+ 'contact-us-email',
27
+ ]);
28
+ }
29
+ async getUserStats() {
30
+ const statuses = ['new', 'answered', 'progress'];
31
+ const counts = await Promise.all(statuses.map((status) => this.prisma.contact_us.count({
32
+ where: { status: status },
33
+ })));
34
+ return {
35
+ total: await this.prisma.contact_us.count({}),
36
+ totalNew: counts[0],
37
+ totalResponded: counts[1],
38
+ totalProgress: counts[2],
39
+ };
40
+ }
41
+ async getContactUsMessage(id) {
42
+ return this.prisma.contact_us.findUnique({
43
+ where: { id: Number(id) },
44
+ include: {
45
+ user_contact_us_response_idTouser: true,
46
+ user_contact_us_user_idTouser: true,
47
+ },
48
+ });
49
+ }
50
+ async getContactUsMessages(paginationParams, status) {
51
+ var _a;
52
+ const searchRaw = ((_a = paginationParams.search) !== null && _a !== void 0 ? _a : '').toString().trim();
53
+ const statusRaw = (status !== null && status !== void 0 ? status : '').toString().trim().toLowerCase();
54
+ const hasSearch = searchRaw.length > 0;
55
+ const hasStatus = statusRaw.length > 0 && statusRaw !== 'all';
56
+ const like = `%${searchRaw.toLowerCase()}%`;
57
+ let rowsQuery;
58
+ if (hasSearch && hasStatus) {
59
+ rowsQuery = this.prisma.$queryRaw `
60
+ SELECT
61
+ cu.id,
62
+ cu.name,
63
+ cu.email,
64
+ cu.message,
65
+ cu.response,
66
+ cu.status,
67
+ cu.created_at,
68
+ cu.response_at,
69
+ cu.user_id,
70
+ cu.response_id
71
+ FROM contact_us AS cu
72
+ WHERE
73
+ cu.status = ${statusRaw}::contact_us_status_enum AND (
74
+ LOWER(cu.name) LIKE ${like}
75
+ OR LOWER(cu.email) LIKE ${like}
76
+ OR LOWER(cu.message) LIKE ${like}
77
+ OR LOWER(COALESCE(cu.response, '')) LIKE ${like}
78
+ )
79
+ ORDER BY cu.id DESC
80
+ LIMIT ${paginationParams.take}
81
+ OFFSET ${paginationParams.skip}
82
+ `;
83
+ }
84
+ else if (hasSearch) {
85
+ rowsQuery = this.prisma.$queryRaw `
86
+ SELECT
87
+ cu.id,
88
+ cu.name,
89
+ cu.email,
90
+ cu.message,
91
+ cu.response,
92
+ cu.status,
93
+ cu.created_at,
94
+ cu.response_at,
95
+ cu.user_id,
96
+ cu.response_id
97
+ FROM contact_us AS cu
98
+ WHERE
99
+ LOWER(cu.name) LIKE ${like}
100
+ OR LOWER(cu.email) LIKE ${like}
101
+ OR LOWER(cu.message) LIKE ${like}
102
+ OR LOWER(COALESCE(cu.response, '')) LIKE ${like}
103
+ ORDER BY cu.id DESC
104
+ LIMIT ${paginationParams.take}
105
+ OFFSET ${paginationParams.skip}
106
+ `;
107
+ }
108
+ else if (hasStatus) {
109
+ rowsQuery = this.prisma.$queryRaw `
110
+ SELECT
111
+ cu.id,
112
+ cu.name,
113
+ cu.email,
114
+ cu.message,
115
+ cu.response,
116
+ cu.status,
117
+ cu.created_at,
118
+ cu.response_at,
119
+ cu.user_id,
120
+ cu.response_id
121
+ FROM contact_us AS cu
122
+ WHERE cu.status = ${statusRaw}::contact_us_status_enum
123
+ ORDER BY cu.id DESC
124
+ LIMIT ${paginationParams.take}
125
+ OFFSET ${paginationParams.skip}
126
+ `;
127
+ }
128
+ else {
129
+ rowsQuery = this.prisma.$queryRaw `
130
+ SELECT
131
+ cu.id,
132
+ cu.name,
133
+ cu.email,
134
+ cu.message,
135
+ cu.response,
136
+ cu.status,
137
+ cu.created_at,
138
+ cu.response_at,
139
+ cu.user_id,
140
+ cu.response_id
141
+ FROM contact_us AS cu
142
+ ORDER BY cu.id DESC
143
+ LIMIT ${paginationParams.take}
144
+ OFFSET ${paginationParams.skip}
145
+ `;
146
+ }
147
+ const countQuery = this.prisma.contact_us.count({
148
+ where: Object.assign(Object.assign({}, (hasStatus && { status: statusRaw })), (hasSearch && {
149
+ OR: [
150
+ { name: { contains: searchRaw, mode: 'insensitive' } },
151
+ { email: { contains: searchRaw, mode: 'insensitive' } },
152
+ { message: { contains: searchRaw, mode: 'insensitive' } },
153
+ { response: { contains: searchRaw, mode: 'insensitive' } },
154
+ ],
155
+ })),
156
+ });
157
+ const [rows, total] = await Promise.all([rowsQuery, countQuery]);
158
+ const pageSize = paginationParams.take;
159
+ const page = Math.floor(paginationParams.skip / pageSize) + 1;
160
+ const lastPage = Math.max(1, Math.ceil(total / pageSize));
161
+ const prev = page > 1 ? page - 1 : null;
162
+ const next = page < lastPage ? page + 1 : null;
163
+ return {
164
+ data: rows,
165
+ total,
166
+ page,
167
+ pageSize,
168
+ prev,
169
+ next,
170
+ lastPage,
171
+ };
172
+ }
173
+ async deleteContactUsMessage(id) {
174
+ const message = await this.prisma.contact_us.findUnique({
175
+ where: { id: Number(id) },
176
+ });
177
+ if (!message) {
178
+ throw new common_1.NotFoundException('Contact Us message not found');
179
+ }
180
+ return this.prisma.contact_us.delete({
181
+ where: { id: Number(id) },
182
+ });
183
+ }
184
+ async updateContactUsMessageStatus(id, { status }) {
185
+ const message = await this.prisma.contact_us.findUnique({
186
+ where: { id: Number(id) },
187
+ });
188
+ if (!message) {
189
+ throw new common_1.NotFoundException('Contact Us message not found');
190
+ }
191
+ if (status === 'all') {
192
+ status = 'new';
193
+ }
194
+ return this.prisma.contact_us.update({
195
+ where: { id: Number(id) },
196
+ data: { status },
197
+ });
198
+ }
199
+ async respondToContactUsMessage(locale, id, { response }, user) {
200
+ const message = await this.prisma.contact_us.findUnique({
201
+ where: { id: Number(id) },
202
+ });
203
+ if (!message) {
204
+ throw new common_1.NotFoundException('Contact Us message not found');
205
+ }
206
+ await this.prisma.contact_us.update({
207
+ where: { id: Number(id) },
208
+ data: {
209
+ response,
210
+ response_at: new Date(),
211
+ response_id: user.id,
212
+ status: 'answered',
213
+ },
214
+ });
215
+ await this.mail.sendTemplatedMail(locale, {
216
+ email: message.email,
217
+ slug: 'contact-us-response',
218
+ variables: {
219
+ name: message.name,
220
+ message: message.message,
221
+ response: response,
222
+ },
223
+ });
224
+ return response;
225
+ }
226
+ async createContactUsMessage(locale, { name, email, message }) {
227
+ const settings = await this.setting.getSettingValues([
228
+ 'datetime-format',
229
+ 'contact-us-email-to',
230
+ ]);
231
+ const { user_id } = await this.prisma.user_identifier.findFirst({
232
+ where: { type: 'email', value: email },
233
+ select: { user_id: true },
234
+ });
235
+ const contactUs = await this.prisma.contact_us.create({
236
+ data: {
237
+ name,
238
+ email,
239
+ message,
240
+ status: 'new',
241
+ user_id: user_id !== null && user_id !== void 0 ? user_id : null,
242
+ },
243
+ });
244
+ await this.mail.sendTemplatedMail(locale, {
245
+ email: contactUs.email,
246
+ slug: 'contact-us-client',
247
+ variables: {
248
+ name: contactUs.name,
249
+ },
250
+ });
251
+ const datetimeFormats = JSON.parse(settings['datetime-format']);
252
+ await this.mail.sendTemplatedMail(locale, {
253
+ email: settings['contact-us-email-to'],
254
+ slug: 'contact-us-to',
255
+ variables: {
256
+ name: contactUs.name,
257
+ message: contactUs.message,
258
+ email: contactUs.email,
259
+ datetime: (0, date_fns_1.format)(contactUs.created_at, datetimeFormats[locale]),
260
+ },
261
+ });
262
+ return contactUs;
263
+ }
264
+ };
265
+ exports.ContactUsService = ContactUsService;
266
+ exports.ContactUsService = ContactUsService = __decorate([
267
+ (0, common_1.Injectable)(),
268
+ __metadata("design:paramtypes", [api_prisma_1.PrismaService,
269
+ admin_1.MailService,
270
+ admin_1.SettingService])
271
+ ], ContactUsService);
272
+ //# sourceMappingURL=contact-us.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-us.service.js","sourceRoot":"","sources":["../src/contact-us.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare class ContactUsResponseDTO {
2
+ response: string;
3
+ }
4
+ //# sourceMappingURL=contact-us-response.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-us-response.dto.d.ts","sourceRoot":"","sources":["../../src/dto/contact-us-response.dto.ts"],"names":[],"mappings":"AAEA,qBAAa,oBAAoB;IAE/B,QAAQ,EAAE,MAAM,CAAC;CAClB"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ContactUsResponseDTO = void 0;
13
+ const class_validator_1 = require("class-validator");
14
+ class ContactUsResponseDTO {
15
+ }
16
+ exports.ContactUsResponseDTO = ContactUsResponseDTO;
17
+ __decorate([
18
+ (0, class_validator_1.IsString)(),
19
+ __metadata("design:type", String)
20
+ ], ContactUsResponseDTO.prototype, "response", void 0);
21
+ //# sourceMappingURL=contact-us-response.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-us-response.dto.js","sourceRoot":"","sources":["../../src/dto/contact-us-response.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAA2C;AAE3C,MAAa,oBAAoB;CAGhC;AAHD,oDAGC;AADC;IADC,IAAA,0BAAQ,GAAE;;sDACM"}
@@ -0,0 +1,6 @@
1
+ export declare class ContactUsSendDTO {
2
+ name: string;
3
+ email: string;
4
+ message: string;
5
+ }
6
+ //# sourceMappingURL=contact-us-send.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-us-send.dto.d.ts","sourceRoot":"","sources":["../../src/dto/contact-us-send.dto.ts"],"names":[],"mappings":"AAEA,qBAAa,gBAAgB;IAE3B,IAAI,EAAE,MAAM,CAAC;IAGb,KAAK,EAAE,MAAM,CAAC;IAGd,OAAO,EAAE,MAAM,CAAC;CACjB"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ContactUsSendDTO = void 0;
13
+ const class_validator_1 = require("class-validator");
14
+ class ContactUsSendDTO {
15
+ }
16
+ exports.ContactUsSendDTO = ContactUsSendDTO;
17
+ __decorate([
18
+ (0, class_validator_1.IsString)(),
19
+ __metadata("design:type", String)
20
+ ], ContactUsSendDTO.prototype, "name", void 0);
21
+ __decorate([
22
+ (0, class_validator_1.IsEmail)(),
23
+ __metadata("design:type", String)
24
+ ], ContactUsSendDTO.prototype, "email", void 0);
25
+ __decorate([
26
+ (0, class_validator_1.IsString)(),
27
+ __metadata("design:type", String)
28
+ ], ContactUsSendDTO.prototype, "message", void 0);
29
+ //# sourceMappingURL=contact-us-send.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-us-send.dto.js","sourceRoot":"","sources":["../../src/dto/contact-us-send.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAAoD;AAEpD,MAAa,gBAAgB;CAS5B;AATD,4CASC;AAPC;IADC,IAAA,0BAAQ,GAAE;;8CACE;AAGb;IADC,IAAA,yBAAO,GAAE;;+CACI;AAGd;IADC,IAAA,0BAAQ,GAAE;;iDACK"}
@@ -0,0 +1,6 @@
1
+ type Status = 'new' | 'progress' | 'answered' | 'archived' | 'all';
2
+ export declare class ContactUsStatusDTO {
3
+ status: Status;
4
+ }
5
+ export {};
6
+ //# sourceMappingURL=contact-us-status.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-us-status.dto.d.ts","sourceRoot":"","sources":["../../src/dto/contact-us-status.dto.ts"],"names":[],"mappings":"AAEA,KAAK,MAAM,GAAG,KAAK,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,KAAK,CAAC;AAEnE,qBAAa,kBAAkB;IAQ7B,MAAM,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ContactUsStatusDTO = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ class ContactUsStatusDTO {
15
+ }
16
+ exports.ContactUsStatusDTO = ContactUsStatusDTO;
17
+ __decorate([
18
+ (0, class_transformer_1.Transform)(({ value }) => {
19
+ if (['new', 'progress', 'answered', 'archived'].includes(value)) {
20
+ return value;
21
+ }
22
+ else {
23
+ throw new Error(`Invalid status: ${value}`);
24
+ }
25
+ }),
26
+ __metadata("design:type", String)
27
+ ], ContactUsStatusDTO.prototype, "status", void 0);
28
+ //# sourceMappingURL=contact-us-status.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-us-status.dto.js","sourceRoot":"","sources":["../../src/dto/contact-us-status.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yDAA8C;AAI9C,MAAa,kBAAkB;CAS9B;AATD,gDASC;AADC;IAPC,IAAA,6BAAS,EAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;QACvB,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAChE,OAAO,KAAK,CAAC;QACf,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,mBAAmB,KAAK,EAAE,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC,CAAC;;kDACa"}
@@ -0,0 +1,2 @@
1
+ export * from './contact-us.module';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./contact-us.module"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sDAAoC"}
@@ -0,0 +1,10 @@
1
+ - url: /contact-us
2
+ icon: file-question-mark
3
+ name:
4
+ en: Contact Us
5
+ pt: Fale Conosco
6
+ slug: /contact-us
7
+ relations:
8
+ role:
9
+ - where:
10
+ slug: admin
@@ -0,0 +1,36 @@
1
+ - url: /contact-us
2
+ method: GET
3
+ relations:
4
+ role:
5
+ - where:
6
+ slug: admin
7
+ - url: /contact-us/stats
8
+ method: GET
9
+ relations:
10
+ role:
11
+ - where:
12
+ slug: admin
13
+ - url: /contact-us/:id
14
+ method: GET
15
+ relations:
16
+ role:
17
+ - where:
18
+ slug: admin
19
+ - url: /contact-us/response/:id
20
+ method: POST
21
+ relations:
22
+ role:
23
+ - where:
24
+ slug: admin
25
+ - url: /contact-us/status/:id
26
+ method: PATCH
27
+ relations:
28
+ role:
29
+ - where:
30
+ slug: admin
31
+ - url: /contact-us/:id
32
+ method: DELETE
33
+ relations:
34
+ role:
35
+ - where:
36
+ slug: admin
@@ -0,0 +1,31 @@
1
+ columns:
2
+ - type: pk
3
+ - name: name
4
+ - name: email
5
+ - name: message
6
+ type: text
7
+ - name: response
8
+ type: text
9
+ isNullable: true
10
+ - name: status
11
+ type: enum
12
+ values: [new, progress, answered, archived]
13
+ default: new
14
+ - name: response_at
15
+ type: datetime
16
+ isNullable: true
17
+ - name: user_id
18
+ type: fk
19
+ isNullable: true
20
+ references:
21
+ table: user
22
+ column: id
23
+ onDelete: CASCADE
24
+ - name: response_id
25
+ type: fk
26
+ isNullable: true
27
+ references:
28
+ table: user
29
+ column: id
30
+ onDelete: SET_NULL
31
+ - type: created_at
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@hed-hog/contact-us",
3
+ "version": "0.0.1",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "dependencies": {
7
+ "@nestjs/common": "*",
8
+ "@nestjs/config": "^4.0.2",
9
+ "@nestjs/core": "^11",
10
+ "@nestjs/jwt": "^11",
11
+ "@nestjs/mapped-types": "*",
12
+ "@hed-hog/api-locale": "0.0.10",
13
+ "@hed-hog/admin": "0.0.130",
14
+ "@hed-hog/api": "0.0.3",
15
+ "@hed-hog/api-prisma": "0.0.4",
16
+ "@hed-hog/api-pagination": "0.0.3"
17
+ },
18
+ "exports": {
19
+ ".": {
20
+ "import": "./dist/index.js",
21
+ "require": "./dist/index.js"
22
+ },
23
+ "./package.json": "./package.json"
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "src",
28
+ "hedhog"
29
+ ],
30
+ "scripts": {
31
+ "lint": "eslint \"{src,apps,libs,test}/**/*.ts\"",
32
+ "prebuild": "npx ts-node ../../scripts/build-dependencies.ts libraries/faq",
33
+ "build": "tsc --project tsconfig.production.json",
34
+ "patch": "npx ts-node ../../scripts/patch.ts libraries/faq",
35
+ "prod": "pnpm run patch && pnpm run build && pnpm publish --access public --no-git-checks"
36
+ }
37
+ }
@@ -0,0 +1,68 @@
1
+ import { Public, User } from "@hed-hog/api";
2
+ import { Locale } from "@hed-hog/api-locale";
3
+ import { Pagination } from "@hed-hog/api-pagination";
4
+ import { Body, Controller, Delete, Get, Param, ParseIntPipe, Patch, Post, Query } from "@nestjs/common";
5
+ import { ContactUsService } from "./contact-us.service";
6
+ import { ContactUsResponseDTO } from "./dto/contact-us-response.dto";
7
+ import { ContactUsSendDTO } from "./dto/contact-us-send.dto";
8
+ import { ContactUsStatusDTO } from "./dto/contact-us-status.dto";
9
+
10
+ @Controller('contact-us')
11
+ export class ContactUsController {
12
+ constructor(
13
+ private readonly contactUsService: ContactUsService,
14
+ ) { }
15
+
16
+ @Public()
17
+ @Get('settings')
18
+ async getContactUsSettings() {
19
+ return this.contactUsService.getContactUsSettings();
20
+ }
21
+
22
+ @Get('stats')
23
+ async getUserStats() {
24
+ return this.contactUsService.getUserStats();
25
+ }
26
+
27
+ @Get(':id')
28
+ async getContactUsMessage(@Param('id', ParseIntPipe) id: number) {
29
+ return this.contactUsService.getContactUsMessage(id);
30
+ }
31
+
32
+ @Get()
33
+ async getContactUsMessages(@Pagination() paginationParams, @Query() { status }) {
34
+ return this.contactUsService.getContactUsMessages(paginationParams, status);
35
+ }
36
+
37
+ @Delete(':id')
38
+ async deleteContactUsMessage(@Param('id', ParseIntPipe) id: number) {
39
+ return this.contactUsService.deleteContactUsMessage(id);
40
+ }
41
+
42
+ @Patch('status/:id')
43
+ async updateContactUsMessageStatus(
44
+ @Param('id', ParseIntPipe) id: number,
45
+ @Body() { status }: ContactUsStatusDTO,
46
+ ) {
47
+ return this.contactUsService.updateContactUsMessageStatus(id, { status });
48
+ }
49
+
50
+ @Post('response/:id')
51
+ async respondToContactUsMessage(
52
+ @Locale() locale: string,
53
+ @Param('id', ParseIntPipe) id: number,
54
+ @Body() { response }: ContactUsResponseDTO,
55
+ @User() user,
56
+ ) {
57
+ return this.contactUsService.respondToContactUsMessage(locale, id, { response }, user);
58
+ }
59
+
60
+ @Public()
61
+ @Post()
62
+ async createContactUsMessage(
63
+ @Locale() locale: string,
64
+ @Body() { name, email, message }: ContactUsSendDTO,
65
+ ) {
66
+ return this.contactUsService.createContactUsMessage(locale, { name, email, message });
67
+ }
68
+ }
@@ -0,0 +1,19 @@
1
+ import { AdminModule } from '@hed-hog/admin';
2
+ import { LocaleModule } from '@hed-hog/api-locale';
3
+ import { PaginationModule } from '@hed-hog/api-pagination';
4
+ import { PrismaModule } from '@hed-hog/api-prisma';
5
+ import { forwardRef, Module } from '@nestjs/common';
6
+ import { ContactUsController } from './contact-us.controller';
7
+ import { ContactUsService } from './contact-us.service';
8
+ @Module({
9
+ imports: [
10
+ forwardRef(() => LocaleModule),
11
+ forwardRef(() => PrismaModule),
12
+ forwardRef(() => PaginationModule),
13
+ forwardRef(() => AdminModule)
14
+ ],
15
+ controllers: [ContactUsController],
16
+ providers: [ContactUsService],
17
+ exports: [forwardRef(() => ContactUsService)],
18
+ })
19
+ export class ContactUsModule {}
@@ -0,0 +1,288 @@
1
+ import { MailService as MailManagerService, SettingService } from '@hed-hog/admin';
2
+ import { PrismaService } from '@hed-hog/api-prisma';
3
+ import { Injectable, NotFoundException } from '@nestjs/common';
4
+ import { format } from 'date-fns';
5
+ import { ContactUsResponseDTO } from './dto/contact-us-response.dto';
6
+ import { ContactUsSendDTO } from './dto/contact-us-send.dto';
7
+ import { ContactUsStatusDTO } from './dto/contact-us-status.dto';
8
+
9
+ @Injectable()
10
+ export class ContactUsService {
11
+ constructor(
12
+ private readonly prisma: PrismaService,
13
+ private readonly mail: MailManagerService,
14
+ private readonly setting: SettingService,
15
+ ) {}
16
+
17
+ async getContactUsSettings() {
18
+ return this.setting.getSettingValues([
19
+ 'contact-us-phone',
20
+ 'contact-us-email',
21
+ ]);
22
+ }
23
+
24
+ async getUserStats() {
25
+ const statuses = ['new', 'answered', 'progress'];
26
+ const counts = await Promise.all(
27
+ statuses.map((status) =>
28
+ this.prisma.contact_us.count({
29
+ where: { status: status },
30
+ }),
31
+ ),
32
+ );
33
+
34
+ return {
35
+ total: await this.prisma.contact_us.count({}),
36
+ totalNew: counts[0],
37
+ totalResponded: counts[1],
38
+ totalProgress: counts[2],
39
+ };
40
+ }
41
+
42
+ async getContactUsMessage(id: number) {
43
+ return this.prisma.contact_us.findUnique({
44
+ where: { id: Number(id) },
45
+ include: {
46
+ user_contact_us_response_idTouser: true,
47
+ user_contact_us_user_idTouser: true,
48
+ },
49
+ });
50
+ }
51
+
52
+ async getContactUsMessages(paginationParams, status) {
53
+ const searchRaw = (paginationParams.search ?? '').toString().trim();
54
+ const statusRaw = (status ?? '').toString().trim().toLowerCase();
55
+ const hasSearch = searchRaw.length > 0;
56
+ const hasStatus = statusRaw.length > 0 && statusRaw !== 'all';
57
+ const like = `%${searchRaw.toLowerCase()}%`;
58
+
59
+ let rowsQuery: any;
60
+
61
+ if (hasSearch && hasStatus) {
62
+ rowsQuery = this.prisma.$queryRaw`
63
+ SELECT
64
+ cu.id,
65
+ cu.name,
66
+ cu.email,
67
+ cu.message,
68
+ cu.response,
69
+ cu.status,
70
+ cu.created_at,
71
+ cu.response_at,
72
+ cu.user_id,
73
+ cu.response_id
74
+ FROM contact_us AS cu
75
+ WHERE
76
+ cu.status = ${statusRaw}::contact_us_status_enum AND (
77
+ LOWER(cu.name) LIKE ${like}
78
+ OR LOWER(cu.email) LIKE ${like}
79
+ OR LOWER(cu.message) LIKE ${like}
80
+ OR LOWER(COALESCE(cu.response, '')) LIKE ${like}
81
+ )
82
+ ORDER BY cu.id DESC
83
+ LIMIT ${paginationParams.take}
84
+ OFFSET ${paginationParams.skip}
85
+ `;
86
+ } else if (hasSearch) {
87
+ rowsQuery = this.prisma.$queryRaw`
88
+ SELECT
89
+ cu.id,
90
+ cu.name,
91
+ cu.email,
92
+ cu.message,
93
+ cu.response,
94
+ cu.status,
95
+ cu.created_at,
96
+ cu.response_at,
97
+ cu.user_id,
98
+ cu.response_id
99
+ FROM contact_us AS cu
100
+ WHERE
101
+ LOWER(cu.name) LIKE ${like}
102
+ OR LOWER(cu.email) LIKE ${like}
103
+ OR LOWER(cu.message) LIKE ${like}
104
+ OR LOWER(COALESCE(cu.response, '')) LIKE ${like}
105
+ ORDER BY cu.id DESC
106
+ LIMIT ${paginationParams.take}
107
+ OFFSET ${paginationParams.skip}
108
+ `;
109
+ } else if (hasStatus) {
110
+ rowsQuery = this.prisma.$queryRaw`
111
+ SELECT
112
+ cu.id,
113
+ cu.name,
114
+ cu.email,
115
+ cu.message,
116
+ cu.response,
117
+ cu.status,
118
+ cu.created_at,
119
+ cu.response_at,
120
+ cu.user_id,
121
+ cu.response_id
122
+ FROM contact_us AS cu
123
+ WHERE cu.status = ${statusRaw}::contact_us_status_enum
124
+ ORDER BY cu.id DESC
125
+ LIMIT ${paginationParams.take}
126
+ OFFSET ${paginationParams.skip}
127
+ `;
128
+ } else {
129
+ rowsQuery = this.prisma.$queryRaw`
130
+ SELECT
131
+ cu.id,
132
+ cu.name,
133
+ cu.email,
134
+ cu.message,
135
+ cu.response,
136
+ cu.status,
137
+ cu.created_at,
138
+ cu.response_at,
139
+ cu.user_id,
140
+ cu.response_id
141
+ FROM contact_us AS cu
142
+ ORDER BY cu.id DESC
143
+ LIMIT ${paginationParams.take}
144
+ OFFSET ${paginationParams.skip}
145
+ `;
146
+ }
147
+
148
+ const countQuery = this.prisma.contact_us.count({
149
+ where: {
150
+ ...(hasStatus && { status: statusRaw as any }),
151
+ ...(hasSearch && {
152
+ OR: [
153
+ { name: { contains: searchRaw, mode: 'insensitive' } },
154
+ { email: { contains: searchRaw, mode: 'insensitive' } },
155
+ { message: { contains: searchRaw, mode: 'insensitive' } },
156
+ { response: { contains: searchRaw, mode: 'insensitive' } },
157
+ ],
158
+ }),
159
+ },
160
+ });
161
+
162
+ const [rows, total] = await Promise.all([rowsQuery, countQuery]);
163
+ const pageSize = paginationParams.take;
164
+ const page = Math.floor(paginationParams.skip / pageSize) + 1;
165
+ const lastPage = Math.max(1, Math.ceil(total / pageSize));
166
+ const prev = page > 1 ? page - 1 : null;
167
+ const next = page < lastPage ? page + 1 : null;
168
+
169
+ return {
170
+ data: rows as any[],
171
+ total,
172
+ page,
173
+ pageSize,
174
+ prev,
175
+ next,
176
+ lastPage,
177
+ };
178
+ }
179
+
180
+ async deleteContactUsMessage(id: number) {
181
+ const message = await this.prisma.contact_us.findUnique({
182
+ where: { id: Number(id) },
183
+ });
184
+
185
+ if (!message) {
186
+ throw new NotFoundException('Contact Us message not found');
187
+ }
188
+
189
+ return this.prisma.contact_us.delete({
190
+ where: { id: Number(id) },
191
+ });
192
+ }
193
+
194
+ async updateContactUsMessageStatus(id: number, { status }: ContactUsStatusDTO) {
195
+ const message = await this.prisma.contact_us.findUnique({
196
+ where: { id: Number(id) },
197
+ });
198
+
199
+ if (!message) {
200
+ throw new NotFoundException('Contact Us message not found');
201
+ }
202
+
203
+ if (status === 'all') {
204
+ status = 'new';
205
+ }
206
+
207
+ return this.prisma.contact_us.update({
208
+ where: { id: Number(id) },
209
+ data: { status },
210
+ });
211
+ }
212
+
213
+ async respondToContactUsMessage(locale: string, id: number, { response }: ContactUsResponseDTO, user) {
214
+ const message = await this.prisma.contact_us.findUnique({
215
+ where: { id: Number(id) },
216
+ });
217
+
218
+ if (!message) {
219
+ throw new NotFoundException('Contact Us message not found');
220
+ }
221
+
222
+ await this.prisma.contact_us.update({
223
+ where: { id: Number(id) },
224
+ data: {
225
+ response,
226
+ response_at: new Date(),
227
+ response_id: user.id,
228
+ status: 'answered',
229
+ },
230
+ });
231
+
232
+ await this.mail.sendTemplatedMail(locale, {
233
+ email: message.email,
234
+ slug: 'contact-us-response',
235
+ variables: {
236
+ name: message.name,
237
+ message: message.message,
238
+ response: response,
239
+ },
240
+ });
241
+
242
+ return response;
243
+ }
244
+
245
+ async createContactUsMessage(locale: string, { name, email, message }: ContactUsSendDTO) {
246
+ const settings = await this.setting.getSettingValues([
247
+ 'datetime-format',
248
+ 'contact-us-email-to',
249
+ ]);
250
+
251
+ const { user_id } = await this.prisma.user_identifier.findFirst({
252
+ where: { type: 'email', value: email },
253
+ select: { user_id: true },
254
+ });
255
+
256
+ const contactUs = await this.prisma.contact_us.create({
257
+ data: {
258
+ name,
259
+ email,
260
+ message,
261
+ status: 'new',
262
+ user_id: user_id ?? null,
263
+ },
264
+ });
265
+
266
+ await this.mail.sendTemplatedMail(locale, {
267
+ email: contactUs.email,
268
+ slug: 'contact-us-client',
269
+ variables: {
270
+ name: contactUs.name,
271
+ },
272
+ });
273
+
274
+ const datetimeFormats = JSON.parse(settings['datetime-format']);
275
+ await this.mail.sendTemplatedMail(locale, {
276
+ email: settings['contact-us-email-to'],
277
+ slug: 'contact-us-to',
278
+ variables: {
279
+ name: contactUs.name,
280
+ message: contactUs.message,
281
+ email: contactUs.email,
282
+ datetime: format(contactUs.created_at, datetimeFormats[locale]),
283
+ },
284
+ });
285
+
286
+ return contactUs;
287
+ }
288
+ }
@@ -0,0 +1,6 @@
1
+ import { IsString } from 'class-validator';
2
+
3
+ export class ContactUsResponseDTO {
4
+ @IsString()
5
+ response: string;
6
+ }
@@ -0,0 +1,12 @@
1
+ import { IsEmail, IsString } from 'class-validator';
2
+
3
+ export class ContactUsSendDTO {
4
+ @IsString()
5
+ name: string;
6
+
7
+ @IsEmail()
8
+ email: string;
9
+
10
+ @IsString()
11
+ message: string;
12
+ }
@@ -0,0 +1,14 @@
1
+ import { Transform } from 'class-transformer';
2
+
3
+ type Status = 'new' | 'progress' | 'answered' | 'archived' | 'all';
4
+
5
+ export class ContactUsStatusDTO {
6
+ @Transform(({ value }) => {
7
+ if (['new', 'progress', 'answered', 'archived'].includes(value)) {
8
+ return value;
9
+ } else {
10
+ throw new Error(`Invalid status: ${value}`);
11
+ }
12
+ })
13
+ status: Status;
14
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './contact-us.module';
2
+