From 3a36f648db7e1cb5e399cbf28d017b6aa8d448aa Mon Sep 17 00:00:00 2001 From: "Christopher C. Wells" Date: Mon, 15 Feb 2021 09:08:28 -0800 Subject: [PATCH] Refactor goals with a "frequency" attribute --- app/Http/Controllers/GoalController.php | 18 ++++--- app/Models/Goal.php | 48 +++++++++++++------ app/Models/User.php | 3 +- app/Support/Nutrients.php | 18 +++---- .../2021_02_13_052427_create_goals_table.php | 5 +- resources/views/goals/delete.blade.php | 2 +- resources/views/goals/edit.blade.php | 36 +++++++++----- resources/views/goals/index.blade.php | 3 +- resources/views/goals/show.blade.php | 2 +- 9 files changed, 83 insertions(+), 52 deletions(-) diff --git a/app/Http/Controllers/GoalController.php b/app/Http/Controllers/GoalController.php index c1584b5..89ead43 100644 --- a/app/Http/Controllers/GoalController.php +++ b/app/Http/Controllers/GoalController.php @@ -24,8 +24,7 @@ class GoalController extends Controller } return view('goals.index') ->with('date', $date) - ->with('goals', Auth::user()->getGoalsByTime($date)) - ->with('goalOptions', Goal::getGoalOptions()); + ->with('goals', Auth::user()->getGoalsByTime($date)); } /** @@ -61,7 +60,8 @@ class GoalController extends Controller { return view('goals.edit') ->with('goal', $goal) - ->with('goalOptions', Goal::getGoalOptions()); + ->with('nameOptions', Goal::getNameOptions()) + ->with('frequencyOptions', Goal::$frequencyOptions); } /** @@ -72,11 +72,11 @@ class GoalController extends Controller $attributes = $request->validate([ 'from' => ['nullable', 'date'], 'to' => ['nullable', 'date'], - 'goal' => ['required', 'string'], - 'amount' => ['required', 'numeric'], + 'frequency' => ['nullable', 'string'], + 'name' => ['required', 'string'], + 'goal' => ['required', 'numeric'], ]); - $goal->fill(array_filter($attributes)) - ->user()->associate(Auth::user()); + $goal->fill($attributes)->user()->associate(Auth::user()); $goal->save(); session()->flash('message', "Goal updated!"); return redirect()->route('goals.show', $goal); @@ -87,9 +87,7 @@ class GoalController extends Controller */ public function delete(Goal $goal): View { - return view('goals.delete') - ->with('goal', $goal) - ->with('goalOptions', Goal::getGoalOptions()); + return view('goals.delete')->with('goal', $goal); } /** diff --git a/app/Models/Goal.php b/app/Models/Goal.php index 3c2cc3f..1bd39d5 100644 --- a/app/Models/Goal.php +++ b/app/Models/Goal.php @@ -14,19 +14,22 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; * @property int $user_id * @property \datetime|null $from * @property \datetime|null $to - * @property string $goal - * @property float $amount + * @property string|null $frequency + * @property string $name + * @property float $goal * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at + * @property-read string $summary * @property-read \App\Models\User $user * @method static \Illuminate\Database\Eloquent\Builder|Goal newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|Goal newQuery() * @method static \Illuminate\Database\Eloquent\Builder|Goal query() - * @method static \Illuminate\Database\Eloquent\Builder|Goal whereAmount($value) * @method static \Illuminate\Database\Eloquent\Builder|Goal whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|Goal whereFrequency($value) * @method static \Illuminate\Database\Eloquent\Builder|Goal whereFrom($value) * @method static \Illuminate\Database\Eloquent\Builder|Goal whereGoal($value) * @method static \Illuminate\Database\Eloquent\Builder|Goal whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|Goal whereName($value) * @method static \Illuminate\Database\Eloquent\Builder|Goal whereTo($value) * @method static \Illuminate\Database\Eloquent\Builder|Goal whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|Goal whereUserId($value) @@ -36,14 +39,22 @@ final class Goal extends Model { use HasFactory; + /** + * Supported options for thr frequency attribute. + */ + public static array $frequencyOptions = [ + ['value' => 'daily', 'label' => 'daily'], + ]; + /** * @inheritdoc */ protected $fillable = [ + 'frequency', 'from', - 'to', 'goal', - 'amount', + 'name', + 'to', ]; /** @@ -51,8 +62,15 @@ final class Goal extends Model */ protected $casts = [ 'from' => 'datetime:Y-m-d', + 'goal' => 'float', 'to' => 'datetime:Y-m-d', - 'amount' => 'float', + ]; + + /** + * @inheritdoc + */ + protected $appends = [ + 'summary', ]; /** @@ -62,18 +80,20 @@ final class Goal extends Model return $this->belongsTo(User::class); } + public function getSummaryAttribute(): string { + $nameOptions = self::getNameOptions(); + return number_format($this->goal) . "{$nameOptions[$this->name]['unit']} {$nameOptions[$this->name]['label']} {$this->frequency}"; + } + /** - * Get options for the "goal" column. - * - * @return array + * Get options for the "name" column. */ - public static function getGoalOptions(): array { + public static function getNameOptions(): array { $options = []; foreach (Nutrients::$all as $nutrient) { - $key = "{$nutrient['value']}_per_day"; - $options[$key] = [ - 'value' => $key, - 'label' => "{$nutrient['value']} per day", + $options[$nutrient['value']] = [ + 'value' => $nutrient['value'], + 'label' => $nutrient['label'], 'unit' => $nutrient['unit'], ]; } diff --git a/app/Models/User.php b/app/Models/User.php index 5aa02c4..36b22c7 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Illuminate\Support\Carbon; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\Auth; /** @@ -79,7 +80,7 @@ final class User extends Authenticatable */ public function getGoalsByTime(?Carbon $date = null): array { $now = $date ?? Carbon::now(); - $goals = ['past' => [], 'present' => [], 'future' => []]; + $goals = ['past' => new Collection(), 'present' => new Collection(), 'future' => new Collection()]; Goal::all()->where('user_id', Auth::user()->id) ->each(function ($item) use(&$goals, $now) { if ($item->to && $now->isAfter($item->to)) { diff --git a/app/Support/Nutrients.php b/app/Support/Nutrients.php index 1b030d4..fc5fa88 100644 --- a/app/Support/Nutrients.php +++ b/app/Support/Nutrients.php @@ -10,21 +10,21 @@ class Nutrients public static float $gramsPerOunce = 28.349523125; public static array $all = [ - ['value' => 'calories', 'unit' => null], - ['value' => 'fat', 'unit' => 'g'], - ['value' => 'cholesterol', 'unit' => 'mg'], - ['value' => 'sodium', 'unit' => 'mg'], - ['value' => 'carbohydrates', 'unit' => 'g'], - ['value' => 'protein', 'unit' => 'g'], + ['value' => 'calories', 'label' => 'calories', 'unit' => null], + ['value' => 'carbohydrates', 'label' => 'carbohydrates', 'unit' => 'g'], + ['value' => 'cholesterol', 'label' => 'cholesterol', 'unit' => 'mg'], + ['value' => 'fat', 'label' => 'fat', 'unit' => 'g'], + ['value' => 'protein', 'label' => 'protein', 'unit' => 'g'], + ['value' => 'sodium', 'label' => 'sodium', 'unit' => 'mg'], ]; public static array $units = [ - ['value' => 'tsp', 'label' => 'tsp.'], - ['value' => 'tbsp', 'label' => 'tbsp.'], ['value' => 'cup', 'label' => 'cup'], - ['value' => 'oz', 'label' => 'oz'], ['value' => 'gram', 'label' => 'grams'], + ['value' => 'oz', 'label' => 'oz'], ['value' => 'serving', 'label' => 'servings'], + ['value' => 'tbsp', 'label' => 'tbsp.'], + ['value' => 'tsp', 'label' => 'tsp.'], ]; /** diff --git a/database/migrations/2021_02_13_052427_create_goals_table.php b/database/migrations/2021_02_13_052427_create_goals_table.php index c2a73fd..a46b999 100644 --- a/database/migrations/2021_02_13_052427_create_goals_table.php +++ b/database/migrations/2021_02_13_052427_create_goals_table.php @@ -19,8 +19,9 @@ class CreateGoalsTable extends Migration $table->foreignIdFor(User::class)->constrained()->cascadeOnUpdate()->cascadeOnDelete(); $table->date('from')->nullable(); $table->date('to')->nullable(); - $table->string('goal'); - $table->unsignedFloat('amount'); + $table->string('frequency')->nullable(); + $table->string('name'); + $table->unsignedFloat('goal'); $table->timestamps(); $table->index('user_id'); }); diff --git a/resources/views/goals/delete.blade.php b/resources/views/goals/delete.blade.php index ac34599..a44182b 100644 --- a/resources/views/goals/delete.blade.php +++ b/resources/views/goals/delete.blade.php @@ -13,7 +13,7 @@ @method('delete') @csrf
- Are you sure what to delete your {{ $goalOptions[$goal->goal]['label'] }} goal? + Are you sure what to delete your {{ $goal->summary }} goal?
Yes, delete diff --git a/resources/views/goals/edit.blade.php b/resources/views/goals/edit.blade.php index 16f963d..82fb2bd 100644 --- a/resources/views/goals/edit.blade.php +++ b/resources/views/goals/edit.blade.php @@ -32,24 +32,36 @@ :value="old('to', $goal->to)" /> - +
- - + + + +
+ + +
+ + +
- - +
diff --git a/resources/views/goals/index.blade.php b/resources/views/goals/index.blade.php index 924ec96..bfef1f9 100644 --- a/resources/views/goals/index.blade.php +++ b/resources/views/goals/index.blade.php @@ -36,10 +36,9 @@
-

Goals

@forelse($goals['present'] as $goal)
- {{ number_format($goal->amount, 0) }}{{ $goalOptions[$goal->goal]['unit'] }} {{ $goalOptions[$goal->goal]['label'] }} + {{ $goal->summary }} TODO: Details for the day!