mirror of https://github.com/kcal-app/kcal.git
Add basic personalized goal views (WIP)
This commit is contained in:
parent
755ef60561
commit
a26a4c71d0
|
|
@ -6,6 +6,7 @@ use App\Models\Goal;
|
||||||
use Illuminate\Contracts\View\View;
|
use Illuminate\Contracts\View\View;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class GoalController extends Controller
|
class GoalController extends Controller
|
||||||
|
|
@ -13,9 +14,18 @@ class GoalController extends Controller
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*/
|
*/
|
||||||
public function index(): View
|
public function index(Request $request): View
|
||||||
{
|
{
|
||||||
return view('goals.index');
|
if ($request->date) {
|
||||||
|
$date = Carbon::createFromFormat('Y-m-d', $request->date);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$date = Carbon::now();
|
||||||
|
}
|
||||||
|
return view('goals.index')
|
||||||
|
->with('date', $date)
|
||||||
|
->with('goals', Auth::user()->getGoalsByTime($date))
|
||||||
|
->with('goalOptions', Goal::getGoalOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -77,7 +87,9 @@ class GoalController extends Controller
|
||||||
*/
|
*/
|
||||||
public function delete(Goal $goal): View
|
public function delete(Goal $goal): View
|
||||||
{
|
{
|
||||||
return view('goals.delete')->with('goal', $goal);
|
return view('goals.delete')
|
||||||
|
->with('goal', $goal)
|
||||||
|
->with('goalOptions', Goal::getGoalOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ final class Goal extends Model
|
||||||
$options[$key] = [
|
$options[$key] = [
|
||||||
'value' => $key,
|
'value' => $key,
|
||||||
'label' => "{$nutrient['value']} per day",
|
'label' => "{$nutrient['value']} per day",
|
||||||
|
'unit' => $nutrient['unit'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
return $options;
|
return $options;
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\User
|
* App\Models\User
|
||||||
|
|
@ -69,4 +71,31 @@ final class User extends Authenticatable
|
||||||
public function goals(): HasMany {
|
public function goals(): HasMany {
|
||||||
return $this->hasMany(Goal::class);
|
return $this->hasMany(Goal::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get User's past, present, and future goals.
|
||||||
|
*
|
||||||
|
* @return \App\Models\Goal[]
|
||||||
|
*/
|
||||||
|
public function getGoalsByTime(?Carbon $date = null): array {
|
||||||
|
$now = $date ?? Carbon::now();
|
||||||
|
$goals = ['past' => [], 'present' => [], 'future' => []];
|
||||||
|
Goal::all()->where('user_id', Auth::user()->id)
|
||||||
|
->each(function ($item) use(&$goals, $now) {
|
||||||
|
if ($item->to && $now->isAfter($item->to)) {
|
||||||
|
$goals['past'][$item->id] = $item;
|
||||||
|
}
|
||||||
|
elseif ($item->from && $now->isBefore($item->from)) {
|
||||||
|
$goals['future'][$item->id] = $item;
|
||||||
|
}
|
||||||
|
elseif (
|
||||||
|
empty($item->from)
|
||||||
|
|| empty($item->to)
|
||||||
|
|| $now->isBetween($item->from, $item->to)
|
||||||
|
) {
|
||||||
|
$goals['present'][$item->id] = $item;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return $goals;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
@method('delete')
|
@method('delete')
|
||||||
@csrf
|
@csrf
|
||||||
<div class="text-lg pb-3">
|
<div class="text-lg pb-3">
|
||||||
Are you sure what to delete your <span class="font-extrabold">{{ $goal->goal }}</span> goal?
|
Are you sure what to delete your <span class="font-extrabold">{{ $goalOptions[$goal->goal]['label'] }}</span> goal?
|
||||||
</div>
|
</div>
|
||||||
<x-inputs.button class="bg-red-800 hover:bg-red-700">
|
<x-inputs.button class="bg-red-800 hover:bg-red-700">
|
||||||
Yes, delete
|
Yes, delete
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,28 @@
|
||||||
<x-app-layout>
|
<x-app-layout>
|
||||||
<x-slot name="header">
|
<x-slot name="header">
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<h2 class="font-semibold text-2xl text-gray-800 leading-tight">{{ Auth::user()->name }}'s Goals</h2>
|
<h2 class="leading-tight text-center">
|
||||||
|
<div class="text-2xl font-semibold text-gray-800">{{ Auth::user()->name }}'s Goals</div>
|
||||||
|
<div class="flex items-center space-x-2">
|
||||||
|
<div>
|
||||||
|
<a class="text-gray-500 hover:text-gray-700 hover:border-gray-300"
|
||||||
|
href="{{ route(Route::current()->getName(), ['date' => $date->copy()->subDay(1)->toDateString()]) }}">
|
||||||
|
<svg class="w-6 h-6" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||||
|
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm.707-10.293a1 1 0 00-1.414-1.414l-3 3a1 1 0 000 1.414l3 3a1 1 0 001.414-1.414L9.414 11H13a1 1 0 100-2H9.414l1.293-1.293z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="text-base text-gray-500">{{ $date->format('D, j M Y') }}</div>
|
||||||
|
<div>
|
||||||
|
<a class="text-gray-500 hover:text-gray-700 hover:border-gray-300"
|
||||||
|
href="{{ route(Route::current()->getName(), ['date' => $date->copy()->addDay(1)->toDateString()]) }}">
|
||||||
|
<svg class="w-6 h-6" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||||
|
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-8.707l-3-3a1 1 0 00-1.414 1.414L10.586 9H7a1 1 0 100 2h3.586l-1.293 1.293a1 1 0 101.414 1.414l3-3a1 1 0 000-1.414z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</h2>
|
||||||
<a href="{{ route('goals.create') }}" class="inline-flex items-center rounded-md font-semibold text-white p-2 bg-green-500 tracking-widest hover:bg-green-700 active:bg-green-900 focus:outline-none focus:border-green-900 focus:ring ring-green-600 disabled:opacity-25 transition ease-in-out duration-150">
|
<a href="{{ route('goals.create') }}" class="inline-flex items-center rounded-md font-semibold text-white p-2 bg-green-500 tracking-widest hover:bg-green-700 active:bg-green-900 focus:outline-none focus:border-green-900 focus:ring ring-green-600 disabled:opacity-25 transition ease-in-out duration-150">
|
||||||
<svg class="w-6 h-6" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
<svg class="w-6 h-6" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||||
<path fill-rule="evenodd" d="M10 5a1 1 0 011 1v3h3a1 1 0 110 2h-3v3a1 1 0 11-2 0v-3H6a1 1 0 110-2h3V6a1 1 0 011-1z" clip-rule="evenodd" />
|
<path fill-rule="evenodd" d="M10 5a1 1 0 011 1v3h3a1 1 0 110 2h-3v3a1 1 0 11-2 0v-3H6a1 1 0 110-2h3V6a1 1 0 011-1z" clip-rule="evenodd" />
|
||||||
|
|
@ -15,7 +36,30 @@
|
||||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
||||||
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
|
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
|
||||||
<div class="p-6 bg-white border-b border-gray-200">
|
<div class="p-6 bg-white border-b border-gray-200">
|
||||||
TODO: Goals index.
|
<h3 class="text-xl font-semibold text-gray-800">Goals</h3>
|
||||||
|
@forelse($goals['present'] as $goal)
|
||||||
|
<details>
|
||||||
|
<summary>{{ number_format($goal->amount, 0) }}{{ $goalOptions[$goal->goal]['unit'] }} {{ $goalOptions[$goal->goal]['label'] }}</summary>
|
||||||
|
TODO: Details for the day!
|
||||||
|
<div class="flex">
|
||||||
|
<a class="text-gray-500 hover:text-gray-700 hover:border-gray-300 text-sm"
|
||||||
|
href="{{ route('goals.edit', $goal) }}">
|
||||||
|
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||||
|
<path d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z" />
|
||||||
|
<path fill-rule="evenodd" d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<a class="text-red-500 hover:text-red-700 hover:border-red-300 text-sm"
|
||||||
|
href="{{ route('goals.delete', $goal) }}">
|
||||||
|
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||||
|
<path fill-rule="evenodd" d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
@empty
|
||||||
|
<div>No goals set.</div>
|
||||||
|
@endforelse
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue