Download the PHP package tinymvc/orbit without Composer
On this page you can find all versions of the php package tinymvc/orbit. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download tinymvc/orbit
More information about tinymvc/orbit
Files in tinymvc/orbit
Package orbit
Short Description A lightweight, fast and flexible admin dashboard built on TinyMVC + Inertia.js + React + Shadcn.
License MIT
Informations about the package orbit
Orbit — TinyMVC Dashboard Starter Kit
A lightweight, fast and flexible admin dashboard built on TinyMVC + Inertia.js + React + Shadcn
Table of Contents
- Overview
- Tech Stack
- Installation
- Via Composer (Recommended)
- Via Git Clone
- Configuration
- Running the Application
- Default Login Credentials
- Project Structure
- BREAD Module (Browse, Read, Edit, Add, Delete)
- Creating a BREAD Resource
- Resource Configuration
- Form Fields
- Table Columns
- Filters
- Bulk Actions
- Permissions
- Dynamic Props
- Lifecycle Hooks
- File Uploads
- Relationships
- Registering Routes
- Complete Resource Example
- Dashboard Module
- Stats Cards
- Charts
- Date Range Picker
- Dashboard Controller Example
- Sidebar Menu Configuration
- Permissions & Privileges
- Available Spark Commands
- License
Overview
Orbit is a production-ready admin dashboard starter kit built on top of the TinyMVC framework. It provides a robust foundation for building modern web applications with a clean, modular architecture.
Key highlights:
- BREAD Module — A powerful, zero-boilerplate CRUD system. Define one PHP resource class per entity and get a full admin interface (table, forms, filters, bulk actions) automatically — no per-model controllers or React pages needed.
- Dashboard Module — A fluent PHP API for building stat cards and charts (Bar, Line, Area, Pie, Radar, Radial) with date range filtering — all rendered via Recharts on the frontend.
- Inertia.js — Server-side routing + React SPA experience. No REST API layer needed.
- Tailwind CSS 4 + shadcn/ui — Beautiful, accessible UI components out of the box.
- Authentication — Login, forgot/reset password, email verification, user/role management with granular permissions.
Tech Stack
| Layer | Technology |
|---|---|
| Backend Framework | TinyMVC / Spark (PHP 8.2+) |
| Server ↔ Client Bridge | Inertia.js 2 |
| Frontend | React 19 + TypeScript |
| Styling | Tailwind CSS 4 |
| UI Components | shadcn/ui (Radix UI primitives) |
| Charts | Recharts |
| Rich Text Editor | Tiptap |
| Data Tables | TanStack Table |
| Build Tool | Vite |
Installation
Prerequisites
- PHP >= 8.2
- Composer
- Node.js >= 18 & npm
- SQLite (default) or MySQL / PostgreSQL
Via Composer (Recommended)
The fastest way to get started. Composer will automatically copy the env file, generate the app key, run migrations with seeds, and create the storage symlink:
Then install frontend dependencies and build:
Via Git Clone
Install PHP dependencies:
Set up the environment:
Generate application key, create storage symlink, and run migrations with seed data:
Install frontend dependencies:
Configuration
The main configuration file is .env in the project root. Key settings:
Running the Application
Development
Start the PHP development server and Vite dev server in two terminals:
The application will be available at http://localhost:8080.
Production
Build the frontend assets:
Set debug to false in .env, configure your root_url, and point your web server (Apache/Nginx) to the public/ directory.
Default Login Credentials
Navigate to /admin and log in with:
| Field | Value |
|---|---|
| Username | admin |
| Password | password |
Project Structure
BREAD Module
The BREAD (Browse, Read, Edit, Add, Delete) module is the heart of Orbit's admin interface. It lets you create fully functional CRUD interfaces by defining a single PHP resource class — no custom controllers, no custom React pages.
How It Works
- You create a Resource class (extends
App\Services\Orbit\Bread\Resource) - Define your form fields, table columns, filters, and bulk actions
- Register the route in
routes/web.phpwith one line - Add a menu entry in the React sidebar config
- Done — you get a complete CRUD interface with search, pagination, filtering, bulk actions, create/edit drawers, file uploads, relationships, and more.
Creating a BREAD Resource
Use the built-in Spark command to generate a resource scaffold:
This creates app/Http/Resources/PostsResource.php with a ready-to-customize template.
You can also create resources in subdirectories:
This creates app/Http/Resources/Blog/PostsResource.php.
Resource Configuration
Every resource has a set of static properties that control its behavior:
Form Fields
Form fields define the create/edit drawer interface. All fields use a fluent builder pattern.
Available Field Types
| Field Type | Class | Description |
|---|---|---|
| TextInput | Form\TextInput |
Text, email, password, number, URL, tel |
| Textarea | Form\Textarea |
Multi-line text area |
| Select | Form\Select |
Dropdown select (single or multi) |
| Combobox | Form\Combobox |
Searchable select with relationship support |
| SlugInput | Form\SlugInput |
Auto-generated slug from another field |
| DatePicker | Form\DatePicker |
Date or date-time picker |
| FileUpload | Form\FileUpload |
File/image upload with compression & resize |
| RichEditor | Form\RichEditor |
Tiptap rich text editor |
| Toggle | Form\Toggle |
Switch/toggle (boolean) |
| Checkbox | Form\Checkbox |
Checkbox (boolean) |
| Hidden | Form\Hidden |
Hidden field (not rendered, but submitted) |
Common Field Methods
Every field type inherits these methods from the base Field class:
TextInput Examples
SlugInput
Auto-generates a URL-friendly slug from another field:
Select
Combobox (Searchable Select)
The Combobox is the most powerful field type — it supports static options, AJAX search, belongsTo, and belongsToMany relationships:
DatePicker
FileUpload
RichEditor (Tiptap)
Toggle & Checkbox
Table Columns
Table columns define how data appears in the browse table.
Column Types Reference
| Method | Description |
|---|---|
->text() |
Plain text (default) |
->badge() |
Colored badge with ->badgeMap() |
->date() |
Formatted date |
->image() |
Image with ->imageSize() |
->thumbnail() |
Thumbnail card preview |
->avatar($field) |
Circular avatar + display name |
->tags() |
Array of items as badges |
->boolean() |
True/false indicator |
->html() |
Rendered HTML content |
->belongsTo() |
Related model display |
Column Modifiers
| Method | Description |
|---|---|
->header('Label') |
Custom column header |
->clickToEdit() |
Click row to open edit drawer |
->truncate(50) |
Truncate text to N characters |
->hidden() |
Initially hidden (toggleable) |
->display(['field1', 'field2']) |
Fields to display (for relations) |
->limit(3) |
Max items to show (for tags) |
->className('text-red-500') |
Custom CSS class |
->accessor('user.name') |
Nested data accessor |
Filters
Server-side filters appear as dropdowns above the table:
Bulk Actions
Bulk actions appear when rows are selected:
You can also handle custom bulk actions in the resource:
Permissions
Set permission requirements on each CRUD operation:
Set to null to disable the permission check for that operation.
Don't forget to register your permission keys in
config/privileges.php:
Dynamic Props
Send additional data to the frontend (e.g., options for select/combobox fields):
Fields reference these using ->dynamicOptions('categories') or ->options('dynamic:categories').
Lifecycle Hooks
Resources provide hooks to customize behavior at every stage:
File Uploads
File fields use Spark\Facades\Storage for uploading and deleting files. Choose any
named disk from config/storage.php in the resource definition:
Existing fields default to public, preserving storage/uploads and existing
relative paths. uploadTo() is relative to the selected disk's root. The server
chooses the disk; browser input cannot override it. Changing a field's disk does
not move existing files: migrate those objects before changing its configuration.
BREAD validates form values before uploads, keeps only existing keys belonging to the edited record, removes replaced files after a successful save, and rolls back new uploads after failed batches or saves. Image resize/compression settings are passed to TinyCore's disk uploader (JPEG, PNG and GIF transforms in the installed version). Multiple-file columns should use a JSON/array model cast.
Stored keys remain separate from preview URLs. Public disks use Storage::url();
private local files use an authenticated resource endpoint and streamed responses.
Private S3 previews redirect to Storage::temporaryUrl() links lasting five minutes.
Preview requests check the resource's browse permission and exact record/field/key
association. Existing external URLs and explicit mediaUrl() overrides remain
supported. Configure AWS credentials, bucket, region, and optional endpoint in
config/storage.php/environment variables. S3-compatible providers use the same disk.
Soft Delete and Trash
Posts use Tinycore's native soft deletes. Run php spark migrate before serving
this version to add the nullable posts.deleted_at column. Existing posts stay
active; the migration does not remove or rewrite their content.
BREAD automatically detects a model's protected const USE_SOFT_DELETES = true
and its deletion column (including SOFT_DELETE_COLUMN overrides). For another
resource, add that constant to its model and add $table->softDeletes() in a new
table migration. Models without soft deletes keep their normal delete behavior.
The table offers Without trashed (default), With trashed, and Only
trashed views using trashed=without|with|only. Search, filters, sorting, and
pagination work within the selected view. The compact trash selector sits after search and shows Active, All, or Trashed.
Trashed rows have a subtle background and an inline badge beside their first visible
data cell, without adding a column; they cannot be edited. Row menus and bulk actions support moving to trash, restoring, and
permanent deletion, with confirmation before destructive actions. In mixed
selections each action operates only on eligible records and displays that count.
DELETE /admin/{resource}/{id}moves an active record to trash.POST /admin/{resource}/{id}/restorerestores a trashed record.DELETE /admin/{resource}/{id}/force-deletepermanently deletes a trashed record.- The bulk endpoint accepts
delete,restore, andforce-deleteactions.
Trash and restore preserve uploaded files and relationship links. Permanent
deletion removes owned files from each field's configured disk after the database
delete succeeds. Private file previews remain available to users with the resource's
browse permission while the record is in trash. Trashed slugs remain reserved by
the unique constraint, so restoring cannot conflict with a reused slug. The existing
archived publication status is separate from trash.
Posts permissions are posts.delete, posts.restore, and posts.force_delete.
Assign the new permissions to roles that need recovery or permanent deletion;
all.access already includes them. Generic resources can set $restorePerm and
$forceDeletePerm; null defaults to their delete permission. Lifecycle hooks
beforeDelete, beforeRestore, afterRestore, and beforeForceDelete run for
individual and bulk actions. Restore and permanent deletion routes are registered
only for soft-delete models.
The shared React BREAD component also supports hand-built tables with
softDeletes: { column: 'deleted_at', badgeColumn: 'title' } in BreadConfig.
badgeColumn is optional; if omitted or hidden, the badge follows the first visible
data column. Server-driven resources receive this configuration automatically
from the model. Pass the supplied restore/permanent-delete handlers and permission
flags to BreadActionsCell when defining custom action columns.
Table and Editor Options
The updated BREAD component uses Orbit's Inertia transport and error handling. It supports desktop drawers or modals, mobile drawers, configurable page sizes, page jumping, multi-select/exclusion filters, grouped advanced filters, optional saved table query state, deep links, and reusable inline-edit cells.
Mark allowed server sort columns with Table\Column::make('name')->sortable().
Pagination is capped at 500 rows, clamps out-of-range pages, and sorting/filtering
runs before pagination. Advanced filters are opt-in scalar database fields;
unknown fields/operators and malformed values are rejected. Relationships still
use custom filter callbacks. Date filters accept YYYY-MM-DD values.
queryKey() changes the request parameter while the field key still names the
filtered column. Multi-select callbacks receive an array. Saved query state is
opt-in, scoped by user ID, and explicit URLs take precedence.
For handwritten React pages, use BreadConfig.editor, pageSizeOptions,
serverSorting, advancedFilters, and tableStateStorageKey. The legacy
size.drawer_width remains supported. deepLink: { param, fetchRecord? } opens
an editor from a record ID in the URL; fetchRecord must enforce access on its
server endpoint. BreadInlineEditCell accepts a value, label, render function,
and asynchronous onSave; reject that promise on validation/save failure so the
editor remains open. These optional APIs do not automatically enable partial
updates in a resource's existing validation rules.
Relationships
BelongsTo
For foreign key fields (e.g., a post belongs to a user):
The user_id value is stored directly on the model.
BelongsToMany
For pivot table relationships (e.g., a post has many categories):
The BREAD module automatically calls sync() on the relationship after create/update.
Registering Routes
In routes/web.php, register your resource with a single line inside the authenticated route group:
This registers the following routes automatically:
| Method | URI | Action |
|---|---|---|
GET |
/admin/products |
Index (browse table) |
POST |
/admin/products |
Store (create record) |
PUT |
/admin/products/{id} |
Update (edit record) |
DELETE |
/admin/products/{id} |
Destroy (delete record) |
POST |
/admin/products/bulk-action |
Bulk action handler |
GET |
/admin/products/search |
AJAX search (for Combobox) |
Complete Resource Example
Here's a full real-world example — the Posts resource included with Orbit:
Dashboard Module
The Dashboard module provides a fluent PHP API for building analytics dashboards with stat cards and charts. The frontend renders everything automatically using Recharts.
Stats Cards
Stats cards display key metrics at the top of the dashboard:
Charts
Six chart types are available, all sharing a common fluent API:
| Chart Type | Class | Best For |
|---|---|---|
| BarChart | Charts\BarChart |
Comparing categories |
| LineChart | Charts\LineChart |
Trends over time |
| AreaChart | Charts\AreaChart |
Volume trends |
| PieChart | Charts\PieChart |
Proportional distribution |
| RadarChart | Charts\RadarChart |
Multi-axis comparison |
| RadialChart | Charts\RadialChart |
Progress/gauge metrics |
Common Chart API
PieChart
RadialChart (Gauge/Progress)
Date Range Picker
Enable a date range picker with quick presets:
The date range is sent as ?from=YYYY-MM-DD&to=YYYY-MM-DD query parameters to the route.
Dashboard Controller Example
Sidebar Menu Configuration
The sidebar navigation is configured in resources/app/config/menu.ts. Import Lucide icons and define your menu structure:
MenuItem Interface
Sidebar Appearance
Customize the sidebar in resources/app/config/sidebar.ts:
Permissions & Privileges
Permission keys are defined in config/privileges.php:
These keys are referenced in:
- Resource classes via
$browsePerm,$createPerm,$editPerm,$deletePerm - Menu items via the
permissionarray - Frontend via the
can()/cannot()helpers from the app context
Available Spark Commands
| Command | Description |
|---|---|
php spark serve |
Start the development server |
php spark key:generate |
Generate the application encryption key |
php spark migrate |
Run database migrations |
php spark migrate --seed |
Run migrations with seed data |
php spark migrate:fresh --seed |
Re-Run migrations with seed data |
php spark storage:link |
Create a symbolic link for public storage |
php spark make:bread {Name} |
Generate a new BREAD resource |
Quick Start Checklist
Here's the step-by-step to add a new CRUD resource (e.g., Products):
- Create the model — Define your
Productmodel inapp/Models/Product.php - Create a migration — Add a migration in
database/migrations/ - Generate the resource — Run
php spark make:bread Product - Customize the resource — Edit
app/Http/Resources/ProductsResource.php(fields, columns, filters, etc.) - Register the route — Add
ResourceController::routes(ProductsResource::class);to the auth group inroutes/web.php - Add permissions — Add a
productssection inconfig/privileges.php - Add the menu item — Add an entry in
resources/app/config/menu.ts - Run migrations —
php spark migrate - Done! — Visit
/admin/products
Testing
Run the PHP regression suite and frontend checks:
Use php test --filter=BreadTest or php test --testsuite=Unit for a focused run.
Feature tests use in-memory SQLite and a separate temporary storage directory for
each test; they do not use the application's database, .env, or compiled config.
The multipart upload test launches a temporary PHP server on loopback and needs
ext-curl, proc_open, and permission to open a local port. All server processes,
generated test resources, and temporary files are cleaned up.
Coverage includes authentication and CSRF, permissions, users and roles, profile updates, notification pagination/read actions/ownership, BREAD CRUD/search/filtering/relationships, file retention and uploads, resource generation, dashboard and form schemas, default seeders, CORS, and the configured SQLite cache/locks/queue and local disks. S3 upload/signing/cleanup is tested against an isolated local S3 transport fixture. External SMTP, Redis, live S3 buckets, and MySQL/PostgreSQL integrations need separate testing against those services.
Notifications are available in the header drawer. The authenticated feed returns
20 items per request, newest first, with an ID cursor for infinite scrolling.
Opening a notification's View action marks it read before navigating. Badge counts
include all unread notifications, including older pages. The drawer supports
retrying failed loads, individual read/remove actions, marking all read, and
clearing the current user's notifications. There is no standalone notifications
page. npm test covers the feed client and read-before-navigation behavior.
BREAD and Dashboard now live under app/Services, with namespaces
App\Services\Orbit\Bread and App\Services\Orbit\Dashboard. After upgrading an existing
checkout, run composer dump-autoload and php spark config:clear to refresh
class maps and cached configuration. Orbit retains its redirecting auth/guest
middleware. The Inertia integration uses the adapter's Inertia::once,
Inertia::always, and Inertia::optional APIs, script-based initial page data,
and page.flash; its React client requires version 2.3.28 or later in the 2.x line.
License
Orbit is open-source software licensed under the MIT License.
Created by Shahin Moyshan.
All versions of orbit with dependencies
tinymvc/tinycore Version ^4.1
tinymvc/inertia-php Version ^2.0
phpmailer/phpmailer Version ^7.0
voku/portable-ascii Version ^2.0