Skip to content

Commit e0386c4

Browse files
committed
Implement payment customization details page
1 parent 578ebc0 commit e0386c4

File tree

1 file changed

+172
-0
lines changed
  • sample-apps/payment-customizations/web/frontend/pages/payment-customization/[functionId]

1 file changed

+172
-0
lines changed
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
import { useState, useEffect } from "react";
2+
import { useParams } from "react-router-dom";
3+
import {
4+
Layout,
5+
Form,
6+
FormLayout,
7+
TextField,
8+
Card,
9+
Page,
10+
Frame,
11+
SkeletonPage,
12+
SkeletonBodyText,
13+
} from "@shopify/polaris";
14+
import { useAppBridge } from "@shopify/app-bridge-react";
15+
import { Redirect } from "@shopify/app-bridge/actions";
16+
import { useAuthenticatedFetch } from "../../../hooks/useAuthenticatedFetch";
17+
import { useAppQuery } from "../../../hooks/useAppQuery";
18+
19+
// Utility hooks for invoking the server endpoints that you created
20+
function useCustomization(id) {
21+
const url = `/api/paymentCustomization/${id}`;
22+
return useAppQuery({ url });
23+
}
24+
25+
function useUpdateCustomization() {
26+
const fetch = useAuthenticatedFetch();
27+
return async (paymentCustomization) => {
28+
return await fetch("/api/paymentCustomization/update", {
29+
method: "PUT",
30+
headers: { "Content-Type": "application/json" },
31+
body: JSON.stringify(paymentCustomization),
32+
});
33+
};
34+
}
35+
36+
// A utility hook for redirecting back to the Payment Customizations list
37+
function useRedirectToCustomizations() {
38+
const app = useAppBridge();
39+
const redirect = Redirect.create(app);
40+
return () => {
41+
redirect.dispatch(Redirect.Action.ADMIN_PATH, {
42+
path: "/settings/payments/customizations",
43+
});
44+
};
45+
}
46+
47+
export default function NewCustomizationPage() {
48+
// Read the function and customization IDs from the URL
49+
const { functionId, id } = useParams();
50+
51+
// Fetch customization data
52+
const { isLoading, data: customization } = useCustomization(id);
53+
54+
// Utility hooks
55+
const updateCustomization = useUpdateCustomization();
56+
const redirect = useRedirectToCustomizations();
57+
58+
// Page state management
59+
const [mutationIsLoading, setMutationIsLoading] = useState(false);
60+
const [formData, setFormData] = useState({});
61+
62+
// Page breadcrumbs [
63+
const breadcrumbs = [
64+
{
65+
content: "Payment Customizations",
66+
onAction: redirect,
67+
},
68+
];
69+
70+
// Store the form state on change
71+
const handleInputChange = (value, name) => {
72+
setFormData((data) => ({ ...data, [name]: value }));
73+
};
74+
75+
// Invoke the server endpoint when the form is submitted
76+
const handleSubmit = async () => {
77+
setMutationIsLoading(true);
78+
const response = await updateCustomization({
79+
functionId,
80+
id: formData.id,
81+
paymentMethod: formData.paymentMethod,
82+
cartTotal: parseFloat(formData.cartTotal),
83+
});
84+
if (response.status != 200) {
85+
const errorResponse = await response.json();
86+
console.log(
87+
"Error creating payment customization: ",
88+
errorResponse.error
89+
);
90+
} else {
91+
redirect();
92+
}
93+
setMutationIsLoading(false);
94+
};
95+
96+
// When the customization is loaded, set the form state
97+
useEffect(() => {
98+
setFormData(customization);
99+
}, [customization, setFormData]);
100+
101+
if (isLoading) {
102+
return (
103+
<Frame>
104+
<SkeletonPage
105+
title="Hide payment method"
106+
breadcrumbs={breadcrumbs}
107+
primaryAction
108+
>
109+
<Layout.Section>
110+
<Card sectioned>
111+
<SkeletonBodyText />
112+
</Card>
113+
</Layout.Section>
114+
</SkeletonPage>
115+
</Frame>
116+
);
117+
}
118+
119+
// A basic input form page created using Polaris components
120+
return (
121+
<Frame>
122+
<Page
123+
title="Hide payment method"
124+
primaryAction={{
125+
onAction: handleSubmit,
126+
content: "Save",
127+
loading: mutationIsLoading,
128+
}}
129+
breadcrumbs={[
130+
{
131+
content: "Payment customizations",
132+
onAction: redirect,
133+
},
134+
]}
135+
>
136+
<Layout.Section>
137+
<Card>
138+
<Card.Section>
139+
<Form onSubmit={handleSubmit}>
140+
<FormLayout>
141+
<FormLayout.Group>
142+
<TextField
143+
type="text"
144+
label="Payment method"
145+
value={formData?.paymentMethod}
146+
onChange={(value) =>
147+
handleInputChange(value, "paymentMethod")
148+
}
149+
disabled={mutationIsLoading}
150+
requiredIndicator
151+
/>
152+
153+
<TextField
154+
type="number"
155+
label="Cart total"
156+
value={formData?.cartTotal}
157+
onChange={(value) =>
158+
handleInputChange(value, "cartTotal")
159+
}
160+
disabled={mutationIsLoading}
161+
requiredIndicator
162+
/>
163+
</FormLayout.Group>
164+
</FormLayout>
165+
</Form>
166+
</Card.Section>
167+
</Card>
168+
</Layout.Section>
169+
</Page>
170+
</Frame>
171+
);
172+
}

0 commit comments

Comments
 (0)