Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 0 additions & 6 deletions .changeset/soft-clowns-turn.md

This file was deleted.

2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v20.19.6
v20.10.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';
import {reactExtension, useApi, AdminAction, Button, TextField, Select, BlockStack} from '@shopify/ui-extensions-react/admin';

function App() {
const {data, close} = useApi('admin.product-details.action.render');
const productId = data.selected[0]?.id;

return (
<AdminAction
title="Assign warehouse location"
primaryAction={
<Button
onPress={async () => {
await fetch('/api/products/assign-warehouse', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({productId}),
});
close();
}}
>
Assign to warehouse
</Button>
}
secondaryAction={
<Button onPress={() => close()}>Cancel</Button>
}
>
<BlockStack gap>
<TextField label="Warehouse SKU" name="warehouseSku" required />
<Select
label="Target warehouse"
name="warehouse"
options={[
{label: 'East Coast — New York', value: 'nyc'},
{label: 'West Coast — Los Angeles', value: 'lax'},
{label: 'Central — Chicago', value: 'chi'},
]}
/>
</BlockStack>
</AdminAction>
);
}

export default reactExtension(
'admin.product-details.action.render',
() => <App />,
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React, {useState, useEffect} from 'react';
import {reactExtension, useApi, AdminAction, Button, Text, ProgressIndicator, BlockStack} from '@shopify/ui-extensions-react/admin';

function App() {
const {data, close, query} = useApi('admin.product-details.action.render');
const productId = data.selected[0]?.id;
const [product, setProduct] = useState(null);
const [loading, setLoading] = useState(true);

useEffect(() => {
query(
`query Product($id: ID!) {
product(id: $id) { title status totalInventory }
}`,
{variables: {id: productId}},
).then((result) => {
setProduct(result?.data?.product);
setLoading(false);
});
}, [productId, query]);

return (
<AdminAction
title="Product details"
primaryAction={<Button onPress={() => close()}>Done</Button>}
>
<BlockStack gap>
{loading ? (
<ProgressIndicator
size="small-200"
accessibilityLabel="Loading product details"
/>
) : product ? (
<>
<Text fontWeight="bold">{product.title}</Text>
<Text>Status: {product.status}</Text>
<Text>Inventory: {product.totalInventory} units</Text>
</>
) : null}
</BlockStack>
</AdminAction>
);
}

export default reactExtension(
'admin.product-details.action.render',
() => <App />,
);
Original file line number Diff line number Diff line change
@@ -1,30 +1,41 @@
import React from 'react';
import {
reactExtension,
AdminAction,
Button,
Text,
} from '@shopify/ui-extensions-react/admin';
import {reactExtension, useApi, AdminAction, Button, Text, BlockStack} from '@shopify/ui-extensions-react/admin';

function App() {
const {data, close} = useApi('admin.product-details.action.render');
const productId = data.selected[0]?.id;

return (
<AdminAction
title="My App Action"
title="Sync to warehouse"
primaryAction={
<Button onPress={() => {}}>Action</Button>
<Button
onPress={async () => {
await fetch('/api/products/sync', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({productId}),
});
close();
}}
>
Sync product
</Button>
}
secondaryAction={
<Button onPress={() => {}}>
Secondary
</Button>
<Button onPress={() => close()}>Cancel</Button>
}
>
<Text>Modal content</Text>
<BlockStack gap>
<Text>
Sync product {productId} to your warehouse management system. This
will update inventory counts, pricing, and metadata.
</Text>
</BlockStack>
</AdminAction>
);
}

export default reactExtension(
'Playground',
'admin.product-details.action.render',
() => <App />,
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, {useState, useEffect} from 'react';
import {reactExtension, useApi, AdminBlock, Text, ProgressIndicator, BlockStack} from '@shopify/ui-extensions-react/admin';

function App() {
const {data, query} = useApi('admin.product-details.block.render');
const productId = data.selected[0]?.id;
const [product, setProduct] = useState(null);
const [loading, setLoading] = useState(true);

useEffect(() => {
query(
`query Product($id: ID!) {
product(id: $id) { title totalInventory totalVariants }
}`,
{variables: {id: productId}},
).then((result) => {
setProduct(result?.data?.product);
setLoading(false);
});
}, [productId, query]);

return (
<AdminBlock title="Product analytics">
<BlockStack gap>
{loading ? (
<ProgressIndicator size="small-200" accessibilityLabel="Loading analytics" />
) : product ? (
<>
<Text fontWeight="bold">{product.title}</Text>
<Text>Variants: {product.totalVariants}</Text>
<Text>Total inventory: {product.totalInventory}</Text>
</>
) : null}
</BlockStack>
</AdminBlock>
);
}

export default reactExtension(
'admin.product-details.block.render',
() => <App />,
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import {reactExtension, AdminBlock, Section, Text, Divider, BlockStack} from '@shopify/ui-extensions-react/admin';

function App() {

return (
<AdminBlock title="Product specifications">
<BlockStack gap>
<Section heading="Compliance">
<Text>CE Marking — Approved</Text>
<Text>EU distribution cleared</Text>
</Section>
<Divider />
<Section heading="Shipping">
<Text>Weight: 2.5 kg</Text>
<Text>Dimensions: 30 × 20 × 15 cm</Text>
</Section>
</BlockStack>
</AdminBlock>
);
}

export default reactExtension(
'admin.product-details.block.render',
() => <App />,
);
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
import React from 'react';
import {reactExtension, AdminBlock} from '@shopify/ui-extensions-react/admin';
import {reactExtension, AdminBlock, Text, Badge, InlineStack, BlockStack} from '@shopify/ui-extensions-react/admin';

function App() {

return (
<AdminBlock title="My App Block">
Block content
<AdminBlock title="Warehouse integration">
<BlockStack gap>
<InlineStack gap>
<Text>Sync status:</Text>
<Badge tone="success">Connected</Badge>
</InlineStack>
<Text>Last synced 5 minutes ago</Text>
<Text>Warehouse inventory: 247 units across 3 locations</Text>
</BlockStack>
</AdminBlock>
);
}

export default reactExtension('Playground', () => <App />);
export default reactExtension(
'admin.product-details.block.render',
() => <App />,
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import {reactExtension, useApi, AdminPrintAction, Text, ProgressIndicator, BlockStack} from '@shopify/ui-extensions-react/admin';

function App() {
const {data} = useApi('admin.product-details.action.render');
const productId = data.selected[0]?.id;

return (
<AdminPrintAction
src={`https://your-app.com/print/invoice?product=${productId}&type=wholesale`}
>
<BlockStack gap>
<ProgressIndicator size="small-200" accessibilityLabel="Generating invoice" />
<Text>
Generating wholesale invoice with pricing and tax details...
</Text>
</BlockStack>
</AdminPrintAction>
);
}

export default reactExtension(
'admin.product-details.action.render',
() => <App />,
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import {reactExtension, useApi, AdminPrintAction, Text, BlockStack} from '@shopify/ui-extensions-react/admin';

function App() {
const {data} = useApi('admin.product-details.action.render');
const productId = data.selected[0]?.id;
const numericId = productId?.split('/').pop();

return (
<AdminPrintAction
src={`https://your-app.com/print/shipping-label?product=${numericId}&format=4x6`}
>
<BlockStack gap>
<Text>Preparing shipping label with warehouse barcode...</Text>
</BlockStack>
</AdminPrintAction>
);
}

export default reactExtension(
'admin.product-details.action.render',
() => <App />,
);
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import React from 'react';
import {
reactExtension,
AdminPrintAction,
Text,
} from '@shopify/ui-extensions-react/admin';
import {reactExtension, useApi, AdminPrintAction, Text, BlockStack} from '@shopify/ui-extensions-react/admin';

function App() {
const {data} = useApi('admin.product-details.action.render');
const productId = data.selected[0]?.id;

return (
<AdminPrintAction src="https://example.com">
<Text>Modal content</Text>
<AdminPrintAction
src={`https://your-app.com/print/packing-slip?product=${productId}`}
>
<BlockStack gap>
<Text>Generating packing slip for this product...</Text>
</BlockStack>
</AdminPrintAction>
);
}

export default reactExtension(
'Playground',
'admin.product-details.action.render',
() => <App />,
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {reactExtension, Badge, BlockStack, Text} from '@shopify/ui-extensions-react/admin';

function App() {

return (
<BlockStack>
<Text fontWeight="bold">Inventory alerts</Text>
<Badge tone="success" icon="CircleTickMajor">In stock</Badge>
<Badge tone="warning" icon="DiamondAlertMajor">Low stock</Badge>
<Badge tone="critical" icon="DiamondAlertMajor">Out of stock</Badge>
</BlockStack>
);
}

export default reactExtension(
'admin.product-details.block.render',
() => <App />,
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {reactExtension, Badge, InlineStack, Text, BlockStack} from '@shopify/ui-extensions-react/admin';

function App() {

return (
<BlockStack>
<Text fontWeight="bold">Sales channels</Text>
<InlineStack>
<Badge size="small-100" tone="success">Online Store</Badge>
<Badge size="small-100" tone="success">POS</Badge>
<Badge size="small-100" tone="info">Facebook — pending</Badge>
</InlineStack>
</BlockStack>
);
}

export default reactExtension(
'admin.product-details.block.render',
() => <App />,
);
Loading