index.tsx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import {
  2. Button,
  3. DataTableBulkActionItem,
  4. defineDashboardExtension,
  5. LogoMark,
  6. usePage,
  7. } from '@vendure/dashboard';
  8. import { InfoIcon } from 'lucide-react';
  9. import { toast } from 'sonner';
  10. import {
  11. BodyInputComponent,
  12. ResponseDisplay,
  13. ReviewMultiSelect,
  14. ReviewSingleSelect,
  15. ReviewStateSelect,
  16. TextareaCustomField,
  17. } from './custom-form-components';
  18. import { CustomWidget } from './custom-widget';
  19. import { reviewDetail } from './review-detail';
  20. import { reviewList } from './review-list';
  21. defineDashboardExtension({
  22. login: {
  23. logo: {
  24. component: () => (
  25. <div className="text-red-500 italic">
  26. <LogoMark className="text-red-500 h-6 w-auto" />
  27. </div>
  28. ),
  29. },
  30. afterForm: {
  31. component: () => (
  32. <div>
  33. <Button variant="secondary" className="w-full">
  34. Login with Vendure ID
  35. </Button>
  36. </div>
  37. ),
  38. },
  39. loginImage: {
  40. component: () => (
  41. <div className="h-full w-full bg-red-500 flex items-center justify-center text-white text-2xl font-bold">
  42. Custom Login Image
  43. </div>
  44. ),
  45. },
  46. },
  47. routes: [reviewList, reviewDetail],
  48. widgets: [
  49. {
  50. id: 'custom-widget',
  51. name: 'Custom Widget',
  52. component: CustomWidget,
  53. defaultSize: { w: 3, h: 3 },
  54. },
  55. ],
  56. actionBarItems: [
  57. {
  58. pageId: 'product-detail',
  59. component: props => {
  60. const page = usePage();
  61. return (
  62. <Button
  63. type="button"
  64. onClick={() => {
  65. console.log('Clicked custom action bar item');
  66. }}
  67. >
  68. Test Button
  69. </Button>
  70. );
  71. },
  72. },
  73. ],
  74. pageBlocks: [
  75. {
  76. id: 'my-block',
  77. component: ({ context }) => {
  78. return <div>Here is my custom block!</div>;
  79. },
  80. title: 'My Custom Block',
  81. location: {
  82. pageId: 'product-detail',
  83. column: 'side',
  84. position: { blockId: 'main-form', order: 'after' },
  85. },
  86. },
  87. ],
  88. customFormComponents: {
  89. customFields: [
  90. {
  91. id: 'textarea',
  92. component: TextareaCustomField,
  93. },
  94. {
  95. id: 'review-single-select',
  96. component: ReviewSingleSelect,
  97. },
  98. {
  99. id: 'review-multi-select',
  100. component: ReviewMultiSelect,
  101. },
  102. ],
  103. },
  104. detailForms: [
  105. {
  106. pageId: 'product-variant-detail',
  107. // extendDetailDocument: `
  108. // query {
  109. // productVariant(id: $id) {
  110. // stockOnHand
  111. // product {
  112. // facetValues {
  113. // id
  114. // name
  115. // facet {
  116. // code
  117. // }
  118. // }
  119. // customFields {
  120. // featuredReview {
  121. // id
  122. // productVariant {
  123. // id
  124. // name
  125. // }
  126. // product {
  127. // name
  128. // }
  129. // }
  130. // }
  131. // }
  132. // }
  133. // }
  134. // `,
  135. },
  136. {
  137. pageId: 'review-detail',
  138. inputs: [
  139. {
  140. blockId: 'main-form',
  141. field: 'body',
  142. component: BodyInputComponent,
  143. },
  144. {
  145. blockId: 'main-form',
  146. field: 'state',
  147. component: ReviewStateSelect,
  148. },
  149. ],
  150. displays: [
  151. {
  152. blockId: 'main-form',
  153. field: 'response',
  154. component: ResponseDisplay,
  155. },
  156. ],
  157. },
  158. ],
  159. dataTables: [
  160. {
  161. pageId: 'product-list',
  162. bulkActions: [
  163. {
  164. component: props => (
  165. <DataTableBulkActionItem
  166. onClick={() => {
  167. console.log('Selection:', props.selection);
  168. toast.message(`There are ${props.selection.length} selected items`);
  169. }}
  170. label="My Custom Action"
  171. icon={InfoIcon}
  172. />
  173. ),
  174. },
  175. ],
  176. // extendListDocument: `
  177. // query {
  178. // products {
  179. // items {
  180. // customFields {
  181. // featuredReview {
  182. // id
  183. // productVariant {
  184. // id
  185. // name
  186. // }
  187. // }
  188. // }
  189. // }
  190. // }
  191. // }
  192. // `,
  193. },
  194. ],
  195. });