diff --git a/app/Filament/Clusters/Loans/Resources/LoanOrderMobiles/LoanOrderMobileResource.php b/app/Filament/Clusters/Loans/Resources/LoanOrderMobiles/LoanOrderMobileResource.php new file mode 100644 index 0000000..6308c34 --- /dev/null +++ b/app/Filament/Clusters/Loans/Resources/LoanOrderMobiles/LoanOrderMobileResource.php @@ -0,0 +1,85 @@ + ListLoanOrderMobiles::route('/'), + 'create' => CreateLoanOrderMobile::route('/create'), + 'edit' => EditLoanOrderMobile::route('/{record}/edit'), + ]; + } + + public static function getRecordRouteBindingEloquentQuery(): Builder + { + return parent::getRecordRouteBindingEloquentQuery() + ->withoutGlobalScopes([ + SoftDeletingScope::class, + ]); + } +} diff --git a/app/Filament/Clusters/Loans/Resources/LoanOrderMobiles/Pages/CreateLoanOrderMobile.php b/app/Filament/Clusters/Loans/Resources/LoanOrderMobiles/Pages/CreateLoanOrderMobile.php new file mode 100644 index 0000000..b48f7a8 --- /dev/null +++ b/app/Filament/Clusters/Loans/Resources/LoanOrderMobiles/Pages/CreateLoanOrderMobile.php @@ -0,0 +1,11 @@ +columns(4) + ->components([ + Hidden::make('source')->default('mobile'), + Hidden::make('user_id')->default(Auth::id()), + + Section::make(__('New loan order')) + ->columnSpan(4) + ->columns(4) + ->components([ + Select::make('status') + ->label(__('Status')) + ->options(OrderStatusRepository::statusValues()) + ->default(OrderStatusRepository::defaultStatus()) + ->native(false) + ->required() + ->columnSpan(2), + + Select::make('satisfiable') + ->label(__('Loan history')) + ->options(LoanOrderRepository::satisfiableValues()) + ->native(false) + ->columnSpan(2), + + Select::make('loan_order_required_doc_id') + ->label(__('Required documents')) + ->relationship('requiredDocs', 'name') + ->searchable() + ->native(false) + ->preload() + ->live() + ->afterStateUpdated(function ($state, callable $set) { + if ($state) { + /** @var null|LoanOrderRequiredDocs */ + $requiredDoc = LoanOrderRequiredDocs::find($state); + + if ($requiredDoc) { + $set('notes', $requiredDoc->value); + } + } + }) + ->columnSpanFull(), + + RichEditor::make('notes') + ->label(__('Bellik')) + ->columnSpanFull(), + ]), + + Tabs::make('Loan Order') + ->tabs([ + Tab::make(__('Loan & Bank')) + ->schema([ + Fieldset::make(__('Loan type and amount')) + ->schema([ + Select::make('loan_type') + ->label(__('Loan type')) + ->relationship('loanType', 'name', fn (Builder $query) => $query->orderByTranslation('name')) + ->required(), + + TextInput::make('loan_amount') + ->label(__('Loan amount')) + ->numeric() + ->required() + ->minValue(1) + ->maxValue(40000) + ->suffix('TMT') + ->belowContent(__('Max is 40 000 TMT')), + ]), + + Fieldset::make(__('Location')) + ->schema([ + Select::make('region') + ->label(__('Region')) + ->options(RegionRepository::values()) + ->live() + ->afterStateUpdated(fn (callable $set) => $set('branch_id', null)) + ->required(), + + Select::make('branch_id') + ->label(__('Branch')) + ->relationship('branch', 'name', function ($query, callable $get) { + $query->orderByTranslation('name'); + + $region = $get('region'); + if ($region) { + $query->where('region', $region); + } + }) + ->required(), + ]), + ]), + Tab::make(__('Personal information')) + ->columns(8) + ->schema([ + TextInput::make('customer_name') + ->label(__('Name')) + ->columnSpan(2) + ->required() + ->maxLength(255) + ->autocomplete(Str::random(10)) + ->default(user()?->first_name), + + TextInput::make('customer_surname') + ->label(__('Surname')) + ->columnSpan(2) + ->required() + ->maxLength(255) + ->default(user()?->last_name), + + TextInput::make('customer_patronic_name') + ->label(__('Patronic name')) + ->columnSpan(2) + ->maxLength(255) + ->default(user()?->getOption('patronic_name')), + + DatePicker::make('born_at') + ->displayFormat('d.m.Y') + ->label(__('Birth date')) + ->native(false) + ->columnSpan(2) + ->required() + ->beforeOrEqual('today') + ->default(user()?->getOption('born_at')), + + FusedGroup::make([ + Select::make('passport_serie') + ->label(__('Passport serie')) + ->options(TurkmenPassportRepository::values()) + ->native(false) + ->required() + ->columnSpan(1) + ->default(user()?->getOption('passport_serie')), + + TextInput::make('passport_id') + ->label(__('Passport number')) + ->required() + ->columnSpan(1) + ->mask('999999') + ->default(user()?->getOption('passport_id')), + ]) + ->columnSpan(3) + ->label(__('Passport serie and number')) + ->columns(2), + + DatePicker::make('passport_given_at') + ->label(__('Passport given date')) + ->columnSpan(2) + ->displayFormat('d.m.Y') + ->native(false) + ->closeOnDateSelection() + ->beforeOrEqual('today') + ->required() + ->default(user()?->getOption('passport_given_at')), + + TextInput::make('born_place') + ->columnSpan(3) + ->label(__('Born place (passport)')) + ->maxLength(255) + ->required() + ->default(user()?->getOption('born_place')), + + TextInput::make('passport_given_by') + ->label(__('Passport given by')) + ->columnSpan(4) + ->maxLength(255) + ->required() + ->default(user()?->getOption('passport_given_by')), + + TextInput::make('passport_address') + ->columnSpan(4) + ->label(__('Proscription for home')) + ->maxLength(255) + ->required() + ->default(user()?->getOption('passport_address')), + + TextInput::make('real_address') + ->label(__('Current home address')) + ->columnSpan(4) + ->maxLength(255) + ->required() + ->default(user()?->getOption('real_address')), + + TextInput::make('email') + ->label(__('Email')) + ->email() + ->maxLength(255) + ->columnSpan(2) + ->default(user()?->getOption('email')), + + TextInput::make('phone') + ->label(__('Phone')) + ->required() + ->mask('99 99 99 99') + ->prefix('+993') + ->rules([ + new PhoneNumberVerificationRule, + ]) + ->columnSpan(2) + ->default(user()?->phone), + + TextInput::make('phone_additional') + ->label(__('Additional phone')) + ->mask('99 99 99 99') + ->prefix('+993') + ->rules([ + new PhoneNumberVerificationRule, + ]) + ->columnSpan(2), + + TextInput::make('phone_home') + ->label(__('Home phone')) + ->numeric() + ->prefix('+993') + ->columnSpan(2), + + Select::make('education') + ->columnSpan(2) + ->label(__('Education')) + ->options(EducationRepository::values()) + ->native(false) + ->required(), + + Select::make('marriage_status') + ->columnSpan(2) + ->label(__('Marital status')) + ->options(MarriageRepository::values()) + ->native(false) + ->required(), + ]), + Tab::make(__('Pasport files')) + ->columns(4) + ->schema([ + FileUpload::make('passport_one') + ->label(__('Passport (page 1)')) + ->image() + ->maxSize(4096) + ->required() + ->columnSpan(2), + + FileUpload::make('passport_two') + ->label(__('Passport (page 2-3)')) + ->image() + ->maxSize(4096) + ->required() + ->columnSpan(2), + + FileUpload::make('passport_three') + ->label(__('Passport (page 8-9)')) + ->image() + ->maxSize(4096) + ->required() + ->columnSpan(2), + + FileUpload::make('passport_four') + ->label(__('Passport (page 32)')) + ->image() + ->maxSize(4096) + ->required() + ->columnSpan(2), + ]), + Tab::make(__('Work')) + ->columns(4) + ->schema([ + Select::make('work_region') + ->label(__('Work region')) + ->options(RegionRepository::values()) + ->columnSpan(1) + ->live() + ->afterStateUpdated(fn (callable $set) => $set('work_province_id', null)) + ->required(), + + Select::make('work_province_id') + ->label(__('Work province')) + ->relationship('workProvince', 'name', function ($query, callable $get) { + $query->orderByTranslation('name'); + + $region = $get('work_region'); + if ($region) { + $query->where('region', $region); + } + }) + ->columnSpan(1) + ->required(), + + TextInput::make('work_company') + ->label(__('Work company name')) + ->maxLength(255) + ->required() + ->columnSpan(2), + + TextInput::make('work_company_accountant_number') + ->label(__('HR number')) + ->prefix('+993') + ->numeric() + ->required() + ->columnSpan(1), + + TextInput::make('work_position') + ->label(__('Work position')) + ->required() + ->maxLength(255) + ->columnSpan(1), + + TextInput::make('work_salary') + ->label(__('Salary')) + ->numeric() + ->required() + ->columnSpan(1), + + DatePicker::make('work_started_at') + ->label(__('Work started at')) + ->displayFormat('d.m.Y') + ->beforeOrEqual('today') + ->required() + ->columnSpan(1), + ]), + ])->columnSpan(4), + ]); + } +} diff --git a/app/Filament/Clusters/Loans/Resources/LoanOrderMobiles/Schemas/LoanOrderMobileInfolist.php b/app/Filament/Clusters/Loans/Resources/LoanOrderMobiles/Schemas/LoanOrderMobileInfolist.php new file mode 100644 index 0000000..60f217b --- /dev/null +++ b/app/Filament/Clusters/Loans/Resources/LoanOrderMobiles/Schemas/LoanOrderMobileInfolist.php @@ -0,0 +1,17 @@ +columns(3) + ->components([ + + ]); + } +} diff --git a/app/Filament/Clusters/Loans/Resources/LoanOrderMobiles/Tables/LoanOrderMobilesTable.php b/app/Filament/Clusters/Loans/Resources/LoanOrderMobiles/Tables/LoanOrderMobilesTable.php new file mode 100644 index 0000000..8aeee1d --- /dev/null +++ b/app/Filament/Clusters/Loans/Resources/LoanOrderMobiles/Tables/LoanOrderMobilesTable.php @@ -0,0 +1,35 @@ +columns([ + // + ]) + ->filters([ + TrashedFilter::make(), + ]) + ->recordActions([ + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ForceDeleteBulkAction::make(), + RestoreBulkAction::make(), + ]), + ]); + } +} diff --git a/app/Filament/Resources/Users/Pages/CreateUser.php b/app/Filament/Resources/Users/Pages/CreateUser.php new file mode 100644 index 0000000..125b3ff --- /dev/null +++ b/app/Filament/Resources/Users/Pages/CreateUser.php @@ -0,0 +1,11 @@ +columns(2) + ->components([ + TextInput::make('first_name') + ->label(__('First name')) + ->required(), + + TextInput::make('last_name') + ->label(__('Last name')) + ->required(), + + TextInput::make('username') + ->label(__('Username')) + ->required() + ->unique(ignoreRecord: true), + + TextInput::make('phone') + ->label(__('Phone number')) + ->required() + ->unique(ignoreRecord: true), + + TextInput::make('email') + ->label(__('Email')) + ->email() + ->unique(ignoreRecord: true), + + TextInput::make('password') + ->label(__('Password')) + ->password() + ->dehydrateStateUsing(fn ($state) => Hash::make($state)) + ->dehydrated(fn ($state) => filled($state)) + ->required(fn (string $context): bool => $context === 'create'), + + Select::make('roles') + ->label(__('Roles')) + ->relationship('roles', 'name') + ->multiple() + ->preload() + ->native(false) + ->required(), + ]); + } +} diff --git a/app/Filament/Resources/Users/Tables/UsersTable.php b/app/Filament/Resources/Users/Tables/UsersTable.php new file mode 100644 index 0000000..372918d --- /dev/null +++ b/app/Filament/Resources/Users/Tables/UsersTable.php @@ -0,0 +1,54 @@ +columns([ + TextColumn::make('first_name') + ->label(__('First name')) + ->searchable() + ->sortable(), + + TextColumn::make('last_name') + ->label(__('Last name')) + ->searchable() + ->sortable(), + + TextColumn::make('username') + ->label(__('Username')) + ->searchable() + ->sortable(), + + TextColumn::make('phone') + ->label(__('Phone number')) + ->searchable() + ->sortable(), + + TextColumn::make('email') + ->label(__('Email')) + ->searchable() + ->sortable(), + ]) + ->filters([ + // + ]) + ->recordActions([ + EditAction::make(), + ]) + ->toolbarActions([ + BulkActionGroup::make([ + DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app/Filament/Resources/Users/UserResource.php b/app/Filament/Resources/Users/UserResource.php new file mode 100644 index 0000000..d339397 --- /dev/null +++ b/app/Filament/Resources/Users/UserResource.php @@ -0,0 +1,50 @@ + ListUsers::route('/'), + 'create' => CreateUser::route('/create'), + 'edit' => EditUser::route('/{record}/edit'), + ]; + } +}