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
95 lines
2.3 KiB
PHP
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;
|
|
}
|
|
}
|