Compare commits
63 Commits
fix/ci-git
...
fix/crysta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2a3a05ea1 | ||
|
|
0af6db4461 | ||
|
|
8995c60d88 | ||
|
|
0c260f69b0 | ||
|
|
63b9372372 | ||
|
|
aaff332937 | ||
|
|
964548ba38 | ||
|
|
cf05d8cad1 | ||
|
|
05dca8f847 | ||
|
|
27328c9106 | ||
|
|
b3dd9a8e23 | ||
|
|
1cd6c15cb3 | ||
|
|
3554578554 | ||
|
|
3962807fc6 | ||
|
|
32054ddcce | ||
|
|
5905699ca1 | ||
|
|
eb8e2a89c4 | ||
|
|
8286aebf4e | ||
|
|
4cff4af841 | ||
|
|
8abcd3291e | ||
|
|
a7c3eb4183 | ||
|
|
1ed62fe0de | ||
|
|
160b312ca5 | ||
|
|
6d22a99259 | ||
|
|
febfd75016 | ||
|
|
fbb72f902b | ||
|
|
fd11ae0fe0 | ||
|
|
16c5c455fa | ||
|
|
df587fdda3 | ||
|
|
3fb5747aa2 | ||
|
|
33c9420b00 | ||
|
|
37204edfd7 | ||
|
|
8d9725b501 | ||
|
|
6cf8ad1854 | ||
|
|
58f787feb0 | ||
|
|
970ce05846 | ||
|
|
672b0d5f6b | ||
|
|
4415194b28 | ||
|
|
213b0ef8f2 | ||
|
|
13dbe046e1 | ||
|
|
592df4de44 | ||
|
|
ae581b4d5c | ||
|
|
8a8f83cc0c | ||
|
|
722904d487 | ||
|
|
ddc84f6730 | ||
|
|
2c510844f0 | ||
|
|
105a1e8ce0 | ||
|
|
7e06ff3488 | ||
|
|
aed1e62c65 | ||
|
|
f9f1b8dc46 | ||
|
|
89d3a54988 | ||
|
|
0c60e5c519 | ||
|
|
1ecc4a916b | ||
|
|
d4ec8c16f3 | ||
|
|
f9d7573cb4 | ||
|
|
e48e9c9b82 | ||
|
|
afbb1ba79c | ||
|
|
08f5a3adac | ||
|
|
e62ea5c809 | ||
|
|
8d43953cad | ||
|
|
a628f2b207 | ||
|
|
367daadfe9 | ||
|
|
b33ebac9bf |
203
app/Filament/Pages/CannaiqSettings.php
Normal file
203
app/Filament/Pages/CannaiqSettings.php
Normal file
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Services\Cannaiq\CannaiqClient;
|
||||
use Filament\Forms\Components\Placeholder;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Concerns\InteractsWithForms;
|
||||
use Filament\Forms\Contracts\HasForms;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Schemas\Components\Section;
|
||||
use Filament\Schemas\Schema;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\HtmlString;
|
||||
|
||||
class CannaiqSettings extends Page implements HasForms
|
||||
{
|
||||
use InteractsWithForms;
|
||||
|
||||
protected static \BackedEnum|string|null $navigationIcon = 'heroicon-o-chart-bar-square';
|
||||
|
||||
protected string $view = 'filament.pages.cannaiq-settings';
|
||||
|
||||
protected static \UnitEnum|string|null $navigationGroup = 'Integrations';
|
||||
|
||||
protected static ?string $navigationLabel = 'CannaiQ';
|
||||
|
||||
protected static ?int $navigationSort = 1;
|
||||
|
||||
protected static ?string $title = 'CannaiQ Settings';
|
||||
|
||||
protected static ?string $slug = 'cannaiq-settings';
|
||||
|
||||
public ?array $data = [];
|
||||
|
||||
public static function canAccess(): bool
|
||||
{
|
||||
return auth('admin')->check();
|
||||
}
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
$this->form->fill([
|
||||
'base_url' => config('services.cannaiq.base_url'),
|
||||
'api_key' => '', // Never show the actual key
|
||||
'cache_ttl' => config('services.cannaiq.cache_ttl', 7200),
|
||||
]);
|
||||
}
|
||||
|
||||
public function form(Schema $schema): Schema
|
||||
{
|
||||
$apiKeyConfigured = ! empty(config('services.cannaiq.api_key'));
|
||||
$baseUrl = config('services.cannaiq.base_url');
|
||||
|
||||
return $schema
|
||||
->schema([
|
||||
Section::make('CannaiQ Integration')
|
||||
->description('CannaiQ is the Marketing Intelligence Engine that powers competitive analysis, pricing intelligence, and promotional recommendations.')
|
||||
->schema([
|
||||
Placeholder::make('status')
|
||||
->label('Connection Status')
|
||||
->content(function () use ($apiKeyConfigured, $baseUrl) {
|
||||
$statusHtml = '<div class="space-y-2">';
|
||||
|
||||
// API Key status
|
||||
if ($apiKeyConfigured) {
|
||||
$statusHtml .= '<div class="flex items-center gap-2 text-success-600 dark:text-success-400">'.
|
||||
'<span class="text-lg">✓</span>'.
|
||||
'<span>API Key configured</span>'.
|
||||
'</div>';
|
||||
} else {
|
||||
$statusHtml .= '<div class="flex items-center gap-2 text-warning-600 dark:text-warning-400">'.
|
||||
'<span class="text-lg">⚠</span>'.
|
||||
'<span>API Key not configured (using trusted origin auth)</span>'.
|
||||
'</div>';
|
||||
}
|
||||
|
||||
// Base URL
|
||||
$statusHtml .= '<div class="text-sm text-gray-500 dark:text-gray-400">'.
|
||||
'Base URL: <code class="bg-gray-100 dark:bg-gray-800 px-1 rounded">'.$baseUrl.'</code>'.
|
||||
'</div>';
|
||||
|
||||
$statusHtml .= '</div>';
|
||||
|
||||
return new HtmlString($statusHtml);
|
||||
}),
|
||||
|
||||
Placeholder::make('features')
|
||||
->label('Features Enabled')
|
||||
->content(new HtmlString(
|
||||
'<div class="rounded-lg border border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-900 p-4">'.
|
||||
'<ul class="list-disc list-inside text-sm text-gray-600 dark:text-gray-400 space-y-1">'.
|
||||
'<li><strong>Brand Analysis</strong> - Market positioning, SKU velocity, shelf opportunities</li>'.
|
||||
'<li><strong>Marketing Intelligence</strong> - Competitive insights and recommendations</li>'.
|
||||
'<li><strong>Promo Recommendations</strong> - AI-powered promotional strategies</li>'.
|
||||
'<li><strong>Store Playbook</strong> - Actionable insights for retail partners</li>'.
|
||||
'</ul>'.
|
||||
'</div>'
|
||||
)),
|
||||
]),
|
||||
|
||||
Section::make('Configuration')
|
||||
->description('CannaiQ is configured via environment variables. Update your .env file to change these settings.')
|
||||
->schema([
|
||||
TextInput::make('base_url')
|
||||
->label('Base URL')
|
||||
->disabled()
|
||||
->helperText('Set via CANNAIQ_BASE_URL environment variable'),
|
||||
|
||||
TextInput::make('cache_ttl')
|
||||
->label('Cache TTL (seconds)')
|
||||
->disabled()
|
||||
->helperText('Set via CANNAIQ_CACHE_TTL environment variable. Default: 7200 (2 hours)'),
|
||||
|
||||
Placeholder::make('env_example')
|
||||
->label('Environment Variables')
|
||||
->content(new HtmlString(
|
||||
'<div class="rounded-lg bg-gray-900 text-gray-100 p-4 font-mono text-sm overflow-x-auto">'.
|
||||
'<div class="text-gray-400"># CannaiQ Configuration</div>'.
|
||||
'<div>CANNAIQ_BASE_URL=https://cannaiq.co/api/v1</div>'.
|
||||
'<div>CANNAIQ_API_KEY=your-api-key-here</div>'.
|
||||
'<div>CANNAIQ_CACHE_TTL=7200</div>'.
|
||||
'</div>'
|
||||
)),
|
||||
])
|
||||
->collapsed(),
|
||||
|
||||
Section::make('Business Access')
|
||||
->description('CannaiQ features must be enabled per-business in the Business settings.')
|
||||
->schema([
|
||||
Placeholder::make('business_info')
|
||||
->label('')
|
||||
->content(new HtmlString(
|
||||
'<div class="rounded-lg border border-info-200 bg-info-50 dark:border-info-800 dark:bg-info-950 p-4">'.
|
||||
'<div class="flex items-start gap-3">'.
|
||||
'<span class="text-info-600 dark:text-info-400 text-lg">ⓘ</span>'.
|
||||
'<div class="text-sm">'.
|
||||
'<p class="font-medium text-info-800 dark:text-info-200">How to enable CannaiQ for a business:</p>'.
|
||||
'<ol class="list-decimal list-inside mt-2 text-info-700 dark:text-info-300 space-y-1">'.
|
||||
'<li>Go to <strong>Users → Businesses</strong></li>'.
|
||||
'<li>Edit the business</li>'.
|
||||
'<li>Go to the <strong>Integrations</strong> tab</li>'.
|
||||
'<li>Toggle <strong>Enable CannaiQ</strong></li>'.
|
||||
'</ol>'.
|
||||
'</div>'.
|
||||
'</div>'.
|
||||
'</div>'
|
||||
)),
|
||||
]),
|
||||
])
|
||||
->statePath('data');
|
||||
}
|
||||
|
||||
public function testConnection(): void
|
||||
{
|
||||
try {
|
||||
$client = app(CannaiqClient::class);
|
||||
|
||||
// Try to fetch something from the API to verify connection
|
||||
// We'll use a simple health check or fetch minimal data
|
||||
$response = $client->getBrandAnalysis('test-brand', 'test-business');
|
||||
|
||||
// If we get here without exception, connection works
|
||||
// (even if the response is empty/error from CannaiQ side)
|
||||
Notification::make()
|
||||
->title('Connection Test')
|
||||
->body('Successfully connected to CannaiQ API')
|
||||
->success()
|
||||
->send();
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Notification::make()
|
||||
->title('Connection Failed')
|
||||
->body($e->getMessage())
|
||||
->danger()
|
||||
->send();
|
||||
}
|
||||
}
|
||||
|
||||
public function clearCache(): void
|
||||
{
|
||||
// Clear all CannaiQ-related cache keys
|
||||
$patterns = [
|
||||
'cannaiq:*',
|
||||
'brand_analysis:*',
|
||||
];
|
||||
|
||||
$cleared = 0;
|
||||
foreach ($patterns as $pattern) {
|
||||
// Note: This is a simplified clear - in production you might want
|
||||
// to use Redis SCAN for pattern matching
|
||||
Cache::forget($pattern);
|
||||
$cleared++;
|
||||
}
|
||||
|
||||
Notification::make()
|
||||
->title('Cache Cleared')
|
||||
->body('CannaiQ cache has been cleared')
|
||||
->success()
|
||||
->send();
|
||||
}
|
||||
}
|
||||
@@ -701,17 +701,6 @@ class BusinessResource extends Resource
|
||||
}),
|
||||
]),
|
||||
|
||||
// ===== CANNAIQ SECTION =====
|
||||
// CannaiQ Marketing Intelligence Engine
|
||||
Section::make('CannaiQ')
|
||||
->description('CannaiQ is the Marketing Intelligence Engine that powers competitive analysis, pricing intelligence, and promotional recommendations.')
|
||||
->schema([
|
||||
Toggle::make('cannaiq_enabled')
|
||||
->label('Enable CannaiQ')
|
||||
->helperText('When enabled, this business gets access to Intelligence and Promos features under the Growth menu.')
|
||||
->default(false),
|
||||
]),
|
||||
|
||||
// ===== SUITE ASSIGNMENT SECTION =====
|
||||
// Suites control feature access (menus, screens, capabilities)
|
||||
Section::make('Suite Assignment')
|
||||
@@ -863,6 +852,40 @@ class BusinessResource extends Resource
|
||||
]),
|
||||
]),
|
||||
|
||||
// ===== INTEGRATIONS TAB =====
|
||||
// Third-party service integrations
|
||||
Tab::make('Integrations')
|
||||
->icon('heroicon-o-link')
|
||||
->schema([
|
||||
// ===== CANNAIQ SECTION =====
|
||||
Section::make('CannaiQ')
|
||||
->description('CannaiQ is the Marketing Intelligence Engine that powers competitive analysis, pricing intelligence, and promotional recommendations.')
|
||||
->schema([
|
||||
Toggle::make('cannaiq_enabled')
|
||||
->label('Enable CannaiQ')
|
||||
->helperText('When enabled, this business gets access to Brand Analysis, Intelligence, and Promos features.')
|
||||
->default(false),
|
||||
|
||||
Forms\Components\Placeholder::make('cannaiq_info')
|
||||
->label('')
|
||||
->content(new \Illuminate\Support\HtmlString(
|
||||
'<div class="rounded-lg border border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-900 p-4 text-sm">'.
|
||||
'<div class="font-medium text-gray-700 dark:text-gray-300 mb-2">CannaiQ Features</div>'.
|
||||
'<ul class="list-disc list-inside text-gray-600 dark:text-gray-400 space-y-1">'.
|
||||
'<li>Brand Analysis - Market positioning, SKU velocity, shelf opportunities</li>'.
|
||||
'<li>Marketing Intelligence - Competitive insights and recommendations</li>'.
|
||||
'<li>Promo Recommendations - AI-powered promotional strategies</li>'.
|
||||
'</ul>'.
|
||||
'<div class="mt-3 pt-3 border-t border-gray-200 dark:border-gray-700">'.
|
||||
'<a href="https://cannaiq.co" target="_blank" class="text-primary-600 hover:text-primary-500 dark:text-primary-400 font-medium inline-flex items-center gap-1">'.
|
||||
'Visit CannaiQ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path></svg>'.
|
||||
'</a>'.
|
||||
'</div>'.
|
||||
'</div>'
|
||||
)),
|
||||
]),
|
||||
]),
|
||||
|
||||
// ===== LEGACY MODULES TAB =====
|
||||
// These flags are kept for backward compatibility.
|
||||
// The recommended way to configure access is via Suites above.
|
||||
|
||||
@@ -82,6 +82,18 @@ class OrderController extends Controller
|
||||
|
||||
$orders = $query->paginate(20)->withQueryString();
|
||||
|
||||
// Return JSON for AJAX/API requests (live search)
|
||||
if ($request->wantsJson()) {
|
||||
return response()->json([
|
||||
'data' => $orders->map(fn ($o) => [
|
||||
'order_number' => $o->order_number,
|
||||
'name' => $o->order_number.' - '.$o->business->name,
|
||||
'customer' => $o->business->name,
|
||||
'status' => $o->status,
|
||||
])->values()->toArray(),
|
||||
]);
|
||||
}
|
||||
|
||||
return view('seller.orders.index', compact('orders', 'business'));
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ class BatchController extends Controller
|
||||
->where('quantity_available', '>', 0)
|
||||
->where('is_active', true)
|
||||
->where('is_quarantined', false)
|
||||
->with('component')
|
||||
->with('product')
|
||||
->orderBy('batch_number')
|
||||
->get()
|
||||
->map(function ($batch) {
|
||||
|
||||
@@ -333,11 +333,14 @@ class BrandController extends Controller
|
||||
{
|
||||
$perPage = $request->get('per_page', 50);
|
||||
$productsPaginator = $brand->products()
|
||||
->whereNotNull('hashid')
|
||||
->where('hashid', '!=', '')
|
||||
->with('images')
|
||||
->orderBy('created_at', 'desc')
|
||||
->paginate($perPage);
|
||||
|
||||
$products = $productsPaginator->getCollection()
|
||||
->filter(fn ($product) => ! empty($product->hashid))
|
||||
->map(function ($product) use ($business, $brand) {
|
||||
$product->setRelation('brand', $brand);
|
||||
|
||||
@@ -354,7 +357,8 @@ class BrandController extends Controller
|
||||
'edit_url' => route('seller.business.products.edit', [$business->slug, $product->hashid]),
|
||||
'preview_url' => route('seller.business.products.preview', [$business->slug, $product->hashid]),
|
||||
];
|
||||
});
|
||||
})
|
||||
->values();
|
||||
|
||||
return [
|
||||
'products' => $products,
|
||||
@@ -1948,4 +1952,141 @@ class BrandController extends Controller
|
||||
'visibilityIssues' => $visibilityIssues,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Display brand market analysis / intelligence page.
|
||||
*
|
||||
* v4 endpoint with optional store_id filtering for per-store projections.
|
||||
*/
|
||||
public function analysis(Request $request, Business $business, Brand $brand)
|
||||
{
|
||||
$this->authorize('view', [$brand, $business]);
|
||||
|
||||
// CannaiQ must be enabled to access Brand Analysis
|
||||
if (! $business->cannaiq_enabled) {
|
||||
return view('seller.brands.analysis-disabled', [
|
||||
'business' => $business,
|
||||
'brand' => $brand,
|
||||
]);
|
||||
}
|
||||
|
||||
// v4: Get optional store_id filter for shelf value projections
|
||||
$storeId = $request->query('store_id');
|
||||
|
||||
$analysisService = app(\App\Services\Cannaiq\BrandAnalysisService::class);
|
||||
$analysis = $analysisService->getAnalysis($brand, $business, $storeId);
|
||||
|
||||
// Load all brands for the brand selector
|
||||
$brands = $business->brands()
|
||||
->where('is_active', true)
|
||||
->withCount('products')
|
||||
->orderBy('name')
|
||||
->get();
|
||||
|
||||
// Build store list from placement data for store selector
|
||||
$storeList = [];
|
||||
if ((bool) $business->cannaiq_enabled) {
|
||||
$placementStores = $analysis->placement['stores'] ?? $analysis->placement ?? [];
|
||||
$whitespaceStores = $analysis->placement['whitespaceStores'] ?? [];
|
||||
|
||||
foreach ($placementStores as $store) {
|
||||
$storeList[] = [
|
||||
'id' => $store['storeId'] ?? '',
|
||||
'name' => $store['storeName'] ?? 'Unknown',
|
||||
'state' => $store['state'] ?? null,
|
||||
];
|
||||
}
|
||||
foreach ($whitespaceStores as $store) {
|
||||
$storeList[] = [
|
||||
'id' => $store['storeId'] ?? '',
|
||||
'name' => $store['storeName'] ?? 'Unknown',
|
||||
'state' => $store['state'] ?? null,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return view('seller.brands.analysis', [
|
||||
'business' => $business,
|
||||
'brand' => $brand,
|
||||
'brands' => $brands,
|
||||
'analysis' => $analysis,
|
||||
'cannaiqEnabled' => (bool) $business->cannaiq_enabled,
|
||||
'storeList' => $storeList,
|
||||
'selectedStoreId' => $storeId,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh brand analysis data (clears cache and re-fetches).
|
||||
*/
|
||||
public function analysisRefresh(Request $request, Business $business, Brand $brand)
|
||||
{
|
||||
$this->authorize('view', [$brand, $business]);
|
||||
|
||||
// CannaiQ must be enabled to refresh analysis
|
||||
if (! $business->cannaiq_enabled) {
|
||||
if ($request->wantsJson()) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'CannaiQ is not enabled for this business. Please contact support.',
|
||||
], 403);
|
||||
}
|
||||
|
||||
return back()->with('error', 'CannaiQ is not enabled for this business.');
|
||||
}
|
||||
|
||||
$analysisService = app(\App\Services\Cannaiq\BrandAnalysisService::class);
|
||||
$analysis = $analysisService->refreshAnalysis($brand, $business);
|
||||
|
||||
if ($request->wantsJson()) {
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Analysis data refreshed',
|
||||
'data' => $analysis->toArray(),
|
||||
]);
|
||||
}
|
||||
|
||||
return redirect()
|
||||
->route('seller.business.brands.analysis', [$business->slug, $brand->hashid])
|
||||
->with('success', 'Analysis data refreshed successfully');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get store-level playbook for a specific store.
|
||||
*
|
||||
* Returns targeted recommendations for a single retail account.
|
||||
*/
|
||||
public function storePlaybook(Request $request, Business $business, Brand $brand, string $storeId)
|
||||
{
|
||||
$this->authorize('view', [$brand, $business]);
|
||||
|
||||
if (! $business->cannaiq_enabled) {
|
||||
if ($request->wantsJson()) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'CannaiQ is not enabled for this business',
|
||||
], 403);
|
||||
}
|
||||
|
||||
return back()->with('error', 'CannaiQ is not enabled for this business');
|
||||
}
|
||||
|
||||
$analysisService = app(\App\Services\Cannaiq\BrandAnalysisService::class);
|
||||
$playbook = $analysisService->getStorePlaybook($brand, $business, $storeId);
|
||||
|
||||
if ($request->wantsJson()) {
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => $playbook,
|
||||
]);
|
||||
}
|
||||
|
||||
// For non-JSON requests, redirect to analysis page with store selected
|
||||
return redirect()
|
||||
->route('seller.business.brands.analysis', [
|
||||
$business->slug,
|
||||
$brand->hashid,
|
||||
'store_id' => $storeId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,10 @@ use App\Models\Crm\CrmEvent;
|
||||
use App\Models\Crm\CrmQuote;
|
||||
use App\Models\Crm\CrmTask;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Location;
|
||||
use App\Models\SalesOpportunity;
|
||||
use App\Models\SendMenuLog;
|
||||
use App\Services\Cannaiq\CannaiqClient;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class AccountController extends Controller
|
||||
@@ -43,6 +45,18 @@ class AccountController extends Controller
|
||||
|
||||
$accounts = $query->orderBy('name')->paginate(25);
|
||||
|
||||
// Return JSON for AJAX/API requests (live search)
|
||||
if ($request->wantsJson()) {
|
||||
return response()->json([
|
||||
'data' => $accounts->map(fn ($a) => [
|
||||
'slug' => $a->slug,
|
||||
'name' => $a->name,
|
||||
'email' => $a->business_email,
|
||||
'status' => $a->status,
|
||||
])->values()->toArray(),
|
||||
]);
|
||||
}
|
||||
|
||||
return view('seller.crm.accounts.index', compact('business', 'accounts'));
|
||||
}
|
||||
|
||||
@@ -90,7 +104,7 @@ class AccountController extends Controller
|
||||
'status' => 'approved', // Auto-approve customers created by sellers
|
||||
]);
|
||||
|
||||
// Create primary contact if provided
|
||||
// Create contact if provided
|
||||
if (! empty($validated['contact_name'])) {
|
||||
$account->contacts()->create([
|
||||
'first_name' => explode(' ', $validated['contact_name'])[0],
|
||||
@@ -98,7 +112,6 @@ class AccountController extends Controller
|
||||
'email' => $validated['contact_email'] ?? null,
|
||||
'phone' => $validated['contact_phone'] ?? null,
|
||||
'title' => $validated['contact_title'] ?? null,
|
||||
'is_primary' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -165,35 +178,55 @@ class AccountController extends Controller
|
||||
{
|
||||
$account->load(['contacts']);
|
||||
|
||||
// Get orders for this account from this seller (with invoices)
|
||||
$orders = $account->orders()
|
||||
// Location filtering
|
||||
$locationId = $request->query('location');
|
||||
$selectedLocation = $locationId ? $account->locations()->find($locationId) : null;
|
||||
|
||||
// Load all locations for this account with contacts pivot
|
||||
$locations = $account->locations()
|
||||
->with(['contacts' => function ($q) {
|
||||
$q->wherePivot('role', 'buyer');
|
||||
}])
|
||||
->orderBy('name')
|
||||
->get();
|
||||
|
||||
// Base order query for this seller
|
||||
$baseOrderQuery = fn () => $account->orders()
|
||||
->whereHas('items.product.brand', function ($q) use ($business) {
|
||||
$q->where('business_id', $business->id);
|
||||
})
|
||||
->with(['invoice'])
|
||||
->latest()
|
||||
->limit(10)
|
||||
->get();
|
||||
});
|
||||
|
||||
// Get quotes for this account
|
||||
$quotes = CrmQuote::where('business_id', $business->id)
|
||||
->where('account_id', $account->id)
|
||||
->with(['contact', 'items'])
|
||||
->latest()
|
||||
->limit(10)
|
||||
->get();
|
||||
// Get orders (filtered by location if selected)
|
||||
$ordersQuery = $baseOrderQuery();
|
||||
if ($selectedLocation) {
|
||||
$ordersQuery->where('location_id', $selectedLocation->id);
|
||||
}
|
||||
$orders = $ordersQuery->with(['invoice', 'location'])->latest()->limit(10)->get();
|
||||
|
||||
// Get invoices for this account (via orders)
|
||||
$invoices = Invoice::whereHas('order', function ($q) use ($business, $account) {
|
||||
// Get quotes for this account (filtered by location if selected)
|
||||
$quotesQuery = CrmQuote::where('business_id', $business->id)
|
||||
->where('account_id', $account->id);
|
||||
if ($selectedLocation) {
|
||||
$quotesQuery->where('location_id', $selectedLocation->id);
|
||||
}
|
||||
$quotes = $quotesQuery->with(['contact', 'items'])->latest()->limit(10)->get();
|
||||
|
||||
// Base invoice query
|
||||
$baseInvoiceQuery = fn () => Invoice::whereHas('order', function ($q) use ($business, $account) {
|
||||
$q->where('business_id', $account->id)
|
||||
->whereHas('items.product.brand', function ($q2) use ($business) {
|
||||
$q2->where('business_id', $business->id);
|
||||
});
|
||||
})
|
||||
->with(['order', 'payments'])
|
||||
->latest()
|
||||
->limit(10)
|
||||
->get();
|
||||
});
|
||||
|
||||
// Get invoices (filtered by location if selected)
|
||||
$invoicesQuery = $baseInvoiceQuery();
|
||||
if ($selectedLocation) {
|
||||
$invoicesQuery->whereHas('order', function ($q) use ($selectedLocation) {
|
||||
$q->where('location_id', $selectedLocation->id);
|
||||
});
|
||||
}
|
||||
$invoices = $invoicesQuery->with(['order', 'payments'])->latest()->limit(10)->get();
|
||||
|
||||
// Get opportunities for this account from this seller
|
||||
$opportunities = SalesOpportunity::where('seller_business_id', $business->id)
|
||||
@@ -234,13 +267,17 @@ class AccountController extends Controller
|
||||
->limit(20)
|
||||
->get();
|
||||
|
||||
// Compute stats for this account with efficient queries
|
||||
$orderStats = $account->orders()
|
||||
->whereHas('items.product.brand', function ($q) use ($business) {
|
||||
$q->where('business_id', $business->id);
|
||||
})
|
||||
->selectRaw('COUNT(*) as total_orders, COALESCE(SUM(total), 0) as total_revenue')
|
||||
->first();
|
||||
// Compute stats - if location selected, show location-specific stats
|
||||
if ($selectedLocation) {
|
||||
$orderStats = $baseOrderQuery()
|
||||
->where('location_id', $selectedLocation->id)
|
||||
->selectRaw('COUNT(*) as total_orders, COALESCE(SUM(total), 0) as total_revenue')
|
||||
->first();
|
||||
} else {
|
||||
$orderStats = $baseOrderQuery()
|
||||
->selectRaw('COUNT(*) as total_orders, COALESCE(SUM(total), 0) as total_revenue')
|
||||
->first();
|
||||
}
|
||||
|
||||
$opportunityStats = SalesOpportunity::where('seller_business_id', $business->id)
|
||||
->where('business_id', $account->id)
|
||||
@@ -248,14 +285,14 @@ class AccountController extends Controller
|
||||
->selectRaw('COUNT(*) as open_count, COALESCE(SUM(value), 0) as pipeline_value')
|
||||
->first();
|
||||
|
||||
// Financial stats from invoices
|
||||
$financialStats = Invoice::whereHas('order', function ($q) use ($business, $account) {
|
||||
$q->where('business_id', $account->id)
|
||||
->whereHas('items.product.brand', function ($q2) use ($business) {
|
||||
$q2->where('business_id', $business->id);
|
||||
});
|
||||
})
|
||||
->selectRaw('
|
||||
// Financial stats from invoices (location-filtered if applicable)
|
||||
$financialStatsQuery = $baseInvoiceQuery();
|
||||
if ($selectedLocation) {
|
||||
$financialStatsQuery->whereHas('order', function ($q) use ($selectedLocation) {
|
||||
$q->where('location_id', $selectedLocation->id);
|
||||
});
|
||||
}
|
||||
$financialStats = $financialStatsQuery->selectRaw('
|
||||
COALESCE(SUM(amount_due), 0) as outstanding_balance,
|
||||
COALESCE(SUM(CASE WHEN due_date < CURRENT_DATE AND amount_due > 0 THEN amount_due ELSE 0 END), 0) as past_due_amount,
|
||||
COUNT(CASE WHEN amount_due > 0 THEN 1 END) as open_invoice_count,
|
||||
@@ -291,6 +328,63 @@ class AccountController extends Controller
|
||||
'last_payment_date' => $lastPayment->payment_date ?? null,
|
||||
];
|
||||
|
||||
// Calculate unattributed orders/invoices (those without location_id)
|
||||
$unattributedOrdersCount = $baseOrderQuery()->whereNull('location_id')->count();
|
||||
$unattributedInvoicesCount = $baseInvoiceQuery()
|
||||
->whereHas('order', function ($q) {
|
||||
$q->whereNull('location_id');
|
||||
})
|
||||
->count();
|
||||
|
||||
// Calculate per-location stats for location tiles
|
||||
$locationStats = [];
|
||||
if ($locations->count() > 0) {
|
||||
$locationIds = $locations->pluck('id')->toArray();
|
||||
|
||||
// Order stats by location
|
||||
$ordersByLocation = $baseOrderQuery()
|
||||
->whereIn('location_id', $locationIds)
|
||||
->selectRaw('location_id, COUNT(*) as orders_count, COALESCE(SUM(total), 0) as revenue')
|
||||
->groupBy('location_id')
|
||||
->get()
|
||||
->keyBy('location_id');
|
||||
|
||||
// Invoice stats by location
|
||||
$invoicesByLocation = Invoice::whereHas('order', function ($q) use ($business, $account, $locationIds) {
|
||||
$q->where('business_id', $account->id)
|
||||
->whereIn('location_id', $locationIds)
|
||||
->whereHas('items.product.brand', function ($q2) use ($business) {
|
||||
$q2->where('business_id', $business->id);
|
||||
});
|
||||
})
|
||||
->selectRaw('
|
||||
(SELECT location_id FROM orders WHERE orders.id = invoices.order_id) as location_id,
|
||||
COALESCE(SUM(amount_due), 0) as outstanding,
|
||||
COALESCE(SUM(CASE WHEN due_date < CURRENT_DATE AND amount_due > 0 THEN amount_due ELSE 0 END), 0) as past_due,
|
||||
COUNT(CASE WHEN amount_due > 0 THEN 1 END) as open_invoices
|
||||
')
|
||||
->groupByRaw('(SELECT location_id FROM orders WHERE orders.id = invoices.order_id)')
|
||||
->get()
|
||||
->keyBy('location_id');
|
||||
|
||||
foreach ($locations as $location) {
|
||||
$orderData = $ordersByLocation->get($location->id);
|
||||
$invoiceData = $invoicesByLocation->get($location->id);
|
||||
|
||||
$ordersCount = $orderData->orders_count ?? 0;
|
||||
$openInvoices = $invoiceData->open_invoices ?? 0;
|
||||
|
||||
$locationStats[$location->id] = [
|
||||
'orders' => $ordersCount,
|
||||
'revenue' => $orderData->revenue ?? 0,
|
||||
'outstanding' => $invoiceData->outstanding ?? 0,
|
||||
'past_due' => $invoiceData->past_due ?? 0,
|
||||
'open_invoices' => $openInvoices,
|
||||
'has_attributed_data' => ($ordersCount + $openInvoices) > 0,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return view('seller.crm.accounts.show', compact(
|
||||
'business',
|
||||
'account',
|
||||
@@ -303,7 +397,12 @@ class AccountController extends Controller
|
||||
'tasks',
|
||||
'conversationEvents',
|
||||
'sendHistory',
|
||||
'activities'
|
||||
'activities',
|
||||
'locations',
|
||||
'selectedLocation',
|
||||
'locationStats',
|
||||
'unattributedOrdersCount',
|
||||
'unattributedInvoicesCount'
|
||||
));
|
||||
}
|
||||
|
||||
@@ -312,9 +411,26 @@ class AccountController extends Controller
|
||||
*/
|
||||
public function contacts(Request $request, Business $business, Business $account)
|
||||
{
|
||||
$contacts = $account->contacts()->paginate(25);
|
||||
// Location filtering
|
||||
$locationId = $request->query('location');
|
||||
$selectedLocation = $locationId ? $account->locations()->find($locationId) : null;
|
||||
|
||||
return view('seller.crm.accounts.contacts', compact('business', 'account', 'contacts'));
|
||||
// Base query for contacts
|
||||
$contactsQuery = $account->contacts();
|
||||
|
||||
// If location selected, filter to contacts assigned to that location
|
||||
if ($selectedLocation) {
|
||||
$contactsQuery->whereHas('locations', function ($q) use ($selectedLocation) {
|
||||
$q->where('locations.id', $selectedLocation->id);
|
||||
});
|
||||
}
|
||||
|
||||
$contacts = $contactsQuery->paginate(25);
|
||||
|
||||
// Load locations for the scope bar
|
||||
$locations = $account->locations()->orderBy('name')->get();
|
||||
|
||||
return view('seller.crm.accounts.contacts', compact('business', 'account', 'contacts', 'locations', 'selectedLocation'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -322,7 +438,21 @@ class AccountController extends Controller
|
||||
*/
|
||||
public function opportunities(Request $request, Business $business, Business $account)
|
||||
{
|
||||
return view('seller.crm.accounts.opportunities', compact('business', 'account'));
|
||||
// Location filtering (note: opportunities don't have location_id yet, so we just pass the context)
|
||||
$locationId = $request->query('location');
|
||||
$selectedLocation = $locationId ? $account->locations()->find($locationId) : null;
|
||||
|
||||
// Load opportunities for this account
|
||||
$opportunities = SalesOpportunity::where('seller_business_id', $business->id)
|
||||
->where('business_id', $account->id)
|
||||
->with(['stage', 'brand', 'owner'])
|
||||
->latest()
|
||||
->paginate(25);
|
||||
|
||||
// Load locations for the scope bar
|
||||
$locations = $account->locations()->orderBy('name')->get();
|
||||
|
||||
return view('seller.crm.accounts.opportunities', compact('business', 'account', 'opportunities', 'locations', 'selectedLocation'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -330,15 +460,28 @@ class AccountController extends Controller
|
||||
*/
|
||||
public function orders(Request $request, Business $business, Business $account)
|
||||
{
|
||||
$orders = $account->orders()
|
||||
// Location filtering
|
||||
$locationId = $request->query('location');
|
||||
$selectedLocation = $locationId ? $account->locations()->find($locationId) : null;
|
||||
|
||||
$ordersQuery = $account->orders()
|
||||
->whereHas('items.product.brand', function ($q) use ($business) {
|
||||
$q->where('business_id', $business->id);
|
||||
})
|
||||
->with(['items.product.brand'])
|
||||
});
|
||||
|
||||
// Filter by location if selected
|
||||
if ($selectedLocation) {
|
||||
$ordersQuery->where('location_id', $selectedLocation->id);
|
||||
}
|
||||
|
||||
$orders = $ordersQuery->with(['items.product.brand', 'location'])
|
||||
->latest()
|
||||
->paginate(25);
|
||||
|
||||
return view('seller.crm.accounts.orders', compact('business', 'account', 'orders'));
|
||||
// Load locations for the scope bar
|
||||
$locations = $account->locations()->orderBy('name')->get();
|
||||
|
||||
return view('seller.crm.accounts.orders', compact('business', 'account', 'orders', 'locations', 'selectedLocation'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -346,13 +489,20 @@ class AccountController extends Controller
|
||||
*/
|
||||
public function activity(Request $request, Business $business, Business $account)
|
||||
{
|
||||
// Location filtering (note: activities don't have location_id yet, so we just pass the context)
|
||||
$locationId = $request->query('location');
|
||||
$selectedLocation = $locationId ? $account->locations()->find($locationId) : null;
|
||||
|
||||
$activities = Activity::where('seller_business_id', $business->id)
|
||||
->where('business_id', $account->id)
|
||||
->with(['causer'])
|
||||
->latest()
|
||||
->paginate(50);
|
||||
|
||||
return view('seller.crm.accounts.activity', compact('business', 'account', 'activities'));
|
||||
// Load locations for the scope bar
|
||||
$locations = $account->locations()->orderBy('name')->get();
|
||||
|
||||
return view('seller.crm.accounts.activity', compact('business', 'account', 'activities', 'locations', 'selectedLocation'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -360,7 +510,22 @@ class AccountController extends Controller
|
||||
*/
|
||||
public function tasks(Request $request, Business $business, Business $account)
|
||||
{
|
||||
return view('seller.crm.accounts.tasks', compact('business', 'account'));
|
||||
// Location filtering (note: tasks don't have location_id yet, so we just pass the context)
|
||||
$locationId = $request->query('location');
|
||||
$selectedLocation = $locationId ? $account->locations()->find($locationId) : null;
|
||||
|
||||
// Load tasks for this account
|
||||
$tasks = CrmTask::where('seller_business_id', $business->id)
|
||||
->where('business_id', $account->id)
|
||||
->with(['assignee', 'opportunity'])
|
||||
->orderByRaw('completed_at IS NOT NULL')
|
||||
->orderBy('due_at')
|
||||
->paginate(25);
|
||||
|
||||
// Load locations for the scope bar
|
||||
$locations = $account->locations()->orderBy('name')->get();
|
||||
|
||||
return view('seller.crm.accounts.tasks', compact('business', 'account', 'tasks', 'locations', 'selectedLocation'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -397,14 +562,8 @@ class AccountController extends Controller
|
||||
'email' => 'nullable|email|max:255',
|
||||
'phone' => 'nullable|string|max:50',
|
||||
'title' => 'nullable|string|max:100',
|
||||
'is_primary' => 'boolean',
|
||||
]);
|
||||
|
||||
// If setting as primary, unset other primary contacts
|
||||
if ($validated['is_primary'] ?? false) {
|
||||
$account->contacts()->update(['is_primary' => false]);
|
||||
}
|
||||
|
||||
$contact = $account->contacts()->create($validated);
|
||||
|
||||
// Return JSON for AJAX requests
|
||||
@@ -453,14 +612,11 @@ class AccountController extends Controller
|
||||
'email' => 'nullable|email|max:255',
|
||||
'phone' => 'nullable|string|max:50',
|
||||
'title' => 'nullable|string|max:100',
|
||||
'is_primary' => 'boolean',
|
||||
'is_active' => 'boolean',
|
||||
]);
|
||||
|
||||
// If setting as primary, unset other primary contacts
|
||||
if ($validated['is_primary'] ?? false) {
|
||||
$account->contacts()->where('id', '!=', $contact->id)->update(['is_primary' => false]);
|
||||
}
|
||||
// Handle checkbox - if not sent, default to false
|
||||
$validated['is_active'] = $request->boolean('is_active');
|
||||
|
||||
$contact->update($validated);
|
||||
|
||||
@@ -485,4 +641,167 @@ class AccountController extends Controller
|
||||
->route('seller.business.crm.accounts.contacts', [$business->slug, $account->slug])
|
||||
->with('success', 'Contact deleted successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show location edit form
|
||||
*/
|
||||
public function editLocation(Request $request, Business $business, Business $account, Location $location)
|
||||
{
|
||||
// Verify location belongs to this account
|
||||
if ($location->business_id !== $account->id) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
// Load contacts that can be assigned to this location
|
||||
$contacts = $account->contacts()->orderBy('first_name')->get();
|
||||
|
||||
// Load currently assigned contacts with their roles
|
||||
$locationContacts = $location->contacts()->get();
|
||||
|
||||
// Available roles for location contacts
|
||||
$contactRoles = [
|
||||
'buyer' => 'Buyer',
|
||||
'ap' => 'Accounts Payable',
|
||||
'marketing' => 'Marketing',
|
||||
'gm' => 'General Manager',
|
||||
'inventory' => 'Inventory Manager',
|
||||
'other' => 'Other',
|
||||
];
|
||||
|
||||
// CannaiQ platforms
|
||||
$cannaiqPlatforms = [
|
||||
'dutchie' => 'Dutchie',
|
||||
'jane' => 'Jane',
|
||||
'weedmaps' => 'Weedmaps',
|
||||
'leafly' => 'Leafly',
|
||||
'iheartjane' => 'iHeartJane',
|
||||
'other' => 'Other',
|
||||
];
|
||||
|
||||
return view('seller.crm.accounts.locations-edit', compact(
|
||||
'business',
|
||||
'account',
|
||||
'location',
|
||||
'contacts',
|
||||
'locationContacts',
|
||||
'contactRoles',
|
||||
'cannaiqPlatforms'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update location
|
||||
*/
|
||||
public function updateLocation(Request $request, Business $business, Business $account, Location $location)
|
||||
{
|
||||
// Verify location belongs to this account
|
||||
if ($location->business_id !== $account->id) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'name' => 'required|string|max:255',
|
||||
'address' => 'nullable|string|max:255',
|
||||
'city' => 'nullable|string|max:100',
|
||||
'state' => 'nullable|string|max:50',
|
||||
'zipcode' => 'nullable|string|max:20',
|
||||
'phone' => 'nullable|string|max:50',
|
||||
'email' => 'nullable|email|max:255',
|
||||
'is_active' => 'boolean',
|
||||
'cannaiq_platform' => 'nullable|string|max:50',
|
||||
'cannaiq_store_slug' => 'nullable|string|max:255',
|
||||
'cannaiq_store_id' => 'nullable|string|max:100',
|
||||
'cannaiq_store_name' => 'nullable|string|max:255',
|
||||
'contact_roles' => 'nullable|array',
|
||||
'contact_roles.*.contact_id' => 'required|exists:contacts,id',
|
||||
'contact_roles.*.role' => 'required|string|max:50',
|
||||
'contact_roles.*.is_primary' => 'boolean',
|
||||
]);
|
||||
|
||||
// Handle checkbox
|
||||
$validated['is_active'] = $request->boolean('is_active');
|
||||
|
||||
// Clear CannaiQ fields if platform is cleared
|
||||
if (empty($validated['cannaiq_platform'])) {
|
||||
$validated['cannaiq_store_slug'] = null;
|
||||
$validated['cannaiq_store_id'] = null;
|
||||
$validated['cannaiq_store_name'] = null;
|
||||
}
|
||||
|
||||
// Update location
|
||||
$location->update([
|
||||
'name' => $validated['name'],
|
||||
'address' => $validated['address'] ?? null,
|
||||
'city' => $validated['city'] ?? null,
|
||||
'state' => $validated['state'] ?? null,
|
||||
'zipcode' => $validated['zipcode'] ?? null,
|
||||
'phone' => $validated['phone'] ?? null,
|
||||
'email' => $validated['email'] ?? null,
|
||||
'is_active' => $validated['is_active'],
|
||||
'cannaiq_platform' => $validated['cannaiq_platform'] ?? null,
|
||||
'cannaiq_store_slug' => $validated['cannaiq_store_slug'] ?? null,
|
||||
'cannaiq_store_id' => $validated['cannaiq_store_id'] ?? null,
|
||||
'cannaiq_store_name' => $validated['cannaiq_store_name'] ?? null,
|
||||
]);
|
||||
|
||||
// Sync location contacts
|
||||
if (isset($validated['contact_roles'])) {
|
||||
$syncData = [];
|
||||
foreach ($validated['contact_roles'] as $contactRole) {
|
||||
// Verify contact belongs to this account
|
||||
$contact = Contact::where('business_id', $account->id)
|
||||
->where('id', $contactRole['contact_id'])
|
||||
->first();
|
||||
|
||||
if ($contact) {
|
||||
$syncData[$contact->id] = [
|
||||
'role' => $contactRole['role'],
|
||||
'is_primary' => $contactRole['is_primary'] ?? false,
|
||||
];
|
||||
}
|
||||
}
|
||||
$location->contacts()->sync($syncData);
|
||||
} else {
|
||||
$location->contacts()->detach();
|
||||
}
|
||||
|
||||
return redirect()
|
||||
->route('seller.business.crm.accounts.show', [$business->slug, $account->slug])
|
||||
->with('success', 'Location updated successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Search CannaiQ stores for linking
|
||||
*/
|
||||
public function searchCannaiqStores(Request $request, Business $business, Business $account, Location $location)
|
||||
{
|
||||
// Verify location belongs to this account
|
||||
if ($location->business_id !== $account->id) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$request->validate([
|
||||
'platform' => 'required|string|max:50',
|
||||
'query' => 'required|string|min:2|max:100',
|
||||
]);
|
||||
|
||||
try {
|
||||
$client = app(CannaiqClient::class);
|
||||
$results = $client->searchStores(
|
||||
platform: $request->input('platform'),
|
||||
query: $request->input('query')
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'stores' => $results,
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Failed to search stores: '.$e->getMessage(),
|
||||
'stores' => [],
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +67,18 @@ class ContactController extends Controller
|
||||
->paginate(25)
|
||||
->withQueryString();
|
||||
|
||||
// Return JSON for AJAX/API requests (live search)
|
||||
if ($request->wantsJson()) {
|
||||
return response()->json([
|
||||
'data' => $contacts->map(fn ($c) => [
|
||||
'hashid' => $c->hashid,
|
||||
'name' => $c->getFullName(),
|
||||
'email' => $c->email,
|
||||
'account' => $c->business?->name,
|
||||
])->values()->toArray(),
|
||||
]);
|
||||
}
|
||||
|
||||
// Get accounts for filter dropdown
|
||||
$accounts = Business::where('type', 'buyer')
|
||||
->where('status', 'approved')
|
||||
|
||||
@@ -35,6 +35,19 @@ class LeadController extends Controller
|
||||
|
||||
$leads = $query->latest()->paginate(25);
|
||||
|
||||
// Return JSON for AJAX/API requests (live search)
|
||||
if ($request->wantsJson()) {
|
||||
return response()->json([
|
||||
'data' => $leads->map(fn ($l) => [
|
||||
'hashid' => $l->hashid,
|
||||
'name' => $l->company_name,
|
||||
'contact' => $l->contact_name,
|
||||
'email' => $l->contact_email,
|
||||
'status' => $l->status,
|
||||
])->values()->toArray(),
|
||||
]);
|
||||
}
|
||||
|
||||
return view('seller.crm.leads.index', compact('business', 'leads'));
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ use App\Models\Contact;
|
||||
use App\Models\Crm\CrmDeal;
|
||||
use App\Models\Crm\CrmQuote;
|
||||
use App\Models\Crm\CrmQuoteItem;
|
||||
use App\Models\Location;
|
||||
use App\Models\Order;
|
||||
use App\Models\OrderItem;
|
||||
use App\Models\Product;
|
||||
@@ -44,6 +45,19 @@ class QuoteController extends Controller
|
||||
|
||||
$quotes = $query->orderByDesc('created_at')->paginate(25);
|
||||
|
||||
// Return JSON for AJAX/API requests (live search)
|
||||
if ($request->wantsJson()) {
|
||||
return response()->json([
|
||||
'data' => $quotes->map(fn ($q) => [
|
||||
'id' => $q->id,
|
||||
'name' => $q->quote_number.' - '.($q->title ?? 'Untitled'),
|
||||
'contact' => $q->contact?->name ?? '-',
|
||||
'status' => $q->status,
|
||||
'total' => '$'.number_format($q->total, 2),
|
||||
])->values()->toArray(),
|
||||
]);
|
||||
}
|
||||
|
||||
return view('seller.crm.quotes.index', compact('quotes', 'business'));
|
||||
}
|
||||
|
||||
@@ -52,11 +66,13 @@ class QuoteController extends Controller
|
||||
*/
|
||||
public function create(Request $request, Business $business)
|
||||
{
|
||||
// Get buyer businesses that have contacts (potential and existing customers)
|
||||
// Get all approved buyer businesses as potential customers
|
||||
// Contacts are loaded dynamically via /search/contacts?customer_id={account_id}
|
||||
// Include locations for delivery address selection
|
||||
// Note: We don't filter by whereHas('contacts') because newly created customers
|
||||
// may not have contacts yet - contacts can be added after selecting the account
|
||||
$accounts = Business::where('type', 'buyer')
|
||||
->whereHas('contacts')
|
||||
->where('status', 'approved')
|
||||
->with('locations:id,business_id,name,is_primary')
|
||||
->orderBy('name')
|
||||
->select(['id', 'name', 'slug'])
|
||||
@@ -69,7 +85,77 @@ class QuoteController extends Controller
|
||||
? CrmDeal::forBusiness($business->id)->find($request->deal_id)
|
||||
: null;
|
||||
|
||||
return view('seller.crm.quotes.create', compact('accounts', 'deals', 'deal', 'business'));
|
||||
// Pre-fill from URL parameters (coming from customer dashboard)
|
||||
$selectedAccount = null;
|
||||
$selectedLocation = null;
|
||||
$selectedContact = null;
|
||||
$locationContacts = collect();
|
||||
|
||||
// Handle clear actions
|
||||
if ($request->has('clearAccount')) {
|
||||
// Redirect without any prefills
|
||||
return redirect()->route('seller.business.crm.quotes.create', $business);
|
||||
}
|
||||
if ($request->has('clearLocation')) {
|
||||
// Keep account but clear location
|
||||
return redirect()->route('seller.business.crm.quotes.create', [$business, 'account_id' => $request->account_id]);
|
||||
}
|
||||
if ($request->has('clearContact')) {
|
||||
// Keep account and location but clear contact
|
||||
$params = ['account_id' => $request->account_id];
|
||||
if ($request->location_id) {
|
||||
$params['location_id'] = $request->location_id;
|
||||
}
|
||||
|
||||
return redirect()->route('seller.business.crm.quotes.create', array_merge([$business], $params));
|
||||
}
|
||||
|
||||
// Pre-fill account
|
||||
if ($request->filled('account_id')) {
|
||||
$selectedAccount = $accounts->firstWhere('id', $request->account_id);
|
||||
}
|
||||
|
||||
// Pre-fill location (must belong to selected account)
|
||||
if ($selectedAccount && $request->filled('location_id')) {
|
||||
$selectedLocation = $selectedAccount->locations->firstWhere('id', $request->location_id);
|
||||
}
|
||||
|
||||
// If location selected, get contacts assigned to that location
|
||||
if ($selectedLocation) {
|
||||
$locationContacts = $selectedLocation->contacts()
|
||||
->with('pivot')
|
||||
->get()
|
||||
->map(fn ($c) => [
|
||||
'value' => $c->id,
|
||||
'label' => $c->getFullName().($c->email ? " ({$c->email})" : ''),
|
||||
'is_primary' => $c->pivot->is_primary ?? false,
|
||||
'role' => $c->pivot->role ?? 'buyer',
|
||||
]);
|
||||
|
||||
// Try to find primary buyer for this location
|
||||
$primaryBuyer = $locationContacts->firstWhere('is_primary', true)
|
||||
?? $locationContacts->firstWhere('role', 'buyer');
|
||||
|
||||
if ($primaryBuyer && ! $request->filled('contact_id')) {
|
||||
$selectedContact = Contact::find($primaryBuyer['value']);
|
||||
}
|
||||
}
|
||||
|
||||
// Pre-fill contact if explicitly provided
|
||||
if ($request->filled('contact_id')) {
|
||||
$selectedContact = Contact::find($request->contact_id);
|
||||
}
|
||||
|
||||
return view('seller.crm.quotes.create', compact(
|
||||
'accounts',
|
||||
'deals',
|
||||
'deal',
|
||||
'business',
|
||||
'selectedAccount',
|
||||
'selectedLocation',
|
||||
'selectedContact',
|
||||
'locationContacts'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,6 +210,7 @@ class QuoteController extends Controller
|
||||
'quote_number' => $quoteNumber,
|
||||
'title' => $validated['title'],
|
||||
'status' => CrmQuote::STATUS_DRAFT,
|
||||
'quote_date' => now(),
|
||||
'valid_until' => $validated['valid_until'] ?? now()->addDays($business->crm_quote_validity_days ?? 30),
|
||||
'discount_type' => $validated['discount_type'],
|
||||
'discount_value' => $validated['discount_value'],
|
||||
|
||||
@@ -40,8 +40,30 @@ class TaskController extends Controller
|
||||
$tasksQuery->where('type', $request->type);
|
||||
}
|
||||
|
||||
// Search filter
|
||||
if ($request->filled('q')) {
|
||||
$search = $request->q;
|
||||
$tasksQuery->where(function ($q) use ($search) {
|
||||
$q->where('title', 'ILIKE', "%{$search}%")
|
||||
->orWhere('details', 'ILIKE', "%{$search}%");
|
||||
});
|
||||
}
|
||||
|
||||
$tasks = $tasksQuery->paginate(25);
|
||||
|
||||
// Return JSON for AJAX/API requests (live search)
|
||||
if ($request->wantsJson()) {
|
||||
return response()->json([
|
||||
'data' => $tasks->map(fn ($t) => [
|
||||
'id' => $t->id,
|
||||
'name' => $t->title,
|
||||
'type' => $t->type,
|
||||
'assignee' => $t->assignee?->name ?? 'Unassigned',
|
||||
'due_at' => $t->due_at?->format('M j, Y'),
|
||||
])->values()->toArray(),
|
||||
]);
|
||||
}
|
||||
|
||||
// Get stats with single efficient query
|
||||
$statsQuery = CrmTask::where('seller_business_id', $business->id)
|
||||
->selectRaw('
|
||||
|
||||
@@ -118,7 +118,7 @@ class InvoiceController extends Controller
|
||||
/**
|
||||
* Display a listing of invoices for the business.
|
||||
*/
|
||||
public function index(Business $business)
|
||||
public function index(Business $business, Request $request)
|
||||
{
|
||||
// Get brand IDs for this business (single query, reused for filtering)
|
||||
$brandIds = $business->brands()->pluck('id');
|
||||
@@ -138,11 +138,47 @@ class InvoiceController extends Controller
|
||||
->where('due_date', '<', now())->count(),
|
||||
];
|
||||
|
||||
// Apply search filter - search by customer business name or invoice number
|
||||
$search = $request->input('search');
|
||||
if ($search) {
|
||||
$baseQuery->where(function ($query) use ($search) {
|
||||
$query->where('invoice_number', 'ilike', "%{$search}%")
|
||||
->orWhereHas('business', function ($q) use ($search) {
|
||||
$q->where('name', 'ilike', "%{$search}%");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Apply status filter
|
||||
$status = $request->input('status');
|
||||
if ($status === 'unpaid') {
|
||||
$baseQuery->where('payment_status', 'unpaid');
|
||||
} elseif ($status === 'paid') {
|
||||
$baseQuery->where('payment_status', 'paid');
|
||||
} elseif ($status === 'overdue') {
|
||||
$baseQuery->where('payment_status', '!=', 'paid')
|
||||
->where('due_date', '<', now());
|
||||
}
|
||||
|
||||
// Paginate with only the relations needed for display
|
||||
$invoices = (clone $baseQuery)
|
||||
->with(['business:id,name,primary_contact_email,business_email', 'order:id,contact_id,user_id', 'order.contact:id,first_name,last_name,email', 'order.user:id,email'])
|
||||
->latest()
|
||||
->paginate(25);
|
||||
->paginate(25)
|
||||
->withQueryString();
|
||||
|
||||
// Return JSON for AJAX/API requests (live search)
|
||||
if ($request->wantsJson()) {
|
||||
return response()->json([
|
||||
'data' => $invoices->map(fn ($i) => [
|
||||
'hashid' => $i->hashid,
|
||||
'name' => $i->invoice_number.' - '.$i->business->name,
|
||||
'invoice_number' => $i->invoice_number,
|
||||
'customer' => $i->business->name,
|
||||
'status' => $i->payment_status,
|
||||
])->values()->toArray(),
|
||||
]);
|
||||
}
|
||||
|
||||
return view('seller.invoices.index', compact('business', 'invoices', 'stats'));
|
||||
}
|
||||
|
||||
@@ -29,6 +29,11 @@ class ProductController extends Controller
|
||||
// Get brand IDs to filter by (respects brand context switcher)
|
||||
$brandIds = BrandSwitcherController::getFilteredBrandIds();
|
||||
|
||||
// Get all brands for the business for the filter dropdown
|
||||
$brands = \App\Models\Brand::where('business_id', $business->id)
|
||||
->orderBy('name')
|
||||
->get(['id', 'name']);
|
||||
|
||||
// Calculate missing BOM count for health alert
|
||||
$missingBomCount = Product::whereIn('brand_id', $brandIds)
|
||||
->where('is_assembly', true)
|
||||
@@ -106,7 +111,7 @@ class ProductController extends Controller
|
||||
'hashid' => $variety->hashid,
|
||||
'name' => $variety->name,
|
||||
'sku' => $variety->sku ?? 'N/A',
|
||||
'price' => $variety->wholesale_price ?? 0,
|
||||
'price' => $variety->effective_price ?? $variety->wholesale_price ?? 0,
|
||||
'status' => $variety->is_active ? 'active' : 'inactive',
|
||||
'image_url' => $variety->getImageUrl('thumb'),
|
||||
'edit_url' => route('seller.business.products.edit', [$business->slug, $variety->hashid]),
|
||||
@@ -123,7 +128,7 @@ class ProductController extends Controller
|
||||
'sku' => $product->sku ?? 'N/A',
|
||||
'brand' => $product->brand->name ?? 'N/A',
|
||||
'channel' => 'Marketplace', // TODO: Add channel field to products
|
||||
'price' => $product->wholesale_price ?? 0,
|
||||
'price' => $product->effective_price ?? $product->wholesale_price ?? 0,
|
||||
'views' => rand(500, 3000), // TODO: Replace with real view tracking
|
||||
'orders' => rand(10, 200), // TODO: Replace with real order count
|
||||
'revenue' => rand(1000, 10000), // TODO: Replace with real revenue calculation
|
||||
@@ -150,7 +155,20 @@ class ProductController extends Controller
|
||||
'to' => $paginator->lastItem(),
|
||||
];
|
||||
|
||||
return view('seller.products.index', compact('business', 'products', 'missingBomCount', 'paginator', 'pagination'));
|
||||
// Return JSON for AJAX/API requests (live search)
|
||||
if ($request->wantsJson()) {
|
||||
return response()->json([
|
||||
'data' => $products->map(fn ($p) => [
|
||||
'hashid' => $p['hashid'],
|
||||
'name' => $p['product'],
|
||||
'sku' => $p['sku'],
|
||||
'brand' => $p['brand'],
|
||||
])->values()->toArray(),
|
||||
'pagination' => $pagination,
|
||||
]);
|
||||
}
|
||||
|
||||
return view('seller.products.index', compact('business', 'brands', 'products', 'missingBomCount', 'paginator', 'pagination'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -475,20 +493,34 @@ class ProductController extends Controller
|
||||
// Set default value for price_unit if not provided
|
||||
$validated['price_unit'] = $validated['price_unit'] ?? 'each';
|
||||
|
||||
// Create product
|
||||
$product = Product::create($validated);
|
||||
// Create product and handle images in a transaction
|
||||
$product = \DB::transaction(function () use ($validated, $request, $business) {
|
||||
$product = Product::create($validated);
|
||||
|
||||
// Handle image uploads if present
|
||||
if ($request->hasFile('images')) {
|
||||
foreach ($request->file('images') as $index => $image) {
|
||||
$path = $image->store('products', 'public');
|
||||
$product->images()->create([
|
||||
'path' => $path,
|
||||
'type' => 'product',
|
||||
'is_primary' => $index === 0,
|
||||
]);
|
||||
// Handle image uploads if present
|
||||
// Note: Uses default disk (minio) per CLAUDE.md rules - never use 'public' disk for media
|
||||
if ($request->hasFile('images')) {
|
||||
$brand = $product->brand;
|
||||
$basePath = "businesses/{$business->slug}/brands/{$brand->slug}/products/{$product->sku}/images";
|
||||
|
||||
foreach ($request->file('images') as $index => $image) {
|
||||
$filename = $image->hashName();
|
||||
$path = $image->storeAs($basePath, $filename);
|
||||
|
||||
if ($path === false) {
|
||||
throw new \RuntimeException('Failed to upload image to storage');
|
||||
}
|
||||
|
||||
$product->images()->create([
|
||||
'path' => $path,
|
||||
'type' => 'product',
|
||||
'is_primary' => $index === 0,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $product;
|
||||
});
|
||||
|
||||
return redirect()
|
||||
->route('seller.business.products.index', $business->slug)
|
||||
@@ -1032,7 +1064,7 @@ class ProductController extends Controller
|
||||
'sku' => $product->sku ?? 'N/A',
|
||||
'brand' => $product->brand->name ?? 'N/A',
|
||||
'channel' => 'Marketplace', // TODO: Add channel field to products
|
||||
'price' => $product->wholesale_price ?? 0,
|
||||
'price' => (float) ($product->wholesale_price ?? 0),
|
||||
'views' => rand(500, 3000), // TODO: Replace with real view tracking
|
||||
'orders' => rand(10, 200), // TODO: Replace with real order count
|
||||
'revenue' => rand(1000, 10000), // TODO: Replace with real revenue calculation
|
||||
|
||||
@@ -55,12 +55,16 @@ class SearchController extends Controller
|
||||
/**
|
||||
* Search contacts for a specific customer or the seller's own contacts.
|
||||
*
|
||||
* GET /s/{business}/search/contacts?q=...&customer_id=...
|
||||
* GET /s/{business}/search/contacts?q=...&customer_id=...&location_id=...
|
||||
*
|
||||
* If location_id is provided, returns only contacts assigned to that location
|
||||
* via the location_contact pivot table.
|
||||
*/
|
||||
public function contacts(Request $request, Business $business): JsonResponse
|
||||
{
|
||||
$query = $request->input('q', '');
|
||||
$customerId = $request->input('customer_id');
|
||||
$locationId = $request->input('location_id');
|
||||
|
||||
$contactsQuery = Contact::query()
|
||||
->where('is_active', true);
|
||||
@@ -73,6 +77,13 @@ class SearchController extends Controller
|
||||
$contactsQuery->where('business_id', $business->id);
|
||||
}
|
||||
|
||||
// If location_id is provided, filter to contacts assigned to that location
|
||||
if ($locationId) {
|
||||
$contactsQuery->whereHas('locations', function ($q) use ($locationId) {
|
||||
$q->where('locations.id', $locationId);
|
||||
});
|
||||
}
|
||||
|
||||
$contacts = $contactsQuery
|
||||
->when($query, function ($q) use ($query) {
|
||||
$q->where(function ($q2) use ($query) {
|
||||
@@ -87,6 +98,26 @@ class SearchController extends Controller
|
||||
->limit(25)
|
||||
->get(['id', 'first_name', 'last_name', 'email', 'title']);
|
||||
|
||||
// If filtering by location, include pivot data for is_primary
|
||||
if ($locationId) {
|
||||
// Reload contacts with pivot data
|
||||
$contactIds = $contacts->pluck('id')->toArray();
|
||||
$pivotData = \DB::table('location_contact')
|
||||
->whereIn('contact_id', $contactIds)
|
||||
->where('location_id', $locationId)
|
||||
->get()
|
||||
->keyBy('contact_id');
|
||||
|
||||
return response()->json(
|
||||
$contacts->map(fn ($c) => [
|
||||
'value' => $c->id,
|
||||
'label' => $c->getFullName().($c->email ? " ({$c->email})" : ''),
|
||||
'is_primary' => $pivotData[$c->id]->is_primary ?? false,
|
||||
'role' => $pivotData[$c->id]->role ?? null,
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
return response()->json(
|
||||
$contacts->map(fn ($c) => [
|
||||
'value' => $c->id,
|
||||
|
||||
@@ -29,9 +29,9 @@ class StoreBrandRequest extends FormRequest
|
||||
|
||||
return [
|
||||
'name' => 'required|string|max:255',
|
||||
'tagline' => ['nullable', 'string', 'min:30', 'max:45'],
|
||||
'description' => ['nullable', 'string', 'min:100', 'max:150'],
|
||||
'long_description' => ['nullable', 'string', 'max:500'],
|
||||
'tagline' => ['nullable', 'string', 'max:255'],
|
||||
'description' => ['nullable', 'string', 'max:1000'],
|
||||
'long_description' => ['nullable', 'string', 'max:5000'],
|
||||
'brand_announcement' => ['nullable', 'string', 'max:500'],
|
||||
'website_url' => 'nullable|string|max:255',
|
||||
|
||||
|
||||
@@ -30,9 +30,9 @@ class UpdateBrandRequest extends FormRequest
|
||||
|
||||
return [
|
||||
'name' => 'required|string|max:255',
|
||||
'tagline' => ['nullable', 'string', 'min:30', 'max:45'],
|
||||
'description' => ['nullable', 'string', 'min:100', 'max:150'],
|
||||
'long_description' => ['nullable', 'string', 'max:500'],
|
||||
'tagline' => ['nullable', 'string', 'max:255'],
|
||||
'description' => ['nullable', 'string', 'max:1000'],
|
||||
'long_description' => ['nullable', 'string', 'max:5000'],
|
||||
'brand_announcement' => ['nullable', 'string', 'max:500'],
|
||||
'website_url' => 'nullable|string|max:255',
|
||||
|
||||
|
||||
159
app/Jobs/CalculateBrandAnalysisMetrics.php
Normal file
159
app/Jobs/CalculateBrandAnalysisMetrics.php
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\Brand;
|
||||
use App\Models\Business;
|
||||
use App\Services\Cannaiq\BrandAnalysisService;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Background job to pre-calculate Brand Analysis metrics.
|
||||
*
|
||||
* This job runs in the background to compute expensive engagement and sentiment
|
||||
* metrics for brands, caching the results for 2 hours. This prevents N+1 queries
|
||||
* and expensive aggregations from running on page load.
|
||||
*
|
||||
* Schedule: Every 2 hours via Horizon
|
||||
* Queue: default (or 'analytics' if available)
|
||||
*
|
||||
* Key benefits:
|
||||
* - Aggregates CRM message counts, response rates, and quote/order metrics in batch
|
||||
* - Pre-computes buyer engagement scores
|
||||
* - For CannaiQ-enabled businesses, also pre-computes sentiment scores
|
||||
* - Uses existing BrandAnalysisService caching mechanism (2-hour TTL)
|
||||
*/
|
||||
class CalculateBrandAnalysisMetrics implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* The business to calculate metrics for (null = all seller businesses)
|
||||
*/
|
||||
public ?int $businessId;
|
||||
|
||||
/**
|
||||
* The brand to calculate metrics for (null = all brands in business)
|
||||
*/
|
||||
public ?int $brandId;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*/
|
||||
public function __construct(?int $businessId = null, ?int $brandId = null)
|
||||
{
|
||||
$this->businessId = $businessId;
|
||||
$this->brandId = $brandId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*/
|
||||
public function handle(BrandAnalysisService $service): void
|
||||
{
|
||||
$startTime = microtime(true);
|
||||
$processedCount = 0;
|
||||
|
||||
try {
|
||||
if ($this->businessId && $this->brandId) {
|
||||
// Single brand calculation
|
||||
$this->calculateForBrand($service, $this->businessId, $this->brandId);
|
||||
$processedCount = 1;
|
||||
} elseif ($this->businessId) {
|
||||
// All brands for a single business
|
||||
$processedCount = $this->calculateForBusiness($service, $this->businessId);
|
||||
} else {
|
||||
// All seller businesses with active brands
|
||||
$processedCount = $this->calculateForAllBusinesses($service);
|
||||
}
|
||||
|
||||
$duration = round(microtime(true) - $startTime, 2);
|
||||
Log::info('CalculateBrandAnalysisMetrics completed', [
|
||||
'business_id' => $this->businessId ?? 'all',
|
||||
'brand_id' => $this->brandId ?? 'all',
|
||||
'brands_processed' => $processedCount,
|
||||
'duration_seconds' => $duration,
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('CalculateBrandAnalysisMetrics failed', [
|
||||
'business_id' => $this->businessId,
|
||||
'brand_id' => $this->brandId,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate metrics for all seller businesses
|
||||
*/
|
||||
private function calculateForAllBusinesses(BrandAnalysisService $service): int
|
||||
{
|
||||
$processedCount = 0;
|
||||
|
||||
Business::where('type', 'seller')
|
||||
->where('status', 'approved')
|
||||
->chunk(10, function ($businesses) use ($service, &$processedCount) {
|
||||
foreach ($businesses as $business) {
|
||||
$processedCount += $this->calculateForBusiness($service, $business->id);
|
||||
}
|
||||
});
|
||||
|
||||
return $processedCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate metrics for all active brands in a business
|
||||
*/
|
||||
private function calculateForBusiness(BrandAnalysisService $service, int $businessId): int
|
||||
{
|
||||
$business = Business::find($businessId);
|
||||
if (! $business) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$brands = Brand::where('business_id', $businessId)
|
||||
->where('is_active', true)
|
||||
->get();
|
||||
|
||||
foreach ($brands as $brand) {
|
||||
$this->calculateForBrand($service, $businessId, $brand->id);
|
||||
}
|
||||
|
||||
return $brands->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate metrics for a single brand
|
||||
*/
|
||||
private function calculateForBrand(BrandAnalysisService $service, int $businessId, int $brandId): void
|
||||
{
|
||||
$business = Business::find($businessId);
|
||||
$brand = Brand::find($brandId);
|
||||
|
||||
if (! $business || ! $brand) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This triggers the full analysis calculation and caches it
|
||||
// The BrandAnalysisService handles caching internally with 2-hour TTL
|
||||
$service->refreshAnalysis($brand, $business);
|
||||
}
|
||||
|
||||
/**
|
||||
* The job failed to process.
|
||||
*/
|
||||
public function failed(\Throwable $exception): void
|
||||
{
|
||||
Log::error('CalculateBrandAnalysisMetrics job failed', [
|
||||
'business_id' => $this->businessId,
|
||||
'brand_id' => $this->brandId,
|
||||
'exception' => $exception->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ use DateTime;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
@@ -134,6 +135,17 @@ class Contact extends Model
|
||||
return $this->belongsTo(Location::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Locations this contact is assigned to via the location_contact pivot table.
|
||||
* This is the many-to-many relationship for location-specific contact assignments.
|
||||
*/
|
||||
public function locations(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Location::class, 'location_contact')
|
||||
->withPivot(['role', 'is_primary', 'notes'])
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
|
||||
@@ -13,6 +13,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* CRM Quote - Sales quotation with line items
|
||||
@@ -26,6 +27,17 @@ class CrmQuote extends Model
|
||||
|
||||
protected $table = 'crm_quotes';
|
||||
|
||||
protected static function boot(): void
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::creating(function ($quote) {
|
||||
if (empty($quote->view_token)) {
|
||||
$quote->view_token = Str::random(32);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public const STATUS_DRAFT = 'draft';
|
||||
|
||||
public const STATUS_SENT = 'sent';
|
||||
@@ -47,6 +59,7 @@ class CrmQuote extends Model
|
||||
'quote_number',
|
||||
'title',
|
||||
'status',
|
||||
'quote_date',
|
||||
'subtotal',
|
||||
'discount_type',
|
||||
'discount_value',
|
||||
@@ -73,6 +86,7 @@ class CrmQuote extends Model
|
||||
'order_id',
|
||||
'notes_customer',
|
||||
'notes_internal',
|
||||
'view_token',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
@@ -83,6 +97,7 @@ class CrmQuote extends Model
|
||||
'tax_amount' => 'decimal:2',
|
||||
'total' => 'decimal:2',
|
||||
'signature_requested' => 'boolean',
|
||||
'quote_date' => 'date',
|
||||
'valid_until' => 'date',
|
||||
'sent_at' => 'datetime',
|
||||
'viewed_at' => 'datetime',
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Traits\BelongsToBusinessDirectly;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
@@ -94,6 +95,12 @@ class Location extends Model
|
||||
'transferred_to_business_id', // For ownership transfers
|
||||
'settings', // JSON
|
||||
'notes',
|
||||
|
||||
// CannaiQ Integration
|
||||
'cannaiq_platform',
|
||||
'cannaiq_store_slug',
|
||||
'cannaiq_store_id',
|
||||
'cannaiq_store_name',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
@@ -122,11 +129,57 @@ class Location extends Model
|
||||
return $this->hasMany(License::class);
|
||||
}
|
||||
|
||||
public function contacts(): HasMany
|
||||
/**
|
||||
* Contacts directly associated with this location (location_id on contact)
|
||||
*/
|
||||
public function directContacts(): HasMany
|
||||
{
|
||||
return $this->hasMany(Contact::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contacts assigned to this location via pivot with roles
|
||||
*/
|
||||
public function contacts(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Contact::class, 'location_contact')
|
||||
->withPivot(['role', 'is_primary', 'notes'])
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get contacts with a specific role for this location
|
||||
*/
|
||||
public function contactsByRole(string $role)
|
||||
{
|
||||
return $this->contacts()->wherePivot('role', $role);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the primary buyer contact for this location
|
||||
*/
|
||||
public function getPrimaryBuyer()
|
||||
{
|
||||
return $this->contacts()
|
||||
->wherePivot('role', 'buyer')
|
||||
->wherePivot('is_primary', true)
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get buyer names as a comma-separated label
|
||||
*/
|
||||
public function getBuyersLabelAttribute(): ?string
|
||||
{
|
||||
$buyers = $this->contacts()->wherePivot('role', 'buyer')->get();
|
||||
|
||||
if ($buyers->isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $buyers->map(fn ($c) => $c->getFullName())->implode(', ');
|
||||
}
|
||||
|
||||
public function addresses(): MorphMany
|
||||
{
|
||||
return $this->morphMany(Address::class, 'addressable');
|
||||
@@ -250,4 +303,25 @@ class Location extends Model
|
||||
'archived_reason' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this location has CannaiQ store mapping
|
||||
*/
|
||||
public function hasCannaiqMapping(): bool
|
||||
{
|
||||
return ! empty($this->cannaiq_store_slug);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the CannaiQ store mapping
|
||||
*/
|
||||
public function clearCannaiqMapping(): void
|
||||
{
|
||||
$this->update([
|
||||
'cannaiq_platform' => null,
|
||||
'cannaiq_store_slug' => null,
|
||||
'cannaiq_store_id' => null,
|
||||
'cannaiq_store_name' => null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +109,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
$versionData = cache()->remember('app.version_data', now()->addSeconds(5), function () {
|
||||
$version = 'dev';
|
||||
$commit = 'unknown';
|
||||
$buildDate = null;
|
||||
|
||||
// For Docker: read from version.env (injected at build time)
|
||||
$versionFile = base_path('version.env');
|
||||
@@ -117,6 +118,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
$data = parse_ini_file($versionFile);
|
||||
$version = $data['VERSION'] ?? 'dev';
|
||||
$commit = $data['COMMIT'] ?? 'unknown';
|
||||
$buildDate = $data['BUILD_DATE'] ?? null;
|
||||
}
|
||||
// For local dev: read from git directly (but cached for 5 seconds)
|
||||
// Check for .git (directory for regular repos, file for worktrees)
|
||||
@@ -128,6 +130,13 @@ class AppServiceProvider extends ServiceProvider
|
||||
|
||||
// Only proceed if we successfully got a commit SHA
|
||||
if ($commit !== '' && $commit !== 'unknown') {
|
||||
// Get commit date for local dev
|
||||
$dateCommand = sprintf('cd %s && git log -1 --format=%%ci 2>/dev/null', escapeshellarg(base_path()));
|
||||
$commitDate = trim(shell_exec($dateCommand) ?: '');
|
||||
if ($commitDate) {
|
||||
$buildDate = date('M j, g:ia', strtotime($commitDate));
|
||||
}
|
||||
|
||||
// Check for uncommitted changes (dirty working directory)
|
||||
$diffCommand = sprintf('cd %s && git diff --quiet 2>/dev/null; echo $?', escapeshellarg(base_path()));
|
||||
$cachedCommand = sprintf('cd %s && git diff --cached --quiet 2>/dev/null; echo $?', escapeshellarg(base_path()));
|
||||
@@ -147,17 +156,19 @@ class AppServiceProvider extends ServiceProvider
|
||||
return [
|
||||
'version' => $version,
|
||||
'commit' => $commit,
|
||||
'buildDate' => $buildDate,
|
||||
];
|
||||
});
|
||||
} catch (\Exception $e) {
|
||||
// If cache fails (e.g., Redis not ready), calculate version without caching
|
||||
$versionData = ['version' => 'dev', 'commit' => 'unknown'];
|
||||
$versionData = ['version' => 'dev', 'commit' => 'unknown', 'buildDate' => null];
|
||||
|
||||
$versionFile = base_path('version.env');
|
||||
if (File::exists($versionFile)) {
|
||||
$data = parse_ini_file($versionFile);
|
||||
$versionData['version'] = $data['VERSION'] ?? 'dev';
|
||||
$versionData['commit'] = $data['COMMIT'] ?? 'unknown';
|
||||
$versionData['buildDate'] = $data['BUILD_DATE'] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,6 +176,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
$view->with([
|
||||
'appVersion' => $versionData['version'],
|
||||
'appCommit' => $versionData['commit'],
|
||||
'appBuildDate' => $versionData['buildDate'],
|
||||
'appVersionFull' => "{$versionData['version']} (sha-{$versionData['commit']})",
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -260,10 +260,10 @@ class BrandVoicePrompt
|
||||
* AI generation MUST respect these limits.
|
||||
*/
|
||||
public const CHARACTER_LIMITS = [
|
||||
'tagline' => ['min' => 30, 'max' => 45, 'label' => 'Tagline'],
|
||||
'short_description' => ['min' => 100, 'max' => 150, 'label' => 'Short Description'],
|
||||
'description' => ['min' => 100, 'max' => 150, 'label' => 'Short Description'], // Alias
|
||||
'long_description' => ['min' => 400, 'max' => 500, 'label' => 'Long Description'],
|
||||
'tagline' => ['min' => null, 'max' => 255, 'label' => 'Tagline'],
|
||||
'short_description' => ['min' => null, 'max' => 1000, 'label' => 'Short Description'],
|
||||
'description' => ['min' => null, 'max' => 1000, 'label' => 'Short Description'], // Alias
|
||||
'long_description' => ['min' => null, 'max' => 5000, 'label' => 'Long Description'],
|
||||
'brand_announcement' => ['min' => 400, 'max' => 500, 'label' => 'Brand Announcement'],
|
||||
'seo_title' => ['min' => 60, 'max' => 70, 'label' => 'SEO Title'],
|
||||
'seo_description' => ['min' => 150, 'max' => 160, 'label' => 'SEO Description'],
|
||||
@@ -803,6 +803,11 @@ class BrandVoicePrompt
|
||||
return '';
|
||||
}
|
||||
|
||||
// If no min is set, only enforce max
|
||||
if ($limits['min'] === null) {
|
||||
return "CHARACTER LIMIT: Output should not exceed {$limits['max']} characters.";
|
||||
}
|
||||
|
||||
return "STRICT CHARACTER LIMIT: Output MUST be between {$limits['min']}-{$limits['max']} characters. Do NOT output fewer than {$limits['min']} or more than {$limits['max']} characters.";
|
||||
}
|
||||
|
||||
|
||||
533
app/Services/Cannaiq/AdvancedV3IntelligenceDTO.php
Normal file
533
app/Services/Cannaiq/AdvancedV3IntelligenceDTO.php
Normal file
@@ -0,0 +1,533 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Cannaiq;
|
||||
|
||||
/**
|
||||
* Advanced v4 Intelligence Data Transfer Object
|
||||
*
|
||||
* Contains advanced brand intelligence analytics including:
|
||||
* - Brand positioning and differentiation scoring (v3)
|
||||
* - Trend lead/lag analysis (predictive vs laggy behavior) (v3)
|
||||
* - Cross-state market signals (v3)
|
||||
* - Shelf displacement opportunities (v3)
|
||||
* - Shelf value projections with capture scenarios (v4)
|
||||
*
|
||||
* v4.0 Additions:
|
||||
* - shelfValueProjections: Revenue projections by scope (store/state/multi_state)
|
||||
* - capture_scenarios: 10%, 25%, 50% market capture modeling
|
||||
* - opportunity_label: "Big prize, low effort" etc.
|
||||
* - consumerDemand: Consumer Demand Index + SKU lifecycle stages
|
||||
* - elasticity: Price elasticity metrics per SKU
|
||||
* - competitiveThreat: Competitive pressure scoring
|
||||
* - portfolioBalance: Category mix, redundancy clusters, gaps
|
||||
*
|
||||
* All data is derived from existing CannaiQ + internal data; no new scrapes.
|
||||
*/
|
||||
class AdvancedV3IntelligenceDTO
|
||||
{
|
||||
public function __construct(
|
||||
// v3.0 fields
|
||||
public readonly ?array $brandPositioning = null,
|
||||
public readonly ?array $trendLeadLag = null,
|
||||
public readonly array $marketSignals = [],
|
||||
public readonly array $shelfOpportunities = [],
|
||||
// v4.0: Shelf value projections with capture scenarios
|
||||
public readonly array $shelfValueProjections = [],
|
||||
// v4.0: Consumer Demand Index + SKU lifecycle
|
||||
public readonly ?array $consumerDemand = null,
|
||||
// v4.0: Price elasticity metrics
|
||||
public readonly ?array $elasticity = null,
|
||||
// v4.0: Competitive threat scoring
|
||||
public readonly ?array $competitiveThreat = null,
|
||||
// v4.0: Portfolio balance analysis
|
||||
public readonly ?array $portfolioBalance = null,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Create empty DTO when data is unavailable
|
||||
*/
|
||||
public static function empty(): self
|
||||
{
|
||||
return new self(
|
||||
brandPositioning: null,
|
||||
trendLeadLag: null,
|
||||
marketSignals: [],
|
||||
shelfOpportunities: [],
|
||||
shelfValueProjections: [],
|
||||
consumerDemand: null,
|
||||
elasticity: null,
|
||||
competitiveThreat: null,
|
||||
portfolioBalance: null,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty brand positioning structure
|
||||
*
|
||||
* Structure:
|
||||
* - differentiation_score: 0-100 (how unique vs competitors)
|
||||
* - positioning_label: 'more_of_the_same'|'value_disruptor'|'premium_standout'|'potency_leader'|'format_outlier'
|
||||
* - comparables: Array of similar brands with distance scores
|
||||
* - notes: Array of bullet explanations
|
||||
*/
|
||||
public static function emptyBrandPositioning(): array
|
||||
{
|
||||
return [
|
||||
'differentiation_score' => null,
|
||||
'positioning_label' => 'more_of_the_same',
|
||||
'comparables' => [],
|
||||
'notes' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty trend lead/lag structure
|
||||
*
|
||||
* Structure:
|
||||
* - lead_lag_index: -100 (laggy) to +100 (predictive)
|
||||
* - classification: 'strong_leader'|'emerging_leader'|'in_line'|'follower'|'laggy'
|
||||
* - supporting_signals: Array of category-level signals
|
||||
*/
|
||||
public static function emptyTrendLeadLag(): array
|
||||
{
|
||||
return [
|
||||
'lead_lag_index' => 0,
|
||||
'classification' => 'in_line',
|
||||
'supporting_signals' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty market signal structure
|
||||
*
|
||||
* Structure:
|
||||
* - scope: 'multi_state'|'state'|'category'
|
||||
* - state_code: optional state
|
||||
* - category: optional category
|
||||
* - description: human-readable summary
|
||||
* - trend_strength: 0-100
|
||||
* - relevant_to_brand: bool
|
||||
* - brand_fit: 'strong_fit'|'partial_fit'|'gap'
|
||||
* - example_brand: optional example
|
||||
*/
|
||||
public static function emptyMarketSignal(): array
|
||||
{
|
||||
return [
|
||||
'scope' => 'category',
|
||||
'state_code' => null,
|
||||
'category' => null,
|
||||
'description' => '',
|
||||
'trend_strength' => 0,
|
||||
'relevant_to_brand' => false,
|
||||
'brand_fit' => 'gap',
|
||||
'example_brand' => null,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty shelf opportunity structure
|
||||
*
|
||||
* Structure:
|
||||
* - store_id: CannaiQ store external ID
|
||||
* - store_name: Store display name
|
||||
* - state_code: State abbreviation
|
||||
* - opportunity_type: 'whitespace'|'displacement'
|
||||
* - competitor_brand: null for whitespace
|
||||
* - competitor_product_name: null for whitespace
|
||||
* - our_best_sku_id: our matching product ID
|
||||
* - our_best_sku_name: our matching product name
|
||||
* - est_monthly_units_current: competitor's current volume
|
||||
* - est_monthly_units_if_we_win: projected volume if we win
|
||||
* - est_monthly_revenue_if_we_win: projected revenue
|
||||
* - quality_score_delta: -100 to +100 (positive = we're better)
|
||||
* - value_score_delta: -100 to +100 (positive = better value)
|
||||
* - displacement_difficulty: 'low'|'medium'|'high'
|
||||
* - difficulty_score: 0-100 (100 = hardest)
|
||||
* - rationale_tags: Array of reason strings
|
||||
*/
|
||||
public static function emptyShelfOpportunity(): array
|
||||
{
|
||||
return [
|
||||
'store_id' => null,
|
||||
'store_name' => 'Unknown',
|
||||
'state_code' => null,
|
||||
'opportunity_type' => 'whitespace',
|
||||
'competitor_brand' => null,
|
||||
'competitor_product_name' => null,
|
||||
'our_best_sku_id' => null,
|
||||
'our_best_sku_name' => null,
|
||||
'est_monthly_units_current' => 0,
|
||||
'est_monthly_units_if_we_win' => 0,
|
||||
'est_monthly_revenue_if_we_win' => 0,
|
||||
'quality_score_delta' => 0,
|
||||
'value_score_delta' => 0,
|
||||
'displacement_difficulty' => 'medium',
|
||||
'difficulty_score' => 50,
|
||||
'rationale_tags' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty shelf value projection structure (v4.0)
|
||||
*
|
||||
* Structure:
|
||||
* - scope: 'store'|'state'|'multi_state' - geographic scope of projection
|
||||
* - store_id: CannaiQ store ID (when scope='store')
|
||||
* - store_name: Store display name (when scope='store')
|
||||
* - state_code: State abbreviation (when scope='store' or 'state')
|
||||
* - current_competitor_sales: Competitor revenue currently on shelf
|
||||
* - category_total_sales: Total category sales at location
|
||||
* - our_current_share: Our % of category sales (0.0-1.0)
|
||||
* - our_current_shelf_value: Our current monthly revenue at location
|
||||
* - avg_displacement_difficulty: 0-100 (aggregated from opportunities)
|
||||
* - opportunity_label: 'Big prize, low effort'|'Low-hanging fruit'|'High potential, high difficulty'|'Grind zone'
|
||||
* - capture_scenarios: Array of capture scenario projections
|
||||
*/
|
||||
public static function emptyShelfValueProjection(): array
|
||||
{
|
||||
return [
|
||||
'scope' => 'store',
|
||||
'store_id' => null,
|
||||
'store_name' => null,
|
||||
'state_code' => null,
|
||||
'current_competitor_sales' => 0,
|
||||
'category_total_sales' => 0,
|
||||
'our_current_share' => 0,
|
||||
'our_current_shelf_value' => 0,
|
||||
'avg_displacement_difficulty' => 50,
|
||||
'opportunity_label' => 'Grind zone',
|
||||
'capture_scenarios' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty capture scenario structure (v4.0)
|
||||
*
|
||||
* Structure:
|
||||
* - capture_percent: 10|25|50 - % of competitor shelf to capture
|
||||
* - projected_monthly_revenue: Revenue if we achieve this capture
|
||||
* - projected_units: Units if we achieve this capture
|
||||
* - revenue_lift_from_current: Delta from our current revenue
|
||||
* - effort_level: 'low'|'medium'|'high' - based on difficulty + capture %
|
||||
*/
|
||||
public static function emptyCaptureScenario(): array
|
||||
{
|
||||
return [
|
||||
'capture_percent' => 10,
|
||||
'projected_monthly_revenue' => 0,
|
||||
'projected_units' => 0,
|
||||
'revenue_lift_from_current' => 0,
|
||||
'effort_level' => 'medium',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get opportunity label based on value and difficulty
|
||||
*
|
||||
* @param float $value Estimated monthly revenue opportunity
|
||||
* @param int $difficulty 0-100 difficulty score
|
||||
*/
|
||||
public static function getOpportunityLabel(float $value, int $difficulty): string
|
||||
{
|
||||
// High value threshold: $5,000/mo
|
||||
// Low difficulty threshold: 40
|
||||
$highValue = $value >= 5000;
|
||||
$lowDifficulty = $difficulty <= 40;
|
||||
|
||||
return match (true) {
|
||||
$highValue && $lowDifficulty => 'Big prize, low effort',
|
||||
! $highValue && $lowDifficulty => 'Low-hanging fruit',
|
||||
$highValue && ! $lowDifficulty => 'High potential, high difficulty',
|
||||
default => 'Grind zone',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to array for views
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'brandPositioning' => $this->brandPositioning,
|
||||
'trendLeadLag' => $this->trendLeadLag,
|
||||
'marketSignals' => $this->marketSignals,
|
||||
'shelfOpportunities' => $this->shelfOpportunities,
|
||||
'shelfValueProjections' => $this->shelfValueProjections,
|
||||
'consumerDemand' => $this->consumerDemand,
|
||||
'elasticity' => $this->elasticity,
|
||||
'competitiveThreat' => $this->competitiveThreat,
|
||||
'portfolioBalance' => $this->portfolioBalance,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if any v3/v4 intelligence data is available
|
||||
*/
|
||||
public function hasData(): bool
|
||||
{
|
||||
return $this->brandPositioning !== null
|
||||
|| $this->trendLeadLag !== null
|
||||
|| ! empty($this->marketSignals)
|
||||
|| ! empty($this->shelfOpportunities)
|
||||
|| ! empty($this->shelfValueProjections)
|
||||
|| $this->consumerDemand !== null
|
||||
|| $this->elasticity !== null
|
||||
|| $this->competitiveThreat !== null
|
||||
|| $this->portfolioBalance !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty consumer demand structure (v4.0)
|
||||
*
|
||||
* Structure:
|
||||
* - consumer_demand_index: 0-100 overall brand demand score
|
||||
* - sku_scores: Array of per-SKU demand metrics
|
||||
*/
|
||||
public static function emptyConsumerDemand(): array
|
||||
{
|
||||
return [
|
||||
'consumer_demand_index' => null,
|
||||
'sku_scores' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty SKU demand score structure (v4.0)
|
||||
*
|
||||
* Structure:
|
||||
* - product_id: Internal product ID
|
||||
* - product_name: Display name
|
||||
* - demand_index: 0-100 demand score
|
||||
* - promo_independence: 0-100 (higher = sells well without promos)
|
||||
* - cross_store_consistency: 0-100 (higher = consistent across stores)
|
||||
* - stage: 'launch'|'growth'|'peak'|'decline'|'terminal'|null
|
||||
*/
|
||||
public static function emptySkuDemandScore(): array
|
||||
{
|
||||
return [
|
||||
'product_id' => null,
|
||||
'product_name' => 'Unknown',
|
||||
'demand_index' => null,
|
||||
'promo_independence' => null,
|
||||
'cross_store_consistency' => null,
|
||||
'stage' => null,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty elasticity structure (v4.0)
|
||||
*
|
||||
* Structure:
|
||||
* - sku_elasticity: Array of per-SKU price elasticity metrics
|
||||
*/
|
||||
public static function emptyElasticity(): array
|
||||
{
|
||||
return [
|
||||
'sku_elasticity' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty SKU elasticity structure (v4.0)
|
||||
*
|
||||
* Structure:
|
||||
* - product_id: Internal product ID
|
||||
* - product_name: Display name
|
||||
* - current_price: Current average price
|
||||
* - elasticity: Numeric elasticity coefficient (negative = price sensitive)
|
||||
* - price_behavior: 'sensitive'|'stable'|'room_to_raise'|null
|
||||
* - note: Human-readable recommendation
|
||||
*/
|
||||
public static function emptySkuElasticity(): array
|
||||
{
|
||||
return [
|
||||
'product_id' => null,
|
||||
'product_name' => 'Unknown',
|
||||
'current_price' => null,
|
||||
'elasticity' => null,
|
||||
'price_behavior' => null,
|
||||
'note' => null,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty competitive threat structure (v4.0)
|
||||
*
|
||||
* Structure:
|
||||
* - overall_threat_score: 0-100 aggregate threat level
|
||||
* - threat_level: 'low'|'medium'|'high'
|
||||
* - threats: Array of competitor threat details
|
||||
*/
|
||||
public static function emptyCompetitiveThreat(): array
|
||||
{
|
||||
return [
|
||||
'overall_threat_score' => null,
|
||||
'threat_level' => null,
|
||||
'threats' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty competitor threat structure (v4.0)
|
||||
*
|
||||
* Structure:
|
||||
* - brand_name: Competitor brand name
|
||||
* - threat_score: 0-100 individual threat score
|
||||
* - price_aggression: 0-100 (how aggressively they undercut)
|
||||
* - velocity_trend: -100 to +100 (their growth vs decline)
|
||||
* - overlap_score: 0-100 (category/store overlap)
|
||||
* - notes: Array of threat reasons
|
||||
*/
|
||||
public static function emptyThreatBrand(): array
|
||||
{
|
||||
return [
|
||||
'brand_name' => 'Unknown',
|
||||
'threat_score' => null,
|
||||
'price_aggression' => null,
|
||||
'velocity_trend' => null,
|
||||
'overlap_score' => null,
|
||||
'notes' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty portfolio balance structure (v4.0)
|
||||
*
|
||||
* Structure:
|
||||
* - category_mix: Array of category distribution
|
||||
* - redundancy_clusters: Array of similar SKU groupings
|
||||
* - gaps: Array of identified portfolio gaps
|
||||
*/
|
||||
public static function emptyPortfolioBalance(): array
|
||||
{
|
||||
return [
|
||||
'category_mix' => [],
|
||||
'redundancy_clusters' => [],
|
||||
'gaps' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty category mix item structure (v4.0)
|
||||
*/
|
||||
public static function emptyCategoryMix(): array
|
||||
{
|
||||
return [
|
||||
'category' => 'Unknown',
|
||||
'sku_count' => 0,
|
||||
'revenue_share_percent' => null,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty redundancy cluster structure (v4.0)
|
||||
*/
|
||||
public static function emptyRedundancyCluster(): array
|
||||
{
|
||||
return [
|
||||
'cluster_id' => null,
|
||||
'label' => 'Unknown',
|
||||
'product_ids' => [],
|
||||
'note' => null,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty portfolio gap structure (v4.0)
|
||||
*/
|
||||
public static function emptyPortfolioGap(): array
|
||||
{
|
||||
return [
|
||||
'category' => 'Unknown',
|
||||
'description' => null,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get threat level label from score
|
||||
*/
|
||||
public static function getThreatLevel(float $score): string
|
||||
{
|
||||
return match (true) {
|
||||
$score >= 70 => 'high',
|
||||
$score >= 40 => 'medium',
|
||||
default => 'low',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lifecycle stage from velocity metrics
|
||||
*
|
||||
* @param float $velocity Current daily velocity
|
||||
* @param float|null $velocityTrend % change vs prior period (-100 to +100)
|
||||
* @param float $categoryAvgVelocity Category average velocity
|
||||
*/
|
||||
public static function getLifecycleStage(float $velocity, ?float $velocityTrend, float $categoryAvgVelocity): string
|
||||
{
|
||||
$relativeVelocity = $categoryAvgVelocity > 0 ? $velocity / $categoryAvgVelocity : 0;
|
||||
|
||||
// Very low velocity with flat/declining trend = terminal
|
||||
if ($relativeVelocity < 0.2 && ($velocityTrend === null || $velocityTrend <= 0)) {
|
||||
return 'terminal';
|
||||
}
|
||||
|
||||
// Low velocity but growing = launch
|
||||
if ($relativeVelocity < 0.5 && $velocityTrend !== null && $velocityTrend > 20) {
|
||||
return 'launch';
|
||||
}
|
||||
|
||||
// Medium velocity with strong growth = growth
|
||||
if ($velocityTrend !== null && $velocityTrend > 10) {
|
||||
return 'growth';
|
||||
}
|
||||
|
||||
// High velocity, stable = peak
|
||||
if ($relativeVelocity >= 0.8 && ($velocityTrend === null || abs($velocityTrend) <= 10)) {
|
||||
return 'peak';
|
||||
}
|
||||
|
||||
// Declining = decline
|
||||
if ($velocityTrend !== null && $velocityTrend < -10) {
|
||||
return 'decline';
|
||||
}
|
||||
|
||||
// Default to growth for healthy products
|
||||
return 'growth';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get positioning label for display
|
||||
*/
|
||||
public function getPositioningLabelDisplay(): string
|
||||
{
|
||||
if (! $this->brandPositioning) {
|
||||
return 'Unknown';
|
||||
}
|
||||
|
||||
return match ($this->brandPositioning['positioning_label'] ?? 'more_of_the_same') {
|
||||
'value_disruptor' => 'Value Disruptor',
|
||||
'premium_standout' => 'Premium Standout',
|
||||
'potency_leader' => 'Potency Leader',
|
||||
'format_outlier' => 'Format Outlier',
|
||||
default => 'More of the Same',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get trend classification for display
|
||||
*/
|
||||
public function getTrendClassificationDisplay(): string
|
||||
{
|
||||
if (! $this->trendLeadLag) {
|
||||
return 'Unknown';
|
||||
}
|
||||
|
||||
return match ($this->trendLeadLag['classification'] ?? 'in_line') {
|
||||
'strong_leader' => 'Predictive (Leads Market)',
|
||||
'emerging_leader' => 'Early Mover',
|
||||
'follower' => 'Follower',
|
||||
'laggy' => 'Laggy (Follows Late)',
|
||||
default => 'In Line with Market',
|
||||
};
|
||||
}
|
||||
}
|
||||
1895
app/Services/Cannaiq/AdvancedV3IntelligenceService.php
Normal file
1895
app/Services/Cannaiq/AdvancedV3IntelligenceService.php
Normal file
File diff suppressed because it is too large
Load Diff
337
app/Services/Cannaiq/BrandAnalysisDTO.php
Normal file
337
app/Services/Cannaiq/BrandAnalysisDTO.php
Normal file
@@ -0,0 +1,337 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Cannaiq;
|
||||
|
||||
/**
|
||||
* Brand Analysis Data Transfer Object (v3.0)
|
||||
*
|
||||
* Contains all market intelligence data for a brand, structured for the Analysis page.
|
||||
* When CannaiQ is disabled, contains only internal sales data.
|
||||
* When CannaiQ is enabled, enriched with market intelligence.
|
||||
*
|
||||
* v2.0 Additions:
|
||||
* - engagement: Buyer outreach and response tracking (always available)
|
||||
* - sentiment: Store support and brand positioning (CannaiQ only)
|
||||
*
|
||||
* v3.0 Additions:
|
||||
* - advancedV3: Advanced intelligence analytics (CannaiQ only)
|
||||
* - brandPositioning: Differentiation score and positioning label
|
||||
* - trendLeadLag: Predictive vs laggy behavior analysis
|
||||
* - marketSignals: Cross-state market trends
|
||||
* - shelfOpportunities: Displacement opportunities with difficulty scores
|
||||
*
|
||||
* Structure Reference (v1.5):
|
||||
*
|
||||
* placement: [
|
||||
* 'stores' => [...], // List of stores carrying brand
|
||||
* 'whitespaceStores' => [...], // v1.5: Stores with competitors but not us
|
||||
* 'whitespaceCount' => int, // v1.5: Count of whitespace opportunities
|
||||
* 'penetrationByRegion' => [ // v1.5: Regional breakdown
|
||||
* ['region' => 'CA', 'storeCount' => 10, 'totalStores' => 50, 'penetrationPercent' => 20],
|
||||
* ],
|
||||
* ]
|
||||
*
|
||||
* competitors: [
|
||||
* 'competitors' => [...], // List of competitor brands
|
||||
* 'pricePosition' => 'value'|'mid'|'premium', // v1.5: Our price position
|
||||
* 'headToHeadSkus' => [ // v1.5: Direct SKU comparisons
|
||||
* ['ourSku' => '...', 'competitorSku' => '...', 'ourVelocity' => 0.5, ...],
|
||||
* ],
|
||||
* 'marketShareTrend' => [ // v1.5: Time series market share
|
||||
* ['period' => '2025-01', 'ourShare' => 12.5, 'competitor1Share' => 15.2, ...],
|
||||
* ],
|
||||
* ]
|
||||
*
|
||||
* promoPerformance: [
|
||||
* [
|
||||
* 'id' => ..., 'name' => ...,
|
||||
* 'baselineVelocity' => float, // v1.5: Non-promo velocity
|
||||
* 'promoVelocity' => float, // v1.5: During-promo velocity
|
||||
* 'velocityLift' => float, // v1.5: Percent lift
|
||||
* 'efficiencyScore' => float, // v1.5: Units gained per discount dollar
|
||||
* ],
|
||||
* ]
|
||||
*
|
||||
* inventoryProjection: [
|
||||
* 'items' => [ // v1.5: Structured items array
|
||||
* ['sku' => '...', 'daysOfStock' => int, 'riskLevel' => 'low'|'medium'|'high', ...],
|
||||
* ],
|
||||
* 'overstockedItems' => [...], // v1.5: Items with >90 days supply
|
||||
* 'rollup' => [ // v1.5: Brand-level summary
|
||||
* 'criticalCount' => int,
|
||||
* 'warningCount' => int,
|
||||
* 'overstockedSkuCount' => int,
|
||||
* 'riskLevel' => 'healthy'|'moderate'|'elevated'|'critical',
|
||||
* ],
|
||||
* ]
|
||||
*
|
||||
* slippage: [
|
||||
* 'alerts' => [...], // Basic alerts (existing)
|
||||
* 'summary' => [ // v1.5: Summary metrics
|
||||
* 'lostStores30dCount' => int,
|
||||
* 'lostStores60dCount' => int,
|
||||
* 'lostSkus30dCount' => int,
|
||||
* 'competitorTakeoverCount' => int,
|
||||
* ],
|
||||
* 'lostStores30d' => [...], // v1.5: List of lost stores
|
||||
* 'lostStores60d' => [...],
|
||||
* 'lostSkus30d' => [...], // v1.5: List of lost SKUs
|
||||
* 'competitorTakeovers' => [...], // v1.5: SKU replacement events
|
||||
* 'oosMetrics' => [ // v1.5: Out-of-stock metrics
|
||||
* 'avgOOSDuration' => float,
|
||||
* 'avgReorderLag' => float,
|
||||
* 'chronicOOSStores' => [...],
|
||||
* ],
|
||||
* ]
|
||||
*
|
||||
* engagement: [ // v2.0: Buyer outreach & response (ALWAYS available)
|
||||
* 'reach' => [
|
||||
* 'storesContacted30d' => int, // Unique stores contacted
|
||||
* 'messagesSent30d' => int, // Total outbound messages
|
||||
* 'touchesPerStore' => float, // Avg touches per store
|
||||
* 'repActivityLeaders' => [...], // Top reps by activity
|
||||
* ],
|
||||
* 'response' => [
|
||||
* 'responseRate' => float, // 0..1 reply rate
|
||||
* 'avgResponseTimeHours' => float|null, // Median reply time
|
||||
* 'storesNotResponding' => int, // Silent accounts
|
||||
* 'mostEngagedStores' => [...], // Top responding stores
|
||||
* ],
|
||||
* 'actions' => [
|
||||
* 'quotesIssued30d' => int, // Quotes tied to brand
|
||||
* 'ordersPlaced30d' => int, // Orders with brand products
|
||||
* 'conversionRate' => float|null, // Quotes → Orders
|
||||
* 'reorderRate' => float|null, // Repeat buyers
|
||||
* 'atRiskAccounts' => [...], // Accounts needing attention
|
||||
* ],
|
||||
* 'quality' => [
|
||||
* 'touchTypeBreakdown' => [...], // By channel type
|
||||
* 'buyerEngagementScore' => float|null, // 0..100
|
||||
* 'buyerEngagementLabel' => string, // "Strong partner" / "Healthy" / "At risk" / "Needs action"
|
||||
* ],
|
||||
* ]
|
||||
*
|
||||
* sentiment: [ // v2.0: Store support (CannaiQ ONLY - null when disabled)
|
||||
* 'storeSupport' => [
|
||||
* 'storesPromotingBrand30d' => int, // Stores with active promos
|
||||
* 'promoFrequencyPerStore' => float|null,// Promos per store
|
||||
* 'featuredPlacementCount' => int, // Featured/specials count
|
||||
* 'avgShelfShare' => float|null, // Category share
|
||||
* 'storeSentimentScore' => float|null, // 0..100
|
||||
* 'storeSentimentLabel' => string, // "Advocates" / "Supportive" / "Neutral" / "Unsupportive"
|
||||
* ],
|
||||
* 'pricingBehavior' => [
|
||||
* 'avgDiscountRate' => float|null, // Avg promo discount
|
||||
* 'priceRespectIndex' => float|null, // 0..100 (MSRP adherence)
|
||||
* 'competitorPricePressure' => float|null, // 0..100
|
||||
* ],
|
||||
* 'inventoryBehavior' => [
|
||||
* 'sellThroughAfterRestock' => float|null, // Units/day post-restock
|
||||
* 'restockUrgencyIndex' => float|null, // 0..100 (faster reorders = higher)
|
||||
* 'stockNeglectEvents' => int, // Extended OOS events
|
||||
* 'shelfCommitment' => [
|
||||
* 'singleSkuStores' => int, // Stores with 1 SKU
|
||||
* 'multiSkuStores' => int, // Stores with 3+ SKUs
|
||||
* 'avgSkusPerStore' => float|null, // Avg SKU depth
|
||||
* ],
|
||||
* ],
|
||||
* ]
|
||||
*/
|
||||
class BrandAnalysisDTO
|
||||
{
|
||||
public function __construct(
|
||||
// Core metadata
|
||||
public readonly int $brandId,
|
||||
public readonly string $brandName,
|
||||
public readonly bool $cannaiqEnabled,
|
||||
public readonly ?\DateTimeInterface $dataFreshness = null,
|
||||
|
||||
// Connection error message (when CannaiQ is enabled but API fails)
|
||||
public readonly ?string $connectionError = null,
|
||||
|
||||
// Store placement data (v1.5: enriched with whitespace + regional)
|
||||
public readonly array $placement = [],
|
||||
|
||||
// Competitor analysis (v1.5: enriched with head-to-head + trends)
|
||||
public readonly array $competitors = [],
|
||||
|
||||
// SKU performance data
|
||||
public readonly array $skuPerformance = [],
|
||||
|
||||
// Promo performance data (v1.5: enriched with lift + efficiency)
|
||||
public readonly array $promoPerformance = [],
|
||||
|
||||
// Inventory projections (v1.5: enriched with risk levels + rollup)
|
||||
public readonly array $inventoryProjection = [],
|
||||
|
||||
// Slippage/velocity warnings (v1.5: fully structured)
|
||||
public readonly array $slippage = [],
|
||||
|
||||
// Summary metrics (v1.5: enriched with whitespace count)
|
||||
public readonly array $summary = [],
|
||||
|
||||
// v2.0: Buyer engagement (internal CRM + orders - ALWAYS available)
|
||||
public readonly array $engagement = [],
|
||||
|
||||
// v2.0: Store sentiment (CannaiQ data - ONLY when cannaiq_enabled)
|
||||
public readonly ?array $sentiment = null,
|
||||
|
||||
// v3.0: Advanced intelligence (CannaiQ data - ONLY when cannaiq_enabled)
|
||||
public readonly ?AdvancedV3IntelligenceDTO $advancedV3 = null,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Create empty DTO for when data is unavailable
|
||||
*/
|
||||
public static function empty(int $brandId, string $brandName, bool $cannaiqEnabled): self
|
||||
{
|
||||
return new self(
|
||||
brandId: $brandId,
|
||||
brandName: $brandName,
|
||||
cannaiqEnabled: $cannaiqEnabled,
|
||||
dataFreshness: null,
|
||||
placement: [
|
||||
'stores' => [],
|
||||
'whitespaceStores' => [],
|
||||
'whitespaceCount' => 0,
|
||||
'penetrationByRegion' => [],
|
||||
],
|
||||
competitors: [
|
||||
'competitors' => [],
|
||||
'pricePosition' => null,
|
||||
'headToHeadSkus' => [],
|
||||
'marketShareTrend' => [],
|
||||
],
|
||||
skuPerformance: [],
|
||||
promoPerformance: [],
|
||||
inventoryProjection: [
|
||||
'items' => [],
|
||||
'overstockedItems' => [],
|
||||
'rollup' => [
|
||||
'criticalCount' => 0,
|
||||
'warningCount' => 0,
|
||||
'overstockedSkuCount' => 0,
|
||||
'riskLevel' => 'healthy',
|
||||
],
|
||||
],
|
||||
slippage: [
|
||||
'alerts' => [],
|
||||
'summary' => [
|
||||
'lostStores30dCount' => 0,
|
||||
'lostStores60dCount' => 0,
|
||||
'lostSkus30dCount' => 0,
|
||||
'competitorTakeoverCount' => 0,
|
||||
],
|
||||
'lostStores30d' => [],
|
||||
'lostStores60d' => [],
|
||||
'lostSkus30d' => [],
|
||||
'competitorTakeovers' => [],
|
||||
'oosMetrics' => [
|
||||
'avgOOSDuration' => null,
|
||||
'avgReorderLag' => null,
|
||||
'chronicOOSStores' => [],
|
||||
],
|
||||
],
|
||||
summary: [
|
||||
'totalStores' => 0,
|
||||
'totalSkus' => 0,
|
||||
'avgPrice' => 0,
|
||||
'marketShare' => null,
|
||||
'pricePosition' => null,
|
||||
'whitespaceCount' => 0,
|
||||
],
|
||||
engagement: self::emptyEngagement(),
|
||||
sentiment: null,
|
||||
advancedV3: null,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get empty engagement structure
|
||||
*/
|
||||
public static function emptyEngagement(): array
|
||||
{
|
||||
return [
|
||||
'reach' => [
|
||||
'storesContacted30d' => 0,
|
||||
'messagesSent30d' => 0,
|
||||
'touchesPerStore' => 0,
|
||||
'repActivityLeaders' => [],
|
||||
],
|
||||
'response' => [
|
||||
'responseRate' => 0,
|
||||
'avgResponseTimeHours' => null,
|
||||
'storesNotResponding' => 0,
|
||||
'mostEngagedStores' => [],
|
||||
],
|
||||
'actions' => [
|
||||
'quotesIssued30d' => 0,
|
||||
'ordersPlaced30d' => 0,
|
||||
'conversionRate' => null,
|
||||
'reorderRate' => null,
|
||||
'atRiskAccounts' => [],
|
||||
],
|
||||
'quality' => [
|
||||
'touchTypeBreakdown' => [],
|
||||
'buyerEngagementScore' => null,
|
||||
'buyerEngagementLabel' => 'Needs action',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get empty sentiment structure
|
||||
*/
|
||||
public static function emptySentiment(): array
|
||||
{
|
||||
return [
|
||||
'storeSupport' => [
|
||||
'storesPromotingBrand30d' => 0,
|
||||
'promoFrequencyPerStore' => null,
|
||||
'featuredPlacementCount' => 0,
|
||||
'avgShelfShare' => null,
|
||||
'storeSentimentScore' => null,
|
||||
'storeSentimentLabel' => 'Neutral',
|
||||
],
|
||||
'pricingBehavior' => [
|
||||
'avgDiscountRate' => null,
|
||||
'priceRespectIndex' => null,
|
||||
'competitorPricePressure' => null,
|
||||
],
|
||||
'inventoryBehavior' => [
|
||||
'sellThroughAfterRestock' => null,
|
||||
'restockUrgencyIndex' => null,
|
||||
'stockNeglectEvents' => 0,
|
||||
'shelfCommitment' => [
|
||||
'singleSkuStores' => 0,
|
||||
'multiSkuStores' => 0,
|
||||
'avgSkusPerStore' => null,
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to array for views
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'brandId' => $this->brandId,
|
||||
'brandName' => $this->brandName,
|
||||
'cannaiqEnabled' => $this->cannaiqEnabled,
|
||||
'connectionError' => $this->connectionError,
|
||||
'dataFreshness' => $this->dataFreshness?->format('Y-m-d H:i:s'),
|
||||
'placement' => $this->placement,
|
||||
'competitors' => $this->competitors,
|
||||
'skuPerformance' => $this->skuPerformance,
|
||||
'promoPerformance' => $this->promoPerformance,
|
||||
'inventoryProjection' => $this->inventoryProjection,
|
||||
'slippage' => $this->slippage,
|
||||
'summary' => $this->summary,
|
||||
'engagement' => $this->engagement,
|
||||
'sentiment' => $this->sentiment,
|
||||
'advancedV3' => $this->advancedV3?->toArray(),
|
||||
];
|
||||
}
|
||||
}
|
||||
1827
app/Services/Cannaiq/BrandAnalysisService.php
Normal file
1827
app/Services/Cannaiq/BrandAnalysisService.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -88,6 +88,46 @@ class CannaiqClient
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search stores by name/query
|
||||
*
|
||||
* @param string $platform Platform to filter by (dutchie, jane, etc)
|
||||
* @param string $query Search query for store name
|
||||
* @param int $limit Max results
|
||||
*/
|
||||
public function searchStores(string $platform, string $query, int $limit = 20): array
|
||||
{
|
||||
try {
|
||||
$response = $this->http->get('/stores', [
|
||||
'platform' => $platform,
|
||||
'q' => $query,
|
||||
'limit' => $limit,
|
||||
]);
|
||||
|
||||
if ($response->successful()) {
|
||||
$data = $response->json();
|
||||
|
||||
return $data['stores'] ?? $data;
|
||||
}
|
||||
|
||||
Log::warning('CannaiQ: Failed to search stores', [
|
||||
'platform' => $platform,
|
||||
'query' => $query,
|
||||
'status' => $response->status(),
|
||||
]);
|
||||
|
||||
return [];
|
||||
} catch (\Exception $e) {
|
||||
Log::error('CannaiQ: Exception searching stores', [
|
||||
'platform' => $platform,
|
||||
'query' => $query,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get store details
|
||||
*
|
||||
@@ -437,4 +477,135 @@ class CannaiqClient
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// Brand Analytics API Endpoints (v1.5)
|
||||
// These endpoints provide brand-level intelligence
|
||||
// ========================================
|
||||
|
||||
/**
|
||||
* Get brand-level metrics including whitespace and regional penetration
|
||||
*
|
||||
* @param string $brandName Brand name/slug
|
||||
*/
|
||||
public function getBrandMetrics(string $brandName): array
|
||||
{
|
||||
try {
|
||||
$response = $this->http->get("/brands/{$brandName}/metrics");
|
||||
|
||||
if ($response->successful()) {
|
||||
return $response->json();
|
||||
}
|
||||
|
||||
Log::warning('CannaiQ: Failed to fetch brand metrics', [
|
||||
'brand' => $brandName,
|
||||
'status' => $response->status(),
|
||||
]);
|
||||
|
||||
return ['error' => true, 'message' => 'Failed to fetch brand metrics'];
|
||||
} catch (\Exception $e) {
|
||||
Log::error('CannaiQ: Exception fetching brand metrics', [
|
||||
'brand' => $brandName,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
return ['error' => true, 'message' => $e->getMessage()];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get competitor analysis for a brand
|
||||
* Returns: head-to-head comparisons, market share trends, price position
|
||||
*
|
||||
* @param string $brandName Brand name/slug
|
||||
* @param array $options Optional parameters (top_n, etc)
|
||||
*/
|
||||
public function getBrandCompetitors(string $brandName, array $options = []): array
|
||||
{
|
||||
try {
|
||||
$response = $this->http->get("/brands/{$brandName}/competitors", $options);
|
||||
|
||||
if ($response->successful()) {
|
||||
return $response->json();
|
||||
}
|
||||
|
||||
Log::warning('CannaiQ: Failed to fetch brand competitors', [
|
||||
'brand' => $brandName,
|
||||
'status' => $response->status(),
|
||||
]);
|
||||
|
||||
return ['error' => true, 'message' => 'Failed to fetch brand competitors'];
|
||||
} catch (\Exception $e) {
|
||||
Log::error('CannaiQ: Exception fetching brand competitors', [
|
||||
'brand' => $brandName,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
return ['error' => true, 'message' => $e->getMessage()];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get promotion performance metrics for a brand
|
||||
* Returns: velocity lift, baseline vs promo velocity, efficiency scores
|
||||
*
|
||||
* @param string $brandName Brand name/slug
|
||||
* @param array $options Optional parameters (from, to date range)
|
||||
*/
|
||||
public function getBrandPromoMetrics(string $brandName, array $options = []): array
|
||||
{
|
||||
try {
|
||||
$response = $this->http->get("/brands/{$brandName}/promo-metrics", $options);
|
||||
|
||||
if ($response->successful()) {
|
||||
return $response->json();
|
||||
}
|
||||
|
||||
Log::warning('CannaiQ: Failed to fetch brand promo metrics', [
|
||||
'brand' => $brandName,
|
||||
'status' => $response->status(),
|
||||
]);
|
||||
|
||||
return ['error' => true, 'message' => 'Failed to fetch brand promo metrics'];
|
||||
} catch (\Exception $e) {
|
||||
Log::error('CannaiQ: Exception fetching brand promo metrics', [
|
||||
'brand' => $brandName,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
return ['error' => true, 'message' => $e->getMessage()];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get slippage/churn metrics for a brand
|
||||
* Returns: lost stores, lost SKUs, competitor takeovers, OOS metrics
|
||||
*
|
||||
* @param string $brandName Brand name/slug
|
||||
* @param array $options Optional parameters (days_back, etc)
|
||||
*/
|
||||
public function getBrandSlippage(string $brandName, array $options = []): array
|
||||
{
|
||||
try {
|
||||
$response = $this->http->get("/brands/{$brandName}/slippage", $options);
|
||||
|
||||
if ($response->successful()) {
|
||||
return $response->json();
|
||||
}
|
||||
|
||||
Log::warning('CannaiQ: Failed to fetch brand slippage', [
|
||||
'brand' => $brandName,
|
||||
'status' => $response->status(),
|
||||
]);
|
||||
|
||||
return ['error' => true, 'message' => 'Failed to fetch brand slippage'];
|
||||
} catch (\Exception $e) {
|
||||
Log::error('CannaiQ: Exception fetching brand slippage', [
|
||||
'brand' => $brandName,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
return ['error' => true, 'message' => $e->getMessage()];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
35
database/data/missing_products.php
Normal file
35
database/data/missing_products.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
['sku' => 'DK-CF-AZ0.5G', 'name' => 'Cake Face - 0.5G Hash Infused Doink', 'brand_slug' => 'doinks', 'desc' => ''],
|
||||
['sku' => 'DK-CF-AZ1G', 'name' => 'Cake Face - 1G Hash Infused Doink', 'brand_slug' => 'doinks', 'desc' => ''],
|
||||
['sku' => 'HF-T2-CD-AZ1G', 'name' => 'Chemdawg - Tier 2 - Live Hash Rosin', 'brand_slug' => 'hash-factory', 'desc' => null],
|
||||
['sku' => 'HF-T2-JLL-AZ1G', 'name' => 'Juanita La Lagrimosa - Tier 2 - Live Hash Rosin', 'brand_slug' => 'hash-factory', 'desc' => null],
|
||||
['sku' => 'HF-T2-WP-AZ1G', 'name' => 'Wedding Pie - Tier 2 - Live Hash Rosin', 'brand_slug' => 'hash-factory', 'desc' => 'Wedding Pie Live Hash Rosin is a sweet, solventless concentrate from the relaxing Wedding Pie strain. Pure, smooth, and packed with dessert-like flavors, it offers a calming, euphoric escape for ultimate relaxation.'],
|
||||
['sku' => 'JV-HH-AZ05G', 'name' => 'Candy Fumez Solventless Live Rosin Cart', 'brand_slug' => 'just-vape', 'desc' => ''],
|
||||
['sku' => 'OC-DR-AZ1G', 'name' => 'Dark Rainbow - 1G All Flower Preroll', 'brand_slug' => 'outlaw-cannabis', 'desc' => 'Dark Rainbow is a standout preroll designed to make your dispensary a destination for serious smokers. Packed with 29.77% THC and 35.46% total cannabinoids, this 1g roll delivers a euphoric, luxurious high that satisfies even the most demanding customers. Its 2.99% terpene profile bursts with layered notes of fruit, earth, and spice, creating a complex and unforgettable flavor experience. Limited-run batches make each preroll rare, and once it sells out, it could be months before it returns. Stocking Dark Rainbow prerolls puts your store among the few offering true connoisseur-level products, with scarcity driving urgency and premium appeal. Add Dark Rainbow to your menu and elevate your shelves and your sales.'],
|
||||
['sku' => 'OG-1', 'name' => 'OG Khush - 1', 'brand_slug' => 'white-label-canna', 'desc' => ''],
|
||||
['sku' => 'TB-BPC-AZ3G', 'name' => 'Banana Punch Cake - 3 Pack', 'brand_slug' => 'thunder-bud', 'desc' => ''],
|
||||
['sku' => 'TB-BPC-AZ5G', 'name' => 'Banana Punch Cake - 5 Pack', 'brand_slug' => 'thunder-bud', 'desc' => ''],
|
||||
['sku' => 'TB-CF-AZ3G', 'name' => 'Cake Face - 3 Pack', 'brand_slug' => 'thunder-bud', 'desc' => ''],
|
||||
['sku' => 'TB-CF-AZ5G', 'name' => 'Cake Face - 5 Pack', 'brand_slug' => 'thunder-bud', 'desc' => ''],
|
||||
['sku' => 'TB-F95-AZ3G', 'name' => 'Fam 95 - 3 Pack', 'brand_slug' => 'thunder-bud', 'desc' => ''],
|
||||
['sku' => 'TB-F95-AZ5G', 'name' => 'Fam 95 - 5 Pack', 'brand_slug' => 'thunder-bud', 'desc' => ''],
|
||||
['sku' => 'TB-HMS-AZ3G', 'name' => 'Hot Mint Sundae - 3 Pack', 'brand_slug' => 'thunder-bud', 'desc' => ''],
|
||||
['sku' => 'TB-HMS-AZ5G', 'name' => 'Hot Mint Sundae - 5 Pack', 'brand_slug' => 'thunder-bud', 'desc' => ''],
|
||||
['sku' => 'TB-IL-AZ1G', 'name' => 'Illemonati', 'brand_slug' => 'thunder-bud', 'desc' => 'description coming soon'],
|
||||
['sku' => 'TB-I-TC-AZ1G', 'name' => 'Tropic Cake', 'brand_slug' => 'thunder-bud', 'desc' => ''],
|
||||
['sku' => 'TB-MB-AZ3G', 'name' => 'Modified Banana - 5 Pack', 'brand_slug' => 'thunder-bud', 'desc' => ''],
|
||||
['sku' => 'TB-MC-AZ3G', 'name' => 'Macaroons - 5 Pack', 'brand_slug' => 'thunder-bud', 'desc' => ''],
|
||||
['sku' => 'TB-PG-AZ3G', 'name' => 'Plasma Gas - 3 Pack', 'brand_slug' => 'thunder-bud', 'desc' => ''],
|
||||
['sku' => 'TB-PG-AZ5G', 'name' => 'Plasma Gas - 5 Pack', 'brand_slug' => 'thunder-bud', 'desc' => ''],
|
||||
['sku' => 'TB-SS-AZ1G', 'name' => 'Singapore Sling - 3 Pack', 'brand_slug' => 'thunder-bud', 'desc' => ''],
|
||||
['sku' => 'TB-VM-AZ3G', 'name' => 'Violet Meadows - 3 Pack', 'brand_slug' => 'thunder-bud', 'desc' => ''],
|
||||
['sku' => 'TB-VM-AZ5G', 'name' => 'Violet Meadows - 3 Pack', 'brand_slug' => 'thunder-bud', 'desc' => ''],
|
||||
['sku' => 'TB-WNLA-AZ3G', 'name' => 'Walkin-N-LA - 3 Pack', 'brand_slug' => 'thunder-bud', 'desc' => ''],
|
||||
['sku' => 'TB-WNLA-AZ5G', 'name' => 'Walkin-N-LA - 5 Pack', 'brand_slug' => 'thunder-bud', 'desc' => ''],
|
||||
['sku' => 'WLC-GH-HFG', 'name' => 'Granulated Hash - Hybrid Food Grade', 'brand_slug' => 'white-label-canna', 'desc' => "Granulated Hash - Hybrid Food Grade\r\nBalanced | Versatile | Full-Spectrum\r\n\r\nThis Hybrid Food Grade Granulated Hash offers a balanced blend of uplifting and relaxing effects, perfect for versatile infusion use. Milled to a fine, sandy consistency, it delivers full-spectrum potency with rich cannabinoid and terpene content. Ideal for blending into pre-rolls, edibles, or solventless concentrates, this hash brings consistent performance and a smooth, flavorful finish to any product it's infused into."],
|
||||
['sku' => 'WLC-LHR-H-FG', 'name' => 'Live Hash Rosin - Hybrid Food Grade', 'brand_slug' => 'white-label-canna', 'desc' => ''],
|
||||
['sku' => 'WLC-LHR-I-FG', 'name' => 'Live Hash Rosin - Indica Food Grade', 'brand_slug' => 'white-label-canna', 'desc' => ''],
|
||||
['sku' => 'WLC-LHR-S-FG', 'name' => 'Live Hash Rosin - Sativa Food Grade', 'brand_slug' => 'white-label-canna', 'desc' => "Sativa Food Grade Live Hash Rosin\r\nUplifting | Solventless\r\n\r\nCrafted from fresh frozen flower and processed without solvents, this Sativa Food Grade Live Hash Rosin delivers bright, energetic effects with a clean, citrus-forward terpene profile. Its smooth, pliable texture makes it ideal for infusions, vapes, or solventless formulations where clarity and flavor shine. Perfect for products designed to elevate and inspire."],
|
||||
];
|
||||
25
database/data/product_descriptions_hf.php
Normal file
25
database/data/product_descriptions_hf.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
['sku' => 'HF-CF-AZ1G', 'desc' => 'Hash Factory: Candy Fumez Live Hash Rosin\r\n\r\nIndulge in Sweet Bliss with Hash Factory<72>s Candy Fumez! ??\r\n\r\nIntroducing Candy Fumez Live Hash Rosin, a premium solventless concentrate that delivers a delightful burst of flavor and relaxation. Crafted from the delectable Candy FUmez strain, this 100% pure, cold-pressed live hash rosin is made with the utmost care. Sustainably sourced and responsibly packaged by Arizonans, prepare for a sweet escape with every dab!\r\n\r\n\r\n\r\nKey Features:\r\n\r\nHybrid Strain: Candy Fumez offers a perfect blend of uplifting euphoria and soothing relaxation, making it ideal for any time of day. ?\r\n\r\nFlavorful Extravaganza: Savor the luscious mix of fruity candy and creamy vanilla, creating a mouthwatering experience. ?\r\n\r\nAromatic Delight: The aroma entices the senses with sweet confections and hints of sugary goodness. ?\r\n\r\nEuphoric Comfort: Experience a blissful lift that melts away stress, perfect for unwinding after a long day. ?\r\n\r\nRelaxing Serenity: Eases tension while promoting a sense of calm and well-being, ideal for cozy evenings or social gatherings. ?\r\n\r\nLive Hash Rosin: Cold-pressed to maintain purity and flavor, ensuring a smooth experience. ??\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\n\r\nCandy Fumez<65>s colorful, frosty buds showcase vibrant greens with hints of pink, adorned with a sparkling layer of trichomes. The combination of fruity candy and creamy vanilla flavors delivers a rich, indulgent experience. Its balanced effects promote relaxation and creativity, making it great for artistic pursuits or winding down with friends. Candy Fumez is also effective for stress relief and enhancing overall well-being.\r\n\r\n\r\nSo, grab your Hash Factory: Candy Fumez Live Hash Rosin today and treat yourself to a sweet journey. This premium rosin is your ticket to a euphoric escape into bliss. Let the good times roll with Hash Factory! ??'],
|
||||
['sku' => 'HF-DI-AZ1G', 'desc' => 'Hash Factory: Dante\'s Inferno Live Hash Rosin\r\n\r\nIgnite Your Senses with Hash Factory<72>s Dante\'s Inferno! ??\r\n\r\nIntroducing Dante\'s Inferno Live Hash Rosin, a premium solventless concentrate that brings a fiery blend of relaxation and creative inspiration. Crafted from the exceptional Dante\'s Inferno strain, this 100% pure, cold-pressed live hash rosin is produced with meticulous care. Sustainably sourced and responsibly packaged by Arizonans, prepare for a blazing experience with every dab!\r\n\r\n\r\nKey Features:\r\n\r\nIndica-Dominant Hybrid: Dante\'s Inferno delivers a harmonious balance of soothing relaxation and uplifting euphoria. ?\r\n\r\nFlavorful Fusion: Revel in the rich combination of spicy herbs and sweet citrus, creating a delightful taste sensation. ?\r\n\r\nAromatic Enchantment: The aroma captivates with earthy undertones and hints of zesty lemon, igniting your senses. ?\r\n\r\nEuphoric Burst: Experience an invigorating head high that sparks creativity and enhances mood. ?\r\n\r\nRelaxing Serenity: Eases stress and tension, wrapping you in a comforting embrace of tranquility. ?\r\n\r\nLive Hash Rosin: Cold-pressed to maintain purity and flavor, ensuring a smooth experience. ??\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\n\r\nDante\'s Inferno features the fusion of spicy herbs and sweet citrus flavors creates an unforgettable and smooth experience. Its uplifting effects promote creativity and social interaction, making it ideal for both artistic endeavors and relaxed gatherings. Dante\'s Inferno is also effective for relieving stress, enhancing mood, and providing a sense of calm.\r\n\r\nSo, grab your Hash Factory: Dante\'s Inferno Live Hash Rosin today and let the flames of creativity ignite your journey. This premium rosin is your gateway to an exhilarating, blissful escape. Let the good times roll with Hash Factory! ??'],
|
||||
['sku' => 'HF-FB-AZ1G', 'desc' => 'Hash Factory: Frankenberry Live Hash Rosin\r\n\r\nAwaken Your Senses with Hash Factory<72>s Frankenberry! ??\r\n\r\nIntroducing Frankenberry Live Hash Rosin, a premium solventless concentrate that delivers a delightful mix of flavor and relaxation. Crafted from the unique Frankenberry strain, this 100% pure, cold-pressed live hash rosin is made with care and attention to detail. Sustainably sourced and responsibly packaged by Arizonans, get ready for a tasty adventure with every dab!\r\n\r\nKey Features:\r\n\r\nHybrid Strain: Frankenberry offers a balanced blend of uplifting euphoria and calming relaxation, perfect for any time of day. ?\r\n\r\nFlavorful Treat: Enjoy the mouthwatering fusion of sweet berries and creamy vanilla, creating a nostalgic flavor experience. ?\r\n\r\nAromatic Delight: The aroma entices with notes of fruity sweetness and a hint of cereal-like richness. ?\r\n\r\nEuphoric Bliss: Experience a joyful lift that brightens your mood and inspires creativity. ?\r\n\r\nRelaxing Comfort: Eases tension and stress, making it ideal for cozy evenings or social gatherings. ?\r\n\r\nLive Hash Rosin: Cold-pressed to maintain purity and flavor, ensuring a smooth experience. ??\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\nFrankenberry<72>s colorful, frosty buds showcase vibrant pink and green hues, adorned with a shimmering layer of trichomes. The combination of sweet berries and creamy vanilla flavors delivers a rich and flavorful experience. Its balanced effects promote relaxation and happiness, making it great for unwinding with friends or enjoying creative pursuits. Frankenberry is also effective for stress relief and enhancing overall mood.\r\n\r\nSo, grab your Hash Factory: Frankenberry Live Hash Rosin today and indulge in a berrylicious journey. This premium rosin is your ticket to a euphoric escape. Let the good times roll with Hash Factory! ??'],
|
||||
['sku' => 'HF-GM-AZ1G', 'desc' => 'Hash Factory: Grease Monkey Live Hash Rosin\r\n\r\nGet Your Gears Turning with Hash Factory<72>s Grease Monkey! ???\r\n\r\nIntroducing Grease Monkey Live Hash Rosin, a premium solventless concentrate that delivers a powerful punch of relaxation and euphoria. Crafted from the high-end Grease Monkey strain, this 100% pure, cold-pressed live hash rosin is made with care. Sustainably sourced and responsibly packaged by Arizonans, prepare for a smooth ride with every dab!\r\n\r\nKey Features:\r\n\r\nIndica-Dominant Hybrid: Grease Monkey provides a perfect blend of deep relaxation and mental euphoria. ?\r\n\r\nFlavorful Delight: Enjoy the rich blend of nutty vanilla and sweet skunky diesel. ?\r\n\r\nAromatic Bliss: The aroma teases the senses with earthy pungency and sugary skunky diesel. ?\r\n\r\nEuphoric Lift: Starts with a cerebral boost, perfect for unwinding after a long day. ?\r\n\r\nRelaxing Calm: Eases tension and stress, leaving you in a state of bliss. ?\r\n\r\nLive Hash Rosin: Cold-pressed to maintain purity and flavor, ensuring a smooth experience. ??\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\n\r\nGrease Monkey<65>s dense, frosty buds boast vibrant green hues with hints of purple, covered in a sparkling layer of trichomes. The combination of nutty vanilla and sweet skunky diesel flavors offers a smooth and flavorful experience. The uplifting and euphoric effects promote creativity and a positive mood, ideal for socializing or artistic pursuits. The deep relaxation eases tension and stress, making it suitable for evening use. Grease Monkey is also effective for stress relief, mood enhancement, and mild pain management.\r\n\r\nSo, grab your Hash Factory: Grease Monkey Live Hash Rosin today and get your gears turning. This premium rosin is your ticket to a euphoric, out-of-this-world journey. Let the good times roll with Hash Factory! ???'],
|
||||
['sku' => 'HF-HH-AZ1G', 'desc' => 'Hash Factory: Headhunter Live Hash Rosin\r\n\r\nHone Your Focus with Hash Factory<72>s Headhunter! ??\r\n\r\nIntroducing Headhunter Live Hash Rosin, a premium solventless concentrate designed to elevate your mind and enhance your creativity. Crafted from the exceptional Headhunter strain, this 100% pure, cold-pressed live hash rosin is made with precision and care. Sustainably sourced and responsibly packaged by Arizonans, prepare for a clear, invigorating experience with every dab!\r\n\r\nKey Features:\r\n\r\nIndica-Dominant Hybrid: Headhunter offers a perfect blend of calming relaxation and gentle euphoria. ?\r\n\r\nFlavorful Delight: Enjoy the rich blend of nutty vanilla and sweet skunky diesel. ?\r\n\r\nAromatic Invigoration: The aroma captivates with bright lemon notes and rich, herbal undertones. ?\r\n\r\nSoothing High: Experience a blissful lift that melts away stress and tension, ideal for unwinding after a long day. ?\r\n\r\nRelaxing Serenity: Balances relaxation with mental clarity, allowing you to drift into a peaceful state without sedation. ?\r\n\r\nLive Hash Rosin: Cold-pressed to maintain purity and flavor, ensuring a smooth experience. ??\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\nHeadhunter<65>s fusion of sweet berries and earthy and gassy flavors delivers a smooth, flavorful experience. Its calming effects promote relaxation and a sense of well-being, making it perfect for evening use or quiet nights in. Headhunter is also effective for stress relief, mood enhancement, and easing minor discomfort.\r\n\r\nSo, grab your Hash Factory: Headhunter Live Hash Rosin today and embrace the tranquility. This premium rosin is your ticket to a soothing, restorative journey. Let the good times roll with Hash Factory! ??'],
|
||||
['sku' => 'HF-SB-AZ1G', 'desc' => 'Hash Factory: Super Boof Live Hash Rosin\r\n\r\nUnleash the Fun with Hash Factory<72>s Super Boof! ??\r\n\r\nIntroducing Super Boof Live Hash Rosin, a premium solventless concentrate that packs a playful punch of flavor and relaxation. Crafted from the unique Super Boof strain, this 100% pure, cold-pressed live hash rosin is made with care and precision. Sustainably sourced and responsibly packaged by Arizonans, get ready for a wild ride with every dab!\r\n\r\nKey Features:\r\n\r\nHybrid Strain: Super Boof delivers a delightful balance of uplifting euphoria and soothing relaxation, perfect for any occasion. ?\r\n\r\nFlavorful Adventure: Indulge in the bold mix of sweet fruit and funky earthiness, creating an unforgettable taste experience. ?\r\n\r\nAromatic Delight: The aroma enchants with vibrant notes of tropical fruits and rich, earthy undertones. ?\r\n\r\nEuphoric Vibes: Experience a burst of happiness that elevates your mood and encourages social interaction. ?\r\n\r\nRelaxing Comfort: Eases tension while promoting a sense of well-being, making it ideal for fun gatherings or relaxing nights in. ?\r\n\r\nLive Hash Rosin: Cold-pressed to maintain purity and flavor, ensuring a smooth experience. ??\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\nSuper Boof<6F>s dense, frosty buds showcase striking green and purple hues, adorned with a glistening layer of trichomes. The combination of sweet fruit and funky earthiness offers a rich and flavorful experience. Its uplifting effects encourage creativity and sociability, making it great for parties or artistic endeavors. Super Boof is also effective for stress relief and enhancing overall mood.\r\n\r\nSo, grab your Hash Factory: Super Boof Live Hash Rosin today and let the good times roll. This premium rosin is your ticket to a euphoric adventure like no other. Enjoy the ride with Hash Factory! ??'],
|
||||
['sku' => 'HF-SB-T1-AZ1G', 'desc' => '?Hash Factory Superboof:\r\nSweet fruit, funky hybrid vibes'],
|
||||
['sku' => 'HF-T1-BS-AZ1G', 'desc' => '? Hash Factory Banana Shack: Tropical fruit, smooth hybrid calm'],
|
||||
['sku' => 'HF-T1-CD-AZ1G', 'desc' => '? Hash Factory Chemdawg:\r\nDiesel, pine, deep indica calm'],
|
||||
['sku' => 'HF-T1-GB-AZ1G', 'desc' => 'Hash Factory: Garlic Breath Live Hash Rosin\r\n\r\nEmbrace the Flavor with Hash Factory<72>s Garlic Breath! ??\r\n\r\nIntroducing Garlic Breath Live Hash Rosin, a top-shelf solventless concentrate that offers a uniquely bold flavor and a blissful high. Crafted from the distinctive Garlic Breath strain, this 100% pure, cold-pressed live hash rosin is made with meticulous care. Sustainably sourced and responsibly packaged by Arizonans, get ready for a rich and savory journey with every dab!\r\n\r\n\r\nKey Features:\r\n\r\nBalanced Hybrid: Garlic Breath provides an ideal mix of soothing relaxation and uplifting euphoria, perfect for winding down or sparking creativity. ?\r\n\r\nSavory Delight: Experience a robust blend of pungent garlic, earthy undertones, and a hint of spice that will tantalize your taste buds. ??\r\n\r\nAromatic Depth: The aroma envelops your senses with bold notes of garlic and herbal richness, creating an inviting and unique experience. ?\r\n\r\nEuphoric Lift: Begins with a comforting wave of happiness that enhances mood and creativity, making it suitable for any time of day. ?\r\n\r\nRelaxing Calm: Transitions into gentle, soothing relaxation that melts away stress. ?\r\n\r\nLive Hash Rosin: Cold-pressed to maintain purity and flavor, ensuring a smooth experience. ??\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\nGarlic Breath<74>s balanced effects promote a positive mood while keeping you relaxed, making it perfect for social gatherings or quiet evenings. Whether you\'re looking to unwind after a long day or explore your creative side, this strain is your go-to choice for a flavorful escape.\r\n\r\nGrab your Hash Factory: Garlic Breath Live Hash Rosin today and savor the bold flavors. This premium rosin is your ticket to a savory, out-of-this-world experience. Let the good times roll with Hash Factory! ??'],
|
||||
['sku' => 'HF-T1-MP-AZ1G', 'desc' => '? Hash Factory Moroccan Peaches: Sweet peach, balanced hybrid bliss'],
|
||||
['sku' => 'HF-T1-SB-AZ1G', 'desc' => '? Hash Factory Superboof: Bold citrus, balanced hybrid buzz'],
|
||||
['sku' => 'HF-T1-SS-AZ1G', 'desc' => '?Hash Factory Singapore Sling: Tropical zest, creative sativa lift'],
|
||||
['sku' => 'HF-T1-TF-AZ1G', 'desc' => '?Hash Factory Truffaloha: Tropical zest, uplifting sativa'],
|
||||
['sku' => 'HF-T1-WP-AZ1G', 'desc' => 'Hash Factory Wedding Pie: Sweet vanilla, relaxing indica calm ?'],
|
||||
['sku' => 'HF-T2-GB-AZ1G', 'desc' => 'Garlic Breath Live Hash Rosin, a top-shelf solventless concentrate that offers a uniquely bold flavor and a blissful high. Crafted from the distinctive Garlic Breath strain, this 100% pure, cold-pressed live hash rosin is made with meticulous care. Sustainably sourced and responsibly packaged by Arizonans, get ready for a rich and savory journey with every dab!'],
|
||||
['sku' => 'HF-T2-LCG-AZ1G', 'desc' => 'Hash Factory Lemon Cherry Gelato Live Hash Rosin ???\r\n\r\nIntroducing Lemon Cherry Gelato Live Hash Rosin, a premium solventless concentrate that blends sweet, fruity flavors with a deeply relaxing high. Crafted from the Indica-dominant Lemon Cherry Gelato strain, this 100% pure, cold-pressed rosin delivers a soothing experience that balances mental clarity with physical relaxation. Sustainably sourced and responsibly packaged, this rosin is perfect for unwinding after a long day or enjoying a laid-back evening.\r\n\r\nKey Features:\r\n\r\nIndica-Dominant Hybrid: Lemon Cherry Gelato offers a perfect blend of relaxation and euphoria. The high starts with a gentle cerebral uplift that calms the mind, followed by a deeply soothing body buzz that melts away stress and tension, leaving you relaxed without feeling too heavy. ????\r\n\r\nFlavor Bliss: Enjoy the mouthwatering combination of tangy lemon and sweet cherry, with creamy vanilla undertones that add a rich, dessert-like finish. It<49>s a refreshing, fruity treat that<61>s as delicious as it is smooth. ???\r\n\r\nAromatic Comfort: The aroma is equally enticing, with bright citrus notes of lemon and cherry, balanced by creamy, sweet undertones. The scent is sweet and inviting, filling the air with a pleasant and comforting fragrance. ???\r\n\r\nRelaxing Euphoria: The initial cerebral effects provide a gentle mood lift and a sense of happiness, which transitions into a relaxing body high that helps ease tension and promote a sense of calm. Perfect for relaxation, evening use, or winding down after a busy day. ??????\r\n\r\nSmooth, Calming Body Buzz: As the high progresses, the indica-dominant effects provide a calming body buzz that doesn<73>t weigh you down, but rather helps you fully unwind and let go of stress. Ideal for those looking to relax and soothe both mind and body. ???\r\n\r\nLive Hash Rosin: Cold-pressed to maintain the highest level of purity and flavor, ensuring a smooth and refined experience. ???\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\nLemon Cherry Gelato is the perfect indica-dominant hybrid for those who want a balanced yet soothing experience. Its sweet, citrusy flavor and relaxing effects make it ideal for evening relaxation, unwinding, or simply enjoying a peaceful, mellow mood.\r\n\r\nSo, grab your Lemon Cherry Gelato Live Hash Rosin today and enjoy the relaxing, flavorful journey this indica-dominant hybrid has to offer. Let the calming effects and delicious taste take you to a place of blissful serenity! ???'],
|
||||
['sku' => 'HF-T2-TF-AZ1G', 'desc' => 'Truffaloha Live Hash Rosin ???\r\n\r\nIntroducing Truffaloha Live Hash Rosin, a premium solventless concentrate that will elevate your cannabis experience to vibrant, tropical heights. Derived from the sativa-dominant Truffaloha strain, this 100% pure, live hash rosin captures the invigorating energy and exotic flavors of its sun-soaked lineage. Sustainably sourced and responsibly packaged, this rosin is your passport to a tropical adventure<72>whether you<6F>re unleashing creativity or simply basking in the uplifting vibes of the islands.\r\n\r\n\r\nKey Features:\r\n\r\nLive Hash Rosin: Made from freshly harvested, frozen cannabis to preserve the plant\'s full terpene profile and potency, resulting in a clean, flavorful, and highly aromatic concentrate. ???\r\n\r\nSativa-Dominant Hybrid: Truffaloha delivers a burst of energetic euphoria, perfect for daytime use, creativity, and boosting focus. It<49>s the ideal strain to spark inspiration and keep you engaged, without leaving you feeling too sedated. ???\r\n\r\nTropical Flavor Explosion: Get ready for a flavorful journey with notes of sweet pineapple, tangy mango, and creamy coconut, with a subtle hint of vanilla that rounds out the experience. It\'s like a tropical fruit cocktail in every hit! ???\\\r\n\r\nAromatic Island Breeze: The aroma is a fragrant blend of ripe tropical fruits, creamy vanilla, and a light, earthy sweetness, instantly transporting you to a beachside retreat. ???\r\n\r\nEnergetic Uplift: The effects start with a clear-headed, cerebral high that sparks creativity, motivation, and a deep sense of happiness<73>perfect for tackling projects, socializing, or simply enjoying a burst of positive energy. ???\r\n\r\nSmooth, Relaxed Vibes: As the high continues, it shifts into a gentle body relaxation that keeps you feeling at ease, without overwhelming sedation. You<6F>ll feel comfortable and chill<6C>ideal for lounging or unwinding after an active day. ???\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\nTruffaloha is a sativa-dominant hybrid that strikes the perfect balance between energetic, creative uplift and smooth, relaxing vibes. Whether you\'re looking to spark new ideas, socialize with friends, or just enjoy a burst of tropical sunshine, this rosin is your ultimate companion for any day that calls for a little extra brightness.\r\n\r\nSo, grab your Truffaloha Live Hash Rosin today and experience the tropical energy and uplifting effects of this exotic sativa-dominant hybrid. Let the vibrant flavors and clear-headed euphoria take you on a sensory journey to paradise! ???'],
|
||||
['sku' => 'HF-T2-WP-AZ1G', 'desc' => 'Wedding Pie Live Hash Rosin is a sweet, solventless concentrate from the relaxing Wedding Pie strain. Pure, smooth, and packed with dessert-like flavors, it offers a calming, euphoric escape for ultimate relaxation.'],
|
||||
['sku' => 'HF-T2-WP-AZ1G', 'desc' => 'Wedding Pie Live Hash Rosin is a sweet, solventless concentrate from the relaxing Wedding Pie strain. Pure, smooth, and packed with dessert-like flavors, it offers a calming, euphoric escape for ultimate relaxation.'],
|
||||
['sku' => 'HF-VC-AZ1G', 'desc' => 'Hash Factory: Vice City Live Hash Rosin\r\n\r\nTake a Trip to Paradise with Hash Factory<72>s Vice City! ??\r\n\r\nHash Factory: Vice City Live Hash Rosin Take a Trip to Paradise with Hash Factory<72>s Vice City! ?? Introducing Vice City Live Hash Rosin, a top-tier solventless concentrate designed to elevate your experience to new heights. Crafted from the exquisite Vice City strain, this 100% pure, cold-pressed live hash rosin is made with precision and care. Sustainably sourced and responsibly packaged by Arizonans, prepare for a smooth, tropical escape with every dab!\r\n\r\n\r\n\r\nKey Features:\r\n\r\nSativa-Dominant Hybrid: Vice City offers a perfect fusion of uplifting energy and creative inspiration. ?\r\n\r\nTropical Flavor: Delight in the exotic blend of zesty citrus and sweet tropical fruits. ?\r\n\r\nAromatic Adventure: The aroma captivates with notes of juicy oranges and a hint of earthy sweetness. ?\r\n\r\nEuphoric Rush: Experience an invigorating cerebral high that sparks creativity and social interaction. ?\r\n\r\nEuphoric Rush: Experience an invigorating cerebral high that sparks creativity and social interaction. ?\r\n\r\nLive Hash Rosin: Cold-pressed to maintain purity and flavor, ensuring a smooth experience. ??\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\n\r\nVice City<74>s lush, colorful buds boast striking green and purple tones, coated in a glimmering layer of trichomes. The enticing flavors of zesty citrus and sweet tropical fruits create a refreshingly smooth and enjoyable experience. The uplifting effects inspire creativity and promote a cheerful mood, making it perfect for social gatherings or artistic endeavors. Vice City is also effective for alleviating stress and enhancing overall well-being.\r\n\r\nSo, grab your Hash Factory: Vice City Live Hash Rosin today and embark on your own tropical getaway. This premium rosin is your passport to a euphoric, exhilarating journey. Let the good times roll with Hash Factory! ??'],
|
||||
];
|
||||
270
database/data/product_descriptions_non_hf.php
Normal file
270
database/data/product_descriptions_non_hf.php
Normal file
@@ -0,0 +1,270 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
['sku' => 'ATM-AR-100MG', 'desc' => '? Meet <20>The Arnie<69> ?\r\n\r\nGet ready to flex your taste buds with The Arnie, a bold, refreshing twist on the classic half-and-half, infused with a punch of good vibes and a wink of nostalgia. This isn<73>t your grandpa<70>s Arnold Palmer. It<49>s a next-level, cannabis-infused masterpiece crafted for those who crave flavor, fun, and a fast-acting experience.\r\n\r\n? What Makes It Legendary\r\n\r\nFlavor Fusion: A perfect blend of robust black tea and zesty lemonade, sweetened naturally with organic blue agave\r\n\r\nPower-Packed: Infused with Live Resin for a balanced, uplifting effect\r\n\r\nRapid Onset: Feel the effects in just 10 minutes with no waiting, just enjoying\r\n\r\nClean & Conscious: Organic, gluten-free, vegan, and made with full extract cannabis oil\r\n\r\n? Why You\'ll Love It\r\n\r\nThe Arnie delivers a mouthwatering fusion of citrus and tea with just the right touch of sweetness, all enhanced by a smooth, euphoric buzz. Crisp, cool, and totally craveable, this infused classic refreshes your palate while lifting your mood. It<49>s a delicious way to sip, smile, and elevate your vibe.'],
|
||||
['sku' => 'ATM-BBL-100MG', 'desc' => '? Blackberry Lemonade?\r\n\r\nBlackberry Lemonade brings a bold, berry packed punch to your taste buds with a tart twist and a sunny kick of citrus. Sweet, tangy, and infused with good vibes, this sparkling stunner is made for those who live for flavor and love to feel the buzz fast. It<49>s not just a drink, it<69>s a vibe in a bottle.\r\n\r\n? What Makes It Legendary\r\n\r\nFlavor Fusion: A juicy mix of ripe blackberries and fresh lemon juice, sweetened naturally with organic blue agave.\r\n\r\nPower-Packed: Infused with RSO for a balanced, elevating experience\r\n\r\nRapid Onset: Effects kick in fast, just 10 minutes from sip to smile\r\n\r\nClean & Conscious: Organic, gluten-free, vegan, and made with full extract cannabis oil\r\n\r\n? Why You\'ll Love It\r\n\r\nBlackberry Lemonade delivers a mouthwatering burst of sweet berries and zesty citrus that<61>s both refreshing and uplifting. With its smooth, euphoric effects and irresistibly juicy flavor, it<69>s the perfect way to quench your thirst, boost your mood, and vibe out with every sip.'],
|
||||
['sku' => 'ATM-CB-100MG', 'desc' => '? Cold Brew?\r\n\r\nThis one<6E>s for the go-getters, deep thinkers, and house-cleaners. Cold Brew is straight-up, black, RSO infused coffee made from locally roasted Press Coffee beans. No sugar, no dairy, no creamer, no fluff. Just bold, rich flavor and smooth, functional fuel.\r\n\r\n\r\n? What Makes It Legendary\r\n\r\nPure Press Power: Brewed with locally roasted beans from Arizona<6E>s own Press Coffee\r\n\r\nSimple & Strong: No sugar, no dairy, no additives, just cold brew and RSO\r\n\r\nCaffeine & Cannabinoids: 150mg of caffeine + 100mg of hybrid RSO\r\n\r\nMake It Yours: Ice it, heat it, mix it with your morning cup, this one plays nice with whatever vibe you\'re chasing\r\n\r\n? Why You\'ll Love It\r\n\r\nCold Brew doesn<73>t mess around. You won<6F>t be falling asleep but you might clean your whole house. It delivers a relaxed, focused buzz that hits in about 10 minutes and keeps you motivated. It<49>s your new best friend with benefits: uplifting, energizing, and all flavor, no fuss.'],
|
||||
['sku' => 'ATM-PB-100MG', 'desc' => '? Peach Bellini ?\r\n\r\nSay aloha to your new favorite sip: Peach Bellini a sparkling, sun-kissed twist on the classic peach tea, infused with a splash of citrus and a whole lot of chill. This isn<73>t just a drink; it<69>s a tropical daydream in a bottle, crafted for those who crave flavor, fun, and a fast-acting experience.\r\n\r\n\r\n? What Makes It Legendary\r\n\r\nFlavor Fusion: A delightful blend of ripe peach tea and zesty lemon juice, sweetened naturally with organic blue agave\r\n\r\nPower-Packed: Infused with Live Resin for a balanced, uplifting effect\r\n\r\nRapid Onset: Feel the effects in just 10 minutes with no waiting, just enjoying\r\n\r\nClean & Conscious: Organic, gluten-free, vegan, and made with full extract cannabis oil\r\n\r\n? Why You\'ll Love It\r\n\r\nPeach Bellini delivers a luscious fusion of juicy peach and bright citrus, all enhanced by a smooth, euphoric buzz. Light, refreshing, and irresistibly craveable, this infused delight invigorates your palate while lifting your spirits. It<49>s the perfect way to sip, smile, and elevate your vibe.'],
|
||||
['sku' => 'ATM-SL-100MG', 'desc' => '?Strawberry Lemonade?\r\n\r\nStrawberry Lemonade is your liquid vacation bursting with juicy strawberries and zesty lemon. This isn\'t just a drink; it\'s a tropical daydream in a bottle, crafted for those who crave flavor, fun, and a fast-acting experience.\r\n\r\n? What Makes It Legendary\r\n\r\nFlavor Fusion: A delightful blend of strawberries and lemon, sweetened naturally with organic blue agave\r\n\r\nPower-Packed: Infused with Live Resin for a balanced, uplifting effect\r\n\r\nRapid Onset: Feel the effects in just 10 minutes with no waiting, just enjoying\r\n\r\nClean & Conscious: Organic, gluten-free, vegan, and made with full extract cannabis oil\r\n\r\n?? Why You\'ll Love It\r\n\r\nStrawberry Lemonade delivers a luscious fusion of fruity flavors with just the right touch of sweetness, all enhanced by a smooth, euphoric buzz. Light, refreshing, and irresistibly craveable, this infused delight invigorates your palate while lifting your spirits. It<49>s the perfect way to sip, smile, and elevate your vibe.'],
|
||||
['sku' => 'ATM-SOTB-100MG', 'desc' => '? Sunrise on the Beach?\r\nIt<49>s delicioso. A breezy blend of simple peach tea, tart cran, lemon, and orange juice that hits just right. Sunrise on the Beach is light, refreshing, and wicked tasty, easy on the stomach, real nice on the taste buds, and yeah...it<69>s a staff favorite for a reason.\r\n\r\n? What Makes It Legendary\r\n\r\nFlavor Fusion: Peach tea, cranberry, lemon, and orange juice, no weird stuff, just flavor that slaps\r\n\r\nSolventless Strength: Infused with Live Hash Rosin for a clean, full-spectrum high\r\n\r\nFast Acting: Onset in 10 minutes, don<6F>t blink\r\n\r\nClean AF: No fake junk, just organic, vegan, gluten-free, full extract cannabis oil\r\n\r\n? Why You\'ll Love It\r\n\r\nHipsters like it. So do your coworkers. It<49>s wicked good. A chill, tasty trip that won<6F>t weigh you down and might just become your go-to. Throw it on ice or sip it straight. Just try it already.'],
|
||||
['sku' => 'ATM-TFP-100MG', 'desc' => '?Tropical Fruit Punch?\r\n\r\nTropical Fruit Punch is your liquid vacation bursting with juicy pineapple, ripe cherry, tart cranberry, and zesty lemon. This isn\'t just a drink; it\'s a tropical daydream in a bottle, crafted for those who crave flavor, fun, and a fast-acting experience.\r\n\r\n? What Makes It Legendary\r\n\r\nFlavor Fusion: A delightful blend of pineapple, cherry, cranberry, and lemon, sweetened naturally with organic blue agave\r\n\r\nPower-Packed: Infused with RSO for a balanced, uplifting effect\r\n\r\nRapid Onset: Feel the effects in just 10 minutes with no waiting, just enjoying\r\n\r\nClean & Conscious: Organic, gluten-free, vegan, and made with full extract cannabis oil\r\n\r\n?? Why You\'ll Love It\r\n\r\nTropical Fruit Punch delivers a luscious fusion of tropical fruits with just the right touch of sweetness, all enhanced by a smooth, euphoric buzz. Light, refreshing, and irresistibly craveable, this infused delight invigorates your palate while lifting your spirits. It<49>s the perfect way to sip, smile, and elevate your vibe.'],
|
||||
['sku' => 'BZ-LR-TB-AZ1G', 'desc' => 'Tropical Blood <20> Live Resin\r\nExotic Flavor | Loud Terps | Savage Finish\r\n\r\nTropical Blood Live Resin doesn<73>t whisper it roars. Pressed from fresh-frozen flower and dripping with terps, this extract delivers a wild rush of tropical fruit layered with gassy undertones and a sharp citrus bite that cuts straight through.\r\n\r\nThe high hits fast and doesn<73>t let go. Expect a soaring, heady lift that drops into a warm, hazy body melt. Uplifting, disorienting, and way too tasty to be safe.\r\n\r\nIt<49>s juicy. It<49>s dangerous. It bleeds flavor.'],
|
||||
['sku' => 'BZ-LRS-TR-AZ1G', 'desc' => 'Trinity <20> Live Resin\r\nFresh Frozen | Full-Spectrum | Faithfully Potent\r\n\r\nTrinity Live Resin is a holy union of flavor, aroma, and full-spectrum fire. Extracted from fresh-frozen flower to preserve every last terp, this concentrate delivers a vivid, true-to-strain experience that hits with divine precision.\r\n\r\nExpect a crisp citrus nose layered with pine, spice, and sweet funk followed by a cerebral lift that settles into calm, centered clarity. It<49>s energetic without chaos. Relaxing without the crash. A perfectly balanced extract for daytime flow or nighttime reset.\r\n\r\nThis one<6E>s sacred. Dab accordingly.'],
|
||||
['sku' => 'BZD-CS-T-AZ1G', 'desc' => 'Trinity <20> Cured Sugar\r\nBalanced Power | Sacred Flavor | Clean Burn\r\n\r\nTrinity Cured Sugar is a crystalized concentrate for the believers the ones who know a good dab is equal parts flavor, function, and fire. This sugar delivers a full-spectrum profile with glistening granules soaked in aromatic terps.\r\n\r\nExpect a smooth blend of citrus zest, earthy pine, and a whisper of floral spice. The high rides high and steady: mentally uplifting with a mellow body float that keeps you grounded but glowing.\r\n\r\nPure. Potent. Perfectly aligned. Trinity is the truth.'],
|
||||
['sku' => 'CAN-RSO-AZ1G', 'desc' => 'Discover the power of RSO Full Spectrum Oil, a premium cannabis extract designed to deliver the full benefits of the plant. This oil is rich in cannabinoids, terpenes, and flavonoids, ensuring you receive a holistic experience that promotes overall wellness. Perfect for those seeking natural relief, RSO Full Spectrum Oil is crafted to enhance your daily routine.\r\n\r\nOur RSO Full Spectrum Oil is meticulously extracted to preserve the integrity of the cannabis plant, providing you with a potent and effective product. Each drop is packed with the goodness of nature, making it an ideal choice for both seasoned users and newcomers alike. Experience the entourage effect as the various compounds work synergistically to support your health.\r\n\r\nEasy to use and versatile, RSO Full Spectrum Oil can be taken sublingually or added to your favorite foods and beverages. With its rich flavor and smooth texture, incorporating this oil into your lifestyle is a breeze. Elevate your wellness journey with RSO Full Spectrum Oil and unlock the potential of cannabis in a convenient and enjoyable way.'],
|
||||
['sku' => 'DBZ-AM-AZ1G', 'desc' => 'Doobz - Animal Mintz\r\n\r\nGet Minty Fresh with Doobz Animal Mintz ?\r\nExperience the pinnacle of purity with Doobz Animal Mintz Pre-rolls. This premium hybrid strain, expertly crafted and infused with solventless, ice water extracted blonde hash, delivers a powerful and smooth hit every time. Sustainably sourced and locally grown, these pre-rolls embody Arizona\'s commitment to quality and community. Each puff offers a minty, refreshing taste that\'ll have you roaring for more. Get ready to unleash the beast within!\r\n\r\nNature\'s Artistry\r\nEach pre-roll is a visual delight, featuring dense, forest-green nuggets dusted with shimmering trichomes and vibrant orange pistils. It\'s a true testament to nature\'s craftsmanship.\r\n\r\nAroma and Flavor\r\nCrack open the pack and let the scent of Animal Mintz envelop you: a minty, earthy aroma with hints of sweet undertones. This aromatic bouquet promises a deeply satisfying and invigorating experience that transports you to a refreshing minty paradise.\r\n\r\nPotent and Flavorful\r\nCrafted with precision, Animal Mintz delivers a smooth, powerful smoke that marries the best qualities of its parent strains. Expect a balanced high that soothes the body and invigorates the mind, making it perfect for relaxation and creative inspiration.\r\n\r\nIndulge in the Experience\r\nIndulge in the exceptional experience of Doobz Infused Pre-rolls, meticulously crafted to showcase the finest cannabis. Each pre-roll is a testament to precision and excellence, offering a sensory journey that ignites the senses with every inhale. The rich flavors and potent effects promise a powerful encounter with each use.\r\n\r\nEco-Friendly Packaging\r\nDoobz<62> responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the minty freshness of Animal Mintz <20> setting the standard for excellence.\r\n\r\nCheers to minty highs! ?'],
|
||||
['sku' => 'DBZ-BK-AZ1G', 'desc' => 'Doobz Banana Kush\r\n\r\nBanana Bliss with Doobz Banana Kush ?\r\nUnwind in the soothing embrace of Doobz Banana Kush Pre-rolls. This exceptional indica strain is expertly crafted and infused with premium solventless, ice water extracted hash, delivering a flavorful and smooth experience with every puff. Sustainably sourced and locally grown, these pre-rolls embody Arizona<6E>s commitment to quality and community.\r\n\r\nDecadent Craft\r\nInside each pre-roll, you<6F>ll find dense, well-cured nugs showcasing a shimmering layer of trichomes, featuring rich yellow and deep green hues. This guarantees a premium smoking experience that captivates the senses.\r\n\r\nAromatically Fruity\r\nOpen the pack and let the delightful scent of Banana Kush envelop you: a sweet, fruity aroma with hints of creamy banana and subtle earthy undertones. This aromatic profile promises a deeply satisfying and comforting experience.\r\n\r\nSmooth and Relaxing\r\nMeticulously crafted, Banana Kush offers a smooth, flavorful smoke that beautifully highlights the best qualities of its parent strains. Expect a tranquil high that relaxes the body and eases the mind, making it perfect for winding down after a long day.\r\n\r\nSavor the Moment\r\nIndulge in the extraordinary experience of Doobz Infused Pre-rolls, thoughtfully crafted to showcase the finest cannabis. Each pre-roll stands as a testament to precision and excellence, providing a sensory journey that delights with every inhale.\r\n\r\nEco-Conscious Packaging\r\nDoobz<62> responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the calming joy of Banana Kush <20> setting a new standard for excellence.\r\n\r\nCheers to soothing highs! ?'],
|
||||
['sku' => 'DBZ-CF-AZ1G', 'desc' => 'Doobz Carbon Fiber\r\n\r\nDrive into the Future with Doobz Carbon Fiber ?\r\nRace ahead with Doobz Carbon Fiber Pre-rolls. This high-performance hybrid strain, infused with solventless, ice water extracted hash, ensures a potent, smooth ride. Sustainably sourced and locally grown in Arizona, these pre-rolls embody a commitment to quality and community.\r\n\r\nHigh-Performance Craft\r\nThe nugs inside these pre-rolls are dense and sticky, dusted with shimmering trichomes and vibrant orange pistils, ensuring a high-quality smoking experience.\r\n\r\nEarthy and Fuel Aroma\r\n\r\nCrack open the pack and let the scent of Carbon Fiber envelop you: rich, earthy tones with hints of fuel and pine. This aromatic bouquet promises a deeply satisfying and invigorating experience.\r\n\r\nEnergetic and Relaxing\r\nCrafted with precision, Carbon Fiber delivers a smooth, powerful smoke that marries the best qualities of its parent strains. Expect a balanced high that energizes and relaxes, making it perfect for any adventure.\r\n\r\nExperience the Thrill\r\nIndulge in the exceptional experience of Doobz Infused Pre-rolls, meticulously crafted to showcase the finest cannabis. Each pre-roll is a testament to precision and excellence, offering a sensory journey that ignites the senses with every inhale.\r\n\r\nEco-Friendly Packaging\r\nDoobz<62> responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the high-speed delight of Carbon Fiber <20> setting the standard for excellence.\r\n\r\nCheers to exhilarating highs! ?'],
|
||||
['sku' => 'DBZ-CW-AZ1G', 'desc' => 'Doobz Chocolate Waffles\r\n\r\nChocoLift with Doobz Chocolate Waffles ?\r\nElevate your day with the delightful experience of Doobz Chocolate Waffles Pre-rolls. This exceptional sativa strain is expertly crafted and infused with premium solventless, ice water extracted hash, delivering a flavorful and invigorating journey with every puff. Sustainably sourced and locally grown, these pre-rolls reflect Arizona<6E>s dedication to quality and community.\r\n\r\nDecadent Craft\r\nInside each pre-roll, you<6F>ll discover dense, well-cured nugs adorned with a shimmering layer of trichomes, showcasing rich brown and deep green hues. This guarantees a premium smoking experience that enchants the senses.\r\n\r\nAromatically Irresistible\r\nOpen the pack and let the delicious scent of Chocolate Waffles envelop you: a rich, chocolatey aroma with notes of warm vanilla and a hint of sweetness. This aromatic profile promises a deeply satisfying and uplifting experience.\r\n\r\nSmooth and Energizing\r\nMeticulously crafted, Chocolate Waffles offers a smooth, flavorful smoke that highlights the best qualities of its parent strains. Expect a lively high that energizes the mind while uplifting the spirit, making it perfect for creative endeavors or social gatherings.\r\n\r\nSavor the Moment\r\nIndulge in the extraordinary experience of Doobz Infused Pre-rolls, thoughtfully crafted to showcase the finest cannabis. Each pre-roll stands as a testament to precision and excellence, providing a sensory journey that delights with every inhale.\r\n\r\nEco-Conscious Packaging\r\nDoobz<62> responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the sweet joy of Chocolate Waffles <20> setting a new standard for excellence.\r\n\r\nCheers to vibrant highs! ?'],
|
||||
['sku' => 'DBZ-F95-AZ1G', 'desc' => 'Doobz Fam 95\r\n\r\nElevated Legacy with Doobz Fam 95 ??\r\n\r\nAwaken your senses with Doobz Fam 95 Pre-rolls <20> a sativa-leaning hybrid infused with premium solventless, ice water extracted hash. Known for its powerful lineage and vibrant energy, Fam 95 blends classic genetics with a modern, uplifting twist. Grown sustainably in Arizona and carefully crafted, each pre-roll delivers a bold, energizing experience built for those who appreciate heritage and high performance.\r\n\r\nPrecision Craft\r\n\r\nEach pre-roll features expertly cured, resin-coated buds shining with trichomes and boasting rich hues of green with flecks of orange and purple. Expect a clean, even burn and a consistently flavorful smoke that reflects true artisan quality.\r\n\r\nGassy & Bright\r\n\r\nUnseal the pack and catch the bold, fuel-forward aroma of Fam 95, cut with hints of citrus zest, pine, and a subtle creamy finish. This invigorating scent profile sets the stage for a dynamic, sensory-driven session.\r\n\r\nEnergizing & Focused\r\n\r\nFam 95 delivers a clear-headed, active high that inspires creativity and keeps the vibes high. Perfect for daytime sessions, social adventures, or tackling tasks with fresh perspective, this sativa-leaning hybrid keeps your energy up without sacrificing chill.\r\n\r\nCrafted for Momentum\r\n\r\nDoobz Infused Pre-rolls are built for those who seek both flavor and function. Fam 95 offers a high-performance experience rooted in legendary genetics, curated with care to spark connection and momentum.\r\n\r\nPlanet-Friendly Packaging\r\n\r\nStay elevated and eco-conscious <20> every Fam 95 pre-roll comes in sustainable packaging that aligns with your values. ?\r\n\r\nFuel your flow with Fam 95 <20> bold energy, timeless flavor.\r\n\r\nStay sharp. Stay lifted. ?'],
|
||||
['sku' => 'DBZ-GG-AZ1G', 'desc' => 'Doobz Grape Gas\r\n\r\nFuel Your Fun with Doobz Grape Gas ??\r\nIgnite your senses with Doobz Grape Gas Pre-rolls. This dynamic hybrid strain, expertly crafted and infused with solventless, ice water extracted hash, delivers a powerful and smooth hit every time. Sustainably sourced and locally grown, these pre-rolls embody Arizona\'s commitment to quality and community.\r\n\r\nDynamic Craft\r\nThe nugs inside these pre-rolls are dense and sticky, dusted with shimmering trichomes and vibrant orange pistils, ensuring a high-quality smoking experience.\r\n\r\nRich Grape Aroma\r\nCrack open the pack and let the scent of Grape Gas envelop you: a rich blend of grape and fuel with hints of sweetness. This aromatic bouquet promises a deeply satisfying and invigorating experience.\r\n\r\nEnergetic and Relaxing\r\nCrafted with precision, Grape Gas delivers a smooth, powerful smoke that marries the best qualities of its parent strains. Expect a balanced high that energizes and relaxes, making it perfect for any occasion.\r\n\r\nSavor the Adventure\r\nIndulge in the exceptional experience of Doobz Infused Pre-rolls, meticulously crafted to showcase the finest cannabis. Each pre-roll is a testament to precision and excellence, offering a sensory journey that ignites the senses with every inhale.\r\n\r\nEco-Friendly Packaging\r\nDoobz<62> responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the dynamic delight of Grape Gas <20> setting the standard for excellence.'],
|
||||
['sku' => 'DBZ-GM-AZ1G', 'desc' => 'Doobz Gush Mints\r\n\r\nMint to Be with Doobz Gush Mints ?\r\nIndulge in the fresh delight of Doobz Gush Mints Pre-rolls. This premium hybrid strain, expertly crafted and infused with solventless, ice water extracted hash, delivers a powerful and smooth hit every time. Sustainably sourced and locally grown, these pre-rolls embody Arizona\'s commitment to quality and community.\r\n\r\nMinty Fresh Craft\r\nThe nugs inside these pre-rolls are dense and sticky, dusted with shimmering trichomes and vibrant orange pistils, ensuring a high-quality smoking experience.\r\n\r\nRefreshing Mint Aroma\r\nCrack open the pack and let the scent of Gush Mints envelop you: a minty, earthy aroma with hints of sweetness. This aromatic bouquet promises a deeply satisfying and invigorating experience.\r\n\r\nSmooth and Uplifting\r\nCrafted with precision, Gush Mints delivers a smooth, powerful smoke that marries the best qualities of its parent strains. Expect a balanced high that relaxes and uplifts, making it perfect for any time of day.\r\n\r\nRelish the Experience\r\nIndulge in the exceptional experience of Doobz Infused Pre-rolls, meticulously crafted to showcase the finest cannabis. Each pre-roll is a testament to precision and excellence, offering a sensory journey that ignites the senses with every inhale.\r\n\r\nEco-Conscious Packaging\r\nDoobz<62> responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the refreshing delight of Gush Mints <20> setting the standard for excellence.\r\n\r\nCheers to minty highs! ?'],
|
||||
['sku' => 'DBZ-HD-AZ1G', 'desc' => 'Doobz Hawaiian Dream\r\n\r\nTropical Escape with Doobz Hawaiian Dream ?\r\nImmerse yourself in the vibrant world of Doobz Hawaiian Dream Pre-rolls. This exceptional sativa-dominant hybrid is expertly crafted and infused with premium solventless, ice water extracted hash, delivering a flavorful and uplifting experience with every puff. Sustainably sourced and locally grown, these pre-rolls embody Arizona<6E>s commitment to quality and community.\r\n\r\nDecadent Craft\r\nInside each pre-roll, you<6F>ll find dense, well-cured nugs adorned with a dazzling layer of trichomes, showcasing bright green and golden hues. This guarantees a premium smoking experience that delights the senses.\r\n\r\nAromatically Tropical\r\n\r\nOpen the pack and let the enchanting scent of Hawaiian Dream envelop you: a sweet, fruity aroma with notes of tropical citrus and subtle floral undertones. This aromatic profile promises a deeply satisfying and refreshing experience.\r\n\r\nSmooth and Uplifting\r\nMeticulously crafted, Hawaiian Dream offers a smooth, flavorful smoke that beautifully combines the best qualities of its parent strains. Expect a lively high that energizes the body while inspiring creativity, making it perfect for daytime adventures or social gatherings.\r\n\r\nSavor the Moment\r\nIndulge in the extraordinary experience of Doobz Infused Pre-rolls, thoughtfully crafted to showcase the finest cannabis. Each pre-roll stands as a testament to precision and excellence, providing a sensory journey that delights with every inhale.\r\n\r\nEco-Conscious Packaging\r\nDoobz<62> responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the tropical bliss of Hawaiian Dream <20> setting a new standard for excellence.\r\n\r\nCheers to vibrant highs! ?'],
|
||||
['sku' => 'DBZ-IL-AZ1G', 'desc' => 'Doobz Illemonati\r\n\r\nZesty Enlightenment with Doobz Illemonati ??\r\n\r\nStep into the limelight with Doobz Illemonati Pre-rolls, a radiant sativa-dominant hybrid infused with premium solventless, ice water extracted hash. Bursting with flavor and carefully curated for an uplifting, citrus-forward experience, Illemonati is your ticket to elevated clarity and energetic vibes. Crafted from sustainably sourced, locally grown flower, this pre-roll is a celebration of Arizona<6E>s passion for quality and conscious cultivation.\r\n\r\nLemon-Laced Craft\r\nEach pre-roll is packed with hand-selected buds glistening with trichomes, painted in vivid greens and soft yellow highlights. This superior flower guarantees a smooth, flavorful smoke designed for the discerning cannabis connoisseur.\r\n\r\nBright and Aromatic\r\nOpen the pack and be greeted by the unmistakable zest of Illemonati, a bright lemon-lime aroma with hints of herbal pine and a whisper of sweetness. This lively terpene profile awakens the senses and sets the tone for a revitalizing journey.\r\n\r\nUplifting & Clear-Headed\r\nIllemonati delivers a clean, euphoric high that sharpens focus and fuels creativity. Perfect for sparking conversation, diving into a project, or enjoying an energizing outdoor escape, this pre-roll enhances the moment without overwhelming it.\r\n\r\nCrafted to Shine\r\nWith every puff, Doobz Infused Pre-rolls reflect a dedication to excellence. From cultivation to infusion, Illemonati is a testament to expert craftsmanship and flavor-forward cannabis experiences.\r\n\r\nEarth-Friendly Elegance\r\nTrue to Doobz values, every pre-roll is housed in eco-conscious packaging because elevating your mood shouldn<64>t come at the planet<65>s expense. ?\r\n\r\nUnlock clarity and spark joy with Illemonati <20> a golden standard of citrus-powered brilliance.\r\n\r\nStay lit, stay lifted. ?'],
|
||||
['sku' => 'DBZ-JC-AZ1G', 'desc' => 'Doobz Jelly Cake\r\n\r\nDecadent Delight with Doobz Jelly Cake ??\r\n\r\nSatisfy your senses with Doobz Jelly Cake Pre-rolls a luxurious indica-dominant hybrid that blends premium flower with solventless, ice water extracted hash for a deeply relaxing and flavorful experience. Handcrafted with care and sourced from local, sustainable growers, Jelly Cake is a rich expression of Arizona<6E>s finest cannabis culture.\r\n\r\nDessert-Level Craft\r\nEach pre-roll is packed with resin-rich, meticulously cured buds sparkling with trichomes and boasting a deep mix of purples, forest greens, and frosted hues. The craftsmanship ensures a slow, even burn and a smooth draw that delivers every time.\r\n\r\nSweet & Seductive Aroma\r\nUnwrap the indulgence and breathe in Jelly Cake<6B>s irresistible scent, a rich bouquet of berries, vanilla frosting, and subtle earthy undertones. This dessert-forward terpene profile teases the nose and prepares you for a truly satisfying session.\r\n\r\nRelaxing and Blissful\r\nJelly Cake offers a smooth, decadent smoke with calming body effects and a gentle cerebral lift. Ideal for unwinding after a long day, boosting your mood, or enhancing cozy evenings, this strain envelops you in a warm, euphoric haze of contentment.\r\n\r\nCurated for Comfort\r\nEvery Doobz Infused Pre-roll is a celebration of precision and potency. With Jelly Cake, you<6F>re not just lighting up you<6F>re elevating your downtime with flavor, care, and intention.\r\n\r\nPlanet-Friendly Packaging\r\nDoobz remains committed to sustainability, delivering every indulgent pre-roll in eco-conscious packaging that feels as good as the product inside. ?\r\n\r\nTreat yourself to the dreamy decadence of Jelly Cake <20> where dessert meets deep relaxation.'],
|
||||
['sku' => 'DBZ-MP-AZ6G', 'desc' => 'Doobz <20> SIXES!\r\nYour All-in-One Preroll Adventure ??\r\n\r\nReady to explore a world of flavor and effects? SIXES by Doobz is the ultimate preroll variety pack, featuring six unique, hand-selected strains infused with premium ice water hash for smooth, potent, unforgettable sessions. From relaxing evenings to creative bursts and energetic vibes, this sampler has a preroll for every mood and every moment.\r\n\r\nWhat<61>s Inside:\r\nZack<63>s Cake - Hybrid\r\nPeanut Butter Breath - Hybrid\r\nGush Mints - Hybrid\r\nHawaiian Dream - Sativa\r\nChocolate Waffles - Sativa\r\nBanana Kush - Indica\r\n\r\nSix strains. Six moods. Endless possibilities. Grab your SIXES pack and let the adventure begin!\r\n\r\n? Cheers to many highs!'],
|
||||
['sku' => 'DBZ-PBB-AZ1G', 'desc' => 'Doobz Peanut Butter Breath\r\n\r\nNutty Bliss with Doobz Peanut Butter Breath ?\r\nDive into the deliciously rich world of Doobz Peanut Butter Breath Pre-rolls. This exceptional hybrid strain is expertly crafted and infused with solventless, ice water extracted hash, delivering a flavorful and smooth experience with every puff. Sustainably sourced and locally grown, these pre-rolls reflect Arizona<6E>s dedication to quality and community.\r\n\r\nDecadent Craft\r\nInside each pre-roll, you<6F>ll find dense, well-cured nugs showcasing a stunning layer of trichomes, exuding rich amber and deep green hues. This guarantees a premium smoking experience that delights the senses.\r\n\r\nAromatically Nutty\r\nOpen the pack and let the captivating scent of Peanut Butter Breath envelop you: a creamy, nutty aroma with undertones of sweet earthiness and subtle spice. This aromatic profile promises a deeply satisfying and comforting experience.\r\n\r\nSmooth and Comforting\r\nMeticulously crafted, Peanut Butter Breath offers a smooth, flavorful smoke that blends the best qualities of its parent strains. Expect a balanced high that relaxes the body while lifting the mind, making it ideal for any time of day.\r\n\r\n\r\nSavor the Moment\r\nIndulge in the extraordinary experience of Doobz Infused Pre-rolls, thoughtfully crafted to highlight the finest cannabis. Each pre-roll is a testament to precision and excellence, providing a sensory journey that delights with every inhale.\r\n\r\nEco-Conscious Packaging\r\nDoobz<62> responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the nutty delight of Peanut Butter Breath <20> setting a new standard for excellence.\r\n\r\nCheers to indulgent highs! ?'],
|
||||
['sku' => 'DBZ-TK-AZ1G', 'desc' => 'Doobz - TK Larry\r\n\r\nLaugh Out Loud with Doobz TK Larry ?\r\nTickle your senses with Doobz TK Larry Pre-rolls. This top-tier hybrid strain, infused with solventless, ice water extracted hash, promises a potent, smooth experience. Sustainably sourced and locally grown in Arizona, these pre-rolls bring quality and community right to your fingertips.\r\n\r\nVisually Stunning\r\nThe nugs inside these pre-rolls are dense and sticky, dusted with shimmering trichomes and vibrant orange pistils, ensuring a high-quality smoking experience.\r\n\r\nCitrus Burst Aroma\r\nCrack open the pack and let the scent of TK Larry envelop you: earthy pine with hints of citrus. This aromatic bouquet promises a deeply satisfying and invigorating experience.\r\n\r\nBalanced and Powerful\r\nCrafted with precision, TK Larry delivers a smooth, powerful smoke that marries the best qualities of its parent strains. Expect a balanced high that soothes the body and mind, perfect for relaxation and stress relief.\r\n\r\nEnjoy the Journey\r\nIndulge in the exceptional experience of Doobz Infused Pre-rolls, meticulously crafted to showcase the finest cannabis. Each pre-roll is a testament to precision and excellence, offering a sensory journey that ignites the senses with every inhale.\r\n\r\nEco-Conscious Packaging\r\nDoobz<62> responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the joy of TK Larry <20> setting the standard for excellence.\r\n\r\nCheers to happy highs! ?'],
|
||||
['sku' => 'DBZ-ZC-AZ1G', 'desc' => 'Doobz Zack\'s Cake\r\n\r\nDecadent Delight with Doobz Zack\'s Cake ?\r\nIndulge in the mouthwatering experience of Doobz Zack\'s Cake Pre-rolls. This exceptional hybrid strain is expertly crafted and infused with premium solventless, ice water extracted hash, delivering a flavorful and smooth experience with every puff. Sustainably sourced and locally grown, these pre-rolls embody Arizona<6E>s commitment to quality and community.\r\n\r\nDecadent Craft\r\nInside each pre-roll, you<6F>ll find dense, well-cured nugs adorned with a shimmering layer of trichomes, showcasing rich gold and deep green hues. This guarantees a premium smoking experience that delights the senses.\r\n\r\nAromatically Sweet\r\nOpen the pack and let the enticing scent of Zack\'s Cake envelop you: a deliciously sweet aroma with notes of vanilla and buttery cake, complemented by subtle hints of fresh berries. This aromatic profile promises a deeply satisfying and indulgent experience.\r\n\r\nSmooth and Comforting\r\nMeticulously crafted, Zack\'s Cake offers a smooth, flavorful smoke that beautifully blends the best qualities of its parent strains. Expect a balanced high that relaxes the body while uplifting the spirit, making it perfect for celebrations or cozy nights in.\r\n\r\nSavor the Moment\r\nIndulge in the extraordinary experience of Doobz Infused Pre-rolls, thoughtfully crafted to showcase the finest cannabis. Each pre-roll stands as a testament to precision and excellence, providing a sensory journey that delights with every inhale.\r\n\r\nEco-Conscious Packaging\r\nDoobz<62> responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the sweet joy of Zack\'s Cake <20> setting a new standard for excellence.\r\n\r\nCheers to delicious highs! ?'],
|
||||
['sku' => 'DBZ-ZM-AZ1G', 'desc' => 'Doobz Zpumoni Moonbelts\r\n\r\nBlast Off with Doobz Zpumoni Moonbelts ?\r\nPrepare for a cosmic journey with Doobz Zpumoni Moonbelts Pre-rolls. This stellar hybrid strain, infused with solventless, ice water extracted hash, offers a powerful, smooth hit that\'s out of this world. Sustainably sourced and locally grown in Arizona, these pre-rolls reflect a dedication to quality and community.\r\n\r\nCosmic Craftsmanship\r\nThe nugs inside these pre-rolls are dense and sticky, dusted with shimmering trichomes and vibrant orange pistils, ensuring a high-quality smoking experience.\r\n\r\nFruity and Earthy Aroma\r\nCrack open the pack and let the scent of Zpumoni Moonbelts envelop you: a blend of sweet and earthy aromas with hints of fruit. This aromatic bouquet promises a deeply satisfying and invigorating experience.\r\n\r\nPotent and Uplifting\r\nCrafted with precision, Zpumoni Moonbelts delivers a smooth, powerful smoke that marries the best qualities of its parent strains. Expect a balanced high that uplifts and relaxes, making it perfect for any occasion.\r\n\r\nSavor the Experience\r\nIndulge in the exceptional experience of Doobz Infused Pre-rolls, meticulously crafted to showcase the finest cannabis. Each pre-roll is a testament to precision and excellence, offering a sensory journey that ignites the senses with every inhale.\r\n\r\nSustainable Packaging\r\nDoobz<62> responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the cosmic delight of Zpumoni Moonbelts <20> setting the standard for excellence.\r\n\r\nCheers to stellar highs! ?'],
|
||||
['sku' => 'DBZ-ZM-AZ3G', 'desc' => 'Doobz Zpumoni Moonbelts\r\n\r\nBlast Off with Doobz Zpumoni Moonbelts ?\r\n\r\nPrepare for a cosmic journey with Doobz Zpumoni Moonbelts Pre-rolls. This stellar hybrid strain, infused with solventless, ice water extracted hash, offers a powerful, smooth hit that\'s out of this world. Sustainably sourced and locally grown in Arizona, these pre-rolls reflect a dedication to quality and community.\r\n\r\nCosmic Craftsmanship\r\n\r\nThe nugs inside these pre-rolls are dense and sticky, dusted with shimmering trichomes and vibrant orange pistils, ensuring a high-quality smoking experience.\r\n\r\nFruity and Earthy Aroma\r\n\r\nCrack open the pack and let the scent of Zpumoni Moonbelts envelop you: a blend of sweet and earthy aromas with hints of fruit. This aromatic bouquet promises a deeply satisfying and invigorating experience.\r\n\r\nPotent and Uplifting\r\n\r\nCrafted with precision, Zpumoni Moonbelts delivers a smooth, powerful smoke that marries the best qualities of its parent strains. Expect a balanced high that uplifts and relaxes, making it perfect for any occasion.\r\n\r\nSavor the Experience\r\n\r\nIndulge in the exceptional experience of Doobz Infused Pre-rolls, meticulously crafted to showcase the finest cannabis. Each pre-roll is a testament to precision and excellence, offering a sensory journey that ignites the senses with every inhale.\r\n\r\nSustainable Packaging\r\n\r\nDoobz<62> responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the cosmic delight of Zpumoni Moonbelts <20> setting the standard for excellence.\r\n\r\nCheers to stellar highs! ?'],
|
||||
['sku' => 'DK-CF-AZ2G', 'desc' => 'CAKE FACE DOINK\r\n2-Gram Ice Water Hash-Infused Hemp Blunt\r\nHybrid | Glass Tip | 100% Flower\r\n\r\nThis Ain<69>t a Joint. It<49>s a DOINK.\r\nCake Face comes through with all the creamy sweetness and heavy gas you didn<64>t know you needed then knocks politely on your frontal lobe and takes over your whole vibe. Wrapped in a clean-burning hemp blunt and finished with a frosty ice water hash infusion, this 2g beast is handcrafted for heads who like their smoke smooth, their flavor loud, and their sesh elevated.\r\n\r\nEvery Doink is rolled thick with premium cannabis flower, no trim, no shake, no shortcuts. Just pure, solventless hash and top-shelf bud, brought together in one slow-burning, glass-tipped masterpiece.\r\n\r\nFLAVOR PROFILE\r\n? Frosted Vanilla Cake\r\n? Loud OG Gas\r\n?? Creamy exhale with a kushy finish\r\n\r\nFEELING YOURSELF? YOU SHOULD BE.\r\nHybrid Vibes: Chill meets charge. Cake Face balances a hazy, feel-good euphoria with a relaxed body buzz. Floaty but grounded. Perfect for daytime hangs, nighttime movies, or anytime you<6F>re tryna vibe and thrive.\r\n\r\nWHY DOINKS HIT HARDER\r\n<> 2 FULL GRAMS of loud, ice water hash-infused flower ?\r\n<> HEMP WRAP <20> Blunt feel, zero tobacco ??\r\n<> GLASS TIP <20> Smooth draws, no soggy ends ???\r\n<> NO BS <20> Just fire flower + hash. No fillers, ever. ?\r\n<> SMALL BATCH ROLLS: Artisan-crafted, quality-checked ?'],
|
||||
['sku' => 'DK-DK-AZ2G', 'desc' => 'DARK RAINBOW DOINK\r\n2-Gram Ice Water Hash-Infused Hemp Blunt\r\nIndica-Dominant Hybrid | Glass Tip | 100% Flower\r\n\r\nEVER SEEN A RAINBOW AFTER DARK?\r\nThis one doesn<73>t sparkle - it glows.\r\nDark Rainbow is a deep-hitting, mood-melting blend that delivers a full-spectrum experience with a heavier lean toward the laid-back. Wrapped tight in a tobacco-free hemp blunt and packed with small-batch flower + solventless ice water hash, this Doink brings layered flavor and heavy vibes in one slow-burning masterpiece.\r\n\r\nLight it up and sink into the softer side of the spectrum dreamy headspace, cozy body high, and colors you can feel.\r\n\r\nFLAVOR PROFILE\r\n? Grape candy with a diesel edge\r\n? Funky fruit swirl\r\n?? Smooth, earthy finish with a kushy punch\r\n\r\nTHE VIBE? SEDUCTIVELY STONEY.\r\nIndica-Dominant Hybrid: Expect mind-easing euphoria followed by a warm body melt that doesn<73>t glue you to the couch <20> unless you want it to. Whether you<6F>re decompressing after a long day or just turning the volume down on life, Dark Rainbow<6F>s got you covered.\r\n\r\nWHY DOINKS HIT HARDER\r\n<> 2 FULL GRAMS of loud, ice water hash-infused flower ?\r\n<> HEMP WRAP <20> Blunt feel, zero tobacco ??\r\n<> GLASS TIP <20> Smooth draws, no soggy ends ???\r\n<> NO BS <20> Just fire flower + hash. No fillers, ever. ?\r\n<> SMALL BATCH ROLLS: Artisan-crafted, quality-checked ?\r\n\r\nDARK RAINBOW\r\nGrape Pie x Rainbow Beltz\r\nIndica-leaning hybrid | Fruity, gassy, grounding | Relaxed, euphoric, hazy\r\n\r\nSEE THE NIGHT IN COLOR. SMOKE THE DARK RAINBOW.'],
|
||||
['sku' => 'DK-MB-AZ2G', 'desc' => 'MODIFIED BANANA DOINK\r\n2-Gram Ice Water Hash-Infused Hemp Blunt\r\nIndica-Dominant Hybrid | Glass Tip | 100% Flower\r\n\r\nBUCKLE UP. THIS BANANA BITES BACK.\r\nDon<6F>t let the name fool you, Modified Banana isn<73>t some mellow fruit puff. It<49>s a rich, funky, flavor packed hybrid with a smooth banana cream intro and a gassy backend that brings the heat. Infused with premium ice water hash and hand-rolled in a hemp blunt wrap with a glass tip, this Doink blends top-tier taste with heavy lifting effects that stick the landing.\r\n\r\nFLAVOR PROFILE\r\n? Banana pudding\r\n? Diesel funk\r\n?? Creamy inhale with a spicy exhale\r\n\r\nTHE VIBE? HEAVY HEAD, HAPPY HEART.\r\nIndica-Leaning Hybrid: Modified Banana delivers an early lift followed by a slow, calming descent. Perfect for evening chillouts, movie marathons, or turning down the noise after a long day. Expect a mellow mind, relaxed muscles, and a silly grin you won<6F>t want to shake.\r\n\r\nWHY DOINKS HIT HARDER\r\n<> 2 FULL GRAMS of loud, ice water hash-infused flower ?\r\n<> HEMP WRAP <20> Blunt feel, zero tobacco ??\r\n<> GLASS TIP <20> Smooth draws, no soggy ends ???\r\n<> NO BS <20> Just fire flower + hash. No fillers, ever. ?\r\n<> SMALL BATCH ROLLS: Artisan-crafted, quality-checked ?'],
|
||||
['sku' => 'DK-OI-AZ2G', 'desc' => 'OISHII DOINK\r\n2-Gram Ice Water Hash Infused Hemp Blunt\r\nHybrid | Glass Tip | 100% Flower\r\n\r\nTHE FLAVOR IS IN THE NAME.\r\n<>Oishii<69> means <20>delicious<75> in Japanese and trust, this one lives up to the name.\r\nThis hybrid Doink is a full-course flavor bomb: sweet, funky, and complex with a creamy exhale that keeps you coming back for another hit. Rolled in a tobacco-free hemp wrap, packed with 100% flower and premium ice water hash, and finished with a glass tip for maximum smoothness, Oishii is a high-end smoke with zero pretense.\r\n\r\nIt<49>s tasty, it<69>s terpy, and it hits like a dream.\r\n\r\nFLAVOR PROFILE\r\n? Ripe berry funk\r\n? Creamy sherbet swirl\r\n?? Sweet gas on the finish\r\n\r\nTHE VIBE? FLAVOR-FORWARD & FLOATY.\r\nTrue Hybrid: Oishii rides the line between uplift and unwind, creative headspace up top, soft body vibes underneath. Ideal for social sessions, creative flow states, or just zoning into your own good mood.\r\n\r\nWHY DOINKS HIT HARDER\r\n<> 2 FULL GRAMS of loud, ice water hash-infused flower ?\r\n<> HEMP WRAP <20> Blunt feel, zero tobacco ??\r\n<> GLASS TIP <20> Smooth draws, no soggy ends ???\r\n<> NO BS <20> Just fire flower + hash. No fillers, ever. ?\r\n<> SMALL BATCH ROLLS: Artisan-crafted, quality-checked ?'],
|
||||
['sku' => 'HE-HH-BM-AZ1.25G', 'desc' => 'High Expectations Hash Holes: Blue Monkey\r\n\r\nGet Ready to Monkey Around with High Expectations Hash Holes: Blue Monkey ?\r\n\r\nStep right up and swing into the wildest adventure with High Expectations Hash Holes! Our Blue Monkey strain is an artisanal marvel meticulously crafted for the connoisseur seeking the pinnacle of cannabis refinement. Wrapped in the finest Elements Rolling Paper, this masterpiece marries craftsmanship with sophistication. Topped off with a sleek glass tip, each puff promises a smooth, flavorful journey through the jungle of your senses. Prepare for a sensory safari where indulgence meets elegance, exclusively with our exquisite High Expectations Hash Holes.\r\n\r\nKey Features:\r\n\r\nHybrid Strain: This dynamic duo of Blue Runtz Flower and Headhunter Rosin delivers a balanced symphony of effects. Whether you<6F>re looking to relax or get a burst of euphoria, it<69>s the best of both worlds, rolled into one.\r\n\r\n2.5 Grams of Blue Runtz Flower + 0.5 Grams of Headhunter Rosin: Embark on a sensory adventure with our Blue Monkey Hash Hole. This tantalizing fusion boasts 2.5 grams of Blue Runtz flower and 0.5 grams of luscious Headhunter Rosin. The sweet, fruity tones of Blue Runtz harmonize with the rich, gassy notes of Headhunter for a flavor fiesta.\r\n\r\n100% Solventless Hash Rosin: No monkey business here<72>our Blue Monkey is crafted with pure, solventless hash rosin. It<49>s just the plant, pure and simple, ensuring a smooth and powerful ride.\r\n\r\nNothing but Plant: We keep it real with nothing but pure plant goodness. High Expectations Hash Holes: Blue Monkey has no synthetic additives, just natural, clean, and unadulterated excellence. ?\r\n\r\nSustainably Sourced: Our ingredients are sustainably sourced, so you can enjoy every puff with a green conscience. It<49>s an eco-friendly indulgence that respects Mother Earth. ?\r\n\r\nResponsibly Packaged: High Expectations Hash Holes: Blue Monkey comes in eco-friendly packaging because we know it<69>s what<61>s on the inside (and the outside) that counts. It<49>s a package that<61>s as classy as the product itself. ?\r\n\r\n\r\nMonkey Business Never Felt So Good ?\r\n\r\nReady to swing from the vines? High Expectationsa Hash Holes: Blue Monkey is your ticket to a high-class, wild experience. This infused pre-roll offers a balanced blend of effects, giving you the best of both worlds<64>uplifting and relaxing, all wrapped in one.\r\n\r\nWhy settle for a regular joint when you can have a Hash Hole? Blue Monkey delivers a smooth, flavorful vapor that<61>ll make your taste buds tingle and your mind soar. It<49>s the perfect blend of wild and wonderful, just the way you like it.\r\n\r\nSo, grab your High Expectations Hash Holes: Blue Monkey today and get ready to monkey around with a wild, wonderful ride. Cheers to a flavor-packed adventure! ??'],
|
||||
['sku' => 'HE-HH-BM-AZ3G', 'desc' => 'High Expectations Hash Holes: Blue Monkey\r\n\r\nGet Ready to Monkey Around with High Expectations Hash Holes: Blue Monkey ?\r\n\r\nStep right up and swing into the wildest adventure with High Expectations Hash Holes! Our Blue Monkey strain is an artisanal marvel meticulously crafted for the connoisseur seeking the pinnacle of cannabis refinement. Wrapped in the finest Elements Rolling Paper, this masterpiece marries craftsmanship with sophistication. Topped off with a sleek glass tip, each puff promises a smooth, flavorful journey through the jungle of your senses. Prepare for a sensory safari where indulgence meets elegance, exclusively with our exquisite High Expectations Hash Holes.\r\n\r\nKey Features:\r\n\r\nHybrid Strain: This dynamic duo of Blue Runtz Flower and Headhunter Rosin delivers a balanced symphony of effects. Whether you<6F>re looking to relax or get a burst of euphoria, it<69>s the best of both worlds, rolled into one.\r\n\r\n2.5 Grams of Blue Runtz Flower + 0.5 Grams of Headhunter Rosin: Embark on a sensory adventure with our Blue Monkey Hash Hole. This tantalizing fusion boasts 2.5 grams of Blue Runtz flower and 0.5 grams of luscious Headhunter Rosin. The sweet, fruity tones of Blue Runtz harmonize with the rich, gassy notes of Headhunter for a flavor fiesta.\r\n\r\n100% Solventless Hash Rosin: No monkey business here<72>our Blue Monkey is crafted with pure, solventless hash rosin. It<49>s just the plant, pure and simple, ensuring a smooth and powerful ride.\r\n\r\nNothing but Plant: We keep it real with nothing but pure plant goodness. High Expectations Hash Holes: Blue Monkey has no synthetic additives, just natural, clean, and unadulterated excellence. ?\r\n\r\nSustainably Sourced: Our ingredients are sustainably sourced, so you can enjoy every puff with a green conscience. It<49>s an eco-friendly indulgence that respects Mother Earth. ?\r\n\r\nResponsibly Packaged: High Expectations Hash Holes: Blue Monkey comes in eco-friendly packaging because we know it<69>s what<61>s on the inside (and the outside) that counts. It<49>s a package that<61>s as classy as the product itself. ?\r\n\r\n\r\nMonkey Business Never Felt So Good ?\r\n\r\nReady to swing from the vines? High Expectationsa Hash Holes: Blue Monkey is your ticket to a high-class, wild experience. This infused pre-roll offers a balanced blend of effects, giving you the best of both worlds<64>uplifting and relaxing, all wrapped in one.\r\n\r\nWhy settle for a regular joint when you can have a Hash Hole? Blue Monkey delivers a smooth, flavorful vapor that<61>ll make your taste buds tingle and your mind soar. It<49>s the perfect blend of wild and wonderful, just the way you like it.\r\n\r\nSo, grab your High Expectations Hash Holes: Blue Monkey today and get ready to monkey around with a wild, wonderful ride. Cheers to a flavor-packed adventure! ??'],
|
||||
['sku' => 'HE-HH-BPC-AZ1.25G', 'desc' => 'Hash Holes: Banana Punch Cake\r\nLive Hash Rosin Hash Hole | 1.25g Total\r\n\r\nDessert for your senses. Balance for your body and mind.\r\nSay hello to Banana Punch Cake, a decadent Hash Hole experience crafted for those who crave sweet flavor and smooth, even effects. This premium pre-roll is expertly hand-rolled in ultra-thin Elements paper and finished with a glass tip for ultra-smooth draws. Packed with small-batch flower and solventless live hash rosin, it is as rich in taste as it is in elevation.\r\n\r\n? The Blend\r\nStrain: Banana Punch Cake (Balanced Hybrid)\r\nInfusion: Live Hash Rosin\r\nContents: 1g Flower + 0.5g Rosin = 1.25g Total\r\n\r\nBanana Punch Cake brings together the tropical sweetness of Banana OG and Purple Punch with the creamy dessert notes of Wedding Cake. The result is a fruit-forward, cakey flavor profile with hints of vanilla, berries, and subtle gas. This evenly balanced hybrid delivers a euphoric head buzz and a mellow body high that is ideal for unwinding without checking out.\r\n\r\nWhen paired with 0.5g of live hash rosin, this Hash Hole becomes a full-bodied, slow-burning treat that satisfies from first spark to final ash.\r\n\r\n? Why You<6F>ll Love It\r\n? Dessert-Like Terps: Rich banana cream, sweet berries, vanilla, and soft gas make it feel like cake in a cone.\r\n\r\n? Smooth Glass Tip: Every hit is cooler, cleaner, and full of flavor thanks to our signature glass filter.\r\n\r\n? 100% Solventless Rosin: Pressed with just heat and pressure. No solvents. No additives. Pure power.\r\n\r\n? All Plant: No fillers. No synthetics. Just premium flower and high-quality rosin.\r\n\r\n?? Sustainable Inside & Out: Thoughtfully sourced ingredients and earth-conscious packaging.\r\n\r\n? Made in Arizona: Locally cultivated, extracted, and rolled. When you light up Banana Punch Cake, you support Arizona cannabis craft.\r\n\r\n? The Experience\r\nBanana Punch Cake delivers a blissful hybrid high that keeps your mood lifted and your body at ease. It is perfect for winding down, sparking up conversation, or leveling out after a long day without getting stuck on the couch. Expect a flavorful, functional experience that is as relaxing as it is enjoyable.\r\n\r\n? Have Your Cake. And Smoke It Too.\r\nBanana Punch Cake is flavor-forward, terp-rich, and expertly crafted to elevate your moment, day or night.'],
|
||||
['sku' => 'HE-HH-DLP-AZ1.25G', 'desc' => 'Hash Holes: Dirty London Poundz\r\n\r\nGet Ready for a Dirty Good Time with Hash Holes: Dirty London Poundz\r\n\r\nIntroducing our signature Hash Hole, an artisanal marvel meticulously crafted for the connoisseur seeking the pinnacle of cannabis refinement! Encased in the finest Elements Rolling Paper, this masterpiece seamlessly marries craftsmanship with sophistication. Within its embrace lies a symphony of premium-grade cannabis and live hash rosin, carefully selected to elevate your senses to new heights. But the luxury doesn\'t stop there, adorned with a sleek glass tip, every inhale promises a smooth, flavorful journey. Prepare to embark on a sensory adventure where indulgence meets elegance, only with our exquisite High Expectations Hash Hole.\r\n\r\n\r\nKey Features:\r\n\r\nHybrid Strain: This dynamic blend of London Poundz Flower and Headhunter delivers a balanced symphony of effects. Whether you\'re looking to relax or get a burst of euphoria, it\'s the best of both worlds, rolled into one.\r\n\r\n2.5 Grams of London Poundz Flower + 0.5 Grams of Headhunter Live Hash Rosin: Embark on a sensory adventure with our Dirty London Poundz Hash Hole, a tantalizing fusion of 2.5 grams of London Poundz flower and 0.5 grams of luscious Headhunter Live Hash Rosin. This artisanal concoction boasts the distinct essence of London Poundz<64>s rich, earthy tones, harmoniously complemented by the delicate sweet flavor of Headhunter.\r\n\r\n100% Solventless Hash Rosin: No shortcuts here<72>our Dirty London Poundz is crafted with pure, solventless hash rosin. It<49>s just the plant, pure and simple, ensuring a smooth and powerful ride.\r\n\r\nNothing but Plant: We keep it real with nothing but pure plant goodness. Hash Holes: Dirty London Poundz has no synthetic additives, just natural, clean, and unadulterated excellence.\r\n\r\nSustainably Sourced: Our ingredients are sustainably sourced, so you can enjoy every puff with a green conscience. It<49>s an eco-friendly indulgence that respects Mother Earth.\r\n\r\nResponsibly Packaged: Dirty London Poundz comes in eco-friendly packaging because we know it\'s what\'s on the inside (and the outside) that counts. It<49>s a package that\'s as classy as the product itself.\r\n\r\n\r\nDirty and Delicious Satisfaction\r\n\r\nReady to roll with the big boys? Dirty London Poundz is your ticket to a high-class experience. This infused pre-roll offers a balanced blend of effects, giving you the best of both worlds<64>uplifting and relaxing, all wrapped in one.\r\n\r\nWhy settle for a regular joint when you can have a Hash Hole? Dirty London Poundz delivers a smooth, flavorful vapor that\'s sure to make your taste buds tingle and your mind soar. It<49>s the perfect blend of naughty and nice, just the way you like it.\r\n\r\nSo, grab your Hash Holes: Dirty London Poundz today and get ready to dive into a dirty, delightful ride. Cheers to a flavor-packed adventure, you cheeky vaper!'],
|
||||
['sku' => 'HE-HH-DLP-AZ3G', 'desc' => 'Hash Holes: Dirty London Poundz\r\n\r\nGet Ready for a Dirty Good Time with Hash Holes: Dirty London Poundz\r\n\r\nIntroducing our signature Hash Hole, an artisanal marvel meticulously crafted for the connoisseur seeking the pinnacle of cannabis refinement! Encased in the finest Elements Rolling Paper, this masterpiece seamlessly marries craftsmanship with sophistication. Within its embrace lies a symphony of premium-grade cannabis and live hash rosin, carefully selected to elevate your senses to new heights. But the luxury doesn\'t stop there, adorned with a sleek glass tip, every inhale promises a smooth, flavorful journey. Prepare to embark on a sensory adventure where indulgence meets elegance, only with our exquisite High Expectations Hash Hole.\r\n\r\n\r\nKey Features:\r\n\r\nHybrid Strain: This dynamic blend of London Poundz Flower and Headhunter delivers a balanced symphony of effects. Whether you\'re looking to relax or get a burst of euphoria, it\'s the best of both worlds, rolled into one.\r\n\r\n2.5 Grams of London Poundz Flower + 0.5 Grams of Headhunter Live Hash Rosin: Embark on a sensory adventure with our Dirty London Poundz Hash Hole, a tantalizing fusion of 2.5 grams of London Poundz flower and 0.5 grams of luscious Headhunter Live Hash Rosin. This artisanal concoction boasts the distinct essence of London Poundz<64>s rich, earthy tones, harmoniously complemented by the delicate sweet flavor of Headhunter.\r\n\r\n100% Solventless Hash Rosin: No shortcuts here<72>our Dirty London Poundz is crafted with pure, solventless hash rosin. It<49>s just the plant, pure and simple, ensuring a smooth and powerful ride.\r\n\r\nNothing but Plant: We keep it real with nothing but pure plant goodness. Hash Holes: Dirty London Poundz has no synthetic additives, just natural, clean, and unadulterated excellence.\r\n\r\nSustainably Sourced: Our ingredients are sustainably sourced, so you can enjoy every puff with a green conscience. It<49>s an eco-friendly indulgence that respects Mother Earth.\r\n\r\nResponsibly Packaged: Dirty London Poundz comes in eco-friendly packaging because we know it\'s what\'s on the inside (and the outside) that counts. It<49>s a package that\'s as classy as the product itself.\r\n\r\n\r\nDirty and Delicious Satisfaction\r\n\r\nReady to roll with the big boys? Dirty London Poundz is your ticket to a high-class experience. This infused pre-roll offers a balanced blend of effects, giving you the best of both worlds<64>uplifting and relaxing, all wrapped in one.\r\n\r\nWhy settle for a regular joint when you can have a Hash Hole? Dirty London Poundz delivers a smooth, flavorful vapor that\'s sure to make your taste buds tingle and your mind soar. It<49>s the perfect blend of naughty and nice, just the way you like it.\r\n\r\nSo, grab your Hash Holes: Dirty London Poundz today and get ready to dive into a dirty, delightful ride. Cheers to a flavor-packed adventure, you cheeky vaper!'],
|
||||
['sku' => 'HE-HH-FF-AZ1.25G', 'desc' => 'Hash Holes: Face on Fire\r\nPremium Infused Pre-Roll | 1.25g Total\r\n\r\nWhere sophistication meets sedation.\r\nIntroducing Face on Fire, an indica-leaning hybrid crafted for deep relaxation and elevated flavor. Rolled in ultra-thin Elements paper and finished with a sleek glass tip, this signature Hash Hole delivers rich potency with undeniable smoothness. It<49>s luxury you can light.\r\n\r\n? The Blend\r\nStrain: Face on Fire (Indica-Leaning Hybrid)\r\nInfusion: Live Hash Rosin\r\nContents: 1g Flower + 0.5g Rosin = 1.25g Total\r\n\r\nA powerhouse cross of White Fire OG and Face Off OG, Face on Fire brings an earthy, spicy diesel profile layered with sweet citrus and pine. Known for its deeply calming effects, this strain leans heavy on the indica side perfect for unwinding, zoning in, or completely zoning out. Paired with Headhunter<65>s premium live hash rosin, the result is a slow-burning escape into comfort and clarity.\r\n\r\n? Why You<6F>ll Love It\r\n? Ultra-Smooth Draw: Finished with a glass tip for cool, flavorful hits and clean airflow.\r\n\r\n? 100% Solventless Rosin: No solvents. No additives. Just heat, pressure, and perfection.\r\n\r\n? Pure Plant Integrity: No synthetic fillers or mystery ingredients just flower and rosin.\r\n\r\n?? Eco-Conscious Inside & Out: Sustainably grown. Responsibly packaged. Guilt-free indulgence.\r\n\r\n? Locally Crafted in Arizona: Grown and rolled by Arizona<6E>s finest cannabis artisans. You<6F>re not just getting high you<6F>re supporting the local scene.\r\n\r\n? The Experience\r\nFace on Fire is your go-to when it<69>s time to slow down and tune in. Expect a heavy body buzz, relaxed limbs, and a headspace that melts stress away without knocking you out. It<49>s stoney, serene, and absolutely satisfying.\r\n\r\n? Time to Unwind?\r\nFace on Fire is your ticket to smooth, elevated relaxation with real depth.'],
|
||||
['sku' => 'HE-HH-GR-AZ1.25G', 'desc' => 'Hash Holes: Gruntz\r\nPremium Infused Pre-Roll | 1.25g Total\r\n\r\nLoud flavor. Laid-back vibes.\r\nMeet Gruntz, the indulgent, flavor forward Hash Hole that doesn<73>t hold back. Handcrafted for those who crave a smooth ride with a candy-coated kick, this infused pre-roll blends top-tier cannabis with live hash rosin in a luxury format. Rolled in Elements paper and finished with a glass tip, it<69>s built for those who savor every puff.\r\n\r\n? The Blend\r\nStrain: Gruntz (Indica-Leaning Hybrid)\r\nInfusion: Live Hash Rosin\r\nContents: 1g Flower + 0.5g Rosin = 1.25g Total\r\n\r\nGruntz is a heavy-hitting cross of Zkittlez and Gelato; a strain celebrated for its bold, fruity aroma and deeply relaxing effects. Expect a burst of candy sweetness on the inhale, followed by creamy, earthy undertones. Enhanced with 0.5 grams of live hash rosin, this Hash Hole delivers a flavorful, body melting experience that<61>s smooth, potent, and satisfying from start to finish.\r\n\r\n? Why You<6F>ll Love It\r\n? Big on Flavor: Bold, fruity, and unmistakably sweet, Gruntz hits your palate like candy with depth.\r\n\r\n? Glass Tip Finish: Experience cooler smoke, smoother draws, and cleaner flavor with every hit.\r\n\r\n? 100% Solventless Rosin: No chemicals. No compromise. Just pure hash rosin pressed with heat and precision.\r\n\r\n? Nothing But Plant: No additives, no fillers just premium cannabis and rosin in perfect harmony.\r\n\r\n?? Sustainable & Smart: Eco-friendly packaging and ethically sourced ingredients mean you can indulge consciously.\r\n\r\n? Arizona-Made: Grown, crafted, and rolled right here in Arizona. When you smoke Gruntz, you<6F>re supporting the local cannabis community.\r\n\r\n? The Experience\r\nGruntz brings you the best of both worlds, a bright, uplifting onset followed by a calm, cozy body high. It<49>s ideal for kicking back, elevating your mood, or winding down with intention. Sweet, smooth, and seriously stoney.\r\n\r\n? Sweeten Your Session\r\nGruntz is your go-to for flavor-rich relaxation and premium potency.'],
|
||||
['sku' => 'HE-HH-GSFV-AZ1.25G', 'desc' => 'Hash Holes: Greasy SFV\r\n\r\nIntroducing our signature Hash Hole, an artisanal marvel meticulously crafted for the connoisseur seeking the pinnacle of cannabis refinement! Encased in the finest Elements Rolling Paper, this masterpiece seamlessly marries craftsmanship with sophistication.\r\n\r\nWithin its embrace lies a symphony of premium-grade cannabis and live hash rosin, carefully selected to elevate your senses to new heights. But the luxury doesn\'t stop there <20> adorned with a sleek glass tip, every inhale promises a smooth, flavorful journey. Prepare to embark on a sensory adventure where indulgence meets elegance, only with our exquisite High Expectations Hash Hole.\r\n\r\n\r\nKey Features:\r\n\r\nHybrid Strain: This slick mix of San Fernando Valley (SFV) Flower and Headhunter Live Hash Rosin delivers a balanced blend of effects. Whether you\'re looking to unwind or get creative, it\'s the best of both worlds in one greasy package.\r\n\r\n1 Gram of SFV Flower + 0.25 Grams of Headhunter Live Hash Rosin: Delve into the epitome of cannabis refinement with our Greasy SFV Hash Hole, meticulously crafted from 1 gram of SFV flower and infused with 0.25 grams of our Headhunter Live Hash Rosin blend. This extraordinary blend combines the robust, piney aroma of SFV with the invigorating fusion of Headhunter, resulting in a symphony of flavors and effects that tantalize the senses.\r\n\r\n100% Solventless Hash Rosin: No slip-ups here<72>our Greasy SFV is crafted with pure, solventless hash rosin. It<49>s just the plant, pure and simple, ensuring a smooth and powerful ride.\r\n\r\nNothing but Plant: We keep it real with nothing but pure plant goodness. Greasy SFV has no synthetic additives, just natural, clean, and unadulterated excellence.\r\n\r\nSustainably Sourced: Our ingredients are sustainably sourced, so you can enjoy every puff with a green conscience. It<49>s an eco-friendly indulgence that respects Mother Earth.\r\n\r\nResponsibly Packaged: Hash Holes: Greasy SFV comes in eco-friendly packaging because we know it\'s what\'s on the inside (and the outside) that counts. It<49>s a package that\'s as slick as the product itself.\r\n\r\nLocally Manufactured by Arizonans: Proudly crafted in Arizona, our product supports local businesses and artisans. When you choose Hash Holes: Greasy SFV, you\'re backing the community and enjoying a product made with local love.\r\n\r\n\r\nSlick and Smooth Satisfaction\r\n\r\nReady to roll with the big boys? Greasy SFV is your ticket to a high-octane experience. This infused pre-roll offers a balanced blend of effects, giving you the best of both worlds<64>uplifting and relaxing, all rolled into one.\r\n\r\nWhy settle for a regular joint when you can have a Hash Hole? Greasy SFV delivers a smooth, flavorful vapor that\'s sure to make your taste buds tingle and your mind soar. It<49>s the perfect blend of naughty and nice, just the way you like it.\r\n\r\nSo, grab your Greasy SFV today and get ready to slip into a smooth, unforgettable ride. Cheers to a greasy good time, you cheeky vaper!'],
|
||||
['sku' => 'HE-HH-GSFV-AZ3G', 'desc' => 'Hash Holes: Greasy SFV\r\n\r\nIntroducing our signature Hash Hole, an artisanal marvel meticulously crafted for the connoisseur seeking the pinnacle of cannabis refinement! Encased in the finest Elements Rolling Paper, this masterpiece seamlessly marries craftsmanship with sophistication.\r\n\r\nWithin its embrace lies a symphony of premium-grade cannabis and live hash rosin, carefully selected to elevate your senses to new heights. But the luxury doesn\'t stop there <20> adorned with a sleek glass tip, every inhale promises a smooth, flavorful journey. Prepare to embark on a sensory adventure where indulgence meets elegance, only with our exquisite High Expectations Hash Hole.\r\n\r\n\r\nKey Features:\r\n\r\nHybrid Strain: This slick mix of San Fernando Valley (SFV) Flower and Headhunter Live Hash Rosin delivers a balanced blend of effects. Whether you\'re looking to unwind or get creative, it\'s the best of both worlds in one greasy package.\r\n\r\n2.5 Grams of SFV Flower + 0.5 Grams of Headhunter Live Hash Rosin: Delve into the epitome of cannabis refinement with our Greasy SFV Hash Hole, meticulously crafted from 2.5 grams of SFV flower and infused with 0.5 grams of our Headhunter Live Hash Rosin blend. This extraordinary blend combines the robust, piney aroma of SFV with the invigorating fusion of Headhunter, resulting in a symphony of flavors and effects that tantalize the senses.\r\n\r\n100% Solventless Hash Rosin: No slip-ups here<72>our Greasy SFV is crafted with pure, solventless hash rosin. It<49>s just the plant, pure and simple, ensuring a smooth and powerful ride.\r\n\r\nNothing but Plant: We keep it real with nothing but pure plant goodness. Greasy SFV has no synthetic additives, just natural, clean, and unadulterated excellence.\r\n\r\nSustainably Sourced: Our ingredients are sustainably sourced, so you can enjoy every puff with a green conscience. It<49>s an eco-friendly indulgence that respects Mother Earth.\r\n\r\nResponsibly Packaged: Hash Holes: Greasy SFV comes in eco-friendly packaging because we know it\'s what\'s on the inside (and the outside) that counts. It<49>s a package that\'s as slick as the product itself.\r\n\r\nLocally Manufactured by Arizonans: Proudly crafted in Arizona, our product supports local businesses and artisans. When you choose Hash Holes: Greasy SFV, you\'re backing the community and enjoying a product made with local love.\r\n\r\n\r\nSlick and Smooth Satisfaction\r\n\r\nReady to roll with the big boys? Greasy SFV is your ticket to a high-octane experience. This infused pre-roll offers a balanced blend of effects, giving you the best of both worlds<64>uplifting and relaxing, all rolled into one.\r\n\r\nWhy settle for a regular joint when you can have a Hash Hole? Greasy SFV delivers a smooth, flavorful vapor that\'s sure to make your taste buds tingle and your mind soar. It<49>s the perfect blend of naughty and nice, just the way you like it.\r\n\r\nSo, grab your Greasy SFV today and get ready to slip into a smooth, unforgettable ride. Cheers to a greasy good time, you cheeky vaper!'],
|
||||
['sku' => 'HE-HH-HS-AZ1.25G', 'desc' => 'Hash Holes: Holy Strawberry\r\n\r\nGet ready to experience a pre-roll like no other with Hash Holes: Holy Strawberry! This isn<73>t your average joint<6E>it\'s an infused pre-roll that combines 1 gram of Ghost Train Haze Flower with 0.25 grams of indulgent Headhunter Live Hash Rosin for a potent and flavorful adventure. Perfect for those who like their cannabis strong and their fun full of flavor.\r\n\r\nKey Features:\r\n\r\nHybrid Strain: This heavenly mix of Ghost Train Haze Flower and Headhunter Rosin offers a balanced blend of uplifting and relaxing effects. It<49>s the best of both worlds, rolled into one.\r\n\r\n100% Solventless Hash Rosin: No shortcuts here<72>our Holy Strawberry is crafted with pure, solventless hash rosin. It<49>s just the plant, no funny business, delivering a clean and powerful experience.\r\n\r\nNothing but Plant: We keep it real with nothing but pure plant power. Holy Strawberry has no synthetic additives, just natural, clean, and unadulterated goodness.\r\n\r\nSustainably Sourced: Our ingredients are sustainably sourced, so you can enjoy every puff with a clear conscience. It<49>s an eco-friendly indulgence that respects Mother Earth.\r\n\r\nResponsibly Packaged: Holy Strawberry comes in eco-friendly packaging because we know it\'s what\'s on the inside (and the outside) that counts. It<49>s a guilt-free package that<61>s easy on the eyes.\r\n\r\nLocally Manufactured by Arizonans: Proudly crafted in Arizona, our product supports local businesses and artisans. When you choose Hash Holes: Holy Strawberry, you\'re backing the community and enjoying a product made with local love.\r\n\r\nStrawberry Bliss Awaits\r\n\r\nReady to roll with the big boys? Holy Strawberry is your ticket to a heavenly high. This infused pre-roll offers a balanced blend of effects, giving you the best of both worlds<64>uplifting and relaxing, all wrapped in one.\r\n\r\nWhy settle for a regular joint when you can have a Hash Hole? Holy Strawberry delivers a smooth, flavorful vapor that\'s sure to make your taste buds tingle and your mind soar. It<49>s the perfect blend of naughty and nice, just the way you like it.\r\n\r\nSo, grab your Holy Strawberry Hash Hole today and buckle up for a ride you won<6F>t forget. Cheers to a berry divine experience!'],
|
||||
['sku' => 'HE-HH-HS-AZ3G', 'desc' => 'Hash Holes: Holy Strawberry\r\n\r\nGet ready to experience a pre-roll like no other with Hash Holes: Holy Strawberry! This isn<73>t your average joint<6E>it\'s an infused pre-roll that combines 2.5 grams of Ghost Train Haze Flower with 0.5 grams of indulgent Headhunter Live Hash Rosin for a potent and flavorful adventure. Perfect for those who like their cannabis strong and their fun full of flavor.\r\n\r\n\r\nKey Features:\r\n\r\nHybrid Strain: This heavenly mix of Ghost Train Haze Flower and Headhunter Rosin offers a balanced blend of uplifting and relaxing effects. It<49>s the best of both worlds, rolled into one.\r\n\r\n100% Solventless Hash Rosin: No shortcuts here<72>our Holy Strawberry is crafted with pure, solventless hash rosin. It<49>s just the plant, no funny business, delivering a clean and powerful experience.\r\n\r\nNothing but Plant: We keep it real with nothing but pure plant power. Holy Strawberry has no synthetic additives, just natural, clean, and unadulterated goodness.\r\n\r\nSustainably Sourced: Our ingredients are sustainably sourced, so you can enjoy every puff with a clear conscience. It<49>s an eco-friendly indulgence that respects Mother Earth.\r\n\r\nResponsibly Packaged: Holy Strawberry comes in eco-friendly packaging because we know it\'s what\'s on the inside (and the outside) that counts. It<49>s a guilt-free package that<61>s easy on the eyes.\r\n\r\nLocally Manufactured by Arizonans: Proudly crafted in Arizona, our product supports local businesses and artisans. When you choose Hash Holes: Holy Strawberry, you\'re backing the community and enjoying a product made with local love.\r\n\r\n\r\nStrawberry Bliss Awaits\r\n\r\nReady to roll with the big boys? Holy Strawberry is your ticket to a heavenly high. This infused pre-roll offers a balanced blend of effects, giving you the best of both worlds<64>uplifting and relaxing, all wrapped in one.\r\n\r\nWhy settle for a regular joint when you can have a Hash Hole? Holy Strawberry delivers a smooth, flavorful vapor that\'s sure to make your taste buds tingle and your mind soar. It<49>s the perfect blend of naughty and nice, just the way you like it.\r\n\r\nSo, grab your Holy Strawberry Hash Hole today and buckle up for a ride you won<6F>t forget. Cheers to a berry divine experience!'],
|
||||
['sku' => 'HE-HH-MB-AZ1.25G', 'desc' => 'Hash Holes: Moonbow\r\nPremium Infused Pre-Roll | 1.25g Total\r\n\r\nCosmic flavor. Balanced elevation.\r\nTake flight with Moonbow, a celestial Hash Hole handcrafted for those who crave flavor, potency, and perfect harmony. Expertly rolled in ultra-thin Elements paper and finished with a smooth glass tip, this premium pre-roll blends craft flower and solventless live hash rosin into a flawless smoking experience that<61>s out of this world.\r\n\r\n? The Blend\r\nStrain: Moonbow (Balanced Hybrid)\r\nInfusion: Live Hash Rosin\r\nContents: 1g Flower + 0.5g Rosin = 1.25g Total\r\n\r\nMoonbow is a rare, terp-heavy cross of Zkittlez and Do-Si-Dos, offering an ideal balance between cerebral energy and full-body calm. With a candy-sweet nose, hints of tropical fruit, and underlying gas, it<69>s as delicious as it is effective. Paired with live hash rosin, this blend delivers a smooth, flavorful burn and a long-lasting high that hits every note mentally and physically.\r\n\r\n? Why You<6F>ll Love It\r\n? Flavor-Rich Terpenes: Think tropical Skittles, gassy funk, and floral depth in every hit.\r\n\r\n? Glass Tip Finish: Enhanced airflow and silky draws for a cleaner, cooler smoking experience.\r\n\r\n? 100% Solventless Rosin: Just heat and pressure no chemicals, ever. Full spectrum, full flavor.\r\n\r\n? Pure & Simple: Only premium cannabis and hash rosin. No additives. No shortcuts.\r\n\r\n?? Eco-Minded Design: Sustainably sourced materials and earth-conscious packaging.\r\n\r\n? Arizona-Built: Grown, extracted, and rolled locally. You<6F>re supporting Arizona<6E>s finest.\r\n\r\n? + ? The Experience\r\nMoonbow strikes the perfect balance uplifting the mind while relaxing the body. Whether you<6F>re getting social, creative, or just floating through your own orbit, this hybrid gives you clarity without couchlock and calm without fog. Smooth, centered, and full of flavor.\r\n\r\n? Your High, Aligned\r\nDon<6F>t choose between mellow and motivated, get both.\r\nMoonbow delivers a perfectly balanced hybrid high with bold flavor and luxe finish.'],
|
||||
['sku' => 'HE-PF-AOG-AZ3.5G', 'desc' => 'High Expectations - Alien OG Flower (3.5g)\r\n\r\nBlast Off with High Expectations - Alien OG ?\r\n\r\nIntroducing High Expectations 3.5g Flower of Alien OG, a premium cannabis strain that epitomizes the pinnacle of cultivation expertise and genetic perfection. Crafted with precision and care, this strain seamlessly blends potency with flavor, offering a sensory journey that\'s out of this world.\r\n\r\nNature\'s Masterpiece\r\n\r\nEach bud of Alien OG is a masterpiece of nature\'s artistry, boasting dense, olive-green nuggets coated in a blanket of shimmering trichomes. Its structure is robust yet delicate, with fiery orange pistils weaving through the greenery, hinting at the intensity within.\r\n\r\nAroma and Flavor\r\n\r\nUpon opening the jar, the room is instantly filled with a tantalizing aroma that captivates the senses. Notes of fresh pine and earthiness mingle with hints of lemon and spice, creating a bouquet that\'s both invigorating and soothing. It\'s a symphony of scents that promises a deeply satisfying experience.\r\n\r\nPotent and Flavorful\r\n\r\nCrafted to perfection, Alien OG delivers a smooth, powerful smoke that is both potent and flavorful. Each hit provides a balanced high, combining the best of both worlds for a truly cosmic experience. Whether you<6F>re looking to relax or elevate your senses, Alien OG is the perfect choice.\r\n\r\nIndulge in the Experience\r\n\r\nIndulge in the extraordinary experience of High Expectations Flower, meticulously grown to encapsulate the essence of top-shelf cannabis. Each nug is a testament to precision and excellence, delivering a sensory journey that ignites the senses with every inhale. The rich hues and potent effects promise a powerful encounter with each use.\r\n\r\nEco-Friendly Packaging\r\n\r\nHigh Expectations<6E> responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the out-of-this-world sensation of Alien OG <20> setting the standard for excellence.\r\n\r\nCheers to cosmic highs! ?'],
|
||||
['sku' => 'HE-PF-HG-AZ3.5G', 'desc' => 'High Expectations - Holy Gelato (Gelato x Holy Grail OG) 3.5g\r\n\r\nFlower Indulge in Divine Delights with High Expectations - Holy Gelato ?\r\n\r\nPrepare for a heavenly experience with High Expectations - Holy Gelato, the celestial blend of Gelato and Holy Grail OG. This top-shelf indica-dominant hybrid offers a divine combination of sweetness and earthiness, promising a journey that\'s simply out of this world.\r\n\r\nNature\'s Artistry\r\n\r\nEach bud of Holy Gelato is a visual treat, boasting dense, olive-green nuggets adorned with shimmering trichomes and fiery orange pistils. It\'s nature\'s way of showing off!\r\n\r\nAroma and Flavor\r\n\r\nPop open the jar and let the aroma transport you: fresh pine and earthy tones mingle with zesty lemon and spicy hints. It\'s a scent symphony that<61>s both invigorating and soothing, promising a sensory experience that<61>s out of this galaxy.\r\n\r\nPotent and Flavorful\r\n\r\nCrafted for dabbing, Holy Gelato is as potent as it is flavorful. Each hit delivers a smooth, powerful smoke that perfectly marries the best traits of Gelato and Holy Grail OG. Expect a balanced high that relaxes your body while uplifting your mind, making it perfect for chilling or getting creative.\r\n\r\nIndulge in the Experience\r\n\r\nIndulge in the extraordinary experience of High Expectations Flower, meticulously cultivated to showcase top-shelf cannabis at its finest. Each nug is a testament to excellence, offering a sensory journey that ignites the senses with every inhale. The rich hues and potent effects promise a powerful encounter with each use.\r\n\r\nEco-Friendly Packaging\r\n\r\nHigh Expectations<6E> responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the divine indulgence of Holy Gelato, a heavenly blend of Gelato and Holy Grail OG <20> setting the standard for excellence.\r\n\r\nCheers to heavenly highs! ?'],
|
||||
['sku' => 'HE-PF-SFV-AZ3.5G', 'desc' => 'High Expectations - SFV OG 3.5g\r\n\r\nFlower Experience the SoCal Vibes with High Expectations - SFV OG ?\r\n\r\nGet ready to bask in the Southern California sunshine with High Expectations - SFV OG, a top-shelf indica-dominant hybrid. This premium strain blends potency with flavor, delivering a laid-back, relaxing experience that\'s perfect for unwinding.\r\n\r\nNature\'s Artistry\r\n\r\nEach bud of SFV OG is a visual delight, featuring dense, forest-green nuggets dusted with shimmering trichomes and vibrant orange pistils. It\'s a true testament to nature\'s craftsmanship.\r\n\r\nAroma and Flavor\r\n\r\nCrack open the jar and let the scent of SFV OG envelop you: earthy pine and lemon zest with hints of diesel fuel. This aromatic bouquet promises a deeply satisfying and invigorating experience that transports you to the heart of SoCal.\r\n\r\nPotent and Flavorful\r\n\r\nCrafted for dabbing, SFV OG delivers a smooth, powerful smoke that marries the best qualities of its parent strains. Expect a balanced high that soothes the body and mind, making it perfect for relaxation and stress relief.\r\n\r\nIndulge in the Experience\r\n\r\nIndulge in the exceptional experience of High Expectations Flower, meticulously grown to showcase the finest cannabis. Each nug is a testament to precision and excellence, offering a sensory journey that ignites the senses with every inhale. The rich hues and potent effects promise a powerful encounter with each use.\r\n\r\nEco-Friendly Packaging\r\n\r\nHigh Expectations<6E> responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the laid-back luxury of SFV OG <20> setting the standard for excellence.\r\n\r\nCheers to SoCal highs! ?'],
|
||||
['sku' => 'HE-R-GD-AZ1G', 'desc' => 'High Expectations - Greasy D (Grease Monkey x Diesel)\r\n\r\n Get Ready for a Slick Experience with High Expectations - Greasy D ??\r\n\r\nDive into the luxurious blend of Grease Monkey and Diesel with High Expectations - Greasy D. This potent mix brings together the best of both worlds, offering a robust aroma that<61>s both earthy and pungent, with a hint of diesel fuel to keep things interesting.\r\n\r\n\r\nSmooth and Powerful\r\n\r\nCrafted from the finest rosin, Greasy D delivers a smooth, powerful smoke that<61>s as intense as it is enjoyable. Perfect for dabbing, our meticulous extraction process ensures every hit is packed with rich flavors and potent effects, making this blend a top choice for connoisseurs.\r\n\r\nEnergize and Elevate\r\n\r\nIdeal for any time of day, Greasy D provides a balanced high that boosts creativity and focus while relaxing the body. Whether you\'re tackling a project or winding down after a long day, this blend keeps you in high spirits.\r\n\r\nIndulge in the Experience\r\n\r\nIndulge in the luxurious experience of High Expectations Rosin Blends, meticulously crafted to encapsulate the essence of every strain. Each blend is a testament to precision and finesse, delivering a sensory journey that ignites the senses with every inhale. The rich hues and potent effects promise a powerful encounter with each dab.\r\n\r\nEco-Friendly Packaging\r\n\r\nHigh Expectations<6E> responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the slick, powerful high of Greasy D <20> setting the standard for excellence.\r\n\r\nCheers to slick highs! ??'],
|
||||
['sku' => 'HE-R-MB-AZ1G', 'desc' => 'High Expectations - Monkey Balls (Grease Monkey x Blueberry)\r\n\r\nGet Wild with High Expectations - Monkey Balls ??\r\n\r\nEmbark on a wild adventure with High Expectations - Monkey Balls, a playful blend of Grease Monkey and Blueberry. This potent mix offers a sweet and earthy aroma, with hints of blueberry and a smooth, creamy finish.\r\n\r\nSweet and Earthy\r\n\r\nCrafted from the finest rosin, Monkey Balls delivers a smooth, flavorful smoke that<61>s as delightful as it is potent. Perfect for dabbing, our meticulous extraction process ensures each hit is packed with rich, sweet flavors and a powerful high.\r\n\r\nRelax and Unwind\r\n\r\nPerfect for evening use, Monkey Balls provides a deeply relaxing high that soothes the body and mind. It<49>s ideal for melting away stress and promoting restful sleep, leaving you feeling blissfully relaxed.\r\n\r\nIndulge in the Experience\r\n\r\nIndulge in the playful experience of High Expectations Rosin Blends, meticulously crafted to encapsulate the essence of every strain. Each blend is a testament to precision and finesse, delivering a sensory journey that ignites the senses with every inhale. The rich hues and potent effects promise a powerful encounter with each dab.\r\n\r\nEco-Friendly Packaging\r\n\r\nHigh Expectations<6E> responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nGet wild with the sweet and earthy delight of Monkey Balls <20> setting the standard for excellence.\r\n\r\nCheers to wild highs! ??'],
|
||||
['sku' => 'HE-R-RT-AZ1G', 'desc' => 'High Expectations - Red Tart (Strawberries N Cream x Grape Dosi x Lemon Meringue)\r\n\r\nSavor the Sweet and Sour Symphony with High Expectations - Red Tart ??\r\n\r\nStep into a world of tantalizing flavors with High Expectations - Red Tart, a delectable blend of Strawberries N Cream, Grape Dosi, and Lemon Meringue. This unique mix offers a sweet and sour symphony that dances on your taste buds with every puff.\r\n\r\n\r\n\r\nSweet and Tangy: Crafted from the finest rosin, Red Tart delivers a smooth, flavorful smoke that<61>s as refreshing as it is potent. Perfect for dabbing, our meticulous extraction process ensures each hit is packed with rich, fruity flavors and a robust high.\r\n\r\n\r\nEuphoric and Uplifting: Ideal for any time of day, Red Tart provides an uplifting high that boosts mood and creativity. Whether you\'re socializing or enjoying some me-time, this blend brings a burst of euphoria to your day.\r\n\r\nIndulge in the Experience: Indulge in the exquisite experience of High Expectations Rosin Blends, meticulously crafted to encapsulate the essence of every strain. Each blend is a testament to precision and finesse, delivering a sensory journey that ignites the senses with every inhale. The rich hues and potent effects promise a powerful encounter with each dab.\r\n\r\nEco-Friendly Packaging: High Expectations<6E> responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nSavor the sweet and sour delight of Red Tart <20> setting the standard for excellence.\r\n\r\nCheers to sweet and tangy highs! ??'],
|
||||
['sku' => 'JV-BS-AZ05G', 'desc' => 'Just Vape: Banana Shack\r\n\r\nGet Ready to Elevate Your Vibe with Just Vape: Banana Shack! ??\r\n\r\nEnergize your senses with Just Vape Banana Shack, a premium sativa-leaning hybrid designed to uplift your mood and spark creativity while keeping things chill. Bursting with tropical flavor and euphoric vibes, this top-shelf, all-flower vape delivers smooth, potent hits every time. Sustainably grown and expertly crafted in Arizona, it<69>s cannabis done right pure, flavorful, and unforgettable.\r\n\r\nKey Features:\r\n\r\nHybrid: Banana Shack brings balanced effects that uplift your mood while relaxing the body. Perfect for chilled-out afternoons, creative sessions, or laid-back social moments. ?\r\n\r\nAll Flower Only: No extras, no additives<65>just pure, high-end cannabis flower. ?\r\n\r\nNothing but Plant: Made with nothing but premium flower for a clean, natural experience. ?\r\n\r\nSustainably Sourced: Eco-friendly choice that respects our planet. ?\r\n\r\nResponsibly Packaged: Eco-friendly packaging that<61>s stylish and kind to the environment. ??\r\n\r\nBanana Shack delivers a smooth, calming high that eases you into a feel-good vibe with a touch of tropical sweetness. It is your perfect go-to for relaxing after a long day, kicking back with friends, or simply enjoying the moment. ??\r\n\r\nWhy wait? Snag your Just Vape: Banana Shack today and experience the bright, uplifting buzz this tropical hybrid brings. With every flavorful puff, find your sweet spot between energized bliss and smooth relaxation. Kick back, vibe up, and let the good times roll. ??'],
|
||||
['sku' => 'JV-DAE-AZ05G', 'desc' => 'Just Vape: Drippin\' Aint Easy\r\n\r\nGet Ready to Experience the Good Life with Just Vape: Drippin\' Ain\'t Easy! ?\r\n\r\nPrepare to indulge in a delightful journey with Just Vape Drippin\' Ain\'t Easy, a premium hybrid strain designed to deliver the perfect blend of relaxation and euphoria. Our top-shelf, all-flower strain offers nothing but pure, potent cannabis magic, sustainably sourced and expertly cultivated in Arizona.\r\n\r\n\r\nKey Features:\r\n\r\nHybrid Strain: Drippin\' Ain\'t Easy strikes a harmonious balance between uplifting energy and soothing relaxation, making it perfect for any occasion<6F>whether you<6F>re chilling at home or out with friends. ?\r\n\r\nAll Flower Only: No extras, no additives<65>just pure, high-end cannabis flower. ?\r\n\r\nNothing but Plant: Made with nothing but premium flower for a clean, natural experience. ?\r\n\r\nSustainably Sourced: Eco-friendly choice that respects our planet. ?\r\n\r\nResponsibly Packaged: Eco-friendly packaging that<61>s stylish and kind to the environment. ??\r\n\r\nDrippin\' Ain\'t Easy delivers a captivating high right from the first puff. You<6F>ll feel an uplifting wave of happiness that gently transitions into a calming body relaxation, ideal for easing stress and enhancing your mood. This strain is your perfect companion for social gatherings, creative projects, or simply enjoying a peaceful evening at home. ??\r\n\r\nWhether you<6F>re seeking relief from anxiety, looking to boost your creativity, or just wanting to elevate your vibe, Drippin\' Ain\'t Easy has you covered. Its aroma features sweet, fruity notes combined with hints of citrus and spice, while the flavor profile delights with smooth, creamy undertones and a touch of earthiness. ??\r\n\r\nDon<6F>t wait<69>grab your Just Vape: Drippin\' Ain\'t Easy today and immerse yourself in the blissful experience this strain has to offer. Elevate your downtime and enjoy a vibrant journey with every puff! ?'],
|
||||
['sku' => 'JV-DI-AZ05G', 'desc' => 'Ignite Your Senses with Just Vape: Dante\'s Inferno! ??\r\n\r\nPrepare for an unforgettable experience with Just Vape Dante\'s Inferno, a fiery strain designed to deliver a scorching mix of euphoria and deep relaxation. Our premium, all-flower strain offers pure, potent cannabis goodness, sustainably sourced and expertly crafted in Arizona.\r\n\r\nKey Features:\r\n\r\nIndica-Dominant Hybrid: Dante\'s Inferno is perfect for those seeking a powerful, relaxing high that melts away stress and tension. ?\r\n\r\nAll Flower Only: No extras, no additives<65>just pure, high-end cannabis flower. ?\r\n\r\nNothing but Plant: Made with nothing but premium flower for a clean, natural experience. ?\r\n\r\nSustainably Sourced: Eco-friendly choice that respects our planet. ?\r\n\r\nResponsibly Packaged: Eco-friendly packaging that<61>s stylish and kind to the environment. ??\r\n\r\nDante\'s Inferno lives up to its name with a potent high that ignites your senses almost immediately. You<6F>ll start with a euphoric rush that sets your mind ablaze, followed by a soothing, body-numbing relaxation. Perfect for unwinding after a long day or settling into a deep, restorative sleep. ??\r\n\r\nIdeal for managing chronic pain, stress, insomnia, or simply enhancing your mood, Dante\'s Inferno offers a versatile experience. Its aroma is a blend of earthy spices and a hint of smoky sweetness, while the flavor profile features rich, peppery notes with a touch of dark chocolate and coffee. ????\r\n\r\nSo, grab your Just Vape: Dante\'s Inferno today and prepare to dive into a blaze of relaxation and euphoria. This intense strain is your gateway to a fiery, blissful escape. Elevate your experience and embrace the heat! ?'],
|
||||
['sku' => 'JV-FB-AZ05G', 'desc' => 'Just Vape: Frankenberry\r\n\r\nGet Ready to Indulge in Sweet Bliss with Just Vape: Frankenberry! ?\r\n\r\nPrepare for a deliciously euphoric experience with Just Vape Frankenberry, a premium strain crafted to elevate your senses and relax your mind. Sourced sustainably and expertly cultivated in Arizona, this all-flower strain is designed for those who seek a unique twist on their cannabis journey.\r\n\r\n\r\nKey Features:\r\n\r\nIndica-Dominant Hybrid: Frankenberry offers a delightful balance of relaxation and happiness, making it the perfect choice for winding down after a busy day. ??\r\n\r\nAll Flower Only: No extras, no additives<65>just pure, high-end cannabis flower. ?\r\n\r\nNothing but Plant: Made with nothing but premium flower for a clean, natural experience. ?\r\n\r\nSustainably Sourced: Eco-friendly choice that respects our planet. ?\r\n\r\nResponsibly Packaged: Eco-friendly packaging that<61>s stylish and kind to the environment. ??\r\n\r\nFrankenberry provides an instant wave of uplifting euphoria that transitions into a soothing body high, perfect for relieving stress and promoting restful relaxation. Whether you<6F>re facing insomnia, chronic pain, or simply need a mood boost, Frankenberry is your ideal companion for cozy evenings or peaceful nights. ??\r\n\r\nThe strain boasts a mouthwatering aroma of sweet berries with hints of earthiness and a touch of spice, while its flavor profile surprises with creamy berry notes and a delightful undertone of gas. ??\r\n\r\nDon<6F>t miss out<75>grab your Just Vape: Frankenberry today and dive into a sweet, relaxing adventure with every puff! Elevate your downtime and savor the blissful experience this strain has to offer. ?'],
|
||||
['sku' => 'JV-GB-AZ05G', 'desc' => 'Just Vape: Garlic Breath\r\n\r\nGet Ready to Experience a Savory Delight with Just Vape: Garlic Breath! ?\r\n\r\nPrepare for a uniquely flavorful journey with Just Vape Garlic Breath, a premium strain crafted to tantalize your senses and bring you to a state of blissful relaxation. Expertly cultivated in Arizona, this all-flower strain is designed for those who crave a distinctive twist on their cannabis experience.\r\n\r\n\r\nKey Features:\r\n\r\nIndica-Dominant Hybrid: Garlic Breath strikes the perfect balance between calming tranquility and uplifting euphoria, making it an excellent choice for unwinding after a long day. ??\r\n\r\nAll Flower Only: No extras, no additives<65>just pure, high-end cannabis flower. ?\r\n\r\nNothing but Plant: Made with nothing but premium flower for a clean, natural experience. ?\r\n\r\nSustainably Sourced: Eco-friendly choice that respects our planet. ?\r\n\r\nResponsibly Packaged: Eco-friendly packaging that<61>s stylish and kind to the environment. ??\r\n\r\nGarlic Breath delivers an instant wave of relaxation, melting away stress and tension, making it perfect for cozy evenings or quiet nights in. Whether you<6F>re dealing with insomnia, chronic pain, or just need a moment to unwind, Garlic Breath is your go-to strain for peaceful moments. ??\r\n\r\nThis strain boasts a pungent aroma of savory garlic intertwined with earthy undertones, and its flavor profile surprises with rich, spicy notes and a hint of sweet herbal richness. ??\r\n\r\nDon<6F>t miss out<75>grab your Just Vape: Garlic Breath today and immerse yourself in a savory, relaxing adventure with every puff! Elevate your downtime and savor the unique experience this strain has to offer. ?'],
|
||||
['sku' => 'JV-HH-AZ05G', 'desc' => 'Just Vape: Headhunter\r\n\r\nGet Ready to Strike Gold with Just Vape: Headhunter! ?\r\n\r\nPrepare to experience the ultimate high with Just Vape Headhunter, a premium strain designed to hit all the right notes of bliss and relaxation. Our top-shelf, all-flower strain offers nothing but pure, potent cannabis magic, sustainably sourced and meticulously crafted in Arizona.\r\n\r\n\r\nKey Features:\r\n\r\nIndica-Dominant Hybrid: Headhunter is your go-to for a potent, relaxing experience. Its balanced profile is perfect for unwinding after a long day. ?\r\n\r\nAll Flower Only: No extras, no additives<65>just pure, high-end cannabis flower. ?\r\n\r\nNothing but Plant: Made with nothing but premium flower for a clean, natural experience. ?\r\n\r\nSustainably Sourced: Eco-friendly choice that respects our planet. ?\r\n\r\nResponsibly Packaged: Eco-friendly packaging that<61>s stylish and kind to the environment. ??\r\n\r\n\r\nHeadhunter delivers an impactful high right from the start. You<6F>ll be hit with an uplifting wave of euphoria that transitions smoothly into a deeply relaxing body high. Ideal for melting away stress and inducing a tranquil state, Headhunter is your perfect companion for a peaceful evening or restful sleep. ??\r\n\r\nWhether you\'re dealing with insomnia, chronic stress, pain, or just need a mood boost, Headhunter has you covered. Its aroma features rich, earthy undertones with hints of pine and spice, while the flavor profile delights with sweet and creamy notes and a touch of gas. ??\r\n\r\nDon<6F>t wait<69>grab your Just Vape: Headhunter today and experience the powerful relaxation and euphoria this strain has to offer. Elevate your downtime and enjoy a golden, blissful journey with every puff! ?'],
|
||||
['sku' => 'JV-SB-AZ05G', 'desc' => 'Just Vape: Super Boof\r\n\r\nGet Ready to Elevate Your Vibe with Just Vape: Super Boof! ?\r\n\r\nPrepare for an unforgettable experience with Just Vape Super Boof, a premium hybrid strain crafted to deliver a perfect balance of relaxation and euphoria. Our top-shelf, all-flower strain offers nothing but pure, potent cannabis magic, sustainably sourced and meticulously cultivated in Arizona.\r\n\r\n\r\nKey Features:\r\n\r\nHybrid: Super Boof is your ultimate choice for a balanced experience, combining uplifting energy with soothing relaxation. It<49>s perfect for enhancing your chill time or social gatherings. ?\r\n\r\nAll Flower Only: No extras, no additives<65>just pure, high-end cannabis flower. ?\r\n\r\nNothing but Plant: Made with nothing but premium flower for a clean, natural experience. ?\r\n\r\nSustainably Sourced: Eco-friendly choice that respects our planet. ?\r\n\r\nResponsibly Packaged: Eco-friendly packaging that<61>s stylish and kind to the environment. ??\r\n\r\nSuper Boof delivers a powerful high that hits right away, wrapping you in a wave of blissful energy that gently transitions into relaxation. Ideal for cozy evenings or social vibes, Super Boof is your perfect companion for a fun night in or unwinding after a busy day. ??\r\n\r\nWhether you<6F>re looking to boost your creativity, relieve stress, or simply enjoy a mood lift, Super Boof has you covered. Its aroma features earthy, pungent notes with hints of sweetness and spice, while the flavor profile delights with rich, creamy undertones and a touch of herbal freshness. ??\r\n\r\nDon<6F>t wait<69>grab your Just Vape: Super Boof today and experience the powerful balance of relaxation and joy this strain has to offer. Elevate your downtime and enjoy a blissful journey with every puff! ?'],
|
||||
['sku' => 'JV-SS-AZ05G', 'desc' => 'Just Vape: Singapore Sling\r\n\r\nGet Ready to Elevate Your Vibe with Just Vape: Singapore Sling! ??\r\n\r\nStep into a tropical escape with Just Vape Singapore Sling, a premium sativa-dominant hybrid crafted to boost your mood and spark your energy. Our top-shelf, all-flower product delivers vibrant, flavorful cannabis magic, sustainably sourced and expertly cultivated in Arizona.\r\n\r\nKey Features:\r\n\r\nSativa-Dominant Hybrid: Singapore Sling offers a bright, uplifting experience with a touch of body relaxation. It is perfect for creative projects, daytime adventures, or social settings where you want to stay sharp and positive. ??\r\n\r\nAll Flower Only: No extras, no additives, just pure, high-end cannabis flower. ?\r\n\r\nNothing but Plant: Made with nothing but premium flower for a clean, natural experience. ?\r\n\r\nSustainably Sourced: Grown using eco-friendly methods that respect the Earth. ?\r\n\r\nResponsibly Packaged: Packaging that is sleek, sustainable, and planet-conscious. ??\r\n\r\nSingapore Sling hits quickly with a wave of euphoria and mental clarity, setting the tone for an energetic and joyful experience. Whether you\'re heading out, getting creative, or simply elevating your mood, it\'s the perfect partner for the ride. ??\r\n\r\nDon<6F>t wait. Grab your Just Vape: Singapore Sling today and experience the refreshing spark of this flavorful hybrid. Make every moment feel like a getaway. ??'],
|
||||
['sku' => 'JV-TF-AZ05G', 'desc' => 'Just Vape: Truffaloha\r\n\r\nGet Ready to Elevate Your Vibe with Just Vape: Truffaloha! ??\r\n\r\nEscape to a lush island of calm and clarity with Just Vape Truffaloha, a premium hybrid strain crafted to deliver the perfect balance of uplifting energy and full-body relaxation. Our top-shelf, all-flower product offers pure, flavorful cannabis magic, sustainably grown and carefully cultivated in Arizona.\r\n\r\nKey Features:\r\n\r\nHybrid: Truffaloha is your go-to for a balanced experience that lifts your mood while soothing your body. It is ideal for daytime creativity or unwinding in the evening. ?\r\n\r\nAll Flower Only: No extras, no additives, just pure, high-end cannabis flower. ?\r\n\r\nNothing but Plant: Made with nothing but premium flower for a clean, natural experience. ?\r\n\r\nSustainably Sourced: An eco-friendly option that supports the planet. ?\r\n\r\nResponsibly Packaged: Smart, stylish packaging that is kind to the environment. ??\r\n\r\nTruffaloha offers a smooth, steady high that begins with a happy, clear-headed buzz and eases into a relaxed, grounded finish. Whether you\'re chilling with friends or taking time for yourself, this strain brings harmony to any moment. ??\r\n\r\nDon<6F>t wait. Grab your Just Vape: Truffaloha today and enjoy the perfect balance of calm and clarity this hybrid has to offer. Let every puff transport you to paradise. ??'],
|
||||
['sku' => 'JV-VC-AZ05G', 'desc' => 'Just Vape: Vice City\r\n\r\nGet Ready to Immerse Yourself in an Urban Escape with Just Vape: Vice City! ?\r\n\r\nPrepare for an exhilarating journey with Just Vape Vice City, a premium strain crafted to ignite your senses and elevate your spirit. Expertly cultivated in Arizona, this all-flower strain is perfect for those looking to embrace a vibrant twist on their cannabis experience.\r\n\r\n\r\nKey Features:\r\n\r\nHybrid Strain: Prepare for an exhilarating journey with Just Vape Vice City, a premium strain crafted to ignite your senses and elevate your spirit. Expertly cultivated in Arizona, this all-flower strain is perfect for those looking to embrace a vibrant twist on their cannabis experience.\r\n\r\nAll Flower Only: No extras, no additives<65>just pure, high-end cannabis flower. ?\r\n\r\nNothing but Plant: Made with nothing but premium flower for a clean, natural experience. ?\r\n\r\nSustainably Sourced: Eco-friendly choice that respects our planet. ?\r\n\r\nResponsibly Packaged: Eco-friendly packaging that<61>s stylish and kind to the environment. ??\r\n\r\nVice City delivers an instant surge of creativity and joy, washing away stress and tension, making it perfect for lively gatherings or chill nights at home. Whether you<6F>re looking to spark inspiration, manage anxiety, or simply enjoy a flavorful experience, Vice City is your go-to strain for exciting, uplifting moments. ??\r\n\r\nThis strain features a captivating aroma with notes of sweet citrus and earthy pine, while its flavor profile delights with hints of zesty fruit and a smooth, herbal finish. ??\r\n\r\nDon<6F>t miss out<75>grab your Just Vape: Vice City today and dive into an exhilarating adventure with every puff! Elevate your downtime and savor the unique experience this strain has to offer. ?'],
|
||||
['sku' => 'NU-BB-LM', 'desc' => 'Body Balance - Lime Flavor - Engage Your Body \r\n\r\nEnergetic and lively individuals will enjoy this hybrid<69>s ability to lift the spirit and engage the body while soothing the mind. It delivers sharp focus housed within a tranquil state of being, and its lime flavor offers a citrus burst of cool refreshment.\r\n \r\nThe terpene caryophyllene sets this blend<6E>s uplifting tone, bolstered by humulene and limonene, which keep you feeling active and creatively stimulated. Linalool and myrcene introduce a relaxed feeling of calm to complete this blend<6E>s balanced feel.\r\n \r\nPotency Results: THC: 70.58%, CBD: 8.32%\r\nProminent Terpenes: Caryophyllene, humulene, limonene, linalool, myrcene\r\n*Individual batch testing on products may vary.'],
|
||||
['sku' => 'NU-BD-BB', 'desc' => 'Body Dominant - Blueberry Flavor - Restore Your Form \r\n \r\nThose seeking peace for the mind and relaxation for the body will find this alleviating oil soothing and uplifting. It evokes a settled air of contentment and is ideal for feeling comfortable and at ease. A refreshing blueberry flavor floods the senses with a cool, calming aroma.\r\n \r\nThe terpene limonene sets a meditative tone by inspiring a sense of creativity, while myrcene provides a strong, calming effect. Caryophyllene and linalool keep the spirit uplifted and relaxed, and humulene injects a subtle hint of kinetic energy to keep you feeling engaged with your tranquility.\r\n \r\nPotency Results: THC: 71.82%, CBD: 8.53%\r\nProminent Terpenes: Limonene, myrcene, caryophyllene, linalool, humulene\r\n*Individual batch testing on products may vary.'],
|
||||
['sku' => 'NU-FB-WG', 'desc' => 'Those in search of full-bodied tranquility will enjoy the alleviating sensations this blend inspires. You will feel physical contentment wash through you, top to bottom, inside and out. The unique, wild grape flavoring creates an intriguing taste and full aroma without being overwhelming.\r\n \r\nThe terpene composition of this blend begins with myrcene, creating the dominant calming sensation. Caryophyllene contributes a warm feeling of uplift along with pinene, which enhances a sense of focus. Humulene and linalool work to provide an active sense of relaxation that inspires a uniquely present feeling of serenity.\r\n \r\nPotency Results: THC: 70.88%, CBD: 8.55%\r\nProminent Terpenes: Myrcene, caryophyllene, pinene, humulene, linalool\r\n*Individual batch testing on products may vary.'],
|
||||
['sku' => 'NU-FL-AP', 'desc' => 'Flow 1:1 CBD:THC - Apricot Flavor - Find Your Flow\r\n\r\nEase into your inner peace with the harmonious blend of CBD and THC in our new Flow 1:1 CBD:THC - Apricot Flavor. This delicate balance of cannabinoids is designed to elevate your senses and calm your mind, while providing a feeling of physical comfort. The apricot flavor is a sweet and a juicy burst of refreshment that will captivate your taste buds and awaken your senses.\r\n\r\nAt the core of this blend lies the terpene myrcene, providing a foundation of deep relaxation and serenity. Terpinolene adds a meditative and introspective touch, while pinene brings a clear focus and heightened perception. Caryophyllene and linalool work together to lift your spirits and provide a warm, comforting sensation.\r\n\r\nCompact and portable, the Nuvata Flow Vape is perfect for those on-the-go, whether commuting, hiking, or relaxing at home. Find your flow and experience a sense of balance, peace, and clarity with every inhale.\r\n\r\nPotency Results: THC: 43.18%, CBD: 41.31%\r\nProminent Terpenes: Myrcene, Terpinolene, Pinene, Caryophyllene, and Linalool\r\n*Individual batch testing on products may vary.'],
|
||||
['sku' => 'NU-FM-ST', 'desc' => 'Full Mind - Strawberry Flavor - Fuel Your Creativity \r\nCreative minds will find that this blend widens the lens through which inspiration passes while providing an active boost to motivation. The refreshing strawberry taste will leave you feeling clear and rejuvenated.\r\n \r\nYou will experience an uplifted sensation, due to the strong presence of the terpene caryophyllene. At the same time, limonene will engage your creative instincts, while myrcene and linalool introduce calming and relaxing effects. Humulene will also be present, reinforcing an active, doer<65>s mindset.\r\n \r\nPotency Results: THC: 70.66%, CBD: 8.53%\r\nProminent Terpenes: Caryophyllene, limonene, myrcene, humulene, linalool\r\n*Individual batch testing on products may vary.'],
|
||||
['sku' => 'NU-MB-TR', 'desc' => 'Mind Balance - Tropical Flavor - Balance Your Energy \r\nAttentive minds will enjoy this hybrid<69>s ability to deliver sharp, cognitive focus while calming the body and lifting the spirit. It<49>s designed to make you feel present and at ease. With a bursting, tropical flavor profile, every inhale will bring to mind relaxing, exotic getaways.\r\n \r\nThe terpene myrcene lays a calming sensational foundation upon which pinene and caryophyllene then build perceptual focus and spiritual uplift. Limonene inspires creative introspection while humulene keeps the body feeling active, rounding out this blend<6E>s balanced feel.\r\n \r\nPotency Results: THC: 70.85%, CBD: 8.40%\r\nProminent Terpenes: Myrcene, pinene, caryophyllene, limonene, humulene\r\n*Individual batch testing on products may vary.'],
|
||||
['sku' => 'NU-MD-TA', 'desc' => 'Mind Dominant - Tangerine Flavor - Energize Your Being \r\nActive minds will find motivation and focus in this stimulating oil. It offers a boost to willpower and energizes the mind while also providing a sense of controlled calm. The tangerine citrus flavor is a pleasant jolt to the taste buds, enlivening the senses with its bright profile.\r\n \r\nThe terpene terpinolene sets a meditative tone and combines with caryophyllene for a sensation of uplifted reflection. Myrcene provides a calming sensation, while humulene and pinene keep your mind alert and focused, primed to experience your world in high definition.\r\n \r\nPotency Results: THC: 71.64%, CBD: 10.34%\r\nProminent Terpenes: Terpinolene, caryophyllene, myrcene, humulene, pinene\r\n*Individual batch testing on products may vary.'],
|
||||
['sku' => 'OC-DR-AZ1G', 'desc' => 'Dark Rainbow is a standout preroll designed to make your dispensary a destination for serious smokers. Packed with 29.77% THC and 35.46% total cannabinoids, this 1g roll delivers a euphoric, luxurious high that satisfies even the most demanding customers. Its 2.99% terpene profile bursts with layered notes of fruit, earth, and spice, creating a complex and unforgettable flavor experience. Limited-run batches make each preroll rare, and once it sells out, it could be months before it returns. Stocking Dark Rainbow prerolls puts your store among the few offering true connoisseur-level products, with scarcity driving urgency and premium appeal. Add Dark Rainbow to your menu and elevate your shelves and your sales.'],
|
||||
['sku' => 'OC-FOF-AZ1G', 'desc' => 'Face on Fire is a standout preroll designed to get customers talking and keep them coming back. Packed with 20.65% THC and 24.34% total cannabinoids, this 1g roll delivers an electrifying, balanced high that satisfies both seasoned smokers and curious newcomers. Its 2.21% terpene profile offers a bold, spicy-sweet aroma and smooth, flavorful smoke that makes every puff memorable. Limited runs keep these prerolls rare and in high demand, so once they sell out, it<69>s anyone<6E>s guess when they<65>ll return. Stocking Face on Fire on your shelves gives your customers something they can<61>t get anywhere else: exclusivity, buzz, and unforgettable quality. Grab it now and give your buyers a preroll that keeps them coming back.'],
|
||||
['sku' => 'OC-GZ-AZ1G', 'desc' => 'Gruntz turns ordinary sessions into must-visit experiences. Packed with 20.15% THC and 22.99% total cannabinoids, this 1g preroll delivers a perfectly balanced, euphoric high that keeps customers coming back for more. Its 2.38% terpene content releases a mouthwatering, candy-sweet aroma with rich, fruity undertones, giving a flavor experience that stands out from first puff to last. Limited runs make each roll rare, so when it<69>s gone, there<72>s no telling when it<69>ll be back. Gruntz prerolls aren<65>t just smoke, they<65>re a statement. Stocking them shows your customers you carry only the best, giving your menu a signature product that keeps buyers coming back.'],
|
||||
['sku' => 'OC-HBR-AZ1G', 'desc' => 'Headbanger flips the script on ordinary prerolls. Packed with 21.72% THC and 22.44% total cannabinoids, this heavy-hitting sativa-dominant hybrid delivers an energetic, creative high that keeps customers reaching for more. Expect a bold, diesel-forward aroma with sharp citrus and earthy notes that ignite the senses with every pull. Scarcity makes Headbanger a true prize, once it<69>s off the shelf it<69>s anyone<6E>s guess when it will be back. For dispensaries, Headbanger prerolls aren<65>t just another SKU, they<65>re a magnet for cannabis fans hunting potency, flavor, and exclusivity. Stocking Headbanger signals your menu is connoisseur-grade, separating your shop from the pack. Secure it while you can and let Headbanger do the talking.'],
|
||||
['sku' => 'OC-IL-AZ1G', 'desc' => 'Illemonati is a preroll designed to become a standout on your shelves and keep customers coming back. Packed with 20.53% THC and 24.14% total cannabinoids, this 1g roll delivers a smooth, clear-headed high with just the right touch of body relaxation, making it a favorite for social smokers and creative minds alike. Its 1.28% terpene profile offers a subtly earthy-sweet aroma that sets it apart from typical prerolls while appealing to a wide range of tastes. Each batch is small-batch crafted and released in highly limited quantities, so when it<69>s gone, there<72>s no set timeline for its return, adding real urgency for shoppers. Stocking Illemonati prerolls isn<73>t just adding another product, it<69>s offering a conversation starter that builds loyalty and keeps buyers coming back for more.'],
|
||||
['sku' => 'OC-JC-AZ1G', 'desc' => 'Jelly Cake redefines what a premium preroll should deliver. Packed with 25.45% THC and 29.98% total cannabinoids, this 1g roll provides long-lasting effects that combine full-body relaxation with an uplifting mental spark. Its 3.04% terpene profile bursts with layered notes of juicy berries, creamy vanilla, and subtle herbal undertones, creating an unforgettable flavor experience from first puff to last. Limited-run batches make each preroll rare, so once it<69>s sold out, it could be months before it<69>s back. This scarcity drives demand and keeps customers coming back for the next drop. Stocking Jelly Cake prerolls shows your clientele you carry only the most exceptional, buzz-worthy offerings and turns your store into a go-to destination for serious cannabis connoisseurs.'],
|
||||
['sku' => 'OC-MB-AZ1G', 'desc' => 'Moonbow is a signature preroll designed to set your shop apart with something truly special. Packed with 24.77% THC and 28.84% total cannabinoids, this 1g roll delivers a luxurious high that is both deeply relaxing and mentally expansive, perfect for customers seeking a premium escape. Its 3.73% terpene profile bursts with mouthwatering fruit-candy sweetness, layered florals, and earthy undertones, creating a complex and addictive flavor experience from first puff to last. Limited-run batches make each preroll rare, and once it sells out, it can return unpredictably, keeping customers checking back. Stocking Moonbow prerolls turns your dispensary into a destination for connoisseurs chasing rare finds. It<49>s more than a product, it<69>s an experience that builds buzz, drives sell-through, and keeps buyers coming back for more.'],
|
||||
['sku' => 'OC-OI-AZ1G', 'desc' => 'Oishii isn<73>t just another preroll, it<69>s a premium, can<61>t-get-it-anywhere-else experience that sets your menu apart. Packed with 20.07% THC and 24.12% total cannabinoids, this smooth-burning 1g roll delivers a blissful high that satisfies both daily smokers and curious newcomers alike. Its 2.34% terpene profile bursts with a sweet, exotic fruit aroma that lingers from the first spark to the final exhale, making every puff unforgettable. Dropping only in strictly limited quantities, Oishii prerolls move fast and once they<65>re gone, it<69>s uncertain when they<65>ll be back. Offering Oishii on your shelves shows customers you carry only the most exclusive, in-demand products. Stock up now and give your buyers a preroll that keeps them coming back.'],
|
||||
['sku' => 'OC-TO-AZ1G', 'desc' => 'The One sets a new standard for premium prerolls. Packed with 21.77% THC and 22.31% total cannabinoids, this hybrid delivers a balanced, full-bodied high that hits both mind and body perfectly. Expect a smooth, earthy flavor with subtle sweet notes that make every puff satisfying from start to finish. Limited production keeps The One rare, so once it<69>s gone, it<69>s anyone<6E>s guess when it will return. For dispensaries, The One prerolls aren<65>t just another SKU, they<65>re a standout product that draws in customers looking for quality, flavor, and exclusivity. Stock The One on your shelves and offer a preroll your buyers will keep coming back for.'],
|
||||
['sku' => 'PC-FM-SB-AZ1G', 'desc' => 'Proper Cock: Superboof Full Melt\r\n\r\nUnlock Balanced Bliss with Proper Cock: Superboof! ??\r\n\r\nIntroducing Superboof Full Melt, a premium solventless concentrate crafted from the perfectly balanced Superboof strain. This 100% pure concentrate is made with the finest trichomes, carefully refined through ice water hash technology to deliver a smooth, flavorful, and powerful experience in every dab. With its even hybrid genetics, Superboof offers the best of both worlds<64>delivering a blend of uplifting mental clarity and calming body relaxation, all wrapped in bold, gassy flavors.\r\n\r\nEven Hybrid: Superboof delivers a well-rounded experience that combines the best of both sativa and indica effects. The high starts with an energizing and euphoric mental lift, sparking creativity and focus, while the effects gradually transition into a soothing body buzz that helps you unwind without feeling overly sedated. Perfect for any time of day when you need a balanced boost. ????\r\n\r\nFull Melt Tech: This exquisite concentrate captures only the finest trichomes, offering a smooth and flavorful experience that melts effortlessly, leaving no residue behind. ???\r\n\r\nBold, Gassy Flavor: Get ready for a robust flavor profile that<61>s heavy on earthy, diesel-like notes with a touch of sourness. This gas-forward taste is complemented by subtle sweet undertones, making it a treat for those who enjoy bold, powerful flavors. ???\r\n\r\nAromatic Intensity: The aroma mirrors the flavor, with strong gassy, diesel-driven notes accompanied by a hint of earthy sweetness. It<49>s a pungent, bold fragrance that fills the room and enhances the overall experience. ???\r\n\r\nLuxurious Texture: With its rich golden hue, Superboof promises an unforgettable sensory journey with each use. ??\r\n\r\nUplifting Euphoria & Relaxing Calm: The even hybrid nature of Superboof provides a perfect balance of mental clarity and body relaxation. Feel energized and creatively inspired, followed by a calming body buzz that helps release tension and promotes a relaxed state. It<49>s the ultimate choice for any activity that calls for focus, creativity, and relaxation. ????\r\n\r\nSuperboof is the ultimate even hybrid experience<63>offering a perfect blend of mental stimulation and body relaxation with every dab. Whether you<6F>re seeking an energy boost, creative spark, or a gentle unwind, Superboof has you covered with its bold flavor and balanced effects.\r\n\r\nSo, grab your Proper Cock: Superboof Full Melt today and enjoy the best of both worlds<64>experience the explosive flavor and balanced effects of this exceptional hybrid strain! ???'],
|
||||
['sku' => 'PC-FM-TF-AZ1G', 'desc' => 'Proper Cock: Truffaloha Full Melt\r\n\r\nA Tropical Journey Begins with Proper Cock: Truffaloha! ???\r\n\r\nIntroducing Truffaloha Full Melt, a premium solventless concentrate made from the exquisite Truffaloha strain. This 100% pure concentrate is crafted from the finest trichomes, refined through ice water hash technology to deliver a smooth, flavorful, and powerful experience with every dab. Get ready to immerse yourself in a tropical paradise, where creativity and relaxation flow seamlessly with every hit.\r\n\r\nSativa-Dominant Hybrid: Truffaloha offers an uplifting, heady euphoria that sparks creativity and fuels motivation, making it ideal for daytime use or social gatherings. The high starts with a cerebral lift, enhancing focus and inspiration, and gradually evolves into a mild body relaxation, perfect for unwinding without feeling sluggish. ???\r\n\r\nFull Melt Tech: Crafted using ice water hash techniques, this concentrate captures only the finest trichomes, ensuring a clean, smooth, and flavorful experience that melts effortlessly with each dab. ???\r\n\r\nTropical Flavor Rush: Savor a burst of tropical sweetness with bold notes of pineapple, juicy mango, and a touch of creamy coconut. It<49>s a refreshing, fruity flavor profile that transports you straight to a sunny island paradise. ???\r\n\r\nAromatic Uplift: The aroma mirrors the flavor, offering an irresistible mix of tropical fruits, creamy vanilla, and a subtle earthy sweetness. Each hit fills the air with a refreshing, energizing scent<6E>perfect for enhancing your mood and sparking creativity. ???\r\n\r\nLuxurious Texture: With its rich white gold hue, Truffaloha promises an unforgettable sensory journey with each use. ?\r\n\r\nCreative Energy & Relaxing Calm: Known for its lively, uplifting effects, Truffaloha delivers a perfect balance of mental clarity and motivation, paired with a gentle body relaxation that keeps you feeling mellow yet energized. Ideal for daytime use, creative projects, or social interactions. ????\r\n\r\nTruffaloha is more than just a concentrate; it<69>s a tropical-inspired journey with every dab. Whether you need a creative boost, a mood enhancer, or a refreshing burst of energy, Truffaloha has you covered with its vibrant, tropical profile and energizing effects. Perfect for daytime adventures, social gatherings, or focusing on your next big idea.\r\n\r\nSo, grab your Proper Cock: Truffaloha Full Melt today and let the tropical vibes elevate your mood and energy. Experience the perfect balance of creativity, focus, and relaxation in every dab! ???'],
|
||||
['sku' => 'PC-FPR-CF-AZ1G', 'desc' => 'Proper Cock: Candy Fumez Fresh Press Rosin\r\n\r\nSweeten Your High with Proper Cock: Candy Fumez! ????\r\n\r\nIntroducing Candy Fumez Fresh Press Rosin, a top-tier solventless concentrate designed to elevate your cannabis experience. Crafted from the extraordinary Candy Fumez strain, this 100% pure, cold-pressed rosin embodies the essence of its rich lineage with exceptional purity. Sustainably sourced and responsibly packaged, get ready to indulge in a candy-coated journey with every dab!\r\n\r\n\r\nKey Features:\r\n\r\nBalanced Hybrid: Candy Fumez provides a perfect blend of invigorating euphoria and soothing calm. ????\r\n\r\nFlavor Extravaganza: Delight in a burst of sweet candy flavors with hints of fruity zest and creamy vanilla undertones. ???\r\n\r\nAromatic Bliss: Experience a tantalizing aroma reminiscent of a candy shop, with sugary sweets, fruity notes, and a touch of creamy richness. ???\r\n\r\nEuphoric Elevation: Begins with a euphoric cerebral lift, sparking joy and creativity. ??\r\n\r\nSoothing Serenity: The initial high smoothly transitions into a relaxing body effect, ideal for unwinding and easing into tranquility. ???\r\n\r\nFresh Press Rosin: Cold-pressed to maintain the highest level of purity and flavor, ensuring a smooth and refined experience. ???\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\nCandy Fumez is a flavorful hybrid strain known for its sweet, candy-like profile and balanced effects. The initial high delivers a euphoric and uplifting experience, perfect for igniting creativity and positive vibes. As the effects progress, it transitions into a relaxing body calm, making it perfect for winding down after a busy day.\r\n\r\nSo, grab your Proper Cock: Candy Fumez Fresh Press Rosin today and immerse yourself in a sweet, euphoric adventure. This premium rosin is your ticket to a delightful and smooth cannabis experience. Let the candy-coated bliss begin with Proper Cock! ????'],
|
||||
['sku' => 'PC-FPR-GB-AZ1G', 'desc' => 'Proper Cock: Garlic Breath Fresh Press Rosin\r\n\r\nEmbrace the Bold with Proper Cock: Garlic Breath! ???\r\n\r\nIntroducing Garlic Breath Fresh Press Rosin, a premium solventless concentrate crafted from the uniquely pungent Garlic Breath strain. Known for its bold and savory profile, this indica-dominant hybrid delivers a powerful, full-bodied experience that starts with a heavy dose of relaxation and finishes with a calming body buzz. Cold-pressed to preserve the strain\'s pure potency and rich flavors, this rosin is the perfect choice for those looking to unwind and enjoy a deeply soothing, flavorful experience. Sustainably sourced and responsibly packaged, Garlic Breath rosin offers a distinctive, unforgettable ride.\r\n\r\nKey Features:\r\n\r\nIndica-Dominant Hybrid: Garlic Breath brings a potent mix of relaxation and comfort. The high starts with a euphoric mental lift, followed by a wave of deep body relaxation that soothes tension and promotes total calm. Perfect for unwinding after a long day or for a quiet, chill evening. ????\r\n\r\nFlavor Profile: True to its name, Garlic Breath offers a bold, savory flavor with distinct notes of garlic and earthy, diesel-like undertones. A subtle hint of sweet and spicy flavors rounds out this unique profile, delivering a complex and satisfying taste with every dab. ????\r\n\r\nAromatic Strength: The aroma is as intense as the flavor, with pungent garlic and earthy diesel notes that fill the air. The scent is unmistakable<6C>sharp, savory, and spicy<63>perfect for those who appreciate a powerful, robust fragrance. ???\r\n\r\nHeavy Relaxation: The effects come on strong, with an initial cerebral buzz that lifts your mood and puts you in a focused state. As the high progresses, the effects shift into a deeply relaxing body buzz that melts away stress, muscle tension, and anxiety<74>making it ideal for evening relaxation or bedtime use. ????\r\n\r\nSoothing Body Buzz: As the indica-dominant effects settle in, you\'ll experience a heavy, calming body high that leaves you feeling deeply relaxed without feeling overly sedated. Ideal for relieving physical tension, unwinding after a busy day, or preparing for a peaceful night\'s sleep. ?????\r\n\r\nFresh Press Rosin: Cold-pressed to maintain the highest level of purity and flavor, ensuring a smooth and refined experience. ???\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\nGarlic Breath is the perfect indica-dominant hybrid for those looking for a robust, savory flavor and deep, lasting relaxation. Whether you need to de-stress, ease physical tension, or simply enjoy a rich, comforting flavor profile, this rosin delivers exactly what you need.\r\n\r\nSo, grab your Proper Cock: Garlic Breath Fresh Press Rosin today and experience the bold, savory flavors and deeply soothing effects of this unique indica-dominant hybrid. Let the relaxing waves of calm and intense flavors take you on a journey of pure relaxation. ???'],
|
||||
['sku' => 'PC-FPR-LCG-AZ1G', 'desc' => 'Proper Cock: Lemon Cherry Gelato Fresh Press Rosin\r\n\r\nIndulge Your Senses with Proper Cock: Lemon Cherry Gelato! ???\r\n\r\nIntroducing Lemon Cherry Gelato Fresh Press Rosin, a premium solventless concentrate that blends sweet, fruity flavors with a deeply relaxing high. Crafted from the Indica-dominant Lemon Cherry Gelato strain, this 100% pure, cold-pressed rosin delivers a soothing experience that balances mental clarity with physical relaxation. Sustainably sourced and responsibly packaged, this rosin is perfect for unwinding after a long day or enjoying a laid-back evening.\r\n\r\nKey Features:\r\n\r\nIndica-Dominant Hybrid: Lemon Cherry Gelato offers a perfect blend of relaxation and euphoria. The high starts with a gentle cerebral uplift that calms the mind, followed by a deeply soothing body buzz that melts away stress and tension, leaving you relaxed without feeling too heavy. ????\r\n\r\nFlavor Bliss: Enjoy the mouthwatering combination of tangy lemon and sweet cherry, with creamy vanilla undertones that add a rich, dessert-like finish. It<49>s a refreshing, fruity treat that<61>s as delicious as it is smooth. ???\r\n\r\nAromatic Comfort: The aroma is equally enticing, with bright citrus notes of lemon and cherry, balanced by creamy, sweet undertones. The scent is sweet and inviting, filling the air with a pleasant and comforting fragrance. ???\r\n\r\nRelaxing Euphoria: The initial cerebral effects provide a gentle mood lift and a sense of happiness, which transitions into a relaxing body high that helps ease tension and promote a sense of calm. Perfect for relaxation, evening use, or winding down after a busy day. ??????\r\n\r\nSmooth, Calming Body Buzz: As the high progresses, the indica-dominant effects provide a calming body buzz that doesn<73>t weigh you down, but rather helps you fully unwind and let go of stress. Ideal for those looking to relax and soothe both mind and body. ???\r\n\r\nFresh Press Rosin: Cold-pressed to maintain the highest level of purity and flavor, ensuring a smooth and refined experience. ???\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\nLemon Cherry Gelato is the perfect indica-dominant hybrid for those who want a balanced yet soothing experience. Its sweet, citrusy flavor and relaxing effects make it ideal for evening relaxation, unwinding, or simply enjoying a peaceful, mellow mood.\r\n\r\nSo, grab your Proper Cock: Lemon Cherry Gelato Fresh Press Rosin today and enjoy the relaxing, flavorful journey this indica-dominant hybrid has to offer. Let the calming effects and delicious taste take you to a place of blissful serenity! ???'],
|
||||
['sku' => 'PC-FPR-SB-AZ1G', 'desc' => 'Proper Cock: Superboof Fresh Press Rosin\r\n\r\nUnleash Your Power with Proper Cock: Superboof! ???\r\n\r\nIntroducing Superboof Fresh Press Rosin, a premium solventless concentrate that<61>s as bold and potent as its name suggests. Derived from the potent Superboof strain, this 100% pure, cold-pressed rosin captures the raw strength and complex flavors of this unique hybrid. Sustainably sourced and responsibly packaged, this rosin is your gateway to an intense and electrifying experience that<61>s as smooth as it is powerful.\r\n\r\nKey Features:\r\n\r\nHybrid Powerhouse: Superboof delivers a balanced hybrid experience that combines cerebral uplift with soothing body effects. The high starts with a burst of euphoria, elevating your mood and energy, before settling into a relaxing body buzz that helps you unwind without feeling overly sedated. ????\r\n\r\nFlavor Bomb: Bold, earthy flavors meet spicy, herbal notes with hints of sweet, citrusy zest<73>creating a rich, multi-layered profile that keeps you coming back for more. Each hit offers a deep, satisfying taste that lingers on your palate. ???\r\n\r\nAromatic Punch: The aroma is equally as intense, with pungent, earthy undertones and a sharp, citrusy zing that gives way to a touch of spicy sweetness. It<49>s a fragrance that announces itself, leaving a lasting impression. ????\r\n\r\nEuphoric Burst: The effects kick off with a heady, uplifting euphoria that ignites creativity and focus. Perfect for creative pursuits or deep thought, it keeps you sharp and engaged while enhancing your mood. ???\r\n\r\nBody Relaxation: As the high continues, it gently transitions into a mellow body relaxation that soothes stress and tension, making it ideal for winding down after a busy day. It\'s not too heavy, leaving you feeling calm but still active. ???\r\n\r\nFresh Press Rosin: Cold-pressed to maintain the highest level of purity and flavor, ensuring a smooth and refined experience. ???\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\nSuperboof is the hybrid you need when you want an experience that hits hard but doesn<73>t weigh you down. With a burst of creative energy, followed by deep relaxation, this rosin offers versatility for any time of day, whether you need focus, stress relief, or a little bit of both.\r\n\r\nSo, grab your Proper Cock: Superboof Fresh Press Rosin today and experience the powerful, multi-dimensional effects of this hybrid strain. Let the robust flavors and electrifying effects take you on an unforgettable ride. ???'],
|
||||
['sku' => 'PC-FPR-TF-AZ1G', 'desc' => 'Proper Cock: Truffaloha Fresh Press Rosin\r\n\r\nEscape to Paradise with Proper Cock: Truffaloha! ???\r\n\r\nIntroducing Truffaloha Fresh Press Rosin, a premium solventless concentrate that will take your cannabis experience to vibrant, tropical heights. Derived from the sativa-dominant Truffaloha strain, this 100% pure, cold-pressed rosin captures the invigorating energy and exotic flavors of its sun-soaked lineage. Sustainably sourced and responsibly packaged, this rosin is your ticket to a tropical adventure<72>whether you<6F>re unleashing creativity or simply basking in the uplifting vibes of the islands.\r\nKey Features:\r\n\r\nSativa-Dominant Hybrid: Truffaloha delivers a burst of energetic euphoria, perfect for daytime use, creativity, and boosting focus. It<49>s the ideal strain to spark inspiration and keep you engaged, without leaving you feeling too sedated. ???\r\n\r\nTropical Flavor Explosion: Get ready for a flavorful journey with notes of sweet pineapple, tangy mango, and creamy coconut, with a subtle hint of vanilla that rounds out the experience. It\'s like a tropical fruit cocktail in every hit! ???\\\r\n\r\nAromatic Island Breeze: The aroma is a fragrant blend of ripe tropical fruits, creamy vanilla, and a light, earthy sweetness, instantly transporting you to a beachside retreat. ???\r\n\r\nEnergetic Uplift: The effects start with a clear-headed, cerebral high that sparks creativity, motivation, and a deep sense of happiness<73>perfect for tackling projects, socializing, or simply enjoying a burst of positive energy. ???\r\n\r\nSmooth, Relaxed Vibes: As the high continues, it shifts into a gentle body relaxation that keeps you feeling at ease, without overwhelming sedation. You<6F>ll feel comfortable and chill<6C>ideal for lounging or unwinding after an active day. ???\r\n\r\nFresh Press Rosin: Cold-pressed to maintain the highest level of purity and flavor, ensuring a smooth and refined experience. ???\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\nTruffaloha is a sativa-dominant hybrid that strikes the perfect balance between energetic, creative uplift and smooth, relaxing vibes. Whether you\'re looking to spark new ideas, socialize with friends, or just enjoy a burst of tropical sunshine, this rosin is your ultimate companion for any day that calls for a little extra brightness.\r\n\r\nSo, grab your Proper Cock: Truffaloha Fresh Press Rosin today and experience the tropical energy and uplifting effects of this exotic sativa-dominant hybrid. Let the vibrant flavors and clear-headed euphoria take you on a sensory journey to paradise! ???'],
|
||||
['sku' => 'PC-RJ-FB-AZ1G', 'desc' => 'Proper Cock: Frankenberry\r\n\r\n?? Unleash the sweetness with Proper Cock: Frankenberry Delight! ??\r\n\r\nIntroducing Frankenberry Rosin Jam, an exquisite concentrate crafted from the fusion of Strawberry Cough and Blueberry strains. This premium, solventless delight is 100% pure, cold-pressed, and made with the finest, sustainably sourced plant goodness, all lovingly produced right here in Arizona.\r\n\r\nDelightful Hybrid: Frankenberry offers a euphoric and uplifting experience, combining blissful energy with a soothing touch. ????\r\n\r\nRosin Jam Tech: Made using heat and pressure to create a jam-like consistency, enhancing flavor and smoothness. ??\r\n\r\nFlavorful Adventure: Indulge in a delightful medley of sweet strawberry, tangy berry, and subtle earthy notes with every dab. ???\r\n\r\nAromatic Bliss: The aroma captivates with a burst of fresh strawberries, hints of blueberries, and a touch of sweet vanilla. ??\r\n\r\nSticky Texture: Rich amber hue and sticky texture promise a sensory journey with each use. ??\r\n\r\nThe Frankenberry experience is truly unique. Strawberry Cough, known for its sweet and fruity flavors, brings a light, uplifting energy, while Blueberry adds a creamy richness and deep relaxation. Together, they create a harmonious blend that stimulates creativity and joy while melting away stress.\r\n\r\nFrankenberry Rosin Jam isn<73>t just a concentrate; it\'s a flavorful journey in every dab. Ideal for unwinding after a long day or igniting your creativity, whether you\'re cozying up at home or exploring the outdoors, Frankenberry has your back.\r\n\r\nSo, grab your Proper Cock: Frankenberry Rosin Jam today and dive into a world of fruity bliss. This premium rosin jam is your gateway to an extraordinary experience. Let the good vibes flow with Proper Cock!'],
|
||||
['sku' => 'PC-RJ-HH-AZ1G', 'desc' => 'Headhunter Rosin Jam: Conquer Your High\r\n\r\nGet ready to embark on an epic adventure with Headhunter Rosin Jam! ??\r\n\r\nIntroducing Headhunter Rosin Jam, an exceptional concentrate crafted from the rare and potent Headhunter strain. This premium, solventless extract is 100% pure, cold-pressed, and made with the finest plant material, sustainably sourced and responsibly packaged to perfection.\r\n\r\nHigh-End Hybrid: Headhunter offers a dynamic high that perfectly balances cerebral stimulation and physical relaxation. ????\r\n\r\nRosin Jam Tech: Made using heat and pressure to create a jam-like consistency, enhancing flavor and smoothness. ??\r\n\r\nFlavorful Adventure: Delight in a rich tapestry of earthy, spicy, and piney notes with every dab. ???\r\n\r\nAromatic Bliss: The aroma captivates with a blend of rich earthiness, a hint of sweet pine, and subtle spicy undertones. ???\r\n\r\nSticky Texture: With its golden amber hue and sticky consistency, Headhunter Rosin Jam promises a deeply immersive experience with each use. ??\r\n\r\nThe Headhunter experience is elevated by its unique lineage. This strain brings together a perfect mix of bold, robust flavors with a potent, balanced effect. Expect a euphoric and uplifting head high that stimulates creativity and mental clarity, paired with a soothing body relaxation that keeps you grounded and calm.\r\n\r\nHeadhunter Rosin Jam isn<73>t just a concentrate; it<69>s your gateway to a powerful, multifaceted high. Ideal for those moments when you want to elevate your mood, enhance your focus, or simply unwind after a long day. Whether you<6F>re tackling a creative project or enjoying a peaceful evening, Headhunter Rosin Jam has you covered.\r\n\r\nSo, seize the day with Proper Cock: Headhunter Rosin Jam and conquer your high with unmatched clarity and relaxation. This premium rosin jam is your key to an extraordinary, out-of-this-world experience. Let the adventure begin with Proper Cock!'],
|
||||
['sku' => 'PC-RJ-LCG-AZ1G', 'desc' => 'Proper Cock: Lemon Cherry Gelato Fresh Press Rosin\r\n\r\nIndulge Your Senses with Proper Cock: Lemon Cherry Gelato! ???\r\n\r\nIntroducing Lemon Cherry Gelato Fresh Press Rosin, a premium solventless concentrate that blends sweet, fruity flavors with a deeply relaxing high. Crafted from the Indica-dominant Lemon Cherry Gelato strain, this 100% pure, cold-pressed rosin delivers a soothing experience that balances mental clarity with physical relaxation. Sustainably sourced and responsibly packaged, this rosin is perfect for unwinding after a long day or enjoying a laid-back evening.\r\n\r\nKey Features:\r\n\r\nIndica-Dominant Hybrid: Lemon Cherry Gelato offers a perfect blend of relaxation and euphoria. The high starts with a gentle cerebral uplift that calms the mind, followed by a deeply soothing body buzz that melts away stress and tension, leaving you relaxed without feeling too heavy. ????\r\n\r\nFlavor Bliss: Enjoy the mouthwatering combination of tangy lemon and sweet cherry, with creamy vanilla undertones that add a rich, dessert-like finish. It<49>s a refreshing, fruity treat that<61>s as delicious as it is smooth. ???\r\n\r\nAromatic Comfort: The aroma is equally enticing, with bright citrus notes of lemon and cherry, balanced by creamy, sweet undertones. The scent is sweet and inviting, filling the air with a pleasant and comforting fragrance. ???\r\n\r\nRelaxing Euphoria: The initial cerebral effects provide a gentle mood lift and a sense of happiness, which transitions into a relaxing body high that helps ease tension and promote a sense of calm. Perfect for relaxation, evening use, or winding down after a busy day. ??????\r\n\r\nSmooth, Calming Body Buzz: As the high progresses, the indica-dominant effects provide a calming body buzz that doesn<73>t weigh you down, but rather helps you fully unwind and let go of stress. Ideal for those looking to relax and soothe both mind and body. ???\r\n\r\nFresh Press Rosin: Cold-pressed to maintain the highest level of purity and flavor, ensuring a smooth and refined experience. ???\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\nLemon Cherry Gelato is the perfect indica-dominant hybrid for those who want a balanced yet soothing experience. Its sweet, citrusy flavor and relaxing effects make it ideal for evening relaxation, unwinding, or simply enjoying a peaceful, mellow mood.\r\n\r\nSo, grab your Proper Cock: Lemon Cherry Gelato Fresh Press Rosin today and enjoy the relaxing, flavorful journey this indica-dominant hybrid has to offer. Let the calming effects and delicious taste take you to a place of blissful serenity! ???'],
|
||||
['sku' => 'PC-RJ-TF-AZ1G', 'desc' => 'Proper Cock: Truffaloha Rosin Jam\r\n\r\nElevate Your Vibe with Proper Cock: Truffaloha! ???\r\n\r\nIntroducing Truffaloha Rosin Jam, a luxurious concentrate crafted from the renowned Truffaloha strain. This premium, solventless extract is 100% pure, cold-pressed, and meticulously produced from the finest plant material, ensuring both quality and sustainability in every jar.\r\n\r\nSativa-Leaning Hybrid: Truffaloha offers an energizing, euphoric high that is perfect for boosting creativity and focus while maintaining a smooth, relaxing body effect. This sativa-dominant hybrid is designed to spark inspiration, elevate mood, and leave you feeling uplifted and motivated, making it ideal for daytime use or social occasions. ???\r\n\r\nRosin Jam Tech: Made using heat and pressure to create a jam-like consistency, enhancing flavor and smoothness. ??\r\n\r\nFlavorful Journey: Delight in a complex flavor profile that combines earthy truffle notes with a hint of tropical sweetness and creamy undertones. ???\r\n\r\nAromatic Indulgence: The aroma invites you with a blend of rich, earthy truffle and subtle tropical fruit notes, creating a fragrant and alluring experience. ??\r\n\r\nLuxurious Texture: With its vibrant amber hue and sticky consistency, Truffaloha Rosin Jam promises an immersive, sensory-rich journey with each dab. ??\r\n\r\nTruffaloha is an energizing strain that combines the deep, earthy richness of truffles with a tropical twist. The result is a high that stimulates creativity, sparks joy, and encourages social interaction while providing just the right amount of body relaxation to keep you grounded. Perfect for those looking to add a bit of zest to their day, whether you<6F>re tackling creative projects, exploring the outdoors, or enjoying time with friends.\r\n\r\nTruffaloha Rosin Jam isn<73>t just a concentrate; it<69>s a lavish escape in every dab. Ideal for moments when you wish to elevate your mood, indulge in an exquisite flavor experience, or unwind after a busy day. Whether you<6F>re enjoying a quiet night in or exploring new adventures, Truffaloha Rosin Jam is your go-to for a sensational, otherworldly high.\r\n\r\nSo, grab your Proper Cock: Truffaloha Rosin Jam today and immerse yourself in a luxurious, flavorful experience. This top-tier rosin jam is your ticket to a sensational and euphoric journey. Let the truffle and tropical bliss begin! ???'],
|
||||
['sku' => 'TB-AKL-AZ1G', 'desc' => 'Amnesia K Lemon <20> Brighten Your Day at an Unbeatable Price ?\r\n\r\nCitrus Bliss Awaits\r\nAmnesia K Lemon is a delightful sativa-dominant hybrid that combines uplifting energy with a burst of citrus flavor. Its refreshing lemon aroma, accented by hints of earthy undertones, offers a zesty escape that invigorates the senses with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Amnesia K Lemon delivers a smooth, vibrant smoke that<61>s perfect for daytime adventures. Our precise grinding process ensures that each inhale is packed with lively flavors and energizing effects, making it an ideal choice for those seeking motivation without breaking the bank.\r\n\r\nEnergize Your Spirit\r\nDesigned for daytime enjoyment, Amnesia K Lemon provides a clear-headed and inspiring high that helps you tackle your to-do list or engage in lively conversations. Let the euphoric vibes lift your mood and ignite your creativity throughout the day.\r\n\r\nSavor the Experience\r\nIndulge in the refreshing experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to encapsulate the essence of this invigorating strain. Thunder Bud seamlessly blends convenience and quality, offering a sensory adventure that awakens the palate with each draw. Each pre-roll showcases a compact, enticing appearance, featuring rich, vibrant hues of finely ground small buds and trim, all adorned with shimmering trichomes, promising a delightful encounter with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your mood with Amnesia K Lemon <20> bright, uplifting highs at an unbeatable price.\r\n\r\nHere<72>s to joyful experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-AKL-PP-AZ28G', 'desc' => 'Amnesia K Lemon <20> Brighten Your Day at an Unbeatable Price ?\r\n\r\nCitrus Bliss Awaits\r\nAmnesia K Lemon is a delightful sativa-dominant hybrid that combines uplifting energy with a burst of citrus flavor. Its refreshing lemon aroma, accented by hints of earthy undertones, offers a zesty escape that invigorates the senses with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Amnesia K Lemon delivers a smooth, vibrant smoke that<61>s perfect for daytime adventures. Our precise grinding process ensures that each inhale is packed with lively flavors and energizing effects, making it an ideal choice for those seeking motivation without breaking the bank.\r\n\r\nEnergize Your Spirit\r\nDesigned for daytime enjoyment, Amnesia K Lemon provides a clear-headed and inspiring high that helps you tackle your to-do list or engage in lively conversations. Let the euphoric vibes lift your mood and ignite your creativity throughout the day.\r\n\r\nSavor the Experience\r\nIndulge in the refreshing experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to encapsulate the essence of this invigorating strain. Thunder Bud seamlessly blends convenience and quality, offering a sensory adventure that awakens the palate with each draw. Each pre-roll showcases a compact, enticing appearance, featuring rich, vibrant hues of finely ground small buds and trim, all adorned with shimmering trichomes, promising a delightful encounter with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your mood with Amnesia K Lemon <20> bright, uplifting highs at an unbeatable price.\r\n\r\nHere<72>s to joyful experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-AM-AZ1G', 'desc' => 'Alien Marker <20> Deep Space Relaxation at an Unbeatable Price ???\r\n\r\nA Cosmic Collision of Flavor\r\n\r\nAlien Marker is a powerful indica-dominant hybrid that sweeps you away with bold, complex flavors. Sweet berry notes blend with funky diesel and earthy undertones, creating an out-of-this-world aroma that\'s both sharp and sugary a true treat for the senses with every puff.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, Alien Marker delivers a rich, smooth smoke that\'s perfect for those moments when you need to kick back and unwind. Thunder Bud<75>s precision grinding process ensures that every pre-roll is loaded with flavorful, potent hits bringing you deep relaxation without the deep price.\r\n\r\nUnwind Among the Stars\r\n\r\nPerfect for evenings or lazy days, Alien Marker offers a heavy, calming high that melts away stress and tension. As your body sinks into relaxation, your mind is gently lifted into a dreamlike, euphoric state ideal for stargazing, movie marathons, or simply drifting off into your own orbit.\r\n\r\nSavor the Experience\r\n\r\nImmerse yourself in the luxurious flavors of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to highlight Alien Marker\'s bold profile. Finely ground small buds and resin rich trim come together in each pre-roll, showcasing colorful, frosty hues and delivering a smooth, flavorful burn that<61>s pure cosmic bliss.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s sustainable packaging lets you enjoy the experience while helping protect the planet. ?\r\n\r\nDrift away with Alien Marker <20> rich flavor, deep relaxation, and stellar value.\r\n\r\nHere<72>s to slowing down, kicking back, and letting the universe take over.'],
|
||||
['sku' => 'TB-BC-AZ1G', 'desc' => 'Buff Cherry <20> Bold Flavor, Balanced Highs at an Unbeatable Price ??\r\n\r\nA Sweet Burst of Energy and Ease\r\n\r\nBuff Cherry is a dynamic hybrid that blends juicy cherry sweetness with subtle earthy undertones, delivering a flavorful smoke that balances uplifting energy with smooth relaxation. Its bold, fruity aroma makes every puff a treat while its effects keep you both engaged and at ease.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, Buff Cherry offers a smooth, tasty burn packed with potency. Thunder Bud<75>s meticulous grinding process ensures every pre-roll is consistently rolled, terpene-rich, and ready to deliver quality effects without the boutique price tag.\r\n\r\nFind Your Balance\r\n\r\nPerfect for anytime use, Buff Cherry provides a clear-headed, euphoric lift alongside a gentle body calm. Whether you<6F>re gearing up for a creative project, hanging out with friends, or just easing into the evening, this strain helps you stay balanced and in the moment.\r\n\r\nSavor the Experience\r\n\r\nIndulge in the flavorful journey of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to highlight the rich, sweet aroma and smooth smoke of Buff Cherry. Each pre-roll features finely ground buds and resinous trim dusted with shimmering trichomes, ensuring a satisfying session from first spark to final puff.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s dedication to sustainable packaging means you can enjoy Buff Cherry while supporting a greener planet. ?\r\n\r\nExperience Buff Cherry <20> bold flavor, balanced highs, unbeatable value.\r\n\r\nHere<72>s to flavorful sessions and good vibes, all while keeping your wallet happy! ?'],
|
||||
['sku' => 'TB-BM-AZ1G', 'desc' => 'Thunder Bud Black Maple <20> Cozy Highs at a Great Price ?\r\n\r\nMaple Comfort\r\nThunder Bud Black Maple is a soothing indica-dominant hybrid that wraps you in warmth and calm with every puff. Its inviting aroma of sweet maple syrup and subtle earthy spice creates a comforting, nostalgic experience that<61>s perfect for unwinding after a long day.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Black Maple delivers a smooth, flavorful smoke that hits just right without hitting your wallet. Thunder Bud<75>s careful grinding process ensures every pre-roll is packed with terpene-rich flower for consistent flavor and relaxing potency.\r\n\r\nRelax and Unwind\r\nBlack Maple provides a deeply calming body high paired with a mellow, happy headspace. Ideal for slow evenings, cozy nights in, or peaceful reflection, this strain helps ease tension while keeping the mood light and serene.\r\n\r\nSavor the Experience\r\nIndulge in Thunder Bud Trim+Smalls Pre-Rolls, designed to highlight the lush, syrupy sweetness and earthy undertones of Black Maple. Each pre-roll features finely ground small buds and resin-rich trim that burn evenly for a smooth, flavorful experience from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s sustainable packaging keeps your smoke session guilt-free and the planet happy. ?\r\n\r\nUnwind with Thunder Bud Black Maple for rich, relaxing flavors at an unbeatable price.\r\nHere<72>s to cozy vibes, calm nights, and premium quality that doesn<73>t break the bank. ?'],
|
||||
['sku' => 'TB-BM-AZ3G', 'desc' => 'Thunder Bud Black Maple <20> Rich Flavors at a Great Price ?\r\n\r\nMaple Bliss\r\nThunder Bud Black Maple is an exceptional hybrid strain that brings warmth and comfort to your day. With its delightful blend of sweet maple syrup aroma and earthy undertones, this strain offers a cozy escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Black Maple delivers a smooth, flavorful smoke that<61>s perfect for any occasion. Our meticulous grinding process ensures each puff is infused with rich flavors and soothing effects, all at an affordable price.\r\n\r\nRelaxed and Inspired\r\nIdeal for both relaxation and creativity, Black Maple provides a balanced high that calms the body while sparking the mind. Whether you<6F>re enjoying a quiet evening or engaging in creative projects, this strain enhances your experience, inviting a sense of tranquility and inspiration.\r\n\r\nImmerse in the Experience\r\nIndulge in the comforting experience of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory journey that delights the senses with each inhale. Each pre-roll is a showcase of precision and artistry. Wrapped in premium rolling paper, these pre-rolls feature a compact, appealing appearance. The rich, earthy tones of finely ground small buds and trim are beautifully highlighted by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nWarm up your day with Thunder Bud Black Maple <20> rich flavors at an affordable price.\r\n\r\nCheers to comforting experiences, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-BM-AZ5G', 'desc' => 'Thunder Bud Black Maple <20> Rich Flavors at a Great Price ?\r\n\r\nMaple Bliss\r\nThunder Bud Black Maple is an exceptional hybrid strain that brings warmth and comfort to your day. With its delightful blend of sweet maple syrup aroma and earthy undertones, this strain offers a cozy escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Black Maple delivers a smooth, flavorful smoke that<61>s perfect for any occasion. Our meticulous grinding process ensures each puff is infused with rich flavors and soothing effects, all at an affordable price.\r\n\r\nRelaxed and Inspired\r\nIdeal for both relaxation and creativity, Black Maple provides a balanced high that calms the body while sparking the mind. Whether you<6F>re enjoying a quiet evening or engaging in creative projects, this strain enhances your experience, inviting a sense of tranquility and inspiration.\r\n\r\nImmerse in the Experience\r\nIndulge in the comforting experience of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory journey that delights the senses with each inhale. Each pre-roll is a showcase of precision and artistry. Wrapped in premium rolling paper, these pre-rolls feature a compact, appealing appearance. The rich, earthy tones of finely ground small buds and trim are beautifully highlighted by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nWarm up your day with Thunder Bud Black Maple <20> rich flavors at an affordable price.\r\n\r\nCheers to comforting experiences, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-BM-AZ5G', 'desc' => 'Thunder Bud Cap Junky <20> Elevate Your Vibes at an Exceptional Price ?\r\n\r\nCaptivating Experience\r\nAmnesia Lemon Kush is a delightful sativa-dominant hybrid that combines uplifting energy with a burst of citrus flavor. Its refreshing lemon aroma, accented by hints of earthy undertones, offers a zesty escape that invigorates the senses with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Cap Junky provides a smooth and satisfying smoke, perfect for unwinding after a long day. Our careful grinding process ensures that each puff is infused with rich flavors and calming effects, making it a great choice for any occasion.\r\n\r\nRelax and Unwind\r\nIdeal for both daytime and evening use, Cap Junky offers a balanced high that promotes relaxation while keeping your mind clear. Whether you<6F>re enjoying a cozy night in or catching up with friends, let the soothing vibes elevate your mood and enhance your experience.\r\n\r\nSavor the Journey\r\nIndulge in the rich experience of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of this distinctive strain. Thunder Bud combines convenience and quality, providing a sensory adventure that awakens the senses with every inhale. Each Thunder Bud Pre-Roll showcases a compact yet inviting appearance, featuring vibrant shades of finely ground small buds and trim, all adorned with sparkling trichomes, promising a delightful encounter with each draw.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nDiscover the bliss of Thunder Bud Cap Junky <20> harmonious highs at an unbeatable price.\r\n\r\nHere<72>s to relaxing experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-BPC-AZ1G', 'desc' => 'Banana Punch Cake <20> Balanced Bliss at a Tasty Price ??\r\n\r\nFlavor That Hits Just Right\r\n\r\nBanana Punch Cake is a perfectly balanced hybrid that brings the best of both worlds uplifting heady effects paired with soothing body vibes. Bursting with flavors of ripe banana, sweet vanilla, and a hint of fruity punch, this strain delivers a smooth, dessert like experience that satisfies from the first puff.\r\n\r\nHarmony in Every Hit, Without the Hefty Tag\r\n\r\nMade from premium trim and smalls, Banana Punch Cake offers a flavorful, mellow smoke that<61>s both budget-friendly and high-quality. Our refined grinding process ensures each pre-roll is evenly packed and slow burning, letting you savor the flavor and effects without burning a hole in your wallet.\r\n\r\nVersatility You<6F>ll Love\r\n\r\nWhether you\'re easing into a creative flow or winding down after a long day, Banana Punch Cake has you covered. Its balanced effects provide a gentle mental uplift while relaxing the body, making it a great go-to for anytime use morning, noon, or night.\r\n\r\nCrafted to Delight\r\n\r\nThunder Bud Trim+Smalls Pre-Rolls showcase the rich character of Banana Punch Cake in a convenient, ready to enjoy form. Finely ground small buds and trim are wrapped up in trichome coated perfection, offering a smooth draw and even burn with every session.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud keeps things green with sustainable packaging because good highs should feel good all around. ?\r\n\r\nBanana Punch Cake deliciously balanced, endlessly versatile, and always easy on the wallet.\r\n\r\nHere<72>s to good vibes, any time of day.'],
|
||||
['sku' => 'TB-BR-AZ1G', 'desc' => 'Thunder Bud Blue Runtz <20> Flavorful Vibes at a Great Price ?\r\n\r\nFruity Bliss\r\nThunder Bud Blue Runtz is a delectable indica-dominant hybrid strain that brings a burst of flavor and relaxation to your day. With its sweet berry aroma and hints of creamy fruit, this strain offers a deliciously enjoyable escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Blue Runtz delivers a smooth, flavorful smoke that<61>s perfect for winding down. Our meticulous grinding process ensures each puff is packed with vibrant flavors and soothing effects, all at an unbeatable price.\r\n\r\nRelaxing and Uplifting\r\nIdeal for evenings or social gatherings, Blue Runtz provides a comforting and euphoric high that promotes relaxation and creativity. Whether you<6F>re enjoying a cozy night in or sharing laughs with friends, this strain enhances your experience and elevates your mood.\r\n\r\nImmerse in the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that excites the senses with each inhale. Each pre-roll showcases precision and care, wrapped in premium rolling paper. The vibrant colors of finely ground small buds and trim are beautifully complemented by glistening trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Blue Runtz <20> flavorful vibes at an affordable price.\r\n\r\nCheers to relaxing moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-BR-AZ3G', 'desc' => 'Thunder Bud Blue Runtz <20> Flavorful Vibes at a Great Price ?\r\n\r\nFruity Bliss\r\nThunder Bud Blue Runtz is a delectable indica-dominant hybrid strain that brings a burst of flavor and relaxation to your day. With its sweet berry aroma and hints of creamy fruit, this strain offers a deliciously enjoyable escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Blue Runtz delivers a smooth, flavorful smoke that<61>s perfect for winding down. Our meticulous grinding process ensures each puff is packed with vibrant flavors and soothing effects, all at an unbeatable price.\r\n\r\nRelaxing and Uplifting\r\nIdeal for evenings or social gatherings, Blue Runtz provides a comforting and euphoric high that promotes relaxation and creativity. Whether you<6F>re enjoying a cozy night in or sharing laughs with friends, this strain enhances your experience and elevates your mood.\r\n\r\nImmerse in the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that excites the senses with each inhale. Each pre-roll showcases precision and care, wrapped in premium rolling paper. The vibrant colors of finely ground small buds and trim are beautifully complemented by glistening trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Blue Runtz <20> flavorful vibes at an affordable price.\r\n\r\nCheers to relaxing moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-BR-AZ5G', 'desc' => 'Thunder Bud Blue Runtz <20> Flavorful Vibes at a Great Price ?\r\n\r\nFruity Bliss\r\nThunder Bud Blue Runtz is a delectable indica-dominant hybrid strain that brings a burst of flavor and relaxation to your day. With its sweet berry aroma and hints of creamy fruit, this strain offers a deliciously enjoyable escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Blue Runtz delivers a smooth, flavorful smoke that<61>s perfect for winding down. Our meticulous grinding process ensures each puff is packed with vibrant flavors and soothing effects, all at an unbeatable price.\r\n\r\nRelaxing and Uplifting\r\nIdeal for evenings or social gatherings, Blue Runtz provides a comforting and euphoric high that promotes relaxation and creativity. Whether you<6F>re enjoying a cozy night in or sharing laughs with friends, this strain enhances your experience and elevates your mood.\r\n\r\nImmerse in the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that excites the senses with each inhale. Each pre-roll showcases precision and care, wrapped in premium rolling paper. The vibrant colors of finely ground small buds and trim are beautifully complemented by glistening trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Blue Runtz <20> flavorful vibes at an affordable price.\r\n\r\nCheers to relaxing moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-CB-AZ1G', 'desc' => 'Thunder Bud Cake Bomb <20> Decadent Highs, Small Price ?\r\n\r\nThe Ultimate Dessert for Your Senses\r\nThunder Bud Cake Bomb is an indica-dominant hybrid that combines sweet, rich flavors with powerful effects. This strain offers a delightful aroma of vanilla and cake batter, making each puff a dessert-like experience. Perfect for those mellow evenings, this indica strain promises to sprinkle your day with relaxation and a burst of delightful tranquility.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Cake Bomb delivers a smooth, delicious smoke that<61>s as indulgent as it sounds. Our grinding process ensures every puff is packed with sweet flavors and potent effects, all at an affordable price.\r\n\r\nOrigin Story\r\nCultivated with pride by Arizonans who know their buds better than a baker knows his dough, each nugget of Thunder Bud Cake Bomb is a homage to locally-grown greatness. Nestled in the sun-drenched soils of Arizona, this strain savors every drop of sunshine, converting it into potent, aromatic bliss.\r\n\r\nRelax and Unwind\r\nPerfect for evening use, Cake Bomb provides a deeply relaxing and euphoric high. It<49>s ideal for melting away stress and promoting a restful night<68>s sleep, leaving you feeling blissfully relaxed.\r\n\r\nIndulge in the Experience\r\nIndulge in the electrifying experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to encapsulate the essence of every strain. Thunder Bud presents a fusion of convenience and quality, delivering a sensory journey that ignites the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls boast a compact yet alluring appearance. The rich, earthy hues of the finely ground small buds and trim, generously packed within the confines of the paper, are punctuated by vibrant streaks of crystalline trichomes, promising a potent encounter with each puff.\r\n\r\nResponsibly Packaged Goodness\r\nThunder Bud<75>s responsible packaging is designed to protect the planet while delivering a top-notch smoking experience. Our packaging isn<73>t just about looking good <20> it<69>s about being good. ?\r\n\r\nHave Your Cake and Feel It Too!\r\nLight up a slice of this cake, and you<6F>ll find yourself floating on a cloud of calm, cocooned in a cushy cradle of chill. Whether you<6F>re looking to soften the sharp edges of a hard day or jazz up a jaded evening, Thunder Bud Cake Bomb is your go-to gentleman, tipping its hat with every toke.\r\n\r\nGet ready to have your cake and feel it too with Thunder Bud Cake Bomb <20> delicious highs at a small price.\r\n\r\nCheers to big highs at a small price! ?'],
|
||||
['sku' => 'TB-CB-AZ5G', 'desc' => 'Thunder Bud Cake Bomb <20> Decadent Highs, Small Price ?\r\n\r\nThe Ultimate Dessert for Your Senses\r\nThunder Bud Cake Bomb is an indica-dominant hybrid that combines sweet, rich flavors with powerful effects. This strain offers a delightful aroma of vanilla and cake batter, making each puff a dessert-like experience. Perfect for those mellow evenings, this indica strain promises to sprinkle your day with relaxation and a burst of delightful tranquility.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Cake Bomb delivers a smooth, delicious smoke that<61>s as indulgent as it sounds. Our grinding process ensures every puff is packed with sweet flavors and potent effects, all at an affordable price.\r\n\r\nRelax and Unwind\r\nPerfect for evening use, Cake Bomb provides a deeply relaxing and euphoric high. It<49>s ideal for melting away stress and promoting a restful night<68>s sleep, leaving you feeling blissfully relaxed.\r\n\r\nIndulge in the Experience\r\nIndulge in the electrifying experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to encapsulate the essence of every strain. Thunder Bud presents a fusion of convenience and quality, delivering a sensory journey that ignites the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls boast a compact yet alluring appearance. The rich, earthy hues of the finely ground small buds and trim, generously packed within the confines of the paper, are punctuated by vibrant streaks of crystalline trichomes, promising a potent encounter with each puff.\r\n\r\nResponsibly Packaged Goodness\r\nThunder Bud<75>s responsible packaging is designed to protect the planet while delivering a top-notch smoking experience. Our packaging isn<73>t just about looking good <20> it<69>s about being good. ?\r\n\r\nHave Your Cake and Feel It Too!\r\nLight up a slice of this cake, and you<6F>ll find yourself floating on a cloud of calm, cocooned in a cushy cradle of chill. Whether you<6F>re looking to soften the sharp edges of a hard day or jazz up a jaded evening, Thunder Bud Cake Bomb is your go-to gentleman, tipping its hat with every toke.\r\n\r\nGet ready to have your cake and feel it too with Thunder Bud Cake Bomb <20> delicious highs at a small price.\r\n\r\nCheers to big highs at a small price! ?'],
|
||||
['sku' => 'TB-CC-AZ1G', 'desc' => 'Cake Crasher <20> Sweet Flavor, Balanced Highs at an Unbeatable Price ??\r\n\r\nA Decadent Escape into Balance\r\n\r\nCake Crasher is a versatile hybrid that blends sweet, dessert-like flavors with subtle earthy undertones, offering a smoke that<61>s as rich and indulgent as it is smooth. With its creamy, fruity aroma and perfectly balanced effects, this strain delivers both an uplifting head buzz and a relaxing body calm, making it an all-around favorite.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, Cake Crasher provides a flavorful, satisfying smoke without the premium price tag. Thunder Bud<75>s precise grinding process ensures that every pre-roll is evenly packed with terpene-rich buds and trim, guaranteeing consistency and potency in every puff.\r\n\r\nBalance Your Vibe\r\n\r\nIdeal for any time of day, Cake Crasher offers a harmonious high that sparks creativity and good vibes while keeping the body relaxed and stress-free. Whether you<6F>re enjoying a daytime sesh, winding down in the evening, or hanging out with friends, this strain adapts to your mood and moment.\r\n\r\nSavor the Experience\r\n\r\nIndulge in the sweet journey of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to showcase the dessert-like essence of Cake Crasher. Each pre-roll features finely ground buds and trichome-coated trim, promising a smooth, flavorful burn that lingers with every draw.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s dedication to eco-friendly packaging ensures you can enjoy Cake Crasher while making a sustainable choice for the planet. ?\r\n\r\nEnjoy Cake Crasher, sweet flavor, balanced highs, unbeatable value.\r\n\r\nHere<72>s to delicious sessions and good times, all while keeping your wallet happy! ??'],
|
||||
['sku' => 'TB-CCT-AZ1G', 'desc' => 'Candycoast <20> Ride the Sweet Wave at an Unbeatable Price ??\r\n\r\nA Sugary Burst of Coastal Energy\r\nCandycoast is a lively sativa-dominant hybrid that blends tropical sweetness with uplifting energy. With notes of candied citrus, ripe pineapple, and a splash of ocean breeze, this strain captures the carefree spirit of sunny shores and sweet escapes. The aroma alone feels like a mini vacation, sparking creativity, focus, and pure good vibes.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Candycoast delivers smooth, flavorful hits that wake up your senses without breaking your budget. Thunder Bud<75>s precision grinding ensures every pre-roll burns evenly and packs the perfect balance of potency and terpene-rich flavor, bringing boutique quality at a down-to-earth price.\r\n\r\nElevate Your Day\r\nIdeal for daytime sessions or creative afternoons, Candycoast delivers an energizing mental buzz paired with a mellow, happy body high. Let the bright, euphoric effects lift your mood and sharpen your focus, perfect for sparking inspiration, tackling projects, or just soaking in good company and sunshine.\r\n\r\nSavor the Experience\r\nImmerse yourself in the tropical flavor of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to preserve Candycoast<73>s sweet, citrus-forward terpene profile. Each pre-roll features finely ground small buds and resin-rich trim, shining with trichomes that promise a flavorful, smooth burn every time.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s eco-friendly packaging helps you enjoy premium cannabis while caring for the planet. ?\r\n\r\nCatch the Wave with Candycoast <20> bright, uplifting highs at an unbeatable price.\r\nHere<72>s to sunny days, sweet vibes, and a smooth ride from coast to coast! ???'],
|
||||
['sku' => 'TB-CD-AZ1G', 'desc' => 'Chemdawg <20> Heavy Hitter at an Unbeatable Price ??\r\n\r\nA Legendary Relaxation Experience\r\nChemdawg is an indica-leaning hybrid that lives up to its reputation as a powerhouse classic. Known for its sharp diesel aroma, earthy spice, and hints of citrus, this strain delivers a bold, flavorful smoke that settles the mind and soothes the body. Expect deep relaxation paired with a steady, mellow euphoria that keeps the stress away and the vibes flowing.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Chemdawg brings top-tier potency and flavor without the top-shelf price. Thunder Bud<75>s precise grinding process ensures every pre-roll is perfectly packed for a slow, even burn that delivers terpene-rich, full-bodied hits. It<49>s boutique quality made affordable for everyday enjoyment.\r\n\r\nRelax Your Mind, Ease Your Body\r\nPerfect for unwinding after a long day or kicking back with friends, Chemdawg<77>s effects lean toward calm and comfort. The high starts with a gentle mental buzz that melts into a soothing body relaxation, making it ideal for evening sessions, movie nights, or simply drifting into your perfect chill.\r\n\r\nSavor the Experience\r\nThunder Bud Trim+Smalls Pre-Rolls capture the bold, signature flavor of Chemdawg with care and precision. Each pre-roll is filled with finely ground small buds and resin-rich trim, ensuring a flavorful, smooth burn that stays consistent from first puff to last.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s commitment to eco-friendly packaging means you can enjoy premium cannabis while doing good for the planet. ?\r\n\r\nUnwind with Chemdawg, powerful, relaxing highs at an unbeatable price.\r\nHere<72>s to calm nights, mellow vibes, and the kind of smoke that never misses. ??'],
|
||||
['sku' => 'TB-CF-AZ1G', 'desc' => 'Cake Face <20> Smooth, Sweet, and Perfectly Balanced ?????\r\n\r\nFlavor That Speaks for Itself\r\n\r\nCake Face is an evenly balanced hybrid that lives up to its name delivering a rich, sugary flavor profile with creamy vanilla cake notes and a touch of earthy spice. It<49>s a sweet escape with a smooth, velvety finish that keeps your taste buds coming back for more.\r\n\r\nFeel Good Highs Without the Premium Price\r\n\r\nCrafted from quality trim and smalls, Cake Face offers a luxurious smoke at a down-to-earth cost. Thunder Bud<75>s fine grind ensures each pre-roll is consistent and slow burning, giving you full access to the flavor and effects without stretching your budget.\r\n\r\nBalanced Vibes, All Day Long\r\n\r\nWith its mellow yet uplifting effects, Cake Face strikes the perfect middle ground. Expect a calm, happy headspace paired with gentle body relaxation ideal for a midday lift, creative sessions, or just cruising through your to-do list with ease.\r\n\r\nRolled to Perfection\r\n\r\nThunder Bud Trim+Smalls Pre-Rolls capture everything you love about Cake Face in a ready to go format. Finely ground small buds and frosty trim come together in compact, visually appealing pre-rolls that deliver a smooth, flavorful experience every time.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud wraps every good high in packaging that<61>s easy on the planet. ?\r\n\r\nCake Face creamy, dreamy balance made for any moment, at a price that makes sense.\r\n\r\nHere<72>s to sweet highs and chill vibes whenever you need them.'],
|
||||
['sku' => 'TB-CG-AZ0.5G', 'desc' => 'Thunder Bud Citral Glue <20> Elevate Your Vibes at an Incredible Price ?\r\n\r\nCitrusy Bliss\r\n\r\nThunder Bud Citral Glue is an enticing hybrid strain that combines vibrant energy with a touch of relaxation. With its delightful citrus aroma and hints of earthy sweetness, this strain offers a refreshing escape with every puff, making it perfect for any occasion.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from the finest trim and smalls, Citral Glue delivers a smooth and flavorful smoke that won<6F>t break the bank. Our meticulous grinding process ensures each puff is infused with rich flavors and balanced effects, providing the ideal blend of upliftment and calm.\r\n\r\nEnergize Your Spirit\r\n\r\nPerfect for daytime use, Citral Glue offers a euphoric high that clears the mind while relaxing the body. Whether you\'re diving into creative projects or simply enjoying time with friends, let the harmonious vibes elevate your mood and enhance your day.\r\n\r\nSavor the Experience\r\n\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of this exceptional strain. Thunder Bud combines convenience and quality, offering a sensory adventure that awakens the senses with every inhale. Each Thunder Bud Pre-Roll showcases a sleek and appealing design, featuring vibrant colors of finely ground small buds and trim, all adorned with sparkling trichomes, ensuring a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nDiscover the bliss of Thunder Bud Citral Glue <20> uplifting highs at an unbeatable price.\r\n\r\nHere<72>s to vibrant experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-CG-AZ1G', 'desc' => 'Thunder Bud Citral Glue <20> Elevate Your Vibes at an Incredible Price ?\r\n\r\nCitrusy Bliss\r\n\r\nThunder Bud Citral Glue is an enticing hybrid strain that combines vibrant energy with a touch of relaxation. With its delightful citrus aroma and hints of earthy sweetness, this strain offers a refreshing escape with every puff, making it perfect for any occasion.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from the finest trim and smalls, Citral Glue delivers a smooth and flavorful smoke that won<6F>t break the bank. Our meticulous grinding process ensures each puff is infused with rich flavors and balanced effects, providing the ideal blend of upliftment and calm.\r\n\r\nEnergize Your Spirit\r\n\r\nPerfect for daytime use, Citral Glue offers a euphoric high that clears the mind while relaxing the body. Whether you\'re diving into creative projects or simply enjoying time with friends, let the harmonious vibes elevate your mood and enhance your day.\r\n\r\nSavor the Experience\r\n\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of this exceptional strain. Thunder Bud combines convenience and quality, offering a sensory adventure that awakens the senses with every inhale. Each Thunder Bud Pre-Roll showcases a sleek and appealing design, featuring vibrant colors of finely ground small buds and trim, all adorned with sparkling trichomes, ensuring a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nDiscover the bliss of Thunder Bud Citral Glue <20> uplifting highs at an unbeatable price.\r\n\r\nHere<72>s to vibrant experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-CG-AZ3G', 'desc' => 'Thunder Bud Citral Glue <20> Elevate Your Vibes at an Incredible Price ?\r\n\r\nCitrusy Bliss\r\nThunder Bud Citral Glue is an enticing hybrid strain that combines vibrant energy with a touch of relaxation. With its delightful citrus aroma and hints of earthy sweetness, this strain offers a refreshing escape with every puff, making it perfect for any occasion.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Citral Glue delivers a smooth and flavorful smoke that won<6F>t break the bank. Our meticulous grinding process ensures each puff is infused with rich flavors and balanced effects, providing the ideal blend of upliftment and calm.\r\n\r\nEnergize Your Spirit\r\nPerfect for daytime use, Citral Glue offers a euphoric high that clears the mind while relaxing the body. Whether you\'re diving into creative projects or simply enjoying time with friends, let the harmonious vibes elevate your mood and enhance your day.\r\n\r\nSavor the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of this exceptional strain. Thunder Bud combines convenience and quality, offering a sensory adventure that awakens the senses with every inhale. Each Thunder Bud Pre-Roll showcases a sleek and appealing design, featuring vibrant colors of finely ground small buds and trim, all adorned with sparkling trichomes, ensuring a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nDiscover the bliss of Thunder Bud Citral Glue <20> uplifting highs at an unbeatable price.\r\n\r\nHere<72>s to vibrant experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-CG-AZ5G', 'desc' => 'Thunder Bud Citral Glue <20> Elevate Your Vibes at an Incredible Price ?\r\n\r\nCitrusy Bliss\r\nThunder Bud Citral Glue is an enticing hybrid strain that combines vibrant energy with a touch of relaxation. With its delightful citrus aroma and hints of earthy sweetness, this strain offers a refreshing escape with every puff, making it perfect for any occasion.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Citral Glue delivers a smooth and flavorful smoke that won<6F>t break the bank. Our meticulous grinding process ensures each puff is infused with rich flavors and balanced effects, providing the ideal blend of upliftment and calm.\r\n\r\nEnergize Your Spirit\r\nPerfect for daytime use, Citral Glue offers a euphoric high that clears the mind while relaxing the body. Whether you\'re diving into creative projects or simply enjoying time with friends, let the harmonious vibes elevate your mood and enhance your day.\r\n\r\nSavor the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of this exceptional strain. Thunder Bud combines convenience and quality, offering a sensory adventure that awakens the senses with every inhale. Each Thunder Bud Pre-Roll showcases a sleek and appealing design, featuring vibrant colors of finely ground small buds and trim, all adorned with sparkling trichomes, ensuring a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nDiscover the bliss of Thunder Bud Citral Glue <20> uplifting highs at an unbeatable price.\r\n\r\nHere<72>s to vibrant experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-CJ-AZ1G', 'desc' => 'Thunder Bud Cap Junky <20> Elevate Your Vibes at an Exceptional Price ?\r\n\r\nCaptivating Experience\r\n\r\nAmnesia Lemon Kush is a delightful sativa-dominant hybrid that combines uplifting energy with a burst of citrus flavor. Its refreshing lemon aroma, accented by hints of earthy undertones, offers a zesty escape that invigorates the senses with every puff.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, Cap Junky provides a smooth and satisfying smoke, perfect for unwinding after a long day. Our careful grinding process ensures that each puff is infused with rich flavors and calming effects, making it a great choice for any occasion.\r\n\r\nRelax and Unwind\r\n\r\nIdeal for both daytime and evening use, Cap Junky offers a balanced high that promotes relaxation while keeping your mind clear. Whether you<6F>re enjoying a cozy night in or catching up with friends, let the soothing vibes elevate your mood and enhance your experience.\r\n\r\nSavor the Journey\r\n\r\nIndulge in the rich experience of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of this distinctive strain. Thunder Bud combines convenience and quality, providing a sensory adventure that awakens the senses with every inhale. Each Thunder Bud Pre-Roll showcases a compact yet inviting appearance, featuring vibrant shades of finely ground small buds and trim, all adorned with sparkling trichomes, promising a delightful encounter with each draw.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nDiscover the bliss of Thunder Bud Cap Junky <20> harmonious highs at an unbeatable price.\r\n\r\nHere<72>s to relaxing experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-CJ-AZ3G', 'desc' => 'Thunder Bud Cap Junky <20> Elevate Your Vibes at an Exceptional Price ?\r\n\r\nCaptivating Experience\r\nAmnesia Lemon Kush is a delightful sativa-dominant hybrid that combines uplifting energy with a burst of citrus flavor. Its refreshing lemon aroma, accented by hints of earthy undertones, offers a zesty escape that invigorates the senses with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Cap Junky provides a smooth and satisfying smoke, perfect for unwinding after a long day. Our careful grinding process ensures that each puff is infused with rich flavors and calming effects, making it a great choice for any occasion.\r\n\r\nRelax and Unwind\r\nIdeal for both daytime and evening use, Cap Junky offers a balanced high that promotes relaxation while keeping your mind clear. Whether you<6F>re enjoying a cozy night in or catching up with friends, let the soothing vibes elevate your mood and enhance your experience.\r\n\r\nSavor the Journey\r\nIndulge in the rich experience of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of this distinctive strain. Thunder Bud combines convenience and quality, providing a sensory adventure that awakens the senses with every inhale. Each Thunder Bud Pre-Roll showcases a compact yet inviting appearance, featuring vibrant shades of finely ground small buds and trim, all adorned with sparkling trichomes, promising a delightful encounter with each draw.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nDiscover the bliss of Thunder Bud Cap Junky <20> harmonious highs at an unbeatable price.\r\n\r\nHere<72>s to relaxing experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-CO-AZ1G', 'desc' => 'Citrus Octane <20> Unwind in Comfort with Smooth, Relaxing Vibes ?Relaxation with a Citrus Twist\r\n\r\nCitrus Octane is a soothing indica-dominant hybrid that offers a perfect blend of relaxation and refreshing citrus flavor. The crisp orange aroma, with hints of earthy undertones and a subtle diesel kick, creates a calming yet flavorful experience that will ease both your mind and body with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Citrus Octane delivers a smooth, relaxing smoke that<61>s perfect for winding down after a long day. Our precise grinding process ensures each puff is rich in vibrant, citrusy flavors with soothing effects, making it an ideal choice for those seeking stress relief and relaxation without the hefty price tag.\r\n\r\nRelax and Unwind\r\nDesigned for evening enjoyment, Citrus Octane offers a deep, calming high that melts away tension and promotes restful relaxation. Its gentle euphoria helps you unwind, making it the perfect companion for quiet evenings, movie nights, or reflective moments. Let the serene vibes settle your mind and ease your body into a state of tranquility.\r\n\r\nSavor the Experience\r\nIndulge in the refreshing experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to encapsulate the essence of this invigorating strain. Thunder Bud seamlessly blends convenience and quality, offering a sensory adventure that awakens the palate with each draw. Each pre-roll showcases a compact, enticing appearance, featuring rich, vibrant hues of finely ground small buds and trim, all adorned with shimmering trichomes, promising a delightful encounter with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nEnd your day the right way with Citrus Octane<6E>smooth, relaxing vibes at an unbeatable price.\r\n\r\nHere<72>s to peaceful moments and restful nights, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-CP-AZ1G', 'desc' => 'Cherry Pie <20> Sweet Balance at an Unbeatable Price ??\r\n\r\nA Dessert-Inspired Delight\r\nCherry Pie is a balanced hybrid that perfectly blends soothing relaxation with a gentle uplift. Its mouthwatering mix of sweet, tart cherries and warm pastry undertones creates a flavorful experience that<61>s both comforting and refreshing. Each puff delivers smooth, dessert-like sweetness with a hint of euphoria that satisfies body and mind alike.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Cherry Pie brings you a smooth, flavorful smoke that delivers big on quality without the big price tag. Thunder Bud<75>s careful grinding process ensures every pre-roll is packed with terpene-rich buds and trim, offering consistency, flavor, and potency in every session.\r\n\r\nBalanced Bliss\r\nCherry Pie provides the perfect middle ground between relaxation and motivation. Its effects start with a pleasant mental uplift before easing into a warm, mellow body high. Ideal for any time of day, this hybrid helps melt away stress while keeping your mood bright and your mind clear.\r\n\r\nSavor the Experience\r\nEnjoy the decadent aroma and taste of Thunder Bud Trim+Smalls Pre-Rolls, crafted to preserve Cherry Pie<69>s signature sweetness and smooth finish. Each pre-roll features finely ground small buds and resin-rich trim, ensuring a flavorful, even burn that highlights every note of this classic strain.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s eco-conscious packaging lets you indulge in premium cannabis while staying kind to the planet. ?\r\n\r\nSatisfy your senses with Cherry Pie <20> balanced, flavorful highs at an unbeatable price.\r\nHere<72>s to sweet moments, mellow moods, and premium quality that keeps you smiling. ??'],
|
||||
['sku' => 'TB-CUC-AZ1G', 'desc' => 'Cuban Cigar <20> Smooth Power at an Unbeatable Price ??\r\n\r\nA Bold Escape into Balance\r\nCuban Cigar is a perfectly balanced hybrid that delivers the rich, classic experience its name promises. With deep, earthy notes of spice, wood, and a hint of sweetness, this strain evokes the smooth sophistication of a fine cigar. Expect a full-bodied flavor that wraps your senses in calm while sparking a clear, uplifted mindset that keeps you grounded yet inspired.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Cuban Cigar offers a robust, flavorful smoke that satisfies without stretching your wallet. Thunder Bud<75>s precise grinding process ensures each pre-roll is evenly packed and terpene-rich, providing consistent, potent hits that rival boutique strains in both quality and smoothness.\r\n\r\nFind Your Rhythm\r\nIdeal for late afternoons or mellow evenings, Cuban Cigar delivers a balanced high that relaxes the body while keeping your thoughts sharp and focused. The experience is smooth, warm, and steady, perfect for those who want the best of both worlds<64>a calm body and a clear mind.\r\n\r\nSavor the Experience\r\nThunder Bud Trim+Smalls Pre-Rolls capture the bold, refined flavor of Cuban Cigar with expert care. Each pre-roll features finely ground small buds and resin-rich trim, offering a slow, even burn that brings out the strain<69>s complex profile from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s dedication to eco-friendly packaging means you can enjoy premium cannabis while helping protect the planet. ?\r\n\r\nLight up with Cuban Cigar <20> rich, balanced highs at an unbeatable price.\r\nHere<72>s to smooth sessions, steady vibes, and timeless flavor every time you spark up. ??'],
|
||||
['sku' => 'TB-DAE-AZ1G', 'desc' => 'Thunder Bud Drippin\' Ain\'t Easy <20> Legendary Highs, Smart Price ?\r\n\r\nIconic Experience\r\nThunder Bud Drippin\' Ain\'t Easy is a remarkable hybrid strain celebrated for its potent effects and distinctive flavor profile. Named for its smooth, dripping flavor, this strain combines sweet, fruity notes with a hint of spicy and earthy undertones, creating an unforgettable smoking experience.\r\n\r\nBig Highs, Small Price\r\nCrafted from top-grade trim and smalls, Drippin\' Ain\'t Easy offers a smooth, impactful smoke that excels in both flavor and effect. Our precise grinding process ensures a premium experience without the high cost, delivering exceptional value and quality.\r\n\r\nEuphoric and Relaxing\r\nPerfect for any time of day, Drippin\' Ain\'t Easy provides a balanced, euphoric high that promotes relaxation and creativity. Whether you\'re tackling tasks or unwinding after a long day, this strain is versatile enough for any occasion, delivering a refreshing and uplifting experience.\r\n\r\nIndulge in the Drip\r\nImmerse yourself in the exceptional quality of Thunder Bud Trim+Smalls Pre-Rolls, designed to capture the essence of each strain with precision. Thunder Bud combines convenience with excellence, offering a sensory journey that invigorates with every puff. Each pre-roll is expertly crafted, featuring finely ground small buds and trim encased in premium rolling paper. The pre-rolls showcase a sleek, appealing appearance, with rich, earthy tones and sparkling trichomes that signal a potent and satisfying smoke.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nCheers to unforgettable highs at a smart price! ?'],
|
||||
['sku' => 'TB-DAE-AZ3G', 'desc' => 'Thunder Bud Drippin\' Ain\'t Easy <20> Legendary Highs, Smart Price ?\r\n\r\nIconic Experience\r\nThunder Bud Drippin\' Ain\'t Easy is a remarkable hybrid strain celebrated for its potent effects and distinctive flavor profile. Named for its smooth, dripping flavor, this strain combines sweet, fruity notes with a hint of spicy and earthy undertones, creating an unforgettable smoking experience.\r\n\r\nBig Highs, Small Price\r\nCrafted from top-grade trim and smalls, Drippin\' Ain\'t Easy offers a smooth, impactful smoke that excels in both flavor and effect. Our precise grinding process ensures a premium experience without the high cost, delivering exceptional value and quality.\r\n\r\nEuphoric and Relaxing\r\nPerfect for any time of day, Drippin\' Ain\'t Easy provides a balanced, euphoric high that promotes relaxation and creativity. Whether you\'re tackling tasks or unwinding after a long day, this strain is versatile enough for any occasion, delivering a refreshing and uplifting experience.\r\n\r\nIndulge in the Drip\r\nImmerse yourself in the exceptional quality of Thunder Bud Trim+Smalls Pre-Rolls, designed to capture the essence of each strain with precision. Thunder Bud combines convenience with excellence, offering a sensory journey that invigorates with every puff. Each pre-roll is expertly crafted, featuring finely ground small buds and trim encased in premium rolling paper. The pre-rolls showcase a sleek, appealing appearance, with rich, earthy tones and sparkling trichomes that signal a potent and satisfying smoke.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nCheers to unforgettable highs at a smart price! ?'],
|
||||
['sku' => 'TB-DAE-AZ5G', 'desc' => 'Thunder Bud Drippin\' Ain\'t Easy <20> Legendary Highs, Smart Price ?\r\n\r\nIconic Experience\r\nThunder Bud Drippin\' Ain\'t Easy is a remarkable hybrid strain celebrated for its potent effects and distinctive flavor profile. Named for its smooth, dripping flavor, this strain combines sweet, fruity notes with a hint of spicy and earthy undertones, creating an unforgettable smoking experience.\r\n\r\nBig Highs, Small Price\r\nCrafted from top-grade trim and smalls, Drippin\' Ain\'t Easy offers a smooth, impactful smoke that excels in both flavor and effect. Our precise grinding process ensures a premium experience without the high cost, delivering exceptional value and quality.\r\n\r\nEuphoric and Relaxing\r\nPerfect for any time of day, Drippin\' Ain\'t Easy provides a balanced, euphoric high that promotes relaxation and creativity. Whether you\'re tackling tasks or unwinding after a long day, this strain is versatile enough for any occasion, delivering a refreshing and uplifting experience.\r\n\r\nIndulge in the Drip\r\nImmerse yourself in the exceptional quality of Thunder Bud Trim+Smalls Pre-Rolls, designed to capture the essence of each strain with precision. Thunder Bud combines convenience with excellence, offering a sensory journey that invigorates with every puff. Each pre-roll is expertly crafted, featuring finely ground small buds and trim encased in premium rolling paper. The pre-rolls showcase a sleek, appealing appearance, with rich, earthy tones and sparkling trichomes that signal a potent and satisfying smoke.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nCheers to unforgettable highs at a smart price! ?'],
|
||||
['sku' => 'TB-DC-AZ1G', 'desc' => 'Delicata Cookies <20> Melt Into Comfort at an Unbeatable Price ??\r\n\r\nA Sweet Escape into Serenity\r\nDelicata Cookies is a decadent indica-dominant hybrid that delivers pure comfort with every puff. Rich aromas of vanilla frosting, sweet dough, and a hint of earthy spice create a dessert-like experience that soothes both body and mind. This flavorful strain invites you to unwind, slow down, and savor a smooth, calming high that melts away tension and wraps you in cozy bliss.\r\n\r\nBig Highs, Small Price\r\nMade from premium trim and smalls, Delicata Cookies offers boutique-grade flavor and potency without the boutique cost. Thunder Bud<75>s precise grinding process ensures that each pre-roll is evenly packed and terpene-rich, delivering consistent, satisfying hits that balance flavor, potency, and smoothness in every session.\r\n\r\nRelax Your Spirit\r\nPerfect for evening indulgence or peaceful weekends, Delicata Cookies offers a deeply relaxing body high paired with a soft, euphoric lift that keeps your mood light and pleasant. Let its mellow effects ease you into your favorite chill spot, helping you unwind and recharge without feeling weighed down.\r\n\r\nSavor the Experience\r\nThunder Bud Trim+Smalls Pre-Rolls preserve the delicious flavor and creamy aroma of Delicata Cookies through expert craftsmanship. Each pre-roll features finely ground small buds and resin-rich trim, creating a slow, smooth burn that highlights the strain<69>s rich dessert profile from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s commitment to sustainable packaging lets you enjoy premium cannabis while caring for the planet. ?\r\n\r\nUnwind with Delicata Cookies <20> sweet, soothing highs at an unbeatable price.\r\nHere<72>s to cozy nights, sweet vibes, and full flavor without breaking the bank. ?'],
|
||||
['sku' => 'TB-DD-AZ1G', 'desc' => 'Thunder Bud Duncan Dandy <20> Delightful Vibes at a Great Price ?\r\n\r\nMorning Bliss\r\nThunder Bud Duncan Dandy is a delightful hybrid strain that adds a sweet touch to your day. With its rich coffee and creamy vanilla aroma, this strain offers a cozy escape with every puff, perfect for those who enjoy a smooth, flavorful experience.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Duncan Dandy delivers a smooth, satisfying smoke that<61>s ideal for any time of day. Our precise grinding process ensures each puff bursts with rich flavors and balanced effects, all at an unbeatable price.\r\n\r\nEnergizing and Comforting\r\nPerfect for morning routines or afternoon breaks, Duncan Dandy provides an uplifting yet relaxing high that enhances focus and creativity. Let the delightful flavors lift your spirits and invigorate your day.\r\n\r\nImmerse in the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that awakens the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The warm, inviting tones of finely ground small buds and trim are highlighted by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Duncan Dandy <20> delightful vibes at an affordable price.\r\n\r\nCheers to cozy moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-DD-AZ3G', 'desc' => 'Thunder Bud Duncan Dandy <20> Delightful Vibes at a Great Price ?\r\n\r\nMorning Bliss\r\nThunder Bud Duncan Dandy is a delightful hybrid strain that adds a sweet touch to your day. With its rich coffee and creamy vanilla aroma, this strain offers a cozy escape with every puff, perfect for those who enjoy a smooth, flavorful experience.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Duncan Dandy delivers a smooth, satisfying smoke that<61>s ideal for any time of day. Our precise grinding process ensures each puff bursts with rich flavors and balanced effects, all at an unbeatable price.\r\n\r\nEnergizing and Comforting\r\nPerfect for morning routines or afternoon breaks, Duncan Dandy provides an uplifting yet relaxing high that enhances focus and creativity. Let the delightful flavors lift your spirits and invigorate your day.\r\n\r\nImmerse in the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that awakens the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The warm, inviting tones of finely ground small buds and trim are highlighted by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Duncan Dandy <20> delightful vibes at an affordable price.\r\n\r\nCheers to cozy moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-DD-AZ5G', 'desc' => 'Thunder Bud Duncan Dandy <20> Delightful Vibes at a Great Price ?\r\n\r\nMorning Bliss\r\nThunder Bud Duncan Dandy is a delightful hybrid strain that adds a sweet touch to your day. With its rich coffee and creamy vanilla aroma, this strain offers a cozy escape with every puff, perfect for those who enjoy a smooth, flavorful experience.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Duncan Dandy delivers a smooth, satisfying smoke that<61>s ideal for any time of day. Our precise grinding process ensures each puff bursts with rich flavors and balanced effects, all at an unbeatable price.\r\n\r\nEnergizing and Comforting\r\nPerfect for morning routines or afternoon breaks, Duncan Dandy provides an uplifting yet relaxing high that enhances focus and creativity. Let the delightful flavors lift your spirits and invigorate your day.\r\n\r\nImmerse in the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that awakens the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The warm, inviting tones of finely ground small buds and trim are highlighted by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Duncan Dandy <20> delightful vibes at an affordable price.\r\n\r\nCheers to cozy moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-DD-PP-AZ28G', 'desc' => 'Thunder Bud Duncan Dandy <20> Delightful Vibes at a Great Price ?\r\n\r\nMorning Bliss\r\n\r\nThunder Bud Duncan Dandy is a delightful hybrid strain that adds a sweet touch to your day. With its rich coffee and creamy vanilla aroma, this strain offers a cozy escape with every puff, perfect for those who enjoy a smooth, flavorful experience.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from the finest trim and smalls, Duncan Dandy delivers a smooth, satisfying smoke that<61>s ideal for any time of day. Our precise grinding process ensures each puff bursts with rich flavors and balanced effects, all at an unbeatable price.\r\n\r\nEnergizing and Comforting\r\n\r\nPerfect for morning routines or afternoon breaks, Duncan Dandy provides an uplifting yet relaxing high that enhances focus and creativity. Let the delightful flavors lift your spirits and invigorate your day.\r\n\r\nImmerse in the Experience\r\n\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that awakens the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The warm, inviting tones of finely ground small buds and trim are highlighted by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Duncan Dandy <20> delightful vibes at an affordable price.\r\n\r\nCheers to cozy moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-DDU-AZ1G', 'desc' => 'Thunder Bud Dulce de Uva <20> Sweet Vibes at a Great Price ?\r\n\r\nFruity Indulgence\r\nThunder Bud Dulce de Uva is a delectable indica-dominant hybrid strain that adds a touch of sweetness to your day. With its rich grape aroma and hints of sugary berries, this strain offers a delightful escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Dulce de Uva delivers a smooth, enjoyable smoke that<61>s perfect for winding down. Our precise grinding process ensures each puff bursts with fruity flavors and soothing effects, all at an unbeatable price.\r\n\r\nRelaxing and Uplifting\r\nIdeal for cozy evenings or social gatherings, Dulce de Uva provides a calming yet uplifting high that enhances your mood and creativity. Let the sweet vibes wrap you in comfort as you unwind and enjoy the moment.\r\n\r\nImmerse in the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that excites the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The vibrant hues of finely ground small buds and trim are beautifully complemented by glistening trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Dulce de Uva <20> sweet vibes at an affordable price.\r\n\r\nCheers to delightful moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-DDU-AZ3G', 'desc' => 'Thunder Bud Dulce de Uva <20> Sweet Vibes at a Great Price ?\r\n\r\nFruity Indulgence\r\nThunder Bud Dulce de Uva is a delectable indica-dominant hybrid strain that adds a touch of sweetness to your day. With its rich grape aroma and hints of sugary berries, this strain offers a delightful escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Dulce de Uva delivers a smooth, enjoyable smoke that<61>s perfect for winding down. Our precise grinding process ensures each puff bursts with fruity flavors and soothing effects, all at an unbeatable price.\r\n\r\nRelaxing and Uplifting\r\nIdeal for cozy evenings or social gatherings, Dulce de Uva provides a calming yet uplifting high that enhances your mood and creativity. Let the sweet vibes wrap you in comfort as you unwind and enjoy the moment.\r\n\r\nImmerse in the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that excites the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The vibrant hues of finely ground small buds and trim are beautifully complemented by glistening trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Dulce de Uva <20> sweet vibes at an affordable price.\r\n\r\nCheers to delightful moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-DDU-AZ5G', 'desc' => 'Thunder Bud Dulce de Uva <20> Sweet Vibes at a Great Price ?\r\n\r\nFruity Indulgence\r\nThunder Bud Dulce de Uva is a delectable indica-dominant hybrid strain that adds a touch of sweetness to your day. With its rich grape aroma and hints of sugary berries, this strain offers a delightful escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Dulce de Uva delivers a smooth, enjoyable smoke that<61>s perfect for winding down. Our precise grinding process ensures each puff bursts with fruity flavors and soothing effects, all at an unbeatable price.\r\n\r\nRelaxing and Uplifting\r\nIdeal for cozy evenings or social gatherings, Dulce de Uva provides a calming yet uplifting high that enhances your mood and creativity. Let the sweet vibes wrap you in comfort as you unwind and enjoy the moment.\r\n\r\nImmerse in the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that excites the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The vibrant hues of finely ground small buds and trim are beautifully complemented by glistening trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Dulce de Uva <20> sweet vibes at an affordable price.\r\n\r\nCheers to delightful moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-DDU-PP-AZ28G', 'desc' => 'Thunder Bud Dulce de Uva <20> Sweet Vibes at a Great Price ?\r\n\r\nFruity Indulgence\r\n\r\nThunder Bud Dulce de Uva is a delectable indica-dominant hybrid strain that adds a touch of sweetness to your day. With its rich grape aroma and hints of sugary berries, this strain offers a delightful escape with every puff.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from the finest trim and smalls, Dulce de Uva delivers a smooth, enjoyable smoke that<61>s perfect for winding down. Our precise grinding process ensures each puff bursts with fruity flavors and soothing effects, all at an unbeatable price.\r\n\r\nRelaxing and Uplifting\r\n\r\nIdeal for cozy evenings or social gatherings, Dulce de Uva provides a calming yet uplifting high that enhances your mood and creativity. Let the sweet vibes wrap you in comfort as you unwind and enjoy the moment.\r\n\r\nImmerse in the Experience\r\n\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that excites the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The vibrant hues of finely ground small buds and trim are beautifully complemented by glistening trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Dulce de Uva <20> sweet vibes at an affordable price.\r\n\r\nCheers to delightful moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-DI-AZ1G', 'desc' => 'Thunder Bud Dante\'s Inferno <20> Fiery Vibes at a Great Price ?\r\n\r\nBold Escape\r\nThunder Bud Dante\'s Inferno is a captivating hybrid strain that brings a unique experience to your day. With its rich earthy aroma and hints of spicy sweetness, this strain offers a soothing escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Dante\'s Inferno delivers a smooth, satisfying smoke that<61>s perfect for any occasion. Our precise grinding process ensures each puff is packed with bold flavors and balanced effects, all at an unbeatable price.\r\n\r\nRelaxing and Uplifting\r\nIdeal for both winding down and sparking creativity, Dante\'s Inferno provides a calming yet uplifting high that melts away stress. Perfect for cozy evenings or social gatherings, this strain enhances your mood and invites a sense of tranquility.\r\n\r\nImmerse in the Experience\r\nIndulge in the mesmerizing journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that delights the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The deep, rich colors of finely ground small buds and trim are highlighted by glistening trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Dante\'s Inferno <20> fiery vibes at an affordable price.\r\n\r\nCheers to enjoyable moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-DI-AZ3G', 'desc' => 'Thunder Bud Dante\'s Inferno <20> Fiery Vibes at a Great Price ?\r\n\r\nBold Escape\r\nThunder Bud Dante\'s Inferno is a captivating hybrid strain that brings a unique experience to your day. With its rich earthy aroma and hints of spicy sweetness, this strain offers a soothing escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Dante\'s Inferno delivers a smooth, satisfying smoke that<61>s perfect for any occasion. Our precise grinding process ensures each puff is packed with bold flavors and balanced effects, all at an unbeatable price.\r\n\r\nRelaxing and Uplifting\r\nIdeal for both winding down and sparking creativity, Dante\'s Inferno provides a calming yet uplifting high that melts away stress. Perfect for cozy evenings or social gatherings, this strain enhances your mood and invites a sense of tranquility.\r\n\r\nImmerse in the Experience\r\nIndulge in the mesmerizing journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that delights the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The deep, rich colors of finely ground small buds and trim are highlighted by glistening trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Dante\'s Inferno <20> fiery vibes at an affordable price.\r\n\r\nCheers to enjoyable moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-DI-AZ5G', 'desc' => 'Thunder Bud Dante\'s Inferno <20> Fiery Vibes at a Great Price ?\r\n\r\nBold Escape\r\nThunder Bud Dante\'s Inferno is a captivating hybrid strain that brings a unique experience to your day. With its rich earthy aroma and hints of spicy sweetness, this strain offers a soothing escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Dante\'s Inferno delivers a smooth, satisfying smoke that<61>s perfect for any occasion. Our precise grinding process ensures each puff is packed with bold flavors and balanced effects, all at an unbeatable price.\r\n\r\nRelaxing and Uplifting\r\nIdeal for both winding down and sparking creativity, Dante\'s Inferno provides a calming yet uplifting high that melts away stress. Perfect for cozy evenings or social gatherings, this strain enhances your mood and invites a sense of tranquility.\r\n\r\nImmerse in the Experience\r\nIndulge in the mesmerizing journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that delights the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The deep, rich colors of finely ground small buds and trim are highlighted by glistening trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Dante\'s Inferno <20> fiery vibes at an affordable price.\r\n\r\nCheers to enjoyable moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-DW-TS', 'desc' => 'Lather Up with The Soap <20> Supreme Strain Experience at a Smart Price ?\r\n\r\nAll-Star Clean\r\nThe Soap is a standout hybrid strain known for its signature effects and distinctive flavor profile. Named for its clean, refreshing taste and potent high, this strain offers a delightful blend of zesty citrus, sweet herbal notes, and subtle earthy undertones.\r\n\r\nSupreme Effects, Smart Price\r\nCrafted from top-tier trim and smalls, The Soap delivers a smooth and powerful smoke that shines in both flavor and impact. Our careful grinding process ensures a high-quality experience without breaking the bank, providing premium effects at an accessible price.\r\n\r\nEuphoric and Uplifting\r\nPerfect for any moment, The Soap delivers an energetic, euphoric high that enhances mood and creativity. Whether you\'re tackling tasks or winding down, this strain is ideal for any occasion, delivering a refreshing and invigorating experience.\r\n\r\nIndulge in the Clean Experience\r\nImmerse yourself in the exceptional quality of Thunder Bud Trim+Smalls Pre-Rolls, designed to capture the essence of each strain with precision. Thunder Bud combines convenience with excellence, offering a sensory journey that energizes with every puff. Each pre-roll is expertly crafted, featuring fine, evenly ground small buds and trim encased in premium rolling paper. The rich, inviting colors and the glistening trichomes signal a potent and satisfying smoke.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with The Soap from Thunder Bud <20> exceptional highs at a smart price.\r\n\r\nCheers to a cleaner, more enjoyable high! ?'],
|
||||
['sku' => 'TB-F95-AZ1G', 'desc' => 'Fam 95 <20> Energize Your Day at an Unbeatable Price ??\r\n\r\nClassic Uplift Awaits\r\n\r\nFam 95 is a vibrant sativa dominant hybrid that channels old-school genetics into a lively, energizing experience. Bursting with classic skunky aromas, hints of earthy spice, and a touch of diesel, this strain offers a bold yet refreshing profile that awakens the senses and fuels the mind.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, Fam 95 delivers a smooth, flavorful smoke that<61>s perfect for busy days or creative sessions. Thanks to Thunder Bud<75>s precise grinding process, every puff is packed with potent, terpene rich flavor bringing you big energy without the big price tag.\r\n\r\nIgnite Your Spirit\r\n\r\nPerfect for daytime adventures, brainstorming sessions, or social gatherings, Fam 95 delivers a clear-headed, euphoric high that keeps you motivated and upbeat. Let the invigorating effects inspire your next project, conversation, or journey.\r\n\r\nSavor the Experience\r\n\r\nDive into the bold, classic character of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to highlight Fam 95<39>s legendary lineage. Each pre-roll features finely ground small buds and resin-rich trim, offering a smooth, dense smoke that\'s rich with nostalgic flavor and lively effects.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s eco-friendly packaging ensures that you can enjoy your favorite strains while supporting a healthier planet. ?\r\n\r\nFuel your day with Fam 95, nostalgic energy and bright highs at an unbeatable price.\r\n\r\nHere<72>s to bold days and great vibes, all while keeping your wallet happy!'],
|
||||
['sku' => 'TB-FB-AZ1G', 'desc' => 'Thunder Bud Frankenberry <20> Monster Hits, Bite-Sized Price ??\r\n\r\nFreaky Fresh Experience\r\nThunder Bud Frankenberry is a delightful hybrid strain that pays homage to the whimsical charm of classic horror. This strain is known for its potent effects and unique flavor profile, featuring a blend of sweet berry, earthy undertones, and a hint of spicy herbal notes.\r\n\r\nMonster Hits, Bite-Sized Price\r\nCrafted from premium trim and smalls, Frankenberry offers a smooth, robust smoke that excels in both flavor and effect. Our precise grinding process ensures a high-quality experience without the hefty price tag.\r\n\r\nSweet and Euphoric\r\nPerfect for any time of day, Frankenberry delivers an uplifting and euphoric high that enhances mood and creativity. Whether you<6F>re embarking on an adventure or relaxing at home, this strain is a versatile choice for any occasion.\r\n\r\nSavor the Experience\r\nImmerse yourself in the thrilling experience of Thunder Bud Trim+Smalls Pre-Rolls, designed to capture the essence of each strain. Thunder Bud brings together convenience and quality, offering a sensory journey that tantalizes with every puff. Each Thunder Bud Pre-Roll is a masterpiece of precision and skill. Encased in premium rolling paper, these pre-rolls showcase a compact yet enticing appearance. The vibrant, berry-colored hues of finely ground small buds and trim are highlighted by glistening trichomes, promising a potent and enjoyable smoke with each inhale.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your sessions with Thunder Bud Frankenberry <20> monster hits at a bite-sized price.\r\n\r\nCheers to extraordinary flavors and sensational highs! ??'],
|
||||
['sku' => 'TB-FB-AZ3G', 'desc' => 'Thunder Bud Frankenberry <20> Monster Hits, Bite-Sized Price ??\r\n\r\nFreaky Fresh Experience\r\nThunder Bud Frankenberry is a delightful hybrid strain that pays homage to the whimsical charm of classic horror. This strain is known for its potent effects and unique flavor profile, featuring a blend of sweet berry, earthy undertones, and a hint of spicy herbal notes.\r\n\r\nMonster Hits, Bite-Sized Price\r\nCrafted from premium trim and smalls, Frankenberry offers a smooth, robust smoke that excels in both flavor and effect. Our precise grinding process ensures a high-quality experience without the hefty price tag.\r\n\r\nSweet and Euphoric\r\nPerfect for any time of day, Frankenberry delivers an uplifting and euphoric high that enhances mood and creativity. Whether you<6F>re embarking on an adventure or relaxing at home, this strain is a versatile choice for any occasion.\r\n\r\nSavor the Experience\r\nImmerse yourself in the thrilling experience of Thunder Bud Trim+Smalls Pre-Rolls, designed to capture the essence of each strain. Thunder Bud brings together convenience and quality, offering a sensory journey that tantalizes with every puff. Each Thunder Bud Pre-Roll is a masterpiece of precision and skill. Encased in premium rolling paper, these pre-rolls showcase a compact yet enticing appearance. The vibrant, berry-colored hues of finely ground small buds and trim are highlighted by glistening trichomes, promising a potent and enjoyable smoke with each inhale.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your sessions with Thunder Bud Frankenberry <20> monster hits at a bite-sized price.\r\n\r\nCheers to extraordinary flavors and sensational highs! ??'],
|
||||
['sku' => 'TB-FB-AZ5G', 'desc' => 'Thunder Bud Frankenberry <20> Monster Hits, Bite-Sized Price ??\r\n\r\nFreaky Fresh Experience\r\nThunder Bud Frankenberry is a delightful hybrid strain that pays homage to the whimsical charm of classic horror. This strain is known for its potent effects and unique flavor profile, featuring a blend of sweet berry, earthy undertones, and a hint of spicy herbal notes.\r\n\r\nMonster Hits, Bite-Sized Price\r\nCrafted from premium trim and smalls, Frankenberry offers a smooth, robust smoke that excels in both flavor and effect. Our precise grinding process ensures a high-quality experience without the hefty price tag.\r\n\r\nSweet and Euphoric\r\nPerfect for any time of day, Frankenberry delivers an uplifting and euphoric high that enhances mood and creativity. Whether you<6F>re embarking on an adventure or relaxing at home, this strain is a versatile choice for any occasion.\r\n\r\nSavor the Experience\r\nImmerse yourself in the thrilling experience of Thunder Bud Trim+Smalls Pre-Rolls, designed to capture the essence of each strain. Thunder Bud brings together convenience and quality, offering a sensory journey that tantalizes with every puff. Each Thunder Bud Pre-Roll is a masterpiece of precision and skill. Encased in premium rolling paper, these pre-rolls showcase a compact yet enticing appearance. The vibrant, berry-colored hues of finely ground small buds and trim are highlighted by glistening trichomes, promising a potent and enjoyable smoke with each inhale.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your sessions with Thunder Bud Frankenberry <20> monster hits at a bite-sized price.\r\n\r\nCheers to extraordinary flavors and sensational highs! ??'],
|
||||
['sku' => 'TB-GC-AZ1G', 'desc' => 'Thunder Bud - Garlic Cocktail ?\r\n\r\nBig Highs, Small Price \r\nReady to Shake Things Up? Thunder Bud Garlic Cocktail adds a zing to your evenings! This hybrid strain is a savory sensation that<61>ll leave your taste buds tingling and your body melting into the ultimate chill.\r\n\r\nBig Highs, Small Price\r\nAt Thunder Bud, we believe you don<6F>t have to sacrifice quality for price. Crafted from the finest trim and smalls, Thunder Bud Garlic Cocktail delivers a smooth, enjoyable smoke that<61>s downright delicious. Our secret? The way we grind makes it taste divine. Every puff is packed with flavor and a high that<61>ll have you coming back for more <20> without emptying your wallet.\r\nAccessible to Everyone\r\nWhether you<6F>re a seasoned smoker or a newcomer, Thunder Bud offers premium highs at budget-friendly prices, making it easy for anyone to enjoy quality pre-rolls.\r\n\r\nHomegrown Goodness\r\nFrom the sun-soaked fields of Arizona, Thunder Bud Garlic Cocktail is as local as it gets. Our dedicated growers, deeply connected to the land, cultivate this hybrid strain with care and respect. These Arizonans don<6F>t just grow cannabis; they nurture a tradition of relaxing, high-quality vibes.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging is as kind to the Earth as it is to your high, ensuring your smoke session leaves a minimal footprint. ?\r\n\r\nUnforgettable Flavor and Aroma\r\nGet ready for a garlic twist that<61>s as bold as it is unique. Each toke is a tantalizing tango of flavors, turning your smoking experience into a flavorful fiesta. Expect a blend of citrus, orange, and cheesy notes that dance on your palate, making each puff an aromatic delight.\r\n\r\nEffects\r\nGarlic Cocktail provides a euphoric and giggly high, perfect for lifting your mood and melting away stress. Users report feeling happy and relaxed, making it ideal for both social gatherings and cozy nights in. It also helps with anxiety, depression, and inflammation, offering a well-rounded experience.\r\n\r\nReliable Satisfaction\r\nJust like your favorite fast food joint, Thunder Bud is always there when you need it. Our Garlic Cocktail is perfect for a cozy night in or spicing up a social scene. Consistent quality, amazing taste, and a high that hits the spot every time.\r\n\r\nSo, whether you<6F>re lounging on the couch or lighting up the party, Thunder Bud Garlic Cocktail is your go-to for a high-flying, flavor-packed adventure. Light up, relax, and enjoy the smooth, savory flavors that make Thunder Bud a trusted favorite.\r\n\r\nCheers to big highs at a small price! ??'],
|
||||
['sku' => 'TB-GC-AZ3G', 'desc' => 'Thunder Bud - Garlic Cocktail ?\r\n\r\nReady to Shake Things Up? Thunder Bud Garlic Cocktail adds a zing to your evenings! This hybrid strain is a savory sensation that<61>ll leave your taste buds tingling and your body melting into the ultimate chill.\r\n\r\nBig Highs, Small Price\r\nAt Thunder Bud, we believe you don<6F>t have to sacrifice quality for price. Crafted from the finest trim and smalls, Thunder Bud Garlic Cocktail delivers a smooth, enjoyable smoke that<61>s downright delicious. Our secret? The way we grind makes it taste divine. Every puff is packed with flavor and a high that<61>ll have you coming back for more <20> without emptying your wallet.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging is as kind to the Earth as it is to your high, ensuring your smoke session leaves a minimal footprint. ?\r\n\r\nUnforgettable Flavor and Aroma\r\nGet ready for a garlic twist that<61>s as bold as it is unique. Each toke is a tantalizing tango of flavors, turning your smoking experience into a flavorful fiesta. Expect a blend of citrus, orange, and cheesy notes that dance on your palate, making each puff an aromatic delight.\r\n\r\nEffects\r\nGarlic Cocktail provides a euphoric and giggly high, perfect for lifting your mood and melting away stress. Users report feeling happy and relaxed, making it ideal for both social gatherings and cozy nights in. It also helps with anxiety, depression, and inflammation, offering a well-rounded experience.\r\n\r\nReliable Satisfaction\r\nJust like your favorite fast food joint, Thunder Bud is always there when you need it. Our Garlic Cocktail is perfect for a cozy night in or spicing up a social scene. Consistent quality, amazing taste, and a high that hits the spot every time.\r\n\r\nSo, whether you<6F>re lounging on the couch or lighting up the party, Thunder Bud Garlic Cocktail is your go-to for a high-flying, flavor-packed adventure. Light up, relax, and enjoy the smooth, savory flavors that make Thunder Bud a trusted favorite.\r\n\r\nCheers to big highs at a small price! ??'],
|
||||
['sku' => 'TB-GC-AZ3G', 'desc' => 'Thunder Bud - Garlic Cocktail ?\r\n\r\nReady to Shake Things Up? Thunder Bud Garlic Cocktail adds a zing to your evenings! This hybrid strain is a savory sensation that<61>ll leave your taste buds tingling and your body melting into the ultimate chill.\r\n\r\nBig Highs, Small Price\r\nAt Thunder Bud, we believe you don<6F>t have to sacrifice quality for price. Crafted from the finest trim and smalls, Thunder Bud Garlic Cocktail delivers a smooth, enjoyable smoke that<61>s downright delicious. Our secret? The way we grind makes it taste divine. Every puff is packed with flavor and a high that<61>ll have you coming back for more <20> without emptying your wallet.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging is as kind to the Earth as it is to your high, ensuring your smoke session leaves a minimal footprint. ?\r\n\r\nUnforgettable Flavor and Aroma\r\nGet ready for a garlic twist that<61>s as bold as it is unique. Each toke is a tantalizing tango of flavors, turning your smoking experience into a flavorful fiesta. Expect a blend of citrus, orange, and cheesy notes that dance on your palate, making each puff an aromatic delight.\r\n\r\nEffects\r\nGarlic Cocktail provides a euphoric and giggly high, perfect for lifting your mood and melting away stress. Users report feeling happy and relaxed, making it ideal for both social gatherings and cozy nights in. It also helps with anxiety, depression, and inflammation, offering a well-rounded experience.\r\n\r\nReliable Satisfaction\r\nJust like your favorite fast food joint, Thunder Bud is always there when you need it. Our Garlic Cocktail is perfect for a cozy night in or spicing up a social scene. Consistent quality, amazing taste, and a high that hits the spot every time.\r\n\r\nSo, whether you<6F>re lounging on the couch or lighting up the party, Thunder Bud Garlic Cocktail is your go-to for a high-flying, flavor-packed adventure. Light up, relax, and enjoy the smooth, savory flavors that make Thunder Bud a trusted favorite.\r\n\r\nCheers to big highs at a small price! ??'],
|
||||
['sku' => 'TB-GC-AZ5G', 'desc' => 'Grease Monkey <20> Big Highs, Small Price ?\r\n\r\nSignature Experience\r\nGrease Monkey is a top-tier hybrid strain celebrated for its rich, savory profile and deeply relaxing effects. Named for its unique blend of sweet, earthy, and diesel-like flavors, this strain delivers a truly unforgettable smoking experience that keeps you coming back for more.\r\n\r\nBig Highs, Small Price\r\nSourced from premium trim and smalls, Grease Monkey provides a smooth, satisfying smoke without breaking the bank. Our precise grinding process ensures that every puff is packed with flavor and potency, offering you premium enjoyment at an exceptional price.\r\n\r\nEuphoric and Focused\r\nIdeal for any time of day, Grease Monkey delivers a euphoric high that calms the mind while enhancing creativity. Whether you<6F>re unwinding after a long day or brainstorming with friends, this strain<69>s versatility makes it perfect for any occasion, providing a warm and comforting experience.\r\n\r\nIndulge in the Marked Experience\r\nExplore the exquisite quality of Thunder Bud Trim + Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Grease Monkey merges convenience with superior quality, ensuring each pre-roll is a sensory delight. Wrapped in premium rolling paper, these pre-rolls feature finely ground small buds and trim, perfectly packed to showcase their shimmering trichomes, promising a rich and satisfying smoke.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Grease Monkey <20> signature highs at a smart price.\r\n\r\nCheers to exceptional highs at a smart price! ??'],
|
||||
['sku' => 'TB-GFD-AZ1G', 'desc' => 'Grapefruit Durban <20> Spark Your Day at an Unbeatable Price ??\r\n\r\nA Burst of Citrus Energy\r\n\r\nGrapefruit Durban is a lively sativa-dominant hybrid that blends zesty citrus sweetness with earthy spice for a refreshing, invigorating experience. Its vibrant grapefruit aroma, accented by herbal undertones, delivers a crisp, uplifting smoke that energizes the senses and brightens your mood.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, Grapefruit Durban offers a smooth, flavorful smoke that brings big effects without the heavy cost. Thunder Bud<75>s precise grinding process ensures every pre-roll is consistent and terpene-rich, capturing the bold citrus flavor and stimulating effects this strain is known for.\r\n\r\nEnergize Your Spirit\r\n\r\nPerfect for daytime sessions, Grapefruit Durban delivers a euphoric cerebral buzz paired with a light, functional body high. Whether you are tackling your to-do list, sparking creative projects, or enjoying good company, this strain helps keep you motivated, clear-headed, and inspired throughout the day.\r\n\r\nSavor the Experience\r\n\r\nIndulge in the crisp, citrusy flavor of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to preserve the essence of Grapefruit Durban. Each pre-roll is packed with finely ground buds and resin-rich trim, shimmering with trichomes for a smooth, uplifting burn from start to finish.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s eco-friendly packaging makes it easy to enjoy your favorite strain while helping protect the planet. ?\r\n\r\nShine with Grapefruit Durban <20> bright, energizing highs at an unbeatable price.\r\n\r\nHere<72>s to fresh flavor, focused energy, and good vibes that keep you going strong! ??'],
|
||||
['sku' => 'TB-GG-AZ1G', 'desc' => 'Grape Gas <20> Relaxation with a Rich, Fruity Twist ?Citrus Bliss Awaits\r\n\r\nFruity Indulgence Meets Smooth Relaxation\r\nGrape Gas is an indica-dominant hybrid that combines deep relaxation with the sweet, aromatic essence of grape and a touch of diesel fuel. The rich grape fragrance, with its earthy and slightly spicy undertones, creates an aromatic escape that soothes the senses with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Grape Gas delivers a smooth, flavorful smoke perfect for winding down after a long day. Our precise grinding process ensures that each inhale is full of bold, fruity flavors and calming effects, making it an excellent choice for those seeking relaxation without the premium price tag.\r\n\r\nUnwind and Relax\r\nDesigned for evening or nighttime enjoyment, Grape Gas offers a potent, mellow high that eases both the mind and body into a relaxed state. Its sedative effects help to melt away stress and tension, making it ideal for quiet nights in, movie marathons, or easing into sleep after a busy day.\r\n\r\nSavor the Experience\r\nIndulge in the flavorful and relaxing experience of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to encapsulate the essence of Grape Gas. These pre-rolls combine convenience with top-tier quality, offering a smooth, enjoyable smoke that awakens your palate with every puff. Each pre-roll features finely ground small buds and trim, all sparkling with trichomes, ensuring an indulgent experience with each draw.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nRelax and unwind with Grape Gas<61>rich, soothing highs at an unbeatable price.\r\n\r\nHere<72>s to cozy, tranquil moments, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-GG4-AZ1G', 'desc' => 'GG4 <20> Get Stuck in Serenity at an Unbeatable Price ??\r\n\r\nA Heavy-Hitting Escape into Relaxation\r\nGG4, also known as Gorilla Glue #4, is a legendary indica-dominant hybrid that delivers pure, unfiltered relaxation. With bold notes of diesel, pine, and rich earth, this potent strain packs a punch that settles both body and mind. GG4 is perfect for melting away stress and sinking into a deep, satisfying calm that sticks with you long after the last puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, GG4 offers the same power and flavor you<6F>d expect from top-shelf flower at a price that keeps your wallet grounded. Thunder Bud<75>s precision grinding process ensures each pre-roll is packed with terpene-rich material for smooth, even burns and full-bodied hits every time.\r\n\r\nRelax Your Spirit\r\nIdeal for unwinding after a long day, GG4 brings a heavy, full-body high paired with a euphoric mental lift that quiets the noise and helps you find your center. Whether you<6F>re kicking back on the couch or zoning into your favorite playlist, this strain delivers that signature glue-like calm that keeps you comfortably locked into relaxation.\r\n\r\nSavor the Experience\r\nThunder Bud Trim+Smalls Pre-Rolls are expertly crafted to preserve GG4<47>s bold flavor and aroma. Each pre-roll contains finely ground buds and resin-rich trim for a consistent, flavorful smoke that showcases this classic strain<69>s earthy, gassy profile from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s eco-conscious packaging lets you enjoy premium cannabis while helping care for the planet. ?\r\n\r\nUnwind with GG4 <20> bold, sticky serenity at an unbeatable price.\r\nHere<72>s to heavy highs, mellow nights, and unbeatable value that keeps you grounded and glowing. ?'],
|
||||
['sku' => 'TB-GL-AZ1G', 'desc' => 'Thunder Bud Glookies <20> Sweet Vibes at a Great Price ?\r\n\r\nDecadent Delight\r\nThunder Bud Glookies is a luscious indica-dominant hybrid strain that brings a delightful mix of flavors to your day. With its rich cookie and earthy undertones, this strain offers a comforting escape with every puff, perfect for those seeking a sweet and satisfying experience.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Glookies delivers a smooth, enjoyable smoke that<61>s ideal for winding down. Our meticulous grinding process ensures each puff bursts with decadent flavors and soothing effects, all at an unbeatable price.\r\n\r\nRelaxing and Uplifting\r\nPerfect for cozy evenings or leisurely afternoons, Glookies provides a calming yet uplifting high that enhances your mood and sparks creativity. Let the sweet, comforting vibes envelop you as you unwind and savor the moment.\r\n\r\nImmerse in the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that excites the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The warm, rich colors of finely ground small buds and trim are beautifully complemented by glistening trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Glookies <20> sweet vibes at an affordable price.\r\n\r\nCheers to delightful moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-GL-AZ1G', 'desc' => 'Grease Lightning <20> Smooth Power at an Unbeatable Price ??\r\n\r\nFast-Acting Relaxation, Smooth Finish\r\nGrease Lightning is an indica-dominant hybrid that strikes with quick, calming relief before settling into a long-lasting, mellow body buzz. With rich notes of diesel, earthy spice, and a subtle sweetness on the exhale, this strain delivers bold flavor and heavy-hitting effects that ease stress and tension with effortless speed.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Grease Lightning provides a potent, flavorful smoke without the premium price tag. Thunder Bud<75>s precise grinding process ensures every pre-roll is packed to perfection with resin-rich flower, offering smooth, terpene-forward hits from start to finish.\r\n\r\nRelax Your Spirit\r\nIdeal for nighttime sessions or slow weekends, Grease Lightning delivers a wave of deep body relaxation paired with a calming mental drift. Perfect for melting into the couch, unwinding after a long day, or catching some peaceful rest, this strain offers powerful comfort without knocking you completely out.\r\n\r\nSavor the Experience\r\nEach Thunder Bud Trim+Smalls Pre-Roll is crafted to preserve the full-bodied flavor and aromatic punch of Grease Lightning. With finely ground small buds and trichome-rich trim, every roll provides a consistent burn and satisfying clouds of smooth, potent smoke.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s eco-friendly packaging lets you enjoy premium cannabis while supporting a greener planet. ?\r\n\r\nGrease Lightning <20> quick, powerful relaxation at an unbeatable price.\r\nHere<72>s to smooth nights, stress-free moments, and the kind of chill that hits fast and stays steady. ??'],
|
||||
['sku' => 'TB-GM-AZ1G', 'desc' => 'Grease Monkey <20> Deep Relaxation at a Smart Price ?\r\n\r\nSignature Experience\r\nGrease Monkey is an indica-dominant hybrid celebrated for its rich, savory profile and deeply relaxing effects. Named for its unique blend of sweet, earthy, and diesel-like flavors, this strain provides a comforting, soothing smoke that gently eases both body and mind.\r\n\r\nBig Highs, Small Price\r\nSourced from premium trim and smalls, Grease Monkey delivers a smooth, flavorful smoke without stretching your budget. Thunder Bud<75>s precise grinding process ensures every pre-roll is packed with potency and aromatic richness, giving you premium quality at an exceptional value.\r\n\r\nCalm and Comforted\r\nPerfect for evenings, quiet weekends, or winding down after a long day, Grease Monkey offers a relaxing body high paired with a soft, uplifting cerebral touch. This indica-dominant hybrid melts away tension while keeping your mind pleasantly engaged, creating a warm and comforting experience.\r\n\r\nIndulge in the Full Experience\r\nDiscover the carefully crafted quality of Thunder Bud Trim+Smalls Pre-Rolls, designed to preserve the essence of Grease Monkey. Each pre-roll features finely ground small buds and resin-rich trim, sparkling with trichomes for a smooth, flavorful burn that delights the senses from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s eco-conscious packaging lets you enjoy Grease Monkey while caring for the planet. ?\r\n\r\nRelax with Grease Monkey, soothing highs at a smart price.\r\nHere<72>s to calming, comforting moments and quality you can trust! ?'],
|
||||
['sku' => 'TB-GM-AZ3G', 'desc' => 'Grease Monkey <20> Big Highs, Small Price ??\r\n\r\nSignature Experience\r\nGrease Monkey is a top-tier hybrid strain celebrated for its rich, savory profile and deeply relaxing effects. Named for its unique blend of sweet, earthy, and diesel-like flavors, this strain delivers a truly unforgettable smoking experience that keeps you coming back for more.\r\n\r\nBig Highs, Small Price\r\nSourced from premium trim and smalls, Grease Monkey provides a smooth, satisfying smoke without breaking the bank. Our precise grinding process ensures that every puff is packed with flavor and potency, offering you premium enjoyment at an exceptional price.\r\n\r\nEuphoric and Focused\r\nIdeal for any time of day, Grease Monkey delivers a euphoric high that calms the mind while enhancing creativity. Whether you<6F>re unwinding after a long day or brainstorming with friends, this strain<69>s versatility makes it perfect for any occasion, providing a warm and comforting experience.\r\n\r\nIndulge in the Marked Experience\r\nExplore the exquisite quality of Thunder Bud Trim + Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Grease Monkey merges convenience with superior quality, ensuring each pre-roll is a sensory delight. Wrapped in premium rolling paper, these pre-rolls feature finely ground small buds and trim, perfectly packed to showcase their shimmering trichomes, promising a rich and satisfying smoke.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Grease Monkey <20> signature highs at a smart price.\r\n\r\nCheers to exceptional highs at a smart price! ?'],
|
||||
['sku' => 'TB-GMC-AZ1G', 'desc' => 'GMO Cookies <20> Indulge in Deep Relaxation at an Unbeatable Price ??\r\n\r\nA Rich, Flavorful Escape into Calm\r\nGMO Cookies is a potent indica-dominant hybrid that delivers a heavy, full-body high paired with a mellow mental lift. Its bold, savory aroma combines earthy, diesel notes with subtle sweet undertones, creating a distinct and memorable sensory experience. This strain is perfect for unwinding after a long day or settling into a calm, peaceful evening.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, GMO Cookies offers a smooth, flavorful smoke that brings boutique quality without the boutique price. Thunder Bud<75>s careful grinding process ensures every pre-roll is packed with terpene-rich material for consistent, satisfying hits every time.\r\n\r\nRelax Your Spirit\r\nIdeal for evening sessions or quiet weekends, GMO Cookies provides a deeply relaxing body high while keeping your mind comfortably uplifted. Let the gentle, euphoric effects melt away tension and stress, helping you sink into a state of calm and comfort.\r\n\r\nSavor the Experience\r\nThunder Bud Trim+Smalls Pre-Rolls are expertly crafted to preserve GMO Cookies<65> bold flavors and aroma. Each pre-roll features finely ground small buds and resin-rich trim for a smooth, flavorful burn from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s commitment to eco-conscious packaging allows you to enjoy premium cannabis while caring for the planet. ?\r\n\r\nUnwind with GMO Cookies <20> rich flavors and soothing highs at an unbeatable price.\r\nHere<72>s to peaceful nights, mellow vibes, and exceptional value for your wallet.'],
|
||||
['sku' => 'TB-GP-AZ1G', 'desc' => 'Thunder Bud Gary Payton <20> Premium Highs, Accessible Price ?\r\n\r\nScore Big with Every Puff\r\nThunder Bud Gary Payton is your ultimate game-changer, offering an elite indica-dominant hybrid experience that combines smooth, rich flavors with a powerful high. Known for its exceptional aroma and taste, this strain delivers a unique blend of earthy and sweet notes, making each puff a memorable part of your day. Perfect for those who want to unwind in style, Gary Payton is your go-to for a chill and satisfying smoke session.\r\n\r\nBig Highs, Small Price\r\nAt Thunder Bud, we pride ourselves on offering high-quality cannabis without the steep price tag. Gary Payton is crafted from top-shelf trims and smalls, providing a smooth, flavorful smoke that<61>s both rich and potent. Our expert grinding process ensures every puff delivers the perfect balance of taste and effects, all while keeping your budget intact.\r\n\r\nRelax and Unwind\r\nGary Payton is perfect for relaxing after a long day or enhancing your evening. Its well-rounded effects promote a deep sense of relaxation and euphoria, ideal for melting away stress and settling into a peaceful state of mind. Whether you<6F>re winding down or gearing up for a mellow night, this strain provides the perfect balance of calm and comfort.\r\n\r\nIndulge in the Experience\r\nExperience the top-notch quality of Thunder Bud<75>s Gary Payton in our meticulously crafted pre-rolls. Each pre-roll is designed to deliver a rich, smooth smoke with every puff. Wrapped in premium rolling paper, these pre-rolls feature finely ground buds that are packed with vibrant trichomes, ensuring a potent and flavorful encounter.\r\n\r\nResponsibly Packaged Goodness\r\nThunder Bud<75>s responsible packaging is designed to protect the planet while delivering a top-notch smoking experience. Our packaging isn<73>t just about looking good <20> it<69>s about being good. ?\r\n\r\nGet in the Game with Gary Payton\r\nLight up Gary Payton and experience a high that<61>s as exceptional as the strain itself. Whether you<6F>re unwinding after a busy day or enjoying a laid-back evening, this strain provides the perfect mix of relaxation and euphoria. With Gary Payton, you<6F>re guaranteed a premium experience at an accessible price.\r\n\r\nGet ready to elevate your game with Thunder Bud Gary Payton <20> premium highs without the premium price tag! ?'],
|
||||
['sku' => 'TB-GPP-AZ1G', 'desc' => 'Guava Papaya <20> Tropical Bliss at an Unbeatable Price ??\r\n\r\nA Taste of Island Paradise\r\n\r\nGuava Papaya is a perfectly balanced hybrid that delivers a refreshing blend of uplifting energy and calming relaxation. Sweet notes of ripe guava and juicy papaya swirl together with gentle floral undertones, offering a smooth, exotic flavor that instantly transports you to a tropical getaway with every puff.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, Guava Papaya delivers a flavorful, aromatic smoke that\'s both smooth and satisfying. Thunder Bud<75>s precision grinding process ensures that each pre-roll is loaded with consistent, terpene-rich hits bringing you premium quality without the premium price tag.\r\n\r\nBalance Your Spirit\r\n\r\nIdeal for anytime use, Guava Papaya offers a perfectly even high that lifts your mood while soothing your body. Whether you<6F>re taking on a creative project, catching up with friends, or simply enjoying some much-needed downtime, this balanced hybrid keeps the good vibes flowing without tipping too far into energy or sedation.\r\n\r\nSavor the Experience\r\n\r\nIndulge in the vibrant, tropical flavors of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to showcase the essence of Guava Papaya. Each pre-roll features finely ground small buds and glistening trim, packed with color, flavor, and a smooth, even burn from start to finish.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s sustainable packaging makes it easy to enjoy a clean high and a cleaner planet. ?\r\n\r\nEscape to paradise with Guava Papaya balanced, flavorful highs at a price you<6F>ll love.\r\n\r\nHere<72>s to tropical moments, anytime you need them.'],
|
||||
['sku' => 'TB-GPS-AZ1G', 'desc' => 'Grandpa<70>s Stash <20> Classic Calm at an Unbeatable Price ??\r\n\r\nA Nostalgic Escape\r\nGrandpa<70>s Stash is an indica-dominant hybrid that blends classic flavor with deeply relaxing effects. Its aroma of pine, skunky earth, and a touch of sweet spice delivers a familiar, vintage vibe while offering the smooth, soothing smoke you crave. Perfect for those who appreciate a timeless strain with calming body effects.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Grandpa<70>s Stash delivers a rich, flavorful smoke that is reliable and affordable. Thunder Bud<75>s careful grinding process ensures consistency in every pre-roll, packing in terpene-rich flavor and potent, relaxing effects.\r\n\r\nRelax and Unwind\r\nGrandpa<70>s Stash provides a deeply calming body high paired with a gentle cerebral lift. Ideal for evenings, quiet weekends, or winding down after a long day, this indica-dominant hybrid melts away stress and helps you fully relax while keeping your mind gently uplifted.\r\n\r\nSavor the Experience\r\nImmerse yourself in the comforting flavor of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to showcase the essence of Grandpa<70>s Stash. Each pre-roll features finely ground buds and resin-rich trim, sparkling with trichomes for a smooth, satisfying burn from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s eco-conscious packaging lets you enjoy Grandpa<70>s Stash while caring for the planet. ?\r\n\r\nUnwind with Grandpa<70>s Stash, classic flavor and soothing highs at an unbeatable price.\r\nHere<72>s to relaxing moments, timeless aromas, and quality you can trust! ??'],
|
||||
['sku' => 'TB-GW-AZ1G', 'desc' => 'Gorilla Watermelon <20> Sweet Relaxation at an Unbeatable Price ??\r\n\r\nA Juicy Escape into Calm\r\nGorilla Watermelon is a balanced hybrid that delivers a smooth, relaxing body high paired with a gentle mental uplift. Bursting with sweet, watermelon-forward flavor and subtle earthy undertones, this aromatic strain offers a deliciously satisfying experience that eases you into calm and comfort.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Gorilla Watermelon delivers a flavorful smoke that brings boutique quality without the boutique price. Thunder Bud<75>s precise grinding process ensures each pre-roll is packed with terpene-rich material for consistent, enjoyable hits every time.\r\n\r\nRelax Your Spirit\r\nPerfect for winding down after a busy day or enjoying a quiet evening, Gorilla Watermelon provides a relaxing body high while keeping your mind lightly elevated. Let the soothing effects melt away stress and tension, helping you find your ideal chill.\r\n\r\nSavor the Experience\r\nThunder Bud Trim+Smalls Pre-Rolls are carefully crafted to preserve the juicy, sweet flavors and aromatic profile of Gorilla Watermelon. Each pre-roll showcases finely ground small buds and resin-rich trim for a smooth, flavorful burn from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s commitment to eco-conscious packaging allows you to enjoy premium cannabis while caring for the planet. ?\r\n\r\nUnwind with Gorilla Watermelon <20> sweet flavors and relaxing highs at an unbeatable price.\r\nHere<72>s to mellow nights, refreshing vibes, and exceptional value for your wallet.'],
|
||||
['sku' => 'TB-GZ-AZ1G', 'desc' => 'Gruntz <20> Sink into Sweet Serenity at an Unbeatable Price ??\r\n\r\nCandy-Coated Calm\r\n\r\nGruntz is a rich indica-dominant hybrid that brings together sweet, fruity flavor with deeply relaxing effects. Its bold candy-like aroma blending grape, berry, and creamy vanilla wraps your senses in a nostalgic haze, making every puff a decadent escape from the daily grind.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, Gruntz delivers a smooth, flavorful smoke that hits hard without hitting your wallet. Thunder Bud<75>s precise grinding process ensures every inhale is packed with lush flavor and tranquil effects, ideal for easing into your evening with style.\r\n\r\nUnplug and Chill\r\n\r\nPerfect for nighttime or laid-back afternoons, Gruntz provides a calming, full-body high that melts away stress and invites stillness. Whether you<6F>re settling in for a movie, kicking back with friends, or winding down solo, this strain sets the perfect tone for mellow moments.\r\n\r\nSavor the Experience\r\n\r\nIndulge in the soothing experience of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to highlight the rich essence of this deeply relaxing strain. Each pre-roll is filled with finely ground small buds and trim, sparkling with trichomes and glowing with color ready to deliver a smooth, satisfying smoke every time.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud keeps things green while you unwind. Our eco-conscious packaging supports both your high and the planet. ?\r\n\r\nRelax with Gruntz <20> sweet, sedating highs at an unbeatable price.\r\n\r\nHere<72>s to tasty flavor, mellow vibes, and keeping it chill without spending big. ?'],
|
||||
['sku' => 'TB-HB-AZ1G', 'desc' => 'Thunder Bud Honey Bells <20> Sweet Highs, Small Price ?\r\n\r\nA Sweet Symphony\r\nThunder Bud Honey Bells is a sativa-dominant hybrid that offers a delightful blend of sweet citrus and honey flavors. This strain<69>s aromatic profile is a refreshing treat that invigorates the senses with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Honey Bells delivers a smooth, sweet smoke that<61>s both refreshing and potent. Our grinding process ensures each puff is packed with honeyed flavors and energizing effects.\r\n\r\nEnergize and Uplift\r\nIdeal for daytime use, Honey Bells provides an uplifting and euphoric high that boosts creativity and focus. Whether you<6F>re tackling a project or enjoying outdoor activities, this strain will keep you energized and motivated.\r\n\r\nIndulge in the Experience\r\nIndulge in the electrifying experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to encapsulate the essence of every strain. Thunder Bud presents a fusion of convenience and quality, delivering a sensory journey that ignites the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls boast a compact yet alluring appearance. The rich, earthy hues of the finely ground small buds and trim, generously packed within the confines of the paper, are punctuated by vibrant streaks of crystalline trichomes, promising a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nEnjoy the sweet, uplifting experience of Honey Bells <20> sweet highs at a small price.\r\n\r\nCheers to honeyed highs at a small price! ?'],
|
||||
['sku' => 'TB-HBC-AZ1G', 'desc' => 'Headband Cookies <20> Elevate Your Vibe at an Unbeatable Price ??\r\n\r\nA Sweet Boost of Focus and Creativity\r\nHeadband Cookies is a dynamic sativa-dominant hybrid that blends the classic cerebral rush of Headband with the sweet, cookie-like smoothness of its dessert lineage. With notes of creamy vanilla, baked dough, and a touch of earthy citrus, this aromatic strain delivers an uplifting and flavorful smoke perfect for sparking ideas and elevating your day.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Headband Cookies offers boutique-level flavor and potency without the boutique price tag. Thunder Bud<75>s precise grinding process ensures every pre-roll is evenly packed with resin-rich, terpene-heavy flower for a consistent, satisfying burn from start to finish.\r\n\r\nElevate Your Spirit\r\nPerfect for daytime sessions or social hangs, Headband Cookies delivers a euphoric, clear-headed high paired with a subtle body ease that keeps you comfortable and engaged. Whether you<6F>re fueling creativity, staying productive, or enjoying laughs with friends, this strain strikes the balance between focus and feel-good vibes.\r\n\r\nSavor the Experience\r\nIndulge in Thunder Bud Trim+Smalls Pre-Rolls, where the sweet, doughy flavor and uplifting effects of Headband Cookies shine through. Each roll features finely ground buds and shimmering trichome-rich trim, preserving the full flavor and energy of the strain for a smooth, tasty experience.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s eco-friendly packaging makes it easy to enjoy your cannabis while helping protect the planet. ?\r\n\r\nShine with Headband Cookies <20> uplifting, flavorful highs at an unbeatable price.\r\nHere<72>s to brighter days, creative sparks, and good vibes that keep you inspired! ??'],
|
||||
['sku' => 'TB-HBR-AZ1G', 'desc' => 'Headbanger <20> Get Lifted at an Unbeatable Price ??\r\n\r\nFuel Your Focus\r\n\r\nHeadbanger is a powerful sativa-dominant hybrid that hits with bold diesel flavor and brain-boosting clarity. Expect a pungent blend of sour citrus, earthy kush, and gassy undertones that spark the senses and energize the mind. Perfect for when you need to stay sharp and dialed in.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, Headbanger delivers a punchy, flavorful smoke without punching your wallet. Thunder Bud<75>s precise grinding ensures every puff is smooth, clean, and potent. Ideal for powering through your day or turning up the volume on your creativity.\r\n\r\nStay Sharp and Energized\r\n\r\nDesigned for daytime use, Headbanger offers a fast-hitting cerebral buzz that boosts focus, sparks motivation, and keeps energy flowing. Whether you\'re getting into a project, vibing with music, or just vibing with friends, this strain keeps the good vibes rolling.\r\n\r\nSavor the Experience\r\n\r\nStep into the energetic world of Thunder Bud Trim+Smalls Pre-Rolls, crafted to capture the electric essence of this invigorating strain. Each pre-roll features finely ground small buds and trim, glistening with trichomes and bursting with flavor. Delivers a clear-headed, creative high with every draw.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s sustainable packaging lets you stay lifted while being kind to the environment. ?\r\n\r\nTurn it up with Headbanger. Bold flavor, clear highs, and unmatched value.\r\n\r\nHere<72>s to staying sharp, elevated, and in control without breaking the bank. ?'],
|
||||
['sku' => 'TB-HH-AZ1G', 'desc' => 'Thunder Bud Headhunter <20> Intense Vibes at a Great Price ?\r\n\r\nBold Adventure\r\nThunder Bud Headhunter is a powerful indica-dominant hybrid strain that delivers an exhilarating experience for those seeking something extraordinary. With its robust earthy aroma and hints of sweet pine, this strain offers a deeply relaxing escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Headhunter provides a smooth, impactful smoke that<61>s perfect for any occasion. Our meticulous grinding process ensures each puff is packed with rich flavors and potent effects, all at an unbeatable price.\r\n\r\nRelaxing and Uplifting\r\nIdeal for winding down after a long day, Headhunter offers a calming and euphoric high that melts away stress. This strain enhances your mood and creativity, making it a perfect choice for cozy nights in or creative projects.\r\n\r\nImmerse in the Experience\r\nIndulge in the electrifying journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to encapsulate the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory adventure that awakens your senses with each inhale. Each pre-roll is a showcase of precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact and enticing appearance. The deep, rich colors of finely ground small buds and trim are highlighted by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Headhunter <20> intense vibes at an affordable price.\r\n\r\nCheers to bold adventures, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-HH-AZ3G', 'desc' => 'Thunder Bud Headhunter <20> Intense Vibes at a Great Price ?\r\n\r\nBold Adventure\r\nThunder Bud Headhunter is a powerful indica-dominant hybrid strain that delivers an exhilarating experience for those seeking something extraordinary. With its robust earthy aroma and hints of sweet pine, this strain offers a deeply relaxing escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Headhunter provides a smooth, impactful smoke that<61>s perfect for any occasion. Our meticulous grinding process ensures each puff is packed with rich flavors and potent effects, all at an unbeatable price.\r\n\r\nRelaxing and Uplifting\r\nIdeal for winding down after a long day, Headhunter offers a calming and euphoric high that melts away stress. This strain enhances your mood and creativity, making it a perfect choice for cozy nights in or creative projects.\r\n\r\nImmerse in the Experience\r\nIndulge in the electrifying journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to encapsulate the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory adventure that awakens your senses with each inhale. Each pre-roll is a showcase of precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact and enticing appearance. The deep, rich colors of finely ground small buds and trim are highlighted by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Headhunter <20> intense vibes at an affordable price.\r\n\r\nCheers to bold adventures, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-HH-AZ5G', 'desc' => 'Thunder Bud Headhunter <20> Intense Vibes at a Great Price ?\r\n\r\nBold Adventure\r\nThunder Bud Headhunter is a powerful indica-dominant hybrid strain that delivers an exhilarating experience for those seeking something extraordinary. With its robust earthy aroma and hints of sweet pine, this strain offers a deeply relaxing escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Headhunter provides a smooth, impactful smoke that<61>s perfect for any occasion. Our meticulous grinding process ensures each puff is packed with rich flavors and potent effects, all at an unbeatable price.\r\n\r\nRelaxing and Uplifting\r\nIdeal for winding down after a long day, Headhunter offers a calming and euphoric high that melts away stress. This strain enhances your mood and creativity, making it a perfect choice for cozy nights in or creative projects.\r\n\r\nImmerse in the Experience\r\nIndulge in the electrifying journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to encapsulate the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory adventure that awakens your senses with each inhale. Each pre-roll is a showcase of precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact and enticing appearance. The deep, rich colors of finely ground small buds and trim are highlighted by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Headhunter <20> intense vibes at an affordable price.\r\n\r\nCheers to bold adventures, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-HMS-AZ1G', 'desc' => 'Hot Mint Sundae <20> Cool Flavor, Smooth Vibes at an Unbeatable Price ??\r\n\r\nA Refreshing Twist on Classic Chill\r\n\r\nHot Mint Sundae is a decadent hybrid that delivers a unique blend of creamy sweetness and crisp minty freshness. With rich dessert-like notes layered over a cool, refreshing finish, this strain offers a truly mouthwatering experience that satisfies both sweet and savory cravings.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, Hot Mint Sundae brings a smooth, flavorful smoke that\'s ideal for anytime enjoyment. Thunder Bud<75>s precise grinding process ensures that each pre-roll is packed with consistent, terpene-rich hits bringing top-shelf taste and balanced effects without the hefty price tag.\r\n\r\nChill Your Spirit\r\n\r\nPerfect for afternoon hangouts or winding down your evening, Hot Mint Sundae offers a balanced high that relaxes the body while gently uplifting the mind. Feel your stress melt away as creativity sparks and a calm, blissful mood sets in making it a go to strain for whatever your day (or night) has in store.\r\n\r\nSavor the Experience\r\n\r\nDive into the delicious flavors of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture Hot Mint Sundae<61>s unique profile. Each pre-roll features finely ground small buds and resin-rich trim, highlighted by vibrant hues and a smooth, slow burn that keeps the flavor flowing with every puff.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s responsible packaging lets you enjoy premium cannabis while caring for the environment. ?\r\n\r\nTreat yourself with Hot Mint Sundae smooth flavor, balanced effects, and unbeatable value.\r\n\r\nHere<72>s to chill moments, sweet flavors, and high quality highs you can feel good about.'],
|
||||
['sku' => 'TB-I-CF-AZ1G', 'desc' => 'Thunder Bud Cake Face <20> Balanced Bliss at a Sweet Price ?\r\n\r\nInfused with Ice Water Hash for a Rich, Flavorful Hit\r\n\r\nThunder Bud Cake Face is a perfectly balanced hybrid that brings together sugary dessert-like flavors with smooth, creamy undertones. Infused with ice water hash, this strain delivers a flavorful and evenly matched high that offers the best of both worlds in every puff.\r\n\r\nBig Highs, Small Price\r\n\r\nCarefully crafted from premium trim and smalls, and infused with potent ice water hash, Cake Face offers a slow-burning, rich smoke that balances euphoria and calm. Our expert grinding and infusion process ensures consistent potency and full-bodied flavor, all at an unbeatable value.\r\n\r\nLift Up & Wind Down\r\n\r\nWhether you\'re kickstarting a creative project or winding down after a long day, Cake Face meets you in the middle. Expect a blissful blend of cerebral uplift and soothing body effects, making it a great go-to strain for any time of day.\r\n\r\nSavor the Experience\r\n\r\nTreat yourself to the indulgent experience of Thunder Bud Infused Pre-Rolls. Each pre-roll is carefully packed with finely ground small buds and trim, infused with ice water hash, and wrapped in premium rolling paper. Rich in flavor and layered with shimmering trichomes, every pre-roll delivers smooth, balanced hits that satisfy from start to finish.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s sustainable packaging helps you enjoy the moment while being kind to the planet. ?\r\n\r\nDiscover the perfect balance with Cake Face. Sweet, smooth, and satisfyingly strong.\r\n\r\nHere<72>s to flavor-packed highs without the heavy price tag! ?'],
|
||||
['sku' => 'TB-I-GPP-AZ1G', 'desc' => 'Thunder Bud Guava Papaya <20> Tropical Vibes at a Juicy Price ??\r\n\r\nInfused with Ice Water Hash for a Smooth, Potent Experience\r\n\r\nThunder Bud Guava Papaya is a delicious hybrid that blends tropical fruitiness with a mellow, balanced high. With mouthwatering notes of ripe guava and sweet papaya, this strain delivers a flavorful escape. Infused with ice water hash, each puff is bursting with rich taste and smooth potency.\r\n\r\nBig Highs, Small Price\r\n\r\nMade from top-tier trim and smalls and infused with powerful ice water hash, Guava Papaya offers a consistent, full-flavored smoke that doesn<73>t compromise on strength or value. Our expert preparation ensures a slow burn and a clean, flavorful inhale every time.\r\n\r\nBalanced and Breezy\r\n\r\nGuava Papaya provides a perfectly blended hybrid experience. Expect a smooth onset of uplifting cerebral energy paired with gentle body relaxation. Whether you<6F>re out exploring or lounging at home, it<69>s a versatile strain that fits any vibe.\r\n\r\nSavor the Experience\r\n\r\nEnjoy the tropical journey of Thunder Bud Infused Pre-Rolls. Each pre-roll is packed with finely ground small buds and trim, infused with ice water hash and wrapped in premium paper. The result is a visually appealing, terpene-rich smoke with sparkling trichomes and bold, fruity flavor in every puff.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s sustainable packaging is designed to support your high while respecting the environment. ?\r\n\r\nGet carried away with Guava Papaya. Fruity flavor and balanced effects at a price you<6F>ll love.\r\n\r\nHere<72>s to good vibes, tropical tastes and unbeatable value. ??'],
|
||||
['sku' => 'TB-I-GR-AZ1G', 'desc' => 'Thunder Bud Garlic Runtz <20> Flavorful Highs, Small Price ?\r\n\r\nInfused with Green Hash for an Amazing High\r\n\r\nThunder Bud Garlic Runtz combines the sweet, fruity flavors of Red Runtz with the bold, savory notes of Garlic Cocktail. Infused with Ice Water Hash, this hybrid strain offers a unique and flavorful smoking experience.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from the finest trim and smalls, and infused with Ice Water Hash, Garlic Runtz delivers a smooth, powerful smoke that<61>s both tasty and potent. Our meticulous grinding and infusion process ensures every puff is packed with rich flavors and strong effects, all at an affordable price.\r\n\r\nEuphoric and Uplifting\r\n\r\nIdeal for any time of day, Garlic Runtz provides a euphoric and uplifting high that boosts mood and creativity. Whether you\'re relaxing at home or out with friends, this strain enhances any experience.\r\n\r\nIndulge in the Experience\r\n\r\nIndulge in the electrifying experience of Thunder Bud Infused Pre-Rolls, meticulously crafted to encapsulate the essence of every strain. Thunder Bud presents a fusion of convenience and quality, delivering a sensory journey that ignites the senses with every inhale. Each 1.3g pre-roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls boast a compact yet alluring appearance. The rich hues of the finely ground small buds and trim, generously packed and infused with Ice Water Hash, are punctuated by vibrant streaks of crystalline trichomes, promising a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the bold flavors of Garlic Runtz <20> big highs at a small price.\r\n\r\nCheers to flavorful highs at a small price! ?'],
|
||||
['sku' => 'TB-I-RG-AZ1G', 'desc' => 'Thunder Bud Rainbow Gary <20> Big Highs, Small Price ?\r\n\r\nInfused with Ice Water Hash for an Amazing High\r\n\r\nThunder Bud Rainbow Gary combines the vibrant energy of Original Z with the balanced potency of Gary Payton. Infused with Ice Water Hash, this sativa-dominant hybrid offers a delightful citrus aroma with sweet, earthy undertones, making each puff a burst of sensory delight.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from the finest trim and smalls, and infused with Ice Water Hash, Rainbow Gary delivers a smooth, flavorful smoke that<61>s both uplifting and relaxing. Our meticulous grinding and infusion process ensures every puff is packed with vibrant flavors and potent effects, all at an affordable price.\r\n\r\nEnergize and Elevate\r\n\r\nIdeal for daytime use, Rainbow Gary provides an energetic and euphoric high that boosts creativity and focus. Whether you\'re tackling a project or enjoying a social gathering, this strain will keep you in high spirits.\r\n\r\nIndulge in the Experience\r\n\r\nIndulge in the electrifying experience of Thunder Bud Infused Pre-Rolls, meticulously crafted to encapsulate the essence of every strain. Thunder Bud presents a fusion of convenience and quality, delivering a sensory journey that ignites the senses with every inhale. Each 1.3g pre-roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls boast a compact yet alluring appearance. The rich hues of the finely ground small buds and trim, generously packed and infused with Ice Water Hash, are punctuated by vibrant streaks of crystalline trichomes, promising a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s responsible packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the vibrant delight of Rainbow Gary <20> big highs at a small price.\r\n\r\nCheers to colorful highs at a small price! ?'],
|
||||
['sku' => 'TB-I-RJ-AZ1G', 'desc' => 'Thunder Bud Royal Jelly <20> Regal Highs, Small Price ?\r\n\r\nInfused with Ice Water Hash for an Amazing High\r\n\r\nThunder Bud Royal Jelly combines the sweet, citrusy flavors of Honey Bells with the rich, earthy notes of King Louis XIII. Infused with Ice Water Hash, this hybrid strain offers a luxurious and aromatic experience with every puff.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from the finest trim and smalls, and infused with Ice Water Hash, Royal Jelly delivers a smooth, flavorful smoke that<61>s both uplifting and deeply relaxing. Our meticulous grinding and infusion process ensures every puff is packed with potent effects, all at an affordable price.\r\n\r\nElevate and Relax\r\n\r\nPerfect for any time of day, Royal Jelly provides a balanced high that uplifts the mood and relaxes the body. Whether you\'re unwinding after a long day or enjoying a social gathering, this strain is your perfect companion.\r\n\r\nIndulge in the Experience\r\n\r\nIndulge in the electrifying experience of Thunder Bud Infused Pre-Rolls, meticulously crafted to encapsulate the essence of every strain. Thunder Bud presents a fusion of convenience and quality, delivering a sensory journey that ignites the senses with every inhale. Each 1.3g pre-roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls boast a compact yet alluring appearance. The rich hues of the finely ground small buds and trim, generously packed and infused with Ice Water Hash, are punctuated by vibrant streaks of crystalline trichomes, promising a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nExperience the royal luxury of Royal Jelly <20> big highs at a small price.\r\n\r\nCheers to regal highs at a small price! ?'],
|
||||
['sku' => 'TB-I-TC-AZ1G', 'desc' => 'Thunder Bud Tropic Cake <20> Tropical Bliss, Small Price ?\r\n\r\nInfused with Ice Water Hash for an Amazing High\r\n\r\nThunder Bud Tropic Cake combines the tropical flavors of Trop Cherry with the rich, sweet notes of Cake Bomb. Infused with Ice Water Hash, this indica-dominant hybrid offers a delightful aroma of tropical fruits and cake batter, making each puff a delightful escape.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from the finest trim and smalls, and infused with Ice Water Hash, Tropic Cake delivers a smooth, flavorful smoke that<61>s both indulgent and relaxing. Our meticulous grinding and infusion process ensures every puff is packed with luscious flavors and potent effects, all at an affordable price.\r\n\r\nRelax and Unwind\r\n\r\nPerfect for evening use, Tropic Cake provides a deeply relaxing and euphoric high. It<49>s ideal for melting away stress and promoting a restful night<68>s sleep, leaving you feeling blissfully relaxed.\r\n\r\nIndulge in the Experience\r\n\r\nIndulge in the electrifying experience of Thunder Bud Infused Pre-Rolls, meticulously crafted to encapsulate the essence of every strain. Thunder Bud presents a fusion of convenience and quality, delivering a sensory journey that ignites the senses with every inhale. Each 1.3g pre-roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls boast a compact yet alluring appearance. The rich hues of the finely ground small buds and trim, generously packed and infused with Ice Water Hash, are punctuated by vibrant streaks of crystalline trichomes, promising a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\n\r\n\r\nThunder Bud<75>s responsible packaging is kind to the Earth and perfect for your smoking sessions. ?\r\n\r\nEscape to the tropics with Thunder Bud Tropic Cake <20> sweet highs at a small price.\r\n\r\nCheers to tropical highs at a small price! ?'],
|
||||
['sku' => 'TB-ICC-AZ1G', 'desc' => 'Ice Cream Cake <20> Sweet Relaxation in Every Puff ?\r\n\r\nDeliciously Smooth, Perfectly Relaxing\r\nIce Cream Cake is an indica-dominant hybrid that combines soothing relaxation with a mouthwatering, dessert-like flavor. Its rich aroma of creamy vanilla and sugary sweetness, accented by soft earthy notes, delivers a delectable sensory experience. Every puff is like a treat for the taste buds, making it the perfect strain to unwind and indulge in pure comfort.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Ice Cream Cake offers a smooth, mellow smoke that<61>s perfect for winding down after a busy day<61>without breaking the bank. Our precise grinding process ensures each hit is packed with creamy, relaxing flavors and calming effects, providing a luxurious experience at a price you<6F>ll love.\r\n\r\nUnwind and De-stress\r\nIdeal for evening use, Ice Cream Cake brings a deeply relaxing high that melts away stress and tension. Let the sedative effects gently wash over you, easing both body and mind into a state of calm serenity. Whether you<6F>re settling in for the night or enjoying a laid-back evening with friends, this strain<69>s soothing effects help you unwind and enjoy the moment.\r\n\r\nA Sweet, Relaxing Experience\r\nTreat yourself to the indulgent experience of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to capture the essence of Ice Cream Cake. Thunder Bud combines convenience with premium quality, offering a flavorful and calming smoke with every puff. Each pre-roll is filled with finely ground small buds and trim, showcasing rich hues and shimmering trichomes, promising a smooth and satisfying experience from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your relaxation with Ice Cream Cake <20> a sweet, calming high at an unbeatable price.\r\n\r\nHere<72>s to enjoying life<66>s little pleasures, all while being gentle on your wallet!'],
|
||||
['sku' => 'TB-ICC-AZ3G', 'desc' => 'Ice Cream Cake <20> Sweet Relaxation in Every Puff ?\r\n\r\nDeliciously Smooth, Perfectly Relaxing\r\nIce Cream Cake is an indica-dominant hybrid that combines soothing relaxation with a mouthwatering, dessert-like flavor. Its rich aroma of creamy vanilla and sugary sweetness, accented by soft earthy notes, delivers a delectable sensory experience. Every puff is like a treat for the taste buds, making it the perfect strain to unwind and indulge in pure comfort.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Ice Cream Cake offers a smooth, mellow smoke that<61>s perfect for winding down after a busy day<61>without breaking the bank. Our precise grinding process ensures each hit is packed with creamy, relaxing flavors and calming effects, providing a luxurious experience at a price you<6F>ll love.\r\n\r\nUnwind and De-stress\r\nIdeal for evening use, Ice Cream Cake brings a deeply relaxing high that melts away stress and tension. Let the sedative effects gently wash over you, easing both body and mind into a state of calm serenity. Whether you<6F>re settling in for the night or enjoying a laid-back evening with friends, this strain<69>s soothing effects help you unwind and enjoy the moment.\r\n\r\nA Sweet, Relaxing Experience\r\nTreat yourself to the indulgent experience of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to capture the essence of Ice Cream Cake. Thunder Bud combines convenience with premium quality, offering a flavorful and calming smoke with every puff. Each pre-roll is filled with finely ground small buds and trim, showcasing rich hues and shimmering trichomes, promising a smooth and satisfying experience from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your relaxation with Ice Cream Cake <20> a sweet, calming high at an unbeatable price.\r\n\r\nHere<72>s to enjoying life<66>s little pleasures, all while being gentle on your wallet!'],
|
||||
['sku' => 'TB-ICC-AZ5G', 'desc' => 'Ice Cream Cake <20> Sweet Relaxation in Every Puff ?\r\n\r\nDeliciously Smooth, Perfectly Relaxing\r\nIce Cream Cake is an indica-dominant hybrid that combines soothing relaxation with a mouthwatering, dessert-like flavor. Its rich aroma of creamy vanilla and sugary sweetness, accented by soft earthy notes, delivers a delectable sensory experience. Every puff is like a treat for the taste buds, making it the perfect strain to unwind and indulge in pure comfort.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Ice Cream Cake offers a smooth, mellow smoke that<61>s perfect for winding down after a busy day<61>without breaking the bank. Our precise grinding process ensures each hit is packed with creamy, relaxing flavors and calming effects, providing a luxurious experience at a price you<6F>ll love.\r\n\r\nUnwind and De-stress\r\nIdeal for evening use, Ice Cream Cake brings a deeply relaxing high that melts away stress and tension. Let the sedative effects gently wash over you, easing both body and mind into a state of calm serenity. Whether you<6F>re settling in for the night or enjoying a laid-back evening with friends, this strain<69>s soothing effects help you unwind and enjoy the moment.\r\n\r\nA Sweet, Relaxing Experience\r\nTreat yourself to the indulgent experience of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to capture the essence of Ice Cream Cake. Thunder Bud combines convenience with premium quality, offering a flavorful and calming smoke with every puff. Each pre-roll is filled with finely ground small buds and trim, showcasing rich hues and shimmering trichomes, promising a smooth and satisfying experience from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your relaxation with Ice Cream Cake <20> a sweet, calming high at an unbeatable price.\r\n\r\nHere<72>s to enjoying life<66>s little pleasures, all while being gentle on your wallet!'],
|
||||
['sku' => 'TB-IL-AZ1G', 'desc' => 'description coming soon'],
|
||||
['sku' => 'TB-IL-AZ1G', 'desc' => 'Illemonati <20> Bright Highs at an Unbeatable Price ??\r\n\r\nAwaken Your Senses\r\n\r\nIllemonati is a lively sativa-dominant hybrid that shines with zesty lemon flavor and uplifting effects. Its crisp citrus aroma, layered with hints of sweetness and earthy spice, creates a refreshing smoke that wakes up the senses and keeps energy flowing. Perfect for sparking creativity and elevating your mood.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, Illemonati delivers a smooth, flavorful smoke that packs big effects without the big cost. Thunder Bud<75>s careful grinding process ensures consistency in every puff, offering a burst of citrusy flavor and an energizing high you can count on.\r\n\r\nStay Bright and Creative\r\n\r\nDesigned for daytime sessions, Illemonati provides a heady cerebral buzz that boosts focus and creativity while keeping your body light and relaxed. Whether you are diving into a project, connecting with friends, or just enjoying the moment, this strain lifts you up and keeps the vibes positive.\r\n\r\nSavor the Experience\r\n\r\nIndulge in the refreshing world of Thunder Bud Trim+Smalls Pre-Rolls, crafted to highlight the vibrant essence of Illemonati. Each pre-roll is packed with finely ground buds and trim, shimmering with trichomes and bursting with citrusy aroma. Expect a smooth, uplifting smoke from start to finish.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud keeps your sessions high while keeping the planet in mind with eco-friendly packaging. ?\r\n\r\nShine brighter with Illemonati. Crisp flavor, uplifting highs, and unbeatable value.\r\n\r\nHere<72>s to fresh energy and positive vibes that won<6F>t break the bank. ?'],
|
||||
['sku' => 'TB-JD-AZ1G', 'desc' => 'Jungle Driver <20> Soothing Relaxation at an Unbeatable Price ??\r\n\r\nA Calming Escape into Comfort\r\nJungle Driver is an indica-dominant hybrid that blends deep relaxation with a gentle, uplifting cerebral touch. With notes of tropical fruit, subtle citrus, and earthy spice, this aromatic strain offers a flavorful, soothing experience that eases both body and mind. Perfect for unwinding after a long day or enjoying quiet, peaceful moments.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Jungle Driver delivers a smooth, flavorful smoke ideal for evening sessions or laid-back weekends. Thunder Bud<75>s precise grinding process ensures each pre-roll is packed with terpene-rich flower, offering consistent, high-quality effects at an approachable price.\r\n\r\nRelax Your Spirit\r\nDesigned for restful evenings or mellow social sessions, Jungle Driver provides a calming body high paired with a soft, uplifting mental clarity. Let the gentle euphoria melt away tension while keeping your mind comfortably engaged for a relaxing, balanced experience.\r\n\r\nSavor the Experience\r\nEnjoy the carefully crafted quality of Thunder Bud Trim+Smalls Pre-Rolls, preserving the rich flavors and aromatic complexity of Jungle Driver. Each pre-roll features finely ground small buds and resin-rich trim, sparkling with trichomes for a smooth, flavorful burn from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s eco-conscious packaging lets you enjoy Jungle Driver while supporting the planet. ?\r\n\r\nJungle Driver <20> soothing, flavorful highs at an unbeatable price.\r\nHere<72>s to calming evenings, relaxed vibes, and peaceful moments that keep you coming back for more.'],
|
||||
['sku' => 'TB-KL-AZ1G', 'desc' => 'Thunder Bud King Louis XIII <20> Regal Highs at a Small Price ?\r\n\r\nThunder Bud King Louis XIII is the epitome of luxury in the cannabis world. This indica-dominant strain offers a rich, earthy pine aroma with a hint of\r\nspice, making every puff a majestic experience.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, King Louis XIII delivers a smooth, potent smoke that<61>s perfect for unwinding after a long day. Our careful grinding process ensures a regal taste and a high that<61>ll have you feeling like royalty without the royal expense.\r\n\r\nRelax Like a King\r\nPerfect for evening use, this strain provides deep relaxation and a soothing body high, ideal for melting away stress and promoting restful\r\nsleep. Feel the royal treatment with every puff.\r\n\r\nIndulge in the Experience\r\nIndulge in the electrifying experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to encapsulate the essence of every strain. Thunder Bud presents a fusion of convenience and quality, delivering a sensory journey that ignites the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls boast a compact yet alluring appearance. The rich, earthy hues of the finely ground small buds and trim, generously packed within the confines of the paper, are punctuated by vibrant streaks of crystalline trichomes, promising a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging is designed to protect the planet while delivering a top-notch smoking experience. ?\r\n\r\nSo, light up and enjoy the regal relaxation of King Louis XIII <20> your ticket to a luxurious high at an affordable price.\r\n\r\nCheers to royal highs at a small price! ?'],
|
||||
['sku' => 'TB-KL-AZ3G', 'desc' => 'Thunder Bud King Louis XIII <20> Regal Highs at a Small Price ?\r\n\r\nThunder Bud King Louis XIII is the epitome of luxury in the cannabis world. This indica-dominant strain offers a rich, earthy pine aroma with a hint of spice, making every puff a majestic experience.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, King Louis XIII delivers a smooth, potent smoke that<61>s perfect for unwinding after a long day. Our careful grinding process ensures a regal taste and a high that<61>ll have you feeling like royalty without the royal expense.\r\n\r\nRelax Like a King\r\nPerfect for evening use, this strain provides deep relaxation and a soothing body high, ideal for melting away stress and promoting restful sleep. Feel the royal treatment with every puff.\r\n\r\nIndulge in the Experience\r\nIndulge in the electrifying experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to encapsulate the essence of every strain. Thunder Bud presents a fusion of convenience and quality, delivering a sensory journey that ignites the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls boast a compact yet alluring appearance. The rich, earthy hues of the finely ground small buds and trim, generously packed within the confines of the paper, are punctuated by vibrant streaks of crystalline trichomes, promising a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging is designed to protect the planet while delivering a top-notch smoking experience. ?\r\n\r\nSo, light up and enjoy the regal relaxation of King Louis XIII <20> your ticket to a luxurious high at an affordable price.\r\n\r\nCheers to royal highs at a small price! ?'],
|
||||
['sku' => 'TB-KL-AZ5G', 'desc' => 'Thunder Bud King Louis XIII <20> Regal Highs at a Small Price ?\r\n\r\nThunder Bud King Louis XIII is the epitome of luxury in the cannabis world. This indica-dominant strain offers a rich, earthy pine aroma with a hint of spice, making every puff a majestic experience.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, King Louis XIII delivers a smooth, potent smoke that<61>s perfect for unwinding after a long day. Our careful grinding process ensures a regal taste and a high that<61>ll have you feeling like royalty without the royal expense.\r\n\r\nRelax Like a King\r\nPerfect for evening use, this strain provides deep relaxation and a soothing body high, ideal for melting away stress and promoting restful sleep. Feel the royal treatment with every puff.\r\n\r\nIndulge in the Experience\r\nIndulge in the electrifying experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to encapsulate the essence of every strain. Thunder Bud presents a fusion of convenience and quality, delivering a sensory journey that ignites the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls boast a compact yet alluring appearance. The rich, earthy hues of the finely ground small buds and trim, generously packed within the confines of the paper, are punctuated by vibrant streaks of crystalline trichomes, promising a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging is designed to protect the planet while delivering a top-notch smoking experience. ?\r\n\r\nSo, light up and enjoy the regal relaxation of King Louis XIII <20> your ticket to a luxurious high at an affordable price.\r\n\r\nCheers to royal highs at a small price! ?'],
|
||||
['sku' => 'TB-LF-AZ1G', 'desc' => 'Lazer Fuel <20> Unwind and Relax with Deep, Soothing Bliss ?\r\n\r\nFuel Your Relaxation\r\nLazer Fuel is a calming, indica-dominant hybrid that delivers a deep sense of relaxation and tranquil euphoria. With its distinctive diesel aroma and earthy undertones, this strain offers a rich, comforting scent that wraps you in a serene, calming embrace. Perfect for unwinding after a long day, Lazer Fuel balances soothing relaxation with a touch of uplifting energy to melt away stress.\r\n\r\nBig Comfort, Small Price\r\nCrafted from premium trim and smalls, Lazer Fuel provides a smooth, rich smoke that<61>s perfect for those seeking relaxation at an affordable price. Our meticulous grinding process ensures each puff delivers robust flavors and a deeply calming high, making it the perfect choice for winding down without breaking the bank.\r\n\r\nRelax and Recharge\r\nIdeal for evening or nighttime use, Lazer Fuel delivers a deeply relaxing and soothing high that helps you unwind and relieve tension. Whether you\'re preparing for a restful sleep or simply seeking a moment of peace, this strain offers the perfect blend of calm, comfort, and tranquility.\r\n\r\nSavor the Comfort\r\nIndulge in the tranquil experience of Thunder Bud Trim+Smalls Pre-Rolls, thoughtfully crafted to deliver the calming essence of Lazer Fuel. Each pre-roll is expertly rolled, showcasing finely ground small buds and trim, all covered in shimmering trichomes, ensuring a smooth, calming encounter with every draw.\r\n\r\nEco-Conscious Packaging\r\nThunder Bud<75>s eco-friendly packaging ensures you can relax and enjoy your high while caring for the environment. ?\r\n\r\nElevate your mood with Lazer Fuel <20> deep, soothing relaxation at an unbeatable price.\r\n\r\nHere<72>s to peaceful experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-LR-AZ1G', 'desc' => 'Thunder Bud Lavender Runtz <20> Calming Vibes at a Great Price ?\r\n\r\nSoothing Delight\r\nThunder Bud Lavender Runtz is a delightful indica strain that envelops you in relaxation. With its sweet floral aroma and hints of lavender and berries, this strain offers a tranquil escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Lavender Runtz delivers a smooth, comforting smoke that<61>s perfect for winding down. Our precise grinding process ensures each puff bursts with rich flavors and soothing effects, all at an unbeatable price.\r\n\r\nRelaxing and Comforting\r\nIdeal for cozy evenings or restful nights, Lavender Runtz provides a deeply calming high that enhances your mood and eases stress. Let the gentle vibes wrap around you as you unwind and savor the moment.\r\n\r\nImmerse in the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that delights the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The soft, pastel hues of finely ground small buds and trim are beautifully complemented by glistening trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Lavender Runtz <20> calming vibes at an affordable price.\r\n\r\nCheers to soothing moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-LR-AZ3G', 'desc' => 'Thunder Bud Lavender Runtz <20> Calming Vibes at a Great Price ?\r\n\r\nSoothing Delight\r\nThunder Bud Lavender Runtz is a delightful indica strain that envelops you in relaxation. With its sweet floral aroma and hints of lavender and berries, this strain offers a tranquil escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Lavender Runtz delivers a smooth, comforting smoke that<61>s perfect for winding down. Our precise grinding process ensures each puff bursts with rich flavors and soothing effects, all at an unbeatable price.\r\n\r\nRelaxing and Comforting\r\nIdeal for cozy evenings or restful nights, Lavender Runtz provides a deeply calming high that enhances your mood and eases stress. Let the gentle vibes wrap around you as you unwind and savor the moment.\r\n\r\nImmerse in the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that delights the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The soft, pastel hues of finely ground small buds and trim are beautifully complemented by glistening trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Lavender Runtz <20> calming vibes at an affordable price.\r\n\r\nCheers to soothing moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-LR-AZ5G', 'desc' => 'Thunder Bud Lavender Runtz <20> Calming Vibes at a Great Price ?\r\n\r\nSoothing Delight\r\nThunder Bud Lavender Runtz is a delightful indica strain that envelops you in relaxation. With its sweet floral aroma and hints of lavender and berries, this strain offers a tranquil escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Lavender Runtz delivers a smooth, comforting smoke that<61>s perfect for winding down. Our precise grinding process ensures each puff bursts with rich flavors and soothing effects, all at an unbeatable price.\r\n\r\nRelaxing and Comforting\r\nIdeal for cozy evenings or restful nights, Lavender Runtz provides a deeply calming high that enhances your mood and eases stress. Let the gentle vibes wrap around you as you unwind and savor the moment.\r\n\r\nImmerse in the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that delights the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The soft, pastel hues of finely ground small buds and trim are beautifully complemented by glistening trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Lavender Runtz <20> calming vibes at an affordable price.\r\n\r\nCheers to soothing moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-LR-PP-AZ28G', 'desc' => 'Thunder Bud Lavender Runtz <20> Calming Vibes at a Great Price ?\r\n\r\nSoothing Delight\r\nThunder Bud Lavender Runtz is a delightful indica strain that envelops you in relaxation. With its sweet floral aroma and hints of lavender and berries, this strain offers a tranquil escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Lavender Runtz delivers a smooth, comforting smoke that<61>s perfect for winding down. Our precise grinding process ensures each puff bursts with rich flavors and soothing effects, all at an unbeatable price.\r\n\r\nRelaxing and Comforting\r\nIdeal for cozy evenings or restful nights, Lavender Runtz provides a deeply calming high that enhances your mood and eases stress. Let the gentle vibes wrap around you as you unwind and savor the moment.\r\n\r\nImmerse in the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that delights the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The soft, pastel hues of finely ground small buds and trim are beautifully complemented by glistening trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Lavender Runtz <20> calming vibes at an affordable price.\r\n\r\nCheers to soothing moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-MB-AZ1G', 'desc' => 'Modified Banana <20> Smooth, Potent Vibes at an Unbeatable Price ??\r\n\r\nFunky Fruit Meets Powerhouse Potency\r\n\r\nModified Banana is a flavorful, indica-leaning hybrid known for its bold banana funk and gassy undertones. This unique strain combines sweet, overripe fruit notes with a pungent diesel twist, creating a rich aroma and flavor that<61>s both funky and unforgettable.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, Modified Banana delivers a smooth, full-bodied smoke that leans into deep relaxation without sacrificing clarity. Thunder Bud<75>s precision grind process ensures each pre-roll is packed for a consistent, flavorful burn making it easy to indulge without going over budget.\r\n\r\nMelt Into the Moment\r\n\r\nIdeal for late afternoons and evenings, Modified Banana brings a heavy-hitting calm that settles the body while keeping the mind pleasantly afloat. Whether you<6F>re kicking back after a long day or diving into a chill creative session, this strain offers a balanced high that soothes without sedating.\r\n\r\nSavor the Experience\r\n\r\nThunder Bud Trim+Smalls Pre-Rolls capture the essence of Modified Banana in every puff. Finely ground small buds and resinous trim are blended and rolled to perfection, delivering a flavorful, terp-rich experience that looks as good as it feels dense, frosty, and full of color.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s sustainable packaging is designed with both your high and the environment in mind. ?\r\n\r\nUnwind with Modified Banana; bold flavor, powerful effects, and a price that<61>s easy to love.\r\n\r\nHere<72>s to deep relaxation, unique flavor, and premium quality that doesn<73>t break the bank.'],
|
||||
['sku' => 'TB-MBL-AZ1G', 'desc' => 'Magic Blast <20> Elevate Your Senses at an Unbeatable Price ??\r\n\r\nA Captivating Escape into Relaxation\r\nMagic Blast is a versatile hybrid that blends uplifting mental clarity with gentle body relaxation. Bursting with sweet, fruity notes and subtle earthy undertones, this aromatic strain delivers a smooth, flavorful experience that eases your mind and refreshes your spirit.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Magic Blast provides a satisfying smoke that offers boutique quality without the boutique price. Thunder Bud<75>s precise grinding process ensures each pre-roll is packed with potent, terpene-rich material for consistent enjoyment in every hit.\r\n\r\nRelax Your Spirit\r\nPerfect for afternoon sessions or unwinding in the evening, Magic Blast delivers a balanced high that lifts your mood while relaxing your body. Let the smooth, euphoric effects help you release stress and find your ideal chill.\r\n\r\nSavor the Experience\r\nThunder Bud Trim+Smalls Pre-Rolls are carefully crafted to preserve the flavorful profile and aromatic character of Magic Blast. Each pre-roll contains finely ground small buds and resin-rich trim for a smooth, flavorful burn from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s commitment to eco-conscious packaging lets you enjoy premium cannabis while caring for the planet. ?\r\n\r\nUnwind with Magic Blast <20> balanced highs and sweet flavors at an unbeatable price.\r\nHere<72>s to elevated moments, relaxed vibes, and exceptional value for your wallet.'],
|
||||
['sku' => 'TB-MC-AZ1G', 'desc' => 'Macaroons <20> Sweet Satisfaction at an Unbeatable Price ??\r\n\r\nA Dessert Dream Awaits\r\n\r\nMacaroons is a delectable hybrid that brings rich, sweet flavors to the forefront. With creamy, nutty notes accented by hints of vanilla and coconut, this strain offers a smooth, dessert like aroma that\'s a true treat for your senses with every puff.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, Macaroons delivers a flavorful, silky smoke that\'s perfect for whenever you want to add a little sweetness to your day. Thunder Bud<75>s precise grinding process ensures that every pre-roll is packed with consistent, terpene-rich hits offering you a top-quality experience without the top-shelf price.\r\n\r\nSatisfy Your Spirit\r\n\r\nIdeal for anytime use, Macaroons offers a perfectly balanced high that gently uplifts the mind while easing the body into a relaxed, contented state. Whether you\'re winding down after a busy day or diving into a creative project, this strain helps you stay light, happy, and deliciously at ease.\r\n\r\nSavor the Experience\r\n\r\nImmerse yourself in the decadent flavors of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to showcase Macaroons\' sweet, creamy profile. Each pre-roll highlights finely ground small buds and frosty trim, packed with beautiful color, inviting aromas, and a smooth, satisfying burn.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s commitment to sustainable packaging ensures that you can enjoy your high while caring for the planet. ?\r\n\r\nIndulge yourself with Macaroons sweet, balanced highs at an unbeatable price.\r\n\r\nHere<72>s to treating yourself because you deserve it.'],
|
||||
['sku' => 'TB-MLC-AZ1G', 'desc' => 'Molotov Cocktail <20> Ignite Your Senses at an Unbeatable Price ??\r\n\r\nA Bold Escape into Relaxation\r\nMolotov Cocktail is a dynamic hybrid that delivers a potent combination of mental uplift and body relaxation. With sharp citrus notes, subtle spice, and a hint of earthy sweetness, this aromatic strain offers a powerful, memorable experience that awakens your senses while easing tension.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Molotov Cocktail provides a smooth, flavorful smoke without the premium price tag. Thunder Bud<75>s precise grinding process ensures each pre-roll is packed with potent, terpene-rich material for consistent enjoyment in every puff.\r\n\r\nRelax Your Spirit\r\nPerfect for evening sessions or a laid-back weekend, Molotov Cocktail delivers a balanced high that stimulates the mind while relaxing the body. Let the gentle, euphoric effects help you release stress and enjoy your moment of calm.\r\n\r\nSavor the Experience\r\nThunder Bud Trim+Smalls Pre-Rolls are carefully crafted to preserve the full flavors and aromatic character of Molotov Cocktail. Each pre-roll contains finely ground small buds and resin-rich trim for a smooth, flavorful burn from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s commitment to eco-conscious packaging lets you enjoy premium cannabis while caring for the planet. ?\r\n\r\nUnwind with Molotov Cocktail <20> bold flavors and balanced highs at an unbeatable price.\r\nHere<72>s to energized evenings, relaxed vibes, and exceptional value for your wallet.'],
|
||||
['sku' => 'TB-NS-AZ1G', 'desc' => 'Thunder Bud Neon Sunshine <20> Radiant Vibes at a Great Price ?\r\n\r\nSunny Delight\r\nThunder Bud Neon Sunshine is a sativa-dominant hybrid that brightens your day with vibrant energy. With its zesty citrus aroma and uplifting floral notes, this strain offers a refreshing escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Neon Sunshine delivers a smooth, invigorating smoke that<61>s perfect for any occasion. Our precise grinding process ensures each puff bursts with lively flavors and energizing effects.\r\n\r\nEnergizing and Creative\r\nIdeal for daytime use, Neon Sunshine provides a clear-headed and motivating high, making it perfect for creativity and social interactions. Let the sunny vibes lift your spirits and inspire your day.\r\n\r\nImmerse in the Experience\r\nIndulge in the electrifying experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to capture the essence of every strain. Thunder Bud combines convenience and quality, delivering a sensory journey that awakens the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The rich, earthy tones of finely ground small buds and trim are accented by sparkling trichomes, promising a potent experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nBrighten your day with Thunder Bud Neon Sunshine <20> uplifting highs at an affordable price.\r\n\r\nCheers to radiant experiences, all without breaking the bank!'],
|
||||
['sku' => 'TB-NS-AZ3G', 'desc' => 'Thunder Bud Neon Sunshine <20> Radiant Vibes at a Great Price ?\r\n\r\nSunny Delight\r\nThunder Bud Neon Sunshine is a sativa-dominant hybrid that brightens your day with vibrant energy. With its zesty citrus aroma and uplifting floral notes, this strain offers a refreshing escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Neon Sunshine delivers a smooth, invigorating smoke that<61>s perfect for any occasion. Our precise grinding process ensures each puff bursts with lively flavors and energizing effects.\r\n\r\nEnergizing and Creative\r\nIdeal for daytime use, Neon Sunshine provides a clear-headed and motivating high, making it perfect for creativity and social interactions. Let the sunny vibes lift your spirits and inspire your day.\r\n\r\nImmerse in the Experience\r\nIndulge in the electrifying experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to capture the essence of every strain. Thunder Bud combines convenience and quality, delivering a sensory journey that awakens the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The rich, earthy tones of finely ground small buds and trim are accented by sparkling trichomes, promising a potent experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nBrighten your day with Thunder Bud Neon Sunshine <20> uplifting highs at an affordable price.\r\n\r\nCheers to radiant experiences, all without breaking the bank!'],
|
||||
['sku' => 'TB-NS-AZ5G', 'desc' => 'Thunder Bud Neon Sunshine <20> Radiant Vibes at a Great Price ?\r\n\r\nSunny Delight\r\nThunder Bud Neon Sunshine is a sativa-dominant hybrid that brightens your day with vibrant energy. With its zesty citrus aroma and uplifting floral notes, this strain offers a refreshing escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Neon Sunshine delivers a smooth, invigorating smoke that<61>s perfect for any occasion. Our precise grinding process ensures each puff bursts with lively flavors and energizing effects.\r\n\r\nEnergizing and Creative\r\nIdeal for daytime use, Neon Sunshine provides a clear-headed and motivating high, making it perfect for creativity and social interactions. Let the sunny vibes lift your spirits and inspire your day.\r\n\r\nImmerse in the Experience\r\nIndulge in the electrifying experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to capture the essence of every strain. Thunder Bud combines convenience and quality, delivering a sensory journey that awakens the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The rich, earthy tones of finely ground small buds and trim are accented by sparkling trichomes, promising a potent experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nBrighten your day with Thunder Bud Neon Sunshine <20> uplifting highs at an affordable price.\r\n\r\nCheers to radiant experiences, all without breaking the bank!'],
|
||||
['sku' => 'TB-OGK-AZ1G', 'desc' => 'OG Kush <20> Classic Power at an Unbeatable Price ??\r\n\r\nA Legendary Escape into Balance\r\nOG Kush is a timeless hybrid known for its signature mix of earthy, pine, and lemon-fuel aromas that deliver a powerful yet balanced experience. This classic strain blends a relaxing body high with a gentle mental uplift, creating a smooth, mellow vibe perfect for any occasion.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, OG Kush delivers the potency and flavor you expect from a legend at a price that keeps things easy. Thunder Bud<75>s precision grinding process ensures every pre-roll is packed with terpene-rich hits that burn evenly and taste incredible.\r\n\r\nRelax Your Spirit\r\nPerfect for kicking back after work or catching up with friends, OG Kush offers the ideal hybrid balance between chill and clarity. The effects wash over you with a calm, euphoric wave, easing tension while keeping your mind centered and engaged.\r\n\r\nSavor the Experience\r\nThunder Bud Trim+Smalls Pre-Rolls capture the essence of OG Kush with finely ground small buds and resin-rich trim for a flavorful, smooth smoke from start to finish. The result is a consistent, satisfying burn that showcases the strain<69>s iconic profile.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s dedication to sustainable packaging means you can enjoy your cannabis while caring for the planet. ?\r\n\r\nUnwind with OG Kush <20> a legendary classic delivering smooth, balanced highs at an unbeatable price.\r\nHere<72>s to easy days, mellow nights, and timeless flavor without the premium price tag.'],
|
||||
['sku' => 'TB-OZ-AZ1G', 'desc' => 'Thunder Bud Original Z <20> Big Highs, Small Price ?\r\n\r\nZesty and Delightful\r\nThunder Bud Original Z is a sativa-dominant strain that offers a vibrant citrus aroma with sweet and tangy notes. This strain is a burst of sunshine in a pre-roll, perfect for brightening your day.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Original Z delivers a smooth, flavorful smoke that<61>s both zesty and satisfying. Our grinding process ensures each puff is packed with delicious flavors and uplifting effects.\r\n\r\nEnergize and Elevate\r\nIdeal for daytime use, Original Z provides an energetic and euphoric high, boosting creativity and focus. Whether you\'re tackling a project or enjoying a social gathering, this strain will keep you in high spirits.\r\n\r\nIndulge in the Experience\r\nIndulge in the electrifying experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to encapsulate the essence of every strain. Thunder Bud presents a fusion of convenience and quality, delivering a sensory journey that ignites the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls boast a compact yet alluring appearance. The rich, earthy hues of the finely ground small buds and trim, generously packed within the confines of the paper, are punctuated by vibrant streaks of crystalline trichomes, promising a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s eco-friendly packaging ensures you<6F>re making a sustainable choice while enjoying your high. ?\r\n\r\nExperience the zest of life with Thunder Bud Original Z <20> big highs at a value-friendly price.\r\n\r\nCheers to big highs at a small price! ?'],
|
||||
['sku' => 'TB-PBB-AZ1G', 'desc' => 'Thunder Bud Peanut Butter Breath <20> Elevate Your Experience at an Unbeatable Price ?\r\n\r\nNutty Indulgence\r\nThunder Bud Peanut Butter Breath is a deliciously unique hybrid strain that combines rich, nutty flavors with soothing effects. With its creamy peanut butter aroma and subtle hints of sweetness, this strain offers a comforting escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Peanut Butter Breath delivers a smooth, satisfying smoke that<61>s perfect for any occasion. Our careful grinding process ensures each puff is infused with bold flavors and relaxing effects, making it a great choice for unwinding after a long day.\r\n\r\nRelax and Enjoy\r\nIdeal for both daytime and evening use, Peanut Butter Breath provides a balanced high that promotes relaxation while keeping the mind engaged. Whether you<6F>re enjoying a cozy night in or sharing laughs with friends, let the delightful vibes elevate your mood and enhance your experience.\r\n\r\nSavor the Experience\r\nIndulge in the comforting experience of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of this indulgent strain. Thunder Bud combines convenience and quality, offering a sensory adventure that awakens the senses with every inhale. Each Thunder Bud Pre-Roll showcases an inviting appearance, featuring warm, earthy tones of finely ground small buds and trim, all accented by glistening trichomes, promising a satisfying encounter with every draw.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nDiscover the cozy bliss of Thunder Bud Peanut Butter Breath <20> deliciously relaxing highs at an unbeatable price.\r\n\r\nHere<72>s to indulgent experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-PBB-AZ3G', 'desc' => 'Thunder Bud Peanut Butter Breath <20> Elevate Your Experience at an Unbeatable Price ?\r\n\r\nNutty Indulgence\r\nThunder Bud Peanut Butter Breath is a deliciously unique hybrid strain that combines rich, nutty flavors with soothing effects. With its creamy peanut butter aroma and subtle hints of sweetness, this strain offers a comforting escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Peanut Butter Breath delivers a smooth, satisfying smoke that<61>s perfect for any occasion. Our careful grinding process ensures each puff is infused with bold flavors and relaxing effects, making it a great choice for unwinding after a long day.\r\n\r\nRelax and Enjoy\r\nIdeal for both daytime and evening use, Peanut Butter Breath provides a balanced high that promotes relaxation while keeping the mind engaged. Whether you<6F>re enjoying a cozy night in or sharing laughs with friends, let the delightful vibes elevate your mood and enhance your experience.\r\n\r\nSavor the Experience\r\nIndulge in the comforting experience of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of this indulgent strain. Thunder Bud combines convenience and quality, offering a sensory adventure that awakens the senses with every inhale. Each Thunder Bud Pre-Roll showcases an inviting appearance, featuring warm, earthy tones of finely ground small buds and trim, all accented by glistening trichomes, promising a satisfying encounter with every draw.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nDiscover the cozy bliss of Thunder Bud Peanut Butter Breath <20> deliciously relaxing highs at an unbeatable price.\r\n\r\nHere<72>s to indulgent experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-PBB-AZ5G', 'desc' => 'Thunder Bud Peanut Butter Breath <20> Elevate Your Experience at an Unbeatable Price ?\r\n\r\nNutty Indulgence\r\nThunder Bud Peanut Butter Breath is a deliciously unique hybrid strain that combines rich, nutty flavors with soothing effects. With its creamy peanut butter aroma and subtle hints of sweetness, this strain offers a comforting escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Peanut Butter Breath delivers a smooth, satisfying smoke that<61>s perfect for any occasion. Our careful grinding process ensures each puff is infused with bold flavors and relaxing effects, making it a great choice for unwinding after a long day.\r\n\r\nRelax and Enjoy\r\nIdeal for both daytime and evening use, Peanut Butter Breath provides a balanced high that promotes relaxation while keeping the mind engaged. Whether you<6F>re enjoying a cozy night in or sharing laughs with friends, let the delightful vibes elevate your mood and enhance your experience.\r\n\r\nSavor the Experience\r\nIndulge in the comforting experience of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of this indulgent strain. Thunder Bud combines convenience and quality, offering a sensory adventure that awakens the senses with every inhale. Each Thunder Bud Pre-Roll showcases an inviting appearance, featuring warm, earthy tones of finely ground small buds and trim, all accented by glistening trichomes, promising a satisfying encounter with every draw.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nDiscover the cozy bliss of Thunder Bud Peanut Butter Breath <20> deliciously relaxing highs at an unbeatable price.\r\n\r\nHere<72>s to indulgent experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-PDM-AZ1G', 'desc' => 'Puddy Mouth <20> Smooth Relaxation and Flavor at an Unbeatable Price ??\r\n\r\nA Rich and Comforting Escape\r\nPuddy Mouth is a hybrid that leans toward a relaxing indica experience with a gentle mental uplift. With sweet chocolate and earthy undertones, plus a hint of rich dessert-like flavor, this aromatic strain provides a calming and comforting high that soothes both body and mind.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Puddy Mouth delivers a smooth, flavorful smoke perfect for unwinding after a long day. Thunder Bud ensures every pre-roll is packed with terpene-rich, potent flower for consistent and enjoyable hits.\r\n\r\nRelax Your Spirit\r\nPerfect for evening sessions or quiet weekends, Puddy Mouth offers a deeply relaxing body high paired with a soft mental lift. Let the smooth, calming effects melt away stress while keeping you grounded and at ease.\r\n\r\nSavor the Experience\r\nThunder Bud Trim+Smalls Pre-Rolls are carefully crafted to preserve the rich flavors and soothing aroma of Puddy Mouth. Each pre-roll features finely ground small buds and resin-rich trim for a smooth, flavorful burn from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud is committed to sustainable packaging so you can enjoy premium cannabis while caring for the planet. ?\r\n\r\nUnwind with Puddy Mouth <20> rich, smooth highs at an unbeatable price.\r\nHere is to relaxing nights, calm moments, and flavorful sessions that keep you coming back for more.'],
|
||||
['sku' => 'TB-PG-AZ1G', 'desc' => 'Plasma Gas <20> Unwind and Relax at an Unbeatable Price ??\r\n\r\nRelaxing Power Awaits\r\n\r\nPlasma Gas is a potent indica dominant hybrid that delivers a relaxing, yet flavorful experience with its distinct diesel aroma and earthy undertones. The rich, pungent scent pairs perfectly with its soothing effects, offering a sensory escape that helps you unwind after a long day.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, Plasma Gas delivers a smooth, calming smoke that<61>s ideal for evening relaxation or winding down. Thunder Bud<75>s precise grinding process ensures each inhale is packed with mellow, stress-relieving flavors and soothing effects, making it the perfect choice for those seeking tranquility without the hefty price tag.\r\n\r\nRelax and Recharge\r\n\r\nDesigned for relaxation, Plasma Gas provides a deeply calming high that melts away tension and promotes restful vibes. Whether you<6F>re kicking back after a busy day or prepping for a cozy night, let the euphoric, mellow effects help you find the relaxation you deserve.\r\n\r\nSavor the Experience\r\n\r\nIndulge in the soothing experience of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to capture the essence of this relaxing strain. Each pre-roll features finely ground small buds and trim, showcasing rich, vibrant hues with shimmering trichomes, offering a smooth, calming smoke that guarantees a peaceful encounter every time.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s commitment to eco-friendly packaging ensures you can enjoy Plasma Gas while supporting a healthier planet. ?\r\n\r\nUnwind with Plasma Gas, relaxing, soothing highs at an unbeatable price.\r\n\r\nHere<72>s to peaceful moments and mellow vibes, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-PIC-AZ1G', 'desc' => 'Poison Cherry <20> Bold Flavor and Relaxation at an Unbeatable Price ??\r\n\r\nA Sweet and Tangy Escape\r\nPoison Cherry is a hybrid that leans toward a relaxing indica experience with a gentle mental uplift. Bursting with sweet cherry notes, subtle berries, and a hint of earthy undertones, this aromatic strain provides a smooth, calming high that eases both body and mind.\r\n\r\nBig Highs, Small Price\r\nMade from premium trim and smalls, Poison Cherry delivers a smooth, flavorful smoke perfect for winding down after a busy day. Thunder Bud ensures every pre-roll is packed with terpene-rich, potent flower for consistent and enjoyable hits.\r\n\r\nRelax Your Spirit\r\nIdeal for evening sessions or a quiet weekend at home, Poison Cherry offers a relaxing body high along with a gentle mental lift. Let the soothing effects melt away stress while keeping you focused and calm.\r\n\r\nSavor the Experience\r\nThunder Bud Trim+Smalls Pre-Rolls are carefully crafted to preserve the rich flavors and aroma of Poison Cherry. Each pre-roll features finely ground small buds and resin-rich trim for a smooth, flavorful burn from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud is committed to sustainable packaging so you can enjoy premium cannabis while caring for the planet. ?\r\n\r\nUnwind with Poison Cherry <20> sweet, flavorful highs at an unbeatable price.\r\nHere is to relaxing nights, calm moments, and a smooth smoke that keeps you coming back for more.'],
|
||||
['sku' => 'TB-PKG-AZ1G', 'desc' => 'Pink Gorilla <20> Sweet Relief at an Unbeatable Price ??\r\n\r\nA Fruity Escape into Relaxation\r\nPink Gorilla is an indica-dominant hybrid that delivers a soothing, full-bodied experience. With sweet notes of ripe berries, tropical fruits, and a hint of earthy undertones, this aromatic strain creates a calm, dreamy high that gently eases you into deep relaxation.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Pink Gorilla offers smooth, flavorful hits perfect for winding down after a long day. Thunder Bud<75>s precise grinding process ensures each pre-roll is packed with potent, terpene-rich flower that burns evenly and delivers consistent quality.\r\n\r\nRelax Your Spirit\r\nIdeal for evening sessions or lazy weekends, Pink Gorilla provides a deeply relaxing body high paired with a gentle mental uplift. Let the soothing effects melt away your stress and tension while keeping you centered and calm.\r\n\r\nSavor the Experience\r\nThunder Bud Trim+Smalls Pre-Rolls are carefully crafted to preserve the lush flavors and fragrant aroma of Pink Gorilla. Each pre-roll features finely ground small buds and resin-rich trim for a smooth, flavorful burn from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s commitment to sustainable packaging lets you enjoy premium cannabis while caring for the planet. ?\r\n\r\nUnwind with Pink Gorilla <20> soothing, fruity highs at an unbeatable price.\r\nHere is to relaxing nights, peaceful moments, and a smooth, satisfying smoke that keeps you coming back for more.'],
|
||||
['sku' => 'TB-PM-AZ1G', 'desc' => 'Thunder Bud Permanent Marker <20> Signature Highs, Smart Price ??\r\n\r\nSignature Experience\r\nThunder Bud Permanent Marker is a standout hybrid strain renowned for its exceptional effects and distinctive flavor profile. Named for its bold, lasting impact, this strain blends tangy citrus, sweet fruit, and earthy undertones to create a memorable smoking experience.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Permanent Marker delivers a smooth, impactful smoke that excels in both taste and effect. Our meticulous grinding process ensures a top-quality experience without the hefty price tag, providing you with premium enjoyment at a smart price.\r\n\r\nEuphoric and Focused\r\nPerfect for any time of day, Permanent Marker offers an uplifting, euphoric high that enhances creativity and focus. Whether you\'re working on a project or relaxing with friends, this strain is versatile enough for any setting, delivering a refreshing and invigorating experience.\r\n\r\nIndulge in the Marked Experience\r\nDive into the standout quality of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to encapsulate the essence of every strain. Thunder Bud merges convenience with superior quality, delivering a sensory journey that sparks the senses with each inhale. Each pre-roll is a masterclass in precision and craft, wrapped in premium rolling paper. The pre-rolls showcase a compact, appealing appearance, with finely ground small buds and trim packed to perfection, highlighted by shimmering trichomes that promise a potent and satisfying smoke.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Permanent Marker <20> signature highs at a smart price.\r\n\r\nCheers to exceptional highs at a smart price! ??'],
|
||||
['sku' => 'TB-PM-AZ3G', 'desc' => 'Thunder Bud Permanent Marker <20> Signature Highs, Smart Price ??\r\n\r\nSignature Experience\r\nThunder Bud Permanent Marker is a standout hybrid strain renowned for its exceptional effects and distinctive flavor profile. Named for its bold, lasting impact, this strain blends tangy citrus, sweet fruit, and earthy undertones to create a memorable smoking experience.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Permanent Marker delivers a smooth, impactful smoke that excels in both taste and effect. Our meticulous grinding process ensures a top-quality experience without the hefty price tag, providing you with premium enjoyment at a smart price.\r\n\r\nEuphoric and Focused\r\nPerfect for any time of day, Permanent Marker offers an uplifting, euphoric high that enhances creativity and focus. Whether you\'re working on a project or relaxing with friends, this strain is versatile enough for any setting, delivering a refreshing and invigorating experience.\r\n\r\nIndulge in the Marked Experience\r\nDive into the standout quality of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to encapsulate the essence of every strain. Thunder Bud merges convenience with superior quality, delivering a sensory journey that sparks the senses with each inhale. Each pre-roll is a masterclass in precision and craft, wrapped in premium rolling paper. The pre-rolls showcase a compact, appealing appearance, with finely ground small buds and trim packed to perfection, highlighted by shimmering trichomes that promise a potent and satisfying smoke.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Permanent Marker <20> signature highs at a smart price.\r\n\r\nCheers to exceptional highs at a smart price! ??'],
|
||||
['sku' => 'TB-PM-AZ5G', 'desc' => 'Thunder Bud Permanent Marker <20> Signature Highs, Smart Price ??\r\n\r\nSignature Experience\r\nThunder Bud Permanent Marker is a standout hybrid strain renowned for its exceptional effects and distinctive flavor profile. Named for its bold, lasting impact, this strain blends tangy citrus, sweet fruit, and earthy undertones to create a memorable smoking experience.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Permanent Marker delivers a smooth, impactful smoke that excels in both taste and effect. Our meticulous grinding process ensures a top-quality experience without the hefty price tag, providing you with premium enjoyment at a smart price.\r\n\r\nEuphoric and Focused\r\nPerfect for any time of day, Permanent Marker offers an uplifting, euphoric high that enhances creativity and focus. Whether you\'re working on a project or relaxing with friends, this strain is versatile enough for any setting, delivering a refreshing and invigorating experience.\r\n\r\nIndulge in the Marked Experience\r\nDive into the standout quality of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to encapsulate the essence of every strain. Thunder Bud merges convenience with superior quality, delivering a sensory journey that sparks the senses with each inhale. Each pre-roll is a masterclass in precision and craft, wrapped in premium rolling paper. The pre-rolls showcase a compact, appealing appearance, with finely ground small buds and trim packed to perfection, highlighted by shimmering trichomes that promise a potent and satisfying smoke.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Permanent Marker <20> signature highs at a smart price.\r\n\r\nCheers to exceptional highs at a smart price! ??'],
|
||||
['sku' => 'TB-PM-PP-AZ28G', 'desc' => 'Thunder Bud Permanent Marker <20> Signature Highs, Smart Price ??\r\n\r\nSignature Experience\r\nThunder Bud Permanent Marker is a standout hybrid strain renowned for its exceptional effects and distinctive flavor profile. Named for its bold, lasting impact, this strain blends tangy citrus, sweet fruit, and earthy undertones to create a memorable smoking experience.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Permanent Marker delivers a smooth, impactful smoke that excels in both taste and effect. Our meticulous grinding process ensures a top-quality experience without the hefty price tag, providing you with premium enjoyment at a smart price.\r\n\r\nEuphoric and Focused\r\nPerfect for any time of day, Permanent Marker offers an uplifting, euphoric high that enhances creativity and focus. Whether you\'re working on a project or relaxing with friends, this strain is versatile enough for any setting, delivering a refreshing and invigorating experience.\r\n\r\nIndulge in the Marked Experience\r\nDive into the standout quality of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to encapsulate the essence of every strain. Thunder Bud merges convenience with superior quality, delivering a sensory journey that sparks the senses with each inhale. Each pre-roll is a masterclass in precision and craft, wrapped in premium rolling paper. The pre-rolls showcase a compact, appealing appearance, with finely ground small buds and trim packed to perfection, highlighted by shimmering trichomes that promise a potent and satisfying smoke.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Permanent Marker <20> signature highs at a smart price.\r\n\r\nCheers to exceptional highs at a smart price! ??'],
|
||||
['sku' => 'TB-PMM-AZ1G', 'desc' => 'Thunder Bud Pink Marshmallow <20> Sweet Bliss at a Great Price ?\r\n\r\nSugary Delight\r\nThunder Bud Pink Marshmallow is a delightful indica strain that brings a touch of sweetness to your day. With its enchanting marshmallow aroma and hints of fruity undertones, this strain offers a comforting escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Pink Marshmallow delivers a smooth, enjoyable smoke that<61>s perfect for any occasion. Our meticulous grinding process ensures each puff bursts with delicious flavors and satisfying effects, all at an unbeatable price.\r\n\r\nRelaxing and Comforting\r\nIdeal for winding down after a busy day, Pink Marshmallow provides a blissful high that relaxes the body and soothes the mind. Let the sweet, cozy vibes wrap around you as you unwind and savor your favorite activities.\r\n\r\nImmerse in the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that delights the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The soft, pastel hues of finely ground small buds and trim are beautifully complemented by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Pink Marshmallow <20> sweet bliss at an affordable price.\r\n\r\nCheers to delightful moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-PMM-AZ3G', 'desc' => 'Thunder Bud Pink Marshmallow <20> Sweet Bliss at a Great Price ?\r\n\r\nSugary Delight\r\nThunder Bud Pink Marshmallow is a delightful indica strain that brings a touch of sweetness to your day. With its enchanting marshmallow aroma and hints of fruity undertones, this strain offers a comforting escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Pink Marshmallow delivers a smooth, enjoyable smoke that<61>s perfect for any occasion. Our meticulous grinding process ensures each puff bursts with delicious flavors and satisfying effects, all at an unbeatable price.\r\n\r\nRelaxing and Comforting\r\nIdeal for winding down after a busy day, Pink Marshmallow provides a blissful high that relaxes the body and soothes the mind. Let the sweet, cozy vibes wrap around you as you unwind and savor your favorite activities.\r\n\r\nImmerse in the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that delights the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The soft, pastel hues of finely ground small buds and trim are beautifully complemented by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Pink Marshmallow <20> sweet bliss at an affordable price.\r\n\r\nCheers to delightful moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-PMM-AZ5G', 'desc' => 'Thunder Bud Pink Marshmallow <20> Sweet Bliss at a Great Price ?\r\n\r\nSugary Delight\r\nThunder Bud Pink Marshmallow is a delightful indica strain that brings a touch of sweetness to your day. With its enchanting marshmallow aroma and hints of fruity undertones, this strain offers a comforting escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Pink Marshmallow delivers a smooth, enjoyable smoke that<61>s perfect for any occasion. Our meticulous grinding process ensures each puff bursts with delicious flavors and satisfying effects, all at an unbeatable price.\r\n\r\nRelaxing and Comforting\r\nIdeal for winding down after a busy day, Pink Marshmallow provides a blissful high that relaxes the body and soothes the mind. Let the sweet, cozy vibes wrap around you as you unwind and savor your favorite activities.\r\n\r\nImmerse in the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that delights the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The soft, pastel hues of finely ground small buds and trim are beautifully complemented by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Pink Marshmallow <20> sweet bliss at an affordable price.\r\n\r\nCheers to delightful moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-PNP-AZ1G', 'desc' => 'Pineapple Planet <20> Explore Bright Highs at an Unbeatable Price ??\r\n\r\nA Tropical Escape into Elevation\r\nPineapple Planet is a lively sativa-dominant hybrid that transports you to sunny vibes and energetic adventures. Bursting with tropical pineapple sweetness, hints of citrus, and subtle earthy undertones, this aromatic strain delivers a vibrant, uplifting experience that invigorates both mind and body. Perfect for sparking creativity or enjoying social moments with friends.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Pineapple Planet offers a smooth, flavorful smoke ideal for daytime or anytime you need an energizing lift. Thunder Bud<75>s precise grinding process ensures each pre-roll is packed with terpene-rich flower, delivering consistent, bright effects without the boutique price tag.\r\n\r\nElevate Your Spirit\r\nDesigned for daytime enjoyment, Pineapple Planet provides a clear-headed, euphoric high that enhances focus, creativity, and motivation. Let the lively, uplifting vibes energize your day, whether you<6F>re tackling projects, exploring outdoors, or sharing laughs with friends.\r\n\r\nSavor the Experience\r\nIndulge in the tropical journey of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to preserve the sweet, fruity aroma and flavorful essence of Pineapple Planet. Each pre-roll features finely ground small buds and resin-rich trim, shimmering with trichomes, promising a smooth, enjoyable smoke from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s commitment to eco-friendly packaging lets you enjoy Pineapple Planet while caring for the planet. ?\r\n\r\nPineapple Planet <20> bright, uplifting highs at an unbeatable price.\r\nHere<72>s to energized days, inspired moments, and flavorful adventures that keep you coming back for more.'],
|
||||
['sku' => 'TB-PS-AZ1G', 'desc' => 'P-Star <20> Shine Bright with Relaxation and Serenity at an Unbeatable Price ?\r\n\r\nA Star-Studded Experience\r\nP-Star is a luxurious indica-dominant hybrid that delivers a perfect blend of calming relaxation and euphoric tranquility. With its sweet, floral aroma, accented by earthy and fruity notes, this strain invites you to unwind and melt into a peaceful state. P-Star is designed for those seeking deep relaxation with a smooth, calming vibe.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, P-Star offers a smooth, mellow smoke that<61>s ideal for evening or nighttime relaxation. Our careful grinding process ensures each puff delivers rich flavors and deeply soothing effects, making it the perfect choice for unwinding after a busy day without stretching your budget.\r\n\r\nRelax and Recharge\r\n\r\nTailored for a stress-free evening, P-Star provides a calming high that melts away tension and promotes a restful, peaceful experience. Whether you\'re looking to relax before bed or enjoy some quiet time, this strain offers the perfect escape into serenity.\r\n\r\nSavor the Tranquility\r\n\r\nIndulge in the serene experience of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to showcase the calming essence of P-Star. Each pre-roll is carefully rolled with finely ground small buds and trim, all dusted with sparkling trichomes, promising a smooth and relaxing journey with every puff.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your mood with P-Star <20> deep, peaceful relaxation at an unbeatable price.\r\n\r\nHere<72>s to calm, restful moments, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-RR-AZ1G', 'desc' => 'Thunder Bud Red Runtz <20> Big Highs, Small Price ?\r\n\r\nBerry Bliss\r\nThunder Bud Red Runtz is a balanced hybrid strain that brings a burst of berry flavor with every puff. With its sweet and fruity aroma reminiscent of strawberries and candy, this strain is a treat for the senses.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Red Runtz delivers a smooth, flavorful smoke that<61>s both satisfying and potent. Our grinding process ensures each puff is packed with berry goodness and uplifting effects.\r\n\r\nEuphoric and Relaxing\r\nIdeal for any time of day, Red Runtz provides a balanced high that uplifts the mood and relaxes the body. It<49>s perfect for social gatherings or unwinding after a long day.\r\n\r\nIndulge in the Experience\r\nIndulge in the electrifying experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to encapsulate the essence of every strain. Thunder Bud presents a fusion of convenience and quality, delivering a sensory journey that ignites the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls boast a compact yet alluring appearance. The rich, earthy hues of the finely ground small buds and trim, generously packed within the confines of the paper, are punctuated by vibrant streaks of crystalline trichomes, promising a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging is kind to the Earth and perfect for your smoking sessions. ?\r\n\r\nSavor the sweet bliss of Red Runtz <20> flavorful highs at a small price.\r\n\r\nCheers to big highs at a small price! ?'],
|
||||
['sku' => 'TB-RR-AZ3G', 'desc' => 'Thunder Bud Red Runtz <20> Big Highs, Small Price ?\r\n\r\nBerry Bliss\r\nThunder Bud Red Runtz is a balanced hybrid strain that brings a burst of berry flavor with every puff. With its sweet and fruity aroma reminiscent of strawberries and candy, this strain is a treat for the senses.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Red Runtz delivers a smooth, flavorful smoke that<61>s both satisfying and potent. Our grinding process ensures each puff is packed with berry goodness and uplifting effects.\r\n\r\nEuphoric and Relaxing\r\nIdeal for any time of day, Red Runtz provides a balanced high that uplifts the mood and relaxes the body. It<49>s perfect for social gatherings or unwinding after a long day.\r\n\r\nIndulge in the Experience\r\nIndulge in the electrifying experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to encapsulate the essence of every strain. Thunder Bud presents a fusion of convenience and quality, delivering a sensory journey that ignites the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls boast a compact yet alluring appearance. The rich, earthy hues of the finely ground small buds and trim, generously packed within the confines of the paper, are punctuated by vibrant streaks of crystalline trichomes, promising a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging is kind to the Earth and perfect for your smoking sessions. ?\r\n\r\nSavor the sweet bliss of Red Runtz <20> flavorful highs at a small price.\r\n\r\nCheers to big highs at a small price! ?'],
|
||||
['sku' => 'TB-RR-AZ5G', 'desc' => 'Thunder Bud Red Runtz <20> Big Highs, Small Price ?\r\n\r\nBerry Bliss\r\nThunder Bud Red Runtz is a balanced hybrid strain that brings a burst of berry flavor with every puff. With its sweet and fruity aroma reminiscent of strawberries and candy, this strain is a treat for the senses.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Red Runtz delivers a smooth, flavorful smoke that<61>s both satisfying and potent. Our grinding process ensures each puff is packed with berry goodness and uplifting effects.\r\n\r\nEuphoric and Relaxing\r\nIdeal for any time of day, Red Runtz provides a balanced high that uplifts the mood and relaxes the body. It<49>s perfect for social gatherings or unwinding after a long day.\r\n\r\nIndulge in the Experience\r\nIndulge in the electrifying experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to encapsulate the essence of every strain. Thunder Bud presents a fusion of convenience and quality, delivering a sensory journey that ignites the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls boast a compact yet alluring appearance. The rich, earthy hues of the finely ground small buds and trim, generously packed within the confines of the paper, are punctuated by vibrant streaks of crystalline trichomes, promising a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging is kind to the Earth and perfect for your smoking sessions. ?\r\n\r\nSavor the sweet bliss of Red Runtz <20> flavorful highs at a small price.\r\n\r\nCheers to big highs at a small price! ?'],
|
||||
['sku' => 'TB-SC-AZ1G', 'desc' => 'Sugar Cake <20> Sweet, Balanced Relaxation at an Unbeatable Price ??\r\n\r\nA Dessert-Inspired Escape\r\nSugar Cake is a hybrid strain that blends comforting sweetness with a balanced, uplifting touch. With notes of vanilla frosting, sugary undertones, and a hint of earthy spice, this aromatic strain offers a smooth, flavorful experience that eases both body and mind into gentle relaxation while keeping the mood light and enjoyable.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Sugar Cake delivers a smooth, satisfying smoke perfect for winding down or enjoying a laid-back afternoon. Thunder Bud<75>s precise grinding process ensures every pre-roll is packed with terpene-rich flower, providing boutique-quality effects without the boutique price tag.\r\n\r\nRelax and Elevate\r\nIdeal for evenings or chill weekends, Sugar Cake provides a calming body high paired with a gentle mental uplift. Let the soothing, balanced effects melt away tension while keeping your mind comfortably engaged for a relaxed, happy experience.\r\n\r\nSavor the Experience\r\nEnjoy the flavorful journey of Thunder Bud Trim+Smalls Pre-Rolls, crafted to preserve the rich sweetness and aromatic complexity of Sugar Cake. Each pre-roll features finely ground small buds and resin-rich trim, sparkling with trichomes, promising a smooth, flavorful burn from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s eco-conscious packaging lets you enjoy Sugar Cake while supporting the planet. ?\r\n\r\nUnwind with Sugar Cake <20> sweet, balanced highs at an unbeatable price.\r\nHere<72>s to cozy moments, relaxing vibes, and flavorful enjoyment without breaking the bank.'],
|
||||
['sku' => 'TB-SD-AZ1G', 'desc' => 'Sour Diesel <20> Energize Your Day at an Unbeatable Price ??\r\n\r\nA Bold and Uplifting Escape\r\nSour Diesel is a sativa-dominant hybrid known for its fast-acting, energizing effects and sharp, pungent aroma. With tangy citrus notes, diesel undertones, and a hint of earthy sweetness, this aromatic strain provides a lively, uplifting experience that sparks creativity and focus.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Sour Diesel delivers a smooth, flavorful smoke that is perfect for daytime use or creative sessions. Thunder Bud ensures every pre-roll is packed with potent, terpene-rich flower for consistent, satisfying hits.\r\n\r\nElevate Your Mind\r\nSour Diesel offers a mental boost paired with gentle body relaxation. Enjoy a clear-headed, euphoric lift that helps you stay motivated, inspired, and energized throughout the day.\r\n\r\nSavor the Experience\r\nThunder Bud Trim+Smalls Pre-Rolls are carefully crafted to preserve the bold flavors and sharp aroma of Sour Diesel. Each pre-roll features finely ground small buds and resin-rich trim for a smooth, flavorful burn from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud is committed to sustainable packaging so you can enjoy premium cannabis while caring for the planet. ?\r\n\r\nUnwind with Sour Diesel <20> bright, uplifting highs at an unbeatable price.\r\nHere is to energetic days, inspired moments, and flavorful sessions that keep you coming back for more.'],
|
||||
['sku' => 'TB-SG-AZ1G', 'desc' => 'Sour G <20> Spark Your Day at an Unbeatable Price ??\r\n\r\nA Zesty Escape into Energy\r\nSour G is a vibrant sativa-dominant hybrid that bursts with tangy citrus and sweet, sour undertones. Its sharp, zesty aroma and bright flavor create an invigorating smoke that awakens the senses and energizes the mind. Perfect for sparking creativity, social vibes, or staying focused throughout the day.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Sour G delivers a smooth, flavorful smoke ideal for daytime enjoyment. Thunder Bud<75>s precise grinding process ensures that every pre-roll is packed with terpene-rich flower, providing consistent uplifting effects without the boutique price tag.\r\n\r\nElevate Your Spirit\r\nDesigned for active sessions, Sour G offers a clear-headed, euphoric high that boosts focus, motivation, and mood. Let the lively, energizing effects carry you through creative projects, adventures outdoors, or lively social moments with friends.\r\n\r\nSavor the Experience\r\nIndulge in the bold flavors of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to preserve the citrusy, tangy essence of Sour G. Each pre-roll features finely ground small buds and resin-rich trim, shimmering with trichomes, promising a smooth, flavorful smoke from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s commitment to eco-friendly packaging lets you enjoy Sour G while caring for the planet. ?\r\n\r\nSour G <20> bright, uplifting highs at an unbeatable price.\r\nHere<72>s to energized days, inspired creativity, and flavorful experiences that keep you coming back for more.'],
|
||||
['sku' => 'TB-SK-AZ1G', 'desc' => 'Star Killer <20> Drift into Deep Relaxation at an Unbeatable Price ??\r\n\r\nA Stellar Escape into Calm\r\nStar Killer is a soothing indica-dominant hybrid that captures the essence of a quiet night under the stars. With sweet notes of dark cherries, earthy undertones, and a hint of spice, this aromatic strain offers a calming, dreamy experience that gently eases both body and mind into pure relaxation.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Star Killer delivers a smooth, flavorful smoke perfect for winding down after a long day. Thunder Bud<75>s precise grinding process ensures every pre-roll is packed with terpene-rich, potent hits<74>offering boutique-quality effects without the boutique price.\r\n\r\nRelax Your Spirit\r\nIdeal for evening sessions or lazy weekends, Star Killer provides a deeply relaxing body high paired with a gentle mental uplift. Let the soothing, euphoric effects melt away stress and tension, helping you find your perfect chill whether you<6F>re sinking into the couch or gazing at the night sky.\r\n\r\nSavor the Experience\r\nIndulge in the relaxing journey of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to preserve the rich flavors and calming aroma of Star Killer. Each pre-roll features finely ground small buds and resin-rich trim, adorned with shimmering trichomes, promising a smooth, flavorful burn from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s commitment to eco-friendly packaging lets you enjoy Star Killer while caring for the planet. ?\r\n\r\nUnwind with Star Killer <20> calming, dreamy highs at an unbeatable price.\r\nHere<72>s to peaceful nights, soothing moments, and relaxing vibes that won<6F>t break the bank.'],
|
||||
['sku' => 'TB-SL-AZ1G', 'desc' => 'Thunder Bud Slurricane <20> Blissful Vibes at a Great Price ??\r\n\r\nChill Delight\r\nThunder Bud Slurricane is an indica-dominant hybrid that offers a calming retreat from the day. With its sweet berry aroma and hints of earthy undertones, this strain provides a soothing escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Slurricane delivers a smooth, mellow smoke that<61>s perfect for unwinding. Our precise grinding process ensures each puff bursts with rich flavors and relaxing effects, all at an unbeatable price.\r\n\r\nRelaxing and Comforting\r\nIdeal for evening use, Slurricane provides a tranquil high that melts away stress and tension. Let the cozy vibes wrap around you as you kick back and enjoy your favorite activities, whether it<69>s watching a movie or sharing laughs with friends.\r\n\r\nImmerse in the Experience\r\nIndulge in the serene journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that delights the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The rich, dark hues of finely ground small buds and trim are beautifully complemented by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Slurricane <20> blissful vibes at an affordable price.\r\n\r\nCheers to relaxing moments, all without breaking the bank! ??'],
|
||||
['sku' => 'TB-SL-AZ3G', 'desc' => 'Thunder Bud Slurricane <20> Blissful Vibes at a Great Price ??\r\n\r\nChill Delight\r\nThunder Bud Slurricane is an indica-dominant hybrid that offers a calming retreat from the day. With its sweet berry aroma and hints of earthy undertones, this strain provides a soothing escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Slurricane delivers a smooth, mellow smoke that<61>s perfect for unwinding. Our precise grinding process ensures each puff bursts with rich flavors and relaxing effects, all at an unbeatable price.\r\n\r\nRelaxing and Comforting\r\nIdeal for evening use, Slurricane provides a tranquil high that melts away stress and tension. Let the cozy vibes wrap around you as you kick back and enjoy your favorite activities, whether it<69>s watching a movie or sharing laughs with friends.\r\n\r\nImmerse in the Experience\r\nIndulge in the serene journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that delights the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The rich, dark hues of finely ground small buds and trim are beautifully complemented by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Slurricane <20> blissful vibes at an affordable price.\r\n\r\nCheers to relaxing moments, all without breaking the bank! ??'],
|
||||
['sku' => 'TB-SL-AZ5G', 'desc' => 'Thunder Bud Slurricane <20> Blissful Vibes at a Great Price ??\r\n\r\nChill Delight\r\nThunder Bud Slurricane is an indica-dominant hybrid that offers a calming retreat from the day. With its sweet berry aroma and hints of earthy undertones, this strain provides a soothing escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Slurricane delivers a smooth, mellow smoke that<61>s perfect for unwinding. Our precise grinding process ensures each puff bursts with rich flavors and relaxing effects, all at an unbeatable price.\r\n\r\nRelaxing and Comforting\r\nIdeal for evening use, Slurricane provides a tranquil high that melts away stress and tension. Let the cozy vibes wrap around you as you kick back and enjoy your favorite activities, whether it<69>s watching a movie or sharing laughs with friends.\r\n\r\nImmerse in the Experience\r\nIndulge in the serene journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that delights the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The rich, dark hues of finely ground small buds and trim are beautifully complemented by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud Slurricane <20> blissful vibes at an affordable price.\r\n\r\nCheers to relaxing moments, all without breaking the bank! ??'],
|
||||
['sku' => 'TB-SS-AZ1G', 'desc' => 'Singapore Sling <20> Elevate Your Experience at an Unbeatable Price ??\r\n\r\nTropical Bliss Awaits\r\n\r\nSingapore Sling is a delightful sativa-dominant hybrid that offers a burst of tropical fruit flavors and a refreshing, lively aroma. This strain combines sweet, citrusy notes with subtle hints of earthy pine, creating a fragrant and flavorful escape that tantalizes your senses with every puff.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, Singapore Sling provides a smooth, vibrant smoke that<61>s perfect for daytime adventures and social gatherings. Thunder Bud<75>s precise grinding process ensures each inhale is packed with lively flavors and energizing effects, making it the ideal choice for those seeking an uplifting mood without breaking the bank.\r\n\r\nElevate Your Spirit\r\n\r\nDesigned for daytime enjoyment, Singapore Sling delivers a euphoric and creative high that keeps you alert, social, and ready to tackle whatever comes your way. Let the uplifting vibes inspire your next adventure, whether you<6F>re catching up with friends or diving into your creative flow.\r\n\r\nSavor the Experience\r\n\r\nIndulge in the tropical experience of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to preserve the essence of this fruity and energizing strain. Each pre-roll showcases finely ground small buds and trim, with rich, vibrant hues and shimmering trichomes, offering a smooth, flavorful smoke that promises a delightful encounter every time.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s eco-friendly packaging ensures that you can enjoy your premium cannabis while caring for the environment. ?\r\n\r\nElevate your day with Singapore Sling, tropical, uplifting highs at an unbeatable price.\r\n\r\nHere<72>s to bright vibes and effortless enjoyment, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-SW-AZ1G', 'desc' => 'Sunset Wedding <20> A Blissful Escape to Sweet Serenity ?Fruity Indulgence\r\n\r\nSweet, Smooth & Soothing\r\nSunset Wedding is an indulgent indica-dominant hybrid that offers the perfect blend of calming relaxation and sweet, fruity aromas. With notes of citrus, berry, and a touch of floral earthiness, this strain wraps you in a smooth, flavorful haze that<61>s perfect for unwinding after a long day or settling in for a peaceful evening.\r\n\r\nBig Highs, Small Price\r\nCrafted from high-quality trim and small buds, Sunset Wedding brings you premium flavor and potent effects without the premium price tag. Our precise grinding process ensures that each pre-roll is packed with rich, smooth smoke, delivering consistent relaxation with every puff.\r\n\r\nRelax and Unwind \r\nSunset Wedding\'s indica-dominant effects provide a deeply soothing, calming experience that<61>s perfect for relaxation and stress relief. Let the tranquil effects melt away the tension of the day while the gentle euphoria lifts your mood and leaves you feeling content and at ease. Ideal for solo evenings, cozy nights in, or winding down with friends.\r\n\r\nImmerse in the Experience\r\nIndulge in the delightful journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that excites the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The vibrant hues of finely ground small buds and trim are beautifully complemented by glistening trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nEscape to Relaxation with Thunder Bud Sunset Wedding <20> the perfect way to unwind without breaking the bank.\r\n\r\nHere<72>s to taking your time and enjoying the little moments in sweet serenity! ?'],
|
||||
['sku' => 'TB-TC-AZ1G', 'desc' => 'Thunder Bud Trop Cherry <20> Tropical Bliss at a Tiny Price ?\r\n\r\nTropical Delight\r\nThunder Bud Trop Cherry is an indica-dominant hybrid that brings the tropics to you. With its sweet cherry aroma and hints of tropical fruit, this strain is a delightful escape in every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Trop Cherry delivers a smooth, fruity smoke that<61>s as enjoyable as a tropical vacation. Our grinding process ensures each puff is packed with luscious flavors and relaxing effects.\r\n\r\nRelax and Unwind\r\nPerfect for evening use, Trop Cherry provides a calming and soothing high, making it ideal for unwinding after a busy day. Let the tropical vibes wash over you and melt away stress.\r\n\r\nIndulge in the Experience\r\nIndulge in the electrifying experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to encapsulate the essence of every strain. Thunder Bud presents a fusion of convenience and quality, delivering a sensory journey that ignites the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls boast a compact yet alluring appearance. The rich, earthy hues of the finely ground small buds and trim, generously packed within the confines of the paper, are punctuated by vibrant streaks of crystalline trichomes, promising a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging is kind to the Earth and perfect for your smoking sessions. ?\r\n\r\nEscape to the tropics with Thunder Bud Trop Cherry <20> sweet highs at an affordable price.\r\n\r\nCheers to tropical highs, at a small price!'],
|
||||
['sku' => 'TB-TC-AZ3G', 'desc' => 'Thunder Bud Trop Cherry <20> Tropical Bliss at a Tiny Price ?\r\n\r\nTropical Delight\r\nThunder Bud Trop Cherry is an indica-dominant hybrid that brings the tropics to you. With its sweet cherry aroma and hints of tropical fruit, this strain is a delightful escape in every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Trop Cherry delivers a smooth, fruity smoke that<61>s as enjoyable as a tropical vacation. Our grinding process ensures each puff is packed with luscious flavors and relaxing effects.\r\n\r\nRelax and Unwind\r\nPerfect for evening use, Trop Cherry provides a calming and soothing high, making it ideal for unwinding after a busy day. Let the tropical vibes wash over you and melt away stress.\r\n\r\nIndulge in the Experience\r\nIndulge in the electrifying experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to encapsulate the essence of every strain. Thunder Bud presents a fusion of convenience and quality, delivering a sensory journey that ignites the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls boast a compact yet alluring appearance. The rich, earthy hues of the finely ground small buds and trim, generously packed within the confines of the paper, are punctuated by vibrant streaks of crystalline trichomes, promising a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging is kind to the Earth and perfect for your smoking sessions. ?\r\n\r\nEscape to the tropics with Thunder Bud Trop Cherry <20> sweet highs at an affordable price.\r\n\r\nCheers to tropical highs, at a small price!'],
|
||||
['sku' => 'TB-TC-AZ5G', 'desc' => 'Thunder Bud Trop Cherry <20> Tropical Bliss at a Tiny Price ?\r\n\r\nTropical Delight\r\nThunder Bud Trop Cherry is an sativa-dominant hybrid that brings the tropics to you. With its sweet cherry aroma and hints of tropical fruit, this strain is a delightful escape in every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Trop Cherry delivers a smooth, fruity smoke that<61>s as enjoyable as a tropical vacation. Our grinding process ensures each puff is packed with luscious flavors and relaxing effects.\r\n\r\nRelax and Unwind\r\n\r\nPerfect for evening use, Trop Cherry provides a calming and soothing high, making it ideal for unwinding after a busy day. Let the tropical vibes wash over you and melt away stress.\r\n\r\nIndulge in the Experience\r\nIndulge in the electrifying experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to encapsulate the essence of every strain. Thunder Bud presents a fusion of convenience and quality, delivering a sensory journey that ignites the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls boast a compact yet alluring appearance. The rich, earthy hues of the finely ground small buds and trim, generously packed within the confines of the paper, are punctuated by vibrant streaks of crystalline trichomes, promising a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging is kind to the Earth and perfect for your smoking sessions. ?\r\n\r\nEscape to the tropics with Thunder Bud Trop Cherry <20> sweet highs at an affordable price.\r\n\r\nCheers to tropical highs, at a small price!'],
|
||||
['sku' => 'TB-TF-AZ1G', 'desc' => 'Thunder Bud Tire Fire <20> Ignite Your Senses at an Amazing Price ?\r\n\r\nFiery Indulgence\r\nThunder Bud Tire Fire is a bold hybrid strain that delivers a robust blend of flavors and effects, perfect for those looking to elevate their experience. With its rich, earthy aroma and hints of sweet spice, this strain offers a captivating escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Tire Fire provides a smooth and flavorful smoke that<61>s ideal for any occasion. Our meticulous grinding process ensures each puff is infused with deep, rich flavors and soothing effects, making it the perfect companion for unwinding after a long day.\r\n\r\nRelax and Recharge\r\nPerfect for both daytime and evening use, Tire Fire offers a balanced high that relaxes the body while keeping the mind engaged. Whether you\'re enjoying a quiet night in or catching up with friends, let the warm vibes elevate your mood and enhance your experience.\r\n\r\nSavor the Experience\r\nIndulge in the compelling experience of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of this intriguing strain. Thunder Bud combines convenience and quality, offering a sensory adventure that awakens the senses with every inhale. Each Thunder Bud Pre-Roll showcases an inviting design, featuring deep, earthy tones of finely ground small buds and trim, all highlighted by glistening trichomes, ensuring a satisfying encounter with each draw.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nDiscover the warm bliss of Thunder Bud Tire Fire <20> fiery highs at an unbeatable price.\r\n\r\nHere<72>s to memorable experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-TF-AZ3G', 'desc' => 'Thunder Bud Tire Fire <20> Ignite Your Senses at an Amazing Price ?\r\n\r\nFiery Indulgence\r\nThunder Bud Tire Fire is a bold hybrid strain that delivers a robust blend of flavors and effects, perfect for those looking to elevate their experience. With its rich, earthy aroma and hints of sweet spice, this strain offers a captivating escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Tire Fire provides a smooth and flavorful smoke that<61>s ideal for any occasion. Our meticulous grinding process ensures each puff is infused with deep, rich flavors and soothing effects, making it the perfect companion for unwinding after a long day.\r\n\r\nRelax and Recharge\r\nPerfect for both daytime and evening use, Tire Fire offers a balanced high that relaxes the body while keeping the mind engaged. Whether you\'re enjoying a quiet night in or catching up with friends, let the warm vibes elevate your mood and enhance your experience.\r\n\r\nSavor the Experience\r\nIndulge in the compelling experience of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of this intriguing strain. Thunder Bud combines convenience and quality, offering a sensory adventure that awakens the senses with every inhale. Each Thunder Bud Pre-Roll showcases an inviting design, featuring deep, earthy tones of finely ground small buds and trim, all highlighted by glistening trichomes, ensuring a satisfying encounter with each draw.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nDiscover the warm bliss of Thunder Bud Tire Fire <20> fiery highs at an unbeatable price.\r\n\r\nHere<72>s to memorable experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-TF-AZ5G', 'desc' => 'Thunder Bud Tire Fire <20> Ignite Your Senses at an Amazing Price ?\r\n\r\nFiery Indulgence\r\nThunder Bud Tire Fire is a bold hybrid strain that delivers a robust blend of flavors and effects, perfect for those looking to elevate their experience. With its rich, earthy aroma and hints of sweet spice, this strain offers a captivating escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Tire Fire provides a smooth and flavorful smoke that<61>s ideal for any occasion. Our meticulous grinding process ensures each puff is infused with deep, rich flavors and soothing effects, making it the perfect companion for unwinding after a long day.\r\n\r\nRelax and Recharge\r\nPerfect for both daytime and evening use, Tire Fire offers a balanced high that relaxes the body while keeping the mind engaged. Whether you\'re enjoying a quiet night in or catching up with friends, let the warm vibes elevate your mood and enhance your experience.\r\n\r\nSavor the Experience\r\nIndulge in the compelling experience of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of this intriguing strain. Thunder Bud combines convenience and quality, offering a sensory adventure that awakens the senses with every inhale. Each Thunder Bud Pre-Roll showcases an inviting design, featuring deep, earthy tones of finely ground small buds and trim, all highlighted by glistening trichomes, ensuring a satisfying encounter with each draw.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nDiscover the warm bliss of Thunder Bud Tire Fire <20> fiery highs at an unbeatable price.\r\n\r\nHere<72>s to memorable experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-TO-AZ1G', 'desc' => 'The One <20> Smooth Highs at an Unbeatable Price ??\r\n\r\nFind Your Balance\r\n\r\nThe One is a well-rounded hybrid that blends relaxing body effects with an uplifting cerebral edge. Its flavor profile is a mix of sweet earthiness, subtle spice, and a touch of herbal freshness, creating a smooth and flavorful smoke that satisfies the senses. Perfect for those seeking harmony between mind and body.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, The One delivers a rich, balanced smoke that offers strong effects without straining your wallet. Thunder Bud<75>s precise grinding process ensures consistency in every puff, bringing out the strain<69>s full-bodied flavor and even-keeled high.\r\n\r\nRelax and Elevate\r\n\r\nDesigned for any time of day, The One provides a calming yet uplifting high that enhances your mood while keeping you grounded. Whether you are unwinding after work, hanging with friends, or tapping into your creative side, this strain adapts to your vibe and helps you feel centered.\r\n\r\nSavor the Experience\r\n\r\nEnjoy the smooth and flavorful world of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to capture the essence of The One. Each pre-roll is packed with finely ground buds and trim, showcasing shimmering trichomes and offering a steady, satisfying smoke from start to finish.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud delivers quality highs while staying committed to eco-friendly packaging. ?\r\n\r\nDiscover The One <20> balanced flavor, versatile highs, and unbeatable value.\r\n\r\nHere<72>s to good vibes and steady energy, all while being kind to your wallet. ?'],
|
||||
['sku' => 'TB-TS-AZ1G', 'desc' => 'Lather Up with The Soap <20> Supreme Strain Experience at a Smart Price ?\r\n\r\nAll-Star Clean\r\nThe Soap is a standout hybrid strain known for its signature effects and distinctive flavor profile. Named for its clean, refreshing taste and potent high, this strain offers a delightful blend of zesty citrus, sweet herbal notes, and subtle earthy undertones.\r\n\r\nSupreme Effects, Smart Price\r\nCrafted from top-tier trim and smalls, The Soap delivers a smooth and powerful smoke that shines in both flavor and impact. Our careful grinding process ensures a high-quality experience without breaking the bank, providing premium effects at an accessible price.\r\n\r\nEuphoric and Uplifting\r\nPerfect for any moment, The Soap delivers an energetic, euphoric high that enhances mood and creativity. Whether you\'re tackling tasks or winding down, this strain is ideal for any occasion, delivering a refreshing and invigorating experience.\r\n\r\nIndulge in the Clean Experience\r\nImmerse yourself in the exceptional quality of Thunder Bud Trim+Smalls Pre-Rolls, designed to capture the essence of each strain with precision. Thunder Bud combines convenience with excellence, offering a sensory journey that energizes with every puff. Each pre-roll is expertly crafted, featuring fine, evenly ground small buds and trim encased in premium rolling paper. The rich, inviting colors and the glistening trichomes signal a potent and satisfying smoke.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with The Soap from Thunder Bud <20> exceptional highs at a smart price.\r\n\r\nCheers to a cleaner, more enjoyable high! ?'],
|
||||
['sku' => 'TB-TS-AZ3G', 'desc' => 'Lather Up with The Soap <20> Supreme Strain Experience at a Smart Price ?\r\n\r\nAll-Star Clean\r\nThe Soap is a standout hybrid strain known for its signature effects and distinctive flavor profile. Named for its clean, refreshing taste and potent high, this strain offers a delightful blend of zesty citrus, sweet herbal notes, and subtle earthy undertones.\r\n\r\nSupreme Effects, Smart Price\r\nCrafted from top-tier trim and smalls, The Soap delivers a smooth and powerful smoke that shines in both flavor and impact. Our careful grinding process ensures a high-quality experience without breaking the bank, providing premium effects at an accessible price.\r\n\r\nEuphoric and Uplifting\r\nPerfect for any moment, The Soap delivers an energetic, euphoric high that enhances mood and creativity. Whether you\'re tackling tasks or winding down, this strain is ideal for any occasion, delivering a refreshing and invigorating experience.\r\n\r\nIndulge in the Clean Experience\r\nImmerse yourself in the exceptional quality of Thunder Bud Trim+Smalls Pre-Rolls, designed to capture the essence of each strain with precision. Thunder Bud combines convenience with excellence, offering a sensory journey that energizes with every puff. Each pre-roll is expertly crafted, featuring fine, evenly ground small buds and trim encased in premium rolling paper. The rich, inviting colors and the glistening trichomes signal a potent and satisfying smoke.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with The Soap from Thunder Bud <20> exceptional highs at a smart price.\r\n\r\nCheers to a cleaner, more enjoyable high! ?'],
|
||||
['sku' => 'TB-TS-AZ5G', 'desc' => 'Lather Up with The Soap <20> Supreme Strain Experience at a Smart Price ?\r\n\r\nAll-Star Clean\r\nThe Soap is a standout hybrid strain known for its signature effects and distinctive flavor profile. Named for its clean, refreshing taste and potent high, this strain offers a delightful blend of zesty citrus, sweet herbal notes, and subtle earthy undertones.\r\n\r\nSupreme Effects, Smart Price\r\nCrafted from top-tier trim and smalls, The Soap delivers a smooth and powerful smoke that shines in both flavor and impact. Our careful grinding process ensures a high-quality experience without breaking the bank, providing premium effects at an accessible price.\r\n\r\nEuphoric and Uplifting\r\nPerfect for any moment, The Soap delivers an energetic, euphoric high that enhances mood and creativity. Whether you\'re tackling tasks or winding down, this strain is ideal for any occasion, delivering a refreshing and invigorating experience.\r\n\r\nIndulge in the Clean Experience\r\nImmerse yourself in the exceptional quality of Thunder Bud Trim+Smalls Pre-Rolls, designed to capture the essence of each strain with precision. Thunder Bud combines convenience with excellence, offering a sensory journey that energizes with every puff. Each pre-roll is expertly crafted, featuring fine, evenly ground small buds and trim encased in premium rolling paper. The rich, inviting colors and the glistening trichomes signal a potent and satisfying smoke.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with The Soap from Thunder Bud <20> exceptional highs at a smart price.\r\n\r\nCheers to a cleaner, more enjoyable high! ?'],
|
||||
['sku' => 'TB-VC-AZ1G', 'desc' => 'Vice City <20> Urban Vibes, High Thrills ??\r\n\r\nCityscape Experience\r\nVice City is an electrifying hybrid strain inspired by the vibrant energy of urban nightlife. Renowned for its potent effects and dynamic flavor profile, this strain delivers a blend of sweet, citrusy, and woody notes that capture the essence of city life.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Vice City offers a smooth, potent smoke that hits all the right notes in both flavor and effect. Our careful grinding process ensures you get a high-quality experience without breaking the bank.\r\n\r\nEnergizing and Creative\r\nPerfect for any time of day, Vice City provides a euphoric and stimulating high that enhances mood and sparks creativity. Whether you\'re exploring the city or unwinding at home, this strain is your ideal companion for any adventure.\r\n\r\nImmerse in the Experience\r\nDive into the vibrant world of Vice City Trim+Smalls Pre-Rolls, expertly crafted to capture the true essence of each strain. Vice City blends convenience with top-notch quality, offering a sensory experience that invigorates with every inhale. Each Vice City Pre-Roll is meticulously rolled in premium paper, showcasing a compact yet captivating design. The rich, golden hues of finely ground small buds and trim are interspersed with shimmering trichomes, promising a potent and enjoyable smoke with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your sessions with Vice City <20> where urban excitement meets affordable highs.\r\n\r\nCheers to vibrant city vibes and high thrills! ??'],
|
||||
['sku' => 'TB-VC-AZ3G', 'desc' => 'Vice City <20> Urban Vibes, High Thrills ??\r\n\r\nCityscape Experience\r\nVice City is an electrifying hybrid strain inspired by the vibrant energy of urban nightlife. Renowned for its potent effects and dynamic flavor profile, this strain delivers a blend of sweet, citrusy, and woody notes that capture the essence of city life.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Vice City offers a smooth, potent smoke that hits all the right notes in both flavor and effect. Our careful grinding process ensures you get a high-quality experience without breaking the bank.\r\n\r\nEnergizing and Creative\r\nPerfect for any time of day, Vice City provides a euphoric and stimulating high that enhances mood and sparks creativity. Whether you\'re exploring the city or unwinding at home, this strain is your ideal companion for any adventure.\r\n\r\nImmerse in the Experience\r\nDive into the vibrant world of Vice City Trim+Smalls Pre-Rolls, expertly crafted to capture the true essence of each strain. Vice City blends convenience with top-notch quality, offering a sensory experience that invigorates with every inhale. Each Vice City Pre-Roll is meticulously rolled in premium paper, showcasing a compact yet captivating design. The rich, golden hues of finely ground small buds and trim are interspersed with shimmering trichomes, promising a potent and enjoyable smoke with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your sessions with Vice City <20> where urban excitement meets affordable highs.\r\n\r\nCheers to vibrant city vibes and high thrills! ??'],
|
||||
['sku' => 'TB-VC-AZ5G', 'desc' => 'Vice City <20> Urban Vibes, High Thrills ??\r\n\r\nCityscape Experience\r\nVice City is an electrifying hybrid strain inspired by the vibrant energy of urban nightlife. Renowned for its potent effects and dynamic flavor profile, this strain delivers a blend of sweet, citrusy, and woody notes that capture the essence of city life.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Vice City offers a smooth, potent smoke that hits all the right notes in both flavor and effect. Our careful grinding process ensures you get a high-quality experience without breaking the bank.\r\n\r\nEnergizing and Creative\r\nPerfect for any time of day, Vice City provides a euphoric and stimulating high that enhances mood and sparks creativity. Whether you\'re exploring the city or unwinding at home, this strain is your ideal companion for any adventure.\r\n\r\nImmerse in the Experience\r\nDive into the vibrant world of Vice City Trim+Smalls Pre-Rolls, expertly crafted to capture the true essence of each strain. Vice City blends convenience with top-notch quality, offering a sensory experience that invigorates with every inhale. Each Vice City Pre-Roll is meticulously rolled in premium paper, showcasing a compact yet captivating design. The rich, golden hues of finely ground small buds and trim are interspersed with shimmering trichomes, promising a potent and enjoyable smoke with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your sessions with Vice City <20> where urban excitement meets affordable highs.\r\n\r\nCheers to vibrant city vibes and high thrills! ??'],
|
||||
['sku' => 'TB-VM-AZ1G', 'desc' => 'Violet Meadows <20> Drift into Tranquility at an Unbeatable Price ??\r\n\r\nA Floral Escape into Relaxation\r\n\r\nViolet Meadows is a soothing indica-dominant hybrid that captures the serene beauty of a meadow bathed in twilight. With sweet notes of ripe berries, delicate florals, and a hint of earthy undertones, this aromatic strain offers a calming, dreamy experience that gently eases you into pure relaxation.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, Violet Meadows delivers a smooth, flavorful smoke perfect for winding down after a long day. Thunder Bud<75>s precise grinding process ensures that every pre-roll is packed with terpene-rich, potent hits bringing you boutique quality without the boutique price tag.\r\n\r\nRelax Your Spirit\r\n\r\nPerfect for evening sessions or lazy weekends, Violet Meadows provides a deeply relaxing body high paired with a soft mental uplift. Let the gentle, euphoric effects melt away your stress, helping you find your perfect chill whether you\'re sinking into the couch or savoring a peaceful moment under the stars.\r\n\r\nSavor the Experience\r\n\r\nIndulge in the fragrant journey of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to preserve the lush flavors and soothing aroma of Violet Meadows. Each pre-roll showcases finely ground small buds and resin-rich trim, with shimmering trichomes that promise a flavorful, smooth burn from start to finish.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s commitment to eco-friendly packaging lets you enjoy your premium cannabis while caring for the planet. ?\r\n\r\nUnwind with Violet Meadows, soothing, dreamy highs at an unbeatable price.\r\n\r\nHere<72>s to peaceful nights and calm moments, all while keeping your wallet happy!'],
|
||||
['sku' => 'TB-WB-AZ1G', 'desc' => 'Wrecking Ball <20> Balanced Relaxation at an Unbeatable Price ???\r\n\r\nA Potent Escape into Calm\r\nWrecking Ball is a hybrid strain that combines soothing relaxation with a gentle cerebral lift. With rich notes of sweet berries, earthy undertones, and a hint of spice, this aromatic strain provides a comforting, flavorful experience that eases both mind and body while keeping your mood lightly uplifted.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Wrecking Ball delivers a smooth, satisfying smoke perfect for unwinding after a long day. Thunder Bud<75>s precise grinding process ensures each pre-roll is packed with terpene-rich flower, giving boutique-quality effects without the boutique price tag.\r\n\r\nRelax and Elevate\r\nIdeal for evenings or laid-back weekends, Wrecking Ball provides a calming body high with a soft mental boost. Let the gentle, euphoric effects melt away stress while keeping your mind pleasantly engaged, perfect for relaxing on the couch, enjoying a peaceful moment, or sharing time with friends.\r\n\r\nSavor the Experience\r\nExperience the rich flavors of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to preserve the essence of Wrecking Ball. Each pre-roll features finely ground small buds and resin-rich trim with shimmering trichomes, promising a smooth, flavorful burn from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s eco-conscious packaging allows you to enjoy Wrecking Ball while supporting the planet. ?\r\n\r\nUnwind with Wrecking Ball <20> balanced, flavorful highs at an unbeatable price.\r\nHere<72>s to calm evenings, relaxing vibes, and stress-free moments, all while keeping your wallet happy.'],
|
||||
['sku' => 'TB-WNLA-AZ1G', 'desc' => 'Walkin-N-LA <20> Step into Bliss at an Unbeatable Price ?????\r\n\r\nCali Vibes Await\r\n\r\nWalkin-N-LA is a delightful indica-dominant hybrid that combines the calming effects of relaxation with a subtle burst of citrus and earthy flavors. Its distinct lemon and pine aroma, enhanced by a touch of sweetness, provides an irresistible escape, grounding the senses with every puff.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from premium trim and smalls, Walkin-N-LA delivers a smooth, mellow smoke that<61>s perfect for unwinding after a busy day. Thunder Bud<75>s precise grinding process ensures each inhale is packed with rich, relaxing flavors and soothing effects, making it an ideal choice for those seeking tranquility without the hefty price.\r\n\r\nRelax and Unwind\r\n\r\nDesigned for evening enjoyment, Walkin-N-LA provides a calming and peaceful high that helps you relax and let go of the stresses of the day. Whether you<6F>re winding down on your own or sharing good times with friends, let the mellow vibes help you find your balance and enjoy your surroundings.\r\n\r\nSavor the Experience\r\n\r\nIndulge in the relaxing experience of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to capture the essence of this soothing strain. Each pre-roll features finely ground small buds and trim, showcasing rich, vibrant hues with shimmering trichomes, offering a smooth, calming smoke that promises a peaceful encounter every time.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s commitment to eco-friendly packaging ensures you can enjoy Walkin-N-LA while supporting a healthier planet. ?\r\n\r\nUnwind with Walkin-N-LA, relaxing, mellow highs at an unbeatable price.\r\n\r\nHere<72>s to peaceful moments and calming vibes, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-WP-AZ1G', 'desc' => 'White Poison <20> Energize Your Day at an Unbeatable Price ??\r\n\r\nA Zesty Escape into Focused Energy\r\nWhite Poison is a vibrant sativa-dominant hybrid that sparks creativity and elevates your senses. With bright citrus notes, subtle floral hints, and a touch of earthy spice, this aromatic strain provides a refreshing, uplifting experience that keeps the mind alert and energized.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, White Poison delivers a smooth, flavorful smoke that invigorates without overwhelming. Thunder Bud<75>s precise grinding process ensures every pre-roll is packed with terpene-rich, potent hits<74>bringing boutique-quality effects at an affordable price.\r\n\r\nElevate Your Spirit\r\nPerfect for daytime use, White Poison provides a clear-headed, energizing high that enhances focus and creativity. Whether you<6F>re tackling projects, socializing with friends, or exploring new ideas, this strain keeps your mind sharp and your vibes bright.\r\n\r\nSavor the Experience\r\nIndulge in the lively journey of Thunder Bud Trim+Smalls Pre-Rolls, meticulously crafted to capture the vibrant essence of White Poison. Each pre-roll features finely ground small buds and resin-rich trim, with shimmering trichomes, promising a flavorful, smooth burn from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s commitment to eco-friendly packaging lets you enjoy White Poison while caring for the planet. ?\r\n\r\nBoost your day with White Poison <20> uplifting, energizing highs at an unbeatable price.\r\nHere<72>s to productive days, inspired moments, and positive energy, all while keeping your wallet happy!'],
|
||||
['sku' => 'TB-WT-AZ1G', 'desc' => 'Thunder Bud White Truffle <20> Luxurious Vibes at a Great Price ?\r\n\r\nGourmet Delight\r\nThunder Bud White Truffle is an exquisite indica-dominant hybrid that envelops you in a rich, relaxing experience. With its earthy, herbal aroma and subtle hints of sweetness, this strain offers a delightful escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, White Truffle delivers a smooth, velvety smoke that<61>s perfect for unwinding after a long day. Our meticulous grinding process ensures each puff is packed with deep flavors and calming effects, all at an unbeatable price.\r\n\r\nRelaxing and Indulgent\r\nIdeal for evening use, White Truffle provides a soothing high that melts away stress and tension. Let the comforting vibes wash over you as you kick back and enjoy a cozy night in, whether it<69>s diving into a good book or savoring your favorite film.\r\n\r\nImmerse in the Experience\r\nIndulge in the luxurious journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that delights the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The rich, earthy tones of finely ground small buds and trim are beautifully complemented by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud White Truffle <20> luxurious vibes at an affordable price.\r\n\r\nCheers to indulgent moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-WT-AZ3G', 'desc' => 'Thunder Bud White Truffle <20> Luxurious Vibes at a Great Price ?\r\n\r\nGourmet Delight\r\nThunder Bud White Truffle is an exquisite indica-dominant hybrid that envelops you in a rich, relaxing experience. With its earthy, herbal aroma and subtle hints of sweetness, this strain offers a delightful escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, White Truffle delivers a smooth, velvety smoke that<61>s perfect for unwinding after a long day. Our meticulous grinding process ensures each puff is packed with deep flavors and calming effects, all at an unbeatable price.\r\n\r\nRelaxing and Indulgent\r\nIdeal for evening use, White Truffle provides a soothing high that melts away stress and tension. Let the comforting vibes wash over you as you kick back and enjoy a cozy night in, whether it<69>s diving into a good book or savoring your favorite film.\r\n\r\nImmerse in the Experience\r\nIndulge in the luxurious journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that delights the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The rich, earthy tones of finely ground small buds and trim are beautifully complemented by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud White Truffle <20> luxurious vibes at an affordable price.\r\n\r\nCheers to indulgent moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-WT-AZ5G', 'desc' => 'Thunder Bud White Truffle <20> Luxurious Vibes at a Great Price ?\r\n\r\nGourmet Delight\r\nThunder Bud White Truffle is an exquisite indica-dominant hybrid that envelops you in a rich, relaxing experience. With its earthy, herbal aroma and subtle hints of sweetness, this strain offers a delightful escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, White Truffle delivers a smooth, velvety smoke that<61>s perfect for unwinding after a long day. Our meticulous grinding process ensures each puff is packed with deep flavors and calming effects, all at an unbeatable price.\r\n\r\nRelaxing and Indulgent\r\nIdeal for evening use, White Truffle provides a soothing high that melts away stress and tension. Let the comforting vibes wash over you as you kick back and enjoy a cozy night in, whether it<69>s diving into a good book or savoring your favorite film.\r\n\r\nImmerse in the Experience\r\nIndulge in the luxurious journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that delights the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The rich, earthy tones of finely ground small buds and trim are beautifully complemented by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud White Truffle <20> luxurious vibes at an affordable price.\r\n\r\nCheers to indulgent moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-WT-PP-AZ28G', 'desc' => 'Thunder Bud White Truffle <20> Luxurious Vibes at a Great Price ?\r\n\r\nGourmet Delight\r\n\r\nThunder Bud White Truffle is an exquisite indica-dominant hybrid that envelops you in a rich, relaxing experience. With its earthy, herbal aroma and subtle hints of sweetness, this strain offers a delightful escape with every puff.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from the finest trim and smalls, White Truffle delivers a smooth, velvety smoke that<61>s perfect for unwinding after a long day. Our meticulous grinding process ensures each puff is packed with deep flavors and calming effects, all at an unbeatable price.\r\n\r\nRelaxing and Indulgent\r\n\r\nIdeal for evening use, White Truffle provides a soothing high that melts away stress and tension. Let the comforting vibes wash over you as you kick back and enjoy a cozy night in, whether it<69>s diving into a good book or savoring your favorite film.\r\n\r\nImmerse in the Experience\r\n\r\nIndulge in the luxurious journey of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of every strain. Thunder Bud combines convenience with quality, delivering a sensory experience that delights the senses with each inhale. Each pre-roll is a testament to precision and craftsmanship. Wrapped in premium rolling paper, these pre-rolls feature a compact yet inviting appearance. The rich, earthy tones of finely ground small buds and trim are beautifully complemented by shimmering trichomes, promising a satisfying experience with every puff.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nElevate your experience with Thunder Bud White Truffle <20> luxurious vibes at an affordable price.\r\n\r\nCheers to indulgent moments, all without breaking the bank! ?'],
|
||||
['sku' => 'TB-YS-AZ1G', 'desc' => 'Yodi Soda <20> Balanced Relaxation at an Unbeatable Price ??\r\n\r\nA Sparkling Escape into Calm\r\nYodi Soda is a hybrid strain that delivers a harmonious blend of relaxation and gentle mental uplift. With sweet notes of tropical fruits, subtle citrus, and a hint of earthy undertones, this aromatic strain provides a soothing, flavorful experience that eases both mind and body while keeping your mood lightly elevated.\r\n\r\nBig Highs, Small Price\r\nCrafted from premium trim and smalls, Yodi Soda offers a smooth, satisfying smoke perfect for unwinding after a long day. Thunder Bud<75>s precise grinding process ensures each pre-roll is packed with terpene-rich flower, providing boutique-quality effects without the boutique price tag.\r\n\r\nRelax and Refresh\r\nIdeal for evenings or quiet weekends, Yodi Soda provides a calming body high paired with a soft cerebral lift. Let the gentle, euphoric effects melt away stress while keeping your mind pleasantly engaged, perfect for relaxing on the couch, enjoying a peaceful moment, or sharing time with friends.\r\n\r\nSavor the Experience\r\nExperience the vibrant flavors of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to preserve the essence of Yodi Soda. Each pre-roll features finely ground small buds and resin-rich trim with shimmering trichomes, promising a smooth, flavorful burn from start to finish.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s eco-conscious packaging lets you enjoy Yodi Soda while supporting the planet. ?\r\n\r\nUnwind with Yodi Soda <20> balanced, flavorful highs at an unbeatable price.\r\nHere<72>s to relaxing evenings, refreshing vibes, and stress-free moments, all while keeping your wallet happy.'],
|
||||
['sku' => 'TB-ZC-AZ1G', 'desc' => 'Thunder Bud Zack\'s Cake <20> Elevate Your Indulgence at an Exceptional Price ?\r\n\r\nDecadent Delight\r\n\r\nThunder Bud Zack\'s Cake is a luscious hybrid strain that brings together the sweetness of dessert with a balanced high. With its rich vanilla and cake-like aroma, complemented by subtle hints of spice, this strain offers a delightful escape with every puff.\r\n\r\nBig Highs, Small Price\r\n\r\nCrafted from the finest trim and smalls, Zack\'s Cake delivers a smooth, flavorful smoke that<61>s perfect for any celebration. Our meticulous grinding process ensures each puff is infused with decadent flavors and comforting effects, making it an ideal choice for unwinding or enjoying special moments.\r\n\r\nRelax and Savor\r\n\r\nPerfect for both daytime and evening use, Zack\'s Cake provides a gentle high that soothes the body while uplifting the mind. Whether you\'re celebrating with friends or enjoying a quiet evening at home, let the delightful vibes elevate your mood and enhance your experience.\r\n\r\nSavor the Journey\r\n\r\nIndulge in the sweet experience of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of this scrumptious strain. Thunder Bud combines convenience and quality, offering a sensory adventure that awakens the senses with every inhale. Each Thunder Bud Pre-Roll showcases an inviting appearance, featuring warm, rich hues of finely ground small buds and trim, all adorned with shimmering trichomes, ensuring a satisfying encounter with each draw.\r\n\r\nEco-Friendly Packaging\r\n\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nDiscover the bliss of Thunder Bud Zack\'s Cake <20> deliciously uplifting highs at an unbeatable price.\r\n\r\nHere<72>s to sweet experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-ZC-AZ3G', 'desc' => 'Thunder Bud Zack\'s Cake <20> Elevate Your Indulgence at an Exceptional Price ?\r\n\r\nDecadent Delight\r\nThunder Bud Zack\'s Cake is a luscious hybrid strain that brings together the sweetness of dessert with a balanced high. With its rich vanilla and cake-like aroma, complemented by subtle hints of spice, this strain offers a delightful escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Zack\'s Cake delivers a smooth, flavorful smoke that<61>s perfect for any celebration. Our meticulous grinding process ensures each puff is infused with decadent flavors and comforting effects, making it an ideal choice for unwinding or enjoying special moments.\r\n\r\nRelax and Savor\r\nPerfect for both daytime and evening use, Zack\'s Cake provides a gentle high that soothes the body while uplifting the mind. Whether you\'re celebrating with friends or enjoying a quiet evening at home, let the delightful vibes elevate your mood and enhance your experience.\r\n\r\nSavor the Journey\r\nIndulge in the sweet experience of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of this scrumptious strain. Thunder Bud combines convenience and quality, offering a sensory adventure that awakens the senses with every inhale. Each Thunder Bud Pre-Roll showcases an inviting appearance, featuring warm, rich hues of finely ground small buds and trim, all adorned with shimmering trichomes, ensuring a satisfying encounter with each draw.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nDiscover the bliss of Thunder Bud Zack\'s Cake <20> deliciously uplifting highs at an unbeatable price.\r\n\r\nHere<72>s to sweet experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-ZC-AZ5G', 'desc' => 'Thunder Bud Zack\'s Cake <20> Elevate Your Indulgence at an Exceptional Price ?\r\n\r\nDecadent Delight\r\nThunder Bud Zack\'s Cake is a luscious hybrid strain that brings together the sweetness of dessert with a balanced high. With its rich vanilla and cake-like aroma, complemented by subtle hints of spice, this strain offers a delightful escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Zack\'s Cake delivers a smooth, flavorful smoke that<61>s perfect for any celebration. Our meticulous grinding process ensures each puff is infused with decadent flavors and comforting effects, making it an ideal choice for unwinding or enjoying special moments.\r\n\r\nRelax and Savor\r\nPerfect for both daytime and evening use, Zack\'s Cake provides a gentle high that soothes the body while uplifting the mind. Whether you\'re celebrating with friends or enjoying a quiet evening at home, let the delightful vibes elevate your mood and enhance your experience.\r\n\r\nSavor the Journey\r\nIndulge in the sweet experience of Thunder Bud Trim+Smalls Pre-Rolls, expertly crafted to capture the essence of this scrumptious strain. Thunder Bud combines convenience and quality, offering a sensory adventure that awakens the senses with every inhale. Each Thunder Bud Pre-Roll showcases an inviting appearance, featuring warm, rich hues of finely ground small buds and trim, all adorned with shimmering trichomes, ensuring a satisfying encounter with each draw.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging supports your high while caring for the environment. ?\r\n\r\nDiscover the bliss of Thunder Bud Zack\'s Cake <20> deliciously uplifting highs at an unbeatable price.\r\n\r\nHere<72>s to sweet experiences, all while being kind to your wallet!'],
|
||||
['sku' => 'TB-ZT-AZ1G', 'desc' => 'Thunder Bud Za-Tiva <20> Elevate Your Spirit at a Great Price ?\r\n\r\nEnergizing Delight\r\nThunder Bud Za-Tiva is a sativa-dominant hybrid that brings a burst of energy and creativity to your day. With its zesty citrus aroma and subtle herbal notes, this strain offers a refreshing escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Za-Tiva delivers a smooth, uplifting smoke that<61>s perfect for any adventure. Our meticulous grinding process ensures each puff is infused with vibrant flavors and invigorating effects.\r\n\r\nEnergize and Inspire\r\nIdeal for daytime use, Za-Tiva provides a clear-headed and motivating high, making it perfect for tackling tasks or enjoying social gatherings. Let the uplifting vibes elevate your mood and spark your creativity.\r\n\r\nIndulge in the Experience\r\nIndulge in the exhilarating experience of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to capture the essence of every strain. Thunder Bud combines convenience and quality, offering a sensory journey that awakens the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls showcase a compact yet enticing appearance. The rich, earthy tones of finely ground small buds and trim are highlighted by glistening trichomes, promising a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging is kind to the Earth and perfect for your smoking sessions. ?\r\n\r\nEscape to a state of bliss with Thunder Bud Za-Tiva <20> energizing highs at an affordable price.\r\n\r\nCheers to uplifting experiences, all without breaking the bank!'],
|
||||
['sku' => 'TB-ZT-AZ3G', 'desc' => 'Thunder Bud Za-Tiva <20> Elevate Your Spirit at a Great Price ?\r\n\r\nEnergizing Delight\r\nThunder Bud Za-Tiva is a sativa-dominant hybrid that brings a burst of energy and creativity to your day. With its zesty citrus aroma and subtle herbal notes, this strain offers a refreshing escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Za-Tiva delivers a smooth, uplifting smoke that<61>s perfect for any adventure. Our meticulous grinding process ensures each puff is infused with vibrant flavors and invigorating effects.\r\n\r\nEnergize and Inspire\r\nIdeal for daytime use, Za-Tiva provides a clear-headed and motivating high, making it perfect for tackling tasks or enjoying social gatherings. Let the uplifting vibes elevate your mood and spark your creativity.\r\n\r\nIndulge in the Experience\r\nIndulge in the exhilarating experience of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to capture the essence of every strain. Thunder Bud combines convenience and quality, offering a sensory journey that awakens the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls showcase a compact yet enticing appearance. The rich, earthy tones of finely ground small buds and trim are highlighted by glistening trichomes, promising a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging is kind to the Earth and perfect for your smoking sessions. ?\r\n\r\nEscape to a state of bliss with Thunder Bud Za-Tiva <20> energizing highs at an affordable price.\r\n\r\nCheers to uplifting experiences, all without breaking the bank!'],
|
||||
['sku' => 'TB-ZT-AZ5G', 'desc' => 'Thunder Bud Za-Tiva <20> Elevate Your Spirit at a Great Price ?\r\n\r\nEnergizing Delight\r\nThunder Bud Za-Tiva is a sativa-dominant hybrid that brings a burst of energy and creativity to your day. With its zesty citrus aroma and subtle herbal notes, this strain offers a refreshing escape with every puff.\r\n\r\nBig Highs, Small Price\r\nCrafted from the finest trim and smalls, Za-Tiva delivers a smooth, uplifting smoke that<61>s perfect for any adventure. Our meticulous grinding process ensures each puff is infused with vibrant flavors and invigorating effects.\r\n\r\nEnergize and Inspire\r\nIdeal for daytime use, Za-Tiva provides a clear-headed and motivating high, making it perfect for tackling tasks or enjoying social gatherings. Let the uplifting vibes elevate your mood and spark your creativity.\r\n\r\nIndulge in the Experience\r\nIndulge in the exhilarating experience of Thunder Bud Trim+Smalls Pre-Rolls, carefully crafted to capture the essence of every strain. Thunder Bud combines convenience and quality, offering a sensory journey that awakens the senses with every inhale. Each Thunder Bud Pre-Roll is a testament to precision and finesse. Wrapped in premium rolling paper, these pre-rolls showcase a compact yet enticing appearance. The rich, earthy tones of finely ground small buds and trim are highlighted by glistening trichomes, promising a potent encounter with each puff.\r\n\r\nEco-Friendly Packaging\r\nThunder Bud<75>s responsible packaging is kind to the Earth and perfect for your smoking sessions. ?\r\n\r\nEscape to a state of bliss with Thunder Bud Za-Tiva <20> energizing highs at an affordable price.\r\n\r\nCheers to uplifting experiences, all without breaking the bank!'],
|
||||
['sku' => 'TW-CG-AZ1.25G', 'desc' => 'Twisties: Citral Glue + Rosin Jam Infused\r\n\r\nStick with Bliss with Twisties: Citral Glue + Rosin Jam ??\r\n\r\nGet ready for a high you won\'t soon forget with Twisties Citral Glue! This rare hybrid strain packs a super heady high and an insanely loud flavor into every tasty toke. Infused with rosin jam for that extra kick, Twisties Citral Glue is sustainably sourced and responsibly packaged, proudly crafted by Arizonans, bringing you nothing but the purest plant goodness. Infused with Blonde Hash it\'s sure to get you where you want to be.\r\n\r\nKey Features:\r\n\r\nBalanced Hybrid: Citral Glue offers an energetic and cerebral high that fuels creativity, focus, and an overall sense of motivation. Perfect for daytime adventures or when you want to feel mentally sharp and engaged. ?\r\n\r\nRosin Jam Infused: With the addition of rosin jam, this strain amps up the intensity, taking your experience to the next level of bliss and potency. A stronger, longer-lasting effect for those who crave a more powerful experience. ??\r\n\r\nEuphoric Rush: Starts with a rush of euphoria that tingles through your mind, pushing you further into blissful oblivion. ??\r\n\r\nGiggly Goodness: As the high progresses, you\'ll find yourself laughing at anything and everything around you. ??\r\n\r\nRelaxing Physical High: A light, relaxing physical high accompanies the heady lift, keeping you anchored to the world below as your mind soars. ???\r\n\r\nSharp Sour Citrus Flavor: Enjoy a sharp sour citrus flavor with a dank herbal skunky exhale. ??\r\n\r\nAromatically Pungent: The aroma follows the same profile, with a heavy hit of pungency to it. ??\r\n\r\nAll Flower Only: Made with premium flower for a clean, natural experience. ?\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ? Responsibly Packaged: Stylish, eco-friendly packaging that you can feel good about. ??\r\n\r\nCitral Glue isn<73>t just a strain; it\'s an adventure in every puff. With the added potency of rosin jam, this strain reaches new heights of euphoria and relaxation. Perfect for those moments when you want to let go and let laughter take over. Whether you<6F>re looking to unwind after a long day or simply want to enjoy some giggly goodness, Citral Glue is your go-to choice.\r\n\r\nSo, grab your Twisties: Citral Glue today and stick with the bliss. This premium pre-roll is your ticket to a euphoric, out-of-this-world experience. Let the good times roll with Twisties! ??'],
|
||||
['sku' => 'TW-GC-AZ1.25G', 'desc' => 'Twisties: Garlic Cocktail + Rosin Jam Infused\r\n\r\nStick with Bliss with Twisties: Garlic Cocktail! ??\r\n\r\nGet ready to savor the unforgettable experience of Twisties Garlic Cocktail! This bold hybrid strain offers a punchy high and a mouthwatering flavor profile in every puff. Infused with rosin jam for that extra boost, Garlic Cocktail is crafted for those who seek a potent and flavorful journey. Proudly created by Arizonans, this strain is sustainably sourced and responsibly packaged to ensure the purest plant goodness with every smoke.\r\n\r\nKey Features:\r\n\r\nHybrid Delight: Garlic Cocktail strikes the perfect balance, delivering an uplifting mental high while soothing your body, making it ideal for any time you need a burst of energy or a relaxed vibe. ??\r\n\r\nRosin Jam Infused: Infused with rosin jam, this strain enhances potency, providing a stronger, longer-lasting experience that will elevate your senses and relaxation. ??\r\n\r\nUnique Flavor Kick: Experience a bold, savory flavor with earthy garlic notes, complemented by hints of spicy citrus and herbal undertones. It<49>s a flavor profile like no other, designed to delight your taste buds with every inhale. ??\r\n\r\nEuphoric Buzz: Kick off your experience with a cerebral rush that inspires creativity and happiness, giving you the perfect mental boost to get things done or unwind. ??\r\n\r\nRelax and Unwind: As the high settles in, you<6F>ll feel your body relax and your mind at ease, creating a laid-back experience ideal for chilling after a long day or enjoying time with friends. ???\r\n\r\nAromatically Rich: The aroma matches the flavor, with a robust garlic scent paired with fresh, herbal tones that captivate the senses and let you know you\'re in for a flavorful ride. ??\r\n\r\nAll Flower Only: Made with premium flower for a clean, natural experience. ?\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\nResponsibly Packaged: Stylish, eco-friendly packaging that you can feel good about. ??\r\n\r\nGarlic Cocktail isn<73>t just a strain; it<69>s a flavorful adventure that packs a punch. With the added intensity of rosin jam, this strain offers a unique and powerful experience that takes your relaxation and creativity to new levels. Perfect for moments when you want something extraordinary to unwind or enjoy with friends.\r\n\r\nSo grab your Twisties: Garlic Cocktail today and stick with the bliss. This premium pre-roll is your ticket to a savory, euphoric experience. Let the good times roll with Twisties! ??'],
|
||||
['sku' => 'TW-I-AF-AZ1.25G', 'desc' => 'Twisties: Apple Fritter + Rosin Jam Infused\r\n\r\nStick with Bliss with Twisties: Apple Fritter! ??\r\n\r\nGet ready to indulge in the unforgettable experience of Twisties Apple Fritter! This delightful hybrid strain delivers a perfect balance of relaxation and euphoria, with a deliciously sweet flavor profile that will leave you craving more. Infused with rosin jam for that extra kick, Twisties Apple Fritter is sustainably sourced and responsibly packaged, proudly crafted by Arizonans to bring you the purest, most flavorful plant goodness.\r\n\r\n\r\nKey Features:\r\n\r\nHybrid Delight: Apple Fritter offers a balanced high that uplifts your mood while providing deep body relaxation. It<49>s the perfect choice for anytime you want to relax, unwind, or elevate your creative energy. ??\r\n\r\nRosin Jam Infused: With the addition of rosin jam, Apple Fritter amps up the potency, giving you a more intense, longer-lasting high that enhances your experience. For those who crave an extra punch, this strain delivers. ??\r\n\r\nEuphoric Bliss: The journey begins with a burst of happiness that flows through your mind, sparking creativity and a feeling of joy that<61>ll brighten your day. ??\r\n\r\nChill and Cozy Vibes: As the high settles in, you<6F>ll feel your body relax and your stress melt away, making it the ideal strain for unwinding after a busy day or enjoying a quiet evening with friends. ???\r\n\r\nSweet, Fruity Flavor: Apple Fritter is a flavor sensation, featuring a blend of sweet, baked apple and doughy, cinnamon-infused goodness. It<49>s like enjoying your favorite pastry with every puff. ??\r\n\r\nAromatic and Inviting: The aroma mirrors the flavor, with sweet, fruity apple notes paired with a touch of cinnamon and earthiness. It<49>s a scent that entices and soothes your senses. ??\r\n\r\nAll Flower Only: Made with premium flower for a clean, natural experience. ?\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\nResponsibly Packaged: Stylish, eco-friendly packaging that you can feel good about. ??\r\n\r\nApple Fritter isn<73>t just a strain; it<69>s an experience you<6F>ll savor. With the added power of rosin jam, this strain takes your relaxation and creativity to the next level. Perfect for those moments when you want to kick back, indulge, and enjoy life to the fullest.\r\n\r\nSo grab your Twisties: Apple Fritter today and stick with the bliss. This premium pre-roll is your ticket to a sweet, euphoric adventure. Let the good times roll with Twisties! ??'],
|
||||
['sku' => 'TW-I-CG-AZ1G', 'desc' => 'Twisties: Citral Glue + Rosin Jam Infused\r\n\r\nStick with Bliss with Twisties: Citral Glue + Rosin Jam ??\r\n\r\nGet ready for a high you won\'t soon forget with Twisties Citral Glue! This rare hybrid strain packs a super heady high and an insanely loud flavor into every tasty toke. Infused with rosin jam for that extra kick, Twisties Citral Glue is sustainably sourced and responsibly packaged, proudly crafted by Arizonans, bringing you nothing but the purest plant goodness. Infused with Blonde Hash it\'s sure to get you where you want to be.\r\n\r\nKey Features:\r\n\r\nSativa-Dominant Hybrid: Citral Glue offers an energetic and cerebral high that fuels creativity, focus, and an overall sense of motivation. Perfect for daytime adventures or when you want to feel mentally sharp and engaged. ?\r\n\r\nRosin Jam Infused: With the addition of rosin jam, this strain amps up the intensity, taking your experience to the next level of bliss and potency. A stronger, longer-lasting effect for those who crave a more powerful experience. ??\r\n\r\nEuphoric Rush: Starts with a rush of euphoria that tingles through your mind, pushing you further into blissful oblivion. ??\r\n\r\nGiggly Goodness: As the high progresses, you\'ll find yourself laughing at anything and everything around you. ??\r\n\r\nRelaxing Physical High: A light, relaxing physical high accompanies the heady lift, keeping you anchored to the world below as your mind soars. ???\r\n\r\nSharp Sour Citrus Flavor: Enjoy a sharp sour citrus flavor with a dank herbal skunky exhale. ??\r\n\r\nAromatically Pungent: The aroma follows the same profile, with a heavy hit of pungency to it. ??\r\n\r\nAll Flower Only: Made with premium flower for a clean, natural experience. ?\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ? Responsibly Packaged: Stylish, eco-friendly packaging that you can feel good about. ??\r\n\r\nCitral Glue isn<73>t just a strain; it\'s an adventure in every puff. With the added potency of rosin jam, this strain reaches new heights of euphoria and relaxation. Perfect for those moments when you want to let go and let laughter take over. Whether you<6F>re looking to unwind after a long day or simply want to enjoy some giggly goodness, Citral Glue is your go-to choice.\r\n\r\nSo, grab your Twisties: Citral Glue today and stick with the bliss. This premium pre-roll is your ticket to a euphoric, out-of-this-world experience. Let the good times roll with Twisties! ??'],
|
||||
['sku' => 'TW-I-FF-AZ1.25G', 'desc' => 'Twisties: Fluff Fumez + Rosin Jam Infused\r\n\r\nStick with Bliss with Twisties: Fluff Fumez! ????\r\n\r\nGet ready to elevate your senses with Twisties Fluff Fumez! This indulgent hybrid strain brings a smooth, euphoric high and a sweet, creamy flavor profile that will leave you floating in bliss. Infused with rosin jam for an added potency boost, Twisties Fluff Fumez is sustainably sourced and responsibly packaged, proudly crafted by Arizonans to deliver the purest plant goodness with every puff.\r\n\r\nKey Features:\r\n\r\nHybrid Bliss: Fluff Fumez offers the perfect balance, uplifting your mood and calming your body in equal measure. Whether you<6F>re looking to relax after a busy day or need a creative spark, this strain has you covered. ??\r\n\r\nRosin Jam Infused: With the addition of rosin jam, Fluff Fumez intensifies your experience, providing a longer-lasting and more potent high for those who crave extra strength and relaxation. ??\r\n\r\nEuphoric Flight: Begin your journey with a blissful rush of euphoria that lifts your spirits, inspiring creativity and good vibes with every inhale. ??\r\n\r\nSmooth and Relaxed Vibes: As the high settles in, you\'ll find yourself in a peaceful, mellow state, perfect for winding down or enjoying time with friends. ???\r\n\r\nSweet, Creamy Flavor: Savor the rich, creamy flavor with subtle hints of vanilla and sweet fruitiness, delivering a smooth and indulgent experience with every puff. ??\r\n\r\nAromatically Enchanting: The aroma mirrors the flavor with soft, sweet, and creamy notes that captivate the senses, inviting you to relax and unwind. ??\r\n\r\nAll Flower Only: Made with premium flower for a clean, natural experience. ?\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\nResponsibly Packaged: Stylish, eco-friendly packaging that you can feel good about. ??\r\n\r\nFluff Fumez isn<73>t just a strain; it<69>s an ethereal experience. With the potency of rosin jam, this strain takes your relaxation and creativity to new heights. Perfect for those moments when you want to float away into bliss or simply enjoy some quality time with friends.\r\n\r\nSo grab your Twisties: Fluff Fumez today and stick with the bliss. This premium pre-roll is your ticket to a sweet, euphoric journey. Let the good times roll with Twisties! ???'],
|
||||
['sku' => 'TW-I-MM-AZ1.25G', 'desc' => 'Twisties: Mo Meat (100% Flower Blend + Rosin Jam Infused)\r\n\r\nStick with Bliss with Twisties: Mo Meat! ??\r\n\r\nGet ready for a savory experience with Twisties Mo Meat! This bold indica strain offers a heavy-hitting high and a rich, meaty flavor profile in every satisfying puff. Infused with rosin jam for that added intensity, Twisties Mo Meat is sustainably sourced and responsibly packaged, proudly crafted by Arizonans to bring you the purest plant goodness.\r\n\r\nKey Features:\r\n\r\nIndica Relaxation: Mo Meat delivers a deep, calming high that relaxes both your mind and body, making it the perfect strain to enjoy when you want to unwind or settle in for the night. ??\r\n\r\nRosin Jam Infused: Extra potency for a more intense and satisfying experience. ??\r\n\r\nEuphoric Comfort: Start your journey with a warm, comforting wave of euphoria that fills your body and mind with a sense of peace and contentment. ??\r\n\r\nChill Vibes: As the high develops, you\'ll melt into a state of relaxation, perfect for kicking back, unwinding, or enjoying time with friends. ???\r\n\r\nSavory, Bold Flavor: Savor the hearty, savory taste with meaty, earthy undertones and subtle hints of spices, creating a unique and satisfying flavor that lingers with every puff. ??\r\n\r\nAromatically Robust: The aroma complements the flavor, with rich, earthy scents and a hint of savory spices that fill the air and prepare you for a truly unique experience. ??\r\n\r\nAll Flower Only: Made with premium flower for a clean, smooth experience from start to finish. ??\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\nResponsibly Packaged: Stylish, eco-friendly packaging that you can feel good about. ??\r\n\r\nMo Meat isn<73>t just a strain; it<69>s a savory adventure in every puff. With the added potency of rosin jam, this strain will elevate your relaxation and enjoyment to new heights. Perfect for those moments when you want to kick back after a long day, indulge in relaxation, or share a satisfying experience with friends.\r\n\r\nSo, grab your Twisties: Mo Meat today and stick with the bliss. This premium pre-roll is your ticket to a deliciously euphoric experience. Let the good times roll with Twisties! ??'],
|
||||
['sku' => 'TW-I-MS-AZ1.25G', 'desc' => 'Twisties: Mandarin Sunset (100% Flower Blend + Rosin Jam Infused)\r\n\r\nStick with Bliss with Twisties: Mandarin Sunset! ??\r\n\r\nGet ready for a relaxing experience with Twisties Mandarin Sunset! This soothing indica strain offers a calming high and a burst of citrusy flavor with every puff. Infused with rosin jam for that extra potency, Twisties Mandarin Sunset is sustainably sourced and responsibly packaged, proudly crafted by Arizonans to bring you the purest plant goodness.\r\n\r\nKey Features:\r\n\r\nIndica Relaxation: Mandarin Sunset provides a calming, tranquil high that soothes both your body and mind, making it perfect for winding down after a long day or enjoying a peaceful evening. ??\r\n\r\nRosin Jam Infused: Extra potency for a more intense and satisfying experience. ??\r\n\r\nEuphoric Calm: Begin your journey with a wave of euphoria that gently eases your mind into a state of bliss, leaving you feeling relaxed, happy, and stress-free. ??\r\n\r\nChill Vibes: As the high develops, you<6F>ll feel a deep sense of relaxation, ideal for kicking back and enjoying quiet time or good company. ???\r\n\r\nCitrusy, Sweet Flavor: Experience the refreshing taste of ripe mandarin oranges, with hints of sweet citrus and tropical fruit, delivering a smooth and satisfying exhale. ??\r\n\r\nAromatically Inviting: The aroma complements the flavor with a burst of citrus and a touch of earthiness, drawing you in with its refreshing and calming scent. ??\r\n\r\nAll Flower Only: Made with premium flower for a clean, smooth experience from start to finish. ??\r\n\r\nSustainably Sourced: An eco-friendly choice that respects our planet. ?\r\n\r\nResponsibly Packaged: Stylish, eco-friendly packaging that you can feel good about. ??\r\n\r\nMandarin Sunset isn<73>t just a strain; it<69>s a tranquil experience in every puff. With the added potency of rosin jam, this strain elevates your relaxation and calm to new heights. Perfect for those moments when you want to unwind, de-stress, or enjoy a peaceful night with friends.\r\n\r\nSo, grab your Twisties: Mandarin Sunset today and stick with the bliss. This premium pre-roll is your ticket to a calming, citrusy escape. Let the good times roll with Twisties! ??'],
|
||||
['sku' => 'WLC-BF-GZ', 'desc' => 'GRUNTZ <20> A Must-Have Exclusive\r\n\r\nGruntz is the kind of strain that turns ordinary shelves into must-visit destinations. With 20.15% THC and 22.99% total cannabinoids, it delivers a perfectly balanced, euphoric high that keeps customers coming back for more. Its 2.38% terpene content releases a mouthwatering, candy-sweet aroma with rich, fruity undertones, offering a flavor experience that stands out in any case.\r\n\r\nLimited production means true scarcity: once it<69>s gone, there<72>s no telling when it<69>ll return, fueling urgency and repeat visits. For dispensaries, Gruntz isn<73>t just another SKU it<69>s a traffic magnet that drives footfall and converts browsers into buyers who value quality and exclusivity.\r\n\r\nStocking Gruntz tells customers your shop carries only the best, making you the go-to source for connoisseur-grade flower. Don<6F>t miss the chance to secure this proven sales driver and give your menu a signature product that sets you apart. Get Gruntz on your shelves while you still can.'],
|
||||
['sku' => 'WLC-BF-IL', 'desc' => 'ILLEMONATI <20> A Strain Worth Chasing\r\n\r\nIllemonati is a standout strain destined to become your shop<6F>s secret weapon for attracting savvy customers. Featuring 20.53% THC and 24.14% total cannabinoids, it delivers a smooth, clear-headed high with just the right touch of body relaxation, making it a favorite for social smokers and creative minds alike.\r\n\r\nIts 1.28% terpene profile brings an intriguing, subtly earthy-sweet aroma that sets it apart from the usual shelf stock while still holding broad appeal. This isn<73>t mass-produced flower each batch is small-batch crafted and released in highly limited quantities. When it<69>s gone, there<72>s no set timeline for its return, creating true urgency for shoppers who don<6F>t want to miss out.\r\n\r\nFor dispensaries, Illemonati is more than just another strain it<69>s a conversation starter that builds trust and loyalty, converting casual visitors into repeat customers who know you carry the exclusive products worth chasing. Secure Illemonati now to keep your menu ahead of the curve.'],
|
||||
['sku' => 'WLC-BF-OI', 'desc' => 'Oishii <20> Premium Flavor, Premium Appeal\r\n\r\nOishii is a truly premium offering designed to set your dispensary apart with a can<61>t-get-it-anywhere-else experience. Featuring 20.07% THC and 24.12% total cannabinoids, Oishii delivers a smooth, blissful high that satisfies both daily smokers and adventurous newcomers alike.\r\n\r\nIts impressive 2.34% terpene profile unveils a delectable, sweet, exotic fruit aroma that captivates from the first whiff to the final exhale. This isn<73>t just flower it<69>s an irresistible traffic driver that turns first-time buyers into loyal fans.\r\n\r\nOishii drops in strictly limited quantities, making it the perfect urgency-boosting feature for your menu. When it<69>s sold out, there<72>s no telling when it will be back, pushing customers to act fast. Stocking Oishii shows your shop carries only the most exclusive, in-demand products that keep customers coming back for more.'],
|
||||
['sku' => 'WLC-CB-HG-AZ1G', 'desc' => 'Heaven<65>s Gate <20> Cured Batter\r\nPotent | Flavor-Forward | Full-Spectrum\r\n\r\nWalk through the clouds and straight into couchlock with Heaven<65>s Gate Cured Batter a divinely potent extract crafted for those who crave full-bodied flavor and deep, lasting effects.\r\n\r\nWhipped to a smooth, glossy consistency, this cured batter delivers rich terpene expression and high cannabinoid content in every dab. Expect a euphoric headrush that melts into serenity, with a flavor profile that blends sweet earth, gassy funk, and a whisper of citrus incense.\r\n\r\nPerfect for heavy hitters, late-night sessions, or anyone looking to meet the divine one glob at a time.\r\n\r\nEnter wisely. Exit stoned.'],
|
||||
['sku' => 'WLC-CS-C22-AZ1G', 'desc' => 'Cosmic 22 <20> Cured Sugar\r\nCrystalline Power | Out-of-Body Flavor | Interstellar Effects\r\n\r\nBlast off with Cosmic 22 Cured Sugar, a space-grade concentrate designed to shatter expectations and launch your senses. This cured sugar packs a terp-heavy punch with glistening crystal textures and a wet, saucy coating that hits like a solar flare.\r\n\r\nExpect a rush of heady euphoria, followed by a smooth, weightless body float. The flavor? Galactic. Bright citrus, candy gas, and a strange-but-satisfying herbal kick that lingers in your orbit.\r\n\r\nFor seasoned dabbers, deep thinkers, and anyone trying to leave Earth for a while.\r\n\r\nOne dab. Zero gravity.'],
|
||||
['sku' => 'WLC-CS-HG-AZ1G', 'desc' => 'Heaven<65>s Gate <20> Cured Sugar\r\nPotent | Crystallized Flavor | Full-Spectrum\r\n\r\nWalk through the clouds and straight into couchlock with Heaven<65>s Gate Cured Sugar a divinely potent extract crafted for those who crave bold terpene expression and a deeply grounded high.\r\n\r\nThis cured sugar features sparkling crystal textures drenched in rich, sticky terps. Expect a euphoric headrush that dissolves into peaceful stillness, with notes of sweet earth, gassy funk, and a touch of citrus incense riding every hit.\r\n\r\nPerfect for seasoned dabbers, late-night rituals, or anyone ready to meet the divine one dab at a time.\r\n\r\nEnter wisely. Exit stoned.'],
|
||||
['sku' => 'WLC-CS-TB-AZ1G', 'desc' => 'Tropical Blood <20> Cured Sugar\r\nCrystalized Mayhem | Bold Fruit | Loud Gas\r\n\r\nTropical Blood Cured Sugar hits like a fruit-fueled ambush. Crystallized to perfection with a terp-rich glaze, this extract balances tropical sweetness with a deep, gassy backbone that lingers like heat on your tongue.\r\n\r\nThe high kicks off bright and euphoric, then melts into full-body stasis. It<49>s the kind of dab that tastes like vacation but leaves you glued to the couch, questioning time.\r\n\r\nSweet. Funky. Unforgiving. This one stains your brain.'],
|
||||
['sku' => 'WLC-DR', 'desc' => 'DARK RAINBOW <20> A True Showstopper\r\n\r\nDark Rainbow is a powerhouse strain designed to turn any menu into a destination. Packing an impressive 29.77% THC and 35.46% total Cannabinoids, it delivers a euphoric, luxurious high that satisfies even the most discerning customers.\r\n\r\nIts 2.99% terpene profile bursts with layered fruit, earth, and spice notes, creating a complex, unforgettable smoking experience. This isn<73>t just flower it<69>s a statement piece that draws attention, moves units, and turns one-time shoppers into loyal regulars.\r\n\r\nProduced only in extremely limited runs, Dark Rainbow disappears fast and may not return for months. That scarcity fuels urgency, exclusivity, and premium pricing potential.\r\n\r\nStocking Dark Rainbow signals that your store offers true connoisseur-grade product and sets you apart as a go-to destination for quality. Secure this conversation-starting, basket-building strain now to elevate your shelves and your sales.'],
|
||||
['sku' => 'WLC-GH-HFG', 'desc' => 'Granulated Hash - Hybrid Food Grade\r\nBalanced | Versatile | Full-Spectrum\r\n\r\nThis Hybrid Food Grade Granulated Hash offers a balanced blend of uplifting and relaxing effects, perfect for versatile infusion use. Milled to a fine, sandy consistency, it delivers full-spectrum potency with rich cannabinoid and terpene content. Ideal for blending into pre-rolls, edibles, or solventless concentrates, this hash brings consistent performance and a smooth, flavorful finish to any product it\'s infused into.'],
|
||||
['sku' => 'WLC-HG-CS', 'desc' => 'Heaven<65>s Gate Cured Sugar\r\n? One dab and you\'re on another plane.\r\n\r\nHeaven<65>s Gate isn<73>t just a name, it<69>s a whole vibe. This indica-leaning hybrid concentrate takes you beyond the clouds with a cured sugar consistency that hits smooth, tastes divine, and melts you into serenity.\r\n\r\nPop the lid and you<6F>re met with sweet floral notes, creamy citrus, and a soft touch of gas. It smells like a peaceful retreat wrapped in silk. Dab it and expect a warm headrush that eases into a deep, body-soothing calm. It<49>s the kind of high that quiets your thoughts, softens your edges, and wraps you up in your own private universe.\r\n\r\nThe cured sugar texture is golden, grippy, and easy to scoop. It delivers full-bodied flavor without the harshness, making it perfect for low-temp dabs and terp lovers alike. Whether you\'re winding down after a long day or setting the mood for a laid-back night, Heaven<65>s Gate has you covered.\r\n\r\n? Why you want it:\r\nDeeply relaxing hybrid high with a peaceful mental edge\r\nSweet citrus-gas flavor with floral undertones\r\nSmooth and manageable cured sugar texture\r\nIdeal for evening use, stress relief, or zoning all the way out\r\n\r\nThis one doesn<73>t just help you unplug it helps you ascend.'],
|
||||
['sku' => 'WLC-IH', 'desc' => 'Pure. Potent. Perfect for rolling. Our Ice Water Hash is a solventless extract crafted with nothing but ice, water, and premium flower, preserving the full-spectrum essence of the plant. Its fine, sandy consistency makes it easy to work with, ideal for evenly coating or blending into prerolls for a smooth, slow-burning experience.\r\n\r\nExpect big flavor, boosted potency, and a clean, terp-rich smoke every time. No solvents, no shortcuts, just cold water, pure resin, and next-level infusion power.\r\n\r\n? Why You<6F>ll Love It:\r\n? Solventless & clean\r\n? High terpene content for full flavor\r\n? Perfect texture for infusing prerolls'],
|
||||
['sku' => 'WLC-JC', 'desc' => 'JELLY CAKE is a Cannabrands-exclusive that redefines what premium shelf space should deliver. Boasting a potent 25.45% THC and a staggering 29.98% total cannabinoids, it<69>s crafted to satisfy those seeking\r\nrich, long-lasting effects that blend full body relaxation with an uplifting mental spark. Its remarkable 3.04% terpene profile is a true showstopper, bursting with layered notes of juicy berries, creamy vanilla, and subtle\r\nherbal undertones creating an unforgettable sensory journey. \r\n\r\nLimited-run harvests mean once it<69>s sold through, it might be months before your customers see it again if ever. This scarcity drives demand, sparks conversations, and keeps customers checking in for the next drop. \r\n\r\nStocking Jelly Cake tells your clientele you curate only the most exceptional, buzz worthy strains. It<49>s not just another SKU it<69>s the reason they choose your dispensary over the rest. Bring in Jelly Cake and watch your store become the go-to spot for serious cannabis connoisseurs.'],
|
||||
['sku' => 'WLC-LHR-S-FG', 'desc' => 'Sativa Food Grade Live Hash Rosin\r\nUplifting | Solventless\r\n\r\nCrafted from fresh frozen flower and processed without solvents, this Sativa Food Grade Live Hash Rosin delivers bright, energetic effects with a clean, citrus-forward terpene profile. Its smooth, pliable texture makes it ideal for infusions, vapes, or solventless formulations where clarity and flavor shine. Perfect for products designed to elevate and inspire.'],
|
||||
['sku' => 'WLC-MB', 'desc' => 'Moonbow <20> Rare Flavor, Rare Experience ?\r\n\r\nMoonbow is a signature strain that sets your shop apart with something truly special. Packing 24.77% THC and 28.84% total cannabinoids, it delivers a luxurious high that<61>s both deeply relaxing and mentally expansive, perfect for anyone seeking a premium escape.\r\n\r\nIts impressive 3.73% terpene profile bursts with mouthwatering fruit-candy sweetness, layered florals, and earthy undertones for a complex, unforgettable aroma. Moonbow isn<73>t part of any mass-market rotation; it arrives in carefully controlled, limited harvests that sell out quickly and return unpredictably, keeping customers checking back.\r\n\r\nStocking Moonbow turns your dispensary into a true destination for connoisseurs chasing rare finds. It<49>s more than just flower it<69>s an experience that builds buzz, drives immediate sell-through, and transforms casual shoppers into loyal, repeat visitors who know you always have something exceptional on your shelves'],
|
||||
['sku' => 'WLC-T-CS', 'desc' => 'Trinity Cured Sugar\r\n? Pure cerebral crackle in every dab.\r\n\r\nThis isn<73>t your average extract. It<49>s Trinity, a balanced hybrid with a loyal underground following, now whipped into a golden cured sugar that delivers clarity, calm, and just the right touch of body buzz.\r\n\r\nCrack open the jar and you<6F>re greeted with a hit of earthy pine, citrus zest, and a sweet-skunky punch that lets you know it means business. One dab in and you\'re off<66>elevated, focused, and riding a wave that floats you through your day without weighing you down.\r\n\r\nThe cured sugar texture is clean and easy to work with. It<49>s gritty but pliable, perfect for low-temp dabs that let the terps shine. Trinity<74>s high is all about balanced bliss. Your mind feels sharp and uplifted, while your body unwinds into a mellow hum that lingers without locking you to the couch.\r\n\r\n? Why you want it:\r\nCreative, euphoric head high paired with smooth body relief\r\nSkunky citrus-pine flavor that hits hard and lingers\r\nClean, scoopable texture made for terp lovers\r\nStrong but functional high for both daytime and evening use\r\nThis is Trinity in its best form. Loud flavor, big effects, no nonsense.'],
|
||||
['sku' => 'WLC-TB-CS', 'desc' => 'Tropical Blood Cured Sugar\r\n? Lush, loud, and bleeding with flavor.\r\n\r\nTropical Blood is a wild ride from first whiff to final exhale. This exotic indica-leaning hybrid cured sugar delivers juicy island vibes with a deep, hazy finish that sticks to your soul. It<49>s tropical punch with a side of menace.\r\n\r\nCrack the lid and you<6F>re slapped with overripe pineapple, sweet berries, and a dank, earthy funk that cuts through the fruit like a machete. One dab in and it<69>s all head rush and heat at first, then the comedown hits with a warm body melt that settles deep into your limbs. Chill, heavy, and euphoric without knocking you out cold.\r\n\r\nThe cured sugar texture is dense and resin-rich, with a glistening amber hue that practically screams potency. Terps are loud, flavors are sticky, and the effects are thick. Perfect for night sessions, creative zoning, or just straight-up tuning out.\r\n\r\n? Why you want it:\r\nTropical fruit flavor bomb with a gas-powered kick\r\nEuphoric head high followed by full-body sedation\r\nChunky cured sugar texture made for low-temp bliss\r\nGreat for evenings, creativity, or shutting the world off\r\n\r\nTropical Blood doesn<73>t whisper. It floods your senses and leaves you dripping in flavor and calm.'],
|
||||
['sku' => 'WLC-TB-SD', 'desc' => 'Tropical Blood <20> Diamonds & Sauce\r\nTerp-Soaked Chaos | Fruit-Driven Power | Brutal Clarity\r\n\r\nTropical Blood Diamonds & Sauce is a full-throttle extract built for flavor chasers and knockout seekers. Chunky THCa diamonds swim in a terp-rich sauce that explodes with tropical fruit, sour citrus, and that telltale gassy punch that lets you know you\'re in deep.\r\n\r\nThe high is sharp, immediate, and long-lasting<6E>starting with a cerebral rocket launch and ending in full-body gravity collapse. Clean. Loud. Dangerous in all the right ways.'],
|
||||
];
|
||||
@@ -0,0 +1,227 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Brand;
|
||||
use App\Models\Product;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* Backfill descriptions from MySQL hub_cannabrands database.
|
||||
*
|
||||
* This migration:
|
||||
* 1. Updates existing products with long_description from product_extras
|
||||
* 2. Creates missing Nuvata products (NU-* SKUs)
|
||||
* 3. Updates existing brands with tagline, description, long_description
|
||||
*
|
||||
* Idempotent: Only updates null fields, won't overwrite existing data.
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
protected string $mysqlConnection = 'mysql_import';
|
||||
|
||||
public function up(): void
|
||||
{
|
||||
// Check if mysql_import connection is configured
|
||||
if (! config('database.connections.mysql_import')) {
|
||||
echo "Skipping: mysql_import connection not configured.\n";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
DB::connection($this->mysqlConnection)->getPdo();
|
||||
} catch (\Exception $e) {
|
||||
echo "Skipping: Cannot connect to mysql_import database.\n";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->backfillProductDescriptions();
|
||||
$this->importNuvataProducts();
|
||||
$this->backfillBrandDescriptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update existing products with long_description from product_extras.
|
||||
*/
|
||||
protected function backfillProductDescriptions(): void
|
||||
{
|
||||
echo "Backfilling product long_descriptions...\n";
|
||||
|
||||
// Get all products with long_description from MySQL
|
||||
$mysqlProducts = DB::connection($this->mysqlConnection)
|
||||
->table('products')
|
||||
->join('product_extras', 'products.id', '=', 'product_extras.product_id')
|
||||
->whereNotNull('product_extras.long_description')
|
||||
->where('product_extras.long_description', '!=', '')
|
||||
->select('products.code as sku', 'product_extras.long_description')
|
||||
->get();
|
||||
|
||||
echo "Found {$mysqlProducts->count()} products with long_description in MySQL.\n";
|
||||
|
||||
$updated = 0;
|
||||
$skipped = 0;
|
||||
|
||||
foreach ($mysqlProducts as $mysqlProduct) {
|
||||
// Find matching product in PostgreSQL by SKU
|
||||
$pgProduct = Product::where('sku', $mysqlProduct->sku)->first();
|
||||
|
||||
if (! $pgProduct) {
|
||||
$skipped++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only update if long_description is null/empty
|
||||
if (empty($pgProduct->long_description)) {
|
||||
$pgProduct->update([
|
||||
'long_description' => $mysqlProduct->long_description,
|
||||
]);
|
||||
$updated++;
|
||||
} else {
|
||||
$skipped++;
|
||||
}
|
||||
}
|
||||
|
||||
echo "Updated {$updated} products, skipped {$skipped} (not found or already has data).\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Import missing Nuvata products (NU-* SKUs).
|
||||
*/
|
||||
protected function importNuvataProducts(): void
|
||||
{
|
||||
echo "Importing missing Nuvata products...\n";
|
||||
|
||||
// Find Nuvata brand in PostgreSQL
|
||||
$nuvataBrand = Brand::where('slug', 'nuvata')->first();
|
||||
|
||||
if (! $nuvataBrand) {
|
||||
echo "Nuvata brand not found in PostgreSQL. Skipping Nuvata product import.\n";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Get Nuvata products from MySQL
|
||||
$nuvataProducts = DB::connection($this->mysqlConnection)
|
||||
->table('products')
|
||||
->leftJoin('product_extras', 'products.id', '=', 'product_extras.product_id')
|
||||
->where('products.code', 'like', 'NU-%')
|
||||
->select(
|
||||
'products.code as sku',
|
||||
'products.name',
|
||||
'products.description',
|
||||
'products.wholesale_price',
|
||||
'products.active',
|
||||
'products.created_at',
|
||||
'products.updated_at',
|
||||
'product_extras.long_description'
|
||||
)
|
||||
->get();
|
||||
|
||||
echo "Found {$nuvataProducts->count()} Nuvata products in MySQL.\n";
|
||||
|
||||
$created = 0;
|
||||
$skipped = 0;
|
||||
|
||||
foreach ($nuvataProducts as $mysqlProduct) {
|
||||
// Check if product already exists
|
||||
if (Product::where('sku', $mysqlProduct->sku)->exists()) {
|
||||
$skipped++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Generate unique hashid
|
||||
$hashid = Str::random(8);
|
||||
while (Product::where('hashid', $hashid)->exists()) {
|
||||
$hashid = Str::random(8);
|
||||
}
|
||||
|
||||
Product::create([
|
||||
'brand_id' => $nuvataBrand->id,
|
||||
'hashid' => $hashid,
|
||||
'sku' => $mysqlProduct->sku,
|
||||
'name' => $mysqlProduct->name,
|
||||
'description' => $mysqlProduct->description,
|
||||
'long_description' => $mysqlProduct->long_description,
|
||||
'wholesale_price' => $mysqlProduct->wholesale_price,
|
||||
'is_active' => (bool) $mysqlProduct->active,
|
||||
'created_at' => $mysqlProduct->created_at,
|
||||
'updated_at' => $mysqlProduct->updated_at,
|
||||
]);
|
||||
|
||||
$created++;
|
||||
}
|
||||
|
||||
echo "Created {$created} Nuvata products, skipped {$skipped} existing.\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Update brands with tagline, description, and long_description.
|
||||
*/
|
||||
protected function backfillBrandDescriptions(): void
|
||||
{
|
||||
echo "Backfilling brand descriptions...\n";
|
||||
|
||||
// Get brands from MySQL with descriptions
|
||||
$mysqlBrands = DB::connection($this->mysqlConnection)
|
||||
->table('brands')
|
||||
->select('name', 'tagline', 'short_desc', 'desc')
|
||||
->get();
|
||||
|
||||
echo "Found {$mysqlBrands->count()} brands in MySQL.\n";
|
||||
|
||||
$updated = 0;
|
||||
$skipped = 0;
|
||||
|
||||
foreach ($mysqlBrands as $mysqlBrand) {
|
||||
$name = trim($mysqlBrand->name ?? '');
|
||||
if (! $name) {
|
||||
$skipped++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find matching brand in PostgreSQL by name (case-insensitive)
|
||||
$pgBrand = Brand::whereRaw('LOWER(name) = ?', [strtolower($name)])->first();
|
||||
|
||||
if (! $pgBrand) {
|
||||
$skipped++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$updates = [];
|
||||
|
||||
// Only update null/empty fields
|
||||
if (empty($pgBrand->tagline) && ! empty($mysqlBrand->tagline)) {
|
||||
$updates['tagline'] = $mysqlBrand->tagline;
|
||||
}
|
||||
|
||||
if (empty($pgBrand->description) && ! empty($mysqlBrand->short_desc)) {
|
||||
$updates['description'] = $mysqlBrand->short_desc;
|
||||
}
|
||||
|
||||
if (empty($pgBrand->long_description) && ! empty($mysqlBrand->desc)) {
|
||||
$updates['long_description'] = $mysqlBrand->desc;
|
||||
}
|
||||
|
||||
if (! empty($updates)) {
|
||||
$pgBrand->update($updates);
|
||||
$updated++;
|
||||
} else {
|
||||
$skipped++;
|
||||
}
|
||||
}
|
||||
|
||||
echo "Updated {$updated} brands, skipped {$skipped} (not found or already has data).\n";
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// This is a data backfill migration - no rollback needed
|
||||
// Data was only added to null fields, original data preserved
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Null out all product description fields in preparation for MySQL import.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
DB::table('products')->update([
|
||||
'description' => null,
|
||||
'consumer_long_description' => null,
|
||||
'buyer_long_description' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
// Cannot restore - data is gone
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Import product descriptions from MySQL for all brands except Hash Factory.
|
||||
* Data extracted from MySQL product_extras.long_description.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
$data = require database_path('data/product_descriptions_non_hf.php');
|
||||
|
||||
foreach ($data as $row) {
|
||||
DB::table('products')
|
||||
->where('sku', $row['sku'])
|
||||
->update([
|
||||
'consumer_long_description' => $row['desc'],
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
// Cannot restore - original data unknown
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Import product descriptions from MySQL for Hash Factory brand.
|
||||
* HF has marketing copy in products.description (not product_extras.long_description).
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
$data = require database_path('data/product_descriptions_hf.php');
|
||||
|
||||
foreach ($data as $row) {
|
||||
DB::table('products')
|
||||
->where('sku', $row['sku'])
|
||||
->update([
|
||||
'consumer_long_description' => $row['desc'],
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
// Cannot restore - original data unknown
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Brand;
|
||||
use App\Models\Product;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
$data = require database_path('data/missing_products.php');
|
||||
|
||||
// Cache brand IDs by slug
|
||||
$brandIds = Brand::whereIn('slug', array_unique(array_column($data, 'brand_slug')))
|
||||
->pluck('id', 'slug')
|
||||
->toArray();
|
||||
|
||||
foreach ($data as $row) {
|
||||
$brandId = $brandIds[$row['brand_slug']] ?? null;
|
||||
|
||||
if (! $brandId) {
|
||||
continue; // Skip if brand doesn't exist
|
||||
}
|
||||
|
||||
// Check if SKU exists (including soft-deleted - unique constraint applies to all)
|
||||
$existing = Product::withTrashed()->where('sku', $row['sku'])->first();
|
||||
|
||||
if ($existing) {
|
||||
// If soft-deleted, restore it and update
|
||||
if ($existing->trashed()) {
|
||||
$existing->restore();
|
||||
$existing->update([
|
||||
'consumer_long_description' => $row['desc'] ?: null,
|
||||
'is_active' => true,
|
||||
'status' => 'available',
|
||||
]);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
Product::create([
|
||||
'brand_id' => $brandId,
|
||||
'sku' => $row['sku'],
|
||||
'name' => $row['name'],
|
||||
'slug' => Str::slug($row['name']),
|
||||
'consumer_long_description' => $row['desc'] ?: null,
|
||||
'is_active' => true,
|
||||
'status' => 'available',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$data = require database_path('data/missing_products.php');
|
||||
$skus = array_column($data, 'sku');
|
||||
|
||||
Product::whereIn('sku', $skus)->forceDelete();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Product;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// Collect all valid SKUs from MySQL source data
|
||||
$validSkus = [];
|
||||
|
||||
// SKUs from non-HF descriptions import
|
||||
$nonHfData = require database_path('data/product_descriptions_non_hf.php');
|
||||
foreach ($nonHfData as $row) {
|
||||
$validSkus[] = $row['sku'];
|
||||
}
|
||||
|
||||
// SKUs from HF descriptions import
|
||||
$hfData = require database_path('data/product_descriptions_hf.php');
|
||||
foreach ($hfData as $row) {
|
||||
$validSkus[] = $row['sku'];
|
||||
}
|
||||
|
||||
// SKUs from missing products import
|
||||
$missingData = require database_path('data/missing_products.php');
|
||||
foreach ($missingData as $row) {
|
||||
$validSkus[] = $row['sku'];
|
||||
}
|
||||
|
||||
// Remove duplicates
|
||||
$validSkus = array_unique($validSkus);
|
||||
|
||||
// Get orphan products (exist in PG but not in MySQL source)
|
||||
// Soft-delete them, don't force delete
|
||||
Product::whereNotIn('sku', $validSkus)->delete();
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// Cannot restore - would need backup of deleted products
|
||||
// To restore: Product::onlyTrashed()->whereNotIn('sku', $validSkus)->restore();
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Product;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// Backfill hashids for products that don't have one
|
||||
Product::withTrashed()
|
||||
->whereNull('hashid')
|
||||
->orWhere('hashid', '')
|
||||
->each(function ($product) {
|
||||
$product->update(['hashid' => $product->generateHashid()]);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// Cannot undo - hashids are permanent identifiers
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
// Add CannaiQ fields to locations
|
||||
Schema::table('locations', function (Blueprint $table) {
|
||||
$table->string('cannaiq_platform')->nullable()->after('notes'); // 'dutchie', 'jane', etc.
|
||||
$table->string('cannaiq_store_slug')->nullable()->after('cannaiq_platform');
|
||||
$table->string('cannaiq_store_id')->nullable()->after('cannaiq_store_slug');
|
||||
$table->string('cannaiq_store_name')->nullable()->after('cannaiq_store_id');
|
||||
});
|
||||
|
||||
// Create location_contact pivot table for location-specific contact roles
|
||||
Schema::create('location_contact', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('location_id')->constrained()->onDelete('cascade');
|
||||
$table->foreignId('contact_id')->constrained()->onDelete('cascade');
|
||||
$table->string('role')->default('buyer'); // buyer, ap, marketing, gm, etc.
|
||||
$table->boolean('is_primary')->default(false);
|
||||
$table->text('notes')->nullable();
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['location_id', 'contact_id', 'role']);
|
||||
});
|
||||
|
||||
// Add location_id to sales_opportunities
|
||||
Schema::table('sales_opportunities', function (Blueprint $table) {
|
||||
$table->foreignId('location_id')->nullable()->after('business_id')->constrained()->onDelete('set null');
|
||||
});
|
||||
|
||||
// Add location_id to crm_events (notes/activity)
|
||||
if (! Schema::hasColumn('crm_events', 'location_id')) {
|
||||
Schema::table('crm_events', function (Blueprint $table) {
|
||||
$table->foreignId('location_id')->nullable()->after('buyer_business_id')->constrained()->onDelete('set null');
|
||||
});
|
||||
}
|
||||
|
||||
// Add location_id to crm_tasks
|
||||
if (! Schema::hasColumn('crm_tasks', 'location_id')) {
|
||||
Schema::table('crm_tasks', function (Blueprint $table) {
|
||||
$table->foreignId('location_id')->nullable()->after('business_id')->constrained()->onDelete('set null');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('locations', function (Blueprint $table) {
|
||||
$table->dropColumn(['cannaiq_platform', 'cannaiq_store_slug', 'cannaiq_store_id', 'cannaiq_store_name']);
|
||||
});
|
||||
|
||||
Schema::dropIfExists('location_contact');
|
||||
|
||||
Schema::table('sales_opportunities', function (Blueprint $table) {
|
||||
$table->dropForeign(['location_id']);
|
||||
$table->dropColumn('location_id');
|
||||
});
|
||||
|
||||
if (Schema::hasColumn('crm_events', 'location_id')) {
|
||||
Schema::table('crm_events', function (Blueprint $table) {
|
||||
$table->dropForeign(['location_id']);
|
||||
$table->dropColumn('location_id');
|
||||
});
|
||||
}
|
||||
|
||||
if (Schema::hasColumn('crm_tasks', 'location_id')) {
|
||||
Schema::table('crm_tasks', function (Blueprint $table) {
|
||||
$table->dropForeign(['location_id']);
|
||||
$table->dropColumn('location_id');
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Product;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// Fix all product descriptions - normalize line endings and decode HTML entities
|
||||
Product::whereNotNull('consumer_long_description')
|
||||
->each(function ($product) {
|
||||
$desc = $product->consumer_long_description;
|
||||
$original = $desc;
|
||||
|
||||
// Normalize Windows CRLF (chr 13 + chr 10) to Unix LF (chr 10)
|
||||
$desc = str_replace("\r\n", "\n", $desc);
|
||||
$desc = str_replace("\r", "\n", $desc);
|
||||
|
||||
// Decode HTML entities (emoji codes like 🌱)
|
||||
$desc = html_entity_decode($desc, ENT_QUOTES | ENT_HTML5, 'UTF-8');
|
||||
|
||||
// Only update if changed
|
||||
if ($desc !== $original) {
|
||||
$product->update(['consumer_long_description' => $desc]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// Cannot reliably undo formatting changes
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Batch;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// Backfill hashids for batches that don't have one
|
||||
Batch::withTrashed()
|
||||
->whereNull('hashid')
|
||||
->orWhere('hashid', '')
|
||||
->each(function ($batch) {
|
||||
$batch->update(['hashid' => $batch->generateHashid()]);
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
// Cannot undo hashid generation
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* Fix schema mismatches in crm_quotes and crm_quote_items tables.
|
||||
*
|
||||
* Issues:
|
||||
* 1. crm_quote_items: Model uses 'sort_order' but migration created 'position'
|
||||
* 2. crm_quote_items: 'name' column is NOT NULL but controller doesn't provide it
|
||||
* 3. crm_quotes: 'account_id' is NOT NULL but should be nullable
|
||||
* 4. crm_quotes: 'valid_until' is NOT NULL but should be nullable
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// Fix crm_quotes table
|
||||
Schema::table('crm_quotes', function (Blueprint $table) {
|
||||
// Make account_id nullable - controller allows nullable
|
||||
if (Schema::hasColumn('crm_quotes', 'account_id')) {
|
||||
$table->foreignId('account_id')->nullable()->change();
|
||||
}
|
||||
// Make valid_until nullable - controller sets default if not provided
|
||||
if (Schema::hasColumn('crm_quotes', 'valid_until')) {
|
||||
$table->date('valid_until')->nullable()->change();
|
||||
}
|
||||
});
|
||||
|
||||
// Fix crm_quote_items table
|
||||
Schema::table('crm_quote_items', function (Blueprint $table) {
|
||||
// Rename position to sort_order to match model
|
||||
if (Schema::hasColumn('crm_quote_items', 'position') && ! Schema::hasColumn('crm_quote_items', 'sort_order')) {
|
||||
$table->renameColumn('position', 'sort_order');
|
||||
}
|
||||
});
|
||||
|
||||
// Make name nullable in a separate statement (required for PostgreSQL)
|
||||
Schema::table('crm_quote_items', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('crm_quote_items', 'name')) {
|
||||
$table->string('name')->nullable()->change();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('crm_quote_items', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('crm_quote_items', 'sort_order') && ! Schema::hasColumn('crm_quote_items', 'position')) {
|
||||
$table->renameColumn('sort_order', 'position');
|
||||
}
|
||||
});
|
||||
|
||||
Schema::table('crm_quote_items', function (Blueprint $table) {
|
||||
if (Schema::hasColumn('crm_quote_items', 'name')) {
|
||||
$table->string('name')->nullable(false)->change();
|
||||
}
|
||||
});
|
||||
|
||||
// Note: Not reverting account_id and valid_until nullability in down()
|
||||
// as that would be a breaking change
|
||||
}
|
||||
};
|
||||
@@ -247,15 +247,15 @@ html:not([data-theme="material"], [data-theme="material-dark"]) {
|
||||
|
||||
/* == Cannabrands Brand Colors ==
|
||||
* DO NOT CHANGE THESE COLORS!
|
||||
* Primary: #4B6FA4 (muted blue)
|
||||
* Success: #4E8D71 (muted green)
|
||||
* Primary: #4E8D71 (green - main action color)
|
||||
* Info: #4B6FA4 (blue - informational)
|
||||
* Error: #E1524D (clean red)
|
||||
* These are the official brand colors. */
|
||||
--color-primary: #4B6FA4;
|
||||
--color-primary: #4E8D71;
|
||||
--color-primary-content: #ffffff;
|
||||
--color-secondary: #4B6FA4;
|
||||
--color-secondary-content: #ffffff;
|
||||
--color-accent: #4B6FA4;
|
||||
--color-accent: #4E8D71;
|
||||
--color-accent-content: #ffffff;
|
||||
--color-neutral: #374151;
|
||||
--color-neutral-content: #ffffff;
|
||||
@@ -302,11 +302,11 @@ html:not([data-theme="material"], [data-theme="material-dark"]) {
|
||||
/* == Cannabrands Brand Colors (Dark) ==
|
||||
* DO NOT CHANGE THESE COLORS!
|
||||
* See light theme for brand color documentation. */
|
||||
--color-primary: #5A7FB4;
|
||||
--color-primary: #5E9D81;
|
||||
--color-primary-content: #ffffff;
|
||||
--color-secondary: #5A7FB4;
|
||||
--color-secondary-content: #ffffff;
|
||||
--color-accent: #5A7FB4;
|
||||
--color-accent: #5E9D81;
|
||||
--color-accent-content: #ffffff;
|
||||
--color-neutral: #9ca3af;
|
||||
--color-neutral-content: #1e2832;
|
||||
|
||||
@@ -5,24 +5,21 @@
|
||||
--}}
|
||||
@php
|
||||
$statusConfig = [
|
||||
// New orders (primary - blue)
|
||||
'new' => ['label' => 'New', 'class' => 'badge-primary'],
|
||||
// All active/in-progress states (neutral - gray)
|
||||
'buyer_modified' => ['label' => 'Modified', 'class' => 'badge-neutral'],
|
||||
'seller_modified' => ['label' => 'Modified', 'class' => 'badge-neutral'],
|
||||
'accepted' => ['label' => 'Accepted', 'class' => 'badge-neutral'],
|
||||
'in_progress' => ['label' => 'In Progress', 'class' => 'badge-neutral'],
|
||||
'ready_for_delivery' => ['label' => 'Buyer Review', 'class' => 'badge-neutral'],
|
||||
'out_for_delivery' => ['label' => 'Delivering', 'class' => 'badge-neutral'],
|
||||
'ready_for_manifest' => ['label' => 'Ready', 'class' => 'badge-neutral'],
|
||||
'approved_for_delivery' => ['label' => 'Ready', 'class' => 'badge-neutral'],
|
||||
'delivered' => ['label' => 'Delivered', 'class' => 'badge-neutral'],
|
||||
'buyer_approved' => ['label' => 'Complete', 'class' => 'badge-neutral'],
|
||||
'completed' => ['label' => 'Complete', 'class' => 'badge-neutral'],
|
||||
|
||||
// Terminal error states only (error - muted red)
|
||||
'cancelled' => ['label' => 'Cancelled', 'class' => 'badge-error'],
|
||||
'rejected' => ['label' => 'Rejected', 'class' => 'badge-error'],
|
||||
// All statuses use ghost (no color) style
|
||||
'new' => ['label' => 'New', 'class' => 'badge-ghost'],
|
||||
'buyer_modified' => ['label' => 'Modified', 'class' => 'badge-ghost'],
|
||||
'seller_modified' => ['label' => 'Modified', 'class' => 'badge-ghost'],
|
||||
'accepted' => ['label' => 'Accepted', 'class' => 'badge-ghost'],
|
||||
'in_progress' => ['label' => 'In Progress', 'class' => 'badge-ghost'],
|
||||
'ready_for_delivery' => ['label' => 'Buyer Review', 'class' => 'badge-ghost'],
|
||||
'out_for_delivery' => ['label' => 'Delivering', 'class' => 'badge-ghost'],
|
||||
'ready_for_manifest' => ['label' => 'Ready', 'class' => 'badge-ghost'],
|
||||
'approved_for_delivery' => ['label' => 'Ready', 'class' => 'badge-ghost'],
|
||||
'delivered' => ['label' => 'Delivered', 'class' => 'badge-ghost'],
|
||||
'buyer_approved' => ['label' => 'Complete', 'class' => 'badge-ghost'],
|
||||
'completed' => ['label' => 'Complete', 'class' => 'badge-ghost'],
|
||||
'cancelled' => ['label' => 'Cancelled', 'class' => 'badge-ghost'],
|
||||
'rejected' => ['label' => 'Rejected', 'class' => 'badge-ghost'],
|
||||
];
|
||||
|
||||
$config = $statusConfig[$status] ?? ['label' => ucfirst(str_replace('_', ' ', $status)), 'class' => 'badge-neutral'];
|
||||
|
||||
@@ -165,6 +165,9 @@
|
||||
v{{ $appVersion }} (sha-{{ $appCommit }})
|
||||
@endif
|
||||
</p>
|
||||
@if($appBuildDate ?? null)
|
||||
<p class="text-[10px] text-base-content/40 mb-0.5">{{ $appBuildDate }}</p>
|
||||
@endif
|
||||
<p>© {{ date('Y') }} creationshop, {{ config('version.company.suffix') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -178,13 +178,16 @@
|
||||
<!-- Version Info Section -->
|
||||
<div class="mx-2 mb-3 px-3 text-xs text-center text-base-content/50">
|
||||
<p class="mb-0.5">{{ config('version.company.name') }} hub</p>
|
||||
<p class="mb-0.5" style="font-family: 'Courier New', monospace;">
|
||||
<p class="mb-0.5 font-mono">
|
||||
@if($appVersion === 'dev')
|
||||
<span class="text-yellow-500 font-semibold">DEV</span> sha-{{ $appCommit }}
|
||||
@else
|
||||
v{{ $appVersion }} (sha-{{ $appCommit }})
|
||||
@endif
|
||||
</p>
|
||||
@if($appBuildDate ?? null)
|
||||
<p class="text-[10px] text-base-content/40 mb-0.5">{{ $appBuildDate }}</p>
|
||||
@endif
|
||||
<p>© {{ date('Y') }} Made with <span class="text-error">♥</span> <a href="https://creationshop.io" target="_blank" rel="noopener noreferrer" class="link link-hover text-xs">Creationshop</a></p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -179,6 +179,9 @@
|
||||
v{{ $appVersion }} (sha-{{ $appCommit }})
|
||||
@endif
|
||||
</p>
|
||||
@if($appBuildDate ?? null)
|
||||
<p class="text-[10px] text-base-content/40 mb-0.5">{{ $appBuildDate }}</p>
|
||||
@endif
|
||||
<p>© {{ date('Y') }} creationshop, {{ config('version.company.suffix') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -25,20 +25,11 @@
|
||||
<div class="size-full overflow-y-auto"
|
||||
x-data="{
|
||||
init() {
|
||||
// Wait for collapse animations to complete (they take ~300ms)
|
||||
setTimeout(() => {
|
||||
// Scroll the active menu item into view
|
||||
const activeItem = this.$el.querySelector('.menu-item.active');
|
||||
if (activeItem) {
|
||||
activeItem.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||
} else {
|
||||
// Fallback to saved scroll position
|
||||
const savedScroll = localStorage.getItem('sidebar-scroll-position');
|
||||
if (savedScroll) {
|
||||
this.$el.scrollTop = parseInt(savedScroll);
|
||||
}
|
||||
}
|
||||
}, 350);
|
||||
// Restore scroll position immediately (no animation)
|
||||
const savedScroll = localStorage.getItem('sidebar-scroll-position');
|
||||
if (savedScroll) {
|
||||
this.$el.scrollTop = parseInt(savedScroll);
|
||||
}
|
||||
}
|
||||
}"
|
||||
@scroll.debounce.150ms="localStorage.setItem('sidebar-scroll-position', $el.scrollTop)">
|
||||
@@ -62,7 +53,6 @@
|
||||
aria-label="Sidemenu item trigger"
|
||||
type="checkbox"
|
||||
class="peer"
|
||||
name="sidebar-menu-parent-item"
|
||||
x-model="menuDashboard" />
|
||||
<div class="collapse-title px-2.5 py-1.5">
|
||||
<span class="icon-[lucide--bar-chart-3] size-4"></span>
|
||||
@@ -99,7 +89,6 @@
|
||||
aria-label="Sidemenu item trigger"
|
||||
type="checkbox"
|
||||
class="peer"
|
||||
name="sidebar-menu-parent-item"
|
||||
x-model="menuCommerce" />
|
||||
<div class="collapse-title px-2.5 py-1.5">
|
||||
<span class="icon-[lucide--shopping-cart] size-4"></span>
|
||||
@@ -145,7 +134,6 @@
|
||||
aria-label="Sidemenu item trigger"
|
||||
type="checkbox"
|
||||
class="peer"
|
||||
name="sidebar-menu-parent-item"
|
||||
x-model="menuBrands" />
|
||||
<div class="collapse-title px-2.5 py-1.5">
|
||||
<span class="icon-[lucide--bookmark] size-4"></span>
|
||||
@@ -176,7 +164,6 @@
|
||||
aria-label="Sidemenu item trigger"
|
||||
type="checkbox"
|
||||
class="peer"
|
||||
name="sidebar-menu-parent-item"
|
||||
x-model="menuInventory" />
|
||||
<div class="collapse-title px-2.5 py-1.5">
|
||||
<span class="icon-[lucide--package-2] size-4"></span>
|
||||
@@ -247,7 +234,6 @@
|
||||
aria-label="Sidemenu item trigger"
|
||||
type="checkbox"
|
||||
class="peer"
|
||||
name="sidebar-menu-parent-item"
|
||||
x-model="menuProcessing" />
|
||||
<div class="collapse-title px-2.5 py-1.5">
|
||||
<span class="icon-[lucide--beaker] size-4"></span>
|
||||
@@ -268,7 +254,6 @@
|
||||
aria-label="Solventless submenu"
|
||||
type="checkbox"
|
||||
class="peer"
|
||||
name="sidebar-menu-child-item"
|
||||
x-model="menuSolventless" />
|
||||
<div class="collapse-title px-2.5 py-1.5">
|
||||
<span class="grow text-sm font-semibold">Solventless</span>
|
||||
@@ -316,7 +301,6 @@
|
||||
aria-label="BHO submenu"
|
||||
type="checkbox"
|
||||
class="peer"
|
||||
name="sidebar-menu-child-item"
|
||||
x-model="menuBHO" />
|
||||
<div class="collapse-title px-2.5 py-1.5">
|
||||
<span class="grow text-sm font-semibold">BHO</span>
|
||||
@@ -364,7 +348,6 @@
|
||||
aria-label="Sidemenu item trigger"
|
||||
type="checkbox"
|
||||
class="peer"
|
||||
name="sidebar-menu-parent-item"
|
||||
x-model="menuManufacturing" />
|
||||
<div class="collapse-title px-2.5 py-1.5">
|
||||
<span class="icon-[lucide--factory] size-4"></span>
|
||||
@@ -410,7 +393,6 @@
|
||||
aria-label="Sidemenu item trigger"
|
||||
type="checkbox"
|
||||
class="peer"
|
||||
name="sidebar-menu-parent-item"
|
||||
x-model="menuManagement" />
|
||||
<div class="collapse-title px-2.5 py-1.5">
|
||||
<span class="icon-[lucide--book-open] size-4"></span>
|
||||
@@ -444,7 +426,6 @@
|
||||
aria-label="Sidemenu item trigger"
|
||||
type="checkbox"
|
||||
class="peer"
|
||||
name="sidebar-menu-parent-item"
|
||||
x-model="menuGrowth" />
|
||||
<div class="collapse-title px-2.5 py-1.5">
|
||||
<span class="icon-[lucide--megaphone] size-4"></span>
|
||||
@@ -513,7 +494,6 @@
|
||||
aria-label="Sidemenu item trigger"
|
||||
type="checkbox"
|
||||
class="peer"
|
||||
name="sidebar-menu-parent-item"
|
||||
x-model="menuSales" />
|
||||
<div class="collapse-title px-2.5 py-1.5">
|
||||
<span class="icon-[lucide--briefcase] size-4"></span>
|
||||
@@ -574,7 +554,6 @@
|
||||
aria-label="Sidemenu item trigger"
|
||||
type="checkbox"
|
||||
class="peer"
|
||||
name="sidebar-menu-parent-item"
|
||||
x-model="menuInbox" />
|
||||
<div class="collapse-title px-2.5 py-1.5">
|
||||
<span class="icon-[lucide--inbox] size-4"></span>
|
||||
@@ -655,7 +634,6 @@
|
||||
aria-label="Sidemenu item trigger"
|
||||
type="checkbox"
|
||||
class="peer"
|
||||
name="sidebar-menu-parent-item"
|
||||
x-model="menuReports" />
|
||||
<div class="collapse-title px-2.5 py-1.5">
|
||||
<span class="icon-[lucide--file-bar-chart] size-4"></span>
|
||||
@@ -693,6 +671,9 @@
|
||||
v{{ $appVersion }} (sha-{{ $appCommit }})
|
||||
@endif
|
||||
</p>
|
||||
@if($appBuildDate ?? null)
|
||||
<p class="text-[10px] text-base-content/40 mb-0.5">{{ $appBuildDate }}</p>
|
||||
@endif
|
||||
<p>© {{ date('Y') }} creationshop, {{ config('version.company.suffix') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -34,6 +34,22 @@
|
||||
alpine
|
||||
clear-action="clearFilters"
|
||||
>
|
||||
|
||||
For Live Search with dropdown (recommended):
|
||||
<x-ui.filter-bar
|
||||
search-placeholder="Search products..."
|
||||
:search-value="request('search')"
|
||||
live-search-url="{{ route('seller.business.products.index', $business->slug) }}"
|
||||
live-search-label="name"
|
||||
live-search-sublabel="sku"
|
||||
live-search-route-prefix="{{ route('seller.business.products.show', [$business->slug, '__ID__']) }}"
|
||||
clear-url="{{ route('seller.business.products.index', $business->slug) }}"
|
||||
>
|
||||
Props:
|
||||
- live-search-url: API endpoint that returns JSON with 'data' array
|
||||
- live-search-label: Primary field to display (default: 'name')
|
||||
- live-search-sublabel: Secondary field to display (optional, e.g., 'sku')
|
||||
- live-search-route-prefix: URL template with __ID__ replaced by item hashid/id
|
||||
--}}
|
||||
@props([
|
||||
'searchPlaceholder' => 'Search...',
|
||||
@@ -45,9 +61,144 @@
|
||||
'alpine' => false,
|
||||
'formAction' => null,
|
||||
'formMethod' => 'GET',
|
||||
'liveSearchUrl' => null,
|
||||
'liveSearchLabel' => 'name',
|
||||
'liveSearchSublabel' => null,
|
||||
'liveSearchRoutePrefix' => null,
|
||||
])
|
||||
|
||||
@if($alpine)
|
||||
@if($liveSearchUrl)
|
||||
{{-- Live Search Mode with Dropdown --}}
|
||||
<div x-data="{
|
||||
liveSearchQuery: '{{ $searchValue ?? '' }}',
|
||||
liveSearchResults: [],
|
||||
liveSearchOpen: false,
|
||||
liveSearchLoading: false,
|
||||
liveSearchIndex: -1,
|
||||
liveSearchUrl: '{{ $liveSearchUrl }}',
|
||||
liveSearchRoutePrefix: '{{ $liveSearchRoutePrefix }}',
|
||||
liveSearchLabelField: '{{ $liveSearchLabel }}',
|
||||
liveSearchSublabelField: '{{ $liveSearchSublabel }}',
|
||||
|
||||
|
||||
async doLiveSearch() {
|
||||
if (this.liveSearchQuery.length < 2) {
|
||||
this.liveSearchResults = [];
|
||||
this.liveSearchOpen = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.liveSearchLoading = true;
|
||||
try {
|
||||
let url = this.liveSearchUrl;
|
||||
if (url.includes('?')) {
|
||||
url = url + encodeURIComponent(this.liveSearchQuery);
|
||||
} else {
|
||||
url = url + '?search=' + encodeURIComponent(this.liveSearchQuery);
|
||||
}
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
},
|
||||
credentials: 'same-origin'
|
||||
});
|
||||
const data = await response.json();
|
||||
this.liveSearchResults = data.data || data || [];
|
||||
this.liveSearchOpen = this.liveSearchResults.length > 0;
|
||||
this.liveSearchIndex = -1;
|
||||
} catch (error) {
|
||||
console.error('Live search error:', error);
|
||||
this.liveSearchResults = [];
|
||||
}
|
||||
this.liveSearchLoading = false;
|
||||
},
|
||||
|
||||
navigateLiveSearch(item) {
|
||||
const id = item.hashid || item.slug || item.id || item.order_number;
|
||||
if (this.liveSearchRoutePrefix && id) {
|
||||
window.location.href = this.liveSearchRoutePrefix.replace('__ID__', id);
|
||||
}
|
||||
},
|
||||
|
||||
handleLiveSearchKeydown(event) {
|
||||
if (!this.liveSearchOpen) return;
|
||||
|
||||
if (event.key === 'ArrowDown') {
|
||||
event.preventDefault();
|
||||
this.liveSearchIndex = Math.min(this.liveSearchIndex + 1, this.liveSearchResults.length - 1);
|
||||
} else if (event.key === 'ArrowUp') {
|
||||
event.preventDefault();
|
||||
this.liveSearchIndex = Math.max(this.liveSearchIndex - 1, -1);
|
||||
} else if (event.key === 'Enter' && this.liveSearchIndex >= 0) {
|
||||
event.preventDefault();
|
||||
this.navigateLiveSearch(this.liveSearchResults[this.liveSearchIndex]);
|
||||
} else if (event.key === 'Escape') {
|
||||
this.liveSearchOpen = false;
|
||||
}
|
||||
},
|
||||
|
||||
getLiveSearchLabel(item) {
|
||||
return item[this.liveSearchLabelField] || item.name || '';
|
||||
},
|
||||
|
||||
getLiveSearchSublabel(item) {
|
||||
if (!this.liveSearchSublabelField) return null;
|
||||
return item[this.liveSearchSublabelField] || null;
|
||||
}
|
||||
}" x-on:keydown="handleLiveSearchKeydown" x-on:click.outside="liveSearchOpen = false"
|
||||
class="{{ $attributes->get('class', 'rounded-lg border border-base-300 bg-base-100 px-4 py-3 flex flex-col gap-3 md:flex-row md:items-center md:justify-between') }}">
|
||||
{{-- Left: Search + Filters --}}
|
||||
<div class="flex flex-1 gap-2 items-center">
|
||||
<div class="relative flex-1 max-w-sm">
|
||||
<input type="text"
|
||||
x-model="liveSearchQuery"
|
||||
x-on:input.debounce.300ms="doLiveSearch()"
|
||||
placeholder="{{ $searchPlaceholder }}"
|
||||
x-on:focus="if (liveSearchResults.length > 0) liveSearchOpen = true"
|
||||
class="input input-sm input-bordered w-full bg-base-100">
|
||||
<template x-if="liveSearchLoading">
|
||||
<span class="absolute right-2.5 top-1/2 -translate-y-1/2">
|
||||
<span class="loading loading-spinner loading-xs text-base-content/30"></span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
{{-- Live Search Dropdown --}}
|
||||
<div class="absolute z-[9999] left-0 right-0 top-full mt-1 bg-base-100 border border-base-300 rounded-lg shadow-lg max-h-72 overflow-hidden"
|
||||
x-bind:style="liveSearchOpen ? '' : 'display: none'">
|
||||
<div class="px-3 py-1.5 border-b border-base-200 bg-base-200/30">
|
||||
<span class="text-xs font-medium text-base-content/50">Search Results</span>
|
||||
</div>
|
||||
<ul class="menu menu-sm p-1 max-h-56 overflow-y-auto">
|
||||
<template x-for="(item, index) in liveSearchResults" :key="item.hashid || item.slug || item.id || index">
|
||||
<li>
|
||||
<a @click.prevent="navigateLiveSearch(item)"
|
||||
:class="{ 'active': liveSearchIndex === index }"
|
||||
class="flex flex-col items-start py-2 cursor-pointer">
|
||||
<span class="font-medium text-sm" x-text="getLiveSearchLabel(item)"></span>
|
||||
<template x-if="getLiveSearchSublabel(item)">
|
||||
<span class="text-xs text-base-content/60" x-text="getLiveSearchSublabel(item)"></span>
|
||||
</template>
|
||||
</a>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ $filters ?? '' }}
|
||||
</div>
|
||||
|
||||
{{-- Right: Actions + Clear --}}
|
||||
<div class="flex items-center gap-2">
|
||||
{{ $actions ?? '' }}
|
||||
|
||||
@if($clearUrl)
|
||||
<a href="{{ $clearUrl }}" class="btn btn-ghost btn-xs text-xs text-base-content/50 hover:text-base-content">Clear</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@elseif($alpine)
|
||||
<div {{ $attributes->merge(['class' => 'rounded-lg border border-base-300 bg-base-100 px-4 py-3 flex flex-col gap-3 md:flex-row md:items-center md:justify-between']) }}>
|
||||
{{-- Left: Search + Filters --}}
|
||||
<div class="flex flex-1 gap-2 items-center">
|
||||
@@ -55,10 +206,22 @@
|
||||
<input type="text"
|
||||
x-model.debounce.200ms="{{ $searchModel }}"
|
||||
placeholder="{{ $searchPlaceholder }}"
|
||||
@if($formAction)
|
||||
x-on:keydown.enter="window.location.href='{{ $formAction }}' + '?search=' + encodeURIComponent({{ $searchModel }})"
|
||||
@endif
|
||||
class="input input-sm input-bordered w-full pr-8 bg-base-100">
|
||||
@if($formAction)
|
||||
<button type="button"
|
||||
x-on:click="window.location.href='{{ $formAction }}' + '?search=' + encodeURIComponent({{ $searchModel }})"
|
||||
class="absolute right-2.5 top-1/2 -translate-y-1/2"
|
||||
title="Search all products (Enter)">
|
||||
<span class="icon-[heroicons--magnifying-glass] size-4 text-base-content/30 hover:text-base-content/60"></span>
|
||||
</button>
|
||||
@else
|
||||
<span class="absolute right-2.5 top-1/2 -translate-y-1/2">
|
||||
<span class="icon-[heroicons--magnifying-glass] size-4 text-base-content/30"></span>
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{ $filters ?? '' }}
|
||||
@@ -82,9 +245,10 @@
|
||||
name="{{ $searchName }}"
|
||||
value="{{ $searchValue }}"
|
||||
placeholder="{{ $searchPlaceholder }}"
|
||||
class="input input-sm input-bordered w-full pr-8 bg-base-100">
|
||||
<button type="submit" class="absolute right-1.5 top-1/2 -translate-y-1/2 btn btn-ghost btn-xs btn-circle">
|
||||
<span class="icon-[heroicons--magnifying-glass] size-4 text-base-content/30"></span>
|
||||
class="input input-sm input-bordered w-full pr-10 bg-base-100"
|
||||
onkeydown="if(event.key==='Enter'){this.form.submit();}">
|
||||
<button type="submit" class="absolute right-2.5 top-1/2 -translate-y-1/2" title="Search">
|
||||
<span class="icon-[heroicons--magnifying-glass] size-4 text-base-content/30 hover:text-base-content/60"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
<div class="fi-footer flex items-center justify-center gap-x-4 py-3 text-xs text-gray-500 dark:text-gray-400">
|
||||
<div>
|
||||
<div class="text-center">
|
||||
@if ($appVersion === 'dev')
|
||||
<span class="font-semibold text-yellow-600 dark:text-yellow-500">DEV</span>
|
||||
<span class="font-mono">sha-{{ $appCommit }}</span>
|
||||
@else
|
||||
<span class="font-mono">v{{ $appVersion }} (sha-{{ $appCommit }})</span>
|
||||
@endif
|
||||
@if($appBuildDate ?? null)
|
||||
<span class="text-gray-400 dark:text-gray-500 ml-2">{{ $appBuildDate }}</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
37
resources/views/filament/pages/cannaiq-settings.blade.php
Normal file
37
resources/views/filament/pages/cannaiq-settings.blade.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<x-filament-panels::page>
|
||||
{{ $this->form }}
|
||||
|
||||
<div class="mt-6 flex gap-3">
|
||||
<x-filament::button
|
||||
type="button"
|
||||
color="info"
|
||||
wire:click="testConnection"
|
||||
>
|
||||
<x-slot name="icon">
|
||||
<x-heroicon-o-signal class="w-5 h-5" />
|
||||
</x-slot>
|
||||
Test Connection
|
||||
</x-filament::button>
|
||||
|
||||
<x-filament::button
|
||||
type="button"
|
||||
color="gray"
|
||||
outlined
|
||||
wire:click="clearCache"
|
||||
>
|
||||
<x-slot name="icon">
|
||||
<x-heroicon-o-trash class="w-5 h-5" />
|
||||
</x-slot>
|
||||
Clear Cache
|
||||
</x-filament::button>
|
||||
|
||||
<x-filament::link
|
||||
href="https://cannaiq.co"
|
||||
target="_blank"
|
||||
color="gray"
|
||||
>
|
||||
Visit CannaiQ
|
||||
<x-heroicon-o-arrow-top-right-on-square class="w-4 h-4 ml-1" />
|
||||
</x-filament::link>
|
||||
</div>
|
||||
</x-filament-panels::page>
|
||||
@@ -333,7 +333,7 @@
|
||||
<option value="">Select source batch...</option>
|
||||
@foreach($componentBatches as $batch)
|
||||
<option value="{{ $batch->id }}">
|
||||
{{ $batch->batch_number }} - {{ $batch->component->name ?? 'Unknown' }} ({{ $batch->quantity_remaining }} {{ $batch->quantity_unit }} remaining)
|
||||
{{ $batch->batch_number }} - {{ $batch->product->name ?? 'Unknown' }} ({{ $batch->quantity_remaining }} {{ $batch->quantity_unit }} remaining)
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<p class="text-sm text-base-content/60 mt-1">Update batch information and test results</p>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ route('seller.business.batches.update', [$business->slug, $batch->id]) }}" enctype="multipart/form-data" class="space-y-6 max-w-5xl">
|
||||
<form method="POST" action="{{ route('seller.business.batches.update', [$business->slug, $batch->hashid]) }}" enctype="multipart/form-data" class="space-y-6 max-w-5xl">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
|
||||
@@ -358,7 +358,7 @@
|
||||
<div class="card bg-base-100 shadow-sm" x-data="{
|
||||
hasQrCode: {{ $batch->qr_code_path ? 'true' : 'false' }},
|
||||
qrCodeUrl: '{{ $batch->qr_code_path ? Storage::url($batch->qr_code_path) : '' }}',
|
||||
downloadUrl: '{{ $batch->qr_code_path ? route('seller.business.batches.qr-code.download', [$business->slug, $batch->id]) : '' }}',
|
||||
downloadUrl: '{{ $batch->qr_code_path ? route('seller.business.batches.qr-code.download', [$business->slug, $batch->hashid]) : '' }}',
|
||||
loading: false,
|
||||
message: '',
|
||||
messageType: '',
|
||||
@@ -369,7 +369,7 @@
|
||||
this.message = '';
|
||||
|
||||
try {
|
||||
const response = await fetch('{{ route('seller.business.batches.qr-code.generate', [$business->slug, $batch->id]) }}', {
|
||||
const response = await fetch('{{ route('seller.business.batches.qr-code.generate', [$business->slug, $batch->hashid]) }}', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -405,7 +405,7 @@
|
||||
this.message = '';
|
||||
|
||||
try {
|
||||
const response = await fetch('{{ route('seller.business.batches.qr-code.regenerate', [$business->slug, $batch->id]) }}', {
|
||||
const response = await fetch('{{ route('seller.business.batches.qr-code.regenerate', [$business->slug, $batch->hashid]) }}', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -440,7 +440,7 @@
|
||||
this.message = '';
|
||||
|
||||
try {
|
||||
const response = await fetch('{{ route('seller.business.batches.qr-code.delete', [$business->slug, $batch->id]) }}', {
|
||||
const response = await fetch('{{ route('seller.business.batches.qr-code.delete', [$business->slug, $batch->hashid]) }}', {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
return [
|
||||
'id' => $batch->id,
|
||||
'hashid' => $batch->hashid,
|
||||
'batch_number' => $batch->batch_number,
|
||||
'internal_code' => $batch->internal_code,
|
||||
'product_name' => $batch->product->name ?? 'N/A',
|
||||
@@ -331,7 +332,7 @@
|
||||
</td>
|
||||
<td>
|
||||
<div class="flex items-center gap-1">
|
||||
<a :href="'/s/{{ $business->slug }}/batches/' + batch.id + '/edit'" @click.stop class="btn btn-ghost btn-xs gap-1">
|
||||
<a :href="'/s/{{ $business->slug }}/batches/' + batch.hashid + '/edit'" @click.stop class="btn btn-ghost btn-xs gap-1">
|
||||
<span class="icon-[heroicons--pencil] size-3.5"></span>
|
||||
Edit
|
||||
</a>
|
||||
@@ -339,7 +340,7 @@
|
||||
<span class="icon-[heroicons--eye] size-3.5"></span>
|
||||
View
|
||||
</button>
|
||||
<form :action="'/s/{{ $business->slug }}/batches/' + batch.id + '/deactivate'" method="POST" class="inline" @click.stop>
|
||||
<form :action="'/s/{{ $business->slug }}/batches/' + batch.hashid + '/deactivate'" method="POST" class="inline" @click.stop>
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-ghost btn-xs gap-1 text-warning">
|
||||
<span class="icon-[heroicons--pause] size-3.5"></span>
|
||||
@@ -421,7 +422,7 @@
|
||||
</td>
|
||||
<td>
|
||||
<div class="flex items-center gap-1">
|
||||
<a :href="'/s/{{ $business->slug }}/batches/' + batch.id + '/edit'" @click.stop class="btn btn-ghost btn-xs gap-1">
|
||||
<a :href="'/s/{{ $business->slug }}/batches/' + batch.hashid + '/edit'" @click.stop class="btn btn-ghost btn-xs gap-1">
|
||||
<span class="icon-[heroicons--pencil] size-3.5"></span>
|
||||
Edit
|
||||
</a>
|
||||
@@ -429,7 +430,7 @@
|
||||
<span class="icon-[heroicons--eye] size-3.5"></span>
|
||||
View
|
||||
</button>
|
||||
<form :action="'/s/{{ $business->slug }}/batches/' + batch.id + '/activate'" method="POST" class="inline" @click.stop>
|
||||
<form :action="'/s/{{ $business->slug }}/batches/' + batch.hashid + '/activate'" method="POST" class="inline" @click.stop>
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-ghost btn-xs gap-1 text-success">
|
||||
<span class="icon-[heroicons--play] size-3.5"></span>
|
||||
@@ -568,7 +569,7 @@
|
||||
|
||||
{{-- Actions --}}
|
||||
<div class="space-y-2">
|
||||
<a :href="'/s/{{ $business->slug }}/batches/' + selectedBatch?.id + '/edit'"
|
||||
<a :href="'/s/{{ $business->slug }}/batches/' + selectedBatch?.hashid + '/edit'"
|
||||
class="btn btn-primary btn-sm w-full gap-2">
|
||||
<span class="icon-[heroicons--pencil] size-4"></span>
|
||||
Edit Batch
|
||||
|
||||
68
resources/views/seller/brands/analysis-disabled.blade.php
Normal file
68
resources/views/seller/brands/analysis-disabled.blade.php
Normal file
@@ -0,0 +1,68 @@
|
||||
@extends('layouts.seller')
|
||||
|
||||
@section('title', 'Brand Analysis - ' . $brand->name)
|
||||
|
||||
@section('content')
|
||||
<div class="container mx-auto px-4 py-8 max-w-4xl">
|
||||
<div class="card bg-base-100 shadow-xl">
|
||||
<div class="card-body text-center py-16">
|
||||
{{-- Icon --}}
|
||||
<div class="flex justify-center mb-6">
|
||||
<div class="bg-primary/10 rounded-full p-6">
|
||||
<span class="icon-[lucide--bar-chart-3] size-16 text-primary"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Title --}}
|
||||
<h1 class="text-3xl font-bold mb-4">Brand Analysis</h1>
|
||||
<h2 class="text-xl text-base-content/70 mb-6">{{ $brand->name }}</h2>
|
||||
|
||||
{{-- Message --}}
|
||||
<div class="max-w-lg mx-auto mb-8">
|
||||
<p class="text-base-content/70 mb-4">
|
||||
Brand Analysis provides powerful market intelligence powered by CannaiQ, including:
|
||||
</p>
|
||||
<ul class="text-left text-base-content/60 space-y-2 mb-6">
|
||||
<li class="flex items-center gap-2">
|
||||
<span class="icon-[lucide--check-circle] size-5 text-success"></span>
|
||||
<span>Store placement and whitespace opportunities</span>
|
||||
</li>
|
||||
<li class="flex items-center gap-2">
|
||||
<span class="icon-[lucide--check-circle] size-5 text-success"></span>
|
||||
<span>Competitor analysis and market positioning</span>
|
||||
</li>
|
||||
<li class="flex items-center gap-2">
|
||||
<span class="icon-[lucide--check-circle] size-5 text-success"></span>
|
||||
<span>SKU velocity and performance tracking</span>
|
||||
</li>
|
||||
<li class="flex items-center gap-2">
|
||||
<span class="icon-[lucide--check-circle] size-5 text-success"></span>
|
||||
<span>Inventory projections and slippage alerts</span>
|
||||
</li>
|
||||
<li class="flex items-center gap-2">
|
||||
<span class="icon-[lucide--check-circle] size-5 text-success"></span>
|
||||
<span>Buyer engagement and sentiment scoring</span>
|
||||
</li>
|
||||
</ul>
|
||||
<p class="text-base-content/70">
|
||||
This feature requires CannaiQ integration to be enabled for your account.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{{-- CTA --}}
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<a href="mailto:support@cannabrands.com?subject=Enable CannaiQ for {{ urlencode($business->name) }}&body=Hi,%0A%0AI'd like to enable CannaiQ Brand Analysis for my business.%0A%0ABusiness: {{ urlencode($business->name) }}%0ABrand: {{ urlencode($brand->name) }}%0A%0AThank you!"
|
||||
class="btn btn-primary gap-2">
|
||||
<span class="icon-[lucide--mail] size-5"></span>
|
||||
Contact Support to Enable
|
||||
</a>
|
||||
<a href="{{ route('seller.business.brands.dashboard', [$business->slug, $brand->hashid]) }}"
|
||||
class="btn btn-ghost gap-2">
|
||||
<span class="icon-[lucide--arrow-left] size-5"></span>
|
||||
Back to Brand Dashboard
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
2138
resources/views/seller/brands/analysis.blade.php
Normal file
2138
resources/views/seller/brands/analysis.blade.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -199,7 +199,7 @@
|
||||
</div>
|
||||
|
||||
{{-- Brand Insights Section (Mini Tiles) --}}
|
||||
@if(isset($brandInsights))
|
||||
@if(!empty($brandInsights) && isset($brandInsights['topPerformer']))
|
||||
<div class="space-y-3">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="icon-[heroicons--light-bulb] size-4 text-base-content/50"></span>
|
||||
@@ -348,11 +348,11 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse($brand->products->take(5) as $product)
|
||||
@forelse($brand->products->filter(fn($p) => !empty($p->hashid))->take(5) as $product)
|
||||
<tr class="hover:bg-base-200/30 transition-colors">
|
||||
<td class="pl-5">
|
||||
<div class="flex items-center gap-3">
|
||||
@if($product->image_path)
|
||||
@if($product->image_path && $product->hashid)
|
||||
<div class="avatar">
|
||||
<div class="w-10 h-10 rounded-lg bg-base-200/50">
|
||||
<img src="{{ route('image.product', [$product->hashid, 80]) }}" alt="{{ $product->name }}" class="object-contain" />
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
@extends('layouts.app-with-sidebar')
|
||||
|
||||
@section('content')
|
||||
@php
|
||||
$locationParam = ($selectedLocation ?? null) ? ['location' => $selectedLocation->id] : [];
|
||||
@endphp
|
||||
<div class="max-w-7xl mx-auto px-4 py-4 space-y-4">
|
||||
{{-- Header --}}
|
||||
<header class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', [$business->slug, $account->slug]) }}" class="btn btn-ghost btn-sm btn-square">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--arrow-left] size-4"></span>
|
||||
</a>
|
||||
<div>
|
||||
@@ -15,14 +18,27 @@
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{{-- Location Scope Banner --}}
|
||||
@if($selectedLocation ?? null)
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<span class="badge badge-ghost text-neutral border-base-300">
|
||||
<span class="icon-[heroicons--map-pin] size-3 mr-1"></span>
|
||||
Viewing: {{ $selectedLocation->name }}
|
||||
</span>
|
||||
<a href="{{ route('seller.business.crm.accounts.activity', [$business->slug, $account->slug]) }}"
|
||||
class="text-xs text-primary hover:underline">Clear location filter</a>
|
||||
<span class="text-xs text-neutral/50">(Activity doesn't have location filtering yet)</span>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Tabs --}}
|
||||
<div role="tablist" class="tabs tabs-bordered">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', [$business->slug, $account->slug]) }}" class="tab">Overview</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.contacts', [$business->slug, $account->slug]) }}" class="tab">Contacts</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.opportunities', [$business->slug, $account->slug]) }}" class="tab">Opportunities</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.orders', [$business->slug, $account->slug]) }}" class="tab">Orders</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.tasks', [$business->slug, $account->slug]) }}" class="tab">Tasks</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.activity', [$business->slug, $account->slug]) }}" class="tab tab-active">Activity</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.show', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Overview</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.contacts', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Contacts</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.opportunities', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Opportunities</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.orders', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Orders</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.tasks', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Tasks</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.activity', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab tab-active">Activity</a>
|
||||
</div>
|
||||
|
||||
{{-- Activity Table --}}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ route('seller.business.crm.accounts.contacts.update', [$business->slug, $account->slug, $contact->id]) }}">
|
||||
<form method="POST" action="{{ route('seller.business.crm.accounts.contacts.update', [$business->slug, $account->slug, $contact->hashid]) }}">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
|
||||
@@ -90,18 +90,6 @@
|
||||
placeholder="e.g., Buyer, Owner, Manager">
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label cursor-pointer justify-start gap-3">
|
||||
<input type="checkbox"
|
||||
name="is_primary"
|
||||
value="1"
|
||||
class="checkbox checkbox-sm"
|
||||
{{ old('is_primary', $contact->is_primary) ? 'checked' : '' }}>
|
||||
<span class="label-text">Primary Contact</span>
|
||||
</label>
|
||||
<p class="text-xs text-base-content/50 ml-8">This is the main contact for the account</p>
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label cursor-pointer justify-start gap-3">
|
||||
<input type="checkbox"
|
||||
@@ -128,23 +116,5 @@
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{{-- Danger Zone --}}
|
||||
<div class="card bg-base-100 shadow-sm mt-6 border border-error/20">
|
||||
<div class="card-body">
|
||||
<h3 class="font-semibold text-error mb-2">Danger Zone</h3>
|
||||
<p class="text-sm text-base-content/60 mb-4">Permanently delete this contact. This action cannot be undone.</p>
|
||||
<form method="POST"
|
||||
action="{{ route('seller.business.crm.accounts.contacts.destroy', [$business->slug, $account->slug, $contact->id]) }}"
|
||||
onsubmit="return confirm('Are you sure you want to delete this contact? This action cannot be undone.')">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-error btn-outline btn-sm">
|
||||
<span class="icon-[heroicons--trash] size-4"></span>
|
||||
Delete Contact
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
@extends('layouts.app-with-sidebar')
|
||||
|
||||
@section('content')
|
||||
@php
|
||||
$locationParam = ($selectedLocation ?? null) ? ['location' => $selectedLocation->id] : [];
|
||||
@endphp
|
||||
<div class="max-w-7xl mx-auto px-4 py-4 space-y-4">
|
||||
{{-- Header --}}
|
||||
<header class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', [$business->slug, $account->slug]) }}" class="btn btn-ghost btn-sm btn-square">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--arrow-left] size-4"></span>
|
||||
</a>
|
||||
<div>
|
||||
@@ -19,17 +22,29 @@
|
||||
</button>
|
||||
</header>
|
||||
|
||||
{{-- Location Scope Banner --}}
|
||||
@if($selectedLocation ?? null)
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<span class="badge badge-ghost text-neutral border-base-300">
|
||||
<span class="icon-[heroicons--map-pin] size-3 mr-1"></span>
|
||||
Viewing: {{ $selectedLocation->name }}
|
||||
</span>
|
||||
<a href="{{ route('seller.business.crm.accounts.contacts', [$business->slug, $account->slug]) }}"
|
||||
class="text-xs text-primary hover:underline">Clear location filter</a>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Tabs --}}
|
||||
<div role="tablist" class="tabs tabs-bordered">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', [$business->slug, $account->slug]) }}" class="tab">Overview</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.contacts', [$business->slug, $account->slug]) }}" class="tab tab-active">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Overview</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.contacts', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab tab-active">
|
||||
Contacts
|
||||
<span class="badge badge-neutral badge-sm ml-1">{{ $contacts->count() }}</span>
|
||||
</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.opportunities', [$business->slug, $account->slug]) }}" class="tab">Opportunities</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.orders', [$business->slug, $account->slug]) }}" class="tab">Orders</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.tasks', [$business->slug, $account->slug]) }}" class="tab">Tasks</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.activity', [$business->slug, $account->slug]) }}" class="tab">Activity</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.opportunities', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Opportunities</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.orders', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Orders</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.tasks', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Tasks</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.activity', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Activity</a>
|
||||
</div>
|
||||
|
||||
{{-- Contacts Table --}}
|
||||
@@ -71,9 +86,6 @@
|
||||
<div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-sm font-medium">{{ $contact->getFullName() }}</span>
|
||||
@if($contact->is_primary)
|
||||
<span class="badge badge-neutral badge-xs">Primary</span>
|
||||
@endif
|
||||
</div>
|
||||
@if($contact->position)
|
||||
<p class="text-[11px] text-base-content/50">{{ $contact->position }}</p>
|
||||
@@ -198,12 +210,6 @@
|
||||
<label class="text-xs font-medium text-base-content/70 mb-1">Title / Role</label>
|
||||
<input type="text" name="title" class="input input-bordered input-sm" placeholder="e.g., Buyer, Owner, Manager">
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<label class="label cursor-pointer justify-start gap-3 py-1">
|
||||
<input type="checkbox" name="is_primary" value="1" class="checkbox checkbox-sm">
|
||||
<span class="text-sm">Set as Primary Contact</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-action">
|
||||
<button type="button" class="btn btn-ghost btn-sm" onclick="document.getElementById('add_contact_modal').close()">Cancel</button>
|
||||
|
||||
@@ -147,10 +147,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Primary Contact --}}
|
||||
{{-- Contact --}}
|
||||
<div class="card bg-base-100 shadow-sm mb-6">
|
||||
<div class="card-body">
|
||||
<h3 class="font-semibold mb-4">Primary Contact</h3>
|
||||
<h3 class="font-semibold mb-4">Contact</h3>
|
||||
<p class="text-sm text-base-content/60 mb-4">Optional - add the main person you'll be working with</p>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
|
||||
@@ -3,26 +3,27 @@
|
||||
@section('content')
|
||||
<div class="max-w-7xl mx-auto px-4 py-4 space-y-4">
|
||||
{{-- Page Header --}}
|
||||
<header class="flex items-center justify-between">
|
||||
<header class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold">All Customers</h1>
|
||||
<p class="text-sm text-base-content/60">Manage your customer relationships and account activity.</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="flex items-center gap-2 self-start sm:self-auto">
|
||||
<a href="{{ route('seller.business.crm.accounts.create', $business->slug) }}" class="btn btn-primary btn-sm gap-1">
|
||||
<span class="icon-[heroicons--plus] size-4"></span>
|
||||
Add Customer
|
||||
<span class="hidden sm:inline">Add Customer</span>
|
||||
<span class="sm:hidden">Add</span>
|
||||
</a>
|
||||
<a href="{{ route('seller.business.crm.leads.index', $business->slug) }}" class="btn btn-outline btn-sm gap-1">
|
||||
<span class="icon-[heroicons--user-plus] size-4"></span>
|
||||
Leads
|
||||
<span class="hidden sm:inline">Leads</span>
|
||||
</a>
|
||||
{{-- Quick Actions Dropdown --}}
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content z-10 menu p-2 shadow-sm bg-base-100 rounded-lg w-52 border border-base-300">
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-52 border border-base-300 z-[100]">
|
||||
<li>
|
||||
<a href="{{ route('seller.business.crm.leads.create', $business->slug) }}" class="gap-2">
|
||||
<span class="icon-[heroicons--user-plus] size-4"></span>
|
||||
@@ -48,18 +49,20 @@
|
||||
|
||||
{{-- Filter Toolbar --}}
|
||||
<x-ui.filter-bar
|
||||
form-action="{{ route('seller.business.crm.accounts.index', $business->slug) }}"
|
||||
search-placeholder="Search accounts..."
|
||||
search-name="q"
|
||||
:search-value="request('q')"
|
||||
search-name="q"
|
||||
form-action="{{ route('seller.business.crm.accounts.index', $business->slug) }}"
|
||||
clear-url="{{ route('seller.business.crm.accounts.index', $business->slug) }}"
|
||||
>
|
||||
<x-slot:filters>
|
||||
<select name="status" class="select select-sm select-bordered w-36" onchange="this.form.submit()">
|
||||
<option value="">All Status</option>
|
||||
<option value="active" {{ request('status') === 'active' ? 'selected' : '' }}>Active</option>
|
||||
<option value="inactive" {{ request('status') === 'inactive' ? 'selected' : '' }}>Inactive</option>
|
||||
</select>
|
||||
<form method="GET" action="{{ route('seller.business.crm.accounts.index', $business->slug) }}" class="contents">
|
||||
<select name="status" class="select select-sm select-bordered w-36" onchange="this.form.submit()">
|
||||
<option value="">All Status</option>
|
||||
<option value="active" {{ request('status') === 'active' ? 'selected' : '' }}>Active</option>
|
||||
<option value="inactive" {{ request('status') === 'inactive' ? 'selected' : '' }}>Inactive</option>
|
||||
</select>
|
||||
</form>
|
||||
</x-slot:filters>
|
||||
</x-ui.filter-bar>
|
||||
|
||||
@@ -91,9 +94,9 @@
|
||||
<thead class="bg-base-200/30">
|
||||
<tr>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap py-3">Account</th>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap py-3">Primary Contact</th>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap text-right py-3">Orders</th>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap text-right py-3">Open Opps</th>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap py-3 hidden md:table-cell">Contact</th>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap text-right py-3 hidden lg:table-cell">Orders</th>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap text-right py-3 hidden lg:table-cell">Open Opps</th>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap py-3">Status</th>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap text-right py-3"></th>
|
||||
</tr>
|
||||
@@ -121,28 +124,28 @@
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-2 align-middle">
|
||||
@php $primaryContact = $account->contacts->where('is_primary', true)->first() ?? $account->contacts->first(); @endphp
|
||||
@if($primaryContact)
|
||||
<p class="text-sm font-medium">{{ $primaryContact->getFullName() }}</p>
|
||||
@if($primaryContact->email)
|
||||
<p class="text-[11px] text-base-content/50 truncate max-w-[180px]">{{ $primaryContact->email }}</p>
|
||||
<td class="py-2 align-middle hidden md:table-cell">
|
||||
@php $contact = $account->contacts->first(); @endphp
|
||||
@if($contact)
|
||||
<p class="text-sm font-medium">{{ $contact->getFullName() }}</p>
|
||||
@if($contact->email)
|
||||
<p class="text-[11px] text-base-content/50 truncate max-w-[180px]">{{ $contact->email }}</p>
|
||||
@endif
|
||||
@else
|
||||
<p class="text-sm text-base-content/40">No contact</p>
|
||||
@endif
|
||||
</td>
|
||||
<td class="py-2 align-middle text-right">
|
||||
<td class="py-2 align-middle text-right hidden lg:table-cell">
|
||||
<span class="text-sm text-base-content/70">{{ $account->orders_count ?? 0 }}</span>
|
||||
</td>
|
||||
<td class="py-2 align-middle text-right">
|
||||
<td class="py-2 align-middle text-right hidden lg:table-cell">
|
||||
@if(($account->opportunities_as_buyer_count ?? 0) > 0)
|
||||
<span class="text-sm font-medium">{{ $account->opportunities_as_buyer_count }}</span>
|
||||
@else
|
||||
<span class="text-sm text-base-content/40">0</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="py-2 align-middle">
|
||||
<td class="py-2 align-middle hidden sm:table-cell">
|
||||
@if($account->is_active)
|
||||
<span class="badge badge-success badge-sm">Active</span>
|
||||
@else
|
||||
|
||||
395
resources/views/seller/crm/accounts/locations-edit.blade.php
Normal file
395
resources/views/seller/crm/accounts/locations-edit.blade.php
Normal file
@@ -0,0 +1,395 @@
|
||||
@extends('layouts.app-with-sidebar')
|
||||
|
||||
@section('content')
|
||||
<div class="px-4 py-6 max-w-3xl mx-auto">
|
||||
{{-- Header --}}
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<div>
|
||||
<p class="text-lg font-medium flex items-center gap-2">
|
||||
<span class="icon-[heroicons--building-storefront] size-5"></span>
|
||||
Edit Location
|
||||
</p>
|
||||
<p class="text-base-content/60 text-sm mt-1">
|
||||
{{ $location->name }} at {{ $account->name }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="breadcrumbs hidden p-0 text-sm sm:inline">
|
||||
<ul>
|
||||
<li><a href="{{ route('seller.business.crm.accounts.index', $business->slug) }}">Customers</a></li>
|
||||
<li><a href="{{ route('seller.business.crm.accounts.show', [$business->slug, $account->slug]) }}">{{ $account->name }}</a></li>
|
||||
<li class="opacity-80">Edit Location</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ route('seller.business.crm.accounts.locations.update', [$business->slug, $account->slug, $location->id]) }}">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
|
||||
{{-- Basic Info --}}
|
||||
<div class="card bg-base-100 shadow-sm mb-6">
|
||||
<div class="card-body">
|
||||
<h3 class="font-semibold mb-4">Location Information</h3>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div class="form-control md:col-span-2">
|
||||
<label class="label">
|
||||
<span class="label-text">Location Name <span class="text-error">*</span></span>
|
||||
</label>
|
||||
<input type="text"
|
||||
name="name"
|
||||
value="{{ old('name', $location->name) }}"
|
||||
class="input input-bordered @error('name') input-error @enderror"
|
||||
required>
|
||||
@error('name')
|
||||
<label class="label"><span class="label-text-alt text-error">{{ $message }}</span></label>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="form-control md:col-span-2">
|
||||
<label class="label">
|
||||
<span class="label-text">Street Address</span>
|
||||
</label>
|
||||
<input type="text"
|
||||
name="address"
|
||||
value="{{ old('address', $location->address) }}"
|
||||
class="input input-bordered">
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text">City</span>
|
||||
</label>
|
||||
<input type="text"
|
||||
name="city"
|
||||
value="{{ old('city', $location->city) }}"
|
||||
class="input input-bordered">
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text">State</span>
|
||||
</label>
|
||||
<input type="text"
|
||||
name="state"
|
||||
value="{{ old('state', $location->state) }}"
|
||||
class="input input-bordered"
|
||||
maxlength="2"
|
||||
placeholder="AZ">
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text">Zip Code</span>
|
||||
</label>
|
||||
<input type="text"
|
||||
name="zipcode"
|
||||
value="{{ old('zipcode', $location->zipcode) }}"
|
||||
class="input input-bordered">
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text">Phone</span>
|
||||
</label>
|
||||
<input type="tel"
|
||||
name="phone"
|
||||
value="{{ old('phone', $location->phone) }}"
|
||||
class="input input-bordered">
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text">Email</span>
|
||||
</label>
|
||||
<input type="email"
|
||||
name="email"
|
||||
value="{{ old('email', $location->email) }}"
|
||||
class="input input-bordered @error('email') input-error @enderror">
|
||||
@error('email')
|
||||
<label class="label"><span class="label-text-alt text-error">{{ $message }}</span></label>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label cursor-pointer justify-start gap-3">
|
||||
<input type="checkbox"
|
||||
name="is_active"
|
||||
value="1"
|
||||
class="checkbox checkbox-sm"
|
||||
{{ old('is_active', $location->is_active) ? 'checked' : '' }}>
|
||||
<span class="label-text">Active Location</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- CannaiQ Integration --}}
|
||||
<div id="cannaiq" class="card bg-base-100 shadow-sm mb-6">
|
||||
<div class="card-body" x-data="cannaiqSearch()">
|
||||
<h3 class="font-semibold mb-4 flex items-center gap-2">
|
||||
<span class="icon-[heroicons--link] size-4"></span>
|
||||
CannaiQ Integration
|
||||
</h3>
|
||||
<p class="text-sm text-base-content/60 mb-4">Link this location to a CannaiQ store to see inventory data, pricing, and stock trends.</p>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text">Platform</span>
|
||||
</label>
|
||||
<select name="cannaiq_platform"
|
||||
x-model="platform"
|
||||
class="select select-bordered">
|
||||
<option value="">-- Not Linked --</option>
|
||||
@foreach($cannaiqPlatforms as $key => $label)
|
||||
<option value="{{ $key }}" {{ old('cannaiq_platform', $location->cannaiq_platform) === $key ? 'selected' : '' }}>{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text">Store Slug</span>
|
||||
</label>
|
||||
<input type="text"
|
||||
name="cannaiq_store_slug"
|
||||
x-model="storeSlug"
|
||||
value="{{ old('cannaiq_store_slug', $location->cannaiq_store_slug) }}"
|
||||
class="input input-bordered"
|
||||
placeholder="e.g., harvest-hoc-phoenix">
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text">Store ID</span>
|
||||
</label>
|
||||
<input type="text"
|
||||
name="cannaiq_store_id"
|
||||
x-model="storeId"
|
||||
value="{{ old('cannaiq_store_id', $location->cannaiq_store_id) }}"
|
||||
class="input input-bordered"
|
||||
readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-control">
|
||||
<label class="label">
|
||||
<span class="label-text">Store Name</span>
|
||||
</label>
|
||||
<input type="text"
|
||||
name="cannaiq_store_name"
|
||||
x-model="storeName"
|
||||
value="{{ old('cannaiq_store_name', $location->cannaiq_store_name) }}"
|
||||
class="input input-bordered"
|
||||
readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Store Search --}}
|
||||
<div class="mt-4 p-4 bg-base-200/50 rounded-lg" x-show="platform">
|
||||
<div class="flex items-center gap-2 mb-3">
|
||||
<span class="icon-[heroicons--magnifying-glass] size-4 text-base-content/60"></span>
|
||||
<span class="text-sm font-medium">Search CannaiQ Stores</span>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<input type="text"
|
||||
x-model="searchQuery"
|
||||
@keydown.enter.prevent="searchStores"
|
||||
class="input input-bordered input-sm flex-1"
|
||||
placeholder="Search by store name...">
|
||||
<button type="button"
|
||||
@click="searchStores"
|
||||
:disabled="searching || !searchQuery"
|
||||
class="btn btn-sm btn-primary">
|
||||
<span x-show="searching" class="loading loading-spinner loading-xs"></span>
|
||||
<span x-show="!searching">Search</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{{-- Search Results --}}
|
||||
<div x-show="searchResults.length > 0" class="mt-3 space-y-2">
|
||||
<template x-for="store in searchResults" :key="store.id || store.slug">
|
||||
<button type="button"
|
||||
@click="selectStore(store)"
|
||||
class="w-full text-left p-2 rounded border border-base-300 hover:border-primary hover:bg-primary/5 transition-colors">
|
||||
<div class="font-medium text-sm" x-text="store.name"></div>
|
||||
<div class="text-xs text-base-content/60" x-text="store.address || store.city || store.slug"></div>
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
{{-- No Results --}}
|
||||
<div x-show="searched && searchResults.length === 0" class="mt-3 text-sm text-base-content/60">
|
||||
No stores found matching your search.
|
||||
</div>
|
||||
|
||||
{{-- Error --}}
|
||||
<div x-show="searchError" class="mt-3 text-sm text-error" x-text="searchError"></div>
|
||||
</div>
|
||||
|
||||
{{-- Currently Linked --}}
|
||||
@if($location->hasCannaiqMapping())
|
||||
<div class="mt-4 p-3 bg-success/10 rounded-lg border border-success/20">
|
||||
<div class="flex items-center gap-2 text-success text-sm">
|
||||
<span class="icon-[heroicons--check-circle] size-4"></span>
|
||||
<span>Currently linked to: {{ $location->cannaiq_store_name ?: $location->cannaiq_store_slug }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Location Contacts --}}
|
||||
<div class="card bg-base-100 shadow-sm mb-6">
|
||||
<div class="card-body" x-data="locationContacts()">
|
||||
<h3 class="font-semibold mb-4 flex items-center gap-2">
|
||||
<span class="icon-[heroicons--users] size-4"></span>
|
||||
Location Contacts
|
||||
</h3>
|
||||
<p class="text-sm text-base-content/60 mb-4">Assign contacts to this location with specific roles (buyer, AP, etc.).</p>
|
||||
|
||||
{{-- Assigned Contacts List --}}
|
||||
<div class="space-y-2 mb-4">
|
||||
<template x-for="(assignment, index) in assignments" :key="index">
|
||||
<div class="flex items-center gap-2 p-2 bg-base-200/50 rounded">
|
||||
<select :name="`contact_roles[${index}][contact_id]`"
|
||||
x-model="assignment.contact_id"
|
||||
class="select select-bordered select-sm flex-1">
|
||||
<option value="">-- Select Contact --</option>
|
||||
@foreach($contacts as $contact)
|
||||
<option value="{{ $contact->id }}">{{ $contact->getFullName() }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<select :name="`contact_roles[${index}][role]`"
|
||||
x-model="assignment.role"
|
||||
class="select select-bordered select-sm w-40">
|
||||
@foreach($contactRoles as $key => $label)
|
||||
<option value="{{ $key }}">{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<label class="label cursor-pointer gap-1">
|
||||
<input type="checkbox"
|
||||
:name="`contact_roles[${index}][is_primary]`"
|
||||
x-model="assignment.is_primary"
|
||||
value="1"
|
||||
class="checkbox checkbox-xs">
|
||||
<span class="text-xs">Primary</span>
|
||||
</label>
|
||||
<button type="button" @click="removeAssignment(index)" class="btn btn-ghost btn-xs btn-square text-error">
|
||||
<span class="icon-[heroicons--x-mark] size-4"></span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
{{-- Add Contact Button --}}
|
||||
<button type="button" @click="addAssignment" class="btn btn-ghost btn-sm gap-1">
|
||||
<span class="icon-[heroicons--plus] size-4"></span>
|
||||
Add Contact
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Actions --}}
|
||||
<div class="flex justify-end gap-3">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', [$business->slug, $account->slug]) }}" class="btn btn-ghost">
|
||||
Cancel
|
||||
</a>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<span class="icon-[heroicons--check] size-4"></span>
|
||||
Save Changes
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
function cannaiqSearch() {
|
||||
return {
|
||||
platform: '{{ old('cannaiq_platform', $location->cannaiq_platform) }}',
|
||||
storeSlug: '{{ old('cannaiq_store_slug', $location->cannaiq_store_slug) }}',
|
||||
storeId: '{{ old('cannaiq_store_id', $location->cannaiq_store_id) }}',
|
||||
storeName: '{{ old('cannaiq_store_name', $location->cannaiq_store_name) }}',
|
||||
searchQuery: '',
|
||||
searchResults: [],
|
||||
searched: false,
|
||||
searching: false,
|
||||
searchError: '',
|
||||
|
||||
async searchStores() {
|
||||
if (!this.platform || !this.searchQuery) return;
|
||||
|
||||
this.searching = true;
|
||||
this.searchError = '';
|
||||
this.searched = false;
|
||||
|
||||
try {
|
||||
const response = await fetch('{{ route('seller.business.crm.accounts.locations.cannaiq-search', [$business->slug, $account->slug, $location->id]) }}', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-TOKEN': '{{ csrf_token() }}',
|
||||
'Accept': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
platform: this.platform,
|
||||
query: this.searchQuery
|
||||
})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
this.searchResults = data.stores || [];
|
||||
} else {
|
||||
this.searchError = data.message || 'Search failed';
|
||||
this.searchResults = [];
|
||||
}
|
||||
} catch (error) {
|
||||
this.searchError = 'Failed to search stores';
|
||||
this.searchResults = [];
|
||||
} finally {
|
||||
this.searching = false;
|
||||
this.searched = true;
|
||||
}
|
||||
},
|
||||
|
||||
selectStore(store) {
|
||||
this.storeSlug = store.slug || '';
|
||||
this.storeId = store.id || '';
|
||||
this.storeName = store.name || '';
|
||||
this.searchResults = [];
|
||||
this.searchQuery = '';
|
||||
this.searched = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function locationContacts() {
|
||||
return {
|
||||
assignments: {!! json_encode($locationContacts->map(function($c) {
|
||||
return [
|
||||
'contact_id' => $c->id,
|
||||
'role' => $c->pivot->role,
|
||||
'is_primary' => (bool) $c->pivot->is_primary,
|
||||
];
|
||||
})->values()) !!},
|
||||
|
||||
addAssignment() {
|
||||
this.assignments.push({
|
||||
contact_id: '',
|
||||
role: 'buyer',
|
||||
is_primary: false
|
||||
});
|
||||
},
|
||||
|
||||
removeAssignment(index) {
|
||||
this.assignments.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@endpush
|
||||
@endsection
|
||||
@@ -1,11 +1,14 @@
|
||||
@extends('layouts.app-with-sidebar')
|
||||
|
||||
@section('content')
|
||||
@php
|
||||
$locationParam = ($selectedLocation ?? null) ? ['location' => $selectedLocation->id] : [];
|
||||
@endphp
|
||||
<div class="max-w-7xl mx-auto px-4 py-4 space-y-4">
|
||||
{{-- Header --}}
|
||||
<header class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', [$business->slug, $account->slug]) }}" class="btn btn-ghost btn-sm btn-square">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--arrow-left] size-4"></span>
|
||||
</a>
|
||||
<div>
|
||||
@@ -19,17 +22,30 @@
|
||||
</a>
|
||||
</header>
|
||||
|
||||
{{-- Location Scope Banner --}}
|
||||
@if($selectedLocation ?? null)
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<span class="badge badge-ghost text-neutral border-base-300">
|
||||
<span class="icon-[heroicons--map-pin] size-3 mr-1"></span>
|
||||
Viewing: {{ $selectedLocation->name }}
|
||||
</span>
|
||||
<a href="{{ route('seller.business.crm.accounts.opportunities', [$business->slug, $account->slug]) }}"
|
||||
class="text-xs text-primary hover:underline">Clear location filter</a>
|
||||
<span class="text-xs text-neutral/50">(Opportunities don't have location filtering yet)</span>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Tabs --}}
|
||||
<div role="tablist" class="tabs tabs-bordered">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', [$business->slug, $account->slug]) }}" class="tab">Overview</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.contacts', [$business->slug, $account->slug]) }}" class="tab">Contacts</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.opportunities', [$business->slug, $account->slug]) }}" class="tab tab-active">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Overview</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.contacts', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Contacts</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.opportunities', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab tab-active">
|
||||
Opportunities
|
||||
<span class="badge badge-neutral badge-sm ml-1">{{ $opportunities->total() }}</span>
|
||||
</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.orders', [$business->slug, $account->slug]) }}" class="tab">Orders</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.tasks', [$business->slug, $account->slug]) }}" class="tab">Tasks</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.activity', [$business->slug, $account->slug]) }}" class="tab">Activity</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.orders', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Orders</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.tasks', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Tasks</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.activity', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Activity</a>
|
||||
</div>
|
||||
|
||||
{{-- Opportunities Table --}}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
@extends('layouts.app-with-sidebar')
|
||||
|
||||
@section('content')
|
||||
@php
|
||||
$locationParam = ($selectedLocation ?? null) ? ['location' => $selectedLocation->id] : [];
|
||||
@endphp
|
||||
<div class="max-w-7xl mx-auto px-4 py-4 space-y-4">
|
||||
{{-- Header --}}
|
||||
<header class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', [$business->slug, $account->slug]) }}" class="btn btn-ghost btn-sm btn-square">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--arrow-left] size-4"></span>
|
||||
</a>
|
||||
<div>
|
||||
@@ -15,17 +18,29 @@
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{{-- Location Scope Banner --}}
|
||||
@if($selectedLocation ?? null)
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<span class="badge badge-ghost text-neutral border-base-300">
|
||||
<span class="icon-[heroicons--map-pin] size-3 mr-1"></span>
|
||||
Viewing: {{ $selectedLocation->name }}
|
||||
</span>
|
||||
<a href="{{ route('seller.business.crm.accounts.orders', [$business->slug, $account->slug]) }}"
|
||||
class="text-xs text-primary hover:underline">Clear location filter</a>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Tabs --}}
|
||||
<div role="tablist" class="tabs tabs-bordered">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', [$business->slug, $account->slug]) }}" class="tab">Overview</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.contacts', [$business->slug, $account->slug]) }}" class="tab">Contacts</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.opportunities', [$business->slug, $account->slug]) }}" class="tab">Opportunities</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.orders', [$business->slug, $account->slug]) }}" class="tab tab-active">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Overview</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.contacts', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Contacts</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.opportunities', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Opportunities</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.orders', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab tab-active">
|
||||
Orders
|
||||
<span class="badge badge-neutral badge-sm ml-1">{{ $orders->total() }}</span>
|
||||
</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.tasks', [$business->slug, $account->slug]) }}" class="tab">Tasks</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.activity', [$business->slug, $account->slug]) }}" class="tab">Activity</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.tasks', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Tasks</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.activity', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Activity</a>
|
||||
</div>
|
||||
|
||||
{{-- Orders Table --}}
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
@php
|
||||
$locStats = $locationStats[$location->id] ?? [];
|
||||
$hasData = $locStats['has_attributed_data'] ?? false;
|
||||
$ordersCount = $locStats['orders'] ?? 0;
|
||||
$revenue = $locStats['revenue'] ?? 0;
|
||||
$outstanding = $locStats['outstanding'] ?? 0;
|
||||
$pastDue = $locStats['past_due'] ?? 0;
|
||||
$locationContacts = $location->contacts ?? collect();
|
||||
@endphp
|
||||
|
||||
<div class="flex flex-col gap-3 text-sm">
|
||||
{{-- Header --}}
|
||||
<div class="flex items-start justify-between gap-2">
|
||||
<div>
|
||||
<div class="text-base font-semibold text-neutral">{{ $location->name }}</div>
|
||||
<div class="text-xs text-neutral/60">
|
||||
{{ $location->address }}{{ $location->address ? ', ' : '' }}{{ $location->city }}{{ $location->city && $location->state ? ', ' : '' }}{{ $location->state }} {{ $location->zipcode }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- GHOST STATUS BADGE --}}
|
||||
@if($location->is_active)
|
||||
<span class="badge badge-ghost text-success border-success/40 text-[11px]">Active</span>
|
||||
@else
|
||||
<span class="badge badge-ghost text-neutral border-base-300 text-[11px]">Inactive</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- CannaiQ mapping --}}
|
||||
<div class="rounded-lg bg-base-200 px-3 py-2 text-xs flex items-start justify-between gap-2">
|
||||
<div>
|
||||
<div class="font-medium text-neutral mb-1">CannaiQ</div>
|
||||
@if($location->cannaiq_store_slug)
|
||||
<div class="text-neutral/70">
|
||||
Platform: {{ strtoupper($location->cannaiq_platform ?? 'NA') }}<br>
|
||||
Store slug: {{ $location->cannaiq_store_slug }}
|
||||
</div>
|
||||
@else
|
||||
<div class="text-neutral/60">
|
||||
No CannaiQ store linked yet.
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<a href="{{ route('seller.business.crm.accounts.locations.edit', [$business->slug, $account->slug, $location->id]) }}#cannaiq" class="link text-[11px]">
|
||||
Edit mapping
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{{-- Contacts & roles + Metrics --}}
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
<div>
|
||||
<div class="text-xs font-medium text-neutral mb-1">Contacts & roles</div>
|
||||
@forelse($locationContacts as $contact)
|
||||
<div class="text-xs text-neutral/80">
|
||||
{{ $contact->getFullName() }}
|
||||
<span class="text-neutral/60">({{ $contact->pivot->role ?? 'buyer' }})</span>
|
||||
</div>
|
||||
@empty
|
||||
<div class="text-xs text-neutral/60">
|
||||
No location-specific contacts yet. Uses account contacts.
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="text-xs font-medium text-neutral mb-1">Location metrics</div>
|
||||
@if($hasData)
|
||||
<div class="text-xs space-y-1">
|
||||
<div>Orders: <span class="font-semibold">{{ $ordersCount }}</span></div>
|
||||
<div>Revenue: <span class="font-semibold text-primary">${{ number_format($revenue, 2) }}</span></div>
|
||||
<div>Outstanding: <span class="font-semibold text-error">${{ number_format($outstanding, 2) }}</span></div>
|
||||
<div>Past Due: <span class="font-semibold text-error">${{ number_format($pastDue, 2) }}</span></div>
|
||||
</div>
|
||||
@else
|
||||
<div class="text-xs text-neutral/60">
|
||||
No orders attributed to this location yet. Account-level totals are shown above.
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Quick actions (location-scoped) --}}
|
||||
<div class="flex flex-wrap gap-2 pt-2 border-t border-base-300 mt-2">
|
||||
<a href="{{ route('seller.business.crm.quotes.create', $business->slug) }}?account_id={{ $account->id }}&location_id={{ $location->id }}"
|
||||
class="btn btn-xs btn-outline">
|
||||
Create Quote
|
||||
</a>
|
||||
<button type="button"
|
||||
@click="$dispatch('open-create-opportunity-modal', { account_id: {{ $account->id }}, location_id: {{ $location->id }}, account_locked: true })"
|
||||
class="btn btn-xs btn-outline">
|
||||
New Opportunity
|
||||
</button>
|
||||
<button type="button"
|
||||
@click="$dispatch('open-send-menu-modal', { customer_id: {{ $account->id }}, location_id: {{ $location->id }}, customer_locked: true })"
|
||||
class="btn btn-xs btn-outline">
|
||||
Send Menu
|
||||
</button>
|
||||
<a href="{{ route('seller.business.crm.tasks.create', $business->slug) }}?business_id={{ $account->id }}&location_id={{ $location->id }}"
|
||||
class="btn btn-xs btn-outline">
|
||||
Add Task
|
||||
</a>
|
||||
<button type="button"
|
||||
@click="$dispatch('open-add-note-modal', { business_id: {{ $account->id }}, location_id: {{ $location->id }} })"
|
||||
class="btn btn-xs btn-outline">
|
||||
Add Note
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -20,9 +20,9 @@
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
@if($account->is_active ?? true)
|
||||
<span class="badge badge-success badge-sm">Active</span>
|
||||
<span class="badge badge-ghost text-success border-success/40 badge-sm">Active</span>
|
||||
@else
|
||||
<span class="badge badge-neutral badge-sm">Inactive</span>
|
||||
<span class="badge badge-ghost text-neutral border-base-300 badge-sm">Inactive</span>
|
||||
@endif
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-primary btn-sm gap-1">
|
||||
@@ -132,57 +132,156 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Quick Actions Row --}}
|
||||
<div class="flex flex-wrap items-center gap-2 mb-4">
|
||||
<a href="{{ route('seller.business.crm.quotes.create', $business->slug) }}?account_id={{ $account->id }}" class="btn btn-sm btn-ghost gap-1.5">
|
||||
<span class="icon-[heroicons--document-text] size-4"></span>
|
||||
Create Quote
|
||||
</a>
|
||||
<button @click="$dispatch('open-create-opportunity-modal', { account_id: {{ $account->id }}, account_locked: true })" class="btn btn-sm btn-ghost gap-1.5">
|
||||
<span class="icon-[heroicons--sparkles] size-4"></span>
|
||||
New Opportunity
|
||||
</button>
|
||||
<button @click="$dispatch('open-send-menu-modal', { customer_id: {{ $account->id }}, customer_locked: true })" class="btn btn-sm btn-ghost gap-1.5">
|
||||
<span class="icon-[heroicons--paper-airplane] size-4"></span>
|
||||
Send Menu
|
||||
</button>
|
||||
<a href="{{ route('seller.business.crm.tasks.create', $business->slug) }}?business_id={{ $account->id }}" class="btn btn-sm btn-ghost gap-1.5">
|
||||
<span class="icon-[heroicons--clipboard-document-check] size-4"></span>
|
||||
Add Task
|
||||
</a>
|
||||
<button @click="document.getElementById('note-section').scrollIntoView({behavior:'smooth'})" class="btn btn-sm btn-ghost gap-1.5">
|
||||
<span class="icon-[heroicons--pencil] size-4"></span>
|
||||
Log Note
|
||||
</button>
|
||||
{{-- Unattributed Data Notice --}}
|
||||
@if(!$selectedLocation && ($unattributedOrdersCount > 0 || $unattributedInvoicesCount > 0))
|
||||
<div class="text-xs text-neutral/60">
|
||||
This customer has {{ $unattributedOrdersCount }} {{ Str::plural('order', $unattributedOrdersCount) }} and {{ $unattributedInvoicesCount }} {{ Str::plural('invoice', $unattributedInvoicesCount) }} not tied to a specific location. Top metrics are account-wide.
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Location Scope Bar --}}
|
||||
@if($locations->count() > 0)
|
||||
<div class="mt-3 flex items-center gap-2 text-xs">
|
||||
<span class="text-neutral/70">Scope:</span>
|
||||
|
||||
{{-- All locations --}}
|
||||
<a href="?" class="badge badge-ghost border-base-300
|
||||
{{ request('location') ? '' : 'badge-outline font-semibold text-primary border-primary/40' }}">
|
||||
All locations
|
||||
</a>
|
||||
|
||||
{{-- One chip per location --}}
|
||||
<div class="flex gap-2 overflow-x-auto no-scrollbar">
|
||||
@foreach($locations as $loc)
|
||||
<a href="?location={{ $loc->id }}"
|
||||
class="badge badge-ghost border-base-300 whitespace-nowrap
|
||||
{{ request('location') == $loc->id ? 'badge-outline font-semibold text-primary border-primary/40' : '' }}">
|
||||
{{ $loc->name }}
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Locations Master/Detail Layout --}}
|
||||
@if($locations->count() > 0)
|
||||
<section class="mt-4 grid grid-cols-1 lg:grid-cols-3 gap-4">
|
||||
{{-- LEFT: Locations list --}}
|
||||
<div class="lg:col-span-1 rounded-xl border border-base-300 bg-base-100 p-4">
|
||||
<h3 class="text-sm font-semibold text-neutral mb-2">
|
||||
Locations ({{ $locations->count() }})
|
||||
</h3>
|
||||
|
||||
<div class="space-y-2 max-h-96 overflow-y-auto pr-1">
|
||||
@foreach($locations as $loc)
|
||||
@php
|
||||
$locStats = $locationStats[$loc->id] ?? [];
|
||||
$locHasData = $locStats['has_attributed_data'] ?? false;
|
||||
$locOrders = $locStats['orders'] ?? 0;
|
||||
$locRevenue = $locStats['revenue'] ?? 0;
|
||||
@endphp
|
||||
<button
|
||||
type="button"
|
||||
onclick="window.location='?location={{ $loc->id }}'"
|
||||
class="w-full text-left rounded-lg px-3 py-2 border transition
|
||||
{{ request('location') == $loc->id
|
||||
? 'border-primary/40 bg-base-200'
|
||||
: 'border-transparent hover:bg-base-200/60' }}">
|
||||
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<div class="text-xs font-medium text-neutral">{{ $loc->name }}</div>
|
||||
<div class="text-[11px] text-neutral/60 truncate">
|
||||
{{ $loc->city }}{{ $loc->city && $loc->state ? ', ' : '' }}{{ $loc->state }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- MUST BE GHOST STATUS BADGE --}}
|
||||
@if($loc->is_active)
|
||||
<span class="badge badge-ghost text-success border-success/40 text-[11px]">Active</span>
|
||||
@else
|
||||
<span class="badge badge-ghost text-neutral border-base-300 text-[11px]">Inactive</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="mt-1 flex items-center gap-2 text-[11px] text-neutral/60">
|
||||
{{-- CannaiQ mapping --}}
|
||||
@if($loc->cannaiq_store_slug)
|
||||
<span class="badge badge-ghost border-base-300 text-[10px]">
|
||||
CannaiQ linked
|
||||
</span>
|
||||
@else
|
||||
<span class="badge badge-ghost border-base-300 text-[10px]">
|
||||
CannaiQ not linked
|
||||
</span>
|
||||
@endif
|
||||
|
||||
{{-- Metrics only if attributed --}}
|
||||
@if($locHasData)
|
||||
<span>Ord: {{ $locOrders }}</span>
|
||||
<span>Rev: ${{ number_format($locRevenue, 0) }}</span>
|
||||
@endif
|
||||
</div>
|
||||
</button>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- RIGHT: Selected location detail --}}
|
||||
<div class="lg:col-span-2 rounded-xl border border-base-300 bg-base-100 p-4">
|
||||
@if(!$selectedLocation)
|
||||
<div class="text-sm text-neutral/60">
|
||||
Select a location on the left to view its contacts, CannaiQ mapping, metrics, and quick actions.
|
||||
</div>
|
||||
@else
|
||||
@include('seller.crm.accounts.partials.location-detail', [
|
||||
'account' => $account,
|
||||
'location' => $selectedLocation,
|
||||
])
|
||||
@endif
|
||||
</div>
|
||||
</section>
|
||||
@endif
|
||||
|
||||
{{-- Tab Navigation --}}
|
||||
@php
|
||||
$locationParam = $selectedLocation ? ['location' => $selectedLocation->id] : [];
|
||||
@endphp
|
||||
|
||||
{{-- Location Scope Banner (above tabs when filtered) --}}
|
||||
@if($selectedLocation)
|
||||
<div class="mb-3 text-xs text-neutral/70">
|
||||
Viewing: <span class="font-semibold text-primary">{{ $selectedLocation->name }}</span>
|
||||
<a href="{{ route('seller.business.crm.accounts.show', [$business->slug, $account->slug]) }}" class="link ml-1">Clear</a>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<nav class="mb-4 border-b border-base-200">
|
||||
<div role="tablist" class="tabs tabs-bordered -mb-px">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', [$business->slug, $account->slug]) }}"
|
||||
<a href="{{ route('seller.business.crm.accounts.show', array_merge([$business->slug, $account->slug], $locationParam)) }}"
|
||||
class="tab tab-sm {{ request()->routeIs('seller.business.crm.accounts.show') ? 'tab-active' : '' }}">
|
||||
Overview
|
||||
</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.contacts', [$business->slug, $account->slug]) }}"
|
||||
<a href="{{ route('seller.business.crm.accounts.contacts', array_merge([$business->slug, $account->slug], $locationParam)) }}"
|
||||
class="tab tab-sm {{ request()->routeIs('seller.business.crm.accounts.contacts') ? 'tab-active' : '' }}">
|
||||
Contacts
|
||||
@if($account->contacts->count() > 0)
|
||||
<span class="badge badge-xs badge-ghost ml-1">{{ $account->contacts->count() }}</span>
|
||||
@endif
|
||||
</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.opportunities', [$business->slug, $account->slug]) }}"
|
||||
<a href="{{ route('seller.business.crm.accounts.opportunities', array_merge([$business->slug, $account->slug], $locationParam)) }}"
|
||||
class="tab tab-sm {{ request()->routeIs('seller.business.crm.accounts.opportunities') ? 'tab-active' : '' }}">
|
||||
Opportunities
|
||||
</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.orders', [$business->slug, $account->slug]) }}"
|
||||
<a href="{{ route('seller.business.crm.accounts.orders', array_merge([$business->slug, $account->slug], $locationParam)) }}"
|
||||
class="tab tab-sm {{ request()->routeIs('seller.business.crm.accounts.orders') ? 'tab-active' : '' }}">
|
||||
Orders
|
||||
</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.tasks', [$business->slug, $account->slug]) }}"
|
||||
<a href="{{ route('seller.business.crm.accounts.tasks', array_merge([$business->slug, $account->slug], $locationParam)) }}"
|
||||
class="tab tab-sm {{ request()->routeIs('seller.business.crm.accounts.tasks') ? 'tab-active' : '' }}">
|
||||
Tasks
|
||||
</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.activity', [$business->slug, $account->slug]) }}"
|
||||
<a href="{{ route('seller.business.crm.accounts.activity', array_merge([$business->slug, $account->slug], $locationParam)) }}"
|
||||
class="tab tab-sm {{ request()->routeIs('seller.business.crm.accounts.activity') ? 'tab-active' : '' }}">
|
||||
Activity
|
||||
</a>
|
||||
@@ -233,7 +332,7 @@
|
||||
<span class="icon-[heroicons--shopping-bag] size-4 text-base-content/50"></span>
|
||||
<h2 class="text-sm font-semibold">Recent Orders</h2>
|
||||
</div>
|
||||
<a href="{{ route('seller.business.crm.accounts.orders', [$business->slug, $account->slug]) }}"
|
||||
<a href="{{ route('seller.business.crm.accounts.orders', array_merge([$business->slug, $account->slug], $locationParam)) }}"
|
||||
class="text-[11px] font-medium text-primary hover:underline">View All</a>
|
||||
</header>
|
||||
<div class="px-4 py-2">
|
||||
@@ -242,7 +341,12 @@
|
||||
<div class="min-w-0">
|
||||
<a href="{{ route('seller.business.orders.show', [$business->slug, $order]) }}"
|
||||
class="text-sm font-medium hover:text-primary">#{{ $order->order_number }}</a>
|
||||
<p class="text-[10px] text-base-content/50">{{ $order->created_at->format('M j, Y') }}</p>
|
||||
<p class="text-[10px] text-base-content/50">
|
||||
{{ $order->created_at->format('M j, Y') }}
|
||||
@if(!$selectedLocation && $order->location)
|
||||
· {{ $order->location->name }}
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-sm font-medium">${{ number_format($order->total, 2) }}</span>
|
||||
@@ -355,7 +459,7 @@
|
||||
<span class="icon-[heroicons--clock] size-4 text-base-content/50"></span>
|
||||
<h2 class="text-sm font-semibold">Recent Activity</h2>
|
||||
</div>
|
||||
<a href="{{ route('seller.business.crm.accounts.activity', [$business->slug, $account->slug]) }}"
|
||||
<a href="{{ route('seller.business.crm.accounts.activity', array_merge([$business->slug, $account->slug], $locationParam)) }}"
|
||||
class="text-[11px] font-medium text-primary hover:underline">View All</a>
|
||||
</header>
|
||||
<div class="px-4 py-2">
|
||||
@@ -418,50 +522,52 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{-- Primary Contact --}}
|
||||
@php $primaryContact = $account->contacts->where('is_primary', true)->first(); @endphp
|
||||
{{-- Contact --}}
|
||||
@php $contact = $account->contacts->first(); @endphp
|
||||
<section class="rounded-2xl border border-base-200 bg-base-100 shadow-sm">
|
||||
<header class="px-4 py-2.5 border-b border-base-200 flex items-center justify-between">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="icon-[heroicons--user] size-4 text-base-content/50"></span>
|
||||
<h2 class="text-sm font-semibold">Primary Contact</h2>
|
||||
<h2 class="text-sm font-semibold">Contact</h2>
|
||||
</div>
|
||||
<a href="{{ route('seller.business.crm.accounts.contacts', [$business->slug, $account->slug]) }}"
|
||||
class="text-[11px] font-medium text-primary hover:underline">Manage Contacts</a>
|
||||
</header>
|
||||
@if($primaryContact)
|
||||
@if($contact)
|
||||
<div class="px-4 py-3">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-9 h-9 rounded-full bg-info/10 text-info flex items-center justify-center text-sm font-semibold flex-shrink-0">
|
||||
{{ strtoupper(mb_substr($primaryContact->first_name, 0, 1)) }}
|
||||
{{ strtoupper(mb_substr($contact->first_name, 0, 1)) }}
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<p class="text-sm font-medium">{{ $primaryContact->getFullName() }}</p>
|
||||
<p class="text-[10px] text-base-content/50">{{ $primaryContact->position ?? 'Primary Contact' }}</p>
|
||||
<p class="text-sm font-medium">{{ $contact->getFullName() }}</p>
|
||||
@if($contact->position)
|
||||
<p class="text-[10px] text-base-content/50">{{ $contact->position }}</p>
|
||||
@endif
|
||||
</div>
|
||||
<a href="{{ route('seller.business.crm.accounts.contacts.edit', [$business->slug, $account->slug, $primaryContact->hashid]) }}"
|
||||
<a href="{{ route('seller.business.crm.accounts.contacts.edit', [$business->slug, $account->slug, $contact->hashid]) }}"
|
||||
class="btn btn-xs btn-ghost btn-square">
|
||||
<span class="icon-[heroicons--pencil] size-3"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="mt-2 flex flex-wrap gap-x-4 gap-y-1 text-xs">
|
||||
@if($primaryContact->email)
|
||||
<a href="mailto:{{ $primaryContact->email }}" class="flex items-center gap-1 text-base-content/70 hover:text-primary">
|
||||
@if($contact->email)
|
||||
<a href="mailto:{{ $contact->email }}" class="flex items-center gap-1 text-base-content/70 hover:text-primary">
|
||||
<span class="icon-[heroicons--envelope] size-3.5"></span>
|
||||
{{ $primaryContact->email }}
|
||||
{{ $contact->email }}
|
||||
</a>
|
||||
@endif
|
||||
@if($primaryContact->phone)
|
||||
<a href="tel:{{ $primaryContact->phone }}" class="flex items-center gap-1 text-base-content/70 hover:text-primary">
|
||||
@if($contact->phone)
|
||||
<a href="tel:{{ $contact->phone }}" class="flex items-center gap-1 text-base-content/70 hover:text-primary">
|
||||
<span class="icon-[heroicons--phone] size-3.5"></span>
|
||||
{{ $primaryContact->phone }}
|
||||
{{ $contact->phone }}
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<div class="px-4 py-4 text-center">
|
||||
<p class="text-xs text-base-content/50 mb-2">No primary contact set</p>
|
||||
<p class="text-xs text-base-content/50 mb-2">No contacts yet</p>
|
||||
<a href="{{ route('seller.business.crm.accounts.contacts', [$business->slug, $account->slug]) }}"
|
||||
class="btn btn-xs btn-primary gap-1">
|
||||
<span class="icon-[heroicons--plus] size-3"></span>
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
@extends('layouts.app-with-sidebar')
|
||||
|
||||
@section('content')
|
||||
@php
|
||||
$locationParam = ($selectedLocation ?? null) ? ['location' => $selectedLocation->id] : [];
|
||||
@endphp
|
||||
<div class="max-w-7xl mx-auto px-4 py-4 space-y-4">
|
||||
{{-- Header --}}
|
||||
<header class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', [$business->slug, $account->slug]) }}" class="btn btn-ghost btn-sm btn-square">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--arrow-left] size-4"></span>
|
||||
</a>
|
||||
<div>
|
||||
@@ -19,17 +22,30 @@
|
||||
</a>
|
||||
</header>
|
||||
|
||||
{{-- Location Scope Banner --}}
|
||||
@if($selectedLocation ?? null)
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<span class="badge badge-ghost text-neutral border-base-300">
|
||||
<span class="icon-[heroicons--map-pin] size-3 mr-1"></span>
|
||||
Viewing: {{ $selectedLocation->name }}
|
||||
</span>
|
||||
<a href="{{ route('seller.business.crm.accounts.tasks', [$business->slug, $account->slug]) }}"
|
||||
class="text-xs text-primary hover:underline">Clear location filter</a>
|
||||
<span class="text-xs text-neutral/50">(Tasks don't have location filtering yet)</span>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Tabs --}}
|
||||
<div role="tablist" class="tabs tabs-bordered">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', [$business->slug, $account->slug]) }}" class="tab">Overview</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.contacts', [$business->slug, $account->slug]) }}" class="tab">Contacts</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.opportunities', [$business->slug, $account->slug]) }}" class="tab">Opportunities</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.orders', [$business->slug, $account->slug]) }}" class="tab">Orders</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.tasks', [$business->slug, $account->slug]) }}" class="tab tab-active">
|
||||
<a href="{{ route('seller.business.crm.accounts.show', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Overview</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.contacts', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Contacts</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.opportunities', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Opportunities</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.orders', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Orders</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.tasks', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab tab-active">
|
||||
Tasks
|
||||
<span class="badge badge-neutral badge-sm ml-1">{{ $tasks->total() }}</span>
|
||||
</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.activity', [$business->slug, $account->slug]) }}" class="tab">Activity</a>
|
||||
<a href="{{ route('seller.business.crm.accounts.activity', array_merge([$business->slug, $account->slug], $locationParam)) }}" class="tab">Activity</a>
|
||||
</div>
|
||||
|
||||
{{-- Tasks Table --}}
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
@section('content')
|
||||
<div class="max-w-7xl mx-auto px-4 py-4 space-y-4">
|
||||
{{-- Page Header --}}
|
||||
<header class="mb-4 flex items-center justify-between gap-3">
|
||||
<header class="mb-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold mb-0.5">Automations</h1>
|
||||
<p class="text-sm text-base-content/70">Build workflows that trigger campaigns, tasks, and updates based on buyer activity.</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="flex items-center gap-2 self-start sm:self-auto">
|
||||
<a href="{{ route('seller.business.crm.automations.create', $business) }}" class="btn btn-primary btn-sm gap-1">
|
||||
<span class="icon-[heroicons--plus] size-4"></span>
|
||||
New Automation
|
||||
@@ -40,10 +40,10 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-xs font-semibold text-base-content/70 whitespace-nowrap">Name</th>
|
||||
<th class="text-xs font-semibold text-base-content/70 whitespace-nowrap">Trigger</th>
|
||||
<th class="text-xs font-semibold text-base-content/70 whitespace-nowrap text-center">Runs</th>
|
||||
<th class="text-xs font-semibold text-base-content/70 whitespace-nowrap hidden md:table-cell">Trigger</th>
|
||||
<th class="text-xs font-semibold text-base-content/70 whitespace-nowrap text-center hidden lg:table-cell">Runs</th>
|
||||
<th class="text-xs font-semibold text-base-content/70 whitespace-nowrap">Status</th>
|
||||
<th class="text-xs font-semibold text-base-content/70 whitespace-nowrap">Last Run</th>
|
||||
<th class="text-xs font-semibold text-base-content/70 whitespace-nowrap hidden md:table-cell">Last Run</th>
|
||||
<th class="text-xs font-semibold text-base-content/70 text-right"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -58,10 +58,10 @@
|
||||
<p class="text-[11px] text-base-content/60 truncate max-w-xs">{{ $automation->description }}</p>
|
||||
@endif
|
||||
</td>
|
||||
<td class="py-2 text-sm">
|
||||
<td class="py-2 text-sm hidden md:table-cell">
|
||||
{{ ucwords(str_replace('_', ' ', $automation->trigger_type)) }}
|
||||
</td>
|
||||
<td class="py-2 text-center">
|
||||
<td class="py-2 text-center hidden lg:table-cell">
|
||||
<span class="text-sm text-base-content/80">{{ $automation->successful_runs ?? 0 }}</span>
|
||||
</td>
|
||||
<td class="py-2">
|
||||
@@ -76,7 +76,7 @@
|
||||
@endif
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-2 text-sm whitespace-nowrap">
|
||||
<td class="py-2 text-sm whitespace-nowrap hidden md:table-cell">
|
||||
{{ $automation->last_run_at?->diffForHumans() ?? 'Never' }}
|
||||
</td>
|
||||
<td class="py-2 text-right">
|
||||
@@ -90,10 +90,10 @@
|
||||
|
||||
{{-- Actions Dropdown --}}
|
||||
<div class="dropdown {{ $loop->last ? 'dropdown-top' : '' }} dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow-lg bg-base-100 rounded-2xl w-40 z-[100] border border-base-200 {{ $loop->last ? 'mb-1' : '' }}">
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100] {{ $loop->last ? 'mb-1' : '' }}">
|
||||
<li>
|
||||
<a href="{{ route('seller.business.crm.automations.show', [$business, $automation]) }}">
|
||||
<span class="icon-[heroicons--eye] size-4"></span>
|
||||
|
||||
@@ -38,10 +38,10 @@
|
||||
</form>
|
||||
@endif
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-5"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content z-10 menu p-2 shadow bg-base-100 rounded-box w-48">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
<li>
|
||||
<a href="{{ route('seller.business.crm.calendar.index', $business->slug) }}?date={{ $event->start_at->format('Y-m-d') }}">
|
||||
<span class="icon-[heroicons--calendar] size-4"></span>
|
||||
|
||||
@@ -22,32 +22,34 @@
|
||||
|
||||
{{-- Filter Toolbar --}}
|
||||
<x-ui.filter-bar
|
||||
form-action="{{ route('seller.business.crm.contacts.index', $business->slug) }}"
|
||||
search-placeholder="Search contacts..."
|
||||
search-name="q"
|
||||
:search-value="request('q')"
|
||||
search-name="q"
|
||||
form-action="{{ route('seller.business.crm.contacts.index', $business->slug) }}"
|
||||
clear-url="{{ route('seller.business.crm.contacts.index', $business->slug) }}"
|
||||
>
|
||||
<x-slot:filters>
|
||||
<select name="account" class="select select-sm select-bordered w-48" onchange="this.form.submit()">
|
||||
<option value="">All Accounts</option>
|
||||
@foreach($accounts as $account)
|
||||
<option value="{{ $account->id }}" {{ request('account') == $account->id ? 'selected' : '' }}>
|
||||
{{ $account->dba_name ?: $account->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<select name="type" class="select select-sm select-bordered w-36" onchange="this.form.submit()">
|
||||
<option value="">All Types</option>
|
||||
@foreach(\App\Models\Contact::CONTACT_TYPES as $key => $label)
|
||||
<option value="{{ $key }}" {{ request('type') === $key ? 'selected' : '' }}>{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<select name="status" class="select select-sm select-bordered w-32" onchange="this.form.submit()">
|
||||
<option value="">Active</option>
|
||||
<option value="inactive" {{ request('status') === 'inactive' ? 'selected' : '' }}>Inactive</option>
|
||||
<option value="all" {{ request('status') === 'all' ? 'selected' : '' }}>All</option>
|
||||
</select>
|
||||
<form method="GET" action="{{ route('seller.business.crm.contacts.index', $business->slug) }}" class="contents">
|
||||
<select name="account" class="select select-sm select-bordered w-48" onchange="this.form.submit()">
|
||||
<option value="">All Accounts</option>
|
||||
@foreach($accounts as $account)
|
||||
<option value="{{ $account->id }}" {{ request('account') == $account->id ? 'selected' : '' }}>
|
||||
{{ $account->dba_name ?: $account->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<select name="type" class="select select-sm select-bordered w-36" onchange="this.form.submit()">
|
||||
<option value="">All Types</option>
|
||||
@foreach(\App\Models\Contact::CONTACT_TYPES as $key => $label)
|
||||
<option value="{{ $key }}" {{ request('type') === $key ? 'selected' : '' }}>{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<select name="status" class="select select-sm select-bordered w-32" onchange="this.form.submit()">
|
||||
<option value="">Active</option>
|
||||
<option value="inactive" {{ request('status') === 'inactive' ? 'selected' : '' }}>Inactive</option>
|
||||
<option value="all" {{ request('status') === 'all' ? 'selected' : '' }}>All</option>
|
||||
</select>
|
||||
</form>
|
||||
</x-slot:filters>
|
||||
</x-ui.filter-bar>
|
||||
|
||||
@@ -103,9 +105,6 @@
|
||||
<div>
|
||||
<p class="text-sm font-medium">
|
||||
{{ $contact->getFullName() }}
|
||||
@if($contact->is_primary)
|
||||
<span class="badge badge-primary badge-xs ml-1">Primary</span>
|
||||
@endif
|
||||
</p>
|
||||
@if($contact->position)
|
||||
<p class="text-[11px] text-base-content/50">{{ $contact->position }}</p>
|
||||
@@ -187,7 +186,7 @@
|
||||
</li>
|
||||
@endif
|
||||
<li class="border-t mt-1 pt-1">
|
||||
<form method="POST" action="{{ route('seller.business.crm.contacts.destroy', [$business->slug, $contact->id]) }}"
|
||||
<form method="POST" action="{{ route('seller.business.crm.contacts.destroy', [$business->slug, $contact->hashid]) }}"
|
||||
onsubmit="return confirm('Archive this contact?')">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
|
||||
@@ -27,12 +27,10 @@
|
||||
</form>
|
||||
@endif
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-sm">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z" />
|
||||
</svg>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-52">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
<li><a href="{{ route('seller.business.crm.quotes.create', ['business' => $business, 'deal_id' => $deal->id]) }}">Create Quote</a></li>
|
||||
<li>
|
||||
<form method="POST" action="{{ route('seller.business.crm.deals.destroy', [$business, $deal]) }}" onsubmit="return confirm('Delete this deal?')">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
@section('content')
|
||||
<div class="px-4 py-6 max-w-7xl mx-auto">
|
||||
{{-- Header --}}
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 mb-6">
|
||||
<div>
|
||||
<p class="text-lg font-medium flex items-center gap-2">
|
||||
<span class="icon-[heroicons--user-plus] size-5"></span>
|
||||
@@ -13,47 +13,33 @@
|
||||
Prospects and potential customers
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="flex items-center gap-2 self-start sm:self-auto">
|
||||
<a href="{{ route('seller.business.crm.leads.create', $business->slug) }}" class="btn btn-primary btn-sm gap-2">
|
||||
<span class="icon-[heroicons--plus] size-4"></span>
|
||||
Add Lead
|
||||
</a>
|
||||
<div class="breadcrumbs hidden p-0 text-sm sm:inline">
|
||||
<ul>
|
||||
<li><a href="{{ route('seller.business.dashboard', $business->slug) }}">Dashboard</a></li>
|
||||
<li><a href="{{ route('seller.business.crm.accounts.index', $business->slug) }}">Customers</a></li>
|
||||
<li class="opacity-80">Leads</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Search & Filters --}}
|
||||
<div class="card bg-base-100 shadow-sm mb-6">
|
||||
<div class="card-body p-4">
|
||||
<form method="GET" class="flex flex-wrap items-center gap-4">
|
||||
<div class="form-control flex-1 min-w-64">
|
||||
<input type="text"
|
||||
name="q"
|
||||
value="{{ request('q') }}"
|
||||
placeholder="Search leads..."
|
||||
class="input input-sm input-bordered w-full">
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<select name="status" class="select select-sm select-bordered">
|
||||
<option value="">All Status</option>
|
||||
@foreach(\App\Models\Crm\CrmLead::STATUSES as $value => $label)
|
||||
<option value="{{ $value }}" {{ request('status') === $value ? 'selected' : '' }}>{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-sm btn-primary">
|
||||
<span class="icon-[heroicons--magnifying-glass] size-4"></span>
|
||||
Search
|
||||
</button>
|
||||
<x-ui.filter-bar
|
||||
search-placeholder="Search leads..."
|
||||
:search-value="request('q')"
|
||||
search-name="q"
|
||||
form-action="{{ route('seller.business.crm.leads.index', $business->slug) }}"
|
||||
clear-url="{{ route('seller.business.crm.leads.index', $business->slug) }}"
|
||||
>
|
||||
<x-slot:filters>
|
||||
<form method="GET" action="{{ route('seller.business.crm.leads.index', $business->slug) }}" class="contents">
|
||||
<select name="status" class="select select-sm select-bordered w-36" onchange="this.form.submit()">
|
||||
<option value="">All Status</option>
|
||||
@foreach(\App\Models\Crm\CrmLead::STATUSES as $value => $label)
|
||||
<option value="{{ $value }}" {{ request('status') === $value ? 'selected' : '' }}>{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</x-slot:filters>
|
||||
</x-ui.filter-bar>
|
||||
|
||||
{{-- Leads List --}}
|
||||
@if($leads->isEmpty())
|
||||
@@ -77,9 +63,9 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Company</th>
|
||||
<th>Contact</th>
|
||||
<th>Location</th>
|
||||
<th>Source</th>
|
||||
<th class="hidden sm:table-cell">Contact</th>
|
||||
<th class="hidden lg:table-cell">Location</th>
|
||||
<th class="hidden md:table-cell">Source</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
@@ -105,7 +91,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<td class="hidden sm:table-cell">
|
||||
<div>
|
||||
<p class="font-medium text-sm">{{ $lead->contact_name }}</p>
|
||||
@if($lead->contact_email)
|
||||
@@ -113,14 +99,14 @@
|
||||
@endif
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<td class="hidden lg:table-cell">
|
||||
@if($lead->city || $lead->state)
|
||||
<span class="text-sm">{{ $lead->city }}{{ $lead->state ? ', ' . $lead->state : '' }}</span>
|
||||
@else
|
||||
<span class="text-xs text-base-content/40">-</span>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
<td class="hidden md:table-cell">
|
||||
@if($lead->source)
|
||||
<span class="text-sm">{{ \App\Models\Crm\CrmLead::SOURCES[$lead->source] ?? $lead->source }}</span>
|
||||
@else
|
||||
@@ -132,12 +118,12 @@
|
||||
{{ \App\Models\Crm\CrmLead::STATUSES[$lead->status] ?? $lead->status }}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<td class="py-2 align-middle text-right">
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content z-10 menu menu-sm p-2 shadow-lg bg-base-100 rounded-box w-52">
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
<li>
|
||||
<a href="{{ route('seller.business.crm.leads.show', [$business->slug, $lead->hashid]) }}">
|
||||
<span class="icon-[heroicons--eye] size-4"></span>
|
||||
|
||||
@@ -223,7 +223,7 @@
|
||||
<select x-model="newOpportunity.contact_id" class="select select-bordered">
|
||||
<option value="">Select contact...</option>
|
||||
<template x-for="contact in contacts" :key="contact.id">
|
||||
<option :value="contact.id" x-text="contact.name + (contact.is_primary ? ' (Primary)' : '')"></option>
|
||||
<option :value="contact.id" x-text="contact.name"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@@ -16,6 +16,54 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Quote Context Bar --}}
|
||||
@if($selectedAccount || $selectedLocation || $selectedContact)
|
||||
<div class="mb-4 flex flex-wrap items-center gap-2 text-xs">
|
||||
{{-- Account chip --}}
|
||||
@if($selectedAccount)
|
||||
<span class="badge badge-ghost border-base-300 whitespace-nowrap">
|
||||
Account: {{ $selectedAccount->name }}
|
||||
</span>
|
||||
<a href="?clearAccount=1" class="link text-xs">Change</a>
|
||||
@endif
|
||||
|
||||
{{-- Location chip --}}
|
||||
@if($selectedLocation)
|
||||
<span class="badge badge-ghost border-base-300 whitespace-nowrap">
|
||||
Location: {{ $selectedLocation->name }}
|
||||
</span>
|
||||
<a href="?account_id={{ $selectedAccount->id }}&clearLocation=1" class="link text-xs">Change</a>
|
||||
@endif
|
||||
|
||||
{{-- Contact chip --}}
|
||||
@if($selectedContact)
|
||||
<span class="badge badge-ghost border-base-300 whitespace-nowrap">
|
||||
Contact: {{ $selectedContact->getFullName() }}
|
||||
</span>
|
||||
<a href="?account_id={{ $selectedAccount->id }}{{ $selectedLocation ? '&location_id=' . $selectedLocation->id : '' }}&clearContact=1" class="link text-xs">Change</a>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Context Summary Card --}}
|
||||
@if($selectedAccount)
|
||||
<div class="rounded-xl border border-base-300 bg-base-100 p-4 text-sm mb-4">
|
||||
<div class="font-semibold text-neutral">{{ $selectedAccount->name }}</div>
|
||||
|
||||
@if($selectedLocation)
|
||||
<div class="text-xs text-neutral/60">
|
||||
{{ $selectedLocation->address }}{{ $selectedLocation->address && $selectedLocation->city ? ', ' : '' }}{{ $selectedLocation->city }}{{ $selectedLocation->city && $selectedLocation->state ? ', ' : '' }}{{ $selectedLocation->state }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if($selectedContact)
|
||||
<div class="text-xs text-neutral/60 mt-1">
|
||||
Contact: {{ $selectedContact->getFullName() }}{{ $selectedContact->email ? ' (' . $selectedContact->email . ')' : '' }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="POST" action="{{ route('seller.business.crm.quotes.store', $business) }}" @submit="validateForm">
|
||||
@csrf
|
||||
|
||||
@@ -93,12 +141,16 @@
|
||||
<select
|
||||
name="location_id"
|
||||
class="select select-bordered select-sm w-full"
|
||||
x-model="selectedLocation">
|
||||
x-model="selectedLocation"
|
||||
@change="onLocationChange($event.target.value)">
|
||||
<option value="">Select delivery location...</option>
|
||||
<template x-for="location in availableLocations" :key="location.id">
|
||||
<option :value="location.id" x-text="location.name + (location.is_primary ? ' (Primary)' : '')"></option>
|
||||
</template>
|
||||
</select>
|
||||
<p class="text-[11px] text-base-content/50 mt-1">
|
||||
Contacts will be filtered by location
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{{-- Associated Deal --}}
|
||||
@@ -577,11 +629,12 @@
|
||||
<script>
|
||||
function quoteCreator() {
|
||||
return {
|
||||
selectedAccount: '{{ old('account_id', $deal?->account_id ?? '') }}',
|
||||
selectedLocation: '{{ old('location_id') }}',
|
||||
selectedContact: '{{ old('contact_id', $deal?->contact_id ?? '') }}',
|
||||
selectedAccount: '{{ old('account_id', $selectedAccount?->id ?? $deal?->account_id ?? '') }}',
|
||||
selectedLocation: '{{ old('location_id', $selectedLocation?->id ?? '') }}',
|
||||
selectedContact: '{{ old('contact_id', $selectedContact?->id ?? $deal?->contact_id ?? '') }}',
|
||||
availableLocations: [],
|
||||
accountContacts: [],
|
||||
locationContacts: @json($locationContacts ?? []),
|
||||
loadingContacts: false,
|
||||
lineItems: [],
|
||||
discountType: '{{ old('discount_type', '') }}',
|
||||
@@ -633,7 +686,13 @@ function quoteCreator() {
|
||||
|
||||
if (this.selectedAccount) {
|
||||
this.loadAccountLocations();
|
||||
this.loadAccountContacts();
|
||||
// If we have pre-loaded location contacts from the server, use them
|
||||
// Otherwise load contacts via AJAX
|
||||
if (this.locationContacts && this.locationContacts.length > 0) {
|
||||
this.accountContacts = this.locationContacts;
|
||||
} else {
|
||||
this.loadAccountContacts();
|
||||
}
|
||||
}
|
||||
|
||||
this.$watch('taxRate', () => {});
|
||||
@@ -642,10 +701,18 @@ function quoteCreator() {
|
||||
onAccountChange(value) {
|
||||
this.selectedAccount = value;
|
||||
this.selectedContact = '';
|
||||
this.selectedLocation = '';
|
||||
this.locationContacts = [];
|
||||
this.loadAccountLocations();
|
||||
this.loadAccountContacts();
|
||||
},
|
||||
|
||||
onLocationChange(value) {
|
||||
this.selectedLocation = value;
|
||||
// When location changes, reload contacts filtered by location
|
||||
this.loadAccountContacts();
|
||||
},
|
||||
|
||||
async loadAccountContacts() {
|
||||
if (!this.selectedAccount) {
|
||||
this.accountContacts = [];
|
||||
@@ -654,9 +721,22 @@ function quoteCreator() {
|
||||
|
||||
this.loadingContacts = true;
|
||||
try {
|
||||
const response = await fetch(`/s/${this.businessSlug}/search/contacts?customer_id=${this.selectedAccount}`);
|
||||
// If a location is selected, fetch location-specific contacts
|
||||
let url = `/s/${this.businessSlug}/search/contacts?customer_id=${this.selectedAccount}`;
|
||||
if (this.selectedLocation) {
|
||||
url += `&location_id=${this.selectedLocation}`;
|
||||
}
|
||||
const response = await fetch(url);
|
||||
const data = await response.json();
|
||||
this.accountContacts = data;
|
||||
|
||||
// If we have contacts and none is selected, try to select primary buyer
|
||||
if (this.accountContacts.length > 0 && !this.selectedContact) {
|
||||
const primaryBuyer = this.accountContacts.find(c => c.is_primary) || this.accountContacts[0];
|
||||
if (primaryBuyer) {
|
||||
this.selectedContact = primaryBuyer.value;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load contacts:', error);
|
||||
this.accountContacts = [];
|
||||
@@ -674,8 +754,11 @@ function quoteCreator() {
|
||||
const account = this.allAccounts.find(a => a.id == this.selectedAccount);
|
||||
if (account && account.locations) {
|
||||
this.availableLocations = account.locations;
|
||||
const primaryLocation = this.availableLocations.find(loc => loc.is_primary);
|
||||
this.selectedLocation = primaryLocation ? primaryLocation.id : (this.availableLocations.length > 0 ? this.availableLocations[0].id : '');
|
||||
// Only auto-select location if none is already selected
|
||||
if (!this.selectedLocation) {
|
||||
const primaryLocation = this.availableLocations.find(loc => loc.is_primary);
|
||||
this.selectedLocation = primaryLocation ? primaryLocation.id : (this.availableLocations.length > 0 ? this.availableLocations[0].id : '');
|
||||
}
|
||||
} else {
|
||||
this.availableLocations = [];
|
||||
this.selectedLocation = '';
|
||||
|
||||
@@ -18,20 +18,23 @@
|
||||
|
||||
{{-- Search & Filter Toolbar --}}
|
||||
<x-ui.filter-bar
|
||||
form-action="{{ route('seller.business.crm.quotes.index', $business) }}"
|
||||
search-placeholder="Search quotes..."
|
||||
:search-value="request('search')"
|
||||
search-name="search"
|
||||
form-action="{{ route('seller.business.crm.quotes.index', $business) }}"
|
||||
clear-url="{{ route('seller.business.crm.quotes.index', $business) }}"
|
||||
>
|
||||
<x-slot:filters>
|
||||
<select name="status" class="select select-sm select-bordered w-36" onchange="this.form.submit()">
|
||||
<option value="">All Status</option>
|
||||
<option value="draft" {{ request('status') === 'draft' ? 'selected' : '' }}>Draft</option>
|
||||
<option value="sent" {{ request('status') === 'sent' ? 'selected' : '' }}>Sent</option>
|
||||
<option value="accepted" {{ request('status') === 'accepted' ? 'selected' : '' }}>Accepted</option>
|
||||
<option value="declined" {{ request('status') === 'declined' ? 'selected' : '' }}>Declined</option>
|
||||
<option value="expired" {{ request('status') === 'expired' ? 'selected' : '' }}>Expired</option>
|
||||
</select>
|
||||
<form method="GET" action="{{ route('seller.business.crm.quotes.index', $business) }}" class="contents">
|
||||
<select name="status" class="select select-sm select-bordered w-36" onchange="this.form.submit()">
|
||||
<option value="">All Status</option>
|
||||
<option value="draft" {{ request('status') === 'draft' ? 'selected' : '' }}>Draft</option>
|
||||
<option value="sent" {{ request('status') === 'sent' ? 'selected' : '' }}>Sent</option>
|
||||
<option value="accepted" {{ request('status') === 'accepted' ? 'selected' : '' }}>Accepted</option>
|
||||
<option value="declined" {{ request('status') === 'declined' ? 'selected' : '' }}>Declined</option>
|
||||
<option value="expired" {{ request('status') === 'expired' ? 'selected' : '' }}>Expired</option>
|
||||
</select>
|
||||
</form>
|
||||
</x-slot:filters>
|
||||
</x-ui.filter-bar>
|
||||
|
||||
@@ -127,12 +130,12 @@
|
||||
<span class="text-sm text-base-content/40">-</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="py-2 text-right">
|
||||
<td class="py-2 align-middle text-right">
|
||||
<div class="dropdown {{ $loop->last ? 'dropdown-top' : '' }} dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow-sm bg-base-100 rounded-lg w-44 z-[100] border border-base-300 {{ $loop->last ? 'mb-1' : '' }}">
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100] {{ $loop->last ? 'mb-1' : '' }}">
|
||||
<li>
|
||||
<a href="{{ route('seller.business.crm.quotes.show', [$business, $quote]) }}">
|
||||
<span class="icon-[heroicons--eye] size-4"></span>
|
||||
|
||||
@@ -44,36 +44,40 @@
|
||||
|
||||
{{-- Filters --}}
|
||||
<x-ui.filter-bar
|
||||
form-action="{{ route('seller.business.crm.tasks.index', $business->slug) }}"
|
||||
search-placeholder="Search tasks..."
|
||||
:search-value="request('q')"
|
||||
search-name="q"
|
||||
form-action="{{ route('seller.business.crm.tasks.index', $business->slug) }}"
|
||||
clear-url="{{ route('seller.business.crm.tasks.index', $business->slug) }}"
|
||||
>
|
||||
<x-slot:filters>
|
||||
<select name="assignee" class="select select-sm select-bordered w-40" onchange="this.form.submit()">
|
||||
<option value="">All Team</option>
|
||||
<option value="me" {{ request('assignee') === 'me' ? 'selected' : '' }}>My Tasks</option>
|
||||
@foreach($teamMembers as $member)
|
||||
<option value="{{ $member->id }}" {{ request('assignee') == $member->id ? 'selected' : '' }}>
|
||||
{{ $member->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<select name="business_id" class="select select-sm select-bordered w-40" onchange="this.form.submit()">
|
||||
<option value="">All Accounts</option>
|
||||
@foreach($buyerBusinesses as $buyer)
|
||||
<option value="{{ $buyer->id }}" {{ request('business_id') == $buyer->id ? 'selected' : '' }}>
|
||||
{{ $buyer->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<select name="priority" class="select select-sm select-bordered w-32" onchange="this.form.submit()">
|
||||
<option value="">All Priority</option>
|
||||
@foreach(\App\Models\Crm\CrmTask::PRIORITIES as $key => $label)
|
||||
<option value="{{ $key }}" {{ request('priority') === $key ? 'selected' : '' }}>
|
||||
{{ $label }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<form method="GET" action="{{ route('seller.business.crm.tasks.index', $business->slug) }}" class="contents">
|
||||
<select name="assignee" class="select select-sm select-bordered w-40" onchange="this.form.submit()">
|
||||
<option value="">All Team</option>
|
||||
<option value="me" {{ request('assignee') === 'me' ? 'selected' : '' }}>My Tasks</option>
|
||||
@foreach($teamMembers as $member)
|
||||
<option value="{{ $member->id }}" {{ request('assignee') == $member->id ? 'selected' : '' }}>
|
||||
{{ $member->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<select name="business_id" class="select select-sm select-bordered w-40" onchange="this.form.submit()">
|
||||
<option value="">All Accounts</option>
|
||||
@foreach($buyerBusinesses as $buyer)
|
||||
<option value="{{ $buyer->id }}" {{ request('business_id') == $buyer->id ? 'selected' : '' }}>
|
||||
{{ $buyer->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<select name="priority" class="select select-sm select-bordered w-32" onchange="this.form.submit()">
|
||||
<option value="">All Priority</option>
|
||||
@foreach(\App\Models\Crm\CrmTask::PRIORITIES as $key => $label)
|
||||
<option value="{{ $key }}" {{ request('priority') === $key ? 'selected' : '' }}>
|
||||
{{ $label }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</form>
|
||||
</x-slot:filters>
|
||||
</x-ui.filter-bar>
|
||||
|
||||
|
||||
@@ -67,12 +67,10 @@
|
||||
|
||||
{{-- Actions dropdown --}}
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-sm">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z" />
|
||||
</svg>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-52">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
@if($thread->status !== 'closed')
|
||||
<li>
|
||||
<form method="POST" action="{{ route('seller.business.crm.threads.close', [$business, $thread]) }}">
|
||||
|
||||
@@ -149,10 +149,10 @@
|
||||
{{-- Actions --}}
|
||||
<td>
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-xs">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content z-[1] menu p-2 shadow-lg bg-base-100 rounded-box w-52 border border-base-300">
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
<li><a><span class="icon-[heroicons--eye] size-4"></span> View Product</a></li>
|
||||
<li><a><span class="icon-[heroicons--pencil] size-4"></span> Edit Product</a></li>
|
||||
<li><a><span class="icon-[heroicons--cube] size-4"></span> Adjust Stock</a></li>
|
||||
|
||||
@@ -3,17 +3,17 @@
|
||||
@section('content')
|
||||
<div class="container-fluid py-6" x-data="invoiceCreator()">
|
||||
<!-- Page Header -->
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<div class="flex flex-col sm:flex-row sm:justify-between sm:items-center gap-3 mb-6">
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold text-base-content flex items-center gap-2">
|
||||
<span class="icon-[heroicons--document-plus] size-8"></span>
|
||||
<h1 class="text-2xl sm:text-3xl font-bold text-base-content flex items-center gap-2">
|
||||
<span class="icon-[heroicons--document-plus] size-6 sm:size-8"></span>
|
||||
Create Manual Invoice
|
||||
</h1>
|
||||
<p class="text-base-content/60 mt-1">Create a new invoice for an existing customer</p>
|
||||
<p class="text-base-content/60 mt-1 text-sm">Create a new invoice for an existing customer</p>
|
||||
</div>
|
||||
<a href="{{ route('seller.business.invoices.index', $business->slug) }}" class="btn btn-ghost">
|
||||
<span class="icon-[heroicons--arrow-left] size-5"></span>
|
||||
Back to Invoices
|
||||
<a href="{{ route('seller.business.invoices.index', $business->slug) }}" class="btn btn-ghost btn-sm self-start sm:self-auto">
|
||||
<span class="icon-[heroicons--arrow-left] size-4"></span>
|
||||
Back
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -225,12 +225,12 @@
|
||||
<table class="table table-zebra w-full">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="w-10"></th>
|
||||
<th class="w-10 hidden sm:table-cell"></th>
|
||||
<th>Product <span class="text-error">*</span></th>
|
||||
<th>Quantity <span class="text-error">*</span></th>
|
||||
<th>Wholesale Unit Price <span class="text-error">*</span></th>
|
||||
<th>Discount</th>
|
||||
<th>Notes</th>
|
||||
<th>Qty <span class="text-error">*</span></th>
|
||||
<th class="hidden md:table-cell">Price <span class="text-error">*</span></th>
|
||||
<th class="hidden lg:table-cell">Discount</th>
|
||||
<th class="hidden xl:table-cell">Notes</th>
|
||||
<th>Total</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
@@ -239,7 +239,7 @@
|
||||
<template x-for="(item, index) in lineItems" :key="index">
|
||||
<tr>
|
||||
<!-- Product Image -->
|
||||
<td>
|
||||
<td class="hidden sm:table-cell">
|
||||
<div class="avatar" x-show="item.image_url">
|
||||
<div class="w-10 h-10 rounded">
|
||||
<img :src="item.image_url" :alt="item.product_name" />
|
||||
@@ -311,7 +311,7 @@
|
||||
</td>
|
||||
|
||||
<!-- Unit Price -->
|
||||
<td class="w-32">
|
||||
<td class="w-32 hidden md:table-cell">
|
||||
<div class="join w-full">
|
||||
<span class="join-item btn btn-sm btn-disabled">$</span>
|
||||
<input
|
||||
@@ -327,7 +327,7 @@
|
||||
</td>
|
||||
|
||||
<!-- Discount -->
|
||||
<td class="w-40">
|
||||
<td class="w-40 hidden lg:table-cell">
|
||||
<div class="flex gap-1">
|
||||
<input
|
||||
type="number"
|
||||
@@ -350,7 +350,7 @@
|
||||
</td>
|
||||
|
||||
<!-- Notes -->
|
||||
<td class="w-48">
|
||||
<td class="w-48 hidden xl:table-cell">
|
||||
<textarea
|
||||
:name="'items[' + index + '][notes]'"
|
||||
class="textarea textarea-bordered textarea-sm w-full h-16 text-xs"
|
||||
@@ -384,43 +384,46 @@
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="6" class="text-right font-semibold">Subtotal:</td>
|
||||
<td colspan="2" class="text-right font-semibold sm:hidden">Subtotal:</td>
|
||||
<td colspan="6" class="text-right font-semibold hidden sm:table-cell">Subtotal:</td>
|
||||
<td colspan="2">
|
||||
<span class="font-semibold" x-text="'$' + calculateSubtotal().toFixed(2)"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr x-show="calculateTotalLineDiscounts() > 0">
|
||||
<td colspan="6" class="text-right font-semibold text-success">Line Discounts:</td>
|
||||
<td colspan="2" class="text-right font-semibold text-success sm:hidden">Discounts:</td>
|
||||
<td colspan="6" class="text-right font-semibold text-success hidden sm:table-cell">Line Discounts:</td>
|
||||
<td colspan="2">
|
||||
<span class="text-success" x-text="'-$' + calculateTotalLineDiscounts().toFixed(2)"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr x-show="calculateTotalLineDiscounts() > 0">
|
||||
<tr x-show="calculateTotalLineDiscounts() > 0" class="hidden md:table-row">
|
||||
<td colspan="6" class="text-right font-semibold">Subtotal After Line Discounts:</td>
|
||||
<td colspan="2">
|
||||
<span class="font-semibold" x-text="'$' + calculateSubtotalAfterLineDiscounts().toFixed(2)"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr x-show="calculateInvoiceDiscount() > 0">
|
||||
<tr x-show="calculateInvoiceDiscount() > 0" class="hidden md:table-row">
|
||||
<td colspan="6" class="text-right font-semibold text-success">Invoice Discount:</td>
|
||||
<td colspan="2">
|
||||
<span class="text-success" x-text="'-$' + calculateInvoiceDiscount().toFixed(2)"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr x-show="calculateInvoiceDiscount() > 0 || calculateTotalLineDiscounts() > 0">
|
||||
<tr x-show="calculateInvoiceDiscount() > 0 || calculateTotalLineDiscounts() > 0" class="hidden md:table-row">
|
||||
<td colspan="6" class="text-right font-semibold">Subtotal After All Discounts:</td>
|
||||
<td colspan="2">
|
||||
<span class="font-semibold" x-text="'$' + calculateSubtotalAfterAllDiscounts().toFixed(2)"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr class="hidden md:table-row">
|
||||
<td colspan="6" class="text-right font-semibold">Tax:</td>
|
||||
<td colspan="2">
|
||||
<span class="text-base-content/60" x-text="'$' + calculateTax().toFixed(2)"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="font-bold text-lg">
|
||||
<td colspan="6" class="text-right">Grand Total:</td>
|
||||
<td colspan="2" class="text-right sm:hidden">Total:</td>
|
||||
<td colspan="6" class="text-right hidden sm:table-cell">Grand Total:</td>
|
||||
<td colspan="2">
|
||||
<span class="text-primary" x-text="'$' + calculateTotal().toFixed(2)"></span>
|
||||
</td>
|
||||
@@ -496,15 +499,15 @@
|
||||
</div>
|
||||
|
||||
<!-- Form Actions -->
|
||||
<div class="flex justify-end gap-2">
|
||||
<a href="{{ route('seller.business.invoices.index', $business->slug) }}" class="btn btn-ghost">
|
||||
<div class="flex flex-col-reverse sm:flex-row sm:justify-end gap-2">
|
||||
<a href="{{ route('seller.business.invoices.index', $business->slug) }}" class="btn btn-ghost btn-sm sm:btn-md">
|
||||
Cancel
|
||||
</a>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-success"
|
||||
class="btn btn-success btn-sm sm:btn-md"
|
||||
:disabled="lineItems.length === 0 || !selectedCustomer || !paymentTerms || !dueDate">
|
||||
<span class="icon-[heroicons--document-plus] size-5"></span>
|
||||
<span class="icon-[heroicons--document-plus] size-4 sm:size-5"></span>
|
||||
Create Invoice
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
@section('content')
|
||||
<div class="max-w-7xl mx-auto px-4 py-4 space-y-4">
|
||||
{{-- Page Header --}}
|
||||
<header class="flex items-center justify-between">
|
||||
<header class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold">Invoices</h1>
|
||||
<p class="text-sm text-base-content/60">Manage and track your invoices.</p>
|
||||
</div>
|
||||
<a href="{{ route('seller.business.invoices.create', $business->slug) }}" class="btn btn-primary btn-sm gap-1">
|
||||
<a href="{{ route('seller.business.invoices.create', $business->slug) }}" class="btn btn-secondary btn-sm gap-1 self-start sm:self-auto">
|
||||
<span class="icon-[heroicons--plus] size-4"></span>
|
||||
Create Invoice
|
||||
</a>
|
||||
@@ -16,18 +16,21 @@
|
||||
|
||||
{{-- Filter Bar --}}
|
||||
<x-ui.filter-bar
|
||||
form-action="{{ route('seller.business.invoices.index', $business->slug) }}"
|
||||
search-placeholder="Search invoices..."
|
||||
:search-value="request('search')"
|
||||
search-name="search"
|
||||
form-action="{{ route('seller.business.invoices.index', $business->slug) }}"
|
||||
clear-url="{{ route('seller.business.invoices.index', $business->slug) }}"
|
||||
>
|
||||
<x-slot:filters>
|
||||
<select name="status" class="select select-sm select-bordered w-36" onchange="this.form.submit()">
|
||||
<option value="">All Status</option>
|
||||
<option value="unpaid" {{ request('status') === 'unpaid' ? 'selected' : '' }}>Unpaid</option>
|
||||
<option value="paid" {{ request('status') === 'paid' ? 'selected' : '' }}>Paid</option>
|
||||
<option value="overdue" {{ request('status') === 'overdue' ? 'selected' : '' }}>Overdue</option>
|
||||
</select>
|
||||
<form method="GET" action="{{ route('seller.business.invoices.index', $business->slug) }}" class="contents">
|
||||
<select name="status" class="select select-sm select-bordered w-36" onchange="this.form.submit()">
|
||||
<option value="">All Status</option>
|
||||
<option value="unpaid" {{ request('status') === 'unpaid' ? 'selected' : '' }}>Unpaid</option>
|
||||
<option value="paid" {{ request('status') === 'paid' ? 'selected' : '' }}>Paid</option>
|
||||
<option value="overdue" {{ request('status') === 'overdue' ? 'selected' : '' }}>Overdue</option>
|
||||
</select>
|
||||
</form>
|
||||
</x-slot:filters>
|
||||
</x-ui.filter-bar>
|
||||
|
||||
@@ -42,7 +45,7 @@
|
||||
<p class="text-xs text-base-content/50 mb-4 max-w-md">
|
||||
Create your first invoice to bill customers and track payment status.
|
||||
</p>
|
||||
<a href="{{ route('seller.business.invoices.create', $business->slug) }}" class="btn btn-primary btn-sm">
|
||||
<a href="{{ route('seller.business.invoices.create', $business->slug) }}" class="btn btn-secondary btn-sm">
|
||||
Create Invoice
|
||||
</a>
|
||||
</div>
|
||||
@@ -54,9 +57,9 @@
|
||||
<thead class="bg-base-200/30">
|
||||
<tr>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap py-3">Invoice</th>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap py-3">Customer</th>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap py-3">Invoice Date</th>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap py-3">Due Date</th>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap py-3 hidden sm:table-cell">Customer</th>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap py-3 hidden md:table-cell">Invoice Date</th>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap py-3 hidden lg:table-cell">Due Date</th>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap text-right py-3">Amount</th>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap py-3">Status</th>
|
||||
<th class="text-xs font-medium text-base-content/50 whitespace-nowrap text-right py-3"></th>
|
||||
@@ -70,7 +73,7 @@
|
||||
{{ $invoice->invoice_number }}
|
||||
</a>
|
||||
</td>
|
||||
<td class="py-2 align-middle">
|
||||
<td class="py-2 align-middle hidden sm:table-cell">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-8 h-8 rounded-lg bg-base-200/50 text-base-content/50 flex items-center justify-center text-sm font-medium">
|
||||
{{ strtoupper(mb_substr($invoice->business->name ?? 'C', 0, 1)) }}
|
||||
@@ -89,10 +92,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-2 align-middle whitespace-nowrap text-sm">
|
||||
<td class="py-2 align-middle whitespace-nowrap text-sm hidden md:table-cell">
|
||||
{{ $invoice->invoice_date->format('M j, Y') }}
|
||||
</td>
|
||||
<td class="py-2 align-middle whitespace-nowrap text-sm">
|
||||
<td class="py-2 align-middle whitespace-nowrap text-sm hidden lg:table-cell">
|
||||
@if($invoice->due_date)
|
||||
<span class="{{ $invoice->isOverdue() ? 'text-error font-medium' : '' }}">
|
||||
{{ $invoice->due_date->format('M j, Y') }}
|
||||
@@ -106,11 +109,11 @@
|
||||
</td>
|
||||
<td class="py-2 align-middle">
|
||||
@if($invoice->payment_status === 'paid')
|
||||
<span class="badge badge-success badge-sm">Paid</span>
|
||||
<span class="badge badge-ghost badge-sm">Paid</span>
|
||||
@elseif($invoice->isOverdue())
|
||||
<span class="badge badge-error badge-sm">Overdue</span>
|
||||
<span class="badge badge-ghost badge-sm">Overdue</span>
|
||||
@else
|
||||
<span class="badge badge-neutral badge-sm">Unpaid</span>
|
||||
<span class="badge badge-ghost badge-sm">Unpaid</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="py-2 align-middle text-right">
|
||||
|
||||
@@ -117,12 +117,12 @@
|
||||
<td class="text-right">
|
||||
@if($period->isOpen() && $canClosePeriods)
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-sm">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm">
|
||||
<span class="icon-[heroicons--lock-closed] size-4"></span>
|
||||
Close
|
||||
<span class="icon-[heroicons--chevron-down] size-4"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-48">
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
<li>
|
||||
<button type="button" onclick="openCloseModal({{ $period->id }}, '{{ $period->period_label }}', 'soft_closed')">
|
||||
<span class="icon-[heroicons--lock-open] size-4 text-warning"></span>
|
||||
|
||||
@@ -133,10 +133,10 @@
|
||||
</td>
|
||||
<td>
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-5"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-52 z-10">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
<li>
|
||||
<button type="button" @click="openEditModal({{ json_encode($vendor) }})">
|
||||
<span class="icon-[heroicons--pencil] size-4"></span>
|
||||
|
||||
@@ -107,12 +107,12 @@
|
||||
<span class="badge badge-ghost badge-sm">Inactive</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<td class="py-2 align-middle text-right">
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-sm">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-48">
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
<li>
|
||||
<a href="{{ route('seller.business.management.bank-accounts.show', [$business, $account]) }}">
|
||||
<span class="icon-[heroicons--eye] size-4"></span>
|
||||
|
||||
@@ -135,10 +135,10 @@
|
||||
<td class="text-sm text-base-content/60">{{ $tx->category_display }}</td>
|
||||
<td>
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-xs">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-52">
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
<li>
|
||||
<button @click="openMatchModal({{ $tx->id }})">
|
||||
<span class="icon-[heroicons--link] size-4"></span>
|
||||
|
||||
@@ -80,10 +80,10 @@
|
||||
Edit
|
||||
</a>
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-xs">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-40">
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
@if(!$budget->approved_at)
|
||||
<li>
|
||||
<form action="{{ route('seller.business.management.budgets.approve', [$business, $budget]) }}" method="POST">
|
||||
|
||||
@@ -116,10 +116,10 @@
|
||||
View
|
||||
</a>
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-xs">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-40">
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
<li>
|
||||
<a href="{{ route('seller.business.management.recurring.edit', [$business, $schedule]) }}">Edit</a>
|
||||
</li>
|
||||
|
||||
@@ -198,12 +198,10 @@
|
||||
|
||||
{{-- Actions Dropdown --}}
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-sm">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z"></path>
|
||||
</svg>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-52 z-10">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
<li><a href="{{ route('seller.marketing.broadcasts.show', $broadcast) }}">View Details</a></li>
|
||||
<li><a href="{{ route('seller.marketing.broadcasts.analytics', $broadcast) }}">Analytics</a></li>
|
||||
|
||||
|
||||
@@ -136,12 +136,12 @@
|
||||
<span class="text-base-content/50 text-sm">-</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="py-2 text-right">
|
||||
<td class="py-2 align-middle text-right">
|
||||
<div class="dropdown {{ $loop->last ? 'dropdown-top' : '' }} dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow-lg bg-base-100 rounded-2xl w-44 z-[100] border border-base-200 {{ $loop->last ? 'mb-1' : '' }}">
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100] {{ $loop->last ? 'mb-1' : '' }}">
|
||||
<li>
|
||||
<a href="{{ route('seller.business.marketing.campaigns.show', [$business->slug, $campaign]) }}">
|
||||
<span class="icon-[heroicons--eye] size-4"></span>
|
||||
|
||||
@@ -82,10 +82,10 @@
|
||||
<span class="badge badge-neutral badge-sm">Inactive</span>
|
||||
@endif
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-xs btn-square">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow-lg bg-base-100 rounded-2xl w-40 z-[100] border border-base-200">
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
<li>
|
||||
<a href="{{ route('seller.business.marketing.channels.edit', [$business->slug, $channel]) }}">
|
||||
<span class="icon-[heroicons--pencil] size-4"></span>
|
||||
|
||||
@@ -81,11 +81,11 @@
|
||||
@change="selected = $event.target.checked ? {{ $contacts->pluck('id') }} : []" />
|
||||
</th>
|
||||
<th>Contact</th>
|
||||
<th>Type</th>
|
||||
<th>Email</th>
|
||||
<th>Phone</th>
|
||||
<th>Subscribed</th>
|
||||
<th>Tags</th>
|
||||
<th class="hidden sm:table-cell">Type</th>
|
||||
<th class="hidden md:table-cell">Email</th>
|
||||
<th class="hidden lg:table-cell">Phone</th>
|
||||
<th class="hidden md:table-cell">Subscribed</th>
|
||||
<th class="hidden lg:table-cell">Tags</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -100,14 +100,14 @@
|
||||
<div class="font-medium">{{ $contact->display_name }}</div>
|
||||
<div class="text-xs text-base-content/60">{{ $contact->source }}</div>
|
||||
</td>
|
||||
<td>
|
||||
<td class="hidden sm:table-cell">
|
||||
<span class="badge badge-sm {{ $contact->type === 'buyer' ? 'badge-primary' : ($contact->type === 'consumer' ? 'badge-secondary' : 'badge-ghost') }}">
|
||||
{{ $contact->getTypeLabel() }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="text-sm">{{ $contact->email ?? '-' }}</td>
|
||||
<td class="text-sm">{{ $contact->phone ?? '-' }}</td>
|
||||
<td>
|
||||
<td class="text-sm hidden md:table-cell">{{ $contact->email ?? '-' }}</td>
|
||||
<td class="text-sm hidden lg:table-cell">{{ $contact->phone ?? '-' }}</td>
|
||||
<td class="hidden md:table-cell">
|
||||
<div class="flex gap-1">
|
||||
@if($contact->is_subscribed_email && $contact->email)
|
||||
<span class="badge badge-xs badge-success">Email</span>
|
||||
@@ -117,7 +117,7 @@
|
||||
@endif
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<td class="hidden lg:table-cell">
|
||||
@if($contact->tags)
|
||||
<div class="flex flex-wrap gap-1">
|
||||
@foreach(array_slice($contact->tags, 0, 3) as $tag)
|
||||
@@ -131,14 +131,12 @@
|
||||
-
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
<td class="py-2 align-middle text-right">
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-xs">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M6 10a2 2 0 11-4 0 2 2 0 014 0zM12 10a2 2 0 11-4 0 2 2 0 014 0zM16 12a2 2 0 100-4 2 2 0 000 4z" />
|
||||
</svg>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-40">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
<li><a href="{{ route('seller.business.marketing.contacts.edit', [$business, $contact]) }}">Edit</a></li>
|
||||
<li>
|
||||
<form method="POST" action="{{ route('seller.business.marketing.contacts.destroy', [$business, $contact]) }}" onsubmit="return confirm('Delete this contact?')">
|
||||
|
||||
@@ -29,12 +29,10 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M6 10a2 2 0 11-4 0 2 2 0 014 0zM12 10a2 2 0 11-4 0 2 2 0 014 0zM16 12a2 2 0 100-4 2 2 0 000 4z" />
|
||||
</svg>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-40">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
<li><a href="{{ route('seller.business.marketing.lists.show', [$business, $list]) }}">View Contacts</a></li>
|
||||
<li><a href="{{ route('seller.business.marketing.lists.edit', [$business, $list]) }}">Edit</a></li>
|
||||
<li>
|
||||
|
||||
@@ -131,12 +131,12 @@
|
||||
<span class="text-base-content/40">-</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="py-2 text-right">
|
||||
<td class="py-2 align-middle text-right">
|
||||
<div class="dropdown {{ $loop->last ? 'dropdown-top' : '' }} dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow-lg bg-base-100 rounded-2xl w-40 z-[100] border border-base-200 {{ $loop->last ? 'mb-1' : '' }}">
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100] {{ $loop->last ? 'mb-1' : '' }}">
|
||||
<li>
|
||||
<a href="{{ route('seller.business.marketing.promos.show', [$business->slug, $promo]) }}">
|
||||
<span class="icon-[heroicons--eye] size-4"></span>
|
||||
|
||||
@@ -120,12 +120,12 @@
|
||||
<td class="py-2 text-sm whitespace-nowrap">
|
||||
{{ $template->updated_at->diffForHumans() }}
|
||||
</td>
|
||||
<td class="py-2 text-right">
|
||||
<td class="py-2 align-middle text-right">
|
||||
<div class="dropdown {{ $loop->last ? 'dropdown-top' : '' }} dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow-lg bg-base-100 rounded-2xl w-40 z-[100] border border-base-200 {{ $loop->last ? 'mb-1' : '' }}">
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100] {{ $loop->last ? 'mb-1' : '' }}">
|
||||
<li>
|
||||
<a href="{{ route('seller.business.marketing.templates.show', [$business->slug, $template]) }}">
|
||||
<span class="icon-[heroicons--eye] size-4"></span>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
@section('content')
|
||||
<div class="max-w-7xl mx-auto px-6 py-4 space-y-4">
|
||||
{{-- Page Header --}}
|
||||
<header class="flex items-center justify-between">
|
||||
<header class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2">
|
||||
<div>
|
||||
<h1 class="text-2xl font-semibold">Orders</h1>
|
||||
<p class="text-sm text-base-content/60">Manage and fulfill customer orders</p>
|
||||
@@ -12,33 +12,36 @@
|
||||
|
||||
{{-- Search + Filter Bar --}}
|
||||
<x-ui.filter-bar
|
||||
form-action="{{ route('seller.business.orders.index', $business->slug) }}"
|
||||
search-placeholder="Search order # or customer..."
|
||||
:search-value="request('search')"
|
||||
search-name="search"
|
||||
form-action="{{ route('seller.business.orders.index', $business->slug) }}"
|
||||
clear-url="{{ route('seller.business.orders.index', $business->slug) }}"
|
||||
>
|
||||
<x-slot:filters>
|
||||
<select name="status" class="select select-sm select-bordered w-36" onchange="this.form.submit()">
|
||||
<option value="">All Statuses</option>
|
||||
<option value="new" {{ request('status') === 'new' ? 'selected' : '' }}>New</option>
|
||||
<option value="accepted" {{ request('status') === 'accepted' ? 'selected' : '' }}>Accepted</option>
|
||||
<option value="in_progress" {{ request('status') === 'in_progress' ? 'selected' : '' }}>In Progress</option>
|
||||
<option value="ready_for_manifest" {{ request('status') === 'ready_for_manifest' ? 'selected' : '' }}>Ready for Manifest</option>
|
||||
<option value="ready_for_delivery" {{ request('status') === 'ready_for_delivery' ? 'selected' : '' }}>Buyer Review</option>
|
||||
<option value="approved_for_delivery" {{ request('status') === 'approved_for_delivery' ? 'selected' : '' }}>Order Ready</option>
|
||||
<option value="out_for_delivery" {{ request('status') === 'out_for_delivery' ? 'selected' : '' }}>Out for Delivery</option>
|
||||
<option value="delivered" {{ request('status') === 'delivered' ? 'selected' : '' }}>Delivered</option>
|
||||
<option value="buyer_approved" {{ request('status') === 'buyer_approved' ? 'selected' : '' }}>Completed</option>
|
||||
<option value="rejected" {{ request('status') === 'rejected' ? 'selected' : '' }}>Rejected</option>
|
||||
<option value="cancelled" {{ request('status') === 'cancelled' ? 'selected' : '' }}>Cancelled</option>
|
||||
</select>
|
||||
<form method="GET" action="{{ route('seller.business.orders.index', $business->slug) }}" class="contents">
|
||||
<select name="status" class="select select-sm select-bordered w-36" onchange="this.form.submit()">
|
||||
<option value="">All Statuses</option>
|
||||
<option value="new" {{ request('status') === 'new' ? 'selected' : '' }}>New</option>
|
||||
<option value="accepted" {{ request('status') === 'accepted' ? 'selected' : '' }}>Accepted</option>
|
||||
<option value="in_progress" {{ request('status') === 'in_progress' ? 'selected' : '' }}>In Progress</option>
|
||||
<option value="ready_for_manifest" {{ request('status') === 'ready_for_manifest' ? 'selected' : '' }}>Ready for Manifest</option>
|
||||
<option value="ready_for_delivery" {{ request('status') === 'ready_for_delivery' ? 'selected' : '' }}>Buyer Review</option>
|
||||
<option value="approved_for_delivery" {{ request('status') === 'approved_for_delivery' ? 'selected' : '' }}>Order Ready</option>
|
||||
<option value="out_for_delivery" {{ request('status') === 'out_for_delivery' ? 'selected' : '' }}>Out for Delivery</option>
|
||||
<option value="delivered" {{ request('status') === 'delivered' ? 'selected' : '' }}>Delivered</option>
|
||||
<option value="buyer_approved" {{ request('status') === 'buyer_approved' ? 'selected' : '' }}>Completed</option>
|
||||
<option value="rejected" {{ request('status') === 'rejected' ? 'selected' : '' }}>Rejected</option>
|
||||
<option value="cancelled" {{ request('status') === 'cancelled' ? 'selected' : '' }}>Cancelled</option>
|
||||
</select>
|
||||
|
||||
<select name="workorder_filter" class="select select-sm select-bordered w-32 hidden lg:block" onchange="this.form.submit()">
|
||||
<option value="">Fulfillment</option>
|
||||
<option value="not_started" {{ request('workorder_filter') === 'not_started' ? 'selected' : '' }}>Not Started</option>
|
||||
<option value="in_progress" {{ request('workorder_filter') === 'in_progress' ? 'selected' : '' }}>In Progress</option>
|
||||
<option value="completed" {{ request('workorder_filter') === 'completed' ? 'selected' : '' }}>Completed</option>
|
||||
</select>
|
||||
<select name="workorder_filter" class="select select-sm select-bordered w-32 hidden lg:block" onchange="this.form.submit()">
|
||||
<option value="">Fulfillment</option>
|
||||
<option value="not_started" {{ request('workorder_filter') === 'not_started' ? 'selected' : '' }}>Not Started</option>
|
||||
<option value="in_progress" {{ request('workorder_filter') === 'in_progress' ? 'selected' : '' }}>In Progress</option>
|
||||
<option value="completed" {{ request('workorder_filter') === 'completed' ? 'selected' : '' }}>Completed</option>
|
||||
</select>
|
||||
</form>
|
||||
</x-slot:filters>
|
||||
</x-ui.filter-bar>
|
||||
|
||||
@@ -51,10 +54,10 @@
|
||||
<tr>
|
||||
<th class="text-xs font-medium text-base-content/50 py-3 whitespace-nowrap">Order</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-3 whitespace-nowrap">Customer</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-3 whitespace-nowrap">Date</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-3 whitespace-nowrap text-center">Items</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-3 whitespace-nowrap hidden md:table-cell">Date</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-3 whitespace-nowrap text-center hidden lg:table-cell">Items</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-3 whitespace-nowrap text-right">Total</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-3 whitespace-nowrap text-center">Fulfillment</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-3 whitespace-nowrap text-center hidden lg:table-cell">Fulfillment</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-3 whitespace-nowrap">Status</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-3"></th>
|
||||
</tr>
|
||||
@@ -83,36 +86,36 @@
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-3 whitespace-nowrap">
|
||||
<td class="py-3 whitespace-nowrap hidden md:table-cell">
|
||||
<div class="text-sm">{{ $order->created_at->format('M j, Y') }}</div>
|
||||
<div class="text-[11px] text-base-content/60">{{ $order->created_at->format('g:i A') }}</div>
|
||||
</td>
|
||||
<td class="py-3 text-center">
|
||||
<td class="py-3 text-center hidden lg:table-cell">
|
||||
<span class="text-sm text-base-content/80">{{ $order->items->count() }}</span>
|
||||
</td>
|
||||
<td class="py-3 text-right">
|
||||
<span class="text-sm font-semibold">${{ number_format($order->total, 2) }}</span>
|
||||
</td>
|
||||
<td class="py-3 text-center">
|
||||
<td class="py-3 text-center hidden lg:table-cell">
|
||||
@if($order->workorder_status == 100)
|
||||
<span class="badge badge-neutral badge-sm whitespace-nowrap">Complete</span>
|
||||
<span class="badge badge-success badge-sm whitespace-nowrap">Complete</span>
|
||||
@elseif($order->workorder_status == 0)
|
||||
<span class="badge badge-neutral badge-sm whitespace-nowrap">Not Started</span>
|
||||
<span class="badge badge-success badge-sm whitespace-nowrap">Not Started</span>
|
||||
@elseif($order->workorder_status > 0 && $order->workorder_status < 100)
|
||||
<span class="badge badge-neutral badge-sm whitespace-nowrap">{{ number_format($order->workorder_status, 0) }}%</span>
|
||||
<span class="badge badge-success badge-sm whitespace-nowrap">{{ number_format($order->workorder_status, 0) }}%</span>
|
||||
@else
|
||||
<span class="badge badge-neutral badge-sm whitespace-nowrap">Not Started</span>
|
||||
<span class="badge badge-success badge-sm whitespace-nowrap">Not Started</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="py-3">
|
||||
@include('buyer.orders.partials.status-badge', ['status' => $order->status])
|
||||
</td>
|
||||
<td class="py-3 text-right">
|
||||
<td class="py-2 align-middle text-right">
|
||||
<div class="dropdown {{ $loop->last ? 'dropdown-top' : '' }} dropdown-end">
|
||||
<button tabindex="0" role="button" class="btn btn-ghost btn-sm btn-square">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu bg-base-100 rounded-lg shadow-sm w-48 p-2 z-[100] border border-base-300 {{ $loop->last ? 'mb-1' : '' }}">
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100] {{ $loop->last ? 'mb-1' : '' }}">
|
||||
<li>
|
||||
<a href="{{ route('seller.business.orders.show', [$business->slug, $order]) }}">
|
||||
<span class="icon-[heroicons--eye] size-4"></span>
|
||||
|
||||
@@ -2607,62 +2607,35 @@ function batchManager(config) {
|
||||
<div x-show="activeTab === 'content'" x-transition>
|
||||
<div class="space-y-6">
|
||||
|
||||
{{-- A. Short & Tagline --}}
|
||||
{{-- A. Short Description --}}
|
||||
<div class="card bg-base-100 shadow">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">Short & Tagline</h2>
|
||||
<h2 class="card-title">Short Description</h2>
|
||||
|
||||
<fieldset class="fieldset mt-4">
|
||||
<div class="grid gap-4 md:grid-cols-2">
|
||||
{{-- Short Description --}}
|
||||
<div class="space-y-2">
|
||||
<label class="label text-sm font-medium" for="short_description">
|
||||
Short Description
|
||||
</label>
|
||||
<input type="text" id="short_description" name="description" value="{{ old('description', $product->description) }}" maxlength="255" class="input w-full @error('description') input-error @enderror" placeholder="Brief product description...">
|
||||
<p class="text-base-content/60 text-xs">Max 255 characters.</p>
|
||||
@error('description')
|
||||
<p class="text-error text-sm">{{ $message }}</p>
|
||||
@enderror
|
||||
@if($business->hasSalesSuite() || $business->copilot_enabled)
|
||||
{{-- AI Copilot Actions --}}
|
||||
<div class="flex gap-2 mt-2">
|
||||
<button type="button" class="btn btn-xs btn-ghost gap-1" onclick="generateAiCopy('short_description', 'generate')">
|
||||
<span class="icon-[heroicons--sparkles] size-3 text-primary"></span>
|
||||
Generate
|
||||
</button>
|
||||
<button type="button" class="btn btn-xs btn-ghost gap-1" onclick="generateAiCopy('short_description', 'improve')">
|
||||
<span class="icon-[heroicons--sparkles] size-3 text-primary"></span>
|
||||
Improve
|
||||
</button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Tagline --}}
|
||||
<div class="space-y-2">
|
||||
<label class="label text-sm font-medium" for="tagline">
|
||||
Tagline
|
||||
</label>
|
||||
<input type="text" id="tagline" name="tagline" value="{{ old('tagline', $product->tagline) }}" maxlength="100" class="input w-full @error('tagline') input-error @enderror" placeholder="Premium quality, unbeatable value...">
|
||||
<p class="text-base-content/60 text-xs">Max 100 characters.</p>
|
||||
@error('tagline')
|
||||
<p class="text-error text-sm">{{ $message }}</p>
|
||||
@enderror
|
||||
@if($business->hasSalesSuite() || $business->copilot_enabled)
|
||||
{{-- AI Copilot Actions --}}
|
||||
<div class="flex gap-2 mt-2">
|
||||
<button type="button" class="btn btn-xs btn-ghost gap-1" onclick="generateAiCopy('tagline', 'generate')">
|
||||
<span class="icon-[heroicons--sparkles] size-3 text-primary"></span>
|
||||
Generate
|
||||
</button>
|
||||
<button type="button" class="btn btn-xs btn-ghost gap-1" onclick="generateAiCopy('tagline', 'improve')">
|
||||
<span class="icon-[heroicons--sparkles] size-3 text-primary"></span>
|
||||
Improve
|
||||
</button>
|
||||
</div>
|
||||
@endif
|
||||
<div class="space-y-2">
|
||||
<textarea name="description"
|
||||
id="short_description"
|
||||
rows="6"
|
||||
class="textarea textarea-bordered w-full resize-none @error('description') textarea-error @enderror"
|
||||
placeholder="Brief product description...">{{ old('description', $product->description) }}</textarea>
|
||||
@error('description')
|
||||
<p class="text-error text-sm">{{ $message }}</p>
|
||||
@enderror
|
||||
<p class="text-base-content/60 text-xs">200-300 characters recommended.</p>
|
||||
@if($business->hasSalesSuite() || $business->copilot_enabled)
|
||||
{{-- AI Copilot Actions --}}
|
||||
<div class="flex gap-2 mt-2">
|
||||
<button type="button" class="btn btn-xs btn-ghost gap-1" onclick="generateAiCopy('short_description', 'generate')">
|
||||
<span class="icon-[heroicons--sparkles] size-3 text-primary"></span>
|
||||
Generate
|
||||
</button>
|
||||
<button type="button" class="btn btn-xs btn-ghost gap-1" onclick="generateAiCopy('short_description', 'improve')">
|
||||
<span class="icon-[heroicons--sparkles] size-3 text-primary"></span>
|
||||
Improve
|
||||
</button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
@@ -2836,8 +2809,8 @@ function batchManager(config) {
|
||||
foreach ($product->images()->orderBy('sort_order')->get() as $img) {
|
||||
$imagesList->push([
|
||||
'id' => $img->id,
|
||||
'url' => route('images.product', ['product' => $product->hashid, 'width' => 400]),
|
||||
'thumb_url' => route('images.product', ['product' => $product->hashid, 'width' => 80]),
|
||||
'url' => route('image.product', ['product' => $product->hashid, 'width' => 400]),
|
||||
'thumb_url' => route('image.product', ['product' => $product->hashid, 'width' => 80]),
|
||||
'is_primary' => $img->is_primary,
|
||||
'is_direct' => false,
|
||||
]);
|
||||
|
||||
@@ -3,11 +3,7 @@
|
||||
@section('content')
|
||||
<div class="max-w-7xl mx-auto px-6 py-4 space-y-4"
|
||||
x-data="{
|
||||
// State
|
||||
search: '',
|
||||
brandFilter: 'all',
|
||||
statusFilter: 'all',
|
||||
visibilityFilter: 'all',
|
||||
// State for view controls
|
||||
focusFilter: 'all',
|
||||
viewMode: 'table',
|
||||
selectedProduct: null,
|
||||
@@ -16,7 +12,7 @@
|
||||
// Pagination info from server
|
||||
pagination: @js($pagination),
|
||||
|
||||
// Real product data from database
|
||||
// Product data from database (already filtered by server-side search)
|
||||
listings: @js($products->map(function($product) {
|
||||
$isListed = $product['status'] === 'active' && $product['visibility'] !== 'private';
|
||||
$stock = 0;
|
||||
@@ -33,16 +29,9 @@
|
||||
]);
|
||||
})),
|
||||
|
||||
// Computed properties
|
||||
// Client-side focus filters only (search is server-side)
|
||||
get filteredListings() {
|
||||
return this.listings.filter(listing => {
|
||||
const matchesSearch = !this.search ||
|
||||
listing.product.toLowerCase().includes(this.search.toLowerCase()) ||
|
||||
listing.sku.toLowerCase().includes(this.search.toLowerCase());
|
||||
const matchesBrand = this.brandFilter === 'all' || listing.brand === this.brandFilter;
|
||||
const matchesStatus = this.statusFilter === 'all' || listing.status === this.statusFilter;
|
||||
const matchesVisibility = this.visibilityFilter === 'all' || listing.visibility === this.visibilityFilter;
|
||||
|
||||
let matchesFocus = true;
|
||||
if (this.focusFilter === 'low-stock') {
|
||||
matchesFocus = listing.stock > 0 && listing.stock <= listing.lowStockThreshold;
|
||||
@@ -56,7 +45,7 @@
|
||||
matchesFocus = listing.status === 'draft';
|
||||
}
|
||||
|
||||
return matchesSearch && matchesBrand && matchesStatus && matchesVisibility && matchesFocus;
|
||||
return matchesFocus;
|
||||
});
|
||||
},
|
||||
|
||||
@@ -79,16 +68,12 @@
|
||||
},
|
||||
|
||||
clearFilters() {
|
||||
this.search = '';
|
||||
this.brandFilter = 'all';
|
||||
this.statusFilter = 'all';
|
||||
this.visibilityFilter = 'all';
|
||||
this.focusFilter = 'all';
|
||||
}
|
||||
}">
|
||||
|
||||
{{-- Page Header --}}
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2">
|
||||
<div>
|
||||
<h1 class="text-xl font-semibold text-base-content">Products</h1>
|
||||
<p class="text-sm text-base-content/50">Manage your product catalog</p>
|
||||
@@ -111,19 +96,19 @@
|
||||
@endcan
|
||||
@endif
|
||||
|
||||
{{-- Search + Filter Bar --}}
|
||||
{{-- Search + Filter Bar - server-side search --}}
|
||||
<x-ui.filter-bar
|
||||
form-action="{{ route('seller.business.products.index', $business->slug) }}"
|
||||
search-placeholder="Search products..."
|
||||
search-name="search"
|
||||
search-placeholder="Search by name or SKU..."
|
||||
:search-value="request('search')"
|
||||
search-name="search"
|
||||
form-action="{{ route('seller.business.products.index', $business->slug) }}"
|
||||
clear-url="{{ route('seller.business.products.index', $business->slug) }}"
|
||||
>
|
||||
<x-slot:filters>
|
||||
<select name="brand_id" class="select select-sm select-bordered w-32" onchange="this.form.submit()">
|
||||
<option value="">All Brands</option>
|
||||
@foreach($products->pluck('brand')->unique()->sort() as $brand)
|
||||
<option value="{{ $products->where('brand', $brand)->first()['id'] ?? '' }}" {{ request('brand_id') == ($products->where('brand', $brand)->first()['id'] ?? '') ? 'selected' : '' }}>{{ $brand }}</option>
|
||||
@foreach($brands as $brand)
|
||||
<option value="{{ $brand->id }}" {{ request('brand_id') == $brand->id ? 'selected' : '' }}>{{ $brand->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<select name="status" class="select select-sm select-bordered w-28 hidden lg:block" onchange="this.form.submit()">
|
||||
@@ -146,38 +131,38 @@
|
||||
</x-ui.filter-bar>
|
||||
|
||||
{{-- Filter Chips Row --}}
|
||||
<div class="flex flex-wrap items-center gap-1.5">
|
||||
<div class="flex items-center gap-1.5 overflow-x-auto pb-1">
|
||||
<button @click="setFocusFilter('all')"
|
||||
:class="focusFilter === 'all' ? 'bg-base-200 text-base-content' : 'text-base-content/50 hover:text-base-content'"
|
||||
class="btn btn-xs btn-ghost rounded-md px-2.5">
|
||||
class="btn btn-xs btn-ghost rounded-md px-2.5 whitespace-nowrap flex-shrink-0">
|
||||
All
|
||||
</button>
|
||||
<button @click="setFocusFilter('low-stock')"
|
||||
:class="focusFilter === 'low-stock' ? 'bg-base-200 text-base-content' : 'text-base-content/50 hover:text-base-content'"
|
||||
class="btn btn-xs btn-ghost rounded-md px-2.5">
|
||||
class="btn btn-xs btn-ghost rounded-md px-2.5 whitespace-nowrap flex-shrink-0">
|
||||
Low Stock
|
||||
</button>
|
||||
<button @click="setFocusFilter('out-of-stock')"
|
||||
:class="focusFilter === 'out-of-stock' ? 'bg-base-200 text-base-content' : 'text-base-content/50 hover:text-base-content'"
|
||||
class="btn btn-xs btn-ghost rounded-md px-2.5">
|
||||
class="btn btn-xs btn-ghost rounded-md px-2.5 whitespace-nowrap flex-shrink-0">
|
||||
Out of Stock
|
||||
</button>
|
||||
<button @click="setFocusFilter('missing-images')"
|
||||
:class="focusFilter === 'missing-images' ? 'bg-base-200 text-base-content' : 'text-base-content/50 hover:text-base-content'"
|
||||
class="btn btn-xs btn-ghost rounded-md px-2.5">
|
||||
class="btn btn-xs btn-ghost rounded-md px-2.5 whitespace-nowrap flex-shrink-0 hidden sm:inline-flex">
|
||||
Missing Images
|
||||
</button>
|
||||
<button @click="setFocusFilter('not-listed')"
|
||||
:class="focusFilter === 'not-listed' ? 'bg-base-200 text-base-content' : 'text-base-content/50 hover:text-base-content'"
|
||||
class="btn btn-xs btn-ghost rounded-md px-2.5">
|
||||
class="btn btn-xs btn-ghost rounded-md px-2.5 whitespace-nowrap flex-shrink-0 hidden sm:inline-flex">
|
||||
Not Listed
|
||||
</button>
|
||||
<button @click="setFocusFilter('drafts')"
|
||||
:class="focusFilter === 'drafts' ? 'bg-base-200 text-base-content' : 'text-base-content/50 hover:text-base-content'"
|
||||
class="btn btn-xs btn-ghost rounded-md px-2.5">
|
||||
class="btn btn-xs btn-ghost rounded-md px-2.5 whitespace-nowrap flex-shrink-0">
|
||||
Drafts
|
||||
</button>
|
||||
<span class="text-xs text-base-content/40 ml-2">
|
||||
<span class="text-xs text-base-content/40 ml-2 whitespace-nowrap flex-shrink-0">
|
||||
<span x-text="filteredListings.length"></span>/<span x-text="pagination.total"></span>
|
||||
</span>
|
||||
</div>
|
||||
@@ -189,11 +174,11 @@
|
||||
<thead class="bg-base-200/30">
|
||||
<tr>
|
||||
<th class="text-xs font-medium text-base-content/50 py-2.5">Product</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-2.5">Brand</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-2.5 hidden md:table-cell">Brand</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-2.5 text-right">Price</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-2.5 text-right">Stock</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-2.5 text-right">Conv.</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-2.5">Status</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-2.5 text-right hidden lg:table-cell">Stock</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-2.5 text-right hidden xl:table-cell">Conv.</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-2.5 hidden sm:table-cell">Status</th>
|
||||
<th class="text-xs font-medium text-base-content/50 py-2.5"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -227,28 +212,38 @@
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-2.5"><span class="text-sm text-base-content/70" x-text="listing.brand"></span></td>
|
||||
<td class="py-2.5 hidden md:table-cell"><span class="text-sm text-base-content/70" x-text="listing.brand"></span></td>
|
||||
<td class="py-2.5 text-right font-medium text-sm">$<span x-text="listing.price.toFixed(2)"></span></td>
|
||||
<td class="py-2.5 text-right">
|
||||
<td class="py-2.5 text-right hidden lg:table-cell">
|
||||
<span class="text-sm" x-text="listing.stock"></span>
|
||||
<span x-show="listing.stock === 0" class="text-xs ml-1 text-error">(Out)</span>
|
||||
</td>
|
||||
<td class="py-2.5 text-right">
|
||||
<td class="py-2.5 text-right hidden xl:table-cell">
|
||||
<span class="text-sm text-base-content/70" x-text="getConversion(listing) + '%'"></span>
|
||||
</td>
|
||||
<td class="py-2.5">
|
||||
<td class="py-2.5 hidden sm:table-cell">
|
||||
<span x-show="listing.status === 'active'" class="badge badge-neutral badge-sm">Active</span>
|
||||
<span x-show="listing.status === 'paused'" class="badge badge-neutral badge-sm">Paused</span>
|
||||
<span x-show="listing.status === 'draft'" class="badge badge-neutral badge-sm">Draft</span>
|
||||
</td>
|
||||
<td class="py-2.5" @click.stop>
|
||||
<td class="py-2 align-middle text-right" @click.stop>
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-xs">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4 text-base-content/40"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content z-[1] menu p-1.5 bg-base-100 rounded-lg w-40 border border-base-300">
|
||||
<li><a @click="openInspector(listing)" class="text-sm py-1.5"><span class="icon-[heroicons--information-circle] size-4"></span> Quick View</a></li>
|
||||
<li><a :href="listing.edit_url" class="text-sm py-1.5"><span class="icon-[heroicons--pencil] size-4"></span> Edit</a></li>
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
<li>
|
||||
<a @click="openInspector(listing)">
|
||||
<span class="icon-[heroicons--information-circle] size-4"></span>
|
||||
Quick View
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a :href="listing.edit_url">
|
||||
<span class="icon-[heroicons--pencil] size-4"></span>
|
||||
Edit
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
@@ -451,6 +446,4 @@
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
||||
@endpush
|
||||
{{-- Alpine.js is already included in the main app bundle - no need for CDN --}}
|
||||
|
||||
@@ -200,10 +200,10 @@
|
||||
|
||||
{{-- Standard actions dropdown --}}
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[lucide--more-vertical] size-4"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content menu bg-base-100 rounded-box z-[1] w-48 p-2 shadow-lg border border-base-200">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
<li>
|
||||
<a href="{{ route('seller.business.products.edit', [$business->slug, $product->hashid]) }}">
|
||||
<span class="icon-[lucide--eye] size-4"></span>
|
||||
|
||||
@@ -501,14 +501,24 @@
|
||||
<span x-show="listing.status === 'paused'" class="badge badge-warning badge-xs">Paused</span>
|
||||
<span x-show="listing.status === 'draft'" class="badge badge-ghost badge-xs">Draft</span>
|
||||
</td>
|
||||
<td @click.stop>
|
||||
<td class="py-2 align-middle text-right" @click.stop>
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-xs">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content z-[1] menu p-2 shadow-lg bg-base-100 rounded-box w-52 border border-base-300">
|
||||
<li><a @click="openInspector(listing)"><span class="icon-[heroicons--information-circle] size-4"></span> Quick View</a></li>
|
||||
<li><a :href="listing.edit_url"><span class="icon-[heroicons--pencil] size-4"></span> Edit Product</a></li>
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
<li>
|
||||
<a @click="openInspector(listing)">
|
||||
<span class="icon-[heroicons--information-circle] size-4"></span>
|
||||
Quick View
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a :href="listing.edit_url">
|
||||
<span class="icon-[heroicons--pencil] size-4"></span>
|
||||
Edit Product
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@@ -130,12 +130,12 @@
|
||||
<td>
|
||||
<input type="checkbox" class="toggle toggle-success toggle-sm" {{ $webhook['enabled'] ? 'checked' : '' }} onchange="toggleWebhook({{ $webhook['id'] }})" />
|
||||
</td>
|
||||
<td>
|
||||
<td class="py-2 align-middle text-right">
|
||||
<div class="dropdown dropdown-end">
|
||||
<label tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<button tabindex="0" class="btn btn-ghost btn-sm btn-square">
|
||||
<span class="icon-[heroicons--ellipsis-vertical] size-4"></span>
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content z-[1] menu menu-sm p-2 shadow-lg bg-base-100 rounded-box w-48 border border-base-300">
|
||||
</button>
|
||||
<ul tabindex="0" class="dropdown-content menu menu-sm p-2 shadow-sm bg-base-100 rounded-lg w-48 border border-base-300 z-[100]">
|
||||
<li><a class="gap-2"><span class="icon-[heroicons--pencil] size-4"></span> Edit</a></li>
|
||||
<li><a class="gap-2"><span class="icon-[heroicons--paper-airplane] size-4"></span> Test Webhook</a></li>
|
||||
<li><a class="gap-2"><span class="icon-[heroicons--arrow-path] size-4"></span> View History</a></li>
|
||||
|
||||
@@ -444,6 +444,9 @@ Route::prefix('s')->name('seller.')->middleware('seller')->group(function () {
|
||||
Route::get('/{brand}/dashboard', [\App\Http\Controllers\Seller\BrandController::class, 'dashboard'])->name('dashboard');
|
||||
Route::get('/{brand}/dashboard/tab-data', [\App\Http\Controllers\Seller\BrandController::class, 'tabData'])->name('dashboard.tab-data');
|
||||
Route::get('/{brand}/stats', [\App\Http\Controllers\Seller\BrandController::class, 'stats'])->name('stats');
|
||||
Route::get('/{brand}/analysis', [\App\Http\Controllers\Seller\BrandController::class, 'analysis'])->name('analysis');
|
||||
Route::post('/{brand}/analysis/refresh', [\App\Http\Controllers\Seller\BrandController::class, 'analysisRefresh'])->name('analysis.refresh');
|
||||
Route::get('/{brand}/store-playbook/{store}', [\App\Http\Controllers\Seller\BrandController::class, 'storePlaybook'])->name('analysis.storePlaybook');
|
||||
Route::get('/{brand}/profile', [\App\Http\Controllers\Seller\BrandController::class, 'profile'])->name('profile');
|
||||
Route::get('/{brand}/edit', [\App\Http\Controllers\Seller\BrandController::class, 'edit'])->name('edit');
|
||||
Route::get('/{brand}/edit-nexus', [\App\Http\Controllers\Seller\BrandController::class, 'editNexus'])->name('edit-nexus');
|
||||
@@ -784,6 +787,10 @@ Route::prefix('s')->name('seller.')->middleware('seller')->group(function () {
|
||||
Route::get('{account:slug}/activity', [\App\Http\Controllers\Seller\Crm\AccountController::class, 'activity'])->name('activity');
|
||||
Route::get('{account:slug}/tasks', [\App\Http\Controllers\Seller\Crm\AccountController::class, 'tasks'])->name('tasks');
|
||||
Route::post('{account:slug}/notes', [\App\Http\Controllers\Seller\Crm\AccountController::class, 'storeNote'])->name('notes.store');
|
||||
// Location management (nested under accounts)
|
||||
Route::get('{account:slug}/locations/{location}/edit', [\App\Http\Controllers\Seller\Crm\AccountController::class, 'editLocation'])->name('locations.edit');
|
||||
Route::put('{account:slug}/locations/{location}', [\App\Http\Controllers\Seller\Crm\AccountController::class, 'updateLocation'])->name('locations.update');
|
||||
Route::post('{account:slug}/locations/{location}/cannaiq-search', [\App\Http\Controllers\Seller\Crm\AccountController::class, 'searchCannaiqStores'])->name('locations.cannaiq-search');
|
||||
});
|
||||
|
||||
// Contacts (All CRM contacts across all accounts) - requires account management permission
|
||||
|
||||
@@ -29,13 +29,13 @@ export default {
|
||||
themes: [
|
||||
{
|
||||
cannabrands: {
|
||||
"primary": "#4B6FA4",
|
||||
"primary": "#4E8D71",
|
||||
"primary-content": "#ffffff",
|
||||
|
||||
"secondary": "#6B7280",
|
||||
"secondary": "#4B6FA4",
|
||||
"secondary-content": "#ffffff",
|
||||
|
||||
"accent": "#4B6FA4",
|
||||
"accent": "#4E8D71",
|
||||
"accent-content": "#ffffff",
|
||||
|
||||
"success": "#4E8D71",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user