adds roles
This commit is contained in:
86
app/Console/Commands/DevMenuCommand.php
Normal file
86
app/Console/Commands/DevMenuCommand.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
final class DevMenuCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'menu';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Developer tools menu';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
if (! in_array(app()->environment(), ['local', 'testing'])) {
|
||||
$this->error('This command can only be run in local or testing environments.');
|
||||
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
$this->info('');
|
||||
$this->info(' ╔═══════════════════════════════╗');
|
||||
$this->info(' ║ Go No Go — Dev Tools ║');
|
||||
$this->info(' ╚═══════════════════════════════╝');
|
||||
$this->info('');
|
||||
|
||||
$choice = $this->choice('Select an action', [
|
||||
0 => 'Exit',
|
||||
1 => 'Fresh migrate, seed & build',
|
||||
]);
|
||||
|
||||
if ($choice === 'Exit') {
|
||||
$this->info('Bye!');
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
if ($choice === 'Fresh migrate, seed & build') {
|
||||
$this->freshMigrateAndBuild();
|
||||
}
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs migrate:fresh with seeding, then runs npm build.
|
||||
*
|
||||
* Displays output from both processes and confirms success or failure.
|
||||
*/
|
||||
private function freshMigrateAndBuild(): void
|
||||
{
|
||||
$this->info('');
|
||||
$this->comment('Running migrate:fresh --seed...');
|
||||
$this->call('migrate:fresh', ['--seed' => true]);
|
||||
|
||||
$this->info('');
|
||||
$this->comment('Running npm run build...');
|
||||
|
||||
$process = new Process(['npm', 'run', 'build']);
|
||||
$process->setWorkingDirectory(base_path());
|
||||
$process->setTimeout(120);
|
||||
$process->run(function (string $type, string $output): void {
|
||||
$this->output->write($output);
|
||||
});
|
||||
|
||||
if ($process->isSuccessful()) {
|
||||
$this->info('');
|
||||
$this->info('Environment rebuilt successfully.');
|
||||
} else {
|
||||
$this->error('Build failed.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Role;
|
||||
use App\Models\User;
|
||||
use App\Services\ActivityLogger;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
@@ -29,17 +30,25 @@ public function callback(): RedirectResponse
|
||||
{
|
||||
$azureUser = Socialite::driver('azure')->user();
|
||||
|
||||
$user = User::query()->firstOrCreate(
|
||||
$user = User::query()->updateOrCreate(
|
||||
['email' => $azureUser->getEmail()],
|
||||
[
|
||||
'name' => $azureUser->getName(),
|
||||
'password' => null,
|
||||
'azure_id' => $azureUser->getId(),
|
||||
'photo' => $azureUser->getAvatar(),
|
||||
'job_title' => Arr::get($azureUser->user, 'jobTitle'),
|
||||
'department' => Arr::get($azureUser->user, 'department'),
|
||||
'phone' => Arr::get($azureUser->user, 'mobilePhone', Arr::get($azureUser->user, 'businessPhones.0')),
|
||||
]
|
||||
);
|
||||
|
||||
if ($user->role_id === null) {
|
||||
$user->update(['role_id' => Role::where('name', 'user')->first()->id]);
|
||||
}
|
||||
|
||||
auth()->login($user);
|
||||
|
||||
ActivityLogger::log('login', $user->id, metadata: ['email' => $user->email, 'firm_name' => Arr::get($azureUser, 'companyName')]);
|
||||
ActivityLogger::log('login', $user->id, metadata: ['email' => $user->email, 'firm_name' => Arr::get($azureUser->user, 'companyName')]);
|
||||
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
@@ -68,10 +68,6 @@ public function update(UpdateSessionRequest $request, Session $session): Redirec
|
||||
{
|
||||
$validated = $request->validated();
|
||||
|
||||
if (Arr::has($validated, 'basic_info')) {
|
||||
$session->update(['basic_info' => Arr::get($validated, 'basic_info')]);
|
||||
}
|
||||
|
||||
if (Arr::has($validated, 'answers')) {
|
||||
$this->saveAnswers($session, Arr::get($validated, 'answers'));
|
||||
}
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Inertia\Middleware;
|
||||
use Laravel\Nova\Nova;
|
||||
|
||||
final class HandleInertiaRequests extends Middleware
|
||||
{
|
||||
@@ -32,6 +34,7 @@ public function share(Request $request): array
|
||||
...parent::share($request),
|
||||
'auth' => [
|
||||
'user' => $this->getAuthenticatedUser(),
|
||||
'logo_href' => $this->getLogoHref(),
|
||||
],
|
||||
'flash' => [
|
||||
'success' => fn () => Arr::get($request->session()->all(), 'success'),
|
||||
@@ -57,4 +60,18 @@ private function getAuthenticatedUser(): ?array
|
||||
'email' => $user->email,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine logo href based on user Nova access.
|
||||
*/
|
||||
private function getLogoHref(): string
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
if ($user !== null && Gate::allows('viewNova', $user)) {
|
||||
return Nova::path();
|
||||
}
|
||||
|
||||
return '/';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,11 +22,6 @@ public function authorize(): bool
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'basic_info' => ['sometimes', 'required', 'array'],
|
||||
'basic_info.client_name' => ['required_with:basic_info', 'string', 'max:255'],
|
||||
'basic_info.client_contact' => ['required_with:basic_info', 'string', 'max:255'],
|
||||
'basic_info.lead_firm_name' => ['required_with:basic_info', 'string', 'max:255'],
|
||||
'basic_info.lead_firm_contact' => ['required_with:basic_info', 'string', 'max:255'],
|
||||
'answers' => ['sometimes', 'array'],
|
||||
'answers.*.value' => ['nullable', 'string', 'in:yes,no,not_applicable'],
|
||||
'answers.*.text_value' => ['nullable', 'string', 'max:10000'],
|
||||
@@ -41,20 +36,6 @@ public function rules(): array
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'basic_info.required' => 'Basic information is required.',
|
||||
'basic_info.array' => 'Basic information must be a valid data structure.',
|
||||
'basic_info.client_name.required_with' => 'The client name is required.',
|
||||
'basic_info.client_name.string' => 'The client name must be text.',
|
||||
'basic_info.client_name.max' => 'The client name cannot exceed 255 characters.',
|
||||
'basic_info.client_contact.required_with' => 'The client contact is required.',
|
||||
'basic_info.client_contact.string' => 'The client contact must be text.',
|
||||
'basic_info.client_contact.max' => 'The client contact cannot exceed 255 characters.',
|
||||
'basic_info.lead_firm_name.required_with' => 'The lead firm name is required.',
|
||||
'basic_info.lead_firm_name.string' => 'The lead firm name must be text.',
|
||||
'basic_info.lead_firm_name.max' => 'The lead firm name cannot exceed 255 characters.',
|
||||
'basic_info.lead_firm_contact.required_with' => 'The lead firm contact is required.',
|
||||
'basic_info.lead_firm_contact.string' => 'The lead firm contact must be text.',
|
||||
'basic_info.lead_firm_contact.max' => 'The lead firm contact cannot exceed 255 characters.',
|
||||
'answers.array' => 'Answers must be a valid data structure.',
|
||||
'answers.*.value.in' => 'Answer value must be yes, no, or not_applicable.',
|
||||
'answers.*.text_value.string' => 'Answer text must be text.',
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
final class Question extends Model
|
||||
{
|
||||
@@ -48,4 +49,12 @@ public function questionGroup(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(QuestionGroup::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all answers for this question.
|
||||
*/
|
||||
public function answers(): HasMany
|
||||
{
|
||||
return $this->hasMany(Answer::class);
|
||||
}
|
||||
}
|
||||
|
||||
23
app/Models/Role.php
Normal file
23
app/Models/Role.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
final class Role extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'name',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get all users with this role.
|
||||
*/
|
||||
public function users(): HasMany
|
||||
{
|
||||
return $this->hasMany(User::class);
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,6 @@ final class Session extends Model
|
||||
'status',
|
||||
'score',
|
||||
'result',
|
||||
'basic_info',
|
||||
'additional_comments',
|
||||
'completed_at',
|
||||
];
|
||||
@@ -40,7 +39,6 @@ protected function casts(): array
|
||||
'category_id' => 'integer',
|
||||
'screening_id' => 'integer',
|
||||
'score' => 'integer',
|
||||
'basic_info' => 'array',
|
||||
'completed_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
@@ -23,6 +24,12 @@ final class User extends Authenticatable
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
'azure_id',
|
||||
'photo',
|
||||
'job_title',
|
||||
'department',
|
||||
'phone',
|
||||
'role_id',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -33,6 +40,7 @@ final class User extends Authenticatable
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
'azure_id',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -45,9 +53,18 @@ protected function casts(): array
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
'role_id' => 'integer',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the role assigned to this user.
|
||||
*/
|
||||
public function role(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Role::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all sessions for this user.
|
||||
*/
|
||||
|
||||
@@ -49,6 +49,22 @@ final class AnswerResource extends Resource
|
||||
*/
|
||||
public static $with = ['session', 'question'];
|
||||
|
||||
/**
|
||||
* Get the displayable label of the resource.
|
||||
*/
|
||||
public static function label(): string
|
||||
{
|
||||
return 'Answers';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the displayable singular label of the resource.
|
||||
*/
|
||||
public static function singularLabel(): string
|
||||
{
|
||||
return 'Answer';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fields displayed by the resource.
|
||||
*
|
||||
@@ -76,6 +92,7 @@ public function fields(NovaRequest $request): array
|
||||
->rules('nullable', 'max:255'),
|
||||
|
||||
Textarea::make('Text Value')
|
||||
->alwaysShow()
|
||||
->rules('nullable'),
|
||||
|
||||
DateTime::make('Created At')
|
||||
|
||||
@@ -42,6 +42,22 @@ final class CategoryResource extends Resource
|
||||
*/
|
||||
public static $displayInNavigation = false;
|
||||
|
||||
/**
|
||||
* Get the displayable label of the resource.
|
||||
*/
|
||||
public static function label(): string
|
||||
{
|
||||
return 'Categories';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the displayable singular label of the resource.
|
||||
*/
|
||||
public static function singularLabel(): string
|
||||
{
|
||||
return 'Category';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fields displayed by the resource.
|
||||
*
|
||||
|
||||
@@ -56,6 +56,22 @@ final class LogResource extends Resource
|
||||
*/
|
||||
public static $with = ['user', 'session', 'category'];
|
||||
|
||||
/**
|
||||
* Get the displayable label of the resource.
|
||||
*/
|
||||
public static function label(): string
|
||||
{
|
||||
return 'Logs';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the displayable singular label of the resource.
|
||||
*/
|
||||
public static function singularLabel(): string
|
||||
{
|
||||
return 'Log';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fields displayed by the resource.
|
||||
*
|
||||
|
||||
@@ -44,6 +44,22 @@ final class QuestionGroupResource extends Resource
|
||||
*/
|
||||
public static $displayInNavigation = false;
|
||||
|
||||
/**
|
||||
* Get the displayable label of the resource.
|
||||
*/
|
||||
public static function label(): string
|
||||
{
|
||||
return 'Question Groups';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the displayable singular label of the resource.
|
||||
*/
|
||||
public static function singularLabel(): string
|
||||
{
|
||||
return 'Question Group';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fields displayed by the resource.
|
||||
*
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
use Laravel\Nova\Fields\BelongsTo;
|
||||
use Laravel\Nova\Fields\Boolean;
|
||||
use Laravel\Nova\Fields\DateTime;
|
||||
use Laravel\Nova\Fields\HasMany;
|
||||
use Laravel\Nova\Fields\ID;
|
||||
use Laravel\Nova\Fields\Number;
|
||||
use Laravel\Nova\Fields\Text;
|
||||
@@ -51,6 +52,22 @@ final class QuestionResource extends Resource
|
||||
*/
|
||||
public static $group = 'Questionnaire';
|
||||
|
||||
/**
|
||||
* Get the displayable label of the resource.
|
||||
*/
|
||||
public static function label(): string
|
||||
{
|
||||
return 'Questions';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the displayable singular label of the resource.
|
||||
*/
|
||||
public static function singularLabel(): string
|
||||
{
|
||||
return 'Question';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fields displayed by the resource.
|
||||
*
|
||||
@@ -111,6 +128,8 @@ public function fields(NovaRequest $request): array
|
||||
->exceptOnForms()
|
||||
->sortable()
|
||||
->filterable(),
|
||||
|
||||
HasMany::make('Answers', 'answers', AnswerResource::class),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
75
app/Nova/RoleResource.php
Normal file
75
app/Nova/RoleResource.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Nova;
|
||||
|
||||
use Laravel\Nova\Fields\DateTime;
|
||||
use Laravel\Nova\Fields\HasMany;
|
||||
use Laravel\Nova\Fields\ID;
|
||||
use Laravel\Nova\Fields\Text;
|
||||
use Laravel\Nova\Http\Requests\NovaRequest;
|
||||
|
||||
final class RoleResource extends Resource
|
||||
{
|
||||
public static string $model = \App\Models\Role::class;
|
||||
|
||||
public static $title = 'name';
|
||||
|
||||
public static $search = ['id', 'name'];
|
||||
|
||||
public static $displayInNavigation = false;
|
||||
|
||||
public static function label(): string
|
||||
{
|
||||
return 'Roles';
|
||||
}
|
||||
|
||||
public static function singularLabel(): string
|
||||
{
|
||||
return 'Role';
|
||||
}
|
||||
|
||||
public function fields(NovaRequest $request): array
|
||||
{
|
||||
return [
|
||||
ID::make()->sortable(),
|
||||
|
||||
Text::make('Name')
|
||||
->sortable()
|
||||
->filterable()
|
||||
->copyable()
|
||||
->rules('required', 'max:255'),
|
||||
|
||||
DateTime::make('Created At')
|
||||
->exceptOnForms()
|
||||
->sortable(),
|
||||
|
||||
DateTime::make('Updated At')
|
||||
->exceptOnForms()
|
||||
->sortable(),
|
||||
|
||||
HasMany::make('Users', 'users', User::class),
|
||||
];
|
||||
}
|
||||
|
||||
public function cards(NovaRequest $request): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function filters(NovaRequest $request): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function lenses(NovaRequest $request): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function actions(NovaRequest $request): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -57,6 +57,22 @@ final class ScreeningResource extends Resource
|
||||
*/
|
||||
public static $with = ['user'];
|
||||
|
||||
/**
|
||||
* Get the displayable label of the resource.
|
||||
*/
|
||||
public static function label(): string
|
||||
{
|
||||
return 'Screenings';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the displayable singular label of the resource.
|
||||
*/
|
||||
public static function singularLabel(): string
|
||||
{
|
||||
return 'Screening';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fields displayed by the resource.
|
||||
*
|
||||
|
||||
@@ -5,12 +5,11 @@
|
||||
namespace App\Nova;
|
||||
|
||||
use Laravel\Nova\Fields\BelongsTo;
|
||||
use Laravel\Nova\Fields\Code;
|
||||
use Laravel\Nova\Fields\DateTime;
|
||||
use Laravel\Nova\Fields\HasMany;
|
||||
use Laravel\Nova\Fields\ID;
|
||||
use Laravel\Nova\Fields\Number;
|
||||
use Laravel\Nova\Fields\Text;
|
||||
use Laravel\Nova\Fields\Select;
|
||||
use Laravel\Nova\Fields\Textarea;
|
||||
use Laravel\Nova\Http\Requests\NovaRequest;
|
||||
use Maatwebsite\LaravelNovaExcel\Actions\DownloadExcel;
|
||||
@@ -59,6 +58,22 @@ final class SessionResource extends Resource
|
||||
*/
|
||||
public static $with = ['user', 'category', 'screening'];
|
||||
|
||||
/**
|
||||
* Get the displayable label of the resource.
|
||||
*/
|
||||
public static function label(): string
|
||||
{
|
||||
return 'Sessions';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the displayable singular label of the resource.
|
||||
*/
|
||||
public static function singularLabel(): string
|
||||
{
|
||||
return 'Session';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fields displayed by the resource.
|
||||
*
|
||||
@@ -85,11 +100,16 @@ public function fields(NovaRequest $request): array
|
||||
->filterable()
|
||||
->rules('nullable'),
|
||||
|
||||
Text::make('Status')
|
||||
Select::make('Status')
|
||||
->options([
|
||||
'in_progress' => 'In Progress',
|
||||
'completed' => 'Completed',
|
||||
'abandoned' => 'Abandoned',
|
||||
])
|
||||
->displayUsingLabels()
|
||||
->sortable()
|
||||
->filterable()
|
||||
->copyable()
|
||||
->rules('required', 'max:255'),
|
||||
->readonly(),
|
||||
|
||||
Number::make('Score')
|
||||
->sortable()
|
||||
@@ -97,15 +117,16 @@ public function fields(NovaRequest $request): array
|
||||
->copyable()
|
||||
->rules('nullable', 'integer'),
|
||||
|
||||
Text::make('Result')
|
||||
Select::make('Result')
|
||||
->options([
|
||||
'go' => 'Go',
|
||||
'no_go' => 'No Go',
|
||||
'consult_leadership' => 'Consult Leadership',
|
||||
])
|
||||
->displayUsingLabels()
|
||||
->sortable()
|
||||
->filterable()
|
||||
->copyable()
|
||||
->rules('nullable', 'max:255'),
|
||||
|
||||
Code::make('Basic Info', 'basic_info')
|
||||
->json()
|
||||
->rules('nullable'),
|
||||
->readonly(),
|
||||
|
||||
Textarea::make('Additional Comments')
|
||||
->rules('nullable'),
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Laravel\Nova\Auth\PasswordValidationRules;
|
||||
use Laravel\Nova\Fields\BelongsTo;
|
||||
use Laravel\Nova\Fields\ID;
|
||||
use Laravel\Nova\Fields\Password;
|
||||
use Laravel\Nova\Fields\Text;
|
||||
@@ -35,7 +36,7 @@ final class User extends Resource
|
||||
* @var array
|
||||
*/
|
||||
public static $search = [
|
||||
'id', 'name', 'email',
|
||||
'id', 'name', 'email', 'department', 'job_title',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -48,6 +49,10 @@ public function fields(NovaRequest $request): array
|
||||
return [
|
||||
ID::make()->sortable(),
|
||||
|
||||
BelongsTo::make('Role', 'role', RoleResource::class)
|
||||
->sortable()
|
||||
->filterable(),
|
||||
|
||||
Text::make('Name')
|
||||
->sortable()
|
||||
->rules('required', 'max:255'),
|
||||
@@ -58,6 +63,31 @@ public function fields(NovaRequest $request): array
|
||||
->creationRules('unique:users,email')
|
||||
->updateRules('unique:users,email,{{resourceId}}'),
|
||||
|
||||
Text::make('Azure ID', 'azure_id')
|
||||
->onlyOnDetail()
|
||||
->copyable(),
|
||||
|
||||
Text::make('Photo', 'photo')
|
||||
->onlyOnDetail()
|
||||
->copyable(),
|
||||
|
||||
Text::make('Job Title', 'job_title')
|
||||
->sortable()
|
||||
->filterable()
|
||||
->copyable()
|
||||
->readonly(),
|
||||
|
||||
Text::make('Department')
|
||||
->sortable()
|
||||
->filterable()
|
||||
->copyable()
|
||||
->readonly(),
|
||||
|
||||
Text::make('Phone')
|
||||
->sortable()
|
||||
->copyable()
|
||||
->readonly(),
|
||||
|
||||
Password::make('Password')
|
||||
->onlyOnForms()
|
||||
->creationRules($this->passwordRules())
|
||||
|
||||
@@ -3,8 +3,16 @@
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Nova\Dashboards\Main;
|
||||
use App\Nova\LogResource;
|
||||
use App\Nova\QuestionResource;
|
||||
use App\Nova\ScreeningResource;
|
||||
use App\Nova\SessionResource;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Laravel\Fortify\Features;
|
||||
use Laravel\Nova\Menu\MenuItem;
|
||||
use Laravel\Nova\Menu\MenuSection;
|
||||
use Laravel\Nova\Nova;
|
||||
use Laravel\Nova\NovaApplicationServiceProvider;
|
||||
|
||||
@@ -17,7 +25,25 @@ public function boot(): void
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
//
|
||||
Nova::mainMenu(function (Request $request) {
|
||||
return [
|
||||
MenuSection::dashboard(Main::class)->icon('home'),
|
||||
|
||||
MenuSection::make('Questionnaire', [
|
||||
MenuItem::resource(QuestionResource::class),
|
||||
MenuItem::resource(ScreeningResource::class),
|
||||
MenuItem::resource(SessionResource::class),
|
||||
])->icon('clipboard-document-list')->collapsible(),
|
||||
|
||||
MenuSection::make('Logs', [
|
||||
MenuItem::resource(LogResource::class),
|
||||
])->icon('chart-bar')->collapsible(),
|
||||
|
||||
MenuSection::make('Users', [
|
||||
MenuItem::resource(\App\Nova\User::class),
|
||||
])->icon('users')->collapsible(),
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user