Uplode Image to shopify with remix app template

Uplode Image to shopify with remix app template

mudasir07
Shopify Partner
3 0 1

Hii can you please see my code and say what I am doing wrong hear the product is creating but the image is not uploading and shows Image: Media failed to process because the image could not be processed

 

import React, { useCallback, useEffect, useState } from "react";
import { json } from "@remix-run/node";
import { useActionData, useNavigation, useSubmit } from "@remix-run/react";
import {
  Page,
  Layout,
  Card,
  Button,
  BlockStack,
  Box,
  InlineStack,
  DropZone,
  LegacyStack,
  Thumbnail,
  Text,
} from "@shopify/polaris";
import { authenticate } from "../shopify.server";

export const loader = async ({ request }) => {
  await authenticate.admin(request);

  return null;
};

export const action = async ({ request }) => {
  const { admin } = await authenticate.admin(request);
  const color = ["Red", "Orange", "Yellow", "Green"][
    Math.floor(Math.random() * 4)
  ];
  const requestBody = await request.text();
  console.log(
    "start:----------------------------------------------------------------------------------",
  );

  const formData = new URLSearchParams(requestBody);
  const name = formData.get("filename");
  const type = formData.get("filetype");
  const size = formData.get("filesize");
  const files = [
    {
      name: name,
      type: type,
      size: size,
    },
  ];
  console.log("File Details:", files);
  const prepareFiles = (files) =>
    files.map((file) => ({
      filename: file.name,
      mimeType: file.type,
      resource: file.type.includes("image") ? "IMAGE" : "FILE",
      fileSize: file.size.toString(),
      httpMethod: "POST",
    }));

  const preparedFiles = prepareFiles(files);
  console.log("Prepared Files for Upload:", preparedFiles);

  const uploadFileResponse = await admin.graphql(
    `#graphql
    mutation stagedUploadsCreate($input: [StagedUploadInput!]!) {
      stagedUploadsCreate(input: $input) {
        stagedTargets {
          resourceUrl
          url
          parameters {
            name
            value
          }
        }
        userErrors {
          field
          message
        }
      }
    }
  `,
    { variables: { input: preparedFiles } },
  );

  console.log(
    "Upload File Response:",
    JSON.stringify(uploadFileResponse, null, 2),
  );
  const uplodeFileJson = await uploadFileResponse.json();
  if (uplodeFileJson.data.stagedUploadsCreate?.userErrors?.length) {
    console.log(
      "Upload Errors:",
      uplodeFileJson.data.stagedUploadsCreate.userErrors,
    );
  }
  const resourceurl =
    uplodeFileJson.data.stagedUploadsCreate?.stagedTargets[0]?.resourceUrl;

  const productResponse = await admin.graphql(
    `#graphql
      mutation populateProduct($input: ProductInput!) {
        productCreate(input: $input) {
          product {
            id
            title
            handle
            status
          }
        }
      }`,
    {
      variables: {
        input: {
          title: `${color} Snowboard`,
        },
      },
    },
  );
  console.log(
    "Product Creation Response:",
    JSON.stringify(productResponse, null, 2),
  );
  const productResponseJson = await productResponse.json();

  const productId = productResponseJson.data?.productCreate?.product?.id;

  // Add image to the product
  const imageResponse = await admin.graphql(
    `mutation productCreateMedia($media: [CreateMediaInput!]!, $productId: ID!) {
      productCreateMedia(media: $media, productId: $productId) {
        media {
          alt
          mediaContentType
          status
        }
        mediaUserErrors {
          field
          message
        }
        product {
          id
          title
        }
      }
    }`,
    {
      variables: {
        media: {
          alt: "Image",
          mediaContentType: "IMAGE",
          originalSource: resourceurl,
        },
        productId: productId,
      },
    },
  );
  console.log("Image Response:", JSON.stringify(imageResponse, null, 2));
  const imageResponseJson = await imageResponse.json();
  console.log(
    "end:----------------------------------------------------------------------------------",
  );

  return json({
    product: {
      id: productId,
      imageResponseJson: imageResponseJson,
    },
  });
};

const Index = () => {
  const nav = useNavigation();
  const actionData = useActionData();
  const submit = useSubmit();
  const isLoading =
    ["loading", "submitting"].includes(nav.state) && nav.formMethod === "POST";
  const productId = actionData?.product?.id.replace(
    "gid://shopify/Product/",
    "",
  );

  useEffect(() => {
    if (productId) {
      shopify.toast.show("Product created");
    }
  }, [productId]);
  const [files, setFiles] = useState([]);

  const handleDropZoneDrop = useCallback(
    async (_dropFiles, acceptedFiles, _rejectedFiles) => {
      if (acceptedFiles.length) {
        setFiles(acceptedFiles);
      }
    },
    [],
  );
  const validImageTypes = ["image/gif", "image/jpeg", "image/png"];

  const fileUpload = !files.length && <DropZone.FileUpload />;
  const uploadedFiles = files.length > 0 && (
    <div style={{ padding: "0" }}>
      <LegacyStack vertical>
        {files.map((file, index) => (
          <LegacyStack alignment="center" key={index}>
            <Thumbnail
              size="small"
              alt={file.name}
              source={
                validImageTypes.includes(file.type)
                  ? window.URL.createObjectURL(file)
                  : ""
              }
            />
            <div>
              {file.name}{" "}
              <Text variant="bodySm" as="p">
                {file.size} bytes
              </Text>
            </div>
          </LegacyStack>
        ))}
      </LegacyStack>
    </div>
  );
  console.log(files);
  const generateProduct = () => {
    const filename = files[0]?.name;
    const filetype = files[0]?.type;
    const filesize = files[0]?.size;
    submit({ filename, filetype, filesize }, { replace: true, method: "POST" });
  };

  return (
    <Page>
      <BlockStack gap="500">
        <Layout>
          <Layout.Section>
            <Card>
              <InlineStack gap="300">
                <DropZone onDrop={handleDropZoneDrop}>
                  {uploadedFiles}
                  {fileUpload}
                </DropZone>
                <Button loading={isLoading} onClick={generateProduct}>
                  Generate a product
                </Button>
                {actionData?.product && (
                  <Button
                    url={`shopify:admin/products/${productId}`}
                    target="_blank"
                    variant="plain"
                  >
                    View product
                  </Button>
                )}
              </InlineStack>
              {actionData?.imageUserErrors && (
                <Box>
                  <p>Errors occurred while adding image:</p>
                  <ul>
                    {actionData.imageUserErrors.map((error, index) => (
                      <li key={index}>
                        <strong>{error.field}: </strong>
                        {error.message}
                      </li>
                    ))}
                  </ul>
                </Box>
              )}
            </Card>
          </Layout.Section>
        </Layout>
      </BlockStack>
    </Page>
  );
};

export default Index;

 

Replies 0 (0)