initial: bootstrap from BukidBountyApp base
This commit is contained in:
657
app/Http/Controllers/Support/VueRouteMap.php
Normal file
657
app/Http/Controllers/Support/VueRouteMap.php
Normal file
@@ -0,0 +1,657 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Support;
|
||||
|
||||
use Hypervel\Support\Facades\Route;
|
||||
use Hypervel\Support\Facades\Auth;
|
||||
use App\Enums\UserTypes;
|
||||
use App\Support\ModuleHelper;
|
||||
|
||||
/**
|
||||
* VueRouteMap handles automated registration of Vue SPA pages mapped via the Custom Inertia setup.
|
||||
* It provides a modular way to handle ViewMap functionality without cluttering web.php.
|
||||
*/
|
||||
class VueRouteMap
|
||||
{
|
||||
/**
|
||||
* Define the route mappings here.
|
||||
* key: The URI route
|
||||
* value: An array with:
|
||||
* - 'component' (string): The Vue component path (e.g. 'ListProductsMarket')
|
||||
* - 'middlewares' (array|string): Optional middlewares to apply to this route
|
||||
* - 'name' (string): Optional route name
|
||||
* - 'loginRequired' (bool): Whether authentication is required to access this page
|
||||
* - 'allowedUserTypes' (array): List of allowed user types who can view this page
|
||||
*/
|
||||
protected static array $routes = [
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Example Usage
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| '/my-path' => [
|
||||
| 'component' => 'MyVueComponent',
|
||||
| 'middlewares' => ['auth'],
|
||||
| 'name' => 'my.route.name',
|
||||
| 'loginRequired' => true,
|
||||
| 'allowedUserTypes' => ['ult', 'operator'],
|
||||
| ],
|
||||
*/
|
||||
|
||||
// Public pages - no login required
|
||||
'/' => [
|
||||
'component' => 'Home',
|
||||
'loginRequired' => false,
|
||||
],
|
||||
'/app' => [
|
||||
'component' => 'Home',
|
||||
'loginRequired' => false,
|
||||
],
|
||||
'/bukidbountyapp' => [
|
||||
'component' => 'Home',
|
||||
'loginRequired' => false,
|
||||
],
|
||||
|
||||
// Market pages - public access
|
||||
'/list-products-market' => [
|
||||
'component' => 'ListProductsMarket',
|
||||
'loginRequired' => false,
|
||||
],
|
||||
'/list-stores' => [
|
||||
'component' => 'ListStores',
|
||||
'loginRequired' => false,
|
||||
],
|
||||
'/my-stores' => [
|
||||
'component' => 'MyStores',
|
||||
'loginRequired' => true,
|
||||
'module' => 'stores',
|
||||
],
|
||||
'/buy-view-product-market' => [
|
||||
'component' => 'BuyViewProductMarket',
|
||||
'loginRequired' => false,
|
||||
],
|
||||
'/view-store-market' => [
|
||||
'component' => 'ViewStoreMarket',
|
||||
'loginRequired' => false,
|
||||
],
|
||||
'/view-all-photos' => [
|
||||
'component' => 'ViewAllPhotos',
|
||||
'loginRequired' => false,
|
||||
],
|
||||
'/photo-viewer' => [
|
||||
'component' => 'PhotoViewer',
|
||||
'loginRequired' => false,
|
||||
],
|
||||
'/create-store' => [
|
||||
'component' => 'CreateStore',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner'],
|
||||
'module' => 'stores',
|
||||
],
|
||||
'/pos' => [
|
||||
'component' => 'PosMain',
|
||||
'loginRequired' => false,
|
||||
'module' => 'pos',
|
||||
],
|
||||
|
||||
// Account settings - requires login
|
||||
'/account-settings' => [
|
||||
'component' => 'AccountSettings',
|
||||
'loginRequired' => true,
|
||||
],
|
||||
|
||||
'/create-user' => [
|
||||
'component' => 'CreateUser',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'coordinator', 'store owner', 'store manager', 'supplier overseer', 'supplier'],
|
||||
],
|
||||
|
||||
// Administrative & Management pages
|
||||
'/create-product' => [
|
||||
'component' => 'CreateProductUltimate',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner'],
|
||||
'module' => 'products',
|
||||
],
|
||||
'/add-products-to-store' => [
|
||||
'component' => 'AddProductsToStore',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
|
||||
'module' => 'stores',
|
||||
],
|
||||
'/create-product-store-owner' => [
|
||||
'component' => 'CreateProductStoreOwner',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
|
||||
'module' => 'products',
|
||||
],
|
||||
'/edit-product' => [
|
||||
'component' => 'EditProductUltimate',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner'],
|
||||
'module' => 'products',
|
||||
],
|
||||
'/edit-store' => [
|
||||
'component' => 'EditStoreUltimate',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
|
||||
'module' => 'stores',
|
||||
],
|
||||
'/transfer-credit' => [
|
||||
'component' => 'TransferMyCredit',
|
||||
'loginRequired' => true,
|
||||
'module' => 'credits',
|
||||
],
|
||||
'/user-list' => [
|
||||
'component' => 'UserList',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'audit'],
|
||||
],
|
||||
'/manage-transactions' => [
|
||||
'component' => 'ManageGlobalTransactions',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator'],
|
||||
'module' => 'transactions',
|
||||
],
|
||||
'/remove-product' => [
|
||||
'component' => 'RemoveProductFromStoreAdmin',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator'],
|
||||
'module' => 'stores',
|
||||
],
|
||||
'/assign-product-to-store' => [
|
||||
'component' => 'AssignProductToStore',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
|
||||
],
|
||||
'/manage-products' => [
|
||||
'component' => 'ManageProductsAdmin',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
|
||||
'module' => 'products',
|
||||
],
|
||||
'/manage-stores' => [
|
||||
'component' => 'ManageStoresAdmin',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
|
||||
'module' => 'stores',
|
||||
],
|
||||
'/pos-access-keys' => [
|
||||
'component' => 'PosAccessKeys',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
|
||||
'module' => 'pos',
|
||||
],
|
||||
'/add-transaction' => [
|
||||
'component' => 'AddTransaction',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
|
||||
'module' => 'transactions',
|
||||
],
|
||||
'/manage-product-admin' => [
|
||||
'component' => 'ManageProductAdmin',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
|
||||
'module' => 'products',
|
||||
],
|
||||
'/batch-add-products' => [
|
||||
'component' => 'BatchAddProducts',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner'],
|
||||
'module' => 'batch',
|
||||
],
|
||||
'/batch-add-stores' => [
|
||||
'component' => 'BatchAddStores',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator'],
|
||||
'module' => 'batch',
|
||||
],
|
||||
'/batch-add-users' => [
|
||||
'component' => 'BatchAddUsers',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator'],
|
||||
'module' => 'batch',
|
||||
],
|
||||
'/batch-add-cooperatives' => [
|
||||
'component' => 'BatchAddCooperatives',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator'],
|
||||
'module' => 'batch',
|
||||
],
|
||||
'/pos-history' => [
|
||||
'component' => 'PosHistory',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
|
||||
'module' => 'pos',
|
||||
],
|
||||
|
||||
// Logistics & Shipments
|
||||
|
||||
|
||||
|
||||
// Property Management
|
||||
'/list-properties' => [
|
||||
'component' => 'ListProperties',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator'],
|
||||
'module' => 'properties',
|
||||
],
|
||||
'/list-referrals' => [
|
||||
'component' => 'ListReferrals',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator'],
|
||||
'module' => 'properties',
|
||||
],
|
||||
|
||||
// Reports
|
||||
'/list-reports' => [
|
||||
'component' => 'ListReports',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
|
||||
'module' => 'accounting',
|
||||
],
|
||||
'/shipment-list' => [
|
||||
'component' => 'ShipmentList',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager', 'rider', 'audit'],
|
||||
'module' => 'shipments',
|
||||
],
|
||||
'/shipment-detail' => [
|
||||
'component' => 'ShipmentDetail',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager', 'rider', 'audit'],
|
||||
'module' => 'shipments',
|
||||
],
|
||||
'/farmer-profile-edit' => [
|
||||
'component' => 'FarmerProfileEdit',
|
||||
'loginRequired' => true,
|
||||
'module' => 'farmers',
|
||||
],
|
||||
'/verification-dashboard' => [
|
||||
'component' => 'VerificationDashboard',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator'],
|
||||
'module' => 'farmers',
|
||||
],
|
||||
'/cooperative-list' => [
|
||||
'component' => 'CooperativeList',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'coordinator', 'coop officer', 'coop member'],
|
||||
'module' => 'cooperatives',
|
||||
],
|
||||
'/chapter-org-chart' => [
|
||||
'component' => 'ChapterOrgChart',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'coordinator', 'coop officer', 'coop member'],
|
||||
'module' => 'cooperatives',
|
||||
],
|
||||
'/coop-member-search' => [
|
||||
'component' => 'CoopMemberSearch',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'coordinator', 'coop officer'],
|
||||
'module' => 'cooperatives',
|
||||
],
|
||||
'/create-coop-user' => [
|
||||
'component' => 'CreateCoopUser',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'coordinator', 'coop officer'],
|
||||
'module' => 'cooperatives',
|
||||
],
|
||||
'/assign-chapter-officer' => [
|
||||
'component' => 'AssignChapterOfficer',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'coordinator', 'coop officer'],
|
||||
'module' => 'cooperatives',
|
||||
],
|
||||
'/create-chapter' => [
|
||||
'component' => 'CreateChapter',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'coordinator', 'coop officer'],
|
||||
'module' => 'cooperatives',
|
||||
],
|
||||
'/register-chapter' => [
|
||||
'component' => 'RegisterChapter',
|
||||
'loginRequired' => false,
|
||||
'module' => 'cooperatives',
|
||||
],
|
||||
'/create-cooperative' => [
|
||||
'component' => 'CreateCooperative',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'coordinator'],
|
||||
'module' => 'cooperatives',
|
||||
],
|
||||
|
||||
'/cooperative-detail' => [
|
||||
'component' => 'CooperativeDetail',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'coordinator', 'coop officer', 'coop member'],
|
||||
'module' => 'cooperatives',
|
||||
],
|
||||
'/enroll-farmer' => [
|
||||
'component' => 'EnrollFarmer',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator'],
|
||||
'module' => 'farmers',
|
||||
],
|
||||
'/cooperative-member-register' => [
|
||||
'component' => 'CooperativeMemberRegister',
|
||||
'loginRequired' => true,
|
||||
'module' => 'cooperatives',
|
||||
],
|
||||
'/register-coop' => [
|
||||
'component' => 'RegisterCoop',
|
||||
'loginRequired' => false,
|
||||
'module' => 'cooperatives',
|
||||
],
|
||||
'/user-registration' => [
|
||||
'component' => 'UserRegistration',
|
||||
'loginRequired' => false,
|
||||
],
|
||||
'/user-info-edit' => [
|
||||
'component' => 'UserInfoEdit',
|
||||
'loginRequired' => true,
|
||||
],
|
||||
'/ultimate-console' => [
|
||||
'component' => 'UltimateConsole',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult'],
|
||||
],
|
||||
'/system-settings' => [
|
||||
'component' => 'SystemSettings',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult'],
|
||||
],
|
||||
'/landing-page-editor' => [
|
||||
'component' => 'LandingPageEditor',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'coordinator'],
|
||||
'module' => 'landing_pages',
|
||||
],
|
||||
'/accounting-dashboard' => [
|
||||
'component' => 'AccountingDashboard',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
|
||||
'module' => 'accounting',
|
||||
'store_module' => 'accounting_store',
|
||||
],
|
||||
'/manage-accounts' => [
|
||||
'component' => 'ManageAccounts',
|
||||
'loginRequired' => true,
|
||||
'allowedUserTypes' => ['ult', 'super operator', 'operator', 'store owner', 'store manager'],
|
||||
'module' => 'accounting',
|
||||
'store_module' => 'accounting_store',
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Helper method to check if user is allowed based on their type.
|
||||
* Returns true if the user can access the page, false otherwise.
|
||||
*/
|
||||
private static function isUserAllowed(string $currentUserType, array $allowedUserTypes): bool
|
||||
{
|
||||
// If no restrictions specified, allow all authenticated users
|
||||
if (empty($allowedUserTypes)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if user type matches any allowed types
|
||||
foreach ($allowedUserTypes as $type) {
|
||||
if (is_string($type) && $currentUserType === $type) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the defined Vue routes into the application.
|
||||
* This should be called in `routes/web.php`.
|
||||
*/
|
||||
public static function registerRoutes(): void
|
||||
{
|
||||
foreach (self::$routes as $uri => $settings) {
|
||||
$component = $settings['component'] ?? '';
|
||||
$middlewares = $settings['middlewares'] ?? [];
|
||||
$name = $settings['name'] ?? null;
|
||||
$loginRequired = $settings['loginRequired'] ?? false;
|
||||
$allowedUserTypes = $settings['allowedUserTypes'] ?? [];
|
||||
|
||||
$options = [];
|
||||
|
||||
if (!empty($middlewares)) {
|
||||
$options['middleware'] = $middlewares;
|
||||
}
|
||||
|
||||
if ($name) {
|
||||
$options['as'] = $name;
|
||||
}
|
||||
|
||||
// Add login requirement middleware if needed
|
||||
if ($loginRequired) {
|
||||
$options['middleware'] = array_unique(array_merge($options['middleware'] ?? [], ['auth']));
|
||||
}
|
||||
|
||||
// Add module requirement middleware if specified
|
||||
$moduleKey = $settings['module'] ?? null;
|
||||
if ($moduleKey) {
|
||||
$options['middleware'] = array_unique(array_merge($options['middleware'] ?? [], ["module:{$moduleKey}"]));
|
||||
}
|
||||
|
||||
Route::get($uri, function (...$routeParams) use ($component, $loginRequired, $allowedUserTypes, $moduleKey) {
|
||||
// Check if user is authenticated
|
||||
if (empty(Auth::user())) {
|
||||
// If login is required but not available, redirect to login page
|
||||
if ($loginRequired) {
|
||||
return redirect('/login');
|
||||
}
|
||||
}
|
||||
|
||||
// Check if module is enabled
|
||||
if ($moduleKey && ModuleHelper::isDisabled($moduleKey)) {
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
// Global Page Disabled Check
|
||||
/** @var \App\Models\User $user */
|
||||
$user = Auth::user();
|
||||
$disabledPages = \App\Models\SystemSetting::getValue('disabled_pages', []);
|
||||
if (is_array($disabledPages) && in_array(strtolower((string)$component), array_map('strtolower', $disabledPages))) {
|
||||
// Ultimate accounts can still access to allow fixing settings
|
||||
if (!$user || $user->acct_type !== UserTypes::ULTIMATE) {
|
||||
return redirect('/');
|
||||
}
|
||||
}
|
||||
|
||||
// Check allowed user types if specified
|
||||
if (!empty($allowedUserTypes)) {
|
||||
$currentUserType = $user->acct_type?->value ?? $user->acct_type ?? UserTypes::PUBLIC->value;
|
||||
$isAllowed = self::isUserAllowed($currentUserType, $allowedUserTypes);
|
||||
if (!$isAllowed) {
|
||||
// Redirect to a forbidden page or login
|
||||
return redirect('/login');
|
||||
}
|
||||
}
|
||||
|
||||
// Return Inertia page properly set up with current user data
|
||||
// Pass parameterized URL segments to the Vue component as properties
|
||||
$page = Inertia::render($component, [
|
||||
'user' => Auth::user(),
|
||||
'routeParams' => empty($routeParams) ? null : $routeParams
|
||||
]);
|
||||
|
||||
return view('layouts/application-layout', compact('page'));
|
||||
}, $options);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a generic SPA request by converting the path into a component name.
|
||||
* This acts as a catch-all universal router.
|
||||
*/
|
||||
public static function handleSpa(string $path = '/')
|
||||
{
|
||||
$path = trim($path, '/');
|
||||
|
||||
// Get user type for access control
|
||||
/** @var \App\Models\User $user */
|
||||
$user = Auth::user();
|
||||
$currentUserType = null;
|
||||
|
||||
if ($user) {
|
||||
$currentUserType = $user->acct_type?->value ?? $user->acct_type ?? UserTypes::PUBLIC->value;
|
||||
}
|
||||
|
||||
// Strip hashkey/payload suffix from path (e.g., "edituser--h:HASHKEY" -> "edituser")
|
||||
// Use RouteArgumentParser to properly extract the base component name
|
||||
$component = $path;
|
||||
|
||||
try {
|
||||
$parser = new \App\Support\RouteArgumentParser();
|
||||
$parsedData = $parser->parseArgument($path);
|
||||
|
||||
// If we have a hash or payload format, use the slug as the component
|
||||
if (isset($parsedData['slug']) && ($parsedData['type'] === 'hash' || $parsedData['type'] === 'payload')) {
|
||||
$component = $parsedData['slug'];
|
||||
}
|
||||
} catch (\Throwable $th) {
|
||||
// If parsing fails or no hash/payload format, use original path
|
||||
}
|
||||
|
||||
// fallback to Home if empty
|
||||
$component = empty($component) ? 'Home' : $component;
|
||||
|
||||
// Convert lowercase component names to camelCase for Vue component matching
|
||||
// e.g., "edituser" -> "EditUser"
|
||||
$vueComponent = self::toCamelCase($component);
|
||||
|
||||
// Find base component from routes map using the route key
|
||||
$componentLower = strtolower($component);
|
||||
$routeKey = '/' . $componentLower;
|
||||
|
||||
$loginRequired = true; // Default: require login
|
||||
$pathWithSlash = '/' . ltrim($path, '/');
|
||||
$pathLower = strtolower($pathWithSlash);
|
||||
|
||||
$routeSettings = self::$routes[$pathWithSlash] ?? self::$routes[$pathLower] ?? null;
|
||||
$allowedUserTypes = [];
|
||||
$moduleKey = null;
|
||||
$foundInMap = false;
|
||||
|
||||
if ($routeSettings) {
|
||||
$settings = $routeSettings;
|
||||
$vueComponent = $settings['component'] ?? $vueComponent;
|
||||
$loginRequired = $settings['loginRequired'] ?? true;
|
||||
$allowedUserTypes = $settings['allowedUserTypes'] ?? [];
|
||||
$moduleKey = $settings['module'] ?? null;
|
||||
$foundInMap = true;
|
||||
} else {
|
||||
// Try hyphen-insensitive match (e.g. "viewstoremarket" vs "view-store-market")
|
||||
$cleanSlug = str_replace(['-', '_'], '', $componentLower);
|
||||
foreach (self::$routes as $uri => $settings) {
|
||||
$cleanUri = str_replace(['-', '_'], '', strtolower(trim($uri, '/')));
|
||||
if ($cleanUri === $cleanSlug) {
|
||||
$vueComponent = $settings['component'] ?? $vueComponent;
|
||||
$loginRequired = $settings['loginRequired'] ?? true;
|
||||
$allowedUserTypes = $settings['allowedUserTypes'] ?? [];
|
||||
$moduleKey = $settings['module'] ?? null;
|
||||
$foundInMap = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$foundInMap) {
|
||||
// Fallback: search by Vue component name (case-insensitive) in case they passed the component direct name
|
||||
foreach (self::$routes as $uri => $settings) {
|
||||
$mappedComponent = $settings['component'] ?? '';
|
||||
if (strcasecmp($mappedComponent, $vueComponent) === 0) {
|
||||
$vueComponent = $mappedComponent; // Use the correctly cased name from map
|
||||
$loginRequired = $settings['loginRequired'] ?? true;
|
||||
$allowedUserTypes = $settings['allowedUserTypes'] ?? [];
|
||||
$moduleKey = $settings['module'] ?? null;
|
||||
$foundInMap = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Enforce login requirement
|
||||
if ($loginRequired && empty($user)) {
|
||||
return redirect('/login');
|
||||
}
|
||||
|
||||
// Enforce module requirement
|
||||
if ($moduleKey && ModuleHelper::isDisabled($moduleKey)) {
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
// For store-level users, check the store-specific module toggle
|
||||
$storeModuleKey = $routeSettings['store_module'] ?? null;
|
||||
if ($storeModuleKey && in_array($currentUserType, ['store owner', 'store manager'])) {
|
||||
if (ModuleHelper::isDisabled($storeModuleKey)) {
|
||||
return redirect('/');
|
||||
}
|
||||
}
|
||||
|
||||
// Global Page Disabled Check
|
||||
$disabledPages = \App\Models\SystemSetting::getValue('disabled_pages', []);
|
||||
if (is_array($disabledPages) && in_array(strtolower((string)$vueComponent), array_map('strtolower', $disabledPages))) {
|
||||
// Ultimate accounts can still access to allow fixing settings
|
||||
if (!$user || $user->acct_type !== UserTypes::ULTIMATE) {
|
||||
return redirect('/');
|
||||
}
|
||||
}
|
||||
|
||||
// Check allowed user types if specified
|
||||
if (!empty($allowedUserTypes) && $currentUserType !== null) {
|
||||
$isAllowed = self::isUserAllowed($currentUserType, $allowedUserTypes);
|
||||
if (!$isAllowed) {
|
||||
// Redirect to a forbidden page or login
|
||||
return redirect('/login');
|
||||
}
|
||||
}
|
||||
|
||||
// Pass standard Inertia props with hashkey if present
|
||||
$props = [
|
||||
'user' => Auth::user(),
|
||||
];
|
||||
|
||||
// Add hashkey to props if it was in the URL for special pages
|
||||
if (isset($parsedData['type']) && $parsedData['type'] === 'hash') {
|
||||
// Provide the hash value under multiple common prop names for better compatibility
|
||||
$props['hashkey'] = $parsedData['value'];
|
||||
$props['target'] = $parsedData['value'];
|
||||
$props['id'] = $parsedData['value'];
|
||||
} elseif (isset($parsedData['type']) && $parsedData['type'] === 'payload') {
|
||||
$props['payload'] = $parsedData['value'];
|
||||
}
|
||||
|
||||
$page = Inertia::render($vueComponent, $props);
|
||||
|
||||
return view('layouts/application-layout', compact('page'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert snake_case or lowercase to camelCase for Vue component matching.
|
||||
*/
|
||||
private static function toCamelCase(string $name): string
|
||||
{
|
||||
// Replace slashes with dots first to handle directory structures
|
||||
$name = str_replace('/', '.', $name);
|
||||
|
||||
// Split by dot (hierarchy)
|
||||
$parts = explode('.', $name);
|
||||
$pascalParts = array_map(function($part) {
|
||||
// Split by hyphen and capitalize each part for PascalCase
|
||||
$subParts = explode('-', $part);
|
||||
return implode('', array_map('ucfirst', $subParts));
|
||||
}, $parts);
|
||||
|
||||
// Return with dots if original had them, otherwise just one string
|
||||
return implode('.', $pascalParts);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user