Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sanjab Laravel Package

sanjabteam/sanjab

Sanjab is a Laravel admin panel package that builds dashboards, CRUD screens, widgets, and permissions from simple configuration. It bundles media management, localization, and extensible tools for creating back-office interfaces quickly, with support for Persian and other languages.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install and pin. Add the package with an explicit version constraint (not ^1.0 if you can avoid it), then run its installer:
    composer require sanjabteam/sanjab
    php artisan sanjab:install
    
    The installer publishes config, migrations, assets, and typically creates the admin user/permission scaffolding. Run php artisan migrate and php artisan storage:link immediately after.
  2. Read config/sanjab.php first. This is the highest-leverage file in the package. Note the route prefix, the auth guard it uses, middleware stack, upload disks, pagination size, and any menu/dashboard registration hooks. Everything you debug later traces back to these values.
  3. Locate the surface area. php artisan route:list filtered by the configured prefix shows you the CRUD/dashboard endpoints the package exposes — useful when a page returns a 403 or an empty JSON payload and you need to know which controller answered.
  4. Find the registration point. The installer usually leaves you a place to declare resources (a service provider or an app/Sanjab-style directory). Put all package registrations there, never scattered across AppServiceProvider.
  5. First use case: one model, end to end. Register a single existing model (e.g. User) as a CRUD resource, list it in the sidebar menu, then log in and verify the four things that matter: the index table renders, search/filter hits the right columns, the edit form saves, and the delete action respects authorization. Get that loop working before adding dashboards or widgets — most of the package's value is this CRUD path.

Implementation Patterns

  • One registration provider, grouped by domain. Keep resource, menu, and dashboard registration in a single provider with small private methods (registerUserResources(), registerMenu(), registerDashboards()). This makes it trivial to feature-flag or disable a module later, and keeps boot time visible.
  • Resource definition as the source of truth. For each model declare index columns, form fields, searchable columns, default sort, and eager-loaded relations in one place. Resist adding columns "just in case" — every index column is a query cost and a permission question.
  • Menus derived from permissions, not hardcoded. Build menu entries conditionally on the same permission/policy you enforce in the resource. A visible menu item that 403s on click is the most common support ticket with admin panels.
  • Authorization via policies on the package's guard. Write normal Laravel policies against the model but ensure Auth::guard(...) matches the configured sanjab guard. Centralize "can this user see this resource" in the policy rather than in menu code.
  • Dashboards as thin, cached queries. Cards/widgets should run aggregate queries only; anything heavier goes behind Cache::remember with a short TTL, otherwise the landing page becomes the slowest page in the app.
  • Custom fields and view overrides for the 20%. Use the package's field types for standard input, then drop to a published/overridden view (kept under resources/views/vendor/...) for bespoke widgets. For screens that fight the abstraction (multi-step wizards, heavy bulk actions), register a plain route + controller inside the admin middleware instead of forcing a CRUD resource.
  • Permissions seeded, not clicked. Ship a seeder that creates roles/permissions for the sanjab guard so every environment (and CI) is reproducible. Pair it with a test that asserts an admin can reach the index and a non-admin gets 403.
  • Deployment is a sequence, not a step. In CI: composer install --no-dev → vendor:publish only for new assets → migrate --force → config:cache/route:cache → storage:link. Publishing assets on every deploy silently clobbers local overrides if you use --force.

Gotchas and Tips

  • Archived means frozen. No Laravel/PHP compatibility fixes are coming. Pin the exact version, lock your PHP constraint, and audit transitive dependencies (spatie/laravel-permission in particular) when you upgrade Laravel. If the app is long-lived, budget for vendoring a fork so you can patch a fatal error yourself.
  • Guard mismatch is the #1 failure mode. A logged-in web user hitting the panel with a sanjab guard gets redirect loops or 403s. Confirm the guard in config, use Auth::guard('sanjab') in your own code, and make sure policies don't assume the default guard.
  • Stale permission cache. After seeding roles/permissions, run the permission package's cache reset (and php artisan cache:clear). Otherwise new permissions "don't exist" until the next deploy.
  • Asset publishing overwrites customizations. Keep all overrides in resources/views/vendor/ and never edit published assets in public/. Use --force deliberately, and diff after publishing.
  • Dynamic registration runs every request. Menu/dashboard closures execute on boot — never put queries, counts, or API calls in them without caching.
  • Debug via the network tab. Errors in the panel often surface as JSON responses from internal endpoints; the HTML page looks fine while a 500/403 hides in the XHR. Check storage/logs/laravel.log and enable the package's debug flag in config.
  • File uploads need both config and symlink. Configure the disk in config/sanjab.php and confirm public/storage exists; a working upload with a broken preview is almost always the missing symlink.
  • Localization and RTL are first-class but not automatic. The package is Persian-first; publish its lang files if you need other locales and verify date/number formatting (Jalali vs Gregorian) matches user expectations.
  • Test with the right guard. actingAs($user, 'sanjab') in feature tests, and avoid withoutMiddleware() — it hides exactly the authorization bugs you're testing.
  • Extension points worth knowing before you fork: custom field types, custom cards/widgets, view overrides, and the configurable middleware stack. Reaching for these three first usually avoids patching vendor code — which you'll have to maintain forever since upstream is dormant.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager