// backend/products.jsw import {ok, notFound, serverError} from 'wix-http-functions'; import wixData from 'wix-data'; export async function get_products(request) { try { const options = { suppressAuth: true // Careful with this! Implement proper authentication }; let query = wixData.query("Products"); // Assuming your collection is named "Products" // Add filtering, sorting, and pagination based on request.query parameters const results = await query.find(options); const response = { headers: { "Content-Type": "application/json", }, body: { products: results.items, totalCount: results.totalCount, // For pagination // ... other relevant data }, }; return ok(response); } catch (error) { return serverError({body: {error: error.message}}); } } // Similar functions for POST, PUT, DELETE // Page Code (Example - Product Display) import {fetch} from 'wix-fetch'; $w.onReady(async function () { // Fetch products from the API const response = await fetch("/_functions/products", {method: 'get'}); // Use the correct endpoint URL if (response.ok) { const data = await response.json(); // Populate a repeater with the product data $w("#productRepeater").data = data.products; $w("#productRepeater").onItemReady(($item, itemData, index) => { // Set the repeater item elements based on the product data $item("#productName").text = itemData.name; $item("#productDescription").text = itemData.description; $item("#productImage").src = itemData.imageURL; // Assuming you have an Image element $item("#productPrice").text = `$${itemData.price.toFixed(2)}`; $item("#addToCartButton").onClick(() => { // Handle adding the product to the cart (implementation depends on your cart logic) console.log(`Adding ${itemData.name} to cart`); // You might use Wix Stores for cart functionality, or implement your own }); // ... set other elements (THC, CBD, etc.) ... }); } else { console.error("Error fetching products:", response.status); // Handle the error (e.g., display an error message to the user) } // Set up event handlers for filtering and sorting $w("#typeFilter").onChange(() => filterProducts()); // Dropdown for product type $w("#strainSearch").onInput(() => filterProducts()); // Input for strain search $w("#sortSelect").onChange(() => filterProducts()); //Implement filter and sorting of products async function filterProducts() { const type = $w("#typeFilter").value; const strain = $w("#strainSearch").value; const sortBy = $w("#sortSelect").value; let url = "/_functions/products?"; if (type) url += `type=${type}&`; if (strain) url += `strain=${strain}&`; if (sortBy) url += `sort=${sortBy}&`; //Remove the last char from string if '&' url = url.slice(0, -1); const response = await fetch(url, { method: 'get' }); //Re-populate the repeater with the response if (response.ok) { const data = await response.json(); // Populate a repeater with the product data $w("#productRepeater").data = data.products; $w("#productRepeater").onItemReady(($item, itemData, index) => { // Set the repeater item elements based on the product data $item("#productName").text = itemData.name; $item("#productDescription").text = itemData.description; $item("#productImage").src = itemData.imageURL; // Assuming you have an Image element $item("#productPrice").text = `$${itemData.price.toFixed(2)}`; $item("#addToCartButton").onClick(() => { // Handle adding the product to the cart (implementation depends on your cart logic) console.log(`Adding ${itemData.name} to cart`); // You might use Wix Stores for cart functionality, or implement your own }); // ... set other elements (THC, CBD, etc.) ... }); } else { console.error("Error fetching products:", response.status); // Handle the error (e.g., display an error message to the user) } } }); // backend/cannabisAPI.jsw import {ok, notFound, badRequest, serverError, forbidden} from 'wix-http-functions'; import wixData from 'wix-data'; import {fetch} from 'wix-fetch'; // --- Helper Functions --- // VERY BASIC scraping example. DO NOT RELY ON THIS FOR PRODUCTION. async function scrapeProductData(url) { try { const response = await fetch(url, {method: 'get'}); if (!response.ok) { console.error(`Scraping failed for ${url}: ${response.status}`); return null; } const html = await response.text(); // *** Extremely simplified parsing - You'll need MUCH more robust logic *** // This is just to illustrate the *concept*. Use a library like Cheerio // on a separate server for real-world scraping. const productName = html.match(/(.*?)<\/h1>/)?.[1]; // Extremely fragile! const productDescription = html.match(/(.*?)<\/p>/)?.[1]; // Extremely fragile! if (!productName) return null return { name: productName, description: productDescription, // ... extract other data (THC, CBD, image URL, etc.) ... }; } catch (error) { console.error(`Error scraping ${url}:`, error); return null; } } // --- API Endpoints --- // Get all products (with filtering and pagination) export async function get_products(request) { try { // --- AGE VERIFICATION (ESSENTIAL - Integrate with a service!) --- // You MUST verify the user's age before allowing access to product data. // This is a placeholder. Replace with a real age verification check. // const ageVerified = await verifyUserAge(request); // Hypothetical function // if (!ageVerified) { // return forbidden({body: {error: 'Age verification failed'}}); // } const options = { suppressAuth: true // Only if age verification is handled elsewhere! }; let query = wixData.query("Products"); // Filtering (example - add more based on your needs) if (request.query.type) { query = query.eq("Type", request.query.type); // e.g., ?type=flower } if (request.query.strain) { query = query.contains("Strain", request.query.strain); // e.g., ?strain=kush } if (request.query.brand) { query = query.contains("Brand", request.query.brand); } // Pagination const limit = parseInt(request.query.limit) || 20; const skip = parseInt(request.query.offset) || 0; query = query.limit(limit).skip(skip); const results = await query.find(options); return ok({ headers: {"Content-Type": "application/json"}, body: { products: results.items, totalCount: results.totalCount, }, }); } catch (error) { return serverError({body: {error: error.message}}); } } // Get a single product by ID export async function get_products_id(request) { try { const options = { suppressAuth: true // Only if age verification is handled elsewhere! }; const productId = request.path[0]; const product = await wixData.get("Products", productId, options); if (!product) { return notFound({body: {error: 'Product not found'}}); } return ok({ headers: {"Content-Type": "application/json"}, body: product, }); } catch (error) { return serverError({body: {error: error.message}}); } } // Add a product (ADMIN ONLY - Requires authentication) export async function post_products(request) { try { // --- Authentication (ESSENTIAL) --- // You MUST authenticate the user (e.g., using Wix Members Area) // and check if they have admin privileges before allowing product creation. // This is a placeholder. Implement proper authentication! // if (!isAdminUser(request)) { // return forbidden({body: {error: 'Unauthorized'}}); // } const options = { suppressAuth: true }; const productData = await request.body.json(); // --- Data Validation (ESSENTIAL) --- // Validate ALL fields (name, description, THC, CBD, etc.) // to ensure data integrity and prevent errors. if (!productData.name || !productData.description || !productData.price) { return badRequest({body: {error: 'Missing required fields'}}); } // --- Scrape Data (Optional - Use with caution) --- // If a scraping URL is provided, attempt to scrape additional data. // if (productData.scrapeUrl) { // const scrapedData = await scrapeProductData(productData.scrapeUrl); // if (scrapedData) { // // Merge scraped data with provided data (prioritize provided data) // productData = {...scrapedData, ...productData}; // } // } const toSave = { "title": productData.name, // Use "title" for Wix Data primary field ...productData, // Spread the rest of the product data }; const result = await wixData.insert("Products", toSave, options); return ok({ headers: {"Content-Type": "application/json"}, body: result, }); } catch (error) { return serverError({body: {error: error.message}}); } } // --- Other Endpoints (Orders, Customers, Reviews) --- // Implement similar endpoints for creating, retrieving, updating, // and deleting orders, customers, and reviews. Include robust // authentication and authorization as needed. Remember age verification // for all customer-related actions. //Example function to get orders. export async function get_orders(request) { try { const options = { suppressAuth: true //Requires secure authentication to implement }; let query = wixData.query("Orders"); const results = await query.find(options); return ok({ headers: {"Content-Type": "application/json"}, body: { products: results.items, totalCount: results.totalCount, }, }); } catch (error) { return serverError({body: {error: error.message}}); } } // --- Scheduled Task (Example - for scraping) --- // You can use Wix's Scheduled Jobs to run scraping tasks periodically. // This is a VERY basic example. You'll need a much more sophisticated // solution for real-world scraping, possibly involving a separate server. // export async function scheduledScrape() { // const sitesToScrape = ['https://example.com/products', 'https://another-site.com/menu']; // for (const url of sitesToScrape) { // const scrapedData = await scrapeProductData(url); // if (scrapedData) { // // Process and save the scraped data to your "Products" collection. // // Handle potential duplicates, updates, etc. // } // } // }
top of page

About Black Cherry Gelato

 

Black Cherry Gelato might be the best dessert strain you’ve ever indulged in, if you can find her. Bred by unknown individuals, this cross between Acai and Black Cherry Funk comes across with an indica-dominant profile that puts up a fight. Robust flavors are plentiful, however actually locating this bud proves to be intensely difficult for most.

 

Not much is known about Black Cherry Gelato but there is one thing for certain — she comes in strong with a 26% THC potency that can be hard to handle for anyone who is less than experienced. Each dark green nug is practically dripping with amber-colored trichomes and features thin orange pistils that poke through this glittering exterior. Bolder on your tongue than you might expect, cherries and berries are the dominant flavors and aromas, however both herbs and skunk also play a role to balance out this bud’s profile.

 

For most, Black Cherry Gelato takes smokers on a gentle ride through a combination of cerebral and physical effects that are ideal for evening time. Your experience will likely start with a sensation of pure relaxation coupled with euphoria, as your mind will be cleared of all worry and a smile will be plastered to your face. As your happiness grows, it’s not uncommon to start feeling tingles from head to toe. Before you know it, you might even find yourself glued to your couch, unable to move. If that’s the case, it’s best not to fight this gal’s strength and instead give in to a blissful slumber.

 

Individuals who love to treat medical issues with cannabis will find Black Cherry Gelato to be of particular interest, as her high potency levels often treat ailments with ease. Physical pain is no match for her relaxing abilities and if you struggle with anxiety or depression, it’s possible that her happy-go-lucky attitude will rid you of any cares you once had. If you smoke enough of this gal, it’s likely that insomnia will also become a thing of the past too, but make sure you’re aware of your own tolerance before you go on a bender.

 

Indica lovers would be thrilled to have Black Cherry Gelato growing in their own backyard, but sadly, no one knows much about how to tend to her at home. Finding nugs of this bud is difficult enough on the retail level, let alone tracking down seeds or clones for personal use. If you do happen to come across the opportunity to grow her yourself, we’d highly recommend consulting with an experienced grower before you do anything else.

 

Why is it that the seemingly best strains on the market are the hardest to find? No one may ever know the answer, but the least we can do is dream of the day that Black Cherry Gelato becomes more readily available across the United States. Between her luscious flavors and her reported effects, it’s as if there’s no telling how amazing this bud truly is.

 

Common Usage

 

Depressed8/10

Anxiety6/10

Insomnia4/10

Migraines2/10

Pain10/10

 

Typical Effects

 

Relaxed6/10

Sleepy4/10

Happy8/10

Sedated2/10

Euphoric

BLACK CHERRY GELATO

$70.00Price
    bottom of page
    // backend/cannabisAPI.jsw import {ok, notFound, badRequest, serverError, forbidden} from 'wix-http-functions'; import wixData from 'wix-data'; import {fetch} from 'wix-fetch'; // --- Helper Functions --- // VERY BASIC scraping example. DO NOT RELY ON THIS FOR PRODUCTION. async function scrapeProductData(url) { try { const response = await fetch(url, {method: 'get'}); if (!response.ok) { console.error(`Scraping failed for ${url}: ${response.status}`); return null; } const html = await response.text(); // *** Extremely simplified parsing - You'll need MUCH more robust logic *** // This is just to illustrate the *concept*. Use a library like Cheerio // on a separate server for real-world scraping. const productName = html.match(/(.*?)<\/h1>/)?.[1]; // Extremely fragile! const productDescription = html.match(/(.*?)<\/p>/)?.[1]; // Extremely fragile! if (!productName) return null return { name: productName, description: productDescription, // ... extract other data (THC, CBD, image URL, etc.) ... }; } catch (error) { console.error(`Error scraping ${url}:`, error); return null; } } // --- API Endpoints --- // Get all products (with filtering and pagination) export async function get_products(request) { try { // --- AGE VERIFICATION (ESSENTIAL - Integrate with a service!) --- // You MUST verify the user's age before allowing access to product data. // This is a placeholder. Replace with a real age verification check. // const ageVerified = await verifyUserAge(request); // Hypothetical function // if (!ageVerified) { // return forbidden({body: {error: 'Age verification failed'}}); // } const options = { suppressAuth: true // Only if age verification is handled elsewhere! }; let query = wixData.query("Products"); // Filtering (example - add more based on your needs) if (request.query.type) { query = query.eq("Type", request.query.type); // e.g., ?type=flower } if (request.query.strain) { query = query.contains("Strain", request.query.strain); // e.g., ?strain=kush } if (request.query.brand) { query = query.contains("Brand", request.query.brand); } // Pagination const limit = parseInt(request.query.limit) || 20; const skip = parseInt(request.query.offset) || 0; query = query.limit(limit).skip(skip); const results = await query.find(options); return ok({ headers: {"Content-Type": "application/json"}, body: { products: results.items, totalCount: results.totalCount, }, }); } catch (error) { return serverError({body: {error: error.message}}); } } // Get a single product by ID export async function get_products_id(request) { try { const options = { suppressAuth: true // Only if age verification is handled elsewhere! }; const productId = request.path[0]; const product = await wixData.get("Products", productId, options); if (!product) { return notFound({body: {error: 'Product not found'}}); } return ok({ headers: {"Content-Type": "application/json"}, body: product, }); } catch (error) { return serverError({body: {error: error.message}}); } } // Add a product (ADMIN ONLY - Requires authentication) export async function post_products(request) { try { // --- Authentication (ESSENTIAL) --- // You MUST authenticate the user (e.g., using Wix Members Area) // and check if they have admin privileges before allowing product creation. // This is a placeholder. Implement proper authentication! // if (!isAdminUser(request)) { // return forbidden({body: {error: 'Unauthorized'}}); // } const options = { suppressAuth: true }; const productData = await request.body.json(); // --- Data Validation (ESSENTIAL) --- // Validate ALL fields (name, description, THC, CBD, etc.) // to ensure data integrity and prevent errors. if (!productData.name || !productData.description || !productData.price) { return badRequest({body: {error: 'Missing required fields'}}); } // --- Scrape Data (Optional - Use with caution) --- // If a scraping URL is provided, attempt to scrape additional data. // if (productData.scrapeUrl) { // const scrapedData = await scrapeProductData(productData.scrapeUrl); // if (scrapedData) { // // Merge scraped data with provided data (prioritize provided data) // productData = {...scrapedData, ...productData}; // } // } const toSave = { "title": productData.name, // Use "title" for Wix Data primary field ...productData, // Spread the rest of the product data }; const result = await wixData.insert("Products", toSave, options); return ok({ headers: {"Content-Type": "application/json"}, body: result, }); } catch (error) { return serverError({body: {error: error.message}}); } } // --- Other Endpoints (Orders, Customers, Reviews) --- // Implement similar endpoints for creating, retrieving, updating, // and deleting orders, customers, and reviews. Include robust // authentication and authorization as needed. Remember age verification // for all customer-related actions. //Example function to get orders. export async function get_orders(request) { try { const options = { suppressAuth: true //Requires secure authentication to implement }; let query = wixData.query("Orders"); const results = await query.find(options); return ok({ headers: {"Content-Type": "application/json"}, body: { products: results.items, totalCount: results.totalCount, }, }); } catch (error) { return serverError({body: {error: error.message}}); } } // --- Scheduled Task (Example - for scraping) --- // You can use Wix's Scheduled Jobs to run scraping tasks periodically. // This is a VERY basic example. You'll need a much more sophisticated // solution for real-world scraping, possibly involving a separate server. // export async function scheduledScrape() { // const sitesToScrape = ['https://example.com/products', 'https://another-site.com/menu']; // for (const url of sitesToScrape) { // const scrapedData = await scrapeProductData(url); // if (scrapedData) { // // Process and save the scraped data to your "Products" collection. // // Handle potential duplicates, updates, etc. // } // } // }