Skip to content

Commit 6ed425c

Browse files
authored
Merge pull request #45 from Shopify/small-example-app-fixes
Small example app fixes
2 parents 17a51b3 + d7db09f commit 6ed425c

4 files changed

Lines changed: 37 additions & 23 deletions

File tree

app/models/QRCode.server.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import qrcode from "qrcode";
22
import invariant from "tiny-invariant";
33

4+
// [START get-qrcode]
45
const METAOBJECT_TYPE = "$app:qrcode";
56

6-
// [START get-qrcode]
77
export async function getQRCode(handle, graphql, shop) {
88
const response = await graphql(
99
`
@@ -103,7 +103,6 @@ export async function getQRCodes(graphql, shop) {
103103

104104
return Promise.all(metaobjects.map((mo) => transformMetaobject(mo, shop)));
105105
}
106-
// [END get-qrcode]
107106

108107
async function transformMetaobject(metaobject, shop) {
109108
const product = metaobject.product?.reference;
@@ -132,6 +131,7 @@ async function transformMetaobject(metaobject, shop) {
132131

133132
return qrCode;
134133
}
134+
// [END get-qrcode]
135135

136136
// [START get-qrcode-image]
137137
export async function getQRCodeImage(handle, shop) {
@@ -240,6 +240,7 @@ export async function incrementQRCodeScans(id, currentScans, graphql) {
240240
}
241241
// [END increment-scans]
242242

243+
// [START generate-handle]
243244
function slugify(text) {
244245
return text
245246
.toLowerCase()
@@ -250,6 +251,7 @@ function slugify(text) {
250251
export function generateHandle(title) {
251252
return `${slugify(title)}-${Date.now().toString(36)}`;
252253
}
254+
// [END generate-handle]
253255

254256
// [START validate-qrcode]
255257
export function validateQRCode(data) {

app/routes/app._index.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useLoaderData, Link } from "react-router";
1+
import { useLoaderData } from "react-router";
22
import { boundary } from "@shopify/shopify-app-react-router/server";
33

44
import { authenticate } from "../shopify.server";
@@ -48,11 +48,13 @@ const EmptyQRCodeState = () => (
4848
);
4949
// [END empty]
5050

51+
// [START truncate]
5152
function truncate(str, { length = 25 } = {}) {
5253
if (!str) return "";
5354
if (str.length <= length) return str;
5455
return str.slice(0, length) + "…";
5556
}
57+
// [END truncate]
5658

5759
// [START table]
5860
const QRTable = ({ qrCodes }) => (

app/routes/app.qrcodes.$id.jsx

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import {
33
useActionData,
44
useLoaderData,
55
useSubmit,
6-
useNavigation,
7-
useNavigate,
86
useParams,
97
} from "react-router";
108
import { authenticate } from "../shopify.server";
@@ -39,12 +37,9 @@ export async function loader({ request, params }) {
3937

4038
// [START action]
4139
export async function action({ request, params }) {
42-
const { session, admin, redirect } = await authenticate.admin(request);
40+
const { admin, redirect } = await authenticate.admin(request);
4341

44-
/** @type {any} */
45-
const data = {
46-
...Object.fromEntries(await request.formData()),
47-
};
42+
const data = Object.fromEntries(await request.formData());
4843

4944
if (data.action === "delete") {
5045
await deleteQRCode(data.metaobjectId, admin.graphql);
@@ -72,7 +67,6 @@ export async function action({ request, params }) {
7267
// [END action]
7368

7469
export default function QRCodeForm() {
75-
const navigate = useNavigate();
7670
const { id } = useParams();
7771

7872
// [START state]
@@ -81,7 +75,6 @@ export default function QRCodeForm() {
8175
const [initialFormState, setInitialFormState] = useState(qrCode);
8276
const [formState, setFormState] = useState(qrCode);
8377
const errors = useActionData()?.errors || {};
84-
const isSaving = useNavigation().state === "submitting";
8578
const isDirty =
8679
JSON.stringify(formState) !== JSON.stringify(initialFormState);
8780
// [END state]
@@ -185,6 +178,7 @@ export default function QRCodeForm() {
185178
<button variant="primary" onClick={handleSave}></button>
186179
<button onClick={handleReset}></button>
187180
</ui-save-bar>
181+
{/* [END save-bar] */}
188182
<form onSubmit={handleSave} onReset={handleReset}>
189183
{/* [START polaris] */}
190184
<s-page heading={initialFormState.title || "Create QR code"}>
@@ -316,7 +310,10 @@ export default function QRCodeForm() {
316310
</s-button>
317311
)}
318312
{errors.productId ? (
319-
<s-text tone="critical">{errors.productId}</s-text>
313+
<div style={{ display: "flex", alignItems: "center", gap: "4px" }}>
314+
<s-icon type="alert-circle" tone="critical" size="small" />
315+
<s-text tone="critical" variant="bodySm">{errors.productId}</s-text>
316+
</div>
320317
) : null}
321318
</s-stack>
322319
</s-stack>

shopify.app.toml

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,44 +12,57 @@ include_config_on_deploy = true
1212
[webhooks]
1313
api_version = "2026-04"
1414

15+
[[webhooks.subscriptions]]
16+
topics = [ "app/uninstalled" ]
17+
uri = "/webhooks/app/uninstalled"
18+
19+
[[webhooks.subscriptions]]
20+
topics = [ "app/scopes_update" ]
21+
uri = "/webhooks/app/scopes_update"
22+
1523
# [START access-scopes]
1624
[access_scopes]
1725
# Learn more at https://shopify.dev/docs/apps/tools/cli/configuration#access_scopes
1826
scopes = "write_metaobject_definitions,write_metaobjects,write_products"
1927
# [END access-scopes]
2028

2129
[auth]
22-
redirect_urls = [ "<YOUR_APP_URL>/api/auth" ]
30+
redirect_urls = [ "https://example.com/api/auth" ]
31+
32+
[product.metafields.app.demo_info]
33+
type = "single_line_text_field"
34+
name = "Demo Source Info"
35+
description = "Tracks products created by the Shopify app template for development"
36+
37+
[product.metafields.app.demo_info.access]
38+
admin = "merchant_read_write"
2339

2440
# [START metaobject-definition]
2541
[metaobjects.app.qrcode]
2642
name = "QR Code"
27-
display_name_field = "title"
43+
description = "QR codes that link to products"
2844

2945
[metaobjects.app.qrcode.access]
3046
admin = "merchant_read_write"
3147

3248
[metaobjects.app.qrcode.fields.title]
33-
type = "single_line_text_field"
3449
name = "Title"
50+
type = "single_line_text_field"
3551
required = true
3652

3753
[metaobjects.app.qrcode.fields.product]
38-
type = "product_reference"
3954
name = "Product"
55+
type = "product_reference"
4056

4157
[metaobjects.app.qrcode.fields.product_variant]
42-
type = "variant_reference"
4358
name = "Product Variant"
59+
type = "variant_reference"
4460

4561
[metaobjects.app.qrcode.fields.destination]
46-
type = "single_line_text_field"
4762
name = "Destination"
48-
49-
[metaobjects.app.qrcode.fields.destination.validations]
50-
choices = [ "product", "cart" ]
63+
type = "single_line_text_field"
5164

5265
[metaobjects.app.qrcode.fields.scans]
53-
type = "number_integer"
5466
name = "Scans"
67+
type = "number_integer"
5568
# [END metaobject-definition]

0 commit comments

Comments
 (0)