import { json } from "@remix-run/node"; import { useLoaderData, useActionData, Form } from "@remix-run/react"; import { useState } from "react"; import { Page, Layout, Card, TextField, Button, TextContainer, InlineError, } from "@shopify/polaris"; import { authenticate } from "../shopify.server"; export const loader = async ({ request }) => { const { admin } = await authenticate.admin(request); // Fetch shop info and stored credentials const gqlResponse = await admin.graphql(` { shop { id name metafield(namespace: "turn14", key: "credentials") { value } } } `); const shopData = await gqlResponse.json(); const shopName = shopData?.data?.shop?.name || "Unknown Shop"; const metafieldRaw = shopData?.data?.shop?.metafield?.value; let creds = {}; if (metafieldRaw) { try { creds = JSON.parse(metafieldRaw); } catch (err) { console.error("Failed to parse stored credentials:", err); } } return json({ shopName, creds }); }; export const action = async ({ request }) => { const formData = await request.formData(); const clientId = formData.get("client_id") || ""; const clientSecret = formData.get("client_secret") || ""; const { admin } = await authenticate.admin(request); // Fetch shop ID const shopInfo = await admin.graphql(`{ shop { id } }`); const shopId = (await shopInfo.json())?.data?.shop?.id; // Get Turn14 token 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, }), }); const tokenData = await tokenRes.json(); if (!tokenRes.ok) { return json({ success: false, error: tokenData.error || "Failed to fetch access token", }); } const accessToken = tokenData.access_token; const expiresAt = new Date(Date.now() + 3600 * 1000).toISOString(); const credentials = { clientId, clientSecret, accessToken, expiresAt, }; // Upsert as metafield in Shopify const mutation = ` mutation { metafieldsSet(metafields: [ { ownerId: "${shopId}" namespace: "turn14" key: "credentials" type: "json" value: "${JSON.stringify(credentials).replace(/"/g, '\\"')}" } ]) { metafields { key value } userErrors { field message } } } `; const saveRes = await admin.graphql(mutation); const result = await saveRes.json(); if (result?.data?.metafieldsSet?.userErrors?.length) { return json({ success: false, error: result.data.metafieldsSet.userErrors[0].message, }); } return json({ success: true, clientId, clientSecret, accessToken, }); } catch (err) { console.error("Turn14 token fetch failed:", err); return json({ success: false, error: "Network or unexpected error occurred", }); } }; export default function SettingsPage() { const loaderData = useLoaderData(); const actionData = useActionData(); const savedCreds = loaderData?.creds || {}; const shopName = loaderData?.shopName || "Shop"; const [clientId, setClientId] = useState(actionData?.clientId || savedCreds.clientId || ""); const [clientSecret, setClientSecret] = useState(actionData?.clientSecret || savedCreds.clientSecret || ""); const displayToken = actionData?.accessToken || savedCreds.accessToken; return (

Connected Shop: {shopName}

{actionData?.error && ( )} {displayToken && (

✅ Access token:

{displayToken}
)}
); }