boilercraft 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +171 -0
- package/bin/boilercraft.js +110 -0
- package/cli/app.js +596 -0
- package/cli/ui.js +356 -0
- package/docs/STACK_ENGINE.md +93 -0
- package/docs/assets/cli-create.svg +52 -0
- package/docs/assets/cli-menu.svg +47 -0
- package/docs/stacks/dotnet-core.md +69 -0
- package/docs/stacks/laravel-vue.md +46 -0
- package/docs/stacks/nextjs.md +58 -0
- package/docs/stacks/node-express.md +58 -0
- package/docs/stacks/raw-php.md +130 -0
- package/main.js +82 -0
- package/package.json +86 -0
- package/public/index.html +721 -0
- package/public/logo.png +17 -0
- package/public/logo.svg +17 -0
- package/server.js +84 -0
- package/services/componentGenerator.js +195 -0
- package/services/engine/scaffoldEngine.js +517 -0
- package/services/engine/toolInstaller.js +232 -0
- package/services/engine/versionCatalog.js +115 -0
- package/services/generate.js +46 -0
- package/services/projectGenerator.js +686 -0
- package/services/readmeGenerator.js +221 -0
- package/services/themeGenerator.js +150 -0
- package/services/versionResolver.js +176 -0
- package/stacks/dotnet-core/overlays/api/Controllers/ProductsController.cs +33 -0
- package/stacks/dotnet-core/overlays/api/Program.cs +33 -0
- package/stacks/dotnet-core/overlays/api/wwwroot/index.html +38 -0
- package/stacks/dotnet-core/overlays/api-auth/Controllers/AuthController.cs +87 -0
- package/stacks/dotnet-core/overlays/common/Data/ApplicationDbContext.cs +25 -0
- package/stacks/dotnet-core/overlays/common/Models/Product.cs +19 -0
- package/stacks/dotnet-core/overlays/mvc/Controllers/ProductsController.cs +84 -0
- package/stacks/dotnet-core/overlays/mvc/Views/Home/Index.cshtml +23 -0
- package/stacks/dotnet-core/overlays/mvc/Views/Products/Create.cshtml +16 -0
- package/stacks/dotnet-core/overlays/mvc/Views/Products/Delete.cshtml +16 -0
- package/stacks/dotnet-core/overlays/mvc/Views/Products/Edit.cshtml +17 -0
- package/stacks/dotnet-core/overlays/mvc/Views/Products/Index.cshtml +46 -0
- package/stacks/dotnet-core/overlays/mvc/Views/Products/_Form.cshtml +19 -0
- package/stacks/dotnet-core/overlays/mvc-auth/Controllers/AccountController.cs +98 -0
- package/stacks/dotnet-core/overlays/mvc-auth/Models/AppUser.cs +48 -0
- package/stacks/dotnet-core/overlays/mvc-auth/Views/Account/Login.cshtml +35 -0
- package/stacks/dotnet-core/overlays/mvc-auth/Views/Account/Register.cshtml +41 -0
- package/stacks/dotnet-core/overlays/mvc-auth/Views/Shared/_AuthNav.cshtml +22 -0
- package/stacks/dotnet-core/snippets/packages-auth.xml +4 -0
- package/stacks/dotnet-core/snippets/packages-common.xml +5 -0
- package/stacks/dotnet-core/snippets/packages-ef.xml +4 -0
- package/stacks/dotnet-core/snippets/packages-mssql.xml +4 -0
- package/stacks/dotnet-core/snippets/packages-mysql.xml +4 -0
- package/stacks/dotnet-core/snippets/packages-swagger.xml +4 -0
- package/stacks/dotnet-core/stack.json +426 -0
- package/stacks/laravel/overlays/auth/app/Http/Controllers/Api/AuthController.php +67 -0
- package/stacks/laravel/overlays/common/app/Http/Controllers/BoilerCraftController.php +14 -0
- package/stacks/laravel/overlays/common/resources/views/boilercraft.blade.php +36 -0
- package/stacks/laravel/overlays/inertia-common/resources/views/app.blade.php +15 -0
- package/stacks/laravel/overlays/inertia-react/resources/js/Pages/Welcome.jsx +18 -0
- package/stacks/laravel/overlays/inertia-react/resources/js/app.jsx +13 -0
- package/stacks/laravel/overlays/inertia-vue/resources/js/Pages/Welcome.vue +23 -0
- package/stacks/laravel/overlays/inertia-vue/resources/js/app.js +13 -0
- package/stacks/laravel/snippets/api-routes.php +9 -0
- package/stacks/laravel/snippets/web-routes-inertia.php +7 -0
- package/stacks/laravel/snippets/web-routes.php +4 -0
- package/stacks/laravel/stack.json +477 -0
- package/stacks/nextjs/overlays/auth/src/lib/auth.js +36 -0
- package/stacks/nextjs/overlays/auth-app/src/app/api/auth/login/route.js +11 -0
- package/stacks/nextjs/overlays/auth-app/src/app/api/auth/register/route.js +14 -0
- package/stacks/nextjs/overlays/auth-pages/src/pages/api/auth/login.js +14 -0
- package/stacks/nextjs/overlays/auth-pages/src/pages/api/auth/register.js +17 -0
- package/stacks/nextjs/overlays/common/.env.example +3 -0
- package/stacks/nextjs/overlays/common/.env.local +3 -0
- package/stacks/nextjs/overlays/db/mongodb/src/lib/db.js +12 -0
- package/stacks/nextjs/overlays/db/mssql/src/lib/db.js +17 -0
- package/stacks/nextjs/overlays/db/mysql/src/lib/db.js +13 -0
- package/stacks/nextjs/overlays/router-app/src/app/api/health/route.js +10 -0
- package/stacks/nextjs/overlays/router-app/src/app/layout.js +16 -0
- package/stacks/nextjs/overlays/router-app/src/app/page.js +19 -0
- package/stacks/nextjs/overlays/router-pages/src/pages/_app.js +7 -0
- package/stacks/nextjs/overlays/router-pages/src/pages/_document.js +13 -0
- package/stacks/nextjs/overlays/router-pages/src/pages/api/health.js +8 -0
- package/stacks/nextjs/overlays/router-pages/src/pages/index.js +27 -0
- package/stacks/nextjs/stack.json +257 -0
- package/stacks/node-express/overlays/auth/src/controllers/authController.js +53 -0
- package/stacks/node-express/overlays/auth/src/middlewares/auth.js +36 -0
- package/stacks/node-express/overlays/auth/src/routes/authRoutes.js +16 -0
- package/stacks/node-express/overlays/common/.env.example +5 -0
- package/stacks/node-express/overlays/common/public/index.html +31 -0
- package/stacks/node-express/overlays/common/src/server.js +32 -0
- package/stacks/node-express/overlays/db/mongodb/src/db.js +13 -0
- package/stacks/node-express/overlays/db/mssql/src/db.js +22 -0
- package/stacks/node-express/overlays/db/mysql/src/db.js +22 -0
- package/stacks/node-express/stack.json +165 -0
- package/templates/dotnet-bootstrap-mssql/Controllers/AuthController.cs +74 -0
- package/templates/dotnet-bootstrap-mssql/Controllers/ProductsController.cs +33 -0
- package/templates/dotnet-bootstrap-mssql/Data/ApplicationDbContext.cs +24 -0
- package/templates/dotnet-bootstrap-mssql/Models/Product.cs +10 -0
- package/templates/dotnet-core/Controllers/AuthController.cs +74 -0
- package/templates/laravel-full/app/Http/Controllers/AuthController.php +79 -0
- package/templates/laravel-full/app/Http/Controllers/HomeController.php +22 -0
- package/templates/laravel-full/app/Models/User.php +49 -0
- package/templates/laravel-full/artisan +22 -0
- package/templates/laravel-full/bootstrap/app.php +21 -0
- package/templates/laravel-full/config/database.php +54 -0
- package/templates/laravel-full/database/migrations/2024_01_01_000001_create_users_table.php +27 -0
- package/templates/laravel-full/public/index.php +17 -0
- package/templates/laravel-full/resources/css/app.css +3 -0
- package/templates/laravel-full/resources/js/Pages/Home.vue +76 -0
- package/templates/laravel-full/resources/js/app.js +21 -0
- package/templates/laravel-full/resources/js/bootstrap.js +3 -0
- package/templates/laravel-full/resources/views/app.blade.php +15 -0
- package/templates/laravel-full/routes/api.php +8 -0
- package/templates/laravel-full/routes/console.php +7 -0
- package/templates/laravel-full/routes/web.php +24 -0
- package/templates/laravel-full/tailwind.config.js +12 -0
- package/templates/laravel-full/vite.config.js +20 -0
- package/templates/laravel-vue/app/Http/Controllers/Auth/AuthenticatedSessionController.php +43 -0
- package/templates/laravel-vue-mysql/app/Http/Controllers/HomeController.php +25 -0
- package/templates/laravel-vue-mysql/resources/js/Pages/Home.vue +70 -0
- package/templates/nextjs/src/app/api/auth/login/route.js +28 -0
- package/templates/nextjs-mongodb/src/app/api/health/route.js +17 -0
- package/templates/nextjs-mongodb/src/lib/mongodb.js +18 -0
- package/templates/nextjs-mssql/src/app/api/health/route.js +24 -0
- package/templates/nextjs-mssql/src/lib/mssql.js +38 -0
- package/templates/node-express/src/controllers/authController.js +53 -0
- package/templates/node-express/src/middlewares/auth.js +36 -0
- package/templates/node-express/src/routes/authRoutes.js +16 -0
- package/templates/node-mongodb/src/controllers/userController.js +30 -0
- package/templates/node-mongodb/src/middlewares/errorHandler.js +8 -0
- package/templates/node-mongodb/src/models/User.js +23 -0
- package/templates/node-mongodb/src/routes/api.js +9 -0
- package/templates/raw-php-mysql/app/Controllers/AuthController.php +73 -0
- package/templates/raw-php-mysql/app/Controllers/HomeController.php +65 -0
- package/templates/raw-php-mysql/app/Models/User.php +60 -0
- package/templates/raw-php-mysql/app/Views/404.php +15 -0
- package/templates/raw-php-mysql/app/Views/auth/login.php +66 -0
- package/templates/raw-php-mysql/app/Views/auth/register.php +71 -0
- package/templates/raw-php-mysql/app/Views/dashboard.php +50 -0
- package/templates/raw-php-mysql/app/Views/home.php +83 -0
- package/templates/raw-php-mysql/config/Auth.php +62 -0
- package/templates/raw-php-mysql/config/Database.php +100 -0
- package/templates/raw-php-mysql/config/Env.php +30 -0
- package/templates/raw-php-mysql/config/Middleware.php +53 -0
- package/templates/raw-php-mysql/config/QueryBuilder.php +109 -0
- package/templates/raw-php-mysql/config/Router.php +33 -0
- package/templates/raw-php-mysql/public/index.php +57 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
namespace App\Config;
|
|
3
|
+
|
|
4
|
+
class Env {
|
|
5
|
+
public static function load(string $path): void {
|
|
6
|
+
if (!file_exists($path)) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
$lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
|
11
|
+
foreach ($lines as $line) {
|
|
12
|
+
$line = trim($line);
|
|
13
|
+
if (empty($line) || str_starts_with($line, '#')) {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (str_contains($line, '=')) {
|
|
18
|
+
[$key, $value] = explode('=', $line, 2);
|
|
19
|
+
$key = trim($key);
|
|
20
|
+
$value = trim($value, " \t\n\r\0\x0B\"'");
|
|
21
|
+
|
|
22
|
+
if (!array_key_exists($key, $_SERVER) && !array_key_exists($key, $_ENV)) {
|
|
23
|
+
putenv("{$key}={$value}");
|
|
24
|
+
$_ENV[$key] = $value;
|
|
25
|
+
$_SERVER[$key] = $value;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
namespace App\Config;
|
|
3
|
+
|
|
4
|
+
class Middleware {
|
|
5
|
+
/**
|
|
6
|
+
* Authentication Guard (Blocks guest users)
|
|
7
|
+
*/
|
|
8
|
+
public static function auth(): void {
|
|
9
|
+
if (!Auth::check()) {
|
|
10
|
+
if (self::isAjax()) {
|
|
11
|
+
http_response_code(401);
|
|
12
|
+
header('Content-Type: application/json');
|
|
13
|
+
echo json_encode(['success' => false, 'error' => 'Unauthorized. Please login.']);
|
|
14
|
+
exit;
|
|
15
|
+
}
|
|
16
|
+
header('Location: /login');
|
|
17
|
+
exit;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Guest Guard (Redirects logged-in users away from login/register)
|
|
23
|
+
*/
|
|
24
|
+
public static function guest(): void {
|
|
25
|
+
if (Auth::check()) {
|
|
26
|
+
header('Location: /dashboard');
|
|
27
|
+
exit;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Role-based Authorization Guard (e.g. 'admin', 'moderator')
|
|
33
|
+
*/
|
|
34
|
+
public static function role(string|array $roles): void {
|
|
35
|
+
self::auth(); // Must be logged in first
|
|
36
|
+
|
|
37
|
+
if (!Auth::hasRole($roles)) {
|
|
38
|
+
if (self::isAjax()) {
|
|
39
|
+
http_response_code(403);
|
|
40
|
+
header('Content-Type: application/json');
|
|
41
|
+
echo json_encode(['success' => false, 'error' => 'Forbidden. You lack sufficient permissions.']);
|
|
42
|
+
exit;
|
|
43
|
+
}
|
|
44
|
+
http_response_code(403);
|
|
45
|
+
die("<h1>403 Forbidden</h1><p>You do not have permission to access this area.</p>");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private static function isAjax(): bool {
|
|
50
|
+
return (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')
|
|
51
|
+
|| (isset($_SERVER['HTTP_ACCEPT']) && str_contains($_SERVER['HTTP_ACCEPT'], 'application/json'));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
namespace App\Config;
|
|
3
|
+
|
|
4
|
+
class QueryBuilder {
|
|
5
|
+
protected string $table = '';
|
|
6
|
+
protected array $fields = ['*'];
|
|
7
|
+
protected array $wheres = [];
|
|
8
|
+
protected array $bindings = [];
|
|
9
|
+
protected string $orderBy = '';
|
|
10
|
+
protected ?int $limitNum = null;
|
|
11
|
+
|
|
12
|
+
public static function table(string $table): self {
|
|
13
|
+
$qb = new self();
|
|
14
|
+
$qb->table = $table;
|
|
15
|
+
return $qb;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public function select(array|string $fields = ['*']): self {
|
|
19
|
+
$this->fields = is_array($fields) ? $fields : func_get_args();
|
|
20
|
+
return $this;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
public function where(string $column, mixed $operatorOrValue, mixed $value = null): self {
|
|
24
|
+
if ($value === null) {
|
|
25
|
+
$value = $operatorOrValue;
|
|
26
|
+
$operator = '=';
|
|
27
|
+
} else {
|
|
28
|
+
$operator = $operatorOrValue;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
$paramKey = ":p_" . count($this->bindings);
|
|
32
|
+
$this->wheres[] = "{$column} {$operator} {$paramKey}";
|
|
33
|
+
$this->bindings[$paramKey] = $value;
|
|
34
|
+
return $this;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public function orderBy(string $column, string $direction = 'ASC'): self {
|
|
38
|
+
$this->orderBy = "ORDER BY {$column} " . strtoupper($direction);
|
|
39
|
+
return $this;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
public function limit(int $limit): self {
|
|
43
|
+
$this->limitNum = $limit;
|
|
44
|
+
return $this;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public function get(): array {
|
|
48
|
+
$sql = "SELECT " . implode(', ', $this->fields) . " FROM {$this->table}";
|
|
49
|
+
if (!empty($this->wheres)) {
|
|
50
|
+
$sql .= " WHERE " . implode(' AND ', $this->wheres);
|
|
51
|
+
}
|
|
52
|
+
if (!empty($this->orderBy)) {
|
|
53
|
+
$sql .= " {$this->orderBy}";
|
|
54
|
+
}
|
|
55
|
+
if ($this->limitNum !== null) {
|
|
56
|
+
$sql .= " LIMIT {$this->limitNum}";
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return Database::query($sql, $this->bindings);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public function first(): ?array {
|
|
63
|
+
$this->limit(1);
|
|
64
|
+
$results = $this->get();
|
|
65
|
+
return $results[0] ?? null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public function insert(array $data): bool {
|
|
69
|
+
$columns = implode(', ', array_keys($data));
|
|
70
|
+
$placeholders = [];
|
|
71
|
+
$params = [];
|
|
72
|
+
|
|
73
|
+
foreach ($data as $k => $v) {
|
|
74
|
+
$param = ":ins_{$k}";
|
|
75
|
+
$placeholders[] = $param;
|
|
76
|
+
$params[$param] = $v;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
$sql = "INSERT INTO {$this->table} ({$columns}) VALUES (" . implode(', ', $placeholders) . ")";
|
|
80
|
+
return Database::execute($sql, $params);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public function update(array $data): bool {
|
|
84
|
+
$sets = [];
|
|
85
|
+
$params = [];
|
|
86
|
+
|
|
87
|
+
foreach ($data as $k => $v) {
|
|
88
|
+
$param = ":upd_{$k}";
|
|
89
|
+
$sets[] = "{$k} = {$param}";
|
|
90
|
+
$params[$param] = $v;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
$sql = "UPDATE {$this->table} SET " . implode(', ', $sets);
|
|
94
|
+
if (!empty($this->wheres)) {
|
|
95
|
+
$sql .= " WHERE " . implode(' AND ', $this->wheres);
|
|
96
|
+
$params = array_merge($params, $this->bindings);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return Database::execute($sql, $params);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public function delete(): bool {
|
|
103
|
+
$sql = "DELETE FROM {$this->table}";
|
|
104
|
+
if (!empty($this->wheres)) {
|
|
105
|
+
$sql .= " WHERE " . implode(' AND ', $this->wheres);
|
|
106
|
+
}
|
|
107
|
+
return Database::execute($sql, $this->bindings);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
namespace App\Config;
|
|
3
|
+
|
|
4
|
+
class Router {
|
|
5
|
+
private array $routes = [];
|
|
6
|
+
|
|
7
|
+
public function get(string $path, callable|array $handler): void {
|
|
8
|
+
$this->routes['GET'][$path] = $handler;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public function post(string $path, callable|array $handler): void {
|
|
12
|
+
$this->routes['POST'][$path] = $handler;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public function dispatch(): void {
|
|
16
|
+
$method = $_SERVER['REQUEST_METHOD'];
|
|
17
|
+
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
|
18
|
+
|
|
19
|
+
if (isset($this->routes[$method][$uri])) {
|
|
20
|
+
$handler = $this->routes[$method][$uri];
|
|
21
|
+
if (is_callable($handler)) {
|
|
22
|
+
call_user_func($handler);
|
|
23
|
+
} elseif (is_array($handler)) {
|
|
24
|
+
[$class, $action] = $handler;
|
|
25
|
+
$controller = new $class();
|
|
26
|
+
$controller->$action();
|
|
27
|
+
}
|
|
28
|
+
} else {
|
|
29
|
+
http_response_code(404);
|
|
30
|
+
require __DIR__ . '/../app/Views/404.php';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
// Autoloader
|
|
3
|
+
spl_autoload_register(function ($class) {
|
|
4
|
+
$prefix = 'App\\';
|
|
5
|
+
$base_dir = __DIR__ . '/../app/';
|
|
6
|
+
|
|
7
|
+
$len = strlen($prefix);
|
|
8
|
+
if (strncmp($prefix, $class, $len) !== 0) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
$relative_class = substr($class, $len);
|
|
13
|
+
if (strpos($relative_class, 'Config\\') === 0) {
|
|
14
|
+
$file = __DIR__ . '/../' . str_replace('\\', '/', $relative_class) . '.php';
|
|
15
|
+
} else {
|
|
16
|
+
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (file_exists($file)) {
|
|
20
|
+
require $file;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
use App\Config\Env;
|
|
25
|
+
use App\Config\Router;
|
|
26
|
+
use App\Config\Middleware;
|
|
27
|
+
use App\Controllers\HomeController;
|
|
28
|
+
use App\Controllers\AuthController;
|
|
29
|
+
|
|
30
|
+
Env::load(__DIR__ . '/../.env');
|
|
31
|
+
|
|
32
|
+
$router = new Router();
|
|
33
|
+
|
|
34
|
+
// Public Routes
|
|
35
|
+
$router->get('/', [HomeController::class, 'index']);
|
|
36
|
+
$router->get('/login', [AuthController::class, 'showLogin']);
|
|
37
|
+
$router->get('/register', [AuthController::class, 'showRegister']);
|
|
38
|
+
$router->get('/logout', [AuthController::class, 'logout']);
|
|
39
|
+
|
|
40
|
+
// AJAX Auth Endpoints
|
|
41
|
+
$router->post('/api/login', [AuthController::class, 'login']);
|
|
42
|
+
$router->post('/api/register', [AuthController::class, 'register']);
|
|
43
|
+
$router->get('/api/health', [HomeController::class, 'apiHealth']);
|
|
44
|
+
|
|
45
|
+
// Protected Routes (Guarded by Middleware)
|
|
46
|
+
$router->get('/dashboard', function() {
|
|
47
|
+
Middleware::auth(); // Protect route: must be logged in
|
|
48
|
+
require __DIR__ . '/../app/Views/dashboard.php';
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
$router->get('/admin', function() {
|
|
52
|
+
Middleware::role('admin'); // Protect route: only admin role allowed
|
|
53
|
+
require __DIR__ . '/../app/Views/dashboard.php';
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Dispatch request
|
|
57
|
+
$router->dispatch();
|