Two-Tier Ghost Serving Stand – Hand, Everyday Comfort, Was $65, Save 38%

$39.99
/** * 优惠码组件模型类 * 处理优惠码的显示和交互逻辑 */ class SpzCustomDiscountCodeModel extends SPZ.BaseElement { constructor(element) { super(element); // 复制按钮和内容的类名 this.copyBtnClass = "discount_code_btn" this.copyClass = "discount_code_value" } isLayoutSupported(layout) { return layout == SPZCore.Layout.LOGIC; } buildCallback() { // 初始化服务 this.action_ = SPZServices.actionServiceForDoc(this.element); this.templates_ = SPZServices.templatesForDoc(this.element); this.xhr_ = SPZServices.xhrFor(this.win); } /** * 渲染优惠码组件 * @param {Object} data - 渲染数据 */ doRender_(data) { return this.templates_ .findAndRenderTemplate(this.element, Object.assign(this.getDefaultData(), data) ) .then((el) => { this.clearDom(); this.element.appendChild(el); // 绑定复制代码功能 this.copyCode(el, data); }); } /** * 获取渲染模板 * @param {Object} data - 渲染数据 */ getRenderTemplate(data) { const renderData = Object.assign(this.getDefaultData(), data); return this.templates_ .findAndRenderTemplate(this.element, renderData) .then((el) => { this.clearDom(); return el; }); } /** * 清除DOM内容 */ clearDom() { const children = this.element.querySelector('*:not(template)'); children && SPZCore.Dom.removeElement(children); } /** * 获取默认数据 * @returns {Object} 默认数据对象 */ getDefaultData() { return { isMobile: appDiscountUtils.judgeMobile(), isRTL: appDiscountUtils.judgeRTL(), image_domain: this.win.SHOPLAZZA.image_domain, copyBtnClass: this.copyBtnClass, copyClass: this.copyClass } } /** * 复制优惠码功能 * @param {Element} el - 当前元素 */ copyCode(el) { const copyBtnList = el.querySelectorAll(`.${this.copyBtnClass}`); if (copyBtnList.length > 0) { copyBtnList.forEach(item => { item.onclick = async () => { // 确保获取正确的元素和内容 const codeElement = item.querySelector(`.${this.copyClass}`); if (!codeElement) return; // 获取纯文本内容 const textToCopy = codeElement.innerText.trim(); // 尝试使用现代API,如果失败则使用备用方案 try { if (navigator.clipboard && navigator.clipboard.writeText) { await navigator.clipboard.writeText(textToCopy); } else { throw new Error('Clipboard API not available'); } // 显示复制成功提示 this.showCopySuccessToast(textToCopy, el); } catch (err) { console.error('Modern clipboard API failed, trying fallback...', err); // 使用备用复制方案 this.fallbackCopy(textToCopy, el); } const discountId = item.dataset["discountId"]; // 跳转决策: is_redirection + link(可选覆盖) const setting = { is_redirection: item.dataset["redirection"] === "true", link: item.dataset["link"], }; const landingUrl = `/promotions/discount-default/${discountId}`; const finalUrl = appDiscountUtils.resolveDiscountHref(setting, landingUrl); if (finalUrl && appDiscountUtils.inProductBody(this.element)) { this.win.open(finalUrl, '_blank', 'noopener'); } } }) } } /** * 使用 execCommand 的复制方案 * @param {string} codeText - 要复制的文本 * @param {Element} el - 当前元素 */ fallbackCopy(codeText, el) { const textarea = this.win.document.createElement('textarea'); textarea.value = codeText; // 设置样式使文本框不可见 textarea.style.position = 'fixed'; textarea.style.left = '-9999px'; textarea.style.top = '0'; // 添加 readonly 属性防止移动端虚拟键盘弹出 textarea.setAttribute('readonly', 'readonly'); this.win.document.body.appendChild(textarea); textarea.focus(); textarea.select(); try { this.win.document.execCommand('copy'); // 显示复制成功提示 this.showCopySuccessToast(codeText, el); } catch (err) { console.error('Copy failed:', err); } this.win.document.body.removeChild(textarea); } /** * 创建 Toast 元素 * @returns {Element} 创建的 Toast 元素 */ createToastEl_() { const toast = document.createElement('ljs-toast'); toast.setAttribute('layout', 'nodisplay'); toast.setAttribute('hidden', ''); toast.setAttribute('id', 'discount-code-toast'); toast.style.zIndex = '1051'; return toast; } /** * 挂载 Toast 元素到 body * @returns {Element} 挂载的 Toast 元素 */ mountToastToBody_() { const existingToast = this.win.document.getElementById('discount-code-toast'); if (existingToast) { return existingToast; } const toast = this.createToastEl_(); this.win.document.body.appendChild(toast); return toast; } /** * 复制成功的提醒 * @param {string} codeText - 要复制的文本 * @param {Element} el - 当前元素 */ showCopySuccessToast(codeText, el) { const $toast = this.mountToastToBody_(); SPZ.whenApiDefined($toast).then(toast => { toast.showToast("Discount code copied !"); this.codeCopyInSessionStorage(codeText); }); } /** * 复制优惠码成功后要存一份到本地存储中,购物车使用 * @param {string} codeText - 要复制的文本 */ codeCopyInSessionStorage(codeText) { try { sessionStorage.setItem('other-copied-coupon', codeText); } catch (error) { console.error(error) } } } // 注册自定义元素 SPZ.defineElement('spz-custom-discount-code-model', SpzCustomDiscountCodeModel);
/** * Custom discount code component that handles displaying and managing discount codes * @extends {SPZ.BaseElement} */ class SpzCustomDiscountCode extends SPZ.BaseElement { constructor(element) { super(element); // API endpoint for fetching discount codes this.getDiscountCodeApi = "\/api\/storefront\/promotion\/code\/list"; // Debounce timer for resize events this.timer = null; // Current variant ID this.variantId = "638524a4-0f2d-4fd6-bea6-5a0a2a6abf31"; // Store discount code data this.discountCodeData = {} } /** * Check if layout is supported * @param {string} layout - Layout type * @return {boolean} */ isLayoutSupported(layout) { return layout == SPZCore.Layout.LOGIC; } /** * Initialize component after build */ buildCallback() { this.templates_ = SPZServices.templatesForDoc(); this.viewport_ = this.getViewport(); // Bind methods to maintain context this.render = this.render.bind(this); this.resize = this.resize.bind(this); this.switchVariant = this.switchVariant.bind(this); } /** * Setup component when mounted */ mountCallback() { this.getData(); // Add event listeners this.viewport_.onResize(this.resize); this.win.document.addEventListener('dj.variantChange', this.switchVariant); } /** * Cleanup when component is unmounted */ unmountCallback() { this.viewport_.removeResize(this.resize); this.win.document.removeEventListener('dj.variantChange', this.switchVariant); // 清除定时器 if (this.timer) { clearTimeout(this.timer); this.timer = null; } } /** * Handle resize events with debouncing */ resize() { if (this.timer) { clearTimeout(this.timer) this.timer = null; } this.timer = setTimeout(() => { if (appDiscountUtils.inProductBody(this.element)) { this.render(); } else { this.renderSkeleton(); } }, 200); } /** * Handle variant changes * @param {Event} event - Variant change event */ switchVariant(event) { const variant = event.detail.selected; if (variant.product_id == 'a6f99705-156c-46e6-9914-31616f2cc8ef' && variant.id != this.variantId) { this.variantId = variant.id; this.getData(); } } /** * Fetch discount code data from API */ getData() { if (appDiscountUtils.inProductBody(this.element)) { const reqBody = { product_id: "a6f99705-156c-46e6-9914-31616f2cc8ef", variant_id: this.variantId, product_type: "default", } if (!reqBody.product_id || !reqBody.variant_id) return; this.discountCodeData = {}; this.win.fetch(this.getDiscountCodeApi, { method: "POST", body: JSON.stringify(reqBody), headers: { "Content-Type": "application/json" } }).then(async (response) => { if (response.ok) { let data = await response.json(); if (data.list && data.list.length > 0) { data.list[0].product_setting.template_config = JSON.parse(data.list[0].product_setting.template_config); // Format timestamps to local timezone const zone = this.win.SHOPLAZZA.shop.time_zone; data.list = data.list.map(item => { if(+item.ends_at !== -1) { item.ends_at = appDiscountUtils.convertTimestampToFormat(+item.ends_at, zone); } item.starts_at = appDiscountUtils.convertTimestampToFormat(+item.starts_at, zone); return item; }); } this.discountCodeData = data; this.render(); } else { this.clearDom(); } }).catch(err => { console.error("discount_code", err) this.clearDom(); }); } else { this.renderSkeleton(); } } /** * Clear component DOM except template */ clearDom() { const children = this.element.querySelector('*:not(template)'); children && SPZCore.Dom.removeElement(children); } /** * Render discount codes with formatted dates */ render() { // Render using discount code model SPZ.whenApiDefined(document.querySelector('#spz_custom_discount_code_model')).then(renderApi => { renderApi.doRender_({ discountCodeData: this.discountCodeData }) }).catch(err => { this.clearDom(); }) } renderSkeleton() { // Render template for non-product pages this.templates_ .findAndRenderTemplate(this.element, { isMobile: appDiscountUtils.judgeMobile() }) .then((el) => { this.clearDom(); this.element.appendChild(el); }) .catch(err => { this.clearDom(); }); } } // Register custom element SPZ.defineElement('spz-custom-discount-code', SpzCustomDiscountCode);
Style:  Ghost
Quantity
Free worldwide shipping
Free returns
Sustainably made
Secure payments

Description

Turn your Halloween treats into part of the decoration with a playful two-tier stand shaped like a pair of friendly floating ghosts.

With two generously sized serving levels, glossy black-and-cream details, and a convenient center handle, this seasonal centerpiece gives candies, cookies, cupcakes, and appetizers a delightfully spooky presentation.


Why You’ll Love This Two-Tier Ghost Serving Stand

Playful Ghost-Shaped Design

The stand features two flowing ghost-shaped trays that create a fun and instantly recognizable Halloween silhouette.

Friendly ghost faces keep the design charming and festive, making it perfect for family gatherings and seasonal décor.

• Two coordinated ghost-shaped trays
• Friendly Halloween character faces
• Flowing wavy tray silhouettes
• Fun without being overly scary
• Decorative from multiple angles
• Beautiful even when empty


Space-Saving Two-Tier Presentation

The dual-level design creates a visually appealing vertical display that helps organize treats without crowding the table.

It adds height and structure while keeping snacks easy to view and reach.

• Two distinct serving levels
• Uses vertical table space efficiently
• Reduces buffet-table clutter
• Adds height to dessert displays
• Keeps treats neatly separated
• Improves guest accessibility


Generous Serving Capacity

Designed with a 10-inch upper tray and a larger 12-inch lower tray to hold a wide variety of party foods.

Perfect for desserts, snacks, and mixed appetizer arrangements.

• Approx. 10-inch upper tray
• Approx. 12-inch lower tray
• Holds cookies, cupcakes, candy
• Suitable for fruit and pastries
• More capacity than a single plate
• Ideal for sharing at gatherings


Raised Edges for Cleaner Serving

Each tray includes a raised rim to help keep food neatly in place during serving and display.

The dark edge also enhances the ghost-shaped outline for a finished decorative look.

• Approx. 1.25-inch tray depth
• Helps contain small snacks
• Prevents items from sliding off
• Defines ghost silhouette shape
• Keeps display more organized
• Adds visual contrast detail


⭕ Convenient Center Ring Handle

The top ring handle allows easy positioning of the stand before and during setup.

It also reinforces the vertical structure for a balanced two-tier presentation.

• Easy-grip top ring
• Simple repositioning when needed
• Stable center support structure
• Keeps trays aligned
• Adds decorative metal accent
• Supports balanced display


Charming Halloween Artwork

Subtle bat, star, and dot details decorate both trays, enhancing the Halloween theme without overwhelming the design.

The black-and-cream palette blends easily with other seasonal décor.

• Bat and star illustrations
• Coordinated tray artwork
• Classic black-and-cream style
• Easy to match Halloween décor
• Adds detail without clutter
• Creates seasonal atmosphere


Versatile Food Display

Suitable for a wide range of sweet and savory party foods, making it useful for everyday entertaining.

Perfect for organized snack presentation at gatherings and parties.

• Displays candy and cookies
• Suitable for cupcakes and pastries
• Holds fruit and appetizers
• Works for sweet and savory foods
• Great for self-serve setups
• Ideal for parties and events


Perfect for Halloween Celebrations

A festive serving piece that enhances any Halloween table setup or party display.

Reusable year after year for seasonal entertaining.

• Great for costume parties
• Fun for trick-or-treat night
• Suitable for family gatherings
• Beautiful on buffet tables
• Reusable each season
• Creates a festive centerpiece


A Fun Gift for Halloween Hosts

A creative and practical gift for anyone who enjoys seasonal entertaining or Halloween décor.

Easy to pair with treats or baking supplies for a thoughtful presentation.

• Great for Halloween hosts
• Suitable for bakers and decorators
• Fun housewarming gift
• Easy to pair with snacks
• Thoughtful seasonal gift
• Combines décor and function


⭐ Customer Reviews

⭐⭐⭐⭐⭐
“The centerpiece of our Halloween table”

I filled the upper tray with cupcakes and the lower tray with cookies and candy. The ghost shapes were adorable, and the two levels made the entire table look much more organized.

— Melissa R., Salem, Massachusetts

⭐⭐⭐⭐⭐
“Cute without being too childish”

The black-and-cream design works beautifully with my other Halloween decorations. It feels festive enough for a party but still looks polished on the dining table.

— Amanda T., Austin, Texas

⭐⭐⭐⭐⭐
“More spacious than I expected”

The lower tray held plenty of snacks, and the raised edges helped keep the wrapped candies in place. I also like that it can be displayed as décor when it is not being used for food.

— Jennifer M., Columbus, Ohio


Specifications

  • Product Name: Two-Tier Ghost Serving Stand
  • Product Type: Seasonal tiered serving and display stand
  • Design Theme: Friendly Halloween ghosts
  • Number of Tiers: Two
  • Main Colors: Cream, black, and silver tone
  • Decorative Details: Ghost faces, stars, bats, and dot accents
  • Center Support: Silver-tone vertical post
  • Handle Style: Circular top carrying ring
  • Recommended Use: Candy, cookies, cupcakes, pastries, fruit, appetizers, party favors, and seasonal décor
  • Suitable For: Halloween parties, dessert tables, kitchen islands, dining tables, buffets, and entryway displays

❓ Frequently Asked Questions

Q: How large is the serving stand?
A: The assembled stand measures approximately 9.5 inches tall. The upper tray is approximately 10 inches wide, and the lower tray is approximately 12 inches wide.

Q: What kinds of food can I serve on it?
A: It is suitable for candy, cookies, cupcakes, brownies, pastries, fruit, finger sandwiches, cheese, and other small party foods.

Q: Does the stand require assembly?
A: The center post and tray levels may require simple assembly. Make sure all components are correctly aligned and securely tightened before placing food on the stand.

Q: Can I carry it by the top ring when it is full?
A: The ring is useful for carefully positioning the empty stand. For safety, support the stand from underneath when moving it after food or decorations have been added.

Q: How should I clean the trays?
A: Hand wash the trays gently with mild soap and a soft, non-abrasive sponge. Dry all components thoroughly and avoid placing the stand in a dishwasher.