Sfoglia il codice sorgente

fix onboarding for deployed backend + without seed

Shahed nasser 1 anno fa
parent
commit
01db57ec99

+ 13 - 9
src/admin/components/onboarding-flow/default/orders/orders-list.tsx

@@ -1,11 +1,13 @@
 import React from "react";
-import { useAdminProduct } from "medusa-react";
-import { useAdminCreateDraftOrder } from "medusa-react";
-import { useAdminShippingOptions } from "medusa-react";
-import { useAdminRegions } from "medusa-react";
-import { useMedusa } from "medusa-react";
+import { 
+  useAdminProduct,
+  useAdminCreateDraftOrder,
+  useMedusa
+} from "medusa-react";
 import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow";
 import { Button, Text } from "@medusajs/ui";
+import prepareRegions from "../../../../utils/prepare-region";
+import prepareShippingOptions from "../../../../utils/prepare-shipping-options";
 
 const OrdersListDefault = ({ onNext, isComplete, data }: StepContentProps) => {
   const { product } = useAdminProduct(data.product_id);
@@ -13,19 +15,21 @@ const OrdersListDefault = ({ onNext, isComplete, data }: StepContentProps) => {
     useAdminCreateDraftOrder();
   const { client } = useMedusa();
 
-  const { regions } = useAdminRegions();
-  const { shipping_options } = useAdminShippingOptions();
-
   const createOrder = async () => {
     const variant = product.variants[0] ?? null;
     try {
+      // check if there is a shipping option and a region
+      // and if not, create demo ones
+      const regions = await prepareRegions(client)
+      const shipping_options = await prepareShippingOptions(client, regions[0])
+
       const { draft_order } = await createDraftOrder({
         email: "customer@medusajs.com",
         items: [
           variant
             ? {
                 quantity: 1,
-                variant_id: variant.id,
+                variant_id: variant?.id,
               }
             : {
                 quantity: 1,

+ 28 - 9
src/admin/components/onboarding-flow/default/products/product-detail.tsx

@@ -1,14 +1,33 @@
-import React from "react";
-import { useAdminPublishableApiKeys } from "medusa-react";
-import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow";
-import { Button, CodeBlock, Text } from "@medusajs/ui";
+import React, { useEffect, useMemo } from "react"
+import { 
+  useAdminPublishableApiKeys,
+  useAdminCreatePublishableApiKey
+} from "medusa-react"
+import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow"
+import { Button, CodeBlock, Text } from "@medusajs/ui"
 
 const ProductDetailDefault = ({ onNext, isComplete, data }: StepContentProps) => {
-  const { publishable_api_keys: keys, isLoading } = useAdminPublishableApiKeys({
+  const { publishable_api_keys: keys, isLoading, refetch } = useAdminPublishableApiKeys({
     offset: 0,
     limit: 1,
   });
-  const api_key = keys?.[0]?.id || "pk_01H0PY648BTMEJR34ZDATXZTD9";
+  const createPublishableApiKey = useAdminCreatePublishableApiKey()
+  
+  const api_key = useMemo(() => keys?.[0]?.id || "", [keys])
+  const backendUrl = process.env.MEDUSA_BACKEND_URL || process.env.MEDUSA_ADMIN_BACKEND_URL || "http://location:9000"
+
+  useEffect(() => {
+    if (!isLoading && !keys?.length) {
+      createPublishableApiKey.mutate({
+        "title": "Development"
+      }, {
+        onSuccess: () => {
+          refetch()
+        }
+      })
+    }
+  }, [isLoading, keys])
+  
   return (
     <div>
       <div className="flex flex-col gap-2">
@@ -24,12 +43,12 @@ const ProductDetailDefault = ({ onNext, isComplete, data }: StepContentProps) =>
             {
               label: "cURL",
               language: "bash",
-              code: `curl "http://localhost:9000/store/products/${data?.product_id}" -H "x-publishable-key: ${api_key}"`,
+              code: `curl "${backendUrl}/store/products/${data?.product_id}"${api_key ? ` -H "x-publishable-key: ${api_key}"` : ``}`,
             },
             {
               label: "Medusa JS Client",
               language: "js",
-              code: `// Install the JS Client in your storefront project: @medusajs/medusa-js\n\nimport Medusa from "@medusajs/medusa-js"\n\nconst medusa = new Medusa({ publishableApiKey: "${api_key}"})\nconst product = await medusa.products.retrieve("${data?.product_id}")\nconsole.log(product.id)`,
+              code: `// Install the JS Client in your storefront project: @medusajs/medusa-js\n\nimport Medusa from "@medusajs/medusa-js"\n\nconst medusa = new Medusa(${api_key ? `{ publishableApiKey: "${api_key}"}` : ``})\nconst product = await medusa.products.retrieve("${data?.product_id}")\nconsole.log(product.id)`,
             },
             {
               label: "Medusa React",
@@ -49,7 +68,7 @@ const ProductDetailDefault = ({ onNext, isComplete, data }: StepContentProps) =>
       </div>
       <div className="flex gap-2">
         <a
-          href={`http://localhost:9000/store/products/${data?.product_id}`}
+          href={`${backendUrl}/store/products/${data?.product_id}`}
           target="_blank"
         >
           <Button variant="secondary" size="base">

+ 15 - 5
src/admin/components/onboarding-flow/default/products/products-list.tsx

@@ -1,18 +1,25 @@
-import React from "react";
-import { useAdminCreateProduct, useAdminCreateCollection } from "medusa-react";
-import { useAdminRegions } from "medusa-react";
+import React, { useMemo } from "react";
+import { 
+  useAdminCreateProduct,
+  useAdminCreateCollection,
+  useMedusa
+} from "medusa-react";
 import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow";
 import { Button, Text } from "@medusajs/ui";
 import getSampleProducts from "../../../../utils/sample-products";
+import prepareRegions from "../../../../utils/prepare-region";
 
 const ProductsListDefault = ({ onNext, isComplete }: StepContentProps) => {
   const { mutateAsync: createCollection, isLoading: collectionLoading } =
     useAdminCreateCollection();
   const { mutateAsync: createProduct, isLoading: productLoading } =
     useAdminCreateProduct();
-  const { regions } = useAdminRegions();
+  const { client } = useMedusa()
 
-  const isLoading = collectionLoading || productLoading;
+  const isLoading = useMemo(() => 
+    collectionLoading || productLoading,
+    [collectionLoading, productLoading]
+  );
 
   const createSample = async () => {
     try {
@@ -20,6 +27,9 @@ const ProductsListDefault = ({ onNext, isComplete }: StepContentProps) => {
         title: "Merch",
         handle: "merch",
       });
+
+      const regions = await prepareRegions(client)
+
       const sampleProducts = getSampleProducts({
         regions,
         collection_id: collection.id

+ 1 - 1
src/admin/components/onboarding-flow/nextjs/orders/order-detail.tsx

@@ -1,5 +1,5 @@
 import React from "react";
-import { CurrencyDollarSolid, NextJs, SquaresPlusSolid, ToolsSolid } from "@medusajs/icons";
+import { CurrencyDollarSolid, NextJs, SquaresPlusSolid } from "@medusajs/icons";
 import { Badge, Heading, Text } from "@medusajs/ui";
 
 const OrderDetailNextjs = () => {

+ 13 - 8
src/admin/components/onboarding-flow/nextjs/orders/orders-list.tsx

@@ -1,30 +1,35 @@
 import React from "react";
-import { useAdminProduct } from "medusa-react";
-import { useCreateCart } from "medusa-react";
-import { useAdminRegions } from "medusa-react";
+import { 
+  useAdminProduct,
+  useCreateCart,
+  useMedusa
+} from "medusa-react";
 import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow";
 import { Button, Text } from "@medusajs/ui";
+import prepareRegions from "../../../../utils/prepare-region";
+import prepareShippingOptions from "../../../../utils/prepare-shipping-options";
 
 const OrdersListNextjs = ({ isComplete, data }: StepContentProps) => {
   const { product } = useAdminProduct(data.product_id);
   const { mutateAsync: createCart, isLoading: cartIsLoading } = useCreateCart()
-
-  const { regions } = useAdminRegions();
+  const { client } = useMedusa()
 
   const prepareNextjsCheckout = async () => {
     const variant = product.variants[0] ?? null;
     try {
+      const regions = await prepareRegions(client)
+      await prepareShippingOptions(client, regions[0])
       const { cart } = await createCart({
-        region_id: regions[0].id,
+        region_id: regions[0]?.id,
         items: [
           {
-            variant_id: variant.id,
+            variant_id: variant?.id,
             quantity: 1
           }
         ]
       })
 
-      window.open(`http://localhost:8000/checkout?cart_id=${cart.id}&onboarding=true`, "_blank")
+      window.open(`http://localhost:8000/checkout?cart_id=${cart?.id}&onboarding=true`, "_blank")
     } catch (e) {
       console.error(e);
     }

+ 9 - 3
src/admin/components/onboarding-flow/nextjs/products/products-list.tsx

@@ -1,17 +1,21 @@
 import React from "react";
-import { useAdminCreateProduct, useAdminCreateCollection } from "medusa-react";
-import { useAdminRegions } from "medusa-react";
+import { 
+  useAdminCreateProduct,
+  useAdminCreateCollection,
+  useMedusa
+} from "medusa-react";
 import { StepContentProps } from "../../../../widgets/onboarding-flow/onboarding-flow";
 import { Button, Text } from "@medusajs/ui";
 import { AdminPostProductsReq, Product } from "@medusajs/medusa";
 import getSampleProducts from "../../../../utils/sample-products";
+import prepareRegions from "../../../../utils/prepare-region";
 
 const ProductsListNextjs = ({ onNext, isComplete }: StepContentProps) => {
   const { mutateAsync: createCollection, isLoading: collectionLoading } =
     useAdminCreateCollection();
   const { mutateAsync: createProduct, isLoading: productLoading } =
     useAdminCreateProduct();
-  const { regions } = useAdminRegions();
+  const { client } = useMedusa()
 
   const isLoading = collectionLoading || productLoading;
 
@@ -22,6 +26,8 @@ const ProductsListNextjs = ({ onNext, isComplete }: StepContentProps) => {
         handle: "merch",
       });
 
+      const regions = await prepareRegions(client)
+
       const tryCreateProduct = async (sampleProduct: AdminPostProductsReq): Promise<Product | null> => {
         try {
           return (await createProduct(sampleProduct)).product

+ 42 - 0
src/admin/utils/prepare-region.ts

@@ -0,0 +1,42 @@
+import { Store } from "@medusajs/medusa"
+import type Medusa from "@medusajs/medusa-js"
+import { ExtendedStoreDTO } from "@medusajs/medusa/dist/types/store"
+
+export default async function prepareRegions (client: Medusa) {
+  let { regions } = await client.admin.regions.list()
+  if (!regions.length) {
+    let { store } = await client.admin.store.retrieve()
+    if (!store.currencies) {
+      store = (await client.admin.store.update({
+        currencies: ["eur"]
+      })).store as ExtendedStoreDTO
+    }
+
+    regions = [(await client.admin.regions.create(getSampleRegion(store))).region]
+  }
+
+  return regions
+}
+
+function getSampleRegion (store: Store) {
+  return {
+    name: "EU",
+    currency_code: store.currencies[0].code,
+    tax_rate: 0,
+    payment_providers: [
+      "manual"
+    ],
+    fulfillment_providers: [
+      "manual"
+    ],
+    countries: [
+      "gb",
+      "de",
+      "dk",
+      "se",
+      "fr",
+      "es",
+      "it"
+    ]
+  }
+}

+ 20 - 0
src/admin/utils/prepare-shipping-options.ts

@@ -0,0 +1,20 @@
+import { Region } from "@medusajs/medusa";
+import type Medusa from "@medusajs/medusa-js"
+
+export default async function prepareShippingOptions (client: Medusa, region: Region) {
+  let { shipping_options } = await client.admin.shippingOptions.list()
+  if (!shipping_options.length) {
+    shipping_options = [(await client.admin.shippingOptions.create({
+      "name": "PostFake Standard",
+      "region_id": region.id,
+      "provider_id": "manual",
+      "data": {
+        "id": "manual-fulfillment"
+      },
+      "price_type": "flat_rate",
+      "amount": 1000
+    })).shipping_option]
+  }
+
+  return shipping_options
+}