Files
hub/app/helpers.php
kelly 7954804998 feat: add Brand Portal navigation, usage billing, and orchestrator improvements
Brand Portal:
- Add dedicated brand-portal-sidebar component with restricted navigation
- Add brand-portal-app layout for Brand Manager users
- Update all brand-portal views to use new restricted layout
- Add EnsureBrandManagerAccess middleware

Usage-Based Billing:
- Add usage_metrics, plan_usage_metrics, business_usage_counters tables
- Add UsageMetric, PlanUsageMetric, BusinessUsageCounter models
- Add UsageDashboard Filament page
- Add PlanUsageSeeder, UsageMetricsSeeder, SampleUsageDataSeeder

Orchestrator Enhancements:
- Add orchestrator_runs table for batch tracking
- Add OrchestratorRun model
- Add OrchestratorCrossBrandService for multi-brand campaigns
- Add orchestrator marketing config, message variants, playbook seeders

Promotions:
- Add promo tracking fields to orders
- Add key_selling_points to brands
- Add PromotionRecommendationEngine service
- Add InBrandPromoHelper, CrossBrandPromoHelper
- Add BuyerPromoIntelligence service
- Add promotion-templates config

Documentation:
- Add BRAND_MANAGER_SUITE.md
- Add USAGE_BASED_BILLING.md
- Add PLANS_AND_PRICING.md
- Add SALES_ORCHESTRATOR.md and related docs

Tests:
- Add BrandDashboardTest, BrandProfileAccessTest
- Add BrandSelectorTest, ProductPreviewTest
- Add OrchestratorBrandIntegrationTest
2025-12-01 14:24:47 -07:00

95 lines
2.3 KiB
PHP

<?php
use App\Http\Controllers\Seller\BrandSwitcherController;
use App\Models\Brand;
if (! function_exists('dashboard_url')) {
function dashboard_url(): string
{
$user = auth()->user();
// If no user is logged in, return home
if (! $user) {
return url('/');
}
// Simple dashboard URL ()
return route('dashboard');
}
}
if (! function_exists('activeBrand')) {
/**
* Get the currently active brand for the seller context.
*
* Resolution order:
* 1. Route parameter 'brand' (hashid in URL)
* 2. Session 'selected_brand_id'
* 3. User's only assigned brand (if exactly one)
* 4. Business default brand (first active brand)
*/
function activeBrand(): ?Brand
{
$user = auth()->user();
if (! $user) {
return null;
}
$business = $user->primaryBusiness();
if (! $business) {
return null;
}
// 1. Check route parameter first (brand hashid in URL)
$brandHashid = request()->route('brand');
if ($brandHashid) {
$brand = Brand::forBusiness($business)
->where('hashid', $brandHashid)
->first();
if ($brand) {
return $brand;
}
}
// 2. Check session for selected brand
$selectedBrand = BrandSwitcherController::getSelectedBrand();
if ($selectedBrand) {
return $selectedBrand;
}
// 3. If user has exactly one accessible brand, use it
$accessibleBrands = $user->accessibleBrands($business);
if ($accessibleBrands->count() === 1) {
return $accessibleBrands->first();
}
// 4. Fall back to business default (first active brand)
return Brand::forBusiness($business)
->where('is_active', true)
->orderBy('name')
->first();
}
}
if (! function_exists('activeBrandId')) {
/**
* Get the ID of the currently active brand.
*/
function activeBrandId(): ?int
{
$brand = activeBrand();
return $brand?->id;
}
}
if (! function_exists('hasActiveBrand')) {
/**
* Check if there is an active brand selected.
*/
function hasActiveBrand(): bool
{
return activeBrand() !== null;
}
}