PageSourceSearch

https://cdn.simplystamps.com/skin/frontend/zephyr/default/js/components/rileyprint.js?v=1126

js simplystamps.com collected 2026-10-02 06:57:40 UTC 4,852 bytes, 119 lines download raw bytes

1/**
2 * Zephyr Modern Theme - RileyPrint PDP Component
3 *
4 * Replaces the legacy jQuery "design return" flow for RileyPrint face-stamp
5 * products. Drives the Alpine root rendered by the `elseif ($isRileyprint)`
6 * branch in catalog/product/view.phtml.
7 *
8 * Flow:
9 *   - No `?d=` param in the URL  -> only the "Design Stamp" button shows.
10 *   - `?d=<designId>` present     -> POST {design_id, product_id} to the
11 *     RileyPrint thumbnail endpoint, inject the returned preview HTML, reveal
12 *     price + qty + Add-to-Cart + options, and populate the hidden
13 *     `rileyprint_design` field so the design rides into the cart.
14 *
15 * Cross-subtree state: the product-options wrapper and the sticky ATC bars are
16 * rendered OUTSIDE this component's DOM root, so `hasDesign` is mirrored into
17 * Alpine.store('rileyprint') for them to gate on (mirrors the groupedWizard
18 * store pattern used elsewhere in the theme).
19 *
20 * Endpoint: HSC_PCE_IndexController::uploadRPThumbnailAction()
21 *           returns JSON { thumbnail_image_html: "..." }
22 *
23 * @see app/design/frontend/zephyr/modern/template/catalog/product/view/rileyprint.phtml
24 */
25function rileyPrint(config) {
26    config = config || {};
27
28    return {
29        // ----- Config (injected from the template) -----
30        productId: config.productId || 0,
31        uploadUrl: config.uploadUrl || '/designer/index/uploadRPThumbnail/',
32
33        // ----- State -----
34        designId: '',
35        thumbnailHtml: '',
36        loading: false,
37        hasDesign: false,
38
39        init() {
40            // Mirror design state to a shared store so sibling blocks rendered
41            // outside this root (options wrapper, sticky ATC) can react.
42            this.$watch('hasDesign', (value) => {
43                if (window.Alpine && Alpine.store('rileyprint')) {
44                    Alpine.store('rileyprint').hasDesign = value;
45                }
46            });
47
48            // Design id can arrive two ways:
49            //   `d`     — handed back by the external RileyPrint editor on a fresh design
50            //   `rpdid` — set by the cart "Edit Design" link (CartController::_getConfigureUrl)
51            //             when editing an existing cart item in configure mode
52            const params = new URLSearchParams(window.location.search);
53            const designId = params.get('d') || params.get('rpdid');
54            if (!designId) { return; }
55
56            this.designId = designId;
57            this.loading = true;
58            this.fetchThumbnail();
59        },
60
61        fetchThumbnail() {
62            if (!this.productId || !this.uploadUrl) {
63                this.loading = false;
64                return;
65            }
66
67            const formData = new FormData();
68            formData.append('design_id', this.designId);
69            formData.append('product_id', this.productId);
70
71            fetch(this.uploadUrl, {
72                method: 'POST',
73                body: formData,
74                credentials: 'same-origin',
75                headers: { 'X-Requested-With': 'XMLHttpRequest' }
76            })
77                .then((response) => {
78                    if (!response.ok) {
79                        throw new Error('HTTP ' + response.status);
80                    }
81                    return response.json();
82                })
83                .then((data) => {
84                    // Endpoint returns { thumbnail_image_html: "..." }.
85                    // Guard against a double-encoded JSON string just in case.
86                    if (typeof data === 'string') {
87                        try { data = JSON.parse(data); } catch (e) { /* keep as-is */ }
88                    }
89
90                    this.thumbnailHtml = (data && data.thumbnail_image_html) || '';
91                    this.hasDesign = true;   // reveal preview + options + qty/ATC; hide Design button
92                    this.loading = false;
93
94                })
95                .catch(() => {
96                    // The design id is still valid (the shopper returned from the
97                    // editor), so allow checkout even if the preview image failed.
98                    this.thumbnailHtml =
99                        '<p class="text-brand-danger text-sm">' +
100                        'We could not load your design preview, but your design is saved. ' +
101                        'You can still add it to your cart.' +
102                        '</p>';
103                    this.hasDesign = true;
104                    this.loading = false;
105                });
106        }
107    };
108}
109
110// Expose the factory for Alpine's x-data="rileyPrint({...})".
111window.rileyPrint = rileyPrint;
112
113// Shared flag consumed by sibling blocks (options wrapper, sticky ATC bars)
114// that live outside the component's DOM root.
115document.addEventListener('alpine:init', () => {
116    Alpine.store('rileyprint', {
117        hasDesign: false
118    });
119});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.