ifx merge for update

This commit is contained in:
2020-08-01 17:34:10 +02:00
62 changed files with 3278 additions and 946 deletions

46
.env.testing Normal file
View File

@@ -0,0 +1,46 @@
APP_NAME=Laravel
APP_ENV=test
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost:8000
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=portal
DB_USERNAME=root
DB_PASSWORD=secret
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=127.0.0.1
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=no-reply@portal.loc
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

76
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,76 @@
# This file is a template, and might need editing before it works on your project.
# Official framework image. Look for the different tagged releases at:
# https://hub.docker.com/r/library/php
image: php:latest
# Pick zero or more services to be used on all builds.
# Only needed when using a docker container to run your tests in.
# Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-a-service
services:
- mysql:latest
variables:
MYSQL_DATABASE: portal
MYSQL_ROOT_PASSWORD: secret
# This folder is cached between builds
# http://docs.gitlab.com/ce/ci/yaml/README.html#cache
cache:
paths:
- vendor/
- node_modules/
# This is a basic example for a gem or script which doesn't use
# services such as redis or postgres
before_script:
# Update packages
- apt-get update -yqq
# Prep for Node
- apt-get install gnupg -yqq
# Upgrade to Node 8
- curl -sL https://deb.nodesource.com/setup_10.x | bash -
# Install dependencies
- apt-get install git nodejs libcurl4-gnutls-dev libicu-dev libmcrypt-dev libvpx-dev libjpeg-dev libpng-dev libxpm-dev zlib1g-dev libfreetype6-dev libxml2-dev libexpat1-dev libbz2-dev libgmp3-dev libldap2-dev unixodbc-dev libpq-dev libsqlite3-dev libaspell-dev libsnmp-dev libpcre3-dev libtidy-dev -yqq
#- apt-get install php-mbstring php-curl php-json php-intl php-gd php-xml php-zip php-bz2 -yqq
# Install php extensions
- docker-php-ext-install pdo pdo_mysql tokenizer xml pcntl curl json
# - docker-php-ext-install mbstring intl gd xml bz2 opcache pdo_mysql curl json zip
# Install & enable Xdebug for code coverage reports
- pecl install xdebug
- docker-php-ext-enable xdebug
# Install Composer and project dependencies.
- curl -sS https://getcomposer.org/installer | php
- php composer.phar install
# Install Node dependencies.
# comment this out if you don't have a node dependency
- npm install
# Copy over testing configuration.
# Don't forget to set the database config in .env.testing correctly
# DB_HOST=mysql
# DB_DATABASE=project_name
# DB_USERNAME=root
# DB_PASSWORD=secret
- cp .env.testing .env
# Run npm build
# comment this out if you don't have a frontend build
# you can change this to to your frontend building script like
# npm run build
- npm run dev
# Generate an application key. Re-cache.
- php artisan key:generate
# - php artisan config:cache
- php artisan optimize
# Run database migrations.
- php artisan migrate
# Run database seed
- php artisan db:seed
test:
script:
# run laravel tests
- php artisan test
# run frontend tests
# if you have any task for testing frontend
# set it in your package.json script
# comment this out if you don't have a frontend test
# - npm test

10
.idea/php.xml generated
View File

@@ -90,8 +90,6 @@
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php73" />
<path value="$PROJECT_DIR$/vendor/psr/simple-cache" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-token-stream" />
<path value="$PROJECT_DIR$/vendor/jakub-onderka/php-console-color" />
<path value="$PROJECT_DIR$/vendor/jakub-onderka/php-console-highlighter" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/type-resolver" />
<path value="$PROJECT_DIR$/vendor/psr/http-message" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-ctype" />
@@ -112,6 +110,14 @@
<path value="$PROJECT_DIR$/vendor/laravel/passport" />
<path value="$PROJECT_DIR$/vendor/spatie/laravel-web-tinker" />
<path value="$PROJECT_DIR$/vendor/intervention/image" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-normalizer" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-grapheme" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php70" />
<path value="$PROJECT_DIR$/vendor/symfony/string" />
<path value="$PROJECT_DIR$/vendor/symfony/deprecation-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php80" />
<path value="$PROJECT_DIR$/vendor/ramsey/collection" />
<path value="$PROJECT_DIR$/vendor/brick/math" />
</include_path>
</component>
<component name="PhpProjectSharedConfiguration" php_language_level="7.2" />

10
.idea/portal.iml generated
View File

@@ -6,6 +6,7 @@
<sourceFolder url="file://$MODULE_DIR$/app" isTestSource="false" packagePrefix="App\" />
<sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/vendor/asm89/stack-cors" />
<excludeFolder url="file://$MODULE_DIR$/vendor/brick/math" />
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/defuse/php-encryption" />
<excludeFolder url="file://$MODULE_DIR$/vendor/dnoegel/php-xdg-base-dir" />
@@ -27,8 +28,6 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/psr7" />
<excludeFolder url="file://$MODULE_DIR$/vendor/hamcrest/hamcrest-php" />
<excludeFolder url="file://$MODULE_DIR$/vendor/intervention/image" />
<excludeFolder url="file://$MODULE_DIR$/vendor/jakub-onderka/php-console-color" />
<excludeFolder url="file://$MODULE_DIR$/vendor/jakub-onderka/php-console-highlighter" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laminas/laminas-diactoros" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laminas/laminas-zendframework-bridge" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/framework" />
@@ -72,6 +71,7 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/simple-cache" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psy/psysh" />
<excludeFolder url="file://$MODULE_DIR$/vendor/ralouphie/getallheaders" />
<excludeFolder url="file://$MODULE_DIR$/vendor/ramsey/collection" />
<excludeFolder url="file://$MODULE_DIR$/vendor/ramsey/uuid" />
<excludeFolder url="file://$MODULE_DIR$/vendor/scrivo/highlight.php" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
@@ -90,6 +90,7 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/swiftmailer/swiftmailer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/console" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/css-selector" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/deprecation-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/error-handler" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher-contracts" />
@@ -99,14 +100,19 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/mime" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-ctype" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-iconv" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-grapheme" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-idn" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-normalizer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-mbstring" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php70" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php72" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php73" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php80" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/process" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/psr-http-message-bridge" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/routing" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/service-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/string" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/var-dumper" />

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class AutomationController extends Controller
{
public function home()
{
$url = "http://192.168.1.32/meteo/meteo/api/?device=all&instant";
$client = new \GuzzleHttp\Client();
$promise = $client->requestAsync('GET', $url);
$response = $promise->wait();
return $response->getBody()->getContents();
}
}

View File

@@ -0,0 +1,85 @@
<?php
namespace App\Http\Controllers;
use App\Http\Requests\EventCategoryRequest;
use App\Http\Resources\EventCategory as EventCategoryResource;
use App\Models\EventCategory;
use Illuminate\Http\Request;
class EventCategoryController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\JsonResponse
*/
public function index()
{
return response()->json([
'data' => EventCategoryResource::collection(EventCategory::orderBy('name')->get()),
]);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function store(EventCategoryRequest $request)
{
$validated = $request->validated();
$category = EventCategory::create($validated);
$category->save();
return (new EventCategoryResource($category))
->response()
->setStatusCode(201);
}
/**
* Display the specified resource.
*
* @param \App\Models\EventCategory $category
* @return \Illuminate\Http\JsonResponse
*/
public function show(EventCategory $category)
{
return (new EventCategoryResource($category))
->response()
->setStatusCode(200);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\EventCategory $category
* @return \Illuminate\Http\JsonResponse
*/
public function update(EventCategoryRequest $request, EventCategory $category)
{
$category->update($request->validated());
return (new EventCategoryResource($category))
->response()
->setStatusCode(200);
}
/**
* Remove the specified resource from storage.
*
* @param \App\Models\EventCategory $category
* @return \Illuminate\Http\JsonResponse
*/
public function destroy(EventCategory $category)
{
if(auth()->user()->isAdmin()) {
$category->delete();
return response()->json([], 204);
} else {
return response()->json([], 403);
}
}
}

View File

@@ -0,0 +1,96 @@
<?php
namespace App\Http\Controllers;
use App\Http\Requests\EventRequest;
use App\Models\Event;
use App\Http\Resources\Event as EventResource;
use Illuminate\Http\Request;
class EventController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @param EventRequest $request
* @return \Illuminate\Http\JsonResponse
*/
public function store(EventRequest $request)
{
$validated = $request->validated();
$event = $request->user()->events()->create($validated);
$event->save();
return (new EventResource($event))
->response()
->setStatusCode(201);
}
/**
* Display the specified resource.
*
* @param \App\Models\Event $event
* @return \Illuminate\Http\JsonResponse
*/
public function show(Event $event)
{
return (new EventResource($event))
->response()
->setStatusCode(200);
}
/**
* Show the form for editing the specified resource.
*
* @param \App\Models\Event $event
* @return \Illuminate\Http\Response
*/
public function edit(Event $event)
{
//
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Event $event
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Event $event)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param \App\Models\Event $event
* @return \Illuminate\Http\Response
*/
public function destroy(Event $event)
{
//
}
}

View File

@@ -6,12 +6,20 @@ use App\Http\Resources\Image as ImageResource;
use App\Models\Memo;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Intervention\Image\Facades\Image;
class ImageController extends Controller
{
public function users(User $user)
{
foreach (auth()->user()->images as $image) {
if(File::exists(storage_path('app/public/'.$image->path))) {
File::delete(storage_path('app/public/'.$image->path));
auth()->user()->images()->where('id', $image->id)->delete();
}
}
$data = $this->storeImage();
$newImage = auth()->user()->images()->create([
@@ -21,11 +29,22 @@ class ImageController extends Controller
'location' => $data['location'],
]);
$this->haveThumbnailImage($data, auth()->user());
auth()->user()->update(['updated_at' => now()]);
return new ImageResource($newImage);
}
public function memos(Memo $memo)
{
foreach ($memo->images as $image) {
if(File::exists(storage_path('app/public/'.$image->path))) {
File::delete(storage_path('app/public/'.$image->path));
$memo->images()->where('id', $image->id)->delete();
}
}
$data = $this->storeImage();
$newImage = $memo->images()->create([
@@ -35,10 +54,29 @@ class ImageController extends Controller
'location' => $data['location'],
]);
$this->haveThumbnailImage($data, $memo);
$memo->update(['updated_at' => now()]);
return new ImageResource($newImage);
}
private function storeImage() {
private function haveThumbnailImage($data, $object)
{
Image::make($data['image'])
->fit(round($data['width'] / 3, 0), round($data['height'] / 3, 0))
->save(storage_path('app/public/thumbnail/images/'.$data['image']->hashName()));
$object->images()->create([
'path' => "thumbnail/".$data['path'],
'width' => round($data['width'] / 3, 0),
'height' => round($data['height'] / 3, 0),
'location' => $data['location']."-small",
]);
}
private function storeImage()
{
$data = request()->validate([
'image' => 'required',
'width' => 'required',

View File

@@ -0,0 +1,31 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class EventCategoryRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return auth()->user()->isAdmin();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required',
'description' => 'nullable|string',
];
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class EventRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return !!(auth()->user());
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required',
'description' => 'nullable|string',
'category_id' => 'required|exists:event_categories,id',
'start_date' => 'required|date',
'end_date' => 'date|after_or_equal:start_date',
'location' => 'string|nullable'
];
}
/**
* Get custom attributes for validator errors.
*
* @return array
*/
public function attributes()
{
return [
'name' => 'nom',
'start_date' => 'date de début',
'end_date' => 'date de fin',
'location' => 'lieu',
];
}
/**
* Get the error messages for the defined validation rules.
*
* @return array
*/
public function messages()
{
return [
'name.required' => 'A :attribute is required',
'start_date.required' => 'A :attribute is required',
];
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class Event extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'data' => [
'type' => 'events',
'event_id' => $this->id,
'attributes' => [
'data' => [
'name' => $this->name,
'description' => $this->description,
'start_date' => $this->start_date,
'end_date' => $this->end_date,
'location' => $this->location,
'category' => [
'data' => [
'category_id' => $this->category_id
],
],
]
],
],
'links' => [
'self' => url('/events/'.$this->id),
]
];
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class EventCategory extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'data' => [
'type' => 'event categories',
'event_category_id' => $this->id,
'attributes' => [
'data' => [
'name' => $this->name,
'description' => $this->description,
]
],
],
'links' => [
'self' => url('/events/categories/'.$this->id),
]
];
}
}

View File

@@ -27,6 +27,7 @@ class Memo extends JsonResource
'attributes' => [
'posted_by' => new UserResource($this->user),
'cover_image' => new ImageResource($this->coverImage),
'thumbnail_cover_image' => new ImageResource($this->thumbnailImage),
]
//'tags' => TagResource::collection($this->tags),
],

View File

@@ -24,6 +24,7 @@ class User extends JsonResource
'email' => $this->email,
'profile_image' => new ImageResource($this->profileImage),
'cover_image' => new ImageResource($this->coverImage),
'thumbnail_cover_image' => new ImageResource($this->thumbnailImage),
'last_login' => optional($this->login_at)->diffForHumans(),
'is_admin' => $this->isAdmin(),
],

10
app/Models/Event.php Normal file
View File

@@ -0,0 +1,10 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Event extends Model
{
protected $guarded = [];
}

View File

@@ -0,0 +1,10 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class EventCategory extends Model
{
protected $guarded = [];
}

View File

@@ -41,4 +41,14 @@ class Memo extends Model
$userImage->path = 'images/default-cover.jpg';
});
}
public function thumbnailImage(): MorphOne
{
return $this->morphOne(Image::class, 'imageable')
->orderBy('id', 'desc')
->where('location', 'cover-small')
->withDefault(function ($userImage) {
$userImage->path = 'images/default-cover.jpg';
});
}
}

View File

@@ -3,6 +3,7 @@
namespace App;
use App\Models\Bookmark;
use App\Models\Event;
use App\Models\Image;
use App\Models\Memo;
use App\Models\ToDoList;
@@ -94,4 +95,19 @@ class User extends Authenticatable
$userImage->path = 'images/default-cover.jpg';
});
}
public function thumbnailImage(): MorphOne
{
return $this->morphOne(Image::class, 'imageable')
->orderBy('id', 'desc')
->where('location', 'profile-small')
->withDefault(function ($userImage) {
$userImage->path = 'images/default-cover.jpg';
});
}
public function events(): HasMany
{
return $this->hasMany(Event::class);
}
}

View File

@@ -14,7 +14,7 @@
"guzzlehttp/guzzle": "^6.5",
"intervention/image": "^2.5",
"laravel/framework": "^7.0",
"laravel/passport": "^8.4",
"laravel/passport": "^9.3",
"laravel/tinker": "^2.0",
"laravel/ui": "^2.0"
},

2433
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateEventCategoriesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('event_categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('description')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('event_categories');
}
}

View File

@@ -0,0 +1,54 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateEventsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('events', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('category_id');
$table->string('name');
$table->text('description')->nullable();
$table->timestamp('start_date');
$table->timestamp('end_date')->nullable();
$table->string('location')->nullable();
$table->timestamps();
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('restrict')
->onUpdate('restrict');
$table->foreign('category_id')
->references('id')
->on('event_categories')
->onDelete('restrict')
->onUpdate('restrict');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('events', function (Blueprint $table) {
$table->dropForeign(['user_id']);
$table->dropForeign(['category_id']);
});
Schema::dropIfExists('events');
}
}

View File

@@ -11,6 +11,6 @@ class DatabaseSeeder extends Seeder
*/
public function run()
{
// $this->call(UsersTableSeeder::class);
$this->call(EventCategorySeeder::class);
}
}

View File

@@ -0,0 +1,22 @@
<?php
use Illuminate\Database\Seeder;
class EventCategorySeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$data = [
'name' => 'Non-classée',
'description' => 'Evénement sans catégorie',
];
$category = \App\Models\EventCategory::firstOrCreate($data);
$category->save();
}
}

View File

@@ -43,6 +43,7 @@ if [ -z "$1" ]; then
if [ "production" == "$env" ];
then
echo "deploy in production"
php artisan down
git pull origin production
composer install
@@ -51,6 +52,7 @@ if [ -z "$1" ]; then
npm install --no-progress
npm run prod
php artisan up
fi
elif [ "$1" = save-sql ]; then

View File

@@ -17,29 +17,29 @@
"cross-env": "^7.0",
"eslint": "^6.8.0",
"eslint-config-standard": "^14.1.1",
"eslint-loader": "^3.0.3",
"eslint-plugin-import": "^2.20.2",
"eslint-loader": "^3.0.4",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"eslint-plugin-vue": "^6.2.2",
"laravel-mix": "^5.0.1",
"laravel-mix-eslint": "^0.1.3",
"laravel-mix-purgecss": "^5.0.0-rc.2",
"lodash": "^4.17.13",
"laravel-mix-purgecss": "^5.0.0",
"lodash": "^4.17.19",
"resolve-url-loader": "^2.3.1",
"sass": "^1.20.1",
"sass": "^1.26.10",
"sass-loader": "^8.0.0",
"vue": "^2.5.17",
"vue-router": "^3.1.6",
"vue-router": "^3.3.4",
"vue-template-compiler": "^2.6.10",
"vuex": "^3.1.3"
"vuex": "^3.5.1"
},
"dependencies": {
"dropzone": "^5.7.0",
"dropzone": "^5.7.2",
"laravel-mix-svg-vue": "^0.2.6",
"markdown-it": "^10.0.0",
"markdown-it-checkbox": "^1.1.0",
"tailwindcss": "^1.3.5"
"tailwindcss": "^1.6.0"
}
}

View File

@@ -51,11 +51,11 @@
<g
transform="translate(0,-197)"
id="g4657"
style="fill:#1f6521;fill-opacity:1">
style="fill:#424242;fill-opacity:1">
<path
d="M 188.97656 0 A 188.97638 188.97638 0 0 0 0 188.97656 A 188.97638 188.97638 0 0 0 188.97656 377.95312 A 188.97638 188.97638 0 0 0 377.95312 188.97656 A 188.97638 188.97638 0 0 0 188.97656 0 z M 170.81055 38.818359 L 211.67188 38.818359 C 214.22548 38.818359 215.50235 38.818893 216.7793 40.109375 C 218.05624 41.399857 219.33203 42.684127 219.33203 43.974609 L 224.43945 77.474609 C 230.8238 80.050168 235.93136 82.625534 239.76172 83.916016 L 265.29883 64.589844 C 266.57592 63.299362 269.1293 63.300781 270.40625 63.300781 C 272.9598 63.300781 274.23673 64.584518 275.51367 65.875 C 290.83607 80.047813 301.05271 90.356699 306.16016 96.798828 C 307.4371 98.08931 307.43555 99.375534 307.43555 100.66602 C 307.43555 101.9565 307.4371 103.24077 306.16016 104.53125 C 304.88331 107.10783 301.05106 112.26237 297.2207 117.41602 C 292.11325 122.56959 289.55975 127.72473 287.00586 130.30078 C 290.8367 136.7434 293.39102 141.89572 294.66797 148.33789 L 327.86523 153.49219 C 329.14218 153.49219 330.42032 154.77788 331.69727 156.06836 C 332.97421 157.3588 332.97461 158.64506 332.97461 159.93555 L 332.97461 201.16406 C 332.97461 202.45454 332.97421 203.74081 331.69727 205.03125 C 330.42032 206.32173 329.14218 207.60742 327.86523 207.60742 L 294.66797 212.76172 C 292.11451 219.20389 290.83709 224.3567 288.2832 230.79883 C 292.1138 238.52955 299.77435 246.26064 307.43555 256.56836 C 308.71249 257.85884 308.71289 259.14506 308.71289 260.43555 C 308.71289 261.72603 308.71249 263.01034 307.43555 264.30078 C 303.60495 268.16637 297.22174 275.89734 289.56055 284.91602 C 280.6225 293.93427 274.23749 297.80078 271.68359 297.80078 C 270.4065 297.80078 267.85312 296.51509 266.57617 295.22461 L 241.03906 275.89844 C 235.93161 278.47403 230.8238 281.05131 224.43945 282.3418 C 223.16236 299.09168 220.60898 310.68678 219.33203 317.12891 C 218.05513 320.99253 216.77762 322.2832 212.94727 322.2832 L 172.08789 322.2832 C 170.81143 322.2832 169.53476 322.28312 168.25781 319.70703 C 166.98087 318.41659 165.70312 317.13033 165.70312 315.83984 L 160.5957 282.3418 C 154.2114 281.05324 149.1055 278.47652 143.99805 275.90039 L 118.46094 295.22656 C 118.46094 296.51704 115.90585 296.51758 114.62891 296.51758 C 112.07535 296.51758 110.79843 296.51704 109.52148 295.22656 C 92.922242 281.05375 82.707795 270.74685 78.876953 264.30469 C 77.600006 263.01421 77.599609 261.72798 77.599609 260.4375 C 77.599609 259.14702 77.600006 256.57227 78.876953 256.57227 C 80.153802 253.99523 83.985568 248.84107 87.816406 243.6875 C 92.923905 238.53336 95.477355 233.37882 98.03125 230.80273 C 94.200892 224.36057 91.646084 219.2058 90.369141 212.76367 L 57.169922 207.61133 C 55.893454 207.61133 54.616791 206.32564 53.339844 205.03516 C 52.06338 203.74475 52.06366 202.45845 49.509766 201.16797 L 49.509766 159.93945 C 49.509766 158.64897 49.508209 157.36275 50.785156 156.07227 C 52.06162 154.78662 53.340244 153.49609 54.617188 153.49609 L 89.091797 148.33594 C 91.645544 141.89377 94.200011 136.74004 96.753906 131.58594 C 92.923306 125.14377 86.537701 116.12363 77.599609 105.81641 C 76.322662 103.23835 76.322266 101.95454 76.322266 100.66406 C 76.322266 99.373581 76.322662 98.087357 77.599609 96.796875 C 80.153357 92.931288 86.538513 86.489941 95.476562 77.470703 C 103.13776 68.452977 109.52228 64.585938 112.07617 64.585938 C 113.35283 64.585938 115.90665 64.584518 117.18359 65.875 L 142.7207 85.203125 C 147.8282 82.627528 154.21281 80.050248 159.32031 78.759766 C 160.5974 62.009882 163.15079 50.414785 164.42773 43.972656 C 165.70459 40.109034 166.98019 38.818359 170.81055 38.818359 z M 192.51953 132.88086 C 179.75084 132.88086 168.25836 138.03545 159.32031 147.05469 C 150.38227 156.07385 145.27539 167.67039 145.27539 180.55469 C 145.27539 193.43898 150.38227 205.03353 159.32031 214.05273 C 168.25836 223.07144 179.75084 228.22656 192.51953 228.22656 C 205.28818 228.22656 216.77875 223.07144 225.7168 214.05273 C 234.65489 205.03353 239.76367 193.43898 239.76367 180.55469 C 239.76367 167.67039 234.65489 156.07385 225.7168 147.05469 C 216.77875 138.03545 205.28818 132.88086 192.51953 132.88086 z "
transform="matrix(0.26458333,0,0,0.26458333,0,197)"
id="path4655"
style="fill:#1f6521;fill-opacity:1" />
style="fill:#424242;fill-opacity:1" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@@ -4,6 +4,12 @@
* Released under the MIT License.
*/
/*!
* vuex v3.5.1
* (c) 2020 Evan You
* @license MIT
*/
/*! https://mths.be/punycode v1.4.1 by @mathias */
/**
@@ -14,9 +20,3 @@
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
*/
/**
* vuex v3.1.3
* (c) 2020 Evan You
* @license MIT
*/

View File

@@ -4,7 +4,7 @@
<div v-if="authUser" class="w-full overflow-y-auto">
<TopBar />
<main>
<router-view :key="$route.fullPath"></router-view>
<router-view :key="$route.fullPath" class="bg-gray-200"></router-view>
</main>
</div>
</div>

View File

@@ -1,7 +1,7 @@
<template>
<div class="relative mb-2">
<label v-if="label" :for="name" class="pb-2 font-bold text-xl ml-1">{{ label }}</label>
<input :id="name" :type="type" :placeholder="placeholder" v-model="value" @input="updateField()" :class="'w-full rounded p-2 ' + classes + ' ' + errorClassObject()">
<input :id="name" :type="type" :placeholder="placeholder" v-model="value" @input="updateField()" :class="'w-full p-2 ' + classes + ' ' + errorClassObject()">
<p class="text-red-600 m-0" v-text="errorMessage()">Error Here</p>
</div>
</template>

View File

@@ -1,7 +1,7 @@
<template>
<div class="top-bar flex justify-between bg-gray-600">
<div class="top-bar relative z-10 flex justify-between bg-marine h-16">
<router-link v-if="authUser" :to="'/profile'" class="flex items-center m-2">
<Avatar :avatar="authUser.data.attributes.profile_image.data.attributes.path" size="small" :alt="authUser.data.attributes.name" class="w-10 h-10"/>
<Avatar :avatar="authUser.data.attributes.thumbnail_cover_image.data.attributes.path" size="small" :alt="authUser.data.attributes.name" class="w-10 h-10"/>
<span class="ml-2 text-gray-100 hover:text-white">{{ authUser.data.attributes.name }}</span>
</router-link>
<form v-if="authUser && search" class="m-2">
@@ -11,7 +11,7 @@
</button>
</form>
<router-link to="/dashboard" v-if="authUser" class="text-gray-100 hover:text-white">
<svg-vue icon="params" class="w-10 m-2 fill-current" />
<svg-vue icon="params" class="w-10 m-3 fill-current" />
</router-link>
<router-link v-else to="/login">
Se connecter

View File

@@ -0,0 +1,30 @@
<template>
<div>
<div class="card block">
<h2>Raspberry Links</h2>
<ul class="mt-2">
<li><a v-for="(link, index) in links" :href="link.link" :key="index" target="_blank" class="block text-lg">{{ link.name }}</a></li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: 'AutomaticLinksHome',
data: function () {
return {
links: [
{ name: 'Météo', link: 'http://192.168.1.32/meteo/meteo'},
{ name: 'MotionEye', link: 'http://192.168.1.32:8765'},
{ name: 'TT-RSS', link: 'https://tt-rss.bricooli.fr'},
{ name: 'Pi-Hole', link: 'http://192.168.1.32/admin/index.php'},
{ name: 'RaspAp', link: 'http://192.168.1.32/raspap'},
{ name: 'Kodi', link: 'http://192.168.1.19:8080/'},
{ name: 'RaspiWeb Adminer', link: 'http://192.168.1.32/adminer.php'},
{ name: 'RaspiGate Adminer', link: 'http://192.168.1.29/adminer.php'},
],
}
},
}
</script>

View File

@@ -0,0 +1,52 @@
<template>
<div>
<div class="card flex flex-col">
<h2>Météo Home</h2>
<ul class="mt-2">
<li v-for="(captor, index) in captors" :key="index" class="block mb-4">
<div class="flex justify-between items-baseline mb-2">
<span class="font-bold text-lg">{{ captor.device }}</span>
<span class="text-sm">{{ captor.date_meteo }}</span>
</div>
<div class="flex flex-no-wrap text-sm -m-1">
<span v-if="captor.temperature" class="mx-1">{{ floated(captor.temperature) }} <span class="font-semibold text-xs">°C</span></span>
<span v-if="captor.humidite" class="mx-1">{{ floated(captor.humidite) }} <span class="font-semibold text-xs">%</span></span>
<span v-if="captor.pression" class="mx-1">{{ floated(captor.pression) }} <span class="font-semibold text-xs">hPa</span></span>
<span v-if="captor.lumiere" class="mx-1">{{ captor.lumiere }}</span>
</div>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: 'AutomaticMeteoHome',
data: function () {
return {
captors: null,
}
},
mounted() {
// eslint-disable-next-line no-undef
axios.get('/api/automation/home')
.then(response => {
this.captors = response.data.data
console.log(response.data.data)
})
.catch(() => {
console.log('Unable to fetch memos.')
})
},
methods: {
floated: function (value) {
return value.toFixed(2)
}
},
}
</script>
<style scoped>
</style>

View File

@@ -1,5 +1,111 @@
<template>
<div class="m-2 p-2 bg-white">
<div class="mx-2 p-2">
<div class="flex flex-wrap -mx-2">
<div class="w-full sm:w-1/2 md:w-1/3 lg:w-1/4 mb-4">
<div class="card bg-marine text-white shadow">
<div class="flex flex-col justify-between h-full">
<div class="text-xl">Active Users</div>
<div class="text-3xl font-bold">72</div>
<div class="mt-4">
<a href="#" class="text-white hover:text-marine-light uppercase">View Refferals -></a>
</div>
</div>
</div>
</div>
<div class="w-full sm:w-1/2 md:w-2/3 lg:w-3/4 mb-4">
<div class="card">
<div class="flex justify-between">
<span>Users</span>
<span class="flex-none text-green text-sm">268 %</span>
</div>
<div class="text-2xl font-bold">15K</div>
</div>
</div>
</div>
<div class="flex flex-wrap -mx-2">
<div class="w-full sm:w-1/2 md:w-1/3 lg:w-1/4 mb-4">
<div class="card">
<div class="flex justify-between">
<span>Users</span>
<span class="flex-none text-green text-sm">268 %</span>
</div>
<div class="text-2xl font-bold">15K</div>
</div>
</div>
<div class="w-full sm:w-1/2 md:w-1/3 lg:w-1/4 mb-4">
<div class="card">
<div class="flex justify-between">
<span>Sessions</span>
<span class="flex-none text-green text-sm">268 %</span>
</div>
<div class="text-2xl font-bold">17K</div>
</div>
</div>
<div class="w-full sm:w-1/2 md:w-1/3 lg:w-1/4 mb-4">
<div class="card">
<div class="flex justify-between items-start">
<span>Bouncing Rate</span>
<span class="flex-none text-red text-sm">- 158 %</span>
</div>
<div class="text-2xl font-bold">62.7 %</div>
</div>
</div>
<div class="flex-initial sm:w-1/2 md:w-1/3 lg:w-1/4 mb-4">
<div class="card">
<div class="flex justify-between">
<span>Session duration best of</span>
<span class="flex-none text-green text-sm">189 %</span>
</div>
<div class="text-2xl font-bold">1 m 32 s</div>
</div>
</div>
<div class="flex-initial sm:w-1/2 md:w-1/3 lg:w-1/4 mb-4">
<div class="card">
<div class="flex justify-between">
<span>Session duration best of</span>
<span class="flex-none text-green text-sm">189 %</span>
</div>
<div class="text-2xl font-bold">1 m 32 s</div>
</div>
</div>
<div class="flex-initial sm:w-1/2 md:w-1/3 lg:w-1/4 mb-4">
<div class="card">
<div class="-m-4">
<img src="https://portal.bricooli.fr/storage/images/default-cover.jpg" alt="" class="w-full rounded rounded-b-none">
</div>
<div class="h-full flex flex-col mt-6">
<h1 class="text-xl text-marine">Memo Name test</h1>
<span class="mt-auto self-end bg-gray-400 text-white tag">Il y a 3 mois</span>
</div>
</div>
</div>
<div class="flex-initial sm:w-1/2 md:w-1/3 lg:w-1/4 mb-4">
<div class="card">
<div class="-m-4">
<img src="https://portal.bricooli.fr/storage/images/default-cover.jpg" alt="" class="w-full rounded rounded-b-none">
</div>
<div class="h-full flex flex-col mt-6">
<h1 class="text-xl text-marine">Memo Name test</h1>
<p class="no-indent">Anim consequat duis culpa in anim aliquip dolore amet laboris eu fugiat commodo reprehenderit aute amet velit sit culpa et proident irure pariatur</p>
<span class="mt-auto self-end bg-gray-400 text-white tag">Il y a 3 mois</span>
</div>
</div>
</div>
<div class="flex-initial sm:w-1/2 md:w-1/3 lg:w-1/4 mb-4">
<div class="card">
<div class="-m-4">
<img src="https://portal.bricooli.fr/storage/images/default-cover.jpg" alt="" class="w-full rounded rounded-b-none">
</div>
<div class="h-full flex flex-col mt-6">
<h1 class="text-xl text-marine">Memo Name test</h1>
<p class="no-indent">Anim consequat duis culpa in anim aliquip dolore amet laboris eu fugiat commodo reprehenderit</p>
<span class="mt-auto self-end bg-gray-400 text-white tag">Il y a 3 mois</span>
</div>
</div>
</div>
</div>
<div class="box">
<h1>testeur CSS</h1>
<h2>testeur CSS</h2>
<h3>testeur CSS</h3>
@@ -64,6 +170,7 @@
<input type="submit" class="mb-1">
</form>
</div>
</div>
</template>
<script>

View File

@@ -1,5 +1,6 @@
<template>
<div class="p-4">
<div class="mx-2 p-2">
<div class="box">
<div class="flex justify-between">
<h1 class="page-title">Administration</h1>
<a href="#" @click.prevent="logout" class="btn">
@@ -8,6 +9,7 @@
</div>
<UserAdmin />
</div>
</div>
</template>
<script>

View File

@@ -1,9 +1,10 @@
<template>
<div class="p-4">
<h1 class="page-title">Home</h1>
<div class="flex flex-wrap -m-2 mt-2">
<OpenWeatherCard class="w-full sm:w-1/2 md:w-1/3 lg:w-1/4" />
<MemoHome class="w-full sm:w-1/2 md:w-1/3 lg:w-1/4" />
<div class="mx-2 p-2">
<div class="flex flex-wrap -mx-2">
<OpenWeatherCard class="w-full sm:w-1/2 md:w-1/3 lg:w-1/4 mb-4" />
<MemoHome class="w-full sm:w-1/2 md:w-1/3 lg:w-1/3 mb-4" />
<AutomaticLinksHome class="w-full sm:w-1/2 md:w-1/3 lg:w-5/12 mb-4" />
<AutomaticMeteoHome class="w-full sm:w-1/2 md:w-1/3 lg:w-1/3 mb-4" />
</div>
</div>
</template>
@@ -11,11 +12,13 @@
<script>
import OpenWeatherCard from './Meteo/OpenWeatherCard'
import MemoHome from './Memo/MemoHome'
import AutomaticLinksHome from './Automation/AutomaticLinksHome'
import AutomaticMeteoHome from './Automation/AutomaticMeteoHome'
export default {
name: 'Home',
components: {
OpenWeatherCard, MemoHome
OpenWeatherCard, MemoHome, AutomaticLinksHome, AutomaticMeteoHome
}
}
</script>

View File

@@ -1,12 +1,14 @@
<template>
<div class="p-4">
<div class="mx-2 p-2">
<form @submit.prevent="submitForm">
<div class="flex justify-between flex-center mb-4">
<router-link to="/memos/" class="btn">Back</router-link>
<button class="btn-primary">Add New Memo</button>
</div>
<div class="box">
<InputField name="name" label="Title" placeholder="Your Title" required @update:field="form.name = $event" :errors="errors" />
<TextAreaField class="" name="memo" placeholder="Your Memo" required @update:field="form.memo = $event" :errors="errors" />
<TextAreaField name="memo" placeholder="Your Memo" required @update:field="form.memo = $event" :errors="errors" />
</div>
</form>
</div>
</template>

View File

@@ -13,14 +13,16 @@
classes="cover"
:alt="form.name"/>
</div>
<div class="p-4">
<div class="mx-2 p-2">
<form @submit.prevent="submitForm">
<div class="flex justify-between mb-4">
<router-link :to="'/memos/' + this.$route.params.id" class="btn">Back</router-link>
<button class="btn-primary">Save</button>
</div>
<div class="box">
<InputField name="name" :data="form.name" label="Title" placeholder="Your Title" required @update:field="form.name = $event" :errors="errors" />
<TextAreaField class="memo-text-area" name="memo" :data="form.memo" placeholder="Your Memo" required @update:field="form.memo = $event" :errors="errors" />
</div>
</form>
</div>

View File

@@ -1,21 +1,21 @@
<template>
<div>
<div class="card m-2">
<div v-if="loading" class="p-2">
<div class="card">
<div v-if="loading">
<h2>Memos</h2>
<Loader />
</div>
<div v-else class="p-2">
<router-link to="/memos"><h2 class="mb-4 text-gray-900">{{ memos.count }} Memos</h2></router-link>
<router-link :to="memos.last_updated.links.self" class="m-2 block">
<div v-else>
<router-link to="/memos" class="mb-4 no-underline"><h2>{{ memos.count }} Memos</h2></router-link>
<router-link :to="memos.last_updated.links.self" class="m-2 block no-underline">
<div class="flex justify-between text-black">
Dernier édité
<span class="inline-block bg-gray-400 text-white text-center rounded-full px-3 py-1 text-sm font-semibold">{{ memos.last_updated.data.last_updated }}</span>
</div>
<div class="text-2xl font-bold">{{ memos.last_updated.data.name }}</div>
</router-link>
<hr class="border border-gray-900">
<router-link :to="memos.last_created.links.self" class="m-2 block">
<hr class="border border-marine">
<router-link :to="memos.last_created.links.self" class="m-2 block no-underline">
<div class="flex justify-between text-black">
Dernier créé
<span class="inline-block bg-gray-400 text-white text-center rounded-full px-3 py-1 text-sm font-semibold">{{ memos.last_created.data.last_updated }}</span>

View File

@@ -1,5 +1,5 @@
<template>
<div class="p-4">
<div class="mx-2 p-2">
<div class="flex justify-between flex-center mb-4">
<a href="#" class="btn" @click="$router.back()">Back</a>
<router-link :to="'/memos/create'" class="btn-primary">Add New Memo</router-link>
@@ -9,14 +9,14 @@
<div v-if="memos.lenght === 0">
<p>No memos yet. <router-link to="/memos/create">Get Started ></router-link></p>
</div>
<router-link v-for="memo in memos" :key="memo.data.memo_id" :to="'/memos/' + memo.data.memo_id" class="w-full sm:w-1/2 md:w-1/3 lg:w-1/4">
<div class="m-2 max-w-lg rounded overflow-hidden shadow-lg bg-white">
<img :src="memo.data.attributes.cover_image.data.attributes.path" alt="" class="w-full">
<div class="px-6 py-4">
<h1 class="text-gray-700">{{ memo.data.name }}</h1>
<router-link v-for="memo in memos" :key="memo.data.memo_id" :to="'/memos/' + memo.data.memo_id" class="flex-initial sm:mx-auto md:w-1/2 md:mx-0 lg:w-1/3 xl:w-1/4 mb-4 no-underline">
<div class="card">
<div class="-m-4">
<img :src="memo.data.attributes.thumbnail_cover_image.data.attributes.path" alt="" class="w-full rounded rounded-b-none">
</div>
<div class="flex justify-end py-2">
<span class="inline-block bg-gray-400 text-white rounded-full px-3 py-1 text-sm font-semibold mr-2">{{ memo.data.last_updated }}</span>
<div class="h-full flex flex-col mt-6">
<h1 class="text-xl text-marine">{{ memo.data.name }}</h1>
<span class="mt-auto self-end bg-gray-400 text-white tag">{{ memo.data.last_updated }}</span>
</div>
</div>
</router-link>
@@ -54,7 +54,7 @@ export default {
methods: {
reorderList() {
this.memos.sort(function(a, b) {
return a.data.last_updated_timestamp + b.data.last_updated_timestamp
return b.data.last_updated_timestamp - a.data.last_updated_timestamp
})
}
}

View File

@@ -30,7 +30,7 @@
<!-- <TagBox :memo="memo" />-->
<div class="p-4">
<div class="memo-style rounded-t-sm p-4 pb-3 -mb-1 bg-white" v-html="memoMarkdown"></div>
<div class="box memo-style rounded-t-sm p-4 pb-3 -mb-1 bg-white" v-html="memoMarkdown"></div>
<div class="bg-gray-400 text-white rounded-b-sm px-2 py-1 flex justify-end">@last update<span class="font-semibold ml-1">{{ memo.last_updated }}</span></div>
</div>
</div>

View File

@@ -3,9 +3,8 @@
<div v-if="loading">
<Loader />
</div>
<div v-else class="m-2">
<div class="card">
<div class="text-black m-2 p-2 flex flex-col">
<div v-else class="card">
<div class="flex flex-col">
<h2>{{ meteo.city.name }}</h2>
<div class="flex">
<div class="flex flex-col justify-end">
@@ -15,14 +14,13 @@
<div><strong>{{ meteo.list[0].main.pressure }}</strong> hPa</div>
</div>
<div class="flex flex-col flex-1 justify-end items-end">
<i v-bind:class="'owf owf-5x owf-' + meteo.list[0].weather[0].id"></i>
<i v-bind:class="'current-fill text-marine owf owf-5x owf-' + meteo.list[0].weather[0].id"></i>
<div><strong>{{ meteo.list[0].weather[0].description }}</strong></div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>

View File

@@ -15,7 +15,7 @@
<input type="text"
v-model="toDo.data.attributes.data.name"
@keypress.enter="updateToDo"
class="flex-1 rounded-sm border border-primary-600 pl-1">
class="flex-1 rounded-sm border border-primary-600 p-0 pl-1">
<span @click="edit = !edit">
<svg-vue icon="close" class="inline w-4 fill-current cursor-pointer mx-2" />
</span>
@@ -42,6 +42,7 @@ export default {
},
data () {
return {
id: this.toDo.data.to_do_id,
edit: false,
checked: !!(this.toDo.data.attributes.data.checked_at),
}
@@ -52,7 +53,6 @@ export default {
axios.patch('/api/to-do-lists/' + this.idList + '/to-do/' + this.toDo.data.to_do_id, {name: this.toDo.data.attributes.data.name })
.then(() => {
this.edit = false
//this.toDoList.data.attributes.data.name = this.listName
})
.catch(errorRes => {
console.log('Internal Error, Unable to delete list.' + errorRes)
@@ -61,10 +61,10 @@ export default {
},
watch: {
checked: function () {
if(event && event.type === 'click') {
// eslint-disable-next-line no-undef
axios.patch('/api/to-do-lists/' + this.idList + '/to-do/' + this.toDo.data.to_do_id + '/check')
.then(res => {
// this.toDoList.data.attributes.data.to_dos.data[position].data.attributes.data.checked_at = res.data.data.attributes.data.checked_at
this.toDo.data.attributes.data.checked_at = res.data.data.attributes.data.checked_at
this.checked = !!(res.data.data.attributes.data.checked_at)
})
@@ -72,6 +72,12 @@ export default {
console.log('Internal Error, Unable to delete contact.' + errorRes)
})
}
},
toDo: function () {
if(this.checked !== !!(this.toDo.data.attributes.data.checked_at)) {
this.checked = !!(this.toDo.data.attributes.data.checked_at)
}
}
}
}
</script>

View File

@@ -1,5 +1,5 @@
<template>
<div class="p-4">
<div class="mx-2 p-2">
<div v-if="modal" class="modal-container" @click="modal = ! modal"></div>
<div v-if="modal" class="modal px-2">
<p class="m-2 text-center">Add a new to-do list ?</p>
@@ -22,8 +22,8 @@
:key="index"
:to="'/to-do-lists/' + toDoList.data.to_do_list_id"
:to-do-list="toDoList"
class="w-full sm:w-1/2 md:w-1/3 lg:w-1/4" >
<div class="bg-gray-300 rounded text-black m-2 p-2">
class="w-full sm:w-1/2 md:w-1/3 lg:w-1/4 no-underline" >
<div class="rounded bg-white text-black m-2 p-2">
<div class="flex justify-between">
<span class="font-bold">{{ toDoList.data.attributes.data.name }}</span>
<span>

View File

@@ -1,5 +1,5 @@
<template>
<div class="px-4 py-2">
<div class="mx-2 p-2">
<div v-if="modal" class="modal-container" @click="modal = ! modal"></div>
<div v-if="modal" class="modal">
<p class="m-2 text-center">Are you sure you want to delete this list ?</p>
@@ -12,15 +12,18 @@
<router-link to="/to-do-lists/" class="btn">Back</router-link>
<a href="#" class="btn-alert" @click="modal = ! modal">Delete</a>
</div>
<div v-if="!loading" class="bg-gray-400 rounded p-1">
<h1 class="mb-2 ml-2 todo" >
<div v-if="!loading" class="bg-marine-medium rounded p-1">
<h1 class="mb-2 ml-2 h-10 todo text-white flex items-center" >
<span v-if="!listNameEdit" class="text-2xl font-bold flex items-center">{{ toDoList.data.attributes.data.name }}
<span @click="listNameEdit = !listNameEdit">
<svg-vue icon="edit" class="edit-icon inline w-4 fill-current cursor-pointer ml-2" />
</span>
</span>
<span v-else class="flex items-center">
<input type="text" class="p-1 rounded-sm mt-1 -ml-1" v-model="listName" @keydown.enter="updateList">
<input type="text"
class="px-1 py-0 text-2xl text-white font-bold bg-marine-medium rounded-sm -ml-1"
v-model="listName"
@keydown.enter="updateList">
<span @click="listNameEdit = !listNameEdit">
<svg-vue icon="close" class="inline w-4 fill-current cursor-pointer ml-2" />
</span>
@@ -40,6 +43,7 @@
<svg-vue icon="draggable" class="w-4 block mr-2 cursor-move" />
<ToDo :to-do="toDo"
:id-list="toDoList.data.to_do_list_id"
ref="toDo"
class="flex-1 bg-blue" />
<span @click="deleteToDo(toDo, index)" class="cursor-pointer ml-2 font-bold edit-icon flex items-center">
<svg-vue icon="close" class="w-4" />
@@ -84,7 +88,7 @@ export default {
this.toDoList = res.data
this.loading = false
this.listName = res.data.data.attributes.data.name
this.reorderList()
this.sortList()
})
.catch(errorRes => {
this.loading = false
@@ -117,11 +121,14 @@ export default {
console.log('Internal Error, Unable to delete contact.' + errorRes)
})
},
reorderList() {
sortList() {
this.toDoList.data.attributes.data.to_dos.data.sort(function(a, b) {
return a.data.attributes.data.order - b.data.attributes.data.order
})
},
reorderList() {
this.sortList()
},
addToDo: function () {
if(this.toDoName.length >= 3) {
// eslint-disable-next-line no-undef

View File

@@ -25,6 +25,11 @@
<h1 class="relative z-10 text-white text-shadow text-3xl left-80 bottom-0">{{ authUser.data.attributes.name }}</h1>
</div>
</div>
<div class="m-2">
<div class="box">
Texte
</div>
</div>
</div>
</template>

View File

@@ -7,6 +7,11 @@
:alt="user.attributes.name"/>
</div>
<h1>{{ user.attributes.name }}</h1>
<div class="m-2">
<div class="box">
Texte
</div>
</div>
</div>
</template>

View File

@@ -2,7 +2,7 @@
<div v-if="authUser">
<div class="flex m-4">
<div class="avatar mr-2">
<Avatar :avatar="authUser.data.attributes.profile_image.data.attributes.path" size="6xl" :alt="authUser.data.attributes.name" class="w-24 h-24" />
<Avatar :avatar="authUser.data.attributes.thumbnail_cover_image.data.attributes.path" size="6xl" :alt="authUser.data.attributes.name" class="w-24 h-24" />
</div>
<div class="flex flex-col justify-center ml-2">
<div><strong>{{ authUser.data.attributes.name }}</strong></div>
@@ -10,7 +10,7 @@
</div>
</div>
<div v-if="authUser.data.attributes.is_admin">
<div class="box-toggle">
<div class="-mx-4 box-toggle">
<div class="box-toggle-header" @click="userAddToggle = !userAddToggle">
<h2 class="mb-1">Ajouter un membre</h2>
<svg-vue icon="arrow" v-bind:class="{ open: userAddToggle }" />
@@ -28,7 +28,7 @@
</form>
</transition>
</div>
<div class="mb-2 box-toggle">
<div class="-mx-4 mb-2 box-toggle">
<div class="box-toggle-header" @click="userListToggle = !userListToggle">
<h2>Liste des utilisateurs</h2>
<svg-vue icon="arrow" v-bind:class="{ open: userListToggle }" />

View File

@@ -1,3 +1,40 @@
h1,
h2,
h3,
h4 {
@apply font-bold;
}
h1 {
@apply text-4xl;
}
h2 {
@apply text-3xl;
}
h3 {
@apply text-2xl;
}
h4 {
@apply text-xl;
}
p {
@apply mb-2 mt-1;
text-indent: 2rem;
}
input,
textarea {
@apply border py-2 px-4 rounded;
}
textarea {
@apply ;
}
.text-shadow {
text-shadow: 1px 1px 2px #000;
}
@@ -33,3 +70,11 @@
.min-h-16 {
min-height: 4rem;
}
.indent {
text-indent: 2rem;
}
.no-indent {
text-indent: unset;
}

View File

@@ -1,7 +1,7 @@
// Button
.btn {
@apply border border-transparent inline-block bg-gray-600 text-white font-semibold whitespace-no-wrap py-2 px-4 shadow-sm rounded cursor-pointer;
@apply border border-transparent inline-block bg-gray-600 text-white font-semibold whitespace-no-wrap py-2 px-4 shadow-sm rounded cursor-pointer no-underline;
&:hover {
@apply text-white bg-gray-800 transition-all duration-300;

View File

@@ -5,10 +5,10 @@
}
a {
@apply text-gray-700;
@apply text-marine underline;
&:hover {
@apply text-gray-900;
@apply text-marine;
}
}
@@ -27,10 +27,9 @@ a {
}
.box-toggle {
@apply shadow;
&-header {
@apply flex justify-between items-center px-4 py-2 text-white bg-gray-800 font-bold cursor-pointer;
@apply flex justify-between items-center px-4 py-2 text-white bg-marine font-bold cursor-pointer;
svg {
@apply w-8 fill-current;
@@ -53,7 +52,7 @@ a {
}
.card {
@apply bg-gray-300 rounded text-black;
@apply bg-white rounded m-2 p-4 h-full flex flex-col justify-between;
svg {
@apply max-w-full max-h-48 max-w-48 m-auto fill-current;
@@ -63,3 +62,11 @@ a {
@apply text-2xl text-center font-bold;
}
}
.box {
@apply bg-white rounded p-4 my-2;
}
.tag {
@apply inline-block rounded-full px-3 py-1 text-sm font-semibold;
}

View File

@@ -1,10 +1,10 @@
nav {
@apply w-48 h-screen bg-gray-800 flex flex-col justify-between shadow;
@apply w-48 h-screen bg-marine flex flex-col justify-between shadow;
transition: width 0.3s;
svg {
@apply fill-current text-gray-300 w-12 p-2;
@apply fill-current text-white w-12 p-2;
transition: color 0.3s;
&:hover {
@@ -13,7 +13,7 @@ nav {
}
.logo {
@apply block;
@apply block text-white;
svg {
@apply w-40 m-2;
@@ -22,7 +22,7 @@ nav {
}
.nav-item {
@apply flex items-center text-gray-100;
@apply flex items-center text-white;
transition: background-color 0.3s;
span {

View File

@@ -1,34 +1,6 @@
.memo-style {
h1,
h2,
h3,
h4 {
@apply font-bold;
}
h1 {
@apply text-4xl;
}
h2 {
@apply text-3xl;
}
h3 {
@apply text-2xl;
}
h4 {
@apply text-xl;
}
p {
@apply mb-2 mt-1;
text-indent: 2rem;
}
pre,
code {
@apply bg-gray-700 text-white p-1;

View File

@@ -1,15 +1,15 @@
@extends('layouts.app')
@section('content')
<div class="bg-orange-200 mx-auto h-screen flex justify-center items-center">
<div class="w-96 m-auto bg-orange-400 rounded p-4 mt-10 shadow-xl">
<div class="bg-gray-200 mx-auto h-screen flex justify-center items-center">
<div class="w-96 m-auto bg-marine rounded p-4 mt-10 shadow-xl text-white">
<div class="text-3xl font-bold text-center mb-4">{{ __('Login') }}</div>
<form method="POST" action="{{ route('login') }}">
@csrf
<label for="email" class="mb-2 font-bold uppercase">{{ __('E-Mail') }}</label>
<div class="mb-4">
<input id="email" type="email" class="w-full border-2 border-orange-500 focus:border-orange-700 rounded p-2 @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
<input id="email" type="email" class="w-full border-2 text-black border-marine-light rounded p-2 @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
@@ -19,7 +19,7 @@
<label for="password" class="mb-2 font-bold uppercase">{{ __('Password') }}</label>
<div class="mb-4">
<input id="password" type="password" class="w-full border-2 border-orange-500 focus:border-orange-700 rounded p-2 @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
<input id="password" type="password" class="w-full border-2 text-black border-marine-light rounded p-2 @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
@error('password')
<span class="invalid-feedback" role="alert">

View File

@@ -1,11 +1,11 @@
@extends('layouts.app')
@section('content')
<div class="auth p-2">
<div class="title-page mb-2">{{ __('Reset Password') }}</div>
<div class="bg-gray-200 mx-auto h-screen flex justify-center items-center">
<div class="w-96 m-auto bg-marine rounded p-4 mt-10 shadow-xl text-white">
<div class="text-3xl font-bold text-center mb-4">{{ __('Reset Password') }}</div>
<div class="card-body">
@if (session('status'))
<div class="alert alert-success p-1 mb-1" role="alert">
{{ session('status') }}
@@ -15,9 +15,9 @@
<form method="POST" action="{{ route('password.email') }}">
@csrf
<label for="email" class="mb-1">{{ __('E-Mail') }}</label>
<div class="mb-2">
<input id="email" type="email" class="@error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
<label for="email" class="mb-2 font-bold uppercase">{{ __('E-Mail') }}</label>
<div class="mb-4">
<input id="email" type="email" class="w-full text-black border-2 border-marine-light rounded p-2 @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
@@ -25,13 +25,14 @@
@enderror
</div>
<div class="flex-between">
<div class="flex justify-center">
<button type="submit" class="btn-primary px-3 w-100">
{{ __('Send Password Reset Link') }}
</button>
</div>
</form>
</div>
</div>
</div>
@endsection

View File

@@ -1,77 +0,0 @@
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Register') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('register') }}">
@csrf
<div class="form-group row">
<label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>
@error('name')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email">
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row">
<label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Register') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@@ -27,10 +27,13 @@ Route::middleware('auth:api')->group(function () {
'/to-do-lists' => 'ToDoListController',
'/to-do-lists/{toDoList}/to-do' => 'ToDoController',
'/bookmarks' => 'BookmarkController',
'/events/categories' => 'EventCategoryController',
'/events' => 'EventController',
// '/users/{user}/posts' => 'UserPostController',
// '/friend-request' => 'FriendRequestController',
]);
Route::get('/automation/home', 'AutomationController@home');
Route::post('/images/users/{users}', 'ImageController@users');
Route::post('/images/memos/{memo}', 'ImageController@memos');
Route::patch('/to-do-lists/{toDoList}/to-do/{toDo}/change', 'ToDoController@changeOrder');

5
tailwind.config.js vendored
View File

@@ -8,6 +8,11 @@ module.exports = {
},
extend: {
colors: {
marine: {
light: '#364f80',
medium:'#2e446e',
default: '#223251',
},
cyan: '#9cdbff',
green: {
light: '#333',

View File

@@ -0,0 +1,321 @@
<?php
namespace Tests\Feature;
use App\Models\Event;
use App\Models\EventCategory;
use App\Models\Memo;
use App\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Symfony\Component\HttpFoundation\Response;
use Tests\TestCase;
class EventsTest extends TestCase
{
use RefreshDatabase;
/** @test */
public function an_admin_can_create_an_event_category()
{
$this->withoutExceptionHandling();
$this->actingAs($user = factory(User::class)->create(['role' => 2]), 'api');
$response = $this->post('/api/events/categories', [
'name' => 'Test name event category',
'description' => 'Test description event category',
])->assertStatus(201);
$category = EventCategory::first();
$this->assertEquals('Test name event category', $category->name);
$this->assertEquals('Test description event category', $category->description);
$response->assertJson([
'data' => [
'type' => 'event categories',
'event_category_id' => $category->id,
'attributes' => [
'data' => [
'name' => $category->name,
'description' => $category->description,
]
],
],
'links' => [
'self' => url('/events/categories/'.$category->id),
]
]);
}
/** @test */
public function event_category_name_are_required()
{
$this->actingAs($user = factory(\App\User::class)->create(['role' => 2]), 'api');
$response = $this->post('/api/events/categories', ['name' => '', 'description' => 'test name required']);
$response->assertSessionHasErrors('name');
$this->assertCount(0, EventCategory::all());
}
/** @test */
public function only_admin_can_create_event_category()
{
$this->actingAs($user = factory(User::class)->create(), 'api');
$response = $this->post('/api/events/categories', ['name' => 'Test fail', 'description' => 'test name required']);
$response->assertStatus(403);
$this->assertCount(0, EventCategory::all());
}
/** @test */
public function an_event_category_can_be_retrieved()
{
$this->actingAs($user = factory(User::class)->create(), 'api');
$category = EventCategory::create(['name' => 'Test category', 'description' => 'Test description']);
$response = $this->get('/api/events/categories/' . $category->id );
$response->assertJson([
'data' => [
'type' => 'event categories',
'event_category_id' => $category->id,
'attributes' => [
'data' => [
'name' => $category->name,
'description' => $category->description,
]
],
]
]);
}
/** @test */
public function all_event_categories_can_be_retrieved()
{
$this->actingAs($user = factory(User::class)->create(), 'api');
$category = EventCategory::create(['name' => 'Test category', 'description' => 'Test description']);
$categoryTwo = EventCategory::create(['name' => 'Test category 2', 'description' => 'Test description']);
$categoryTree = EventCategory::create(['name' => 'Test category 3', 'description' => 'Test description']);
$response = $this->get('/api/events/categories');
$response->assertJson([
'data' => [
[
'data' => [
'type' => 'event categories',
'event_category_id' => $category->id,
'attributes' => [
'data' => [
'name' => $category->name,
'description' => $category->description,
]
],
],
],
[
'data' => [
'type' => 'event categories',
'event_category_id' => $categoryTwo->id,
'attributes' => [
'data' => [
'name' => $categoryTwo->name,
'description' => $categoryTwo->description,
]
],
],
],
[
'data' => [
'type' => 'event categories',
'event_category_id' => $categoryTree->id,
'attributes' => [
'data' => [
'name' => $categoryTree->name,
'description' => $categoryTree->description,
]
],
],
],
],
]);
}
/** @test */
public function a_event_category_can_be_patch()
{
$this->actingAs($user = factory(User::class)->create(['role' => 2]), 'api');
$category = EventCategory::create(['name' => 'Test category', 'description' => 'Test description']);
$response = $this->patch('/api/events/categories/' . $category->id, ['name' => 'Update Catégory']);
$category = $category->fresh();
$this->assertEquals('Update Catégory', $category->name);
$response->assertStatus(200);
$response->assertJson([
'data' => [
'type' => 'event categories',
'event_category_id' => $category->id,
'attributes' => [
'data' => [
'name' => $category->name,
'description' => $category->description,
]
],
],
]);
}
/** @test */
public function only_the_admin_can_patch_the_memo()
{
$this->actingAs($user = factory(User::class)->create(), 'api');
$category = EventCategory::create(['name' => 'Test category', 'description' => 'Test description']);
$response = $this->patch('/api/events/categories/' . $category->id, ['name' => 'try to update']);
$response->assertStatus(403);
}
/** @test */
public function an_event_category_can_be_delete()
{
$this->actingAs($user = factory(User::class)->create(['role' => 2]), 'api');
$category = EventCategory::create(['name' => 'Test category', 'description' => 'Test description']);
$response = $this->delete('/api/events/categories/' . $category->id);
$category = $category->fresh();
$this->assertCount(0, EventCategory::all());
$response->assertStatus(204);
}
/** @test */
public function only_admin_can_delete_an_event_category()
{
$this->actingAs($user = factory(User::class)->create(), 'api');
$category = EventCategory::create(['name' => 'Test category', 'description' => 'Test description']);
$response = $this->delete('/api/events/categories/' . $category->id);
$response->assertStatus(403);
}
/** @test */
public function a_user_can_create_an_event()
{
$this->withoutExceptionHandling();
$this->actingAs($user = factory(User::class)->create(), 'api');
app(\DatabaseSeeder::class)->call(\EventCategorySeeder::class);
//dd(EventCategory::all());
$response = $this->post('/api/events', $this->data())->assertStatus(201);
$event = Event::first();
$this->assertEquals($user->id, $event->user_id);
$this->assertEquals(1, $event->category_id);
$this->assertEquals('Test name event', $event->name);
$this->assertEquals('Test description event', $event->description);
$this->assertEquals('2020-07-20 09:00:00', $event->start_date);
$this->assertEquals('2020-07-26 09:00:00', $event->end_date);
$this->assertEquals('Marcillac', $event->location);
$response->assertJson([
'data' => [
'type' => 'events',
'event_id' => $event->id,
'attributes' => [
'data' => [
'name' => $event->name,
'description' => $event->description,
'start_date' => $event->start_date,
'end_date' => $event->end_date,
'location' => $event->location,
'category' => [
'data' => [
'category_id' => 1
],
],
]
],
],
'links' => [
'self' => url('/events/'.$event->id),
]
]);
}
/** @test */
public function event_name_are_required()
{
$this->actingAs($user = factory(\App\User::class)->create(), 'api');
$response = $this->post('/api/events', array_merge($this->data(), ['name' => '']));
$response->assertSessionHasErrors('name');
$this->assertCount(0, EventCategory::all());
}
/** @test */
public function event_start_date_are_required()
{
$this->actingAs($user = factory(\App\User::class)->create(), 'api');
$response = $this->post('/api/events', array_merge($this->data(), ['start_date' => '']));
$response->assertSessionHasErrors('start_date');
$this->assertCount(0, EventCategory::all());
}
/** @test */
public function an_event_can_be_retrieved()
{
$this->actingAs($user = factory(User::class)->create(), 'api');
app(\DatabaseSeeder::class)->call(\EventCategorySeeder::class);
$event = $user->events()->create($this->data());
$response = $this->get('/api/events/' . $event->id );
$response->assertJson([
'data' => [
'type' => 'events',
'event_id' => $event->id,
'attributes' => [
'data' => [
'name' => $event->name,
'description' => $event->description,
'start_date' => $event->start_date,
'end_date' => $event->end_date,
'location' => $event->location,
'category' => [
'data' => [
'category_id' => 1
],
],
]
],
],
]);
}
private function data()
{
return [
'name' => 'Test name event',
'description' => 'Test description event',
'category_id' => 1,
'start_date' => '2020-07-20 09:00:00',
'end_date' => '2020-07-26 09:00:00',
'location' => 'Marcillac',
];
}
}

View File

@@ -99,7 +99,7 @@ class ImagesTest extends TestCase
'profile_image' => [
'data' => [
'type' => 'images',
'image_id' => 2,
'image_id' => 3,
'attributes' => []
]
]

View File

@@ -14,14 +14,14 @@ class MemosTest extends TestCase
use RefreshDatabase;
/** @test */
public function an_unauthenticated_user_should_redirect_to_login()
/* public function an_unauthenticated_user_should_redirect_to_login()
{
$response = $this->post('/api/memos', $this->data());
$this->assertGuest($guard = null);
$response->assertRedirect('/login');
$this->assertCount(0, Memo::all());
}
} */
/** @test */
public function an_unauthenticated_user_can_add_a_memo()

2
webpack.mix.js vendored
View File

@@ -10,4 +10,4 @@ mix.js('resources/js/app.js', 'public/js')
processCssUrls: false,
postCss: [ tailwindcss('./tailwind.config.js') ],
})
.purgeCss();
.purgeCss({whitelistPatterns: [/-active$/, /-enter$/, /-leave-to$/, /show$/, /code$/, /pre$/, /blockquote$/]});