reviews-plugin.ts 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import { OnApplicationBootstrap } from '@nestjs/common';
  2. import {
  3. LanguageCode,
  4. PluginCommonModule,
  5. Product,
  6. ProductVariant,
  7. RequestContextService,
  8. TransactionalConnection,
  9. VendurePlugin,
  10. } from '@vendure/core';
  11. import { AdminUiExtension } from '@vendure/ui-devkit/compiler';
  12. import path from 'path';
  13. import { adminApiExtensions, shopApiExtensions } from './api/api-extensions';
  14. import { ProductEntityResolver } from './api/product-entity.resolver';
  15. import { ProductReviewAdminResolver } from './api/product-review-admin.resolver';
  16. import { ProductReviewEntityResolver } from './api/product-review-entity.resolver';
  17. import { ProductReviewShopResolver } from './api/product-review-shop.resolver';
  18. import { ProductReviewTranslation } from './entities/product-review-translation.entity';
  19. import { ProductReview } from './entities/product-review.entity';
  20. import { ReviewState } from './types';
  21. @VendurePlugin({
  22. imports: [PluginCommonModule],
  23. entities: [ProductReview, ProductReviewTranslation],
  24. adminApiExtensions: {
  25. schema: adminApiExtensions,
  26. resolvers: [ProductEntityResolver, ProductReviewAdminResolver, ProductReviewEntityResolver],
  27. },
  28. shopApiExtensions: {
  29. schema: shopApiExtensions,
  30. resolvers: [ProductEntityResolver, ProductReviewShopResolver, ProductReviewEntityResolver],
  31. },
  32. configuration: config => {
  33. config.customFields.Product.push({
  34. name: 'reviewRating',
  35. label: [{ languageCode: LanguageCode.en, value: 'Review rating' }],
  36. public: true,
  37. nullable: true,
  38. type: 'float',
  39. ui: { tab: 'Reviews', component: 'star-rating-form-input' },
  40. });
  41. config.customFields.Product.push({
  42. name: 'reviewCount',
  43. label: [{ languageCode: LanguageCode.en, value: 'Review count' }],
  44. public: true,
  45. defaultValue: 0,
  46. type: 'float',
  47. ui: { tab: 'Reviews', component: 'review-count-link' },
  48. });
  49. config.customFields.Product.push({
  50. name: 'featuredReview',
  51. label: [{ languageCode: LanguageCode.en, value: 'Featured review' }],
  52. public: true,
  53. type: 'relation',
  54. entity: ProductReview,
  55. ui: { tab: 'Reviews', component: 'review-selector-form-input' },
  56. inverseSide: undefined,
  57. });
  58. config.customFields.ProductReview = [
  59. {
  60. type: 'string',
  61. name: 'reviewerName',
  62. label: [{ languageCode: LanguageCode.en, value: 'Reviewer name' }],
  63. public: true,
  64. nullable: true,
  65. },
  66. ];
  67. return config;
  68. },
  69. dashboard: './dashboard/index.tsx',
  70. })
  71. export class ReviewsPlugin implements OnApplicationBootstrap {
  72. constructor(
  73. private readonly connection: TransactionalConnection,
  74. private readonly requestContextService: RequestContextService,
  75. ) {}
  76. static uiExtensions: AdminUiExtension = {
  77. extensionPath: path.join(__dirname, 'ui'),
  78. routes: [{ route: 'product-reviews', filePath: 'routes.ts' }],
  79. providers: ['providers.ts'],
  80. };
  81. async onApplicationBootstrap() {
  82. const ctx = await this.requestContextService.create({
  83. apiType: 'admin',
  84. languageCode: LanguageCode.en,
  85. });
  86. const reviewCount = await this.connection.getRepository(ctx, ProductReview).count();
  87. if (reviewCount === 0) {
  88. const products = await this.connection.getRepository(ctx, Product).find();
  89. if (products.length === 0) {
  90. return;
  91. }
  92. const demoReviews = [
  93. {
  94. summary: 'Great product, highly recommend!',
  95. body: 'I was really impressed with the quality and performance. Would definitely buy again.',
  96. rating: 5,
  97. authorName: 'John Smith',
  98. authorLocation: 'New York, USA',
  99. state: 'approved',
  100. customFields: {
  101. reviewerName: 'JSmith123',
  102. },
  103. },
  104. {
  105. summary: 'Good value for money',
  106. body: 'Does exactly what it says. No complaints.',
  107. rating: 4,
  108. authorName: 'Sarah Wilson',
  109. authorLocation: 'London, UK',
  110. state: 'approved',
  111. customFields: {
  112. reviewerName: 'SarahW',
  113. },
  114. },
  115. {
  116. summary: 'Decent but could be better',
  117. body: 'The product is okay but there is room for improvement in terms of durability.',
  118. rating: 3,
  119. authorName: 'Mike Johnson',
  120. authorLocation: 'Toronto, Canada',
  121. state: 'approved',
  122. customFields: {
  123. reviewerName: 'MikeJ',
  124. },
  125. },
  126. {
  127. summary: 'Exceeded expectations',
  128. body: 'Really happy with this purchase. The quality is outstanding.',
  129. rating: 5,
  130. authorName: 'Emma Brown',
  131. authorLocation: 'Sydney, Australia',
  132. state: 'approved',
  133. customFields: {
  134. reviewerName: 'EmmaB',
  135. },
  136. },
  137. {
  138. summary: 'Good product, fast delivery',
  139. body: 'Product arrived quickly and works as described. Happy with the purchase.',
  140. rating: 4,
  141. authorName: 'David Lee',
  142. authorLocation: 'Singapore',
  143. state: 'approved',
  144. customFields: {
  145. reviewerName: 'DavidL',
  146. },
  147. },
  148. ];
  149. for (const review of demoReviews) {
  150. const randomProduct = products[Math.floor(Math.random() * products.length)];
  151. const productVariants = await this.connection.getRepository(ctx, ProductVariant).find({
  152. where: { productId: randomProduct.id },
  153. });
  154. const randomVariant = productVariants[Math.floor(Math.random() * productVariants.length)];
  155. await this.connection.getRepository(ctx, ProductReview).save({
  156. ...review,
  157. state: review.state as ReviewState,
  158. product: randomProduct,
  159. productVariant: randomVariant,
  160. });
  161. }
  162. }
  163. }
  164. }