components([ Section::make(__('admin.users.sections.account')) ->columns(2) ->schema([ TextInput::make('name') ->label(__('admin.users.fields.name')) ->required() ->maxLength(255), TextInput::make('email') ->label(__('admin.users.fields.email')) ->email() ->required() ->unique(ignoreRecord: true) ->maxLength(255), Select::make('locale') ->label(__('admin.users.fields.locale')) ->options(self::localeOptions()) ->default('en') ->required(), Select::make('role') ->label(__('admin.users.fields.role')) ->options(UserRole::class) ->default(UserRole::USER->value) ->required(), FileUpload::make('avatar_url') ->label(__('admin.users.fields.avatar')) ->image() ->directory('avatars') ->visibility('public') ->maxSize(2048), TextInput::make('password') ->label(__('admin.users.fields.password')) ->password() ->revealable() ->rule(Password::default()) ->required(fn (string $operation): bool => $operation === 'create') ->formatStateUsing(fn (): ?string => null) ->dehydrated(fn ($state): bool => filled($state)) ->autocomplete('new-password'), DateTimePicker::make('email_verified_at') ->label(__('admin.users.fields.email_verified_at')), DateTimePicker::make('account_verified_at') ->label(__('admin.users.fields.account_verified_at')), ]), Section::make(__('admin.users.sections.profile')) ->columns(2) ->schema([ Textarea::make('bio') ->label(__('admin.users.fields.bio')) ->rows(4) ->columnSpanFull(), TextInput::make('height') ->label(__('admin.users.fields.height')) ->integer() ->minValue(0) ->maxValue(300) ->suffix('cm'), DatePicker::make('date_of_birth') ->label(__('admin.users.fields.date_of_birth')) ->minDate('1900-01-01') ->maxDate(now()->subDay()), Select::make('sex') ->label(__('admin.users.fields.sex')) ->options(UserSex::class) ->default(UserSex::UNKNOWN->value) ->required(), ]), Section::make(__('admin.users.sections.nutrition_goals')) ->columns(4) ->schema([ TextInput::make('daily_calorie_goal') ->label(__('admin.users.fields.daily_calorie_goal')) ->integer() ->minValue(0) ->maxValue(100000) ->suffix('kcal') ->default(2000) ->required(), TextInput::make('daily_protein_goal') ->label(__('admin.users.fields.daily_protein_goal')) ->numeric() ->minValue(0) ->maxValue(10000) ->suffix('g') ->default(120) ->required(), TextInput::make('daily_carbs_goal') ->label(__('admin.users.fields.daily_carbs_goal')) ->numeric() ->minValue(0) ->maxValue(10000) ->suffix('g') ->default(250) ->required(), TextInput::make('daily_fats_goal') ->label(__('admin.users.fields.daily_fats_goal')) ->numeric() ->minValue(0) ->maxValue(10000) ->suffix('g') ->default(70) ->required(), ]), Section::make(__('admin.users.sections.activity')) ->columns(3) ->schema([ Select::make('physical_activity_level') ->label(__('admin.users.fields.physical_activity_level')) ->options(PhysicalActivityLevel::class) ->default(PhysicalActivityLevel::SEDENTARY->value) ->required(), Select::make('weight_goal') ->label(__('admin.users.fields.weight_goal')) ->options(WeightGoal::class) ->default(WeightGoal::LOSE_WEIGHT->value) ->required(), Select::make('pace_preference') ->label(__('admin.users.fields.pace_preference')) ->options(PacePreference::class) ->default(PacePreference::SLOW->value) ->required(), ]), ]); } /** * @return array */ private static function localeOptions(): array { $labels = __('admin.users.locales'); return collect(config('app.supported_locales', ['fr', 'en'])) ->mapWithKeys(fn (string $locale): array => [ $locale => is_array($labels) ? ($labels[$locale] ?? $locale) : $locale, ]) ->all(); } }