// app/routes/store-credentials.jsx import { json, redirect } from "@remix-run/node"; import { useLoaderData, useActionData, Form } from "@remix-run/react"; import { useEffect, useState } from "react"; import { Page, Layout, Card, TextField, Button, TextContainer, InlineError, Text, BlockStack, InlineStack, Box, } from "@shopify/polaris"; import { TitleBar } from "@shopify/app-bridge-react"; import { authenticate } from "../shopify.server"; const SCOPES = [ "read_inventory", "read_products", "write_inventory", "write_products", "read_publications", "write_publications", ].join(","); const REDIRECT_URI = "https://backend.data4autos.com/auth/callback"; const CLIENT_ID = "b7534c980967bad619cfdb9d3f837cfa"; export const loader = async ({ request }) => { const { admin } = await authenticate.admin(request); const resp = await admin.graphql(` { shop { id name metafield(namespace: "turn14", key: "credentials") { value } } } `); const { data } = await resp.json(); let creds = {}; if (data.shop.metafield?.value) { try { creds = JSON.parse(data.shop.metafield.value); } catch { } } //creds = {}; return json({ shopName: data.shop.name, shopId: data.shop.id, savedCreds: creds, }); }; // export const action = async ({ request }) => { // const formData = await request.formData(); // const { admin } = await authenticate.admin(request); // // ——— Handle Shopify-install trigger ——— // if (formData.get("install_shopify") === "1") { // const shopName = formData.get("shop_name"); // const stateNonce = Math.random().toString(36).slice(2); // const installUrl = // `https://${shopName}.myshopify.com/admin/oauth/authorize` + // `?client_id=${CLIENT_ID}` + // `&scope=${SCOPES}` + // `&redirect_uri=${encodeURIComponent(REDIRECT_URI)}` + // `&state=${stateNonce}` + // `&grant_options%5B%5D=per-user`; // // return the URL instead of redirecting // return json({ confirmationUrl: installUrl }); // } // // ——— Otherwise handle Turn14 token exchange ——— // const clientId = formData.get("client_id"); // const clientSecret = formData.get("client_secret"); // const shopInfo = await admin.graphql(`{ shop { id } }`); // const shopId = (await shopInfo.json()).data.shop.id; // let tokenData; // try { // const tokenRes = await fetch("https://turn14.data4autos.com/v1/auth/token", { // method: "POST", // headers: { "Content-Type": "application/json" }, // body: JSON.stringify({ // grant_type: "client_credentials", // client_id: clientId, // client_secret: clientSecret, // }), // }); // tokenData = await tokenRes.json(); // if (!tokenRes.ok) { // throw new Error(tokenData.error || "Failed to fetch Turn14 token"); // } // } catch (err) { // return json({ success: false, error: err.message }); // } // // upsert as Shopify metafield // const creds = { // clientId, // clientSecret, // accessToken: tokenData.access_token, // expiresAt: new Date(Date.now() + 3600 * 1000).toISOString(), // }; // const mutation = ` // mutation { // metafieldsSet(metafields: [{ // ownerId: "${shopId}", // namespace: "turn14", // key: "credentials", // type: "json", // value: "${JSON.stringify(creds).replace(/"/g, '\\"')}" // }]) { // userErrors { message } // } // } // `; // const saveRes = await admin.graphql(mutation); // const saveJson = await saveRes.json(); // const errs = saveJson.data.metafieldsSet.userErrors; // if (errs.length) { // return json({ success: false, error: errs[0].message }); // } // return json({ success: true, creds }); // }; export const action = async ({ request }) => { const formData = await request.formData(); const { admin } = await authenticate.admin(request); // ——— Turn14 token exchange ——— const clientId = formData.get("client_id"); const clientSecret = formData.get("client_secret"); const shopResp = await admin.graphql(`{ shop { id name } }`); const shopJson = await shopResp.json(); const shopId = shopJson.data.shop.id; const shopName = shopJson.data.shop.name; let tokenData; try { const tokenRes = await fetch("https://turn14.data4autos.com/v1/auth/token", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ grant_type: "client_credentials", client_id: clientId, client_secret: clientSecret, }), }); tokenData = await tokenRes.json(); if (!tokenRes.ok) { throw new Error(tokenData.error || "Failed to fetch Turn14 token"); } } catch (err) { return json({ success: false, error: err.message }); } // ——— Upsert to Shopify metafield ——— const creds = { clientId, clientSecret, accessToken: tokenData.access_token, expiresAt: new Date(Date.now() + 3600 * 1000).toISOString(), }; const mutation = ` mutation { metafieldsSet(metafields: [{ ownerId: "${shopId}", namespace: "turn14", key: "credentials", type: "json", value: "${JSON.stringify(creds).replace(/"/g, '\\"')}" }]) { userErrors { message } } } `; const saveRes = await admin.graphql(mutation); const saveJson = await saveRes.json(); const errs = saveJson.data.metafieldsSet.userErrors; if (errs.length) { return json({ success: false, error: errs[0].message }); } // ——— Build the Shopify OAuth URL and return it ——— const stateNonce = Math.random().toString(36).slice(2); const installUrl = `https://${shopName}.myshopify.com/admin/oauth/authorize` + `?client_id=${CLIENT_ID}` + `&scope=${SCOPES}` + `&redirect_uri=${encodeURIComponent(REDIRECT_URI)}` + `&state=${stateNonce}` //+ `&grant_options%5B%5D=per-user`; return json({ success: true, confirmationUrl: installUrl, }); }; export default function StoreCredentials() { const { shopName, shopId, savedCreds } = useLoaderData(); const actionData = useActionData(); useEffect(() => { if (actionData?.confirmationUrl) { window.open(actionData.confirmationUrl, "_blank", "noopener,noreferrer"); } }, [actionData?.confirmationUrl]); const [clientId, setClientId] = useState(actionData?.creds?.clientId || savedCreds.clientId || ""); const [clientSecret, setClientSecret] = useState(actionData?.creds?.clientSecret || savedCreds.clientSecret || ""); const connected = actionData?.success || Boolean(savedCreds.accessToken); return (
Data4Autos Turn14 Integration
Shop: {shopName} {/* —— TURN14 FORM —— */}
{actionData?.error && ( )} {connected && (

✅ Turn14 connected successfully!

{/* —— SHOPIFY INSTALL FORM —— */} {/*
*/}
)}
); }