├── quasar-medusa-client ├── src │ ├── boot │ │ ├── .gitkeep │ │ ├── i18n.js │ │ └── medusaClient.js │ ├── css │ │ └── app.css │ ├── i18n │ │ ├── index.js │ │ └── en-US │ │ │ └── index.js │ ├── App.vue │ ├── stores │ │ ├── store-flag.d.ts │ │ ├── example-store.js │ │ └── index.js │ ├── pages │ │ ├── IndexPage.vue │ │ └── ErrorNotFound.vue │ ├── composables │ │ ├── useAuth.js │ │ ├── useCollections.js │ │ └── useCustomer.js │ └── router │ │ └── routes.js ├── src-capacitor │ ├── .gradle │ │ ├── 5.6.4 │ │ │ ├── gc.properties │ │ │ ├── fileChanges │ │ │ │ └── last-build.bin │ │ │ ├── fileHashes │ │ │ │ └── fileHashes.lock │ │ │ └── executionHistory │ │ │ │ ├── executionHistory.bin │ │ │ │ └── executionHistory.lock │ │ └── buildOutputCleanup │ │ │ ├── cache.properties │ │ │ └── buildOutputCleanup.lock │ ├── android │ │ ├── app │ │ │ ├── .gitignore │ │ │ ├── src │ │ │ │ ├── main │ │ │ │ │ ├── res │ │ │ │ │ │ ├── values │ │ │ │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ │ ├── drawable │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ │ │ ├── drawable-land-hdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-land-mdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-land-xhdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-port-hdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-port-mdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-port-xhdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ │ │ ├── drawable-land-xxhdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-land-xxxhdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-port-xxhdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-port-xxxhdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── xml │ │ │ │ │ │ │ ├── config.xml │ │ │ │ │ │ │ └── file_paths.xml │ │ │ │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ │ │ └── layout │ │ │ │ │ │ │ └── activity_main.xml │ │ │ │ │ ├── assets │ │ │ │ │ │ └── capacitor.config.json │ │ │ │ │ └── java │ │ │ │ │ │ └── org │ │ │ │ │ │ └── capacitor │ │ │ │ │ │ └── quasar │ │ │ │ │ │ └── app │ │ │ │ │ │ ├── EnableHttpsSelfSigned.java │ │ │ │ │ │ └── MainActivity.java │ │ │ │ ├── test │ │ │ │ │ └── java │ │ │ │ │ │ └── com │ │ │ │ │ │ └── getcapacitor │ │ │ │ │ │ └── myapp │ │ │ │ │ │ └── ExampleUnitTest.java │ │ │ │ └── androidTest │ │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── getcapacitor │ │ │ │ │ └── myapp │ │ │ │ │ └── ExampleInstrumentedTest.java │ │ │ ├── capacitor.build.gradle │ │ │ └── proguard-rules.pro │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── settings.gradle │ │ ├── capacitor.settings.gradle │ │ ├── variables.gradle │ │ └── build.gradle │ ├── capacitor.config.json │ ├── capacitor-flag.d.ts │ └── package.json ├── .npmrc ├── .eslintignore ├── public │ ├── favicon.ico │ ├── qrcode-arjs.png │ └── icons │ │ ├── icon-128x128.png │ │ ├── icon-192x192.png │ │ ├── icon-256x256.png │ │ ├── icon-384x384.png │ │ ├── icon-512x512.png │ │ ├── favicon-128x128.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ ├── ms-icon-144x144.png │ │ ├── apple-icon-120x120.png │ │ ├── apple-icon-152x152.png │ │ ├── apple-icon-167x167.png │ │ └── apple-icon-180x180.png ├── src-electron │ ├── icons │ │ ├── icon.ico │ │ ├── icon.png │ │ └── icon.icns │ ├── electron-flag.d.ts │ └── electron-preload.js ├── .editorconfig ├── .env.example ├── src-pwa │ ├── pwa-flag.d.ts │ ├── manifest.json │ └── custom-service-worker.js ├── .vscode │ ├── extensions.json │ └── settings.json ├── .gitignore ├── README.md ├── jsconfig.json └── postcss.config.js ├── medusa-admin ├── static │ └── _redirects ├── .prettierignore ├── netlify.toml ├── src │ ├── utils │ │ ├── focus-by-name.ts │ │ ├── callAll.ts │ │ ├── remove-nullish.ts │ │ ├── date-utils.ts │ │ ├── xorObjFields.ts │ │ ├── convert-empty-string-to-null.js │ │ ├── equals-set.ts │ │ ├── error-messages.js │ │ ├── validate-email.ts │ │ ├── generate-promotion-code.ts │ │ ├── color.ts │ │ ├── product-status-variant.ts │ │ ├── trim-values.ts │ │ ├── get-error-status.ts │ │ ├── is-nullish-object.ts │ │ ├── totals.js │ │ ├── consolidate-images.ts │ │ ├── sales-channel-compare-operator.ts │ │ ├── bytes-converter.ts │ │ ├── form-helpers.ts │ │ ├── fulfillment-providers.mapper.ts │ │ ├── extract-options.ts │ │ ├── get-combinations.js │ │ ├── format-address.js │ │ ├── map-address-to-form.ts │ │ ├── is-line-item.ts │ │ └── images.ts │ ├── fonts │ │ ├── Inter-Regular.ttf │ │ ├── Inter-SemiBold.ttf │ │ ├── RobotoMono-Bold.ttf │ │ └── RobotoMono-Regular.ttf │ ├── components │ │ ├── molecules │ │ │ ├── timeline-events │ │ │ │ ├── event-type.ts │ │ │ │ ├── order-canceled.tsx │ │ │ │ └── event-actionables.tsx │ │ │ ├── select │ │ │ │ └── next-select │ │ │ │ │ ├── components │ │ │ │ │ ├── select-primitives.ts │ │ │ │ │ ├── placeholder.tsx │ │ │ │ │ └── index.ts │ │ │ │ │ └── index.tsx │ │ │ ├── grid-input │ │ │ │ └── index.tsx │ │ │ ├── notification-bell │ │ │ │ ├── notification-bell.stories.tsx │ │ │ │ └── index.tsx │ │ │ ├── tag-input │ │ │ │ └── tag-input.stories.tsx │ │ │ ├── connected-form.tsx │ │ │ ├── sidebar-company-logo │ │ │ │ └── index.tsx │ │ │ ├── view-raw │ │ │ │ └── view-raw.stories.tsx │ │ │ ├── note-input │ │ │ │ └── note-input.stories.tsx │ │ │ ├── table-toaster │ │ │ │ └── index.tsx │ │ │ ├── generating-input │ │ │ │ └── generating-input.stories.tsx │ │ │ ├── hot-key-action │ │ │ │ ├── index.tsx │ │ │ │ └── hot-key-action.stories.tsx │ │ │ ├── sidebar-team-member │ │ │ │ └── index.tsx │ │ │ ├── section │ │ │ │ └── index.tsx │ │ │ ├── native-select │ │ │ │ └── native-select.stories.tsx │ │ │ ├── customers-groups-summary │ │ │ │ └── index.tsx │ │ │ └── customer-avatar-item │ │ │ │ └── index.tsx │ │ ├── fundamentals │ │ │ ├── icons │ │ │ │ ├── types │ │ │ │ │ └── icon-type.ts │ │ │ │ ├── tag-icon │ │ │ │ │ └── tag-icon.stories.tsx │ │ │ │ ├── eye-icon │ │ │ │ │ └── eye-icon.stories.tsx │ │ │ │ ├── bell-icon │ │ │ │ │ └── bell-icon.stories.tsx │ │ │ │ ├── cash-icon │ │ │ │ │ └── cash-icon.stories.tsx │ │ │ │ ├── clock-icon │ │ │ │ │ ├── clock.stories.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── edit-icon │ │ │ │ │ └── edit-icon.stories.tsx │ │ │ │ ├── gear-icon │ │ │ │ │ └── gear-icon.stories.tsx │ │ │ │ ├── gift-icon │ │ │ │ │ └── gift-icon.stories.tsx │ │ │ │ ├── mail-icon │ │ │ │ │ └── mail-icon.stories.tsx │ │ │ │ ├── plus-icon │ │ │ │ │ ├── plus-icon.stories.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── sale-icon │ │ │ │ │ └── sale-icon.stories.tsx │ │ │ │ ├── users-icon │ │ │ │ │ └── user-icon.stories.tsx │ │ │ │ ├── coins-icon │ │ │ │ │ └── coins-icon.stories.tsx │ │ │ │ ├── cross-icon │ │ │ │ │ ├── cross-icon.stories.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── happy-icon │ │ │ │ │ └── happy-icon.stories.tsx │ │ │ │ ├── minus-icon │ │ │ │ │ ├── minus-icon.stories.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── truck-icon │ │ │ │ │ └── truck-icon.stories.tsx │ │ │ │ ├── search-icon │ │ │ │ │ └── search-icon.stories.tsx │ │ │ │ ├── eye-off-icon │ │ │ │ │ └── eye-off-icon.stories.tsx │ │ │ │ ├── map-pin-icon │ │ │ │ │ └── map-pin-icon.stories.tsx │ │ │ │ ├── upload-icon │ │ │ │ │ └── upload-icon.stories.tsx │ │ │ │ ├── percent-icon │ │ │ │ │ └── percent-icon.stories.tsx │ │ │ │ ├── publish-icon │ │ │ │ │ └── publish-icon.stories.tsx │ │ │ │ ├── customer-icon │ │ │ │ │ └── customer-icon.stories.tsx │ │ │ │ ├── down-left │ │ │ │ │ └── down-left-icon.stories.tsx │ │ │ │ ├── pointer-icon │ │ │ │ │ ├── pointer-icon.stories.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── sad-face-icon │ │ │ │ │ └── sad-face-icon.stories.tsx │ │ │ │ ├── arrow-left-icon │ │ │ │ │ ├── arrow-left-icon.stories.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── backspace-icon │ │ │ │ │ └── backspace-icon.stories.tsx │ │ │ │ ├── crosshair-icon │ │ │ │ │ └── crosshair-icon.stories.tsx │ │ │ │ ├── unpublish-icon │ │ │ │ │ └── unpublish-icon.stories.tsx │ │ │ │ ├── arrow-right-icon │ │ │ │ │ ├── arrow-right-icon.stories.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── dollar-sign-icon │ │ │ │ │ └── dollar-sign-icon.stories.tsx │ │ │ │ ├── chevron-left-icon │ │ │ │ │ ├── chevron-left-icon.stories.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── long-arrow-right-icon │ │ │ │ │ ├── long-arrow-right.stories.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── chevron-right-icon │ │ │ │ │ ├── chevron-right-icon.stories.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── bell-noti-icon │ │ │ │ │ └── bell-noti-icon.stories.tsx │ │ │ │ ├── sided-mouth-face │ │ │ │ │ └── sided-mouth-face.stories.tsx │ │ │ │ ├── arrow-top-right-icon │ │ │ │ │ ├── arrow-top-right-icon.stories.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── info-icon │ │ │ │ │ └── info-icon.stories.tsx │ │ │ │ ├── alert-icon │ │ │ │ │ └── alert-icon.stories.tsx │ │ │ │ ├── chevron-down.tsx │ │ │ │ ├── chevron-up.tsx │ │ │ │ ├── check-icon.tsx │ │ │ │ ├── clipboard-copy-icon │ │ │ │ │ └── clipboard-copy.stories.tsx │ │ │ │ ├── arrow-up-icon.tsx │ │ │ │ ├── arrow-down-icon.tsx │ │ │ │ └── sorting-icon │ │ │ │ │ └── sorting-icon.stories.tsx │ │ │ ├── image-placeholder.tsx │ │ │ ├── feature-toggle.tsx │ │ │ ├── status-indicator │ │ │ │ └── status-indicator.stories.tsx │ │ │ └── badge │ │ │ │ └── index.tsx │ │ ├── atoms │ │ │ ├── date-picker │ │ │ │ ├── types.tsx │ │ │ │ ├── utils.ts │ │ │ │ └── date-picker.stories.tsx │ │ │ ├── text-input │ │ │ │ ├── text-input.stories.tsx │ │ │ │ └── index.tsx │ │ │ ├── checkbox │ │ │ │ └── checkbox.stories.tsx │ │ │ ├── page-description │ │ │ │ ├── index.tsx │ │ │ │ └── page-description.stories.tsx │ │ │ ├── os-shortcut │ │ │ │ └── os-shortcut.stories.tsx │ │ │ ├── avatar │ │ │ │ └── avatar.stories.tsx │ │ │ ├── file-upload-field │ │ │ │ └── file-upload-field.stories.tsx │ │ │ ├── settings-card │ │ │ │ └── settings-card.stories.tsx │ │ │ ├── switch │ │ │ │ ├── switch.stories.tsx │ │ │ │ └── index.tsx │ │ │ ├── toaster-container │ │ │ │ ├── index.tsx │ │ │ │ └── toaster.stories.tsx │ │ │ ├── includes-tax-tooltip │ │ │ │ └── index.tsx │ │ │ ├── two-step-delete │ │ │ │ └── two-step-delete.stories.tsx │ │ │ ├── back-button │ │ │ │ └── index.tsx │ │ │ └── save-notification │ │ │ │ └── saving-state.tsx │ │ ├── templates │ │ │ ├── collection-product-table │ │ │ │ ├── types.ts │ │ │ │ └── utils.tsx │ │ │ ├── settings-overview.tsx │ │ │ ├── collection-modal │ │ │ │ ├── add-collection-modal.stories.tsx │ │ │ │ └── collection-modal.stories.tsx │ │ │ └── login-layout.tsx │ │ ├── organisms │ │ │ ├── metadata │ │ │ │ └── add-metadata.stories.tsx │ │ │ ├── price-input │ │ │ │ └── price-input.stories.tsx │ │ │ ├── custom-table-header │ │ │ │ └── index.tsx │ │ │ ├── details-collapsible │ │ │ │ └── details-collapsible.stories.tsx │ │ │ └── file-upload-modal │ │ │ │ └── index.tsx │ │ ├── declarative-toaster │ │ │ ├── index.tsx │ │ │ └── declarative-toaster.stories.tsx │ │ ├── private-route │ │ │ └── index.js │ │ └── loading-container │ │ │ └── index.tsx │ ├── domain │ │ ├── discounts │ │ │ ├── new │ │ │ │ ├── discount-form │ │ │ │ │ └── condition-tables │ │ │ │ │ │ └── shared │ │ │ │ │ │ └── common.tsx │ │ │ │ └── index.tsx │ │ │ └── details │ │ │ │ └── conditions │ │ │ │ └── add-condition │ │ │ │ └── index.tsx │ │ ├── pricing │ │ │ ├── details │ │ │ │ ├── utils.ts │ │ │ │ └── sections │ │ │ │ │ └── prices-details │ │ │ │ │ ├── utils.ts │ │ │ │ │ └── edit-prices-overrides │ │ │ │ │ └── mappers.tsx │ │ │ └── new.tsx │ │ ├── collections │ │ │ └── index.tsx │ │ ├── gift-cards │ │ │ ├── manage │ │ │ │ └── utils │ │ │ │ │ └── types.ts │ │ │ └── index.tsx │ │ ├── sales-channels │ │ │ └── index.tsx │ │ ├── orders │ │ │ └── details │ │ │ │ └── templates │ │ │ │ ├── index.ts │ │ │ │ ├── tracking-link.tsx │ │ │ │ ├── payment-status.tsx │ │ │ │ ├── order-status.tsx │ │ │ │ └── fulfillment-status.tsx │ │ ├── products │ │ │ ├── index.tsx │ │ │ ├── edit │ │ │ │ └── sections │ │ │ │ │ ├── variants │ │ │ │ │ └── edit-variants-modal │ │ │ │ │ │ └── use-edit-variants-modal.tsx │ │ │ │ │ ├── raw │ │ │ │ │ └── index.tsx │ │ │ │ │ └── general │ │ │ │ │ └── channels-modal.tsx │ │ │ └── components │ │ │ │ ├── variant-form │ │ │ │ └── variant-prices-form │ │ │ │ │ └── index.tsx │ │ │ │ ├── sales-channels-modal │ │ │ │ └── use-sales-channels-modal.tsx │ │ │ │ └── organize-form │ │ │ │ └── use-organize-data.tsx │ │ ├── oauth │ │ │ └── index.js │ │ ├── customers │ │ │ └── header.tsx │ │ └── settings │ │ │ ├── currencies │ │ │ └── components │ │ │ │ └── default-store-currency │ │ │ │ └── index.tsx │ │ │ └── regions │ │ │ └── index.tsx │ ├── assets │ │ └── svg │ │ │ ├── star.svg │ │ │ ├── flag.svg │ │ │ ├── plane.svg │ │ │ ├── heart.svg │ │ │ ├── happy.svg │ │ │ ├── lightbulb.svg │ │ │ ├── search.svg │ │ │ └── sprout.svg │ ├── pages │ │ ├── 404.js │ │ └── index.js │ ├── hooks │ │ ├── use-is-me.tsx │ │ ├── use-outside-click.ts │ │ ├── use-scroll.ts │ │ ├── use-notification.tsx │ │ ├── use-window-dimensions.ts │ │ ├── use-set-search-params.tsx │ │ ├── use-on-click-outside.tsx │ │ ├── use-computed-height.ts │ │ ├── use-observe-width.ts │ │ ├── use-debounce.ts │ │ └── use-highlight-search.tsx │ ├── context │ │ └── cache.js │ ├── services │ │ ├── config.js │ │ └── request.js │ └── types │ │ └── shared.ts ├── .prettierrc ├── postcss.config.js ├── .storybook │ └── preview-head.html ├── tsconfig.json ├── gatsby-node.js └── gatsby-ssr.js ├── medusa-server ├── .dockerignore ├── .gitignore ├── tsconfig.json ├── medusa-db.sql ├── develop.sh ├── .babelrc.js ├── Dockerfile └── docker-compose.yml ├── .DS_Store └── docs ├── 3DMode.png ├── mobile.png ├── Browser1.png ├── Browser2.png ├── capacitor.png ├── logo-github.png └── App-desktop-electron.png /quasar-medusa-client/src/boot/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /medusa-admin/static/_redirects: -------------------------------------------------------------------------------- 1 | /a/* /a/index.html 200 -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/.gradle/5.6.4/gc.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /quasar-medusa-client/src/css/app.css: -------------------------------------------------------------------------------- 1 | /* app global css */ 2 | -------------------------------------------------------------------------------- /medusa-server/.dockerignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | 4 | npm-debug.log 5 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/.gradle/5.6.4/fileChanges/last-build.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/.DS_Store -------------------------------------------------------------------------------- /medusa-admin/.prettierignore: -------------------------------------------------------------------------------- 1 | .cache 2 | package.json 3 | package-lock.json 4 | public 5 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build/* 2 | !/build/.npmkeep 3 | -------------------------------------------------------------------------------- /docs/3DMode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/docs/3DMode.png -------------------------------------------------------------------------------- /docs/mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/docs/mobile.png -------------------------------------------------------------------------------- /docs/Browser1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/docs/Browser1.png -------------------------------------------------------------------------------- /docs/Browser2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/docs/Browser2.png -------------------------------------------------------------------------------- /docs/capacitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/docs/capacitor.png -------------------------------------------------------------------------------- /docs/logo-github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/docs/logo-github.png -------------------------------------------------------------------------------- /medusa-admin/netlify.toml: -------------------------------------------------------------------------------- 1 | [template.environment] 2 | GATSBY_MEDUSA_BACKEND_URL="URL of your Medusa Server" 3 | -------------------------------------------------------------------------------- /medusa-server/.gitignore: -------------------------------------------------------------------------------- 1 | /dist 2 | .env 3 | .DS_Store 4 | /uploads 5 | /node_modules 6 | yarn-error.log 7 | /.idea -------------------------------------------------------------------------------- /medusa-server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "experimentalDecorators": true 4 | }, 5 | } 6 | -------------------------------------------------------------------------------- /quasar-medusa-client/.npmrc: -------------------------------------------------------------------------------- 1 | # pnpm-related options 2 | shamefully-hoist=true 3 | strict-peer-dependencies=false 4 | -------------------------------------------------------------------------------- /quasar-medusa-client/src/i18n/index.js: -------------------------------------------------------------------------------- 1 | import enUS from './en-US' 2 | 3 | export default { 4 | 'en-US': enUS 5 | } 6 | -------------------------------------------------------------------------------- /medusa-server/medusa-db.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/medusa-server/medusa-db.sql -------------------------------------------------------------------------------- /quasar-medusa-client/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist 2 | /src-capacitor 3 | /src-cordova 4 | /.quasar 5 | /node_modules 6 | .eslintrc.js 7 | -------------------------------------------------------------------------------- /docs/App-desktop-electron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/docs/App-desktop-electron.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/.gradle/buildOutputCleanup/cache.properties: -------------------------------------------------------------------------------- 1 | #Sun Oct 09 12:45:45 BRT 2022 2 | gradle.version=5.6.4 3 | -------------------------------------------------------------------------------- /medusa-admin/src/utils/focus-by-name.ts: -------------------------------------------------------------------------------- 1 | export function focusByName(name: string) { 2 | document?.getElementsByName(name)?.[0]?.focus() 3 | } 4 | -------------------------------------------------------------------------------- /medusa-admin/src/fonts/Inter-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/medusa-admin/src/fonts/Inter-Regular.ttf -------------------------------------------------------------------------------- /quasar-medusa-client/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/public/favicon.ico -------------------------------------------------------------------------------- /medusa-admin/src/components/molecules/timeline-events/event-type.ts: -------------------------------------------------------------------------------- 1 | export type EventType = { 2 | id: string 3 | type: string 4 | time: Date 5 | } 6 | -------------------------------------------------------------------------------- /medusa-admin/src/fonts/Inter-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/medusa-admin/src/fonts/Inter-SemiBold.ttf -------------------------------------------------------------------------------- /medusa-admin/src/fonts/RobotoMono-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/medusa-admin/src/fonts/RobotoMono-Bold.ttf -------------------------------------------------------------------------------- /quasar-medusa-client/public/qrcode-arjs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/public/qrcode-arjs.png -------------------------------------------------------------------------------- /medusa-admin/src/fonts/RobotoMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/medusa-admin/src/fonts/RobotoMono-Regular.ttf -------------------------------------------------------------------------------- /medusa-admin/src/domain/discounts/new/discount-form/condition-tables/shared/common.tsx: -------------------------------------------------------------------------------- 1 | export const defaultQueryProps = { 2 | limit: 12, 3 | offset: 0, 4 | } 5 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-electron/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-electron/icons/icon.ico -------------------------------------------------------------------------------- /quasar-medusa-client/src-electron/icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-electron/icons/icon.png -------------------------------------------------------------------------------- /medusa-admin/src/utils/callAll.ts: -------------------------------------------------------------------------------- 1 | export const callAll = (...fns: Function[]) => (...args) => 2 | fns?.forEach(async fn => typeof fn === "function" && fn(...args)) 3 | -------------------------------------------------------------------------------- /quasar-medusa-client/public/icons/icon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/public/icons/icon-128x128.png -------------------------------------------------------------------------------- /quasar-medusa-client/public/icons/icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/public/icons/icon-192x192.png -------------------------------------------------------------------------------- /quasar-medusa-client/public/icons/icon-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/public/icons/icon-256x256.png -------------------------------------------------------------------------------- /quasar-medusa-client/public/icons/icon-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/public/icons/icon-384x384.png -------------------------------------------------------------------------------- /quasar-medusa-client/public/icons/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/public/icons/icon-512x512.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-electron/icons/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-electron/icons/icon.icns -------------------------------------------------------------------------------- /quasar-medusa-client/public/icons/favicon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/public/icons/favicon-128x128.png -------------------------------------------------------------------------------- /quasar-medusa-client/public/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/public/icons/favicon-16x16.png -------------------------------------------------------------------------------- /quasar-medusa-client/public/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/public/icons/favicon-32x32.png -------------------------------------------------------------------------------- /quasar-medusa-client/public/icons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/public/icons/favicon-96x96.png -------------------------------------------------------------------------------- /quasar-medusa-client/public/icons/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/public/icons/ms-icon-144x144.png -------------------------------------------------------------------------------- /medusa-server/develop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #Run migrations to ensure the database is updated 4 | medusa migrations run 5 | 6 | #Start development environment 7 | medusa develop -------------------------------------------------------------------------------- /medusa-admin/src/utils/remove-nullish.ts: -------------------------------------------------------------------------------- 1 | export const removeNullish = (obj: Record) => 2 | Object.entries(obj).reduce((a, [k, v]) => (v ? ((a[k] = v), a) : a), {}) 3 | -------------------------------------------------------------------------------- /quasar-medusa-client/public/icons/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/public/icons/apple-icon-120x120.png -------------------------------------------------------------------------------- /quasar-medusa-client/public/icons/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/public/icons/apple-icon-152x152.png -------------------------------------------------------------------------------- /quasar-medusa-client/public/icons/apple-icon-167x167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/public/icons/apple-icon-167x167.png -------------------------------------------------------------------------------- /quasar-medusa-client/public/icons/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/public/icons/apple-icon-180x180.png -------------------------------------------------------------------------------- /medusa-admin/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "always", 3 | "semi": false, 4 | "endOfLine": "auto", 5 | "singleQuote": false, 6 | "tabWidth": 2, 7 | "trailingComma": "es5" 8 | } 9 | -------------------------------------------------------------------------------- /medusa-admin/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require("tailwindcss/nesting"), 4 | require("tailwindcss"), 5 | require("autoprefixer"), 6 | ], 7 | } 8 | -------------------------------------------------------------------------------- /medusa-admin/src/components/molecules/select/next-select/components/select-primitives.ts: -------------------------------------------------------------------------------- 1 | import { components as SelectPrimitives } from "react-select" 2 | 3 | export default SelectPrimitives -------------------------------------------------------------------------------- /medusa-admin/src/utils/date-utils.ts: -------------------------------------------------------------------------------- 1 | export const weekFromNow = () => { 2 | const now = new Date() 3 | const weekFromNow = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000) 4 | return weekFromNow 5 | } 6 | -------------------------------------------------------------------------------- /medusa-admin/src/components/molecules/select/next-select/index.tsx: -------------------------------------------------------------------------------- 1 | import NextCreateableSelect from "./createable-select" 2 | import NextSelect from "./select" 3 | 4 | export { NextSelect, NextCreateableSelect } 5 | -------------------------------------------------------------------------------- /medusa-admin/.storybook/preview-head.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /medusa-admin/src/utils/xorObjFields.ts: -------------------------------------------------------------------------------- 1 | const xorObjFields = (obj: Record, keyA: string, keyB: string) => 2 | obj[keyA] ? { [keyA]: obj[keyA] } : { [keyB]: obj[keyB] } 3 | 4 | export default xorObjFields 5 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/.gradle/5.6.4/fileHashes/fileHashes.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/.gradle/5.6.4/fileHashes/fileHashes.lock -------------------------------------------------------------------------------- /quasar-medusa-client/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable/splash.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/capacitor.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "appId": "org.capacitor.quasar.app", 3 | "appName": "Quasar Medusa Client", 4 | "bundledWebRuntime": false, 5 | "npmClient": "yarn", 6 | "webDir": "www" 7 | } -------------------------------------------------------------------------------- /quasar-medusa-client/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | -------------------------------------------------------------------------------- /quasar-medusa-client/src/i18n/en-US/index.js: -------------------------------------------------------------------------------- 1 | // This is just an example, 2 | // so you can safely delete all default props below 3 | 4 | export default { 5 | failed: 'Action failed', 6 | success: 'Action was successful' 7 | } 8 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/.gradle/buildOutputCleanup/buildOutputCleanup.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/.gradle/buildOutputCleanup/buildOutputCleanup.lock -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/types/icon-type.ts: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | type IconProps = { 4 | color?: string 5 | size?: string | number 6 | } & React.SVGAttributes 7 | 8 | export default IconProps 9 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/.gradle/5.6.4/executionHistory/executionHistory.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/.gradle/5.6.4/executionHistory/executionHistory.bin -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/.gradle/5.6.4/executionHistory/executionHistory.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/.gradle/5.6.4/executionHistory/executionHistory.lock -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-land-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-land-hdpi/splash.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-land-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-land-mdpi/splash.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-land-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-land-xhdpi/splash.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-port-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-port-hdpi/splash.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-port-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-port-mdpi/splash.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-port-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-port-xhdpi/splash.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /medusa-admin/src/components/atoms/date-picker/types.tsx: -------------------------------------------------------------------------------- 1 | import { InputHeaderProps } from "../../fundamentals/input-header" 2 | 3 | export type DateTimePickerProps = { 4 | date: Date 5 | onSubmitDate: (newDate: Date) => void 6 | } & InputHeaderProps 7 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-land-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-land-xxhdpi/splash.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-land-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-land-xxxhdpi/splash.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-port-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-port-xxhdpi/splash.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-port-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/drawable-port-xxxhdpi/splash.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickmonteiro/medusa-ecommerce-vue/HEAD/quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/xml/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | include ':capacitor-cordova-android-plugins' 3 | project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/') 4 | 5 | apply from: 'capacitor.settings.gradle' -------------------------------------------------------------------------------- /medusa-admin/src/utils/convert-empty-string-to-null.js: -------------------------------------------------------------------------------- 1 | export const convertEmptyStringToNull = (data) => { 2 | const obj = { ...data } 3 | Object.keys(data).forEach((k) => { 4 | if (obj[k] === "") { 5 | obj[k] = null 6 | } 7 | }) 8 | return obj 9 | } 10 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/capacitor.settings.gradle: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN 2 | include ':capacitor-android' 3 | project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor') 4 | -------------------------------------------------------------------------------- /medusa-admin/src/utils/equals-set.ts: -------------------------------------------------------------------------------- 1 | export const setsEqual = (as: Set, bs: Set) => { 2 | if (as.size !== bs.size) { 3 | return false 4 | } 5 | for (const a of as) { 6 | if (!bs.has(a)) { 7 | return false 8 | } 9 | } 10 | return true 11 | } 12 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/xml/file_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /medusa-admin/src/utils/error-messages.js: -------------------------------------------------------------------------------- 1 | export const getErrorMessage = (error) => { 2 | let msg = error?.response?.data?.message 3 | if (msg[0].message) { 4 | msg = msg[0].message 5 | } 6 | if (!msg) { 7 | msg = "Something went wrong, Please try again." 8 | } 9 | return msg 10 | } 11 | -------------------------------------------------------------------------------- /medusa-admin/src/utils/validate-email.ts: -------------------------------------------------------------------------------- 1 | export const validateEmail = (email: string) => { 2 | return email 3 | .toLowerCase() 4 | .match( 5 | /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ 6 | ) 7 | } 8 | -------------------------------------------------------------------------------- /medusa-admin/src/utils/generate-promotion-code.ts: -------------------------------------------------------------------------------- 1 | import randomize from "randomatic" 2 | 3 | export const generatePromotionCode = () => { 4 | const code = [ 5 | randomize("A0", 4), 6 | randomize("A0", 4), 7 | randomize("A0", 4), 8 | randomize("A0", 4), 9 | ].join("-") 10 | 11 | return code 12 | } 13 | -------------------------------------------------------------------------------- /quasar-medusa-client/.env.example: -------------------------------------------------------------------------------- 1 | # Rename this to .env and provide your own vavalues 2 | 3 | ## Medusa 4 | MEDUSA_BASE_URL="" 5 | MEDUSA_API_KEY="" 6 | 7 | ## Contentful 8 | CONTENTFUL_SPACE="" 9 | CONTENTFUL_PUBLIC_ACCESS_TOKEN="" 10 | 11 | ## Deskree 12 | DESKREE_BASE_URL="" 13 | 14 | ## Stripe 15 | STRIPE_SECRET="" 16 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/assets/capacitor.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "appId": "org.capacitor.quasar.app", 3 | "appName": "Quasar Medusa Client", 4 | "bundledWebRuntime": false, 5 | "npmClient": "yarn", 6 | "webDir": "www", 7 | "server": { 8 | "url": "https://192.168.0.6:9500" 9 | } 10 | } -------------------------------------------------------------------------------- /medusa-admin/src/utils/color.ts: -------------------------------------------------------------------------------- 1 | export const getColor = (index: number): string => { 2 | const colors = [ 3 | "bg-fuschia-40", 4 | "bg-pink-40", 5 | "bg-orange-40", 6 | "bg-teal-40", 7 | "bg-cyan-40", 8 | "bg-blue-40", 9 | "bg-indigo-40", 10 | ] 11 | return colors[index % colors.length] 12 | } 13 | -------------------------------------------------------------------------------- /medusa-admin/src/components/templates/collection-product-table/types.ts: -------------------------------------------------------------------------------- 1 | export type CollectionProductTableItem = { 2 | id: string 3 | thumbnail?: string 4 | title: string 5 | status: string 6 | created_at: Date 7 | } 8 | 9 | export type AddCollectionProductTableItem = { 10 | selected: boolean 11 | } & CollectionProductTableItem 12 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/pricing/details/utils.ts: -------------------------------------------------------------------------------- 1 | export const mergeExistingWithDefault = ( 2 | variantPrices: any[] = [], 3 | defaultPrices 4 | ) => { 5 | return defaultPrices.map((pr) => { 6 | const price = variantPrices.find( 7 | (vpr) => vpr?.currency_code === pr.currency_code 8 | ) 9 | return price || pr 10 | }) 11 | } 12 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-pwa/pwa-flag.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // THIS FEATURE-FLAG FILE IS AUTOGENERATED, 3 | // REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING 4 | import "quasar/dist/types/feature-flag"; 5 | 6 | declare module "quasar/dist/types/feature-flag" { 7 | interface QuasarFeatureFlags { 8 | pwa: true; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /medusa-admin/src/assets/svg/star.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/collections/index.tsx: -------------------------------------------------------------------------------- 1 | import { Router } from "@reach/router" 2 | import React from "react" 3 | import CollectionDetails from "./details" 4 | 5 | const Collections = () => { 6 | return ( 7 | 8 | 9 | 10 | ) 11 | } 12 | 13 | export default Collections 14 | -------------------------------------------------------------------------------- /medusa-admin/src/utils/product-status-variant.ts: -------------------------------------------------------------------------------- 1 | export const getProductStatusVariant = (title) => { 2 | switch (title) { 3 | case "proposed": 4 | return "warning" 5 | case "published": 6 | return "success" 7 | case "rejected": 8 | return "danger" 9 | case "draft": 10 | default: 11 | return "default" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quasar-medusa-client/src/stores/store-flag.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // THIS FEATURE-FLAG FILE IS AUTOGENERATED, 3 | // REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING 4 | import "quasar/dist/types/feature-flag"; 5 | 6 | declare module "quasar/dist/types/feature-flag" { 7 | interface QuasarFeatureFlags { 8 | store: true; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-electron/electron-flag.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // THIS FEATURE-FLAG FILE IS AUTOGENERATED, 3 | // REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING 4 | import "quasar/dist/types/feature-flag"; 5 | 6 | declare module "quasar/dist/types/feature-flag" { 7 | interface QuasarFeatureFlags { 8 | electron: true; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /medusa-admin/src/utils/trim-values.ts: -------------------------------------------------------------------------------- 1 | export const trimValues = (obj: T) => { 2 | Object.keys(obj).forEach((key) => { 3 | if (typeof obj[key] === "string") { 4 | obj[key] = obj[key].trim() 5 | } else if (obj[key] && obj[key].constructor.name === "Object") { 6 | trimValues(obj[key]) 7 | } 8 | }) 9 | 10 | return obj 11 | } 12 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/capacitor-flag.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // THIS FEATURE-FLAG FILE IS AUTOGENERATED, 3 | // REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING 4 | import "quasar/dist/types/feature-flag"; 5 | 6 | declare module "quasar/dist/types/feature-flag" { 7 | interface QuasarFeatureFlags { 8 | capacitor: true; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /quasar-medusa-client/src/stores/example-store.js: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia' 2 | 3 | export const useCounterStore = defineStore('counter', { 4 | state: () => ({ 5 | counter: 0 6 | }), 7 | getters: { 8 | doubleCount: (state) => state.counter * 2 9 | }, 10 | actions: { 11 | increment () { 12 | this.counter++ 13 | } 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/gift-cards/manage/utils/types.ts: -------------------------------------------------------------------------------- 1 | import { FormImage, Option } from "../../../../types/shared" 2 | 3 | export type ManageGiftCardFormData = { 4 | title: string 5 | handle?: string 6 | subtitle?: string | null 7 | description?: string | null 8 | type: Option | null 9 | tags?: string[] 10 | images: FormImage[] 11 | thumbnail: number 12 | } 13 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/sales-channels/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { Router } from "@reach/router" 3 | 4 | import Details from "./pages/details" 5 | 6 | const SalesChannels = () => { 7 | return ( 8 | 9 |
10 |
11 | 12 | ) 13 | } 14 | 15 | export default SalesChannels 16 | -------------------------------------------------------------------------------- /medusa-server/.babelrc.js: -------------------------------------------------------------------------------- 1 | let ignore = [`**/dist`]; 2 | 3 | // Jest needs to compile this code, but generally we don't want this copied 4 | // to output folders 5 | if (process.env.NODE_ENV !== `test`) { 6 | ignore.push(`**/__tests__`); 7 | } 8 | 9 | module.exports = { 10 | presets: [["babel-preset-medusa-package"], ["@babel/preset-typescript"]], 11 | ignore, 12 | }; 13 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/orders/details/templates/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./display-total" 2 | export * from "./payment-details" 3 | export * from "./address" 4 | export * from "./order-status" 5 | export * from "./payment-status" 6 | export * from "./fulfillment-status" 7 | export * from "./tracking-link" 8 | export * from "./payment-actionables" 9 | export * from "./fulfillment" 10 | -------------------------------------------------------------------------------- /quasar-medusa-client/src/boot/i18n.js: -------------------------------------------------------------------------------- 1 | import { boot } from 'quasar/wrappers' 2 | import { createI18n } from 'vue-i18n' 3 | import messages from 'src/i18n' 4 | 5 | export default boot(({ app }) => { 6 | const i18n = createI18n({ 7 | locale: 'en-US', 8 | globalInjection: true, 9 | messages 10 | }) 11 | 12 | // Set i18n instance on app 13 | app.use(i18n) 14 | }) 15 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/products/index.tsx: -------------------------------------------------------------------------------- 1 | import { Router } from "@reach/router" 2 | import React from "react" 3 | import Edit from "./edit" 4 | import Overview from "./overview" 5 | 6 | const ProductsRoute = () => { 7 | return ( 8 | 9 | 10 | 11 | 12 | ) 13 | } 14 | 15 | export default ProductsRoute 16 | -------------------------------------------------------------------------------- /medusa-server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:17.1.0 2 | 3 | WORKDIR /app/medusa 4 | 5 | COPY package.json . 6 | COPY develop.sh . 7 | COPY yarn.* . 8 | 9 | RUN apt-get update 10 | 11 | RUN apt-get install -y python 12 | 13 | RUN npm install -g npm@latest 14 | 15 | RUN npm install -g @medusajs/medusa-cli@latest 16 | 17 | RUN npm install 18 | 19 | COPY . . 20 | 21 | ENTRYPOINT ["./develop.sh"] 22 | -------------------------------------------------------------------------------- /quasar-medusa-client/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "editorconfig.editorconfig", 5 | "vue.volar", 6 | "wayou.vscode-todo-highlight" 7 | ], 8 | "unwantedRecommendations": [ 9 | "octref.vetur", 10 | "hookyqr.beautify", 11 | "dbaeumer.jshint", 12 | "ms-vscode.vscode-typescript-tslint-plugin" 13 | ] 14 | } -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "quasar-medusa-client", 3 | "version": "0.0.1", 4 | "description": " A Quasar Project with Medusajs", 5 | "author": "Patrick ", 6 | "private": true, 7 | "dependencies": { 8 | "@capacitor/android": "2.5.0", 9 | "@capacitor/cli": "^2.0.0", 10 | "@capacitor/core": "^2.0.0" 11 | } 12 | } -------------------------------------------------------------------------------- /medusa-admin/src/utils/get-error-status.ts: -------------------------------------------------------------------------------- 1 | export const getErrorStatus = (error: Error): { status: number, message: string} | undefined => { 2 | const formattedError = JSON.parse(JSON.stringify(error)) 3 | 4 | if ("status" in formattedError && "message" in formattedError) { 5 | return { status: formattedError.status, message: formattedError.message } 6 | } 7 | 8 | return undefined 9 | } -------------------------------------------------------------------------------- /medusa-admin/src/pages/404.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import SEO from "../components/seo" 3 | import Layout from "../components/templates/layout" 4 | 5 | const NotFoundPage = () => ( 6 | 7 | 8 |

NOT FOUND

9 |

You just hit a route that doesn't exist... the sadness.

10 |
11 | ) 12 | 13 | export default NotFoundPage 14 | -------------------------------------------------------------------------------- /medusa-admin/src/utils/is-nullish-object.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Utility function that checks if every object property is nullish. 3 | */ 4 | const isNullishObject = (obj?: Object | null) => { 5 | if (!obj) { 6 | return true 7 | } 8 | 9 | return Object.values(obj).every( 10 | (value) => value === null || value === undefined || value === "" 11 | ) 12 | } 13 | 14 | export default isNullishObject 15 | -------------------------------------------------------------------------------- /medusa-admin/src/hooks/use-is-me.tsx: -------------------------------------------------------------------------------- 1 | import { useContext, useMemo } from "react" 2 | import { AccountContext } from "../context/account" 3 | 4 | export const useIsMe = (userId: string | undefined) => { 5 | const account = useContext(AccountContext) 6 | 7 | const isMe = useMemo(() => { 8 | return !account.id || !userId ? false : account.id === userId 9 | }, [account, userId]) 10 | 11 | return isMe 12 | } 13 | -------------------------------------------------------------------------------- /medusa-admin/src/utils/totals.js: -------------------------------------------------------------------------------- 1 | const computeShippingTotal = shipping_methods => { 2 | if (!shipping_methods) return 0 3 | return shipping_methods.reduce((acc, method) => acc + method.price, 0) 4 | } 5 | 6 | const computeSubtotal = items => { 7 | if (!items) return 0 8 | return items.reduce((acc, item) => acc + item.unit_price * item.quantity, 0) 9 | } 10 | 11 | export { computeShippingTotal, computeSubtotal } 12 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Quasar Medusa Client 4 | Quasar Medusa Client 5 | org.capacitor.quasar.app 6 | org.capacitor.quasar.app 7 | 8 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/image-placeholder.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import ImagePlaceholderIcon from "./icons/image-placeholder-icon" 3 | 4 | const ImagePlaceholder = () => { 5 | return ( 6 |
7 | 8 |
9 | ) 10 | } 11 | 12 | export default ImagePlaceholder 13 | -------------------------------------------------------------------------------- /medusa-admin/src/utils/consolidate-images.ts: -------------------------------------------------------------------------------- 1 | export const consolidateImages = (images, uploaded) => { 2 | const result: any[] = [] 3 | let i = 0 4 | let j = 0 5 | for (i = 0; i < images.length; i++) { 6 | const image = images[i].url 7 | if (image.startsWith("blob")) { 8 | result.push(uploaded[j]) 9 | j++ 10 | } else { 11 | result.push(image) 12 | } 13 | } 14 | return result 15 | } 16 | -------------------------------------------------------------------------------- /quasar-medusa-client/src/pages/IndexPage.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | -------------------------------------------------------------------------------- /quasar-medusa-client/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.bracketPairColorization.enabled": true, 3 | "editor.guides.bracketPairs": true, 4 | "editor.formatOnSave": true, 5 | "editor.defaultFormatter": "dbaeumer.vscode-eslint", 6 | "editor.codeActionsOnSave": [ 7 | "source.fixAll.eslint" 8 | ], 9 | "eslint.validate": [ 10 | "javascript", 11 | "javascriptreact", 12 | "typescript", 13 | "vue" 14 | ] 15 | } -------------------------------------------------------------------------------- /medusa-admin/src/utils/sales-channel-compare-operator.ts: -------------------------------------------------------------------------------- 1 | import { SalesChannel } from "@medusajs/medusa" 2 | 3 | export const defaultChannelsSorter = (defaultSalesChanenlId: string) => ( 4 | sc1: SalesChannel, 5 | sc2: SalesChannel 6 | ) => { 7 | if (sc1.id === defaultSalesChanenlId) { 8 | return -1 9 | } 10 | if (sc2.id === defaultSalesChanenlId) { 11 | return 1 12 | } 13 | 14 | return sc1.name.localeCompare(sc2.name) 15 | } 16 | -------------------------------------------------------------------------------- /medusa-admin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "esnext", 5 | "jsx": "react", 6 | "lib": ["dom", "esnext"], 7 | "strict": true, 8 | "noEmit": true, 9 | "isolatedModules": true, 10 | "esModuleInterop": true, 11 | "noUnusedLocals": false, 12 | "allowJs": true, 13 | "noImplicitAny": false 14 | }, 15 | "exclude": ["node_modules", "public", ".cache"] 16 | } 17 | -------------------------------------------------------------------------------- /medusa-admin/src/pages/index.js: -------------------------------------------------------------------------------- 1 | import { navigate } from "gatsby" 2 | import React, { useEffect } from "react" 3 | import SEO from "../components/seo" 4 | import Layout from "../components/templates/layout" 5 | 6 | const IndexPage = () => { 7 | useEffect(() => { 8 | navigate("/a/orders") 9 | }, []) 10 | 11 | return ( 12 | 13 | 14 |
hi index
15 |
16 | ) 17 | } 18 | 19 | export default IndexPage 20 | -------------------------------------------------------------------------------- /medusa-admin/src/components/atoms/text-input/text-input.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import TextInput from "." 4 | 5 | export default { 6 | title: "Atoms/TextInput", 7 | component: TextInput, 8 | } as ComponentMeta 9 | 10 | const Template = args => 11 | 12 | export const Primary = Template.bind({}) 13 | Primary.args = { 14 | placeholder: "Search anything...", 15 | } 16 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/gift-cards/index.tsx: -------------------------------------------------------------------------------- 1 | import { Router } from "@reach/router" 2 | import React from "react" 3 | import GiftCardDetails from "./details" 4 | import ManageGiftCard from "./manage" 5 | import Overview from "./overview" 6 | 7 | const GiftCard = () => { 8 | return ( 9 | 10 | 11 | 12 | 13 | 14 | ) 15 | } 16 | 17 | export default GiftCard 18 | -------------------------------------------------------------------------------- /medusa-admin/src/utils/bytes-converter.ts: -------------------------------------------------------------------------------- 1 | const units: [string, number][] = [ 2 | ["B", 1], 3 | ["Kb", 1000], 4 | ["Mb", 1000000], 5 | ["Gb", 1000000000] 6 | ] 7 | 8 | export function bytesConverter(size: number): string | undefined { 9 | let result: string | undefined = undefined 10 | 11 | for (const [unit, divider] of units) { 12 | if (size >= divider) { 13 | result = `${(size / divider).toFixed(2)} ${unit}` 14 | } 15 | } 16 | 17 | return result 18 | } 19 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/capacitor.build.gradle: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN 2 | 3 | android { 4 | compileOptions { 5 | sourceCompatibility JavaVersion.VERSION_1_8 6 | targetCompatibility JavaVersion.VERSION_1_8 7 | } 8 | } 9 | 10 | apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" 11 | dependencies { 12 | 13 | 14 | } 15 | 16 | 17 | if (hasProperty('postBuildExtras')) { 18 | postBuildExtras() 19 | } 20 | -------------------------------------------------------------------------------- /medusa-admin/src/components/atoms/checkbox/checkbox.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta, ComponentStory } from "@storybook/react" 2 | import React from "react" 3 | import Checkbox from "." 4 | 5 | export default { 6 | title: "Atoms/Checkbox", 7 | component: Checkbox, 8 | } as ComponentMeta 9 | 10 | const Template: ComponentStory = (args) => ( 11 | 12 | ) 13 | 14 | export const Default = Template.bind({}) 15 | Default.args = { 16 | label: "Checkbox", 17 | } 18 | -------------------------------------------------------------------------------- /quasar-medusa-client/src/composables/useAuth.js: -------------------------------------------------------------------------------- 1 | import { medusa } from 'boot/medusaClient' 2 | 3 | export default () => { 4 | const login = async (email, password) => { 5 | try { 6 | const { customer } = medusa.auth.authenticate(email, password) 7 | return customer 8 | } catch (e) { 9 | throw new Error(e) 10 | } 11 | } 12 | 13 | const logout = async () => { 14 | return await medusa.auth.deleteSession() 15 | } 16 | 17 | return { 18 | login, 19 | logout 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/pricing/new.tsx: -------------------------------------------------------------------------------- 1 | import { RouteComponentProps } from "@reach/router" 2 | import React from "react" 3 | import PriceListForm from "./pricing-form" 4 | import { PriceListFormProvider } from "./pricing-form/form/pricing-form-context" 5 | import { ViewType } from "./pricing-form/types" 6 | 7 | const New: React.FC = () => { 8 | return ( 9 | 10 | 11 | 12 | ) 13 | } 14 | 15 | export default New 16 | -------------------------------------------------------------------------------- /medusa-admin/src/hooks/use-outside-click.ts: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react" 2 | 3 | const useOutsideClick = (callback: () => void, ref: any) => { 4 | useEffect(() => { 5 | const handleClickOutside = (e) => { 6 | if (!ref.current.contains(e.target)) { 7 | callback() 8 | } 9 | } 10 | 11 | document.addEventListener("click", handleClickOutside) 12 | 13 | return () => { 14 | document.removeEventListener("click", handleClickOutside) 15 | } 16 | }, [ref]) 17 | } 18 | 19 | export default useOutsideClick 20 | -------------------------------------------------------------------------------- /medusa-admin/src/components/atoms/page-description/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | type PageDescriptionProps = { 4 | title?: string 5 | subtitle?: string 6 | } 7 | 8 | const PageDescription: React.FC = ({ 9 | title, 10 | subtitle, 11 | }) => { 12 | return ( 13 |
14 |

{title}

15 |

{subtitle}

16 |
17 | ) 18 | } 19 | 20 | export default PageDescription 21 | -------------------------------------------------------------------------------- /medusa-admin/src/hooks/use-scroll.ts: -------------------------------------------------------------------------------- 1 | import { useState } from "react" 2 | 3 | type useScrollProps = { 4 | threshold?: number 5 | } 6 | 7 | export const useScroll = ({ threshold = 0 }: useScrollProps) => { 8 | const [isScrolled, setIsScrolled] = useState(false) 9 | 10 | const scrollListener = e => { 11 | const currentScrollY = e.target.scrollTop 12 | if (currentScrollY > threshold) { 13 | setIsScrolled(true) 14 | } else { 15 | setIsScrolled(false) 16 | } 17 | } 18 | 19 | return { isScrolled, scrollListener } 20 | } 21 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.getcapacitor.myapp; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /medusa-admin/src/components/atoms/text-input/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import clsx from "clsx" 3 | 4 | type TextInputProps = React.InputHTMLAttributes 5 | 6 | const TextInput = React.forwardRef( 7 | ({ className, ...props }, ref) => ( 8 | 16 | ) 17 | ) 18 | 19 | export default TextInput 20 | -------------------------------------------------------------------------------- /medusa-admin/src/assets/svg/flag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /medusa-admin/src/components/templates/settings-overview.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import PageDescription from "../atoms/page-description" 3 | 4 | const SettingsOverview: React.FC = ({ children }) => { 5 | return ( 6 |
7 | 11 |
12 | {children} 13 |
14 |
15 | ) 16 | } 17 | 18 | export default SettingsOverview 19 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/orders/details/templates/tracking-link.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | export const TrackingLink = ({ trackingLink }) => { 4 | if (trackingLink.url) { 5 | return ( 6 | 11 |
{trackingLink.tracking_number}
12 |
13 | ) 14 | } else { 15 | return ( 16 | {trackingLink.tracking_number} 17 | ) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /quasar-medusa-client/src/stores/index.js: -------------------------------------------------------------------------------- 1 | import { store } from 'quasar/wrappers' 2 | import { createPinia } from 'pinia' 3 | 4 | /* 5 | * If not building with SSR mode, you can 6 | * directly export the Store instantiation; 7 | * 8 | * The function below can be async too; either use 9 | * async/await or return a Promise which resolves 10 | * with the Store instance. 11 | */ 12 | 13 | export default store((/* { ssrContext } */) => { 14 | const pinia = createPinia() 15 | 16 | // You can add Pinia plugins here 17 | // pinia.use(SomePiniaPlugin) 18 | 19 | return pinia 20 | }) 21 | -------------------------------------------------------------------------------- /medusa-admin/src/components/organisms/metadata/add-metadata.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta, ComponentStory } from "@storybook/react" 2 | import React from "react" 3 | import Metadata from "." 4 | 5 | export default { 6 | title: "Organisms/Metadata", 7 | component: Metadata, 8 | } as ComponentMeta 9 | 10 | const Template: ComponentStory = (args) => ( 11 |
12 | 13 |
14 | ) 15 | 16 | export const Default = Template.bind({}) 17 | Default.args = { 18 | control: {}, 19 | metadata: [], 20 | } 21 | -------------------------------------------------------------------------------- /medusa-admin/src/components/atoms/date-picker/utils.ts: -------------------------------------------------------------------------------- 1 | export const range = (start, end) => { 2 | const range: number[] = [] 3 | for (let i = start; i <= end; i++) { 4 | range.push(i) 5 | } 6 | return range 7 | } 8 | 9 | export const getYearRange = (step = 20) => 10 | range(new Date().getFullYear() - step, new Date().getFullYear() + step) 11 | 12 | export const monthNames = [ 13 | "January", 14 | "February", 15 | "March", 16 | "April", 17 | "May", 18 | "June", 19 | "July", 20 | "August", 21 | "September", 22 | "October", 23 | "November", 24 | "December", 25 | ] 26 | -------------------------------------------------------------------------------- /quasar-medusa-client/.gitignore: -------------------------------------------------------------------------------- 1 | # Other 2 | .DS_Store 3 | .thumbs.db 4 | node_modules 5 | .env 6 | 7 | # Quasar core related directories 8 | .quasar 9 | /dist 10 | 11 | # Cordova related directories and files 12 | /src-cordova/node_modules 13 | /src-cordova/platforms 14 | /src-cordova/plugins 15 | /src-cordova/www 16 | 17 | # Capacitor related directories and files 18 | /src-capacitor/www 19 | /src-capacitor/node_modules 20 | 21 | # Log files 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | 26 | # Editor directories and files 27 | .idea 28 | *.suo 29 | *.ntvs* 30 | *.njsproj 31 | *.sln 32 | -------------------------------------------------------------------------------- /medusa-admin/src/hooks/use-notification.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { toast } from "react-hot-toast" 3 | import Notification, { 4 | NotificationTypes, 5 | } from "../components/atoms/notification" 6 | 7 | const useNotification = () => { 8 | return (title: string, message: string, type: NotificationTypes) => { 9 | toast.custom( 10 | (t) => ( 11 | 12 | ), 13 | { 14 | position: "top-right", 15 | duration: 3000, 16 | } 17 | ) 18 | } 19 | } 20 | 21 | export default useNotification 22 | -------------------------------------------------------------------------------- /medusa-admin/src/components/molecules/grid-input/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | type GridInputProps = React.InputHTMLAttributes 4 | 5 | const GridInput: React.FC = ({ value, ...props }) => { 6 | return ( 7 | 12 | ) 13 | } 14 | 15 | export default GridInput 16 | -------------------------------------------------------------------------------- /medusa-admin/src/context/cache.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react" 2 | 3 | export const defaultCacheContext = { 4 | cache: {}, 5 | } 6 | 7 | export const CacheContext = React.createContext(defaultCacheContext) 8 | 9 | export const CacheProvider = ({ children }) => { 10 | const [cache, set] = useState({}) 11 | 12 | const setCache = (key, val) => { 13 | set({ 14 | ...cache, 15 | [key]: val, 16 | }) 17 | } 18 | 19 | return ( 20 | 26 | {children} 27 | 28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/products/edit/sections/variants/edit-variants-modal/use-edit-variants-modal.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react" 2 | 3 | type EditVariantsModalContext = { 4 | onClose: () => void 5 | } 6 | 7 | export const EditVariantsModalContext = React.createContext( 8 | null 9 | ) 10 | 11 | export const useEditVariantsModal = () => { 12 | const context = useContext(EditVariantsModalContext) 13 | 14 | if (context === null) { 15 | throw new Error( 16 | "useEditVariantsModal must be used within a EditVariantsModalProvicer" 17 | ) 18 | } 19 | 20 | return context 21 | } 22 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/tag-icon/tag-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import TagIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/TagIcon", 7 | component: TagIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/eye-icon/eye-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import EyeIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/EyeIcon", 7 | component: EyeIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = (args) => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "20", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/services/config.js: -------------------------------------------------------------------------------- 1 | import { QueryClient } from "react-query" 2 | 3 | let medusaUrl = "http://localhost:9000" 4 | 5 | // deprecated 6 | if (process.env.GATSBY_STORE_URL) { 7 | medusaUrl = process.env.GATSBY_STORE_URL 8 | } 9 | 10 | // takes precedence over GATSBY_STORE_URL 11 | if (process.env.GATSBY_MEDUSA_BACKEND_URL) { 12 | medusaUrl = process.env.GATSBY_MEDUSA_BACKEND_URL 13 | } 14 | 15 | const queryClient = new QueryClient({ 16 | defaultOptions: { 17 | queries: { 18 | refetchOnWindowFocus: false, 19 | staleTime: 90000, 20 | retry: 1, 21 | }, 22 | }, 23 | }) 24 | 25 | export { medusaUrl, queryClient } 26 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/bell-icon/bell-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import BellIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/BellIcon", 7 | component: BellIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/cash-icon/cash-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import CashIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/CashIcon", 7 | component: CashIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = (args) => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/clock-icon/clock.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import ClockIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/ClockIcon", 7 | component: ClockIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = (args) => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/edit-icon/edit-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import EditIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/EditIcon", 7 | component: EditIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "20", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/gear-icon/gear-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import GearIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/GearIcon", 7 | component: GearIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/gift-icon/gift-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import GiftIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/GiftIcon", 7 | component: GiftIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/mail-icon/mail-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import MailIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/MailIcon", 7 | component: MailIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/plus-icon/plus-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import PlusIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/PlusIcon", 7 | component: PlusIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/sale-icon/sale-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import SaleIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/SaleIcon", 7 | component: SaleIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = (args) => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/users-icon/user-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import UserIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/UserIcon", 7 | component: UserIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/templates/collection-modal/add-collection-modal.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta, ComponentStory } from "@storybook/react" 2 | import React from "react" 3 | import CollectionModal from "." 4 | 5 | export default { 6 | title: "Template/AddCollectionModal", 7 | component: CollectionModal, 8 | } as ComponentMeta 9 | 10 | const Template: ComponentStory = (args) => ( 11 | 12 | ) 13 | 14 | export const Default = Template.bind({}) 15 | Default.args = { 16 | onClose: () => {}, 17 | onSubmit: (values) => console.log(JSON.stringify(values, null, 2)), 18 | } 19 | -------------------------------------------------------------------------------- /medusa-admin/src/components/templates/collection-modal/collection-modal.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta, ComponentStory } from "@storybook/react" 2 | import React from "react" 3 | import CollectionModal from "." 4 | 5 | export default { 6 | title: "Template/AddCollectionModal", 7 | component: CollectionModal, 8 | } as ComponentMeta 9 | 10 | const Template: ComponentStory = (args) => ( 11 | 12 | ) 13 | 14 | export const Default = Template.bind({}) 15 | Default.args = { 16 | onClose: () => {}, 17 | onSubmit: (values) => console.log(JSON.stringify(values, null, 2)), 18 | } 19 | -------------------------------------------------------------------------------- /medusa-admin/src/components/declarative-toaster/index.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { toast, ToastOptions } from "react-hot-toast" 3 | 4 | export type ToasterProps = { 5 | visible: boolean 6 | children: React.ReactElement 7 | } & ToastOptions 8 | 9 | const Toaster = ({ visible, children, ...options }: ToasterProps) => { 10 | React.useEffect(() => { 11 | if (visible) { 12 | toast.custom((t) => React.cloneElement(children, { toast: t }), { 13 | ...options, 14 | }) 15 | } else { 16 | toast.dismiss(options.id) 17 | } 18 | }, [visible, children]) 19 | 20 | return null 21 | } 22 | 23 | export default Toaster 24 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/feature-toggle.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { FeatureFlagContext } from "../../context/feature-flag" 3 | 4 | export type FeatureToggleProps = { 5 | featureFlag: string 6 | showOnlyWhenDisabled?: boolean 7 | } 8 | 9 | const FeatureToggle: React.FC = ({ 10 | featureFlag, 11 | showOnlyWhenDisabled = false, 12 | children, 13 | }) => { 14 | const { isFeatureEnabled } = React.useContext(FeatureFlagContext) 15 | 16 | const showContent = isFeatureEnabled(featureFlag) === !showOnlyWhenDisabled 17 | return showContent ? <>{children} : null 18 | } 19 | 20 | export default FeatureToggle 21 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/coins-icon/coins-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import CoinsIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/CoinsIcon", 7 | component: CoinsIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/cross-icon/cross-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import CrossIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/CrossIcon", 7 | component: CrossIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/happy-icon/happy-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import HappyIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/HappyIcon", 7 | component: HappyIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/minus-icon/minus-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import MinusIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/MinusIcon", 7 | component: MinusIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/truck-icon/truck-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import TruckIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/TruckIcon", 7 | component: TruckIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/molecules/notification-bell/notification-bell.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import NotificationBell from "." 4 | 5 | export default { 6 | title: "Molecules/NotificationBell", 7 | component: NotificationBell, 8 | } as ComponentMeta 9 | 10 | const Template = args => 11 | 12 | export const HasNotifications = Template.bind({}) 13 | HasNotifications.args = { 14 | hasNotifications: true, 15 | } 16 | 17 | export const NoNotifications = Template.bind({}) 18 | NoNotifications.args = { 19 | hasNotifications: false, 20 | } 21 | -------------------------------------------------------------------------------- /quasar-medusa-client/README.md: -------------------------------------------------------------------------------- 1 | # Quasar Medusa Client (quasar-medusa-client) 2 | 3 | A Quasar Project with Medusajs 4 | 5 | ## Install the dependencies 6 | ```bash 7 | yarn 8 | # or 9 | npm install 10 | ``` 11 | 12 | ### Start the app in development mode (hot-code reloading, error reporting, etc.) 13 | ```bash 14 | quasar dev 15 | ``` 16 | 17 | 18 | ### Lint the files 19 | ```bash 20 | yarn lint 21 | # or 22 | npm run lint 23 | ``` 24 | 25 | 26 | 27 | ### Build the app for production 28 | ```bash 29 | quasar build 30 | ``` 31 | 32 | ### Customize the configuration 33 | See [Configuring quasar.config.js](https://v2.quasar.dev/quasar-cli-vite/quasar-config-js). 34 | -------------------------------------------------------------------------------- /medusa-admin/src/components/atoms/os-shortcut/os-shortcut.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import OSShortcut from "." 4 | 5 | export default { 6 | title: "Atoms/OSShortcut", 7 | component: OSShortcut, 8 | } as ComponentMeta 9 | 10 | const Template = args => 11 | 12 | export const CmdK = Template.bind({}) 13 | CmdK.args = { 14 | winModifiers: "Control", 15 | macModifiers: "⌘", 16 | keys: "K", 17 | } 18 | 19 | export const CmdKL = Template.bind({}) 20 | CmdKL.args = { 21 | winModifiers: "Control", 22 | macModifiers: "⌘", 23 | keys: ["K", "L"], 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/search-icon/search-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import SearchIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/SearchIcon", 7 | component: SearchIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/molecules/tag-input/tag-input.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta, ComponentStory } from "@storybook/react" 2 | import React from "react" 3 | import TagInput from "." 4 | 5 | export default { 6 | title: "Molecules/TagInput", 7 | component: TagInput, 8 | } as ComponentMeta 9 | 10 | const Template: ComponentStory = (args) => ( 11 | 12 | ) 13 | 14 | export const Normal = Template.bind({}) 15 | Normal.args = { 16 | label: "Tags (comma separated values)", 17 | values: ["SS21", "Core"], 18 | placeholder: "Sprint, autumn, etc.", 19 | tooltipContent: "Used to add keywords", 20 | } 21 | -------------------------------------------------------------------------------- /medusa-admin/src/utils/form-helpers.ts: -------------------------------------------------------------------------------- 1 | import { DeepMap } from "react-hook-form" 2 | 3 | export const stringOrNull = (value: string) => { 4 | return value === "" ? null : value 5 | } 6 | 7 | export const numberOrNull = (value: string) => { 8 | const tmp = parseInt(value, 10) 9 | 10 | return isNaN(tmp) ? null : tmp 11 | } 12 | 13 | export const checkForDirtyState = ( 14 | dirtyFields: DeepMap, true>, 15 | otherValues: Record 16 | ) => { 17 | const otherDirtyState = otherValues 18 | ? Object.values(otherValues).some((v) => v) 19 | : false 20 | 21 | return !!Object.keys(dirtyFields).length || otherDirtyState 22 | } 23 | -------------------------------------------------------------------------------- /medusa-admin/src/utils/fulfillment-providers.mapper.ts: -------------------------------------------------------------------------------- 1 | import { Option } from "../types/shared" 2 | 3 | export default function (provider: string): Option { 4 | switch (provider) { 5 | case "primecargo": 6 | return { 7 | label: "Prime Cargo", 8 | value: "primecargo", 9 | } 10 | case "manual": 11 | return { 12 | label: "Manual", 13 | value: "manual", 14 | } 15 | case "webshipper": 16 | return { 17 | label: "Webshipper", 18 | value: "webshipper", 19 | } 20 | default: 21 | return { 22 | label: provider, 23 | value: provider, 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /medusa-admin/src/components/atoms/avatar/avatar.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import Avatar from "." 4 | 5 | export default { 6 | title: "Atoms/Avatar", 7 | component: Avatar, 8 | } as ComponentMeta 9 | 10 | const Template = args => ( 11 |
12 | 13 |
14 | ) 15 | 16 | export const User = Template.bind({}) 17 | User.args = { 18 | user: { 19 | first_name: "Kasper", 20 | last_name: "Kristensen", 21 | email: "kasper@medusajs.com", 22 | }, 23 | } 24 | 25 | export const NoUser = Template.bind({}) 26 | NoUser.args = {} 27 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/eye-off-icon/eye-off-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import EyeOffIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/EyeOffIcon", 7 | component: EyeOffIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = (args) => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "20", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/map-pin-icon/map-pin-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import MapPinIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/MapPinIcon", 7 | component: MapPinIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/upload-icon/upload-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import UploadIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/UploadIcon", 7 | component: UploadIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = (args) => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "20", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/utils/extract-options.ts: -------------------------------------------------------------------------------- 1 | export function extractRegionOptions( 2 | regions: any[] | undefined 3 | ): { label: string; value: string; currency: string }[] { 4 | if (!regions) { 5 | return [] 6 | } 7 | 8 | return regions.map((region) => ({ 9 | label: region.name, 10 | value: region.id, 11 | currency: region.currency_code, 12 | })) 13 | } 14 | 15 | export function extractProductOptions( 16 | products: any[] | undefined 17 | ): { label: string; value: string }[] { 18 | if (!products) { 19 | return [] 20 | } 21 | 22 | return products.map((product) => ({ 23 | label: product.title, 24 | value: product.id, 25 | })) 26 | } 27 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/variables.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | minSdkVersion = 21 3 | compileSdkVersion = 29 4 | targetSdkVersion = 29 5 | androidxAppCompatVersion = '1.1.0' 6 | androidxCoreVersion = '1.2.0' 7 | androidxMaterialVersion = '1.1.0-rc02' 8 | androidxBrowserVersion = '1.2.0' 9 | androidxLocalbroadcastmanagerVersion = '1.0.0' 10 | androidxExifInterfaceVersion = '1.2.0' 11 | firebaseMessagingVersion = '20.1.2' 12 | playServicesLocationVersion = '17.0.0' 13 | junitVersion = '4.12' 14 | androidxJunitVersion = '1.1.1' 15 | androidxEspressoCoreVersion = '3.2.0' 16 | cordovaAndroidVersion = '7.0.0' 17 | } -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/percent-icon/percent-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import PercentIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/PercentIcon", 7 | component: PercentIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/publish-icon/publish-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import PublishIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/PublishIcon", 7 | component: PublishIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "20", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/hooks/use-window-dimensions.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react" 2 | 3 | export const useWindowDimensions = () => { 4 | const [dimensions, setDimensions] = useState({ 5 | height: window.innerHeight, 6 | width: window.innerWidth, 7 | }) 8 | 9 | useEffect(() => { 10 | const handleResize = () => { 11 | setDimensions({ 12 | height: window.innerHeight, 13 | width: window.innerWidth, 14 | }) 15 | } 16 | 17 | window.addEventListener("resize", handleResize) 18 | 19 | return () => { 20 | window.removeEventListener("resize", handleResize) 21 | } 22 | }, []) 23 | 24 | return dimensions 25 | } 26 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/customer-icon/customer-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import CustomerIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/CustomerIcon", 7 | component: CustomerIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/down-left/down-left-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import DownLeftIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/DownLeftIcon", 7 | component: DownLeftIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = (args) => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "16px", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/pointer-icon/pointer-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import PointerIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/PointerIcon", 7 | component: PointerIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = (args) => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "16px", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/sad-face-icon/sad-face-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import SadFaceIcon from "./index" 4 | 5 | export default { 6 | title: "Fundamentals/Icons/CrossIcon", 7 | component: SadFaceIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-electron/electron-preload.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is used specifically for security reasons. 3 | * Here you can access Nodejs stuff and inject functionality into 4 | * the renderer thread (accessible there through the "window" object) 5 | * 6 | * WARNING! 7 | * If you import anything from node_modules, then make sure that the package is specified 8 | * in package.json > dependencies and NOT in devDependencies 9 | * 10 | * Example (injects window.myAPI.doAThing() into renderer thread): 11 | * 12 | * import { contextBridge } from 'electron' 13 | * 14 | * contextBridge.exposeInMainWorld('myAPI', { 15 | * doAThing: () => {} 16 | * }) 17 | */ 18 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/oauth/index.js: -------------------------------------------------------------------------------- 1 | import qs from "query-string" 2 | import React from "react" 3 | import Button from "../../components/fundamentals/button" 4 | import Medusa from "../../services/api" 5 | 6 | const Oauth = ({ app_name }) => { 7 | const { code, state } = qs.parse(location.search) 8 | return ( 9 | <> 10 |
{app_name}
11 | 22 | 23 | ) 24 | } 25 | 26 | export default Oauth 27 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/orders/details/templates/payment-status.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | import StatusDot from "../../../../components/fundamentals/status-indicator" 4 | 5 | export const PaymentStatusComponent = ({ status }) => { 6 | switch (status) { 7 | case "captured": 8 | return 9 | case "awaiting": 10 | return 11 | case "canceled": 12 | return 13 | case "requires_action": 14 | return 15 | default: 16 | return null 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/products/components/variant-form/variant-prices-form/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { NestedForm } from "../../../../../utils/nested-form" 3 | import PricesForm, { PricesFormType } from "../../prices-form" 4 | 5 | type Props = { 6 | form: NestedForm 7 | } 8 | 9 | const VariantPricesForm = ({ form }: Props) => { 10 | return ( 11 |
12 |

13 | Configure the pricing for this variant. 14 |

15 |
16 | 17 |
18 |
19 | ) 20 | } 21 | 22 | export default VariantPricesForm 23 | -------------------------------------------------------------------------------- /medusa-admin/src/utils/get-combinations.js: -------------------------------------------------------------------------------- 1 | export const getCombinations = (options) => { 2 | if (options.length === 0) { 3 | return [] 4 | } 5 | 6 | if (options.length === 1) { 7 | const values = options.shift().values 8 | if (values.length > 0) { 9 | return values.map((v) => [v]) 10 | } 11 | 12 | return [""] 13 | } 14 | 15 | const combinations = [] 16 | const theseValues = options.shift().values 17 | 18 | const lowerCombinations = getCombinations(options) 19 | for (const v of theseValues) { 20 | for (const second of lowerCombinations) { 21 | combinations.push([v, second].flat()) 22 | } 23 | } 24 | 25 | return combinations 26 | } 27 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/arrow-left-icon/arrow-left-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import ArrowLeftIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/ArrowLeftIcon", 7 | component: ArrowLeftIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/backspace-icon/backspace-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import BackspaceIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/BackspaceIcon", 7 | component: BackspaceIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = (args) => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "16", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/crosshair-icon/crosshair-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import CrosshairIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/CrosshairIcon", 7 | component: CrosshairIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/unpublish-icon/unpublish-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import UnpublishIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/UnpublishIcon", 7 | component: UnpublishIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = (args) => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "20", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/molecules/connected-form.tsx: -------------------------------------------------------------------------------- 1 | import type { ReactElement } from "react" 2 | import type { FieldValues, UseFormReturn } from "react-hook-form" 3 | import { useFormContext } from "react-hook-form" 4 | 5 | interface ConnectedFormProps { 6 | children(children: UseFormReturn): ReactElement 7 | } 8 | 9 | /** 10 | * Utility component for nested forms. 11 | */ 12 | const ConnectedForm = ({ 13 | children, 14 | }: ConnectedFormProps) => { 15 | const methods = useFormContext() 16 | 17 | return children({ ...methods }) 18 | } 19 | 20 | export default ConnectedForm 21 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/orders/details/templates/order-status.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | import StatusDot from "../../../../components/fundamentals/status-indicator" 4 | 5 | export const OrderStatusComponent = ({ status }) => { 6 | switch (status) { 7 | case "completed": 8 | return 9 | case "pending": 10 | return 11 | case "canceled": 12 | return 13 | case "requires_action": 14 | return 15 | default: 16 | return null 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/arrow-right-icon/arrow-right-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import ArrowRightIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/ArrowRightIcon", 7 | component: ArrowRightIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/dollar-sign-icon/dollar-sign-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import DollarSignIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/DollarSignIcon", 7 | component: DollarSignIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/molecules/timeline-events/order-canceled.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { TimelineEvent } from "../../../hooks/use-build-timeline" 3 | import CancelIcon from "../../fundamentals/icons/cancel-icon" 4 | import EventContainer, { EventIconColor } from "./event-container" 5 | 6 | type OrderCanceledProps = { 7 | event: TimelineEvent 8 | } 9 | 10 | const OrderCanceled: React.FC = ({ event }) => { 11 | const args = { 12 | icon: , 13 | iconColor: EventIconColor.RED, 14 | time: event.time, 15 | title: "Order Canceled", 16 | } 17 | return 18 | } 19 | 20 | export default OrderCanceled 21 | -------------------------------------------------------------------------------- /medusa-admin/gatsby-node.js: -------------------------------------------------------------------------------- 1 | exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => { 2 | if (stage === "build-html") { 3 | actions.setWebpackConfig({ 4 | module: { 5 | rules: [ 6 | { 7 | test: /react-json-view/, 8 | use: loaders.null(), 9 | }, 10 | { 11 | test: /emoji-picker-react/, 12 | use: loaders.null(), 13 | }, 14 | ], 15 | }, 16 | }) 17 | } 18 | actions.setWebpackConfig({ 19 | resolve: { 20 | fallback: { 21 | crypto: require.resolve("crypto-browserify"), 22 | stream: require.resolve("stream-browserify"), 23 | }, 24 | }, 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/chevron-left-icon/chevron-left-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import ChevronLeftIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/ChevronLeftIcon", 7 | component: ChevronLeftIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = (args) => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/long-arrow-right-icon/long-arrow-right.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import LongArrowRight from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/LongArrowRight", 7 | component: LongArrowRight, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = (args) => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/molecules/sidebar-company-logo/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | type SidebarCompanyLogoProps = { 4 | storeName?: string 5 | } 6 | 7 | const SidebarCompanyLogo: React.FC = ({ 8 | storeName, 9 | }: SidebarCompanyLogoProps) => { 10 | return ( 11 |
12 |
13 |
{storeName?.slice(0, 1) || "M"}
14 |
15 | {storeName} 16 |
17 | ) 18 | } 19 | 20 | export default SidebarCompanyLogo 21 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/app/src/main/java/org/capacitor/quasar/app/EnableHttpsSelfSigned.java: -------------------------------------------------------------------------------- 1 | 2 | package org.capacitor.quasar.app; 3 | import android.net.http.SslError; 4 | import android.webkit.SslErrorHandler; 5 | import android.webkit.WebView; 6 | import com.getcapacitor.Bridge; 7 | import com.getcapacitor.BridgeWebViewClient; 8 | 9 | public class EnableHttpsSelfSigned { 10 | public static void enable(Bridge bridge) { 11 | bridge.getWebView().setWebViewClient(new BridgeWebViewClient(bridge) { 12 | @Override 13 | public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) { 14 | handler.proceed(); 15 | } 16 | }); 17 | } 18 | } -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/chevron-right-icon/chevron-right-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import ChevronRightIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/ChevronRightIcon", 7 | component: ChevronRightIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/atoms/file-upload-field/file-upload-field.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import FileUploadField from "." 4 | 5 | export default { 6 | title: "Atoms/FileUploadField", 7 | component: FileUploadField, 8 | } as ComponentMeta 9 | 10 | const Template = (args) => ( 11 |
12 | 13 |
14 | ) 15 | 16 | export const FileUpload = Template.bind({}) 17 | FileUpload.args = { 18 | onFileChosen: (values) => {}, 19 | filetypes: ["image/png", "image/jpeg"], 20 | placeholder: "Drag and drop an image here, or click to select a file", 21 | } 22 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/bell-noti-icon/bell-noti-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import BellIcon from "../bell-noti-icon" 4 | 5 | export default { 6 | title: "Fundamentals/Icons/BellNotiIcon", 7 | component: BellIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | accentColor: "#F43F5E", 25 | } 26 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/sided-mouth-face/sided-mouth-face.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import SidedMouthFaceIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/SidedMouthFaceIcon", 7 | component: SidedMouthFaceIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = args => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/arrow-top-right-icon/arrow-top-right-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import ArrowTopRightIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/ArrowRightIcon", 7 | component: ArrowTopRightIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template = (args) => 19 | 20 | export const Icon = Template.bind({}) 21 | Icon.args = { 22 | size: "24", 23 | color: "currentColor", 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/info-icon/info-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta, ComponentStory } from "@storybook/react" 2 | import React from "react" 3 | import InfoIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/InfoIcon", 7 | component: InfoIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template: ComponentStory = (args) => ( 19 | 20 | ) 21 | 22 | export const Icon = Template.bind({}) 23 | Icon.args = { 24 | size: "24", 25 | color: "currentColor", 26 | } 27 | -------------------------------------------------------------------------------- /medusa-admin/src/components/organisms/price-input/price-input.stories.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react" 2 | import { ComponentMeta } from "@storybook/react" 3 | 4 | import PriceInput from "./index" 5 | import { currencies } from "../../../utils/currencies" 6 | 7 | function C(args) { 8 | const [amount, setAmount] = useState() 9 | 10 | return 11 | } 12 | 13 | export default { 14 | title: "Organisms/PriceInput", 15 | component: PriceInput, 16 | } as ComponentMeta 17 | 18 | const Template = (args) => 19 | 20 | export const Default = Template.bind({}) 21 | Default.args = { 22 | currency: currencies.BHD, 23 | } 24 | -------------------------------------------------------------------------------- /medusa-admin/src/hooks/use-set-search-params.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react" 2 | 3 | /* 4 | * Effect hook which reflects `queryObject` k/v in the url. 5 | */ 6 | function useSetSearchParams(queryObject: Record) { 7 | useEffect(() => { 8 | const url = new URL(window.location.href) 9 | 10 | for (const k of url.searchParams.keys()) { 11 | if (!(k in queryObject)) { 12 | url.searchParams.delete(k) 13 | } 14 | } 15 | 16 | for (const k in queryObject) { 17 | url.searchParams.set(k, queryObject[k].toString()) 18 | } 19 | 20 | window.history.replaceState(null, "", url.toString()) 21 | }, [queryObject]) 22 | } 23 | 24 | export default useSetSearchParams 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/alert-icon/alert-icon.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta, ComponentStory } from "@storybook/react" 2 | import React from "react" 3 | import AlertIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/AlertIcon", 7 | component: AlertIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template: ComponentStory = (args) => ( 19 | 20 | ) 21 | 22 | export const Icon = Template.bind({}) 23 | Icon.args = { 24 | size: "24", 25 | color: "currentColor", 26 | } 27 | -------------------------------------------------------------------------------- /medusa-admin/src/components/molecules/view-raw/view-raw.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta, ComponentStory } from "@storybook/react" 2 | import React from "react" 3 | import ViewRaw from "." 4 | 5 | export default { 6 | title: "Molecules/ViewRaw", 7 | component: ViewRaw, 8 | } as ComponentMeta 9 | 10 | const Template: ComponentStory = (args) => 11 | 12 | export const Default = Template.bind({}) 13 | const metadata = { 14 | test: true, 15 | valid_days: ["monday", "wednesday", "friday"], 16 | } 17 | 18 | Default.args = { 19 | raw: metadata, 20 | } 21 | 22 | export const WithName = Template.bind({}) 23 | WithName.args = { 24 | raw: metadata, 25 | name: "metadata", 26 | } 27 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/minus-icon/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import IconProps from "../types/icon-type" 3 | 4 | const MinusIcon: React.FC = ({ 5 | size = "16", 6 | color = "currentColor", 7 | ...attributes 8 | }) => { 9 | return ( 10 | 18 | 25 | 26 | ) 27 | } 28 | 29 | export default MinusIcon 30 | -------------------------------------------------------------------------------- /medusa-admin/src/components/molecules/notification-bell/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import Button, { ButtonProps } from "../../fundamentals/button" 3 | import BellIcon from "../../fundamentals/icons/bell-icon" 4 | import BellNotiIcon from "../../fundamentals/icons/bell-noti-icon" 5 | 6 | type NotificationBellProps = ButtonProps & { 7 | hasNotifications?: boolean 8 | } 9 | 10 | const NotificationBell: React.FC = ({ 11 | hasNotifications = false, 12 | ...attributes 13 | }) => { 14 | return ( 15 | 18 | ) 19 | } 20 | 21 | export default NotificationBell 22 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/chevron-down.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import IconProps from "./types/icon-type" 3 | 4 | const ChevronDownIcon: React.FC = ({ 5 | size = "24px", 6 | color = "currentColor", 7 | ...attributes 8 | }) => { 9 | return ( 10 | 18 | 25 | 26 | ) 27 | } 28 | 29 | export default ChevronDownIcon 30 | -------------------------------------------------------------------------------- /medusa-admin/src/components/private-route/index.js: -------------------------------------------------------------------------------- 1 | import { navigate } from "gatsby" 2 | import React, { useContext, useState } from "react" 3 | import { AccountContext } from "../../context/account" 4 | 5 | const PrivateRoute = ({ component: Component, location, ...rest }) => { 6 | const [loading, setLoading] = useState(false) 7 | const account = useContext(AccountContext) 8 | 9 | if (account.isLoggedIn) { 10 | return 11 | } else if (!loading) { 12 | account 13 | .session() 14 | .then((data) => { 15 | setLoading(false) 16 | }) 17 | .catch((err) => { 18 | navigate("/login") 19 | }) 20 | } 21 | return "Loading..." 22 | } 23 | 24 | export default PrivateRoute 25 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/chevron-up.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import IconProps from "./types/icon-type" 3 | 4 | const ChevronUpIcon: React.FC = ({ 5 | size = "24px", 6 | color = "currentColor", 7 | ...attributes 8 | }) => { 9 | return ( 10 | 18 | 25 | 26 | ) 27 | } 28 | 29 | export default ChevronUpIcon 30 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/check-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import IconProps from "./types/icon-type" 3 | 4 | const CheckIcon: React.FC = ({ 5 | size = "24px", 6 | color = "currentColor", 7 | ...attributes 8 | }) => { 9 | return ( 10 | 18 | 25 | 26 | ) 27 | } 28 | 29 | export default CheckIcon 30 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/chevron-left-icon/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import IconProps from "../types/icon-type" 3 | 4 | const ChevronLeftIcon: React.FC = ({ 5 | size = "24", 6 | color = "currentColor", 7 | ...attributes 8 | }) => { 9 | return ( 10 | 18 | 25 | 26 | ) 27 | } 28 | 29 | export default ChevronLeftIcon 30 | -------------------------------------------------------------------------------- /quasar-medusa-client/src/pages/ErrorNotFound.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 32 | -------------------------------------------------------------------------------- /medusa-admin/src/assets/svg/plane.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/chevron-right-icon/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import IconProps from "../types/icon-type" 3 | 4 | const ChevronRightIcon: React.FC = ({ 5 | size = "24", 6 | color = "currentColor", 7 | ...attributes 8 | }) => { 9 | return ( 10 | 18 | 25 | 26 | ) 27 | } 28 | 29 | export default ChevronRightIcon 30 | -------------------------------------------------------------------------------- /medusa-admin/src/hooks/use-on-click-outside.tsx: -------------------------------------------------------------------------------- 1 | import { RefObject, useEffect } from "react" 2 | 3 | type Handler = (event: MouseEvent) => void 4 | 5 | const useOnClickOutside = ( 6 | ref: RefObject, 7 | handler: Handler 8 | ): void => { 9 | useEffect(() => { 10 | const handleClick = (event: MouseEvent) => { 11 | const el = ref?.current 12 | 13 | if (!el || el.contains(event.target as Node)) { 14 | return 15 | } 16 | 17 | handler(event) 18 | } 19 | 20 | document.addEventListener("click", handleClick) 21 | 22 | return () => { 23 | document.removeEventListener("click", handleClick) 24 | } 25 | }, [ref]) 26 | } 27 | 28 | export default useOnClickOutside 29 | -------------------------------------------------------------------------------- /medusa-admin/src/components/atoms/settings-card/settings-card.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import SettingsCard from "." 4 | import HappyIcon from "../../fundamentals/icons/happy-icon" 5 | 6 | export default { 7 | title: "Atoms/SettingsCard", 8 | component: SettingsCard, 9 | } as ComponentMeta 10 | 11 | const Template = args => 12 | 13 | const icon = 14 | 15 | export const CustomerService = Template.bind({}) 16 | CustomerService.args = { 17 | icon: icon, 18 | heading: "Customer Service", 19 | description: "Reach out to our customer service team", 20 | to: "/customer-service", 21 | externalLink: null, 22 | disabled: false, 23 | } 24 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/pricing/details/sections/prices-details/utils.ts: -------------------------------------------------------------------------------- 1 | import { Idable } from "../../../../../types/shared" 2 | 3 | export const merge = ( 4 | l1: T[] = [], 5 | l2: U[] = [] 6 | ) => { 7 | const normalizedListA = normalize(l1, "id") 8 | const normalizedListB = normalize(l2, "id") 9 | const merged = Object.values(normalizedListA) 10 | Object.values(normalizedListB).forEach((element: any) => { 11 | if (!normalizedListA[element.id]) { 12 | merged.push(element) 13 | } 14 | }) 15 | return merged 16 | } 17 | 18 | const normalize = (arr: T[], key) => { 19 | return arr.reduce( 20 | (obj, curr) => ((obj[curr[key]] = { ...curr }), obj), 21 | {} as T 22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/products/components/sales-channels-modal/use-sales-channels-modal.tsx: -------------------------------------------------------------------------------- 1 | import { SalesChannel } from "@medusajs/medusa" 2 | import React, { useContext } from "react" 3 | 4 | type SalesChannelsModalContext = { 5 | source: SalesChannel[] 6 | onClose: () => void 7 | onSave: (channels: SalesChannel[]) => void 8 | } 9 | 10 | export const SalesChannelsModalContext = React.createContext( 11 | null 12 | ) 13 | 14 | export const useSalesChannelsModal = () => { 15 | const context = useContext(SalesChannelsModalContext) 16 | 17 | if (context === null) { 18 | throw new Error( 19 | "useSalesChannelsModal must be used within a SalesChannelsModalProvider" 20 | ) 21 | } 22 | 23 | return context 24 | } 25 | -------------------------------------------------------------------------------- /medusa-admin/src/assets/svg/heart.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /medusa-admin/src/components/molecules/note-input/note-input.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta, ComponentStory } from "@storybook/react" 2 | import React from "react" 3 | import useState from "storybook-addon-state" 4 | import NoteInput from "." 5 | 6 | export default { 7 | title: "Molecules/NoteInput", 8 | component: NoteInput, 9 | } as ComponentMeta 10 | 11 | const Template: ComponentStory = (args) => { 12 | const [note, setNote] = useState("note", undefined) 13 | return ( 14 |
15 | 16 |
{note}
17 |
18 | ) 19 | } 20 | 21 | export const Default = Template.bind({}) 22 | Default.args = {} 23 | -------------------------------------------------------------------------------- /quasar-medusa-client/src/composables/useCollections.js: -------------------------------------------------------------------------------- 1 | import { medusa } from 'boot/medusaClient' 2 | 3 | export default function useProduct () { 4 | const listCollections = async () => { 5 | try { 6 | return await medusa.collections.list() 7 | } catch (error) { 8 | throw new Error(error) 9 | } 10 | } 11 | 12 | const getColletion = async (id) => { 13 | try { 14 | const { collection } = await medusa.collections.retrieve(id) 15 | const { products } = await medusa.products.list({ collection_id: [id] }) 16 | return { 17 | collection, 18 | products 19 | } 20 | } catch (error) { 21 | throw new Error(error) 22 | } 23 | } 24 | 25 | return { 26 | listCollections, 27 | getColletion 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/clipboard-copy-icon/clipboard-copy.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta, ComponentStory } from "@storybook/react" 2 | import React from "react" 3 | import ClipboardCopyIcon from "." 4 | 5 | export default { 6 | title: "Fundamentals/Icons/ClipboardCopy", 7 | component: ClipboardCopyIcon, 8 | argTypes: { 9 | size: { 10 | control: { 11 | type: "select", 12 | options: ["24", "20", "16"], 13 | }, 14 | }, 15 | }, 16 | } as ComponentMeta 17 | 18 | const Template: ComponentStory = (args) => ( 19 | 20 | ) 21 | 22 | export const Icon = Template.bind({}) 23 | Icon.args = { 24 | size: "24", 25 | color: "currentColor", 26 | } 27 | -------------------------------------------------------------------------------- /medusa-admin/src/hooks/use-computed-height.ts: -------------------------------------------------------------------------------- 1 | import { useLayoutEffect, useRef } from "react" 2 | import { useWindowDimensions } from "./use-window-dimensions" 3 | 4 | export const useComputedHeight = (bottomPad: number) => { 5 | const ref = useRef(null) 6 | const heightRef = useRef(0) 7 | 8 | const { height } = useWindowDimensions() 9 | 10 | useLayoutEffect(() => { 11 | if (ref.current) { 12 | let { top } = ref.current.getBoundingClientRect() 13 | // take the inner height of the window, subtract 32 from it (for the bottom padding), then subtract that from the top position of our grid row (wherever that is) 14 | heightRef.current = height - bottomPad - top 15 | } 16 | }, [bottomPad, height]) 17 | 18 | return { ref, height: heightRef.current } 19 | } 20 | -------------------------------------------------------------------------------- /medusa-admin/src/assets/svg/happy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /medusa-admin/src/components/atoms/page-description/page-description.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta } from "@storybook/react" 2 | import React from "react" 3 | import PageDescription from "." 4 | 5 | export default { 6 | title: "Atoms/PageDescription", 7 | component: PageDescription, 8 | } as ComponentMeta 9 | 10 | const Template = args => 11 | 12 | export const TitleAndSubtitle = Template.bind({}) 13 | TitleAndSubtitle.args = { 14 | title: "Region", 15 | subtitle: "Manage your regions", 16 | } 17 | 18 | export const TitleOnly = Template.bind({}) 19 | TitleOnly.args = { 20 | title: "Region", 21 | } 22 | 23 | export const SubtitleOnly = Template.bind({}) 24 | SubtitleOnly.args = { 25 | subtitle: "Manage your regions", 26 | } 27 | -------------------------------------------------------------------------------- /medusa-admin/src/components/atoms/switch/switch.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta, ComponentStory } from "@storybook/react" 2 | import React, { useEffect, useState } from "react" 3 | 4 | import Switch from "./" 5 | 6 | export default { 7 | title: "Atoms/Switch", 8 | component: Switch, 9 | } as ComponentMeta 10 | 11 | const Template: ComponentStory = (args) => { 12 | const [checked, setChecked] = useState(args.checked) 13 | 14 | useEffect(() => { 15 | setChecked(args.checked) 16 | }, [args.checked]) 17 | 18 | return ( 19 | setChecked(c)} 23 | /> 24 | ) 25 | } 26 | 27 | export const Default = Template.bind({}) 28 | Default.args = { checked: true } 29 | -------------------------------------------------------------------------------- /medusa-admin/src/components/molecules/table-toaster/index.tsx: -------------------------------------------------------------------------------- 1 | import clsx from "clsx" 2 | import React from "react" 3 | import { Toast } from "react-hot-toast" 4 | 5 | export type TableToasterContainerProps = { 6 | children: React.ReactElement[] | React.ReactElement | React.ReactNode 7 | toast?: Toast 8 | } 9 | 10 | export const TableToasterContainer = ({ 11 | children, 12 | toast, 13 | }: TableToasterContainerProps) => { 14 | return ( 15 |
22 |
23 | {children} 24 |
25 |
26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /medusa-admin/src/hooks/use-observe-width.ts: -------------------------------------------------------------------------------- 1 | import { MutableRefObject, useEffect, useRef, useState } from "react" 2 | 3 | export const useObserveWidth = (ref: MutableRefObject): number => { 4 | const [currentWidth, setCurrentWidth] = useState(0) 5 | 6 | const observer = useRef( 7 | new ResizeObserver((entries) => { 8 | const { width } = entries[0].contentRect 9 | 10 | setCurrentWidth(width) 11 | }) 12 | ) 13 | 14 | useEffect(() => { 15 | if (observer?.current && ref?.current) { 16 | observer.current.observe(ref.current) 17 | } 18 | 19 | return () => { 20 | if (observer?.current && ref?.current) { 21 | observer.current.unobserve(ref?.current) 22 | } 23 | } 24 | }, [ref, observer]) 25 | 26 | return currentWidth 27 | } 28 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-capacitor/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.6.1' 11 | classpath 'com.google.gms:google-services:4.3.3' 12 | 13 | // NOTE: Do not place your application dependencies here; they belong 14 | // in the individual module build.gradle files 15 | } 16 | } 17 | 18 | apply from: "variables.gradle" 19 | 20 | allprojects { 21 | repositories { 22 | google() 23 | jcenter() 24 | } 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /quasar-medusa-client/src-pwa/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "orientation": "portrait", 3 | "background_color": "#ffffff", 4 | "theme_color": "#027be3", 5 | "icons": [ 6 | { 7 | "src": "icons/icon-128x128.png", 8 | "sizes": "128x128", 9 | "type": "image/png" 10 | }, 11 | { 12 | "src": "icons/icon-192x192.png", 13 | "sizes": "192x192", 14 | "type": "image/png" 15 | }, 16 | { 17 | "src": "icons/icon-256x256.png", 18 | "sizes": "256x256", 19 | "type": "image/png" 20 | }, 21 | { 22 | "src": "icons/icon-384x384.png", 23 | "sizes": "384x384", 24 | "type": "image/png" 25 | }, 26 | { 27 | "src": "icons/icon-512x512.png", 28 | "sizes": "512x512", 29 | "type": "image/png" 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /medusa-admin/src/components/molecules/timeline-events/event-actionables.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import MoreHorizontalIcon from "../../fundamentals/icons/more-horizontal-icon" 3 | import Actionables, { ActionType } from "../actionables" 4 | 5 | type EventActionablesProps = { 6 | actions: ActionType[] 7 | } 8 | 9 | const EventActionables: React.FC = ({ actions }) => { 10 | const EventTrigger = ( 11 | 14 | ) 15 | return ( 16 | 17 | ) 18 | } 19 | 20 | export default EventActionables 21 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/products/edit/sections/raw/index.tsx: -------------------------------------------------------------------------------- 1 | import { Product } from "@medusajs/medusa" 2 | import React from "react" 3 | import ReactJson from "react-json-view" 4 | import Section from "../../../../../components/organisms/section" 5 | 6 | type Props = { 7 | product: Product 8 | } 9 | 10 | /** Temporary component, should be replaced with but since the design is different we will use this to not break the existing design across admin. */ 11 | const RawSection = ({ product }: Props) => { 12 | return ( 13 |
14 |
15 | 16 |
17 |
18 | ) 19 | } 20 | 21 | export default RawSection 22 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/customers/header.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { navigate } from "gatsby" 3 | 4 | import TableViewHeader from "../../components/organisms/custom-table-header" 5 | 6 | type P = { 7 | activeView: "customers" | "groups" 8 | } 9 | 10 | /* 11 | * Shared header component for "customers" and "customer groups" page 12 | */ 13 | function CustomersPageTableHeader(props: P) { 14 | return ( 15 | { 17 | if (v === "customers") { 18 | navigate(`/a/customers`) 19 | } else { 20 | navigate(`/a/customers/groups`) 21 | } 22 | }} 23 | views={["customers", "groups"]} 24 | activeView={props.activeView} 25 | /> 26 | ) 27 | } 28 | 29 | export default CustomersPageTableHeader 30 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/orders/details/templates/fulfillment-status.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | import StatusDot from "../../../../components/fundamentals/status-indicator" 4 | 5 | export const FulfillmentStatusComponent = ({ status }) => { 6 | switch (status) { 7 | case "shipped": 8 | return 9 | case "fulfilled": 10 | return 11 | case "canceled": 12 | return 13 | case "partially_fulfilled": 14 | return 15 | case "requires_action": 16 | return 17 | default: 18 | return null 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /quasar-medusa-client/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "src/*": [ 6 | "src/*" 7 | ], 8 | "app/*": [ 9 | "*" 10 | ], 11 | "components/*": [ 12 | "src/components/*" 13 | ], 14 | "layouts/*": [ 15 | "src/layouts/*" 16 | ], 17 | "pages/*": [ 18 | "src/pages/*" 19 | ], 20 | "assets/*": [ 21 | "src/assets/*" 22 | ], 23 | "boot/*": [ 24 | "src/boot/*" 25 | ], 26 | "stores/*": [ 27 | "src/stores/*" 28 | ], 29 | "vue$": [ 30 | "node_modules/vue/dist/vue.runtime.esm-bundler.js" 31 | ] 32 | } 33 | }, 34 | "exclude": [ 35 | "dist", 36 | ".quasar", 37 | "node_modules" 38 | ] 39 | } -------------------------------------------------------------------------------- /medusa-admin/src/components/molecules/generating-input/generating-input.stories.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentMeta, ComponentStory } from "@storybook/react" 2 | import React from "react" 3 | import GeneratingInput from "." 4 | 5 | export default { 6 | title: "Molecules/GeneratingInput", 7 | component: GeneratingInput, 8 | } as ComponentMeta 9 | 10 | const Template: ComponentStory = (args) => ( 11 | 12 | ) 13 | 14 | export const Default = Template.bind({}) 15 | Default.args = { 16 | label: "Code", 17 | required: true, 18 | placeholder: "MEDUSA15", 19 | } 20 | 21 | export const HasValue = Template.bind({}) 22 | HasValue.args = { 23 | label: "Code", 24 | required: true, 25 | placeholder: "MEDUSA15", 26 | value: "SUMMER2014", 27 | } 28 | -------------------------------------------------------------------------------- /medusa-admin/src/domain/settings/currencies/components/default-store-currency/index.tsx: -------------------------------------------------------------------------------- 1 | import { Store } from "@medusajs/medusa" 2 | import React from "react" 3 | import DefaultCurrencySelector from "./default-currency-selector" 4 | 5 | type Props = { 6 | store: Store 7 | } 8 | 9 | const DefaultStoreCurrency = ({ store }: Props) => { 10 | return ( 11 |
12 |
13 |

14 | Default store currency 15 |

16 |

17 | This is the currency your prices are shown in. 18 |

19 |
20 | 21 | 22 |
23 | ) 24 | } 25 | 26 | export default DefaultStoreCurrency 27 | -------------------------------------------------------------------------------- /quasar-medusa-client/src/composables/useCustomer.js: -------------------------------------------------------------------------------- 1 | import { medusa } from 'boot/medusaClient' 2 | 3 | export default () => { 4 | const createCustomer = async (newCustomerData) => { 5 | try { 6 | return await medusa.customers.create(newCustomerData) 7 | } catch (e) { 8 | throw new Error(e) 9 | } 10 | } 11 | 12 | const updateCustomer = async (customerData) => { 13 | try { 14 | return await medusa.customers.update(customerData) 15 | } catch (e) { 16 | throw new Error(e) 17 | } 18 | } 19 | 20 | const getCustomer = async () => { 21 | try { 22 | return await medusa.customers.retrieve() 23 | } catch (e) { 24 | throw new Error(e) 25 | } 26 | } 27 | 28 | return { 29 | createCustomer, 30 | updateCustomer, 31 | getCustomer 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /medusa-admin/src/components/atoms/toaster-container/index.tsx: -------------------------------------------------------------------------------- 1 | import clsx from "clsx" 2 | import React from "react" 3 | 4 | type ToasterContainerProps = { 5 | visible: boolean 6 | } & React.HTMLAttributes 7 | 8 | const ToasterContainer: React.FC = ({ 9 | children, 10 | visible, 11 | className, 12 | ...rest 13 | }) => { 14 | return ( 15 |
28 | {children} 29 |
30 | ) 31 | } 32 | 33 | export default ToasterContainer 34 | -------------------------------------------------------------------------------- /medusa-admin/src/components/molecules/hot-key-action/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { useHotkeys } from "react-hotkeys-hook" 3 | 4 | type HotKeyActionProps = { 5 | label: string 6 | hotKey: string 7 | icon: React.ReactNode 8 | onAction: (keyboardEvent: KeyboardEvent, hotkeysEvent: any) => void | boolean 9 | } 10 | 11 | const HotKeyAction = ({ label, hotKey, icon, onAction }: HotKeyActionProps) => { 12 | useHotkeys(hotKey, onAction, {}) 13 | return ( 14 |
15 | {label} 16 |
17 | {icon} 18 |
19 |
20 | ) 21 | } 22 | 23 | export default HotKeyAction 24 | -------------------------------------------------------------------------------- /quasar-medusa-client/src/boot/medusaClient.js: -------------------------------------------------------------------------------- 1 | import { boot } from 'quasar/wrappers' 2 | import Medusa from '@medusajs/medusa-js' 3 | 4 | const medusa = new Medusa({ 5 | baseUrl: process.env.MEDUSA_BASE_URL, 6 | apiKey: '', 7 | maxRetries: 3 8 | }) 9 | 10 | export default boot(({ app }) => { 11 | // for use inside Vue files (Options API) through this.$axios and this.$api 12 | 13 | // app.config.globalProperties.$medusa = medusa 14 | // ^ ^ ^ this will allow you to use this.$axios (for Vue Options API form) 15 | // so you won't necessarily have to import axios in each vue file 16 | 17 | // app.config.globalProperties.$api = api 18 | // ^ ^ ^ this will allow you to use this.$api (for Vue Options API form) 19 | // so you can easily perform requests against your app's API 20 | }) 21 | 22 | export { medusa } 23 | -------------------------------------------------------------------------------- /medusa-admin/src/components/fundamentals/icons/arrow-top-right-icon/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import IconProps from "../types/icon-type" 3 | 4 | const ArrowTopRightIcon: React.FC = ({ 5 | size = "20", 6 | color = "currentColor", 7 | ...attributes 8 | }) => { 9 | return ( 10 | 18 | 25 | 26 | ) 27 | } 28 | 29 | export default ArrowTopRightIcon 30 | -------------------------------------------------------------------------------- /medusa-admin/src/components/templates/collection-product-table/utils.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import StatusIndicator from "../../fundamentals/status-indicator" 3 | 4 | export type SimpleProductType = { 5 | id: string 6 | thumbnail?: string 7 | title: string 8 | status: string 9 | created_at: Date 10 | } 11 | 12 | export const decideStatus = (status: string) => { 13 | switch (status) { 14 | case "published": 15 | return 16 | case "draft": 17 | return 18 | case "proposed": 19 | return 20 | case "rejected": 21 | return 22 | default: 23 | return null 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /medusa-admin/src/components/molecules/select/next-select/components/placeholder.tsx: -------------------------------------------------------------------------------- 1 | import clsx from "clsx" 2 | import React from "react" 3 | import { GroupBase, PlaceholderProps } from "react-select" 4 | 5 | const Placeholder = < 6 | Option, 7 | IsMulti extends boolean, 8 | Group extends GroupBase