mirror of https://github.com/kcal-app/kcal.git
Merge remote-tracking branch 'origin/main' into demo
This commit is contained in:
commit
13b10038d7
|
|
@ -3,6 +3,9 @@ on:
|
|||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ namespace PHPSTORM_META {
|
|||
'Illuminate\Contracts\Pipeline\Hub' => \Illuminate\Pipeline\Hub::class,
|
||||
'Illuminate\Contracts\Queue\EntityResolver' => \Illuminate\Database\Eloquent\QueueEntityResolver::class,
|
||||
'Illuminate\Contracts\Routing\ResponseFactory' => \Illuminate\Routing\ResponseFactory::class,
|
||||
'Illuminate\Contracts\Validation\UncompromisedVerifier' => \Illuminate\Validation\NotPwnedVerifier::class,
|
||||
'Illuminate\Database\Console\DbCommand' => \Illuminate\Database\Console\DbCommand::class,
|
||||
'Illuminate\Foundation\Mix' => \Illuminate\Foundation\Mix::class,
|
||||
'Illuminate\Foundation\PackageManifest' => \Illuminate\Foundation\PackageManifest::class,
|
||||
|
|
@ -88,7 +89,6 @@ namespace PHPSTORM_META {
|
|||
'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class,
|
||||
'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class,
|
||||
'cache' => \Illuminate\Cache\CacheManager::class,
|
||||
'cache.dynamodb.client' => \Aws\DynamoDb\DynamoDbClient::class,
|
||||
'cache.store' => \Illuminate\Cache\Repository::class,
|
||||
'command.auth.resets.clear' => \Illuminate\Auth\Console\ClearResetsCommand::class,
|
||||
'command.cache.clear' => \Illuminate\Cache\Console\ClearCommand::class,
|
||||
|
|
@ -272,6 +272,7 @@ namespace PHPSTORM_META {
|
|||
'Illuminate\Contracts\Pipeline\Hub' => \Illuminate\Pipeline\Hub::class,
|
||||
'Illuminate\Contracts\Queue\EntityResolver' => \Illuminate\Database\Eloquent\QueueEntityResolver::class,
|
||||
'Illuminate\Contracts\Routing\ResponseFactory' => \Illuminate\Routing\ResponseFactory::class,
|
||||
'Illuminate\Contracts\Validation\UncompromisedVerifier' => \Illuminate\Validation\NotPwnedVerifier::class,
|
||||
'Illuminate\Database\Console\DbCommand' => \Illuminate\Database\Console\DbCommand::class,
|
||||
'Illuminate\Foundation\Mix' => \Illuminate\Foundation\Mix::class,
|
||||
'Illuminate\Foundation\PackageManifest' => \Illuminate\Foundation\PackageManifest::class,
|
||||
|
|
@ -297,7 +298,6 @@ namespace PHPSTORM_META {
|
|||
'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class,
|
||||
'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class,
|
||||
'cache' => \Illuminate\Cache\CacheManager::class,
|
||||
'cache.dynamodb.client' => \Aws\DynamoDb\DynamoDbClient::class,
|
||||
'cache.store' => \Illuminate\Cache\Repository::class,
|
||||
'command.auth.resets.clear' => \Illuminate\Auth\Console\ClearResetsCommand::class,
|
||||
'command.cache.clear' => \Illuminate\Cache\Console\ClearCommand::class,
|
||||
|
|
@ -481,6 +481,7 @@ namespace PHPSTORM_META {
|
|||
'Illuminate\Contracts\Pipeline\Hub' => \Illuminate\Pipeline\Hub::class,
|
||||
'Illuminate\Contracts\Queue\EntityResolver' => \Illuminate\Database\Eloquent\QueueEntityResolver::class,
|
||||
'Illuminate\Contracts\Routing\ResponseFactory' => \Illuminate\Routing\ResponseFactory::class,
|
||||
'Illuminate\Contracts\Validation\UncompromisedVerifier' => \Illuminate\Validation\NotPwnedVerifier::class,
|
||||
'Illuminate\Database\Console\DbCommand' => \Illuminate\Database\Console\DbCommand::class,
|
||||
'Illuminate\Foundation\Mix' => \Illuminate\Foundation\Mix::class,
|
||||
'Illuminate\Foundation\PackageManifest' => \Illuminate\Foundation\PackageManifest::class,
|
||||
|
|
@ -506,7 +507,6 @@ namespace PHPSTORM_META {
|
|||
'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class,
|
||||
'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class,
|
||||
'cache' => \Illuminate\Cache\CacheManager::class,
|
||||
'cache.dynamodb.client' => \Aws\DynamoDb\DynamoDbClient::class,
|
||||
'cache.store' => \Illuminate\Cache\Repository::class,
|
||||
'command.auth.resets.clear' => \Illuminate\Auth\Console\ClearResetsCommand::class,
|
||||
'command.cache.clear' => \Illuminate\Cache\Console\ClearCommand::class,
|
||||
|
|
@ -690,6 +690,7 @@ namespace PHPSTORM_META {
|
|||
'Illuminate\Contracts\Pipeline\Hub' => \Illuminate\Pipeline\Hub::class,
|
||||
'Illuminate\Contracts\Queue\EntityResolver' => \Illuminate\Database\Eloquent\QueueEntityResolver::class,
|
||||
'Illuminate\Contracts\Routing\ResponseFactory' => \Illuminate\Routing\ResponseFactory::class,
|
||||
'Illuminate\Contracts\Validation\UncompromisedVerifier' => \Illuminate\Validation\NotPwnedVerifier::class,
|
||||
'Illuminate\Database\Console\DbCommand' => \Illuminate\Database\Console\DbCommand::class,
|
||||
'Illuminate\Foundation\Mix' => \Illuminate\Foundation\Mix::class,
|
||||
'Illuminate\Foundation\PackageManifest' => \Illuminate\Foundation\PackageManifest::class,
|
||||
|
|
@ -715,7 +716,6 @@ namespace PHPSTORM_META {
|
|||
'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class,
|
||||
'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class,
|
||||
'cache' => \Illuminate\Cache\CacheManager::class,
|
||||
'cache.dynamodb.client' => \Aws\DynamoDb\DynamoDbClient::class,
|
||||
'cache.store' => \Illuminate\Cache\Repository::class,
|
||||
'command.auth.resets.clear' => \Illuminate\Auth\Console\ClearResetsCommand::class,
|
||||
'command.cache.clear' => \Illuminate\Cache\Console\ClearCommand::class,
|
||||
|
|
@ -899,6 +899,7 @@ namespace PHPSTORM_META {
|
|||
'Illuminate\Contracts\Pipeline\Hub' => \Illuminate\Pipeline\Hub::class,
|
||||
'Illuminate\Contracts\Queue\EntityResolver' => \Illuminate\Database\Eloquent\QueueEntityResolver::class,
|
||||
'Illuminate\Contracts\Routing\ResponseFactory' => \Illuminate\Routing\ResponseFactory::class,
|
||||
'Illuminate\Contracts\Validation\UncompromisedVerifier' => \Illuminate\Validation\NotPwnedVerifier::class,
|
||||
'Illuminate\Database\Console\DbCommand' => \Illuminate\Database\Console\DbCommand::class,
|
||||
'Illuminate\Foundation\Mix' => \Illuminate\Foundation\Mix::class,
|
||||
'Illuminate\Foundation\PackageManifest' => \Illuminate\Foundation\PackageManifest::class,
|
||||
|
|
@ -924,7 +925,6 @@ namespace PHPSTORM_META {
|
|||
'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class,
|
||||
'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class,
|
||||
'cache' => \Illuminate\Cache\CacheManager::class,
|
||||
'cache.dynamodb.client' => \Aws\DynamoDb\DynamoDbClient::class,
|
||||
'cache.store' => \Illuminate\Cache\Repository::class,
|
||||
'command.auth.resets.clear' => \Illuminate\Auth\Console\ClearResetsCommand::class,
|
||||
'command.cache.clear' => \Illuminate\Cache\Console\ClearCommand::class,
|
||||
|
|
@ -1108,6 +1108,7 @@ namespace PHPSTORM_META {
|
|||
'Illuminate\Contracts\Pipeline\Hub' => \Illuminate\Pipeline\Hub::class,
|
||||
'Illuminate\Contracts\Queue\EntityResolver' => \Illuminate\Database\Eloquent\QueueEntityResolver::class,
|
||||
'Illuminate\Contracts\Routing\ResponseFactory' => \Illuminate\Routing\ResponseFactory::class,
|
||||
'Illuminate\Contracts\Validation\UncompromisedVerifier' => \Illuminate\Validation\NotPwnedVerifier::class,
|
||||
'Illuminate\Database\Console\DbCommand' => \Illuminate\Database\Console\DbCommand::class,
|
||||
'Illuminate\Foundation\Mix' => \Illuminate\Foundation\Mix::class,
|
||||
'Illuminate\Foundation\PackageManifest' => \Illuminate\Foundation\PackageManifest::class,
|
||||
|
|
@ -1133,7 +1134,6 @@ namespace PHPSTORM_META {
|
|||
'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class,
|
||||
'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class,
|
||||
'cache' => \Illuminate\Cache\CacheManager::class,
|
||||
'cache.dynamodb.client' => \Aws\DynamoDb\DynamoDbClient::class,
|
||||
'cache.store' => \Illuminate\Cache\Repository::class,
|
||||
'command.auth.resets.clear' => \Illuminate\Auth\Console\ClearResetsCommand::class,
|
||||
'command.cache.clear' => \Illuminate\Cache\Console\ClearCommand::class,
|
||||
|
|
@ -1317,6 +1317,7 @@ namespace PHPSTORM_META {
|
|||
'Illuminate\Contracts\Pipeline\Hub' => \Illuminate\Pipeline\Hub::class,
|
||||
'Illuminate\Contracts\Queue\EntityResolver' => \Illuminate\Database\Eloquent\QueueEntityResolver::class,
|
||||
'Illuminate\Contracts\Routing\ResponseFactory' => \Illuminate\Routing\ResponseFactory::class,
|
||||
'Illuminate\Contracts\Validation\UncompromisedVerifier' => \Illuminate\Validation\NotPwnedVerifier::class,
|
||||
'Illuminate\Database\Console\DbCommand' => \Illuminate\Database\Console\DbCommand::class,
|
||||
'Illuminate\Foundation\Mix' => \Illuminate\Foundation\Mix::class,
|
||||
'Illuminate\Foundation\PackageManifest' => \Illuminate\Foundation\PackageManifest::class,
|
||||
|
|
@ -1342,7 +1343,6 @@ namespace PHPSTORM_META {
|
|||
'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class,
|
||||
'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class,
|
||||
'cache' => \Illuminate\Cache\CacheManager::class,
|
||||
'cache.dynamodb.client' => \Aws\DynamoDb\DynamoDbClient::class,
|
||||
'cache.store' => \Illuminate\Cache\Repository::class,
|
||||
'command.auth.resets.clear' => \Illuminate\Auth\Console\ClearResetsCommand::class,
|
||||
'command.cache.clear' => \Illuminate\Cache\Console\ClearCommand::class,
|
||||
|
|
@ -1526,6 +1526,7 @@ namespace PHPSTORM_META {
|
|||
'Illuminate\Contracts\Pipeline\Hub' => \Illuminate\Pipeline\Hub::class,
|
||||
'Illuminate\Contracts\Queue\EntityResolver' => \Illuminate\Database\Eloquent\QueueEntityResolver::class,
|
||||
'Illuminate\Contracts\Routing\ResponseFactory' => \Illuminate\Routing\ResponseFactory::class,
|
||||
'Illuminate\Contracts\Validation\UncompromisedVerifier' => \Illuminate\Validation\NotPwnedVerifier::class,
|
||||
'Illuminate\Database\Console\DbCommand' => \Illuminate\Database\Console\DbCommand::class,
|
||||
'Illuminate\Foundation\Mix' => \Illuminate\Foundation\Mix::class,
|
||||
'Illuminate\Foundation\PackageManifest' => \Illuminate\Foundation\PackageManifest::class,
|
||||
|
|
@ -1551,7 +1552,6 @@ namespace PHPSTORM_META {
|
|||
'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class,
|
||||
'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class,
|
||||
'cache' => \Illuminate\Cache\CacheManager::class,
|
||||
'cache.dynamodb.client' => \Aws\DynamoDb\DynamoDbClient::class,
|
||||
'cache.store' => \Illuminate\Cache\Repository::class,
|
||||
'command.auth.resets.clear' => \Illuminate\Auth\Console\ClearResetsCommand::class,
|
||||
'command.cache.clear' => \Illuminate\Cache\Console\ClearCommand::class,
|
||||
|
|
@ -1735,6 +1735,7 @@ namespace PHPSTORM_META {
|
|||
'Illuminate\Contracts\Pipeline\Hub' => \Illuminate\Pipeline\Hub::class,
|
||||
'Illuminate\Contracts\Queue\EntityResolver' => \Illuminate\Database\Eloquent\QueueEntityResolver::class,
|
||||
'Illuminate\Contracts\Routing\ResponseFactory' => \Illuminate\Routing\ResponseFactory::class,
|
||||
'Illuminate\Contracts\Validation\UncompromisedVerifier' => \Illuminate\Validation\NotPwnedVerifier::class,
|
||||
'Illuminate\Database\Console\DbCommand' => \Illuminate\Database\Console\DbCommand::class,
|
||||
'Illuminate\Foundation\Mix' => \Illuminate\Foundation\Mix::class,
|
||||
'Illuminate\Foundation\PackageManifest' => \Illuminate\Foundation\PackageManifest::class,
|
||||
|
|
@ -1760,7 +1761,6 @@ namespace PHPSTORM_META {
|
|||
'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class,
|
||||
'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class,
|
||||
'cache' => \Illuminate\Cache\CacheManager::class,
|
||||
'cache.dynamodb.client' => \Aws\DynamoDb\DynamoDbClient::class,
|
||||
'cache.store' => \Illuminate\Cache\Repository::class,
|
||||
'command.auth.resets.clear' => \Illuminate\Auth\Console\ClearResetsCommand::class,
|
||||
'command.cache.clear' => \Illuminate\Cache\Console\ClearCommand::class,
|
||||
|
|
@ -1944,6 +1944,7 @@ namespace PHPSTORM_META {
|
|||
'Illuminate\Contracts\Pipeline\Hub' => \Illuminate\Pipeline\Hub::class,
|
||||
'Illuminate\Contracts\Queue\EntityResolver' => \Illuminate\Database\Eloquent\QueueEntityResolver::class,
|
||||
'Illuminate\Contracts\Routing\ResponseFactory' => \Illuminate\Routing\ResponseFactory::class,
|
||||
'Illuminate\Contracts\Validation\UncompromisedVerifier' => \Illuminate\Validation\NotPwnedVerifier::class,
|
||||
'Illuminate\Database\Console\DbCommand' => \Illuminate\Database\Console\DbCommand::class,
|
||||
'Illuminate\Foundation\Mix' => \Illuminate\Foundation\Mix::class,
|
||||
'Illuminate\Foundation\PackageManifest' => \Illuminate\Foundation\PackageManifest::class,
|
||||
|
|
@ -1969,7 +1970,6 @@ namespace PHPSTORM_META {
|
|||
'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class,
|
||||
'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class,
|
||||
'cache' => \Illuminate\Cache\CacheManager::class,
|
||||
'cache.dynamodb.client' => \Aws\DynamoDb\DynamoDbClient::class,
|
||||
'cache.store' => \Illuminate\Cache\Repository::class,
|
||||
'command.auth.resets.clear' => \Illuminate\Auth\Console\ClearResetsCommand::class,
|
||||
'command.cache.clear' => \Illuminate\Cache\Console\ClearCommand::class,
|
||||
|
|
@ -2153,6 +2153,7 @@ namespace PHPSTORM_META {
|
|||
'Illuminate\Contracts\Pipeline\Hub' => \Illuminate\Pipeline\Hub::class,
|
||||
'Illuminate\Contracts\Queue\EntityResolver' => \Illuminate\Database\Eloquent\QueueEntityResolver::class,
|
||||
'Illuminate\Contracts\Routing\ResponseFactory' => \Illuminate\Routing\ResponseFactory::class,
|
||||
'Illuminate\Contracts\Validation\UncompromisedVerifier' => \Illuminate\Validation\NotPwnedVerifier::class,
|
||||
'Illuminate\Database\Console\DbCommand' => \Illuminate\Database\Console\DbCommand::class,
|
||||
'Illuminate\Foundation\Mix' => \Illuminate\Foundation\Mix::class,
|
||||
'Illuminate\Foundation\PackageManifest' => \Illuminate\Foundation\PackageManifest::class,
|
||||
|
|
@ -2178,7 +2179,6 @@ namespace PHPSTORM_META {
|
|||
'auth.password.broker' => \Illuminate\Auth\Passwords\PasswordBroker::class,
|
||||
'blade.compiler' => \Illuminate\View\Compilers\BladeCompiler::class,
|
||||
'cache' => \Illuminate\Cache\CacheManager::class,
|
||||
'cache.dynamodb.client' => \Aws\DynamoDb\DynamoDbClient::class,
|
||||
'cache.store' => \Illuminate\Cache\Repository::class,
|
||||
'command.auth.resets.clear' => \Illuminate\Auth\Console\ClearResetsCommand::class,
|
||||
'command.cache.clear' => \Illuminate\Cache\Console\ClearCommand::class,
|
||||
|
|
|
|||
206
_ide_helper.php
206
_ide_helper.php
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
/**
|
||||
* A helper file for Laravel, to provide autocomplete information to your IDE
|
||||
* Generated for Laravel 8.38.0.
|
||||
* Generated for Laravel 8.42.1.
|
||||
*
|
||||
* This file should not be included in your code, only analyzed by your IDE!
|
||||
*
|
||||
|
|
@ -989,6 +989,7 @@
|
|||
* @param \Closure|string|null $concrete
|
||||
* @param bool $shared
|
||||
* @return void
|
||||
* @throws \TypeError
|
||||
* @static
|
||||
*/
|
||||
public static function bind($abstract, $concrete = null, $shared = false)
|
||||
|
|
@ -1862,6 +1863,20 @@
|
|||
{
|
||||
/** @var \Illuminate\Auth\SessionGuard $instance */
|
||||
return $instance->attempt($credentials, $remember);
|
||||
}
|
||||
/**
|
||||
* Attempt to authenticate a user with credentials and additional callbacks.
|
||||
*
|
||||
* @param array $credentials
|
||||
* @param array|callable $callbacks
|
||||
* @param false $remember
|
||||
* @return bool
|
||||
* @static
|
||||
*/
|
||||
public static function attemptWhen($credentials = [], $callbacks = null, $remember = false)
|
||||
{
|
||||
/** @var \Illuminate\Auth\SessionGuard $instance */
|
||||
return $instance->attemptWhen($credentials, $callbacks, $remember);
|
||||
}
|
||||
/**
|
||||
* Log the given user ID into the application.
|
||||
|
|
@ -2863,6 +2878,7 @@
|
|||
*
|
||||
* @param mixed $command
|
||||
* @return mixed
|
||||
* @throws \RuntimeException
|
||||
* @static
|
||||
*/
|
||||
public static function dispatchToQueue($command)
|
||||
|
|
@ -2945,6 +2961,45 @@
|
|||
{
|
||||
/** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
|
||||
$instance->assertNotDispatched($command, $callback);
|
||||
}
|
||||
/**
|
||||
* Assert if a job was explicitly dispatched synchronously based on a truth-test callback.
|
||||
*
|
||||
* @param string|\Closure $command
|
||||
* @param callable|int|null $callback
|
||||
* @return void
|
||||
* @static
|
||||
*/
|
||||
public static function assertDispatchedSync($command, $callback = null)
|
||||
{
|
||||
/** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
|
||||
$instance->assertDispatchedSync($command, $callback);
|
||||
}
|
||||
/**
|
||||
* Assert if a job was pushed synchronously a number of times.
|
||||
*
|
||||
* @param string $command
|
||||
* @param int $times
|
||||
* @return void
|
||||
* @static
|
||||
*/
|
||||
public static function assertDispatchedSyncTimes($command, $times = 1)
|
||||
{
|
||||
/** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
|
||||
$instance->assertDispatchedSyncTimes($command, $times);
|
||||
}
|
||||
/**
|
||||
* Determine if a job was dispatched based on a truth-test callback.
|
||||
*
|
||||
* @param string|\Closure $command
|
||||
* @param callable|null $callback
|
||||
* @return void
|
||||
* @static
|
||||
*/
|
||||
public static function assertNotDispatchedSync($command, $callback = null)
|
||||
{
|
||||
/** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
|
||||
$instance->assertNotDispatchedSync($command, $callback);
|
||||
}
|
||||
/**
|
||||
* Assert if a job was dispatched after the response was sent based on a truth-test callback.
|
||||
|
|
@ -3034,6 +3089,19 @@
|
|||
{
|
||||
/** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
|
||||
return $instance->dispatched($command, $callback);
|
||||
}
|
||||
/**
|
||||
* Get all of the jobs dispatched synchronously matching a truth-test callback.
|
||||
*
|
||||
* @param string $command
|
||||
* @param callable|null $callback
|
||||
* @return \Illuminate\Support\Collection
|
||||
* @static
|
||||
*/
|
||||
public static function dispatchedSync($command, $callback = null)
|
||||
{
|
||||
/** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
|
||||
return $instance->dispatchedSync($command, $callback);
|
||||
}
|
||||
/**
|
||||
* Get all of the jobs dispatched after the response was sent matching a truth-test callback.
|
||||
|
|
@ -3079,6 +3147,18 @@
|
|||
* @return bool
|
||||
* @static
|
||||
*/
|
||||
public static function hasDispatchedSync($command)
|
||||
{
|
||||
/** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
|
||||
return $instance->hasDispatchedSync($command);
|
||||
}
|
||||
/**
|
||||
* Determine if there are any stored commands for a given class.
|
||||
*
|
||||
* @param string $command
|
||||
* @return bool
|
||||
* @static
|
||||
*/
|
||||
public static function hasDispatchedAfterResponse($command)
|
||||
{
|
||||
/** @var \Illuminate\Support\Testing\Fakes\BusFake $instance */
|
||||
|
|
@ -4041,6 +4121,20 @@
|
|||
{
|
||||
/** @var \Illuminate\Cookie\CookieJar $instance */
|
||||
$instance->queue(...$parameters);
|
||||
}
|
||||
/**
|
||||
* Queue a cookie to expire with the next response.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $path
|
||||
* @param string|null $domain
|
||||
* @return void
|
||||
* @static
|
||||
*/
|
||||
public static function expire($name, $path = null, $domain = null)
|
||||
{
|
||||
/** @var \Illuminate\Cookie\CookieJar $instance */
|
||||
$instance->expire($name, $path, $domain);
|
||||
}
|
||||
/**
|
||||
* Remove a cookie from the queue.
|
||||
|
|
@ -4374,6 +4468,18 @@
|
|||
{
|
||||
/** @var \Illuminate\Database\DatabaseManager $instance */
|
||||
$instance->setReconnector($reconnector);
|
||||
}
|
||||
/**
|
||||
* Set the application instance used by the manager.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Foundation\Application $app
|
||||
* @return \Illuminate\Database\DatabaseManager
|
||||
* @static
|
||||
*/
|
||||
public static function setApplication($app)
|
||||
{
|
||||
/** @var \Illuminate\Database\DatabaseManager $instance */
|
||||
return $instance->setApplication($app);
|
||||
}
|
||||
/**
|
||||
* Determine if the connected database is a MariaDB database.
|
||||
|
|
@ -5185,6 +5291,7 @@
|
|||
*
|
||||
* @param callable $callback
|
||||
* @return void
|
||||
* @throws \RuntimeException
|
||||
* @static
|
||||
*/
|
||||
public static function afterCommit($callback)
|
||||
|
|
@ -5576,6 +5683,7 @@
|
|||
* @param string $path
|
||||
* @param array $data
|
||||
* @return mixed
|
||||
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
|
||||
* @static
|
||||
*/
|
||||
public static function requireOnce($path, $data = [])
|
||||
|
|
@ -5731,6 +5839,7 @@
|
|||
* @param string $target
|
||||
* @param string $link
|
||||
* @return void
|
||||
* @throws \RuntimeException
|
||||
* @static
|
||||
*/
|
||||
public static function relativeLink($target, $link)
|
||||
|
|
@ -5791,6 +5900,7 @@
|
|||
*
|
||||
* @param string $path
|
||||
* @return string|null
|
||||
* @throws \RuntimeException
|
||||
* @static
|
||||
*/
|
||||
public static function guessExtension($path)
|
||||
|
|
@ -6536,13 +6646,16 @@
|
|||
* @method static \Illuminate\Http\Client\PendingRequest asForm()
|
||||
* @method static \Illuminate\Http\Client\PendingRequest asJson()
|
||||
* @method static \Illuminate\Http\Client\PendingRequest asMultipart()
|
||||
* @method static \Illuminate\Http\Client\PendingRequest attach(string $name, string $contents, string|null $filename = null, array $headers = [])
|
||||
* @method static \Illuminate\Http\Client\PendingRequest async()
|
||||
* @method static \Illuminate\Http\Client\PendingRequest attach(string|array $name, string $contents = '', string|null $filename = null, array $headers = [])
|
||||
* @method static \Illuminate\Http\Client\PendingRequest baseUrl(string $url)
|
||||
* @method static \Illuminate\Http\Client\PendingRequest beforeSending(callable $callback)
|
||||
* @method static \Illuminate\Http\Client\PendingRequest bodyFormat(string $format)
|
||||
* @method static \Illuminate\Http\Client\PendingRequest contentType(string $contentType)
|
||||
* @method static \Illuminate\Http\Client\PendingRequest dd()
|
||||
* @method static \Illuminate\Http\Client\PendingRequest dump()
|
||||
* @method static \Illuminate\Http\Client\PendingRequest retry(int $times, int $sleep = 0)
|
||||
* @method static \Illuminate\Http\Client\PendingRequest sink($to)
|
||||
* @method static \Illuminate\Http\Client\PendingRequest sink(string|resource $to)
|
||||
* @method static \Illuminate\Http\Client\PendingRequest stub(callable $callback)
|
||||
* @method static \Illuminate\Http\Client\PendingRequest timeout(int $seconds)
|
||||
* @method static \Illuminate\Http\Client\PendingRequest withBasicAuth(string $username, string $password)
|
||||
|
|
@ -6550,17 +6663,16 @@
|
|||
* @method static \Illuminate\Http\Client\PendingRequest withCookies(array $cookies, string $domain)
|
||||
* @method static \Illuminate\Http\Client\PendingRequest withDigestAuth(string $username, string $password)
|
||||
* @method static \Illuminate\Http\Client\PendingRequest withHeaders(array $headers)
|
||||
* @method static \Illuminate\Http\Client\PendingRequest withMiddleware(callable $middleware)
|
||||
* @method static \Illuminate\Http\Client\PendingRequest withOptions(array $options)
|
||||
* @method static \Illuminate\Http\Client\PendingRequest withToken(string $token, string $type = 'Bearer')
|
||||
* @method static \Illuminate\Http\Client\PendingRequest withUserAgent(string $userAgent)
|
||||
* @method static \Illuminate\Http\Client\PendingRequest withoutRedirecting()
|
||||
* @method static \Illuminate\Http\Client\PendingRequest withoutVerifying()
|
||||
* @method static \Illuminate\Http\Client\PendingRequest dump()
|
||||
* @method static \Illuminate\Http\Client\PendingRequest dd()
|
||||
* @method static \Illuminate\Http\Client\PendingRequest async()
|
||||
* @method static \Illuminate\Http\Client\Pool pool(callable $callback)
|
||||
* @method static array pool(callable $callback)
|
||||
* @method static \Illuminate\Http\Client\Response delete(string $url, array $data = [])
|
||||
* @method static \Illuminate\Http\Client\Response get(string $url, array $query = [])
|
||||
* @method static \Illuminate\Http\Client\Response head(string $url, array $query = [])
|
||||
* @method static \Illuminate\Http\Client\Response get(string $url, array|string|null $query = null)
|
||||
* @method static \Illuminate\Http\Client\Response head(string $url, array|string|null $query = null)
|
||||
* @method static \Illuminate\Http\Client\Response patch(string $url, array $data = [])
|
||||
* @method static \Illuminate\Http\Client\Response post(string $url, array $data = [])
|
||||
* @method static \Illuminate\Http\Client\Response put(string $url, array $data = [])
|
||||
|
|
@ -6966,6 +7078,7 @@
|
|||
*
|
||||
* @param string $locale
|
||||
* @return void
|
||||
* @throws \InvalidArgumentException
|
||||
* @static
|
||||
*/
|
||||
public static function setLocale($locale)
|
||||
|
|
@ -7334,6 +7447,7 @@
|
|||
*
|
||||
* @param array $config
|
||||
* @return \Swift_Transport
|
||||
* @throws \InvalidArgumentException
|
||||
* @static
|
||||
*/
|
||||
public static function createTransport($config)
|
||||
|
|
@ -10080,7 +10194,7 @@
|
|||
* if the proxy is trusted (see "setTrustedProxies()"), otherwise it returns
|
||||
* the latter (from the "SERVER_PROTOCOL" server parameter).
|
||||
*
|
||||
* @return string
|
||||
* @return string|null
|
||||
* @static
|
||||
*/
|
||||
public static function getProtocolVersion()
|
||||
|
|
@ -11103,8 +11217,8 @@
|
|||
* @method static \Illuminate\Routing\RouteRegistrar middleware(array|string|null $middleware)
|
||||
* @method static \Illuminate\Routing\RouteRegistrar name(string $value)
|
||||
* @method static \Illuminate\Routing\RouteRegistrar namespace(string|null $value)
|
||||
* @method static \Illuminate\Routing\RouteRegistrar prefix(string $prefix)
|
||||
* @method static \Illuminate\Routing\RouteRegistrar where(array $where)
|
||||
* @method static \Illuminate\Routing\RouteRegistrar prefix(string $prefix)
|
||||
* @method static \Illuminate\Routing\RouteRegistrar where(array $where)
|
||||
* @see \Illuminate\Routing\Router
|
||||
*/
|
||||
class Route {
|
||||
|
|
@ -12084,6 +12198,7 @@
|
|||
*
|
||||
* @param string $type
|
||||
* @return void
|
||||
* @throws \InvalidArgumentException
|
||||
* @static
|
||||
*/
|
||||
public static function defaultMorphKeyType($type)
|
||||
|
|
@ -14681,6 +14796,7 @@
|
|||
* @param string $name
|
||||
* @param string|null $content
|
||||
* @return void
|
||||
* @throws \InvalidArgumentException
|
||||
* @static
|
||||
*/
|
||||
public static function slot($name, $content = null)
|
||||
|
|
@ -15197,6 +15313,26 @@
|
|||
{
|
||||
/** @var \Facade\FlareClient\Flare $instance */
|
||||
return $instance->determineVersionUsing($determineVersionCallable);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @static
|
||||
*/
|
||||
public static function reportErrorLevels($reportErrorLevels)
|
||||
{
|
||||
/** @var \Facade\FlareClient\Flare $instance */
|
||||
return $instance->reportErrorLevels($reportErrorLevels);
|
||||
}
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @static
|
||||
*/
|
||||
public static function filterExceptionsUsing($filterExceptionsCallable)
|
||||
{
|
||||
/** @var \Facade\FlareClient\Flare $instance */
|
||||
return $instance->filterExceptionsUsing($filterExceptionsCallable);
|
||||
}
|
||||
/**
|
||||
*
|
||||
|
|
@ -16046,6 +16182,23 @@ namespace {
|
|||
return $instance->simplePaginate($perPage, $columns, $pageName, $page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginate the given query into a cursor paginator.
|
||||
*
|
||||
* @param int|null $perPage
|
||||
* @param array $columns
|
||||
* @param string $cursorName
|
||||
* @param string|null $cursor
|
||||
* @return \Illuminate\Contracts\Pagination\Paginator
|
||||
* @throws \Illuminate\Pagination\CursorPaginationException
|
||||
* @static
|
||||
*/
|
||||
public static function cursorPaginate($perPage = null, $columns = [], $cursorName = 'cursor', $cursor = null)
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $instance */
|
||||
return $instance->cursorPaginate($perPage, $columns, $cursorName, $cursor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a new model and return the instance.
|
||||
*
|
||||
|
|
@ -16138,6 +16291,19 @@ namespace {
|
|||
return $instance->without($relations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the relationships that should be eager loaded while removing any previously added eager loading specifications.
|
||||
*
|
||||
* @param mixed $relations
|
||||
* @return \Illuminate\Database\Eloquent\Builder|static
|
||||
* @static
|
||||
*/
|
||||
public static function withOnly($relations)
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $instance */
|
||||
return $instance->withOnly($relations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the model being queried.
|
||||
*
|
||||
|
|
@ -16646,6 +16812,19 @@ namespace {
|
|||
return $instance->withAvg($relation, $column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add subselect queries to include the existence of related models.
|
||||
*
|
||||
* @param string|array $relation
|
||||
* @return \Illuminate\Database\Eloquent\Builder|static
|
||||
* @static
|
||||
*/
|
||||
public static function withExists($relation)
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $instance */
|
||||
return $instance->withExists($relation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the where constraints from another query to the current query.
|
||||
*
|
||||
|
|
@ -16705,6 +16884,7 @@ namespace {
|
|||
* @param callable $callback
|
||||
* @param int $count
|
||||
* @return bool
|
||||
* @throws \RuntimeException
|
||||
* @static
|
||||
*/
|
||||
public static function each($callback, $count = 1000)
|
||||
|
|
@ -16750,6 +16930,7 @@ namespace {
|
|||
*
|
||||
* @param int $chunkSize
|
||||
* @return \Illuminate\Support\LazyCollection
|
||||
* @throws \InvalidArgumentException
|
||||
* @static
|
||||
*/
|
||||
public static function lazy($chunkSize = 1000)
|
||||
|
|
@ -16765,6 +16946,7 @@ namespace {
|
|||
* @param string|null $column
|
||||
* @param string|null $alias
|
||||
* @return \Illuminate\Support\LazyCollection
|
||||
* @throws \InvalidArgumentException
|
||||
* @static
|
||||
*/
|
||||
public static function lazyById($chunkSize = 1000, $column = null, $alias = null)
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ use App\Http\Requests\UpdateGoalRequest;
|
|||
use App\Models\Goal;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class GoalController extends Controller
|
||||
|
|
@ -15,17 +13,10 @@ class GoalController extends Controller
|
|||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(Request $request): View
|
||||
public function index(): View
|
||||
{
|
||||
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('goals', Goal::whereUserId(Auth::user()->id)->get());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -51,10 +42,7 @@ class GoalController extends Controller
|
|||
*/
|
||||
public function show(Goal $goal): View
|
||||
{
|
||||
return view('goals.show')
|
||||
->with('goal', $goal)
|
||||
->with('nameOptions', Goal::getNameOptions())
|
||||
->with('frequencyOptions', Goal::$frequencyOptions);
|
||||
return view('goals.show')->with('goal', $goal);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -62,10 +50,7 @@ class GoalController extends Controller
|
|||
*/
|
||||
public function edit(Goal $goal): View
|
||||
{
|
||||
return view('goals.edit')
|
||||
->with('goal', $goal)
|
||||
->with('nameOptions', Goal::getNameOptions())
|
||||
->with('frequencyOptions', Goal::$frequencyOptions);
|
||||
return view('goals.edit')->with('goal', $goal);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -74,10 +59,16 @@ class GoalController extends Controller
|
|||
public function update(UpdateGoalRequest $request, Goal $goal): RedirectResponse
|
||||
{
|
||||
$attributes = $request->validated();
|
||||
if (isset($attributes['days'])) {
|
||||
$attributes['days'] = array_sum($attributes['days']);
|
||||
}
|
||||
else if (!empty($goal->days)) {
|
||||
$attributes['days'] = null;
|
||||
}
|
||||
$goal->fill($attributes)->user()->associate(Auth::user());
|
||||
$goal->save();
|
||||
session()->flash('message', "Goal updated!");
|
||||
return redirect()->route('goals.show', $goal);
|
||||
return redirect()->route('goals.index');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\JournalDate;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class JournalDateController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Change the goals for a journal date.
|
||||
*/
|
||||
public function updateGoal(Request $request, JournalDate $journalDate): RedirectResponse
|
||||
{
|
||||
$attributes = $request->validate(['goal' => 'exists:App\Models\Goal,id']);
|
||||
$journalDate->goal()->associate($attributes['goal'])->save();
|
||||
return redirect()->route('journal-entries.index', [
|
||||
'date' => $journalDate->date->format('Y-m-d')
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -8,6 +8,8 @@ namespace App\Http\Controllers;
|
|||
use App\Http\Requests\StoreFromNutrientsJournalEntryRequest;
|
||||
use App\Http\Requests\StoreJournalEntryRequest;
|
||||
use App\Models\Food;
|
||||
use App\Models\Goal;
|
||||
use App\Models\JournalDate;
|
||||
use App\Models\JournalEntry;
|
||||
use App\Models\Recipe;
|
||||
use App\Support\ArrayFormat;
|
||||
|
|
@ -42,25 +44,36 @@ class JournalEntryController extends Controller
|
|||
}
|
||||
|
||||
// Get daily goals data for user.
|
||||
$goals = Auth::user()->getGoalsByTime($date);
|
||||
$dailyGoals = [];
|
||||
foreach (Nutrients::all()->pluck('value') as $nutrient) {
|
||||
$goal = $goals['present']
|
||||
->where('frequency', 'daily')
|
||||
->where('name', $nutrient)
|
||||
->first();
|
||||
if ($goal) {
|
||||
$dailyGoals[$goal->name] = round($sums[$goal->name] / $goal->goal * 100);
|
||||
if ($dailyGoals[$goal->name] > 0) {
|
||||
$dailyGoals[$goal->name] .= '%';
|
||||
$goal = Auth::user()->getGoalByDate($date);
|
||||
$goalProgress = [];
|
||||
if ($goal) {
|
||||
foreach (Nutrients::all()->pluck('value') as $nutrient) {
|
||||
if ($goal->{$nutrient} > 0) {
|
||||
$goalProgress[$nutrient] = round($sums[$nutrient] / $goal->{$nutrient} * 100);
|
||||
$goalProgress[$nutrient] .= '%';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get all goals as options to change for the date.
|
||||
$goalOptions = Goal::whereUserId(Auth::user()->id)
|
||||
->orderBy('name')
|
||||
->get()
|
||||
->map(function (Goal $goal) {
|
||||
return ['value' => $goal->id, 'label' => $goal->name];
|
||||
});
|
||||
|
||||
// Get the associated journal date.
|
||||
// @todo Refactor journal date as a relationship on journal entries.
|
||||
$journalDate = JournalDate::getOrCreateJournalDate(Auth::user(), $date);
|
||||
|
||||
return view('journal-entries.index')
|
||||
->with('entries', $entries)
|
||||
->with('sums', $sums)
|
||||
->with('dailyGoals', $dailyGoals)
|
||||
->with('currentGoal', $goal)
|
||||
->with('goalProgress', $goalProgress)
|
||||
->with('goalOptions', $goalOptions)
|
||||
->with('journalDate', $journalDate)
|
||||
->with('date', $date);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,11 +14,15 @@ class UpdateGoalRequest extends FormRequest
|
|||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'from' => ['nullable', 'date'],
|
||||
'to' => ['nullable', 'date'],
|
||||
'frequency' => ['required', 'string'],
|
||||
'name' => ['required', 'string'],
|
||||
'goal' => ['required', 'numeric', 'min:0'],
|
||||
'days' => ['nullable', 'array'],
|
||||
'days.*' => ['nullable', 'numeric', 'min:0', 'max:64'],
|
||||
'calories' => ['nullable', 'numeric', 'min:0'],
|
||||
'fat' => ['nullable', 'numeric', 'min:0'],
|
||||
'cholesterol' => ['nullable', 'numeric', 'min:0'],
|
||||
'sodium' => ['nullable', 'numeric', 'min:0'],
|
||||
'carbohydrates' => ['nullable', 'numeric', 'min:0'],
|
||||
'protein' => ['nullable', 'numeric', 'min:0'],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class GoalAdapter extends AdapterBase
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $defaultSort = ['-from', '-to'];
|
||||
protected $defaultSort = ['-name'];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ class FoodSchema extends SchemaProvider
|
|||
*/
|
||||
public function getAttributes($resource): array
|
||||
{
|
||||
/** @var \App\Models\Food $resource */
|
||||
return [
|
||||
'slug' => $resource->slug,
|
||||
'name' => $resource->name,
|
||||
|
|
|
|||
|
|
@ -25,12 +25,17 @@ class GoalSchema extends SchemaProvider
|
|||
*/
|
||||
public function getAttributes($resource): array
|
||||
{
|
||||
/** @var \App\Models\Goal $resource */
|
||||
return [
|
||||
'frequency' => $resource->frequency,
|
||||
'from' => $resource->from,
|
||||
'goal' => $resource->goal,
|
||||
'name' => $resource->name,
|
||||
'to' => $resource->to,
|
||||
'days' => $resource->days,
|
||||
'daysFormatted' => $resource->days_formatted,
|
||||
'calories' => $resource->calories,
|
||||
'carbohydrates' => $resource->carbohydrates,
|
||||
'cholesterol' => $resource->cholesterol,
|
||||
'fat' => $resource->fat,
|
||||
'protein' => $resource->protein,
|
||||
'sodium' => $resource->sodium,
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ class IngredientAmountSchema extends SchemaProvider
|
|||
*/
|
||||
public function getAttributes($resource): array
|
||||
{
|
||||
/** @var \App\Models\IngredientAmount $resource */
|
||||
return [
|
||||
'amount' => $resource->amount,
|
||||
'amountFormatted' => $resource->amount_formatted,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ class JournalEntrySchema extends SchemaProvider
|
|||
*/
|
||||
public function getAttributes($resource): array
|
||||
{
|
||||
/** @var \App\Models\JournalEntry $resource */
|
||||
return [
|
||||
'calories' => $resource->calories,
|
||||
'carbohydrates' => $resource->carbohydrates,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ class RecipeSchema extends SchemaProvider
|
|||
*/
|
||||
public function getAttributes($resource): array
|
||||
{
|
||||
/** @var \App\Models\Recipe $resource */
|
||||
return [
|
||||
'slug' => $resource->slug,
|
||||
'name' => $resource->name,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ class RecipeSeparatorSchema extends SchemaProvider
|
|||
*/
|
||||
public function getAttributes($resource): array
|
||||
{
|
||||
/** @var \App\Models\RecipeSeparator $resource */
|
||||
return [
|
||||
'container' => $resource->container,
|
||||
'weight' => $resource->weight,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ class RecipeStepSchema extends SchemaProvider
|
|||
*/
|
||||
public function getAttributes($resource): array
|
||||
{
|
||||
/** @var \App\Models\RecipeStep $resource */
|
||||
return [
|
||||
'number' => $resource->number,
|
||||
'step' => $resource->step,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ class TagSchema extends SchemaProvider
|
|||
*/
|
||||
public function getAttributes($resource): array
|
||||
{
|
||||
/** @var \App\Models\Tag $resource */
|
||||
return [
|
||||
'name' => $resource->name,
|
||||
'slug' => $resource->slug,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ class UserSchema extends SchemaProvider
|
|||
*/
|
||||
public function getAttributes($resource): array
|
||||
{
|
||||
/** @var \App\Models\User $resource */
|
||||
return [
|
||||
'username' => $resource->username,
|
||||
'name' => $resource->name,
|
||||
|
|
|
|||
|
|
@ -2,82 +2,151 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Support\Nutrients;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* App\Models\Goal
|
||||
*
|
||||
* @property int $id
|
||||
* @property int $user_id
|
||||
* @property \datetime|null $from
|
||||
* @property \datetime|null $to
|
||||
* @property string|null $frequency
|
||||
* @property int $days
|
||||
* @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 float|null $calories
|
||||
* @property float|null $fat
|
||||
* @property float|null $cholesterol
|
||||
* @property float|null $sodium
|
||||
* @property float|null $carbohydrates
|
||||
* @property float|null $protein
|
||||
* @property-read \App\Models\User $user
|
||||
* @method static \Database\Factories\GoalFactory factory(...$parameters)
|
||||
* @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 whereCalories($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Goal whereCarbohydrates($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Goal whereCholesterol($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 whereDays($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Goal whereFat($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 whereProtein($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Goal whereSodium($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)
|
||||
* @mixin \Eloquent
|
||||
* @method static \Database\Factories\GoalFactory factory(...$parameters)
|
||||
* @property-read array $days_formatted
|
||||
*/
|
||||
final class Goal extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* Supported options for thr frequency attribute.
|
||||
*/
|
||||
public static array $frequencyOptions = [
|
||||
'daily' => [
|
||||
'value' => 'daily',
|
||||
'label' => 'daily'
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected $fillable = [
|
||||
'frequency',
|
||||
'from',
|
||||
'goal',
|
||||
'name',
|
||||
'to',
|
||||
// Bitwise field: mon=1, tue=2, wed=4, thu=8, fri=16, sat=32, sun=64.
|
||||
'days',
|
||||
'calories',
|
||||
'carbohydrates',
|
||||
'cholesterol',
|
||||
'fat',
|
||||
'protein',
|
||||
'sodium',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected $casts = [
|
||||
'from' => 'datetime:Y-m-d',
|
||||
'goal' => 'float',
|
||||
'to' => 'datetime:Y-m-d',
|
||||
'days' => 'int',
|
||||
'calories' => 'float',
|
||||
'carbohydrates' => 'float',
|
||||
'cholesterol' => 'float',
|
||||
'fat' => 'float',
|
||||
'protein' => 'float',
|
||||
'sodium' => 'float',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected $appends = [
|
||||
'summary',
|
||||
'days_formatted',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the days for the goals as strings in array keyed by dow.
|
||||
*/
|
||||
public function getDaysFormattedAttribute(): Collection {
|
||||
if (empty($this->days)) {
|
||||
return new Collection([]);
|
||||
}
|
||||
return self::days()->filter(function ($day) {
|
||||
if (($this->days & $day['value']) != 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all supported days and metadata.
|
||||
*
|
||||
* Each entry has the following keys:
|
||||
* - value: Day value (used for bitwise operations).
|
||||
* - label: Human-readable name for the day.
|
||||
* - dow: ISO-8601 numeric representation of the day of the week.
|
||||
*/
|
||||
public static function days(): Collection
|
||||
{
|
||||
return new Collection([
|
||||
[
|
||||
'value' => 1,
|
||||
'label' => 'monday',
|
||||
'dow' => 1,
|
||||
],
|
||||
[
|
||||
'value' => 2,
|
||||
'label' => 'tuesday',
|
||||
'dow' => 2,
|
||||
],
|
||||
[
|
||||
'value' => 4,
|
||||
'label' => 'wednesday',
|
||||
'dow' => 3,
|
||||
],
|
||||
[
|
||||
'value' => 8,
|
||||
'label' => 'thursday',
|
||||
'dow' => 4,
|
||||
],
|
||||
[
|
||||
'value' => 16,
|
||||
'label' => 'friday',
|
||||
'dow' => 5,
|
||||
],
|
||||
[
|
||||
'value' => 32,
|
||||
'label' => 'saturday',
|
||||
'dow' => 6,
|
||||
],
|
||||
[
|
||||
'value' => 64,
|
||||
'label' => 'sunday',
|
||||
'dow' => 7,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User this goal belongs to.
|
||||
*/
|
||||
|
|
@ -85,23 +154,4 @@ 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 "name" column.
|
||||
*/
|
||||
public static function getNameOptions(): array {
|
||||
$options = [];
|
||||
foreach (Nutrients::all() as $nutrient) {
|
||||
$options[$nutrient['value']] = [
|
||||
'value' => $nutrient['value'],
|
||||
'label' => Str::ucfirst($nutrient['label']),
|
||||
'unit' => $nutrient['unit'],
|
||||
];
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,8 +150,6 @@ final class IngredientAmount extends Model
|
|||
* @param array $parameters
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @noinspection PhpMissingParamTypeInspection
|
||||
*/
|
||||
public function __call($method, $parameters): mixed {
|
||||
if (in_array($method, $this->nutrientMethods)) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
/**
|
||||
* App\Models\JournalDate
|
||||
*
|
||||
* @property int $id
|
||||
* @property \datetime $date
|
||||
* @property int $user_id
|
||||
* @property int|null $goal_id
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property-read \App\Models\Goal|null $goal
|
||||
* @property-read \App\Models\User $user
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|JournalDate newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|JournalDate newQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|JournalDate query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|JournalDate whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|JournalDate whereDate($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|JournalDate whereGoalId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|JournalDate whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|JournalDate whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|JournalDate whereUserId($value)
|
||||
* @mixin \Eloquent
|
||||
* @method static \Database\Factories\JournalDateFactory factory(...$parameters)
|
||||
*/
|
||||
final class JournalDate extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected $fillable = [
|
||||
'date',
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected $casts = [
|
||||
'date' => 'datetime:Y-m-d',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the Goal for this date.
|
||||
*/
|
||||
public function goal(): BelongsTo {
|
||||
return $this->belongsTo(Goal::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User this journal date belongs to.
|
||||
*/
|
||||
public function user(): BelongsTo {
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a journal date for a user and date, creating a new one if necessary.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* User.
|
||||
* @param \Illuminate\Support\Carbon $date
|
||||
* Date.
|
||||
*
|
||||
* @return \App\Models\JournalDate
|
||||
* Journal date for provided user and date.
|
||||
*/
|
||||
public static function getOrCreateJournalDate(User $user, Carbon $date): JournalDate {
|
||||
/** @var \App\Models\JournalDate $journal_date */
|
||||
$journal_date = $user->journalDates()->whereDate('date', '=', $date)->first();
|
||||
if (empty($journal_date)) {
|
||||
$journal_date = JournalDate::make(['date' => $date])->user()->associate($user);
|
||||
}
|
||||
return $journal_date;
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,6 @@ 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;
|
||||
use Spatie\MediaLibrary\HasMedia;
|
||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||
|
|
@ -50,6 +49,8 @@ use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
|||
* @method static \Illuminate\Database\Eloquent\Builder|User whereSlug($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|User withUniqueSlugConstraints(\Illuminate\Database\Eloquent\Model $model, string $attribute, array $config, string $slug)
|
||||
* @mixin \Eloquent
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\JournalDate[] $journalDates
|
||||
* @property-read int|null $journal_dates_count
|
||||
*/
|
||||
final class User extends Authenticatable implements HasMedia
|
||||
{
|
||||
|
|
@ -98,6 +99,13 @@ final class User extends Authenticatable implements HasMedia
|
|||
return $this->hasMany(Goal::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User's journal dates.
|
||||
*/
|
||||
public function journalDates(): HasMany {
|
||||
return $this->hasMany(JournalDate::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the User's journal entries.
|
||||
*/
|
||||
|
|
@ -106,30 +114,33 @@ final class User extends Authenticatable implements HasMedia
|
|||
}
|
||||
|
||||
/**
|
||||
* Get User's past, present, and future goals.
|
||||
* Get user's goal (if one exists) for a specific date.
|
||||
*
|
||||
* @return \App\Models\Goal[]
|
||||
* The primary use for a JournalDate entry right now is the goal so this
|
||||
* method also creates a JournalDate if one does not already exist.
|
||||
*/
|
||||
public function getGoalsByTime(?Carbon $date = null): array {
|
||||
$now = $date ?? Carbon::now();
|
||||
$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)) {
|
||||
$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;
|
||||
public function getGoalByDate(Carbon $date): ?Goal {
|
||||
$journal_date = JournalDate::getOrCreateJournalDate($this, $date);
|
||||
if ($journal_date->goal) {
|
||||
return $journal_date->goal;
|
||||
}
|
||||
|
||||
// Check for a goal based on day of week configurations.
|
||||
$day = Goal::days()->firstWhere('dow', $date->format('N'));
|
||||
if (!$day) {
|
||||
throw new \BadMethodCallException("No day with `dow` value {$date->format('N')}.");
|
||||
}
|
||||
/** @var \App\Models\Goal $goal */
|
||||
$goal = $this->goals()->whereRaw("(days & {$day['value']}) != 0")->first();
|
||||
if (!empty($goal)) {
|
||||
$journal_date->goal()->associate($goal);
|
||||
}
|
||||
|
||||
if ($journal_date->hasChanges(['date', 'goal'])) {
|
||||
$journal_date->save();
|
||||
}
|
||||
|
||||
return $goal;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -13,13 +13,11 @@ class Nutrients
|
|||
/**
|
||||
* Get all supported units and metadata.
|
||||
*
|
||||
* Each entry has two keys:
|
||||
* Each entry has the following keys:
|
||||
* - value: Machine name for the unit.
|
||||
* - label: Human-readable name for the unit.
|
||||
* - plural: Human-readable plural form of the unit name.
|
||||
* - type: Unit type -- matching types can be converted.
|
||||
*
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public static function units(): Collection {
|
||||
return new Collection([
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -3,6 +3,7 @@
|
|||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Goal;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class GoalFactory extends Factory
|
||||
|
|
@ -15,16 +16,18 @@ class GoalFactory extends Factory
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function definition()
|
||||
public function definition(): array
|
||||
{
|
||||
$from = $this->faker->dateTimeThisMonth;
|
||||
$to = $this->faker->dateTimeBetween($from, '+1 year');
|
||||
return [
|
||||
'from' => $this->faker->randomElement([$from, null]),
|
||||
'to' => $this->faker->randomElement([$to, null]),
|
||||
'frequency' => $this->faker->randomElement(Goal::$frequencyOptions)['value'],
|
||||
'name' => $this->faker->randomElement(Goal::getNameOptions())['value'],
|
||||
'goal' => $this->faker->numberBetween(0, 2000),
|
||||
'user_id' => User::factory(),
|
||||
'name' => $this->faker->words(asText: true),
|
||||
'days' => $this->faker->numberBetween(1, Goal::days()->pluck('value')->sum()),
|
||||
'calories' => $this->faker->numberBetween(1600, 2500),
|
||||
'fat' => $this->faker->numberBetween(40, 90),
|
||||
'cholesterol' => $this->faker->numberBetween(int2: 500),
|
||||
'sodium' => $this->faker->numberBetween(int2: 3000),
|
||||
'carbohydrates' => $this->faker->numberBetween(50, 100),
|
||||
'protein' => $this->faker->numberBetween(90, 200),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Goal;
|
||||
use App\Models\JournalDate;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class JournalDateFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $model = JournalDate::class;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'date' => $this->faker->dateTimeThisMonth,
|
||||
'user_id' => User::factory(),
|
||||
'goal_id' => Goal::factory(),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -21,6 +21,7 @@ class DatabaseSeeder extends Seeder
|
|||
*/
|
||||
public function run(): void
|
||||
{
|
||||
/** @var \App\Models\User $user */
|
||||
$user = User::factory()->admin()->create([
|
||||
'username' => 'kcal',
|
||||
'password' => Hash::make('kcal'),
|
||||
|
|
@ -28,15 +29,8 @@ class DatabaseSeeder extends Seeder
|
|||
'remember_token' => Str::random(10),
|
||||
]);
|
||||
|
||||
$goals = [];
|
||||
foreach (Nutrients::all() as $nutrient) {
|
||||
$goals[] = [
|
||||
'frequency' => 'daily',
|
||||
'name' => $nutrient['value'],
|
||||
'goal' => $nutrient['rdi'],
|
||||
];
|
||||
}
|
||||
Goal::factory()->for($user)->createMany($goals);
|
||||
// Goals will probably overlap but that's OK.
|
||||
Goal::factory()->for($user)->count(3)->create();
|
||||
|
||||
$foods = Food::factory()->count(100)->create();
|
||||
$recipes = Recipe::factory()
|
||||
|
|
|
|||
|
|
@ -17,11 +17,14 @@ class CreateGoalsTable extends Migration
|
|||
Schema::create('goals', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignIdFor(User::class)->constrained()->cascadeOnUpdate()->cascadeOnDelete();
|
||||
$table->date('from')->nullable();
|
||||
$table->date('to')->nullable();
|
||||
$table->string('frequency')->nullable();
|
||||
$table->string('name');
|
||||
$table->unsignedFloat('goal');
|
||||
$table->unsignedTinyInteger('days')->nullable();
|
||||
$table->unsignedFloat('calories')->nullable();
|
||||
$table->unsignedFloat('fat')->nullable();
|
||||
$table->unsignedFloat('cholesterol')->nullable();
|
||||
$table->unsignedFloat('sodium')->nullable();
|
||||
$table->unsignedFloat('carbohydrates')->nullable();
|
||||
$table->unsignedFloat('protein')->nullable();
|
||||
$table->timestamps();
|
||||
$table->index('user_id');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Goal;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateJournalDatesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('journal_dates', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->date('date')->useCurrent();
|
||||
$table->foreignIdFor(User::class)->constrained()->cascadeOnUpdate()->cascadeOnDelete();
|
||||
$table->foreignIdFor(Goal::class)->nullable()->constrained()->cascadeOnUpdate()->cascadeOnDelete();
|
||||
$table->timestamps();
|
||||
$table->unique(['date', 'user_id']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('journal_dates');
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
|
|
@ -16,16 +16,16 @@
|
|||
"autoprefixer": "^10.2.5",
|
||||
"axios": "^0.21.1",
|
||||
"cross-env": "^7.0",
|
||||
"laravel-mix": "^6.0.16",
|
||||
"laravel-mix": "^6.0.19",
|
||||
"lodash": "^4.17.21",
|
||||
"postcss-import": "^14.0.1",
|
||||
"postcss-import": "^14.0.2",
|
||||
"quill": "^1.3.7",
|
||||
"resolve-url-loader": "^3.1.2",
|
||||
"tailwindcss": "^2.1.1",
|
||||
"resolve-url-loader": "^4.0.0",
|
||||
"tailwindcss": "^2.1.2",
|
||||
"vue-template-compiler": "^2.6.12"
|
||||
},
|
||||
"dependencies": {
|
||||
"@shopify/draggable": "^1.0.0-beta.12",
|
||||
"alpine-magic-helpers": "^1.2.0"
|
||||
"alpine-magic-helpers": "^1.2.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -15,7 +15,8 @@
|
|||
'disabled:opacity-25',
|
||||
'transition',
|
||||
'ease-in-out',
|
||||
'duration-150'
|
||||
'duration-150',
|
||||
'cursor-pointer',
|
||||
];
|
||||
@endphp
|
||||
<a {{ $attributes->merge(['class' => implode(' ', $classes)]) }}>
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@
|
|||
<a href="{{ $model->getFirstMedia()->getFullUrl() }}" target="_blank">
|
||||
{{ $model->getFirstMedia()($previewName) }}
|
||||
</a>
|
||||
<fieldset class="flex space-x-2 mt-1 items-center">
|
||||
<x-inputs.label for="remove_image" class="text-red-800" value="Remove this image" />
|
||||
<x-inputs.label class="inline-flex items-center">
|
||||
<x-inputs.input type="checkbox" name="remove_image" value="1" />
|
||||
</fieldset>
|
||||
<span class="ml-2 text-red-800">Remove this image</span>
|
||||
</x-inputs.label>
|
||||
</div>
|
||||
@endif
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -9,61 +9,47 @@
|
|||
@csrf
|
||||
<div class="flex flex-col space-y-4">
|
||||
<div class="flex flex-col space-y-4 md:flex-row md:space-x-4 md:space-y-0">
|
||||
<!-- From -->
|
||||
<!-- Name -->
|
||||
<div class="flex-auto">
|
||||
<x-inputs.label for="from" value="From"/>
|
||||
<x-inputs.input name="from"
|
||||
type="date"
|
||||
class="block w-full"
|
||||
:value="old('from', $goal->from?->toDateString())"
|
||||
:hasError="$errors->has('from')" />
|
||||
</div>
|
||||
<x-inputs.label for="name" value="Name" />
|
||||
|
||||
<!-- To -->
|
||||
<div class="flex-auto">
|
||||
<x-inputs.label for="to" value="To"/>
|
||||
<x-inputs.input name="to"
|
||||
type="date"
|
||||
class="block w-full"
|
||||
:value="old('to', $goal->to?->toDateString())"
|
||||
:hasError="$errors->has('to')" />
|
||||
</div>
|
||||
|
||||
<!-- Frequency -->
|
||||
<div class="flex-auto">
|
||||
<x-inputs.label for="frequency" value="Frequency" />
|
||||
<x-inputs.select name="frequency"
|
||||
class="block w-full"
|
||||
:options="$frequencyOptions"
|
||||
:selectedValue="old('frequency', $goal->frequency)"
|
||||
:hasError="$errors->has('frequency')">
|
||||
</x-inputs.select>
|
||||
</div>
|
||||
|
||||
<!-- Trackable -->
|
||||
<div class="flex-auto">
|
||||
<x-inputs.label for="name" value="Trackable" />
|
||||
<x-inputs.select name="name"
|
||||
class="block w-full"
|
||||
:options="$nameOptions"
|
||||
:selectedValue="old('name', $goal->name)"
|
||||
:hasError="$errors->has('name')"
|
||||
required>
|
||||
</x-inputs.select>
|
||||
</div>
|
||||
|
||||
<!-- Goal -->
|
||||
<div class="flex-auto">
|
||||
<x-inputs.label for="goal" value="Goal" />
|
||||
<x-inputs.input name="goal"
|
||||
type="number"
|
||||
step="any"
|
||||
class="block w-full"
|
||||
:value="old('goal', $goal->goal)"
|
||||
:hasError="$errors->has('goal')"
|
||||
<x-inputs.input name="name"
|
||||
type="text"
|
||||
class="block mt-1 w-full"
|
||||
:value="old('name', $goal->name)"
|
||||
required />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col space-y-4 md:flex-row md:space-x-4 md:space-y-0">
|
||||
<!-- Days of the week -->
|
||||
<fieldset>
|
||||
<legend class="block font-medium text-sm text-gray-700">Days of the week</legend>
|
||||
<div class="flex flex-col justify-content divide-x border rounded-md shadow-sm border-gray-300 md:inline-flex md:flex-row">
|
||||
@foreach(\App\Models\Goal::days() as $day)
|
||||
<x-inputs.label class="inline-flex justify-center p-2">
|
||||
<x-inputs.input type="checkbox" name="days[]" :value="$day['value']" :checked="($goal->days & $day['value']) != 0" />
|
||||
<span class="ml-2">{{ \Illuminate\Support\Str::ucfirst($day['label']) }}</span>
|
||||
</x-inputs.label>
|
||||
@endforeach
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="flex flex-col space-y-4 md:flex-row md:space-y-0">
|
||||
@foreach (\App\Support\Nutrients::all()->sortBy('weight') as $nutrient)
|
||||
<!-- {{ ucfirst($nutrient['value']) }} -->
|
||||
<div class="flex-auto">
|
||||
<x-inputs.label for="{{ $nutrient['value'] }}"
|
||||
:value="ucfirst($nutrient['value']) . ($nutrient['unit'] ? ' (' . $nutrient['unit'] . ')' : '')"/>
|
||||
|
||||
<x-inputs.input name="{{ $nutrient['value'] }}"
|
||||
type="number"
|
||||
step="any"
|
||||
class="block w-full mt-1 md:w-5/6"
|
||||
:value="old($nutrient['value'], $goal->{$nutrient['value']})"
|
||||
:hasError="$errors->has($nutrient['value'])"/>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-end mt-4">
|
||||
|
|
|
|||
|
|
@ -1,63 +1,53 @@
|
|||
<x-app-layout>
|
||||
<x-slot name="title">My Goals - {{ $date->format('D, j M Y') }}</x-slot>
|
||||
<x-slot name="title">My Goals</x-slot>
|
||||
<x-slot name="header">
|
||||
<div class="flex justify-between items-center">
|
||||
<h1 class="leading-tight text-center">
|
||||
<div class="text-2xl font-semibold text-gray-800">My 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">
|
||||
<form x-data method="GET" action="{{ route('goals.index') }}">
|
||||
<x-inputs.input name="date"
|
||||
type="date"
|
||||
class="border-0 shadow-none p-0 text-center"
|
||||
:value="$date->toDateString()"
|
||||
x-on:change="$el.submit();"
|
||||
required />
|
||||
</form>
|
||||
</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>
|
||||
</h1>
|
||||
<h1 class="font-semibold text-2xl text-gray-800 leading-tight">My Goals</h1>
|
||||
<x-button-link.green href="{{ route('goals.create') }}" class="text-sm">
|
||||
Add Goal
|
||||
</x-button-link.green>
|
||||
</div>
|
||||
</x-slot>
|
||||
<div class="space-y-4">
|
||||
@forelse($goals['present'] as $goal)
|
||||
<div class="flex space-x-2 items-center">
|
||||
<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 class="text-lg font-bold">{{ $goal->summary }}</div>
|
||||
</div>
|
||||
@empty
|
||||
<div>No goals set.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
<table class="w-full table-fixed">
|
||||
<thead>
|
||||
<tr class="bg-gray-200 text-gray-600 uppercase text-sm leading-normal">
|
||||
<th class="py-3 px-6 text-left">Name</th>
|
||||
<th class="hidden py-3 px-6 text-left lg:table-cell">Days of Week</th>
|
||||
<th class="hidden py-3 px-6 text-left sm:table-cell">Total Calories</th>
|
||||
<th class="py-3 px-6 text-left">Operations</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($goals as $goal)
|
||||
<tr class="border-b border-gray-200">
|
||||
<td class="py-3 px-6">
|
||||
<a class="text-gray-500 hover:text-gray-700 hover:border-gray-300"
|
||||
href="{{ route('goals.show', $goal) }}">
|
||||
{{ $goal->name }}
|
||||
</a>
|
||||
</td>
|
||||
<td class="hidden py-3 px-6 lg:table-cell">
|
||||
@empty($goal->days_formatted->count())
|
||||
<em>none</em>
|
||||
@else
|
||||
{{ $goal->days_formatted->pluck('label')->join(', ') }}
|
||||
@endempty
|
||||
</td>
|
||||
<td class="hidden py-3 px-6 sm:table-cell">
|
||||
{{ number_format($goal->calories) }}
|
||||
</td>
|
||||
<td class="py-3 px-6">
|
||||
<div class="flex flex-col space-y-2 justify-start sm:flex-row sm:space-x-2 sm:space-y-0">
|
||||
<x-button-link.gray href="{{ route('goals.edit', $goal) }}">
|
||||
Edit
|
||||
</x-button-link.gray>
|
||||
<x-button-link.red href="{{ route('goals.delete', $goal) }}">
|
||||
Delete
|
||||
</x-button-link.red>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</x-app-layout>
|
||||
|
|
|
|||
|
|
@ -1,33 +1,67 @@
|
|||
<x-app-layout>
|
||||
<x-slot name="title">Goal</x-slot>
|
||||
<x-slot name="title">{{ $goal->name }}</x-slot>
|
||||
<x-slot name="header">
|
||||
<h1 class="font-semibold text-xl text-gray-800 leading-tight flex flex-auto">
|
||||
{{ $goal->summary }}
|
||||
<a class="ml-2 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="h-6 w-6 text-red-500 hover:text-red-700 hover:border-red-300 float-right text-sm"
|
||||
href="{{ route('goals.delete', $goal) }}">
|
||||
<svg 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>
|
||||
<h1 class="font-semibold text-xl text-gray-800 leading-tight flex flex-auto items-center">
|
||||
{{ $goal->name }}
|
||||
</h1>
|
||||
</x-slot>
|
||||
<div class="grid grid-cols-2 gap-y-1 gap-x-3 max-w-md inline-grid">
|
||||
<div class="font-bold">From</div>
|
||||
<div>{{ $goal->from?->toDateString() ?? 'Any' }}</div>
|
||||
<div class="font-bold">To</div>
|
||||
<div>{{ $goal->to?->toDateString() ?? 'Any' }}</div>
|
||||
<div class="font-bold">Frequency</div>
|
||||
<div>{{ \Illuminate\Support\Str::ucfirst($frequencyOptions[$goal->frequency]['label']) }}</div>
|
||||
<div class="font-bold">Trackable</div>
|
||||
<div>{{ \Illuminate\Support\Str::ucfirst($nameOptions[$goal->name]['label']) }}</div>
|
||||
<div class="font-bold">Goal</div>
|
||||
<div>{{ $goal->goal }}{{ $nameOptions[$goal->name]['unit'] }}</div>
|
||||
<div class="flex flex-col-reverse justify-between pb-4 md:flex-row md:space-x-4">
|
||||
<div class="flex-1">
|
||||
<section>
|
||||
Default goal <span class="font-bold">{{ $goal->days_formatted->count() }}</span> days per week.
|
||||
@if($goal->days_formatted->count() > 1)
|
||||
<ul class="list-disc list-inside pt-2">
|
||||
@foreach($goal->days_formatted->pluck('label') as $day)
|
||||
<li>{{ \Illuminate\Support\Str::ucfirst($day) }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
</section>
|
||||
</div>
|
||||
<aside class="flex flex-col space-y-4 mt-8 sm:mt-0 sm:max-w-xs">
|
||||
<section class="p-1 border-2 border-black font-sans md:w-72">
|
||||
<h1 class="text-3xl font-extrabold leading-none border-b-8 border-black">Goals</h1>
|
||||
<h2 class="font-bold text-right">Amount per day</h2>
|
||||
<section class="flex justify-between items-end font-extrabold">
|
||||
<h1 class="text-3xl">Calories</h1>
|
||||
<div class="text-4xl">{{ number_format($goal->calories) }}</div>
|
||||
</section>
|
||||
<div class="border-t-4 border-black text-sm">
|
||||
<hr class="border-gray-500"/>
|
||||
<section class="flex justify-between">
|
||||
<h1 class="font-bold">Total Fat</h1>
|
||||
<div>{{ number_format($goal->fat) }}g</div>
|
||||
</section>
|
||||
<hr class="border-gray-500"/>
|
||||
<section class="flex justify-between">
|
||||
<h1 class="font-bold">Cholesterol</h1>
|
||||
<div>{{ number_format($goal->cholesterol) }}mg</div>
|
||||
</section>
|
||||
<hr class="border-gray-500"/>
|
||||
<section class="flex justify-between">
|
||||
<h1 class="font-bold">Sodium</h1>
|
||||
<div>{{ number_format($goal->sodium) }}mg</div>
|
||||
</section>
|
||||
<hr class="border-gray-500"/>
|
||||
<section class="flex justify-between">
|
||||
<h1 class="font-bold">Total Carbohydrate</h1>
|
||||
<div>{{ number_format($goal->carbohydrates) }}g</div>
|
||||
</section>
|
||||
<hr class="border-gray-500"/>
|
||||
<section class="flex justify-between">
|
||||
<h1 class="font-bold">Protein</h1>
|
||||
<div>{{ number_format($goal->protein) }}g</div>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
<section class="flex flex-row space-x-2 justify-around md:flex-col md:space-y-2 md:space-x-0">
|
||||
<x-button-link.gray href="{{ route('goals.edit', $goal) }}">
|
||||
Edit Goal
|
||||
</x-button-link.gray>
|
||||
<x-button-link.red href="{{ route('goals.delete', $goal) }}">
|
||||
Delete Goal
|
||||
</x-button-link.red>
|
||||
</section>
|
||||
</aside>
|
||||
</div>
|
||||
</x-app-layout>
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@
|
|||
</svg>
|
||||
</x-inputs.icon-green>
|
||||
<div class="flex items-center justify-end mt-4 space-x-4">
|
||||
<fieldset class="flex space-x-2">
|
||||
<x-inputs.input name="group_entries" type="checkbox" class="h-5 w-5" value="1" />
|
||||
<x-inputs.label for="groupEntries" value="Group entries by day and meal" />
|
||||
</fieldset>
|
||||
<x-inputs.label class="inline-flex items-center">
|
||||
<x-inputs.input type="checkbox" name="group_entries" class="h-5 w-5" value="1" />
|
||||
<span class="ml-2">Group entries by day and meal</span>
|
||||
</x-inputs.label>
|
||||
<x-inputs.button x-on:click="removeTemplate($el);">Add entries</x-inputs.button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@
|
|||
<span class="text-lg">{{ number_format($sums['calories']) }}</span>
|
||||
</div>
|
||||
<div class="font-extrabold text-right text-lg">
|
||||
{{ $dailyGoals['calories'] ?? 'N/A' }}
|
||||
{{ $goalProgress['calories'] ?? 'N/A' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between items-baseline border-b border-gray-300 text-sm">
|
||||
|
|
@ -60,7 +60,7 @@
|
|||
{{ number_format($sums['fat']) }}g
|
||||
</div>
|
||||
<div class="text-right">
|
||||
{{ $dailyGoals['fat'] ?? 'N/A' }}
|
||||
{{ $goalProgress['fat'] ?? 'N/A' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between items-baseline border-b border-gray-300 text-sm">
|
||||
|
|
@ -69,7 +69,7 @@
|
|||
{{ number_format($sums['cholesterol']) }}mg
|
||||
</div>
|
||||
<div class="text-right">
|
||||
{{ $dailyGoals['cholesterol'] ?? 'N/A' }}
|
||||
{{ $goalProgress['cholesterol'] ?? 'N/A' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between items-baseline border-b border-gray-300 text-sm">
|
||||
|
|
@ -78,7 +78,7 @@
|
|||
{{ number_format($sums['sodium']) }}mg
|
||||
</div>
|
||||
<div class="text-right">
|
||||
{{ $dailyGoals['sodium'] ?? 'N/A' }}
|
||||
{{ $goalProgress['sodium'] ?? 'N/A' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between items-baseline border-b border-gray-300 text-sm">
|
||||
|
|
@ -87,7 +87,7 @@
|
|||
{{ number_format($sums['carbohydrates']) }}g
|
||||
</div>
|
||||
<div class="text-right">
|
||||
{{ $dailyGoals['carbohydrates'] ?? 'N/A' }}
|
||||
{{ $goalProgress['carbohydrates'] ?? 'N/A' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between items-baseline text-sm">
|
||||
|
|
@ -96,9 +96,43 @@
|
|||
{{ number_format($sums['protein']) }}g
|
||||
</div>
|
||||
<div class="text-right">
|
||||
{{ $dailyGoals['protein'] ?? 'N/A' }}
|
||||
{{ $goalProgress['protein'] ?? 'N/A' }}
|
||||
</div>
|
||||
</div>
|
||||
<section class="pt-2" x-data="{ showGoalChangeForm: false }">
|
||||
<h4 class="font-semibold text-lg">
|
||||
Goal
|
||||
<span class="text-sm text-gray-500 hover:text-gray-700 hover:border-gray-300 font-normal cursor-pointer"
|
||||
x-show="!showGoalChangeForm"
|
||||
x-on:click="showGoalChangeForm = !showGoalChangeForm">[change]</span>
|
||||
</h4>
|
||||
<div x-show="!showGoalChangeForm">
|
||||
@empty($currentGoal)
|
||||
<div class="italic">No goal.</div>
|
||||
@else
|
||||
<a class="text-gray-500 hover:text-gray-700 hover:border-gray-300"
|
||||
href="{{ route('goals.show', $currentGoal) }}">
|
||||
{{ $currentGoal->name }}
|
||||
</a>
|
||||
@endempty
|
||||
</div>
|
||||
<div x-show="showGoalChangeForm">
|
||||
<form method="POST" action="{{ route('journal-dates.update.goal', $journalDate) }}">
|
||||
@csrf
|
||||
<x-inputs.select name="goal"
|
||||
class="block w-full"
|
||||
:options="$goalOptions ?? []"
|
||||
:selectedValue="$currentGoal?->id ?? null">
|
||||
</x-inputs.select>
|
||||
<div class="flex items-center justify-start mt-4">
|
||||
<x-inputs.button class="bg-green-800 hover:bg-green-700">Change Goal</x-inputs.button>
|
||||
<x-button-link.red class="ml-3" x-on:click="showGoalChangeForm = !showGoalChangeForm">
|
||||
Cancel
|
||||
</x-button-link.red>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="w-full sm:w-3/5 md:w-2/3 lg:w-3/4 flex flex-col space-y-4">
|
||||
@foreach(['breakfast', 'lunch', 'dinner', 'snacks'] as $meal)
|
||||
|
|
@ -110,9 +144,9 @@
|
|||
</div>
|
||||
<span class="text-sm text-gray-500">
|
||||
@foreach(\App\Support\Nutrients::all()->sortBy('weight') as $nutrient)
|
||||
{{ \App\Support\Nutrients::round($entries->where('meal', $meal)->sum($nutrient['value']), $nutrient['value']) }}{{ $nutrient['unit'] }}
|
||||
{{ $nutrient['value'] }}@if(!$loop->last), @endif
|
||||
@endforeach
|
||||
{{ \App\Support\Nutrients::round($entries->where('meal', $meal)->sum($nutrient['value']), $nutrient['value']) }}{{ $nutrient['unit'] }}
|
||||
{{ $nutrient['value'] }}@if(!$loop->last), @endif
|
||||
@endforeach
|
||||
</span>
|
||||
</h3>
|
||||
@forelse($entries->where('meal', $meal) as $entry)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
use App\Http\Controllers\FoodController;
|
||||
use App\Http\Controllers\GoalController;
|
||||
use App\Http\Controllers\IngredientPickerController;
|
||||
use App\Http\Controllers\JournalDateController;
|
||||
use App\Http\Controllers\JournalEntryController;
|
||||
use App\Http\Controllers\ProfileController;
|
||||
use App\Http\Controllers\RecipeController;
|
||||
|
|
@ -30,6 +31,9 @@ Route::middleware(['auth'])->group(function () {
|
|||
// Ingredient picker.
|
||||
Route::get('/ingredient-picker/search', [IngredientPickerController::class, 'search'])->name('ingredient-picker.search');
|
||||
|
||||
// Journal dates.
|
||||
Route::post('/journal-dates/{journal_date}/update/goal', [JournalDateController::class, 'updateGoal'])->name('journal-dates.update.goal');
|
||||
|
||||
// Journal entries.
|
||||
Route::get('/journal-entries/create/from-nutrients', [JournalEntryController::class, 'createFromNutrients'])->name('journal-entries.create.from-nutrients');
|
||||
Route::post('/journal-entries/create/from-nutrients', [JournalEntryController::class, 'storeFromNutrients'])->name('journal-entries.store.from-nutrients');
|
||||
|
|
|
|||
|
|
@ -41,4 +41,39 @@ class GoalControllerTest extends HttpControllerTestCase
|
|||
return $this->factory()->for($this->user)->create();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function testCanAddInstance(): void
|
||||
{
|
||||
$create_url = action([$this->class(), 'create']);
|
||||
$response = $this->get($create_url);
|
||||
$response->assertOk();
|
||||
|
||||
$data = $this->factory()->makeOne()->toArray();
|
||||
$data['days'] = Goal::days()->pluck('value')->random(3)->toArray();
|
||||
|
||||
$store_url = action([$this->class(), 'store']);
|
||||
$response = $this->post($store_url, $data);
|
||||
$response->assertSessionHasNoErrors();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function testCanEditInstance(): void
|
||||
{
|
||||
$instance = $this->createInstance();
|
||||
$edit_url = action([$this->class(), 'edit'], [$this->routeKey() => $instance]);
|
||||
$response = $this->get($edit_url);
|
||||
$response->assertOk();
|
||||
|
||||
$data = $this->factory()->makeOne()->toArray();
|
||||
$data['days'] = Goal::days()->pluck('value')->random(3)->toArray();
|
||||
|
||||
$put_url = action([$this->class(), 'update'], [$this->routeKey() => $instance]);
|
||||
$response = $this->put($put_url, $data);
|
||||
$response->assertSessionHasNoErrors();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue