import { useEffect, useMemo, useState } from "react";
import { useFetcher, useLoaderData } from "react-router";
import { useAppBridge } from "@shopify/app-bridge-react";
import { boundary } from "@shopify/shopify-app-react-router/server";
import { authenticate } from "../shopify.server";
import styles from "../styles/app-dashboard.module.css";
function getBackendApiUrl() {
return String(process.env.BACKEND_API_URL || "http://localhost:3002").replace(/\/+$/, "");
}
async function readJsonSafe(response) {
const text = await response.text();
try {
return text ? JSON.parse(text) : null;
} catch {
return { raw: text };
}
}
export const loader = async ({ request }) => {
const { session } = await authenticate.admin(request);
const backendApiUrl = getBackendApiUrl();
const shop = session.shop;
let connection = null;
let currentJob = null;
try {
const response = await fetch(
`${backendApiUrl}/shops/${encodeURIComponent(shop)}`,
);
connection = await readJsonSafe(response);
} catch (error) {
connection = {
status: 0,
message: `Backend unavailable: ${error.message}`,
};
}
try {
const statusResponse = await fetch(
`${backendApiUrl}/pipeline/status/${encodeURIComponent(shop)}`,
);
if (statusResponse.ok) {
currentJob = await readJsonSafe(statusResponse);
}
} catch {
currentJob = null;
}
return {
shop,
backendApiUrl,
connection,
currentJob,
};
};
export const action = async ({ request }) => {
const { session } = await authenticate.admin(request);
const formData = await request.formData();
const backendApiUrl = getBackendApiUrl();
const shop = session.shop;
const limitValue = String(formData.get("limit") || "").trim();
const limit = limitValue ? Number(limitValue) : null;
try {
const response = await fetch(`${backendApiUrl}/pipeline/run`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
shop,
limit: Number.isFinite(limit) && limit > 0 ? limit : null,
}),
});
const payload = await readJsonSafe(response);
if (!response.ok) {
return {
ok: false,
error: payload?.error || "Failed to start import job.",
};
}
return {
ok: true,
jobId: payload.jobId,
shop,
limit: payload.limit,
backendApiUrl,
};
} catch (error) {
return {
ok: false,
error: error.message,
};
}
};
function FieldState({ fields }) {
if (!fields) {
return
Start an import to see the live progress and current step here.
Current import
{job.detail || "-"}
{job.error}
{JSON.stringify(job.summary, null, 2)}
Import Center
Start an import, follow the progress, and keep track of what is happening without leaving Shopify.
{connectionMessage}
Connect your store first, then start the import.
Your store is ready. You can start importing products now.